diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 590d7834b2b8be..9f808af38e69df 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,7 +6,7 @@ ENV WASI_SDK_VERSION=20 ENV WASI_SDK_PATH=/opt/wasi-sdk ENV WASMTIME_HOME=/opt/wasmtime -ENV WASMTIME_VERSION=9.0.1 +ENV WASMTIME_VERSION=14.0.4 ENV WASMTIME_CPU_ARCH=x86_64 RUN dnf -y --nodocs --setopt=install_weak_deps=False install /usr/bin/{blurb,clang,curl,git,ln,tar,xz} 'dnf-command(builddep)' && \ 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 8c37dbbb631022..22afffb05abb20 100644 --- a/.gitattributes +++ b/.gitattributes @@ -76,6 +76,7 @@ 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/internal/pycore_uop_ids.h generated Include/opcode.h generated Include/opcode_ids.h generated Include/token.h generated @@ -84,6 +85,7 @@ Lib/keyword.py generated Lib/test/levenshtein_examples.json generated Lib/test/test_stable_abi_ctypes.py generated Lib/token.py generated +Misc/sbom.spdx.json generated Objects/typeslots.inc generated PC/python3dll.c generated Parser/parser.c generated diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cd35cba5b5c56d..db28c2a231ae04 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,14 +28,19 @@ Objects/type* @markshannon Objects/codeobject.c @markshannon Objects/frameobject.c @markshannon Objects/call.c @markshannon -Python/ceval.c @markshannon +Python/ceval*.c @markshannon @gvanrossum +Python/ceval*.h @markshannon @gvanrossum Python/compile.c @markshannon @iritkatriel Python/assemble.c @markshannon @iritkatriel Python/flowgraph.c @markshannon @iritkatriel Python/ast_opt.c @isidentical +Python/bytecodes.c @markshannon @gvanrossum +Python/optimizer*.c @markshannon @gvanrossum Lib/test/test_patma.py @brandtbucher Lib/test/test_peepholer.py @brandtbucher Lib/test/test_type_*.py @JelleZijlstra +Lib/test/test_capi/test_misc.py @markshannon @gvanrossum +Tools/c-analyzer/ @ericsnowcurrently # Exceptions Lib/traceback.py @iritkatriel @@ -102,6 +107,9 @@ Include/internal/pycore_time.h @pganssle @abalkin /Lib/tokenize.py @pablogsal @lysnikolaou /Lib/test/test_tokenize.py @pablogsal @lysnikolaou +# Code generator +/Tools/cases_generator/ @gvanrossum + # AST Python/ast.c @isidentical Parser/asdl.py @isidentical @@ -151,7 +159,7 @@ Doc/c-api/stable.rst @encukou **/*idlelib* @terryjreedy -**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra @AlexWaygood +**/*typing* @JelleZijlstra @AlexWaygood **/*ftplib @giampaolo **/*shutil @giampaolo @@ -181,5 +189,14 @@ Doc/c-api/stable.rst @encukou /Lib/test/test_clinic.py @erlend-aasland @AlexWaygood Doc/howto/clinic.rst @erlend-aasland +# Subinterpreters +Lib/test/support/interpreters/ @ericsnowcurrently +Modules/_xx*interp*module.c @ericsnowcurrently +Lib/test/test_interpreters/ @ericsnowcurrently + # WebAssembly /Tools/wasm/ @brettcannon + +# SBOM +/Misc/sbom.spdx.json @sethmlarson +/Tools/build/generate_sbom.py @sethmlarson diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 21a375361bf58e..395516f29b037c 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -39,6 +39,7 @@ body: - "3.10" - "3.11" - "3.12" + - "3.13" - "CPython main branch" validations: required: true diff --git a/.github/workflows/add-issue-header.yml b/.github/workflows/add-issue-header.yml index 1ef9178b95e5f6..570b8779994a0f 100644 --- a/.github/workflows/add-issue-header.yml +++ b/.github/workflows/add-issue-header.yml @@ -19,7 +19,7 @@ jobs: permissions: issues: write steps: - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 with: # language=JavaScript script: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ffcfbac290b726..cfb36c8c32e18d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,6 @@ on: - '3.10' - '3.9' - '3.8' - - '3.7' pull_request: branches: - 'main' @@ -22,7 +21,6 @@ on: - '3.10' - '3.9' - '3.8' - - '3.7' permissions: contents: read @@ -40,6 +38,7 @@ 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@v4 @@ -76,6 +75,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: | @@ -106,20 +120,22 @@ jobs: check_generated_files: name: 'Check if generated files are up to date' - runs-on: ubuntu-latest + # Don't use ubuntu-latest but a specific version to make the job + # reproducible: to get the same tools versions (autoconf, aclocal, ...) + runs-on: ubuntu-22.04 timeout-minutes: 60 needs: check_source if: needs.check_source.outputs.run_tests == 'true' steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' - 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@v4 - with: - python-version: '3.x' + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}-${{ env.pythonLocation }} - name: Install Dependencies run: sudo ./.github/workflows/posix-deps-apt.sh - name: Add ccache to PATH @@ -129,15 +145,16 @@ jobs: - name: Check Autoconf and aclocal versions run: | grep "Generated by GNU Autoconf 2.71" configure - grep "aclocal 1.16.4" aclocal.m4 + grep "aclocal 1.16.5" aclocal.m4 grep -q "runstatedir" configure grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 - name: Configure CPython run: | # Build Python with the libpython dynamic library ./configure --config-cache --with-pydebug --enable-shared - - name: Regenerate autoconf files with container image - run: make regen-configure + - name: Regenerate autoconf files + # Same command used by Tools/build/regen-configure.sh ($AUTORECONF) + run: autoreconf -ivf -Werror - name: Build CPython run: | make -j4 regen-all @@ -164,159 +181,63 @@ jobs: if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME run: make check-c-globals - build_win32: - name: 'Windows (x86)' - runs-on: windows-latest - timeout-minutes: 60 + build_windows: + name: 'Windows' needs: check_source if: needs.check_source.outputs.run_tests == 'true' - env: - IncludeUwp: 'true' - steps: - - 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 --fast-ci + uses: ./.github/workflows/reusable-windows.yml - build_win_amd64: - name: 'Windows (x64)' - runs-on: windows-latest - timeout-minutes: 60 + build_windows_free_threaded: + name: 'Windows (free-threaded)' 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 x64 - - name: Display build info - run: .\python.bat -m test.pythoninfo - - name: Tests - run: .\PCbuild\rt.bat -p x64 -d -q --fast-ci + uses: ./.github/workflows/reusable-windows.yml + with: + free-threaded: true - build_win_arm64: - name: 'Windows (arm64)' - runs-on: windows-latest - timeout-minutes: 60 + build_macos: + name: 'macOS' 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 + uses: ./.github/workflows/reusable-macos.yml + with: + config_hash: ${{ needs.check_source.outputs.config_hash }} - build_macos: - name: 'macOS' - runs-on: macos-latest - timeout-minutes: 60 + build_macos_free_threaded: + name: 'macOS (free-threaded)' needs: check_source if: needs.check_source.outputs.run_tests == 'true' - env: - HOMEBREW_NO_ANALYTICS: 1 - HOMEBREW_NO_AUTO_UPDATE: 1 - HOMEBREW_NO_INSTALL_CLEANUP: 1 - PYTHONSTRICTEXTENSIONBUILD: 1 - steps: - - 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 }} - - name: Install Homebrew dependencies - run: brew install pkg-config openssl@3.0 xz gdbm tcl-tk - - name: Configure CPython - run: | - GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ - GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ - ./configure \ - --config-cache \ - --with-pydebug \ - --prefix=/opt/python-dev \ - --with-openssl="$(brew --prefix openssl@3.0)" - - name: Build CPython - run: make -j4 - - name: Display build info - run: make pythoninfo - - name: Tests - run: make test + uses: ./.github/workflows/reusable-macos.yml + with: + config_hash: ${{ needs.check_source.outputs.config_hash }} + free-threaded: true build_ubuntu: name: 'Ubuntu' - runs-on: ubuntu-20.04 - timeout-minutes: 60 needs: check_source if: needs.check_source.outputs.run_tests == 'true' - env: - OPENSSL_VER: 3.0.11 - PYTHONSTRICTEXTENSIONBUILD: 1 - steps: - - uses: actions/checkout@v4 - - name: Register gcc problem matcher - run: echo "::add-matcher::.github/problem-matchers/gcc.json" - - name: Install Dependencies - run: sudo ./.github/workflows/posix-deps-apt.sh - - name: Configure OpenSSL env vars - run: | - echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV - echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV - - name: 'Restore OpenSSL build' - id: cache-openssl - uses: actions/cache@v3 - with: - path: ./multissl/openssl/${{ env.OPENSSL_VER }} - key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} - - name: Install OpenSSL - if: steps.cache-openssl.outputs.cache-hit != 'true' - run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux - - name: Add ccache to PATH - run: | - echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV - - name: Configure ccache action - uses: hendrikmuhs/ccache-action@v1.2 - - name: Setup directory envs for out-of-tree builds - run: | - echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV - echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV - - name: Create directories for read-only out-of-tree builds - run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR - - name: Bind mount sources read-only - run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR - - name: Restore config.cache - uses: actions/cache@v3 - with: - path: ${{ env.CPYTHON_BUILDDIR }}/config.cache - key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} - - name: Configure CPython out-of-tree - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: | + uses: ./.github/workflows/reusable-ubuntu.yml + with: + config_hash: ${{ needs.check_source.outputs.config_hash }} + options: | ../cpython-ro-srcdir/configure \ --config-cache \ --with-pydebug \ --with-openssl=$OPENSSL_DIR - - name: Build CPython out-of-tree - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: make -j4 - - name: Display build info - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: make pythoninfo - - name: Remount sources writable for tests - # some tests write to srcdir, lack of pyc files slows down testing - run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw - - name: Tests - working-directory: ${{ env.CPYTHON_BUILDDIR }} - run: xvfb-run make test + + build_ubuntu_free_threaded: + name: 'Ubuntu (free-threaded)' + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + uses: ./.github/workflows/reusable-ubuntu.yml + with: + config_hash: ${{ needs.check_source.outputs.config_hash }} + options: | + ../cpython-ro-srcdir/configure \ + --config-cache \ + --with-pydebug \ + --with-openssl=$OPENSSL_DIR \ + --disable-gil build_ubuntu_ssltests: name: 'Ubuntu SSL tests with OpenSSL' @@ -534,6 +455,46 @@ jobs: - name: Tests 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 if: always() @@ -542,14 +503,16 @@ jobs: - check_source # Transitive dependency, needed to access `run_tests` value - check-docs - check_generated_files - - build_win32 - - build_win_amd64 - - build_win_arm64 - build_macos + - build_macos_free_threaded - build_ubuntu + - build_ubuntu_free_threaded - build_ubuntu_ssltests + - build_windows + - build_windows_free_threaded - test_hypothesis - build_asan + - cifuzz runs-on: ubuntu-latest @@ -558,10 +521,8 @@ jobs: uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe with: allowed-failures: >- - build_macos, build_ubuntu_ssltests, - build_win32, - build_win_arm64, + cifuzz, test_hypothesis, allowed-skips: >- ${{ @@ -575,16 +536,24 @@ jobs: needs.check_source.outputs.run_tests != 'true' && ' check_generated_files, - build_win32, - build_win_amd64, - build_win_arm64, build_macos, + build_macos_free_threaded, build_ubuntu, + build_ubuntu_free_threaded, build_ubuntu_ssltests, + build_windows, + build_windows_free_threaded, build_asan, ' || '' }} + ${{ + !fromJSON(needs.check_source.outputs.run_cifuzz) + && ' + cifuzz, + ' + || '' + }} ${{ !fromJSON(needs.check_source.outputs.run_hypothesis) && ' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 89f65816b6969d..6c1c29a58cf4fc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,7 +7,7 @@ permissions: env: FORCE_COLOR: 1 - RUFF_FORMAT: github + RUFF_OUTPUT_FORMAT: github concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 405511ca6820b3..792903a90a4880 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -8,6 +8,8 @@ on: pull_request: paths: - ".github/workflows/mypy.yml" + - "Lib/test/libregrtest/**" + - "Tools/build/generate_sbom.py" - "Tools/cases_generator/**" - "Tools/clinic/**" - "Tools/peg_generator/**" @@ -32,6 +34,8 @@ jobs: strategy: matrix: target: [ + "Lib/test/libregrtest", + "Tools/build/", "Tools/cases_generator", "Tools/clinic", "Tools/peg_generator", diff --git a/.github/workflows/new-bugs-announce-notifier.yml b/.github/workflows/new-bugs-announce-notifier.yml index 80514b4d2ca572..9f1a8a824e5f19 100644 --- a/.github/workflows/new-bugs-announce-notifier.yml +++ b/.github/workflows/new-bugs-announce-notifier.yml @@ -13,12 +13,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 20 - run: npm install mailgun.js form-data - name: Send notification - uses: actions/github-script@v6 + uses: actions/github-script@v7 env: MAILGUN_API_KEY: ${{ secrets.MAILGUN_PYTHON_ORG_MAILGUN_KEY }} with: diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh index a220896f2cd7be..0800401f4cd113 100755 --- a/.github/workflows/posix-deps-apt.sh +++ b/.github/workflows/posix-deps-apt.sh @@ -1,9 +1,11 @@ #!/bin/sh apt-get update +# autoconf-archive is needed by autoreconf (check_generated_files job) apt-get -yq install \ build-essential \ pkg-config \ + autoconf-archive \ ccache \ gdb \ lcov \ @@ -19,6 +21,7 @@ apt-get -yq install \ libssl-dev \ lzma \ lzma-dev \ + strace \ tk-dev \ uuid-dev \ xvfb \ diff --git a/.github/workflows/reusable-macos.yml b/.github/workflows/reusable-macos.yml new file mode 100644 index 00000000000000..22f46d18e1b43a --- /dev/null +++ b/.github/workflows/reusable-macos.yml @@ -0,0 +1,46 @@ +on: + workflow_call: + inputs: + config_hash: + required: true + type: string + free-threaded: + required: false + type: boolean + default: false + +jobs: + build_macos: + name: 'build and test' + runs-on: macos-latest + timeout-minutes: 60 + env: + HOMEBREW_NO_ANALYTICS: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + PYTHONSTRICTEXTENSIONBUILD: 1 + steps: + - uses: actions/checkout@v4 + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ inputs.config_hash }} + - name: Install Homebrew dependencies + run: brew install pkg-config openssl@3.0 xz gdbm tcl-tk + - name: Configure CPython + run: | + GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ + GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ + ./configure \ + --config-cache \ + --with-pydebug \ + ${{ inputs.free-threaded && '--disable-gil' || '' }} \ + --prefix=/opt/python-dev \ + --with-openssl="$(brew --prefix openssl@3.0)" + - name: Build CPython + run: make -j4 + - name: Display build info + run: make pythoninfo + - name: Tests + run: make test diff --git a/.github/workflows/reusable-ubuntu.yml b/.github/workflows/reusable-ubuntu.yml new file mode 100644 index 00000000000000..819b45bda7f980 --- /dev/null +++ b/.github/workflows/reusable-ubuntu.yml @@ -0,0 +1,71 @@ +on: + workflow_call: + inputs: + config_hash: + required: true + type: string + options: + required: true + type: string + +jobs: + build_ubuntu_reusable: + name: 'build and test' + timeout-minutes: 60 + runs-on: ubuntu-20.04 + env: + OPENSSL_VER: 3.0.11 + PYTHONSTRICTEXTENSIONBUILD: 1 + steps: + - uses: actions/checkout@v4 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1.2 + - name: Setup directory envs for out-of-tree builds + run: | + echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV + echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV + - name: Create directories for read-only out-of-tree builds + run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR + - name: Bind mount sources read-only + run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: ${{ env.CPYTHON_BUILDDIR }}/config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ inputs.config_hash }} + - name: Configure CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: ${{ inputs.options }} + - name: Build CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make -j4 + - name: Display build info + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make pythoninfo + - name: Remount sources writable for tests + # some tests write to srcdir, lack of pyc files slows down testing + run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw + - name: Tests + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: xvfb-run make test diff --git a/.github/workflows/reusable-windows.yml b/.github/workflows/reusable-windows.yml new file mode 100644 index 00000000000000..47a3c10d2ca4c1 --- /dev/null +++ b/.github/workflows/reusable-windows.yml @@ -0,0 +1,53 @@ +on: + workflow_call: + inputs: + free-threaded: + required: false + type: boolean + default: false + +jobs: + build_win32: + name: 'build and test (x86)' + runs-on: windows-latest + timeout-minutes: 60 + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v4 + - name: Build CPython + run: .\PCbuild\build.bat -e -d -v -p Win32 ${{ inputs.free-threaded && '--disable-gil' || '' }} + - name: Display build info + run: .\python.bat -m test.pythoninfo + - name: Tests + run: .\PCbuild\rt.bat -p Win32 -d -q --fast-ci + + build_win_amd64: + name: 'build and test (x64)' + runs-on: windows-latest + timeout-minutes: 60 + 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 -v -p x64 ${{ inputs.free-threaded && '--disable-gil' || '' }} + - name: Display build info + run: .\python.bat -m test.pythoninfo + - name: Tests + run: .\PCbuild\rt.bat -p x64 -d -q --fast-ci + + build_win_arm64: + name: 'build (arm64)' + runs-on: windows-latest + timeout-minutes: 60 + 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 -v -p arm64 ${{ inputs.free-threaded && '--disable-gil' || '' }} diff --git a/.gitignore b/.gitignore index dddf28da016192..c424a894c2a6e0 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ gmon.out .coverage .mypy_cache/ .pytest_cache/ +.ruff_cache/ .DS_Store *.exe @@ -124,6 +125,7 @@ Tools/unicode/data/ /config.status.lineno # hendrikmuhs/ccache-action@v1 /.ccache +/cross-build/ /platform /profile-clean-stamp /profile-run-stamp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4c1fd20ea921b8..9bd9c59a1ddc74 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,18 @@ repos: - repo: /~https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.288 + rev: v0.1.7 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 + rev: v4.5.0 hooks: - id: check-toml exclude: ^Lib/test/test_tomllib/ @@ -17,12 +21,16 @@ repos: types: [python] 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.8 + rev: v0.9.1 hooks: - id: sphinx-lint args: [--enable=default-role] 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..7af56e965e1be4 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 = @@ -30,6 +29,7 @@ help: @echo " venv to create a venv with necessary tools" @echo " html to make standalone HTML files" @echo " htmlview to open the index page built by the html target in your browser" + @echo " htmllive to rebuild and reload HTML files in your browser" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " text to make plain text files" @@ -140,6 +140,11 @@ pydoc-topics: build htmlview: html $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))" +.PHONY: htmllive +htmllive: SPHINXBUILD = $(VENVDIR)/bin/sphinx-autobuild +htmllive: SPHINXOPTS = --re-ignore="/venv/" +htmllive: html + .PHONY: clean clean: clean-venv -rm -rf build/* diff --git a/Doc/bugs.rst b/Doc/bugs.rst index d98192b369603e..908987cf41ff6e 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -38,7 +38,7 @@ though it may take a while to be processed. `Helping with Documentation `_ Comprehensive guide for individuals that are interested in contributing to Python documentation. - `Documentation Translations `_ + `Documentation Translations `_ A list of GitHub pages for documentation translation and their primary contacts. diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index c43dd0f4303cd4..834aae9372fe3b 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -413,21 +413,35 @@ API Functions than a variable number of arguments. -.. c:function:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...) +.. c:function:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char * const *keywords, ...) Parse the parameters of a function that takes both positional and keyword - parameters into local variables. The *keywords* argument is a - ``NULL``-terminated array of keyword parameter names. Empty names denote + parameters into local variables. + The *keywords* argument is a ``NULL``-terminated array of keyword parameter + names specified as null-terminated ASCII or UTF-8 encoded C strings. + Empty names denote :ref:`positional-only parameters `. Returns true on success; on failure, it returns false and raises the appropriate exception. + .. note:: + + The *keywords* parameter declaration is :c:expr:`char * const *` in C and + :c:expr:`const char * const *` in C++. + This can be overridden with the :c:macro:`PY_CXX_CONST` macro. + .. versionchanged:: 3.6 Added support for :ref:`positional-only parameters `. + .. versionchanged:: 3.13 + The *keywords* parameter has now type :c:expr:`char * const *` in C and + :c:expr:`const char * const *` in C++, instead of :c:expr:`char **`. + Added support for non-ASCII keyword parameter names. + -.. c:function:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs) + +.. c:function:: int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char * const *keywords, va_list vargs) Identical to :c:func:`PyArg_ParseTupleAndKeywords`, except that it accepts a va_list rather than a variable number of arguments. @@ -500,6 +514,19 @@ API Functions PyArg_ParseTuple(args, "O|O:ref", &object, &callback) +.. c:macro:: PY_CXX_CONST + + The value to be inserted, if any, before :c:expr:`char * const *` + in the *keywords* parameter declaration of + :c:func:`PyArg_ParseTupleAndKeywords` and + :c:func:`PyArg_VaParseTupleAndKeywords`. + Default empty for C and ``const`` for C++ + (:c:expr:`const char * const *`). + To override, define it to the desired value before including + :file:`Python.h`. + + .. versionadded:: 3.13 + --------------- Building values diff --git a/Doc/c-api/bool.rst b/Doc/c-api/bool.rst index b14fa6a0a982e2..b4dc4849d044e1 100644 --- a/Doc/c-api/bool.rst +++ b/Doc/c-api/bool.rst @@ -26,19 +26,19 @@ are available, however. .. c:var:: PyObject* Py_False The Python ``False`` object. This object has no methods and is - `immortal `_. + :term:`immortal`. -.. versionchanged:: 3.12 - :c:data:`Py_False` is immortal. + .. versionchanged:: 3.12 + :c:data:`Py_False` is :term:`immortal`. .. c:var:: PyObject* Py_True The Python ``True`` object. This object has no methods and is - `immortal `_. + :term:`immortal`. -.. versionchanged:: 3.12 - :c:data:`Py_True` is immortal. + .. versionchanged:: 3.12 + :c:data:`Py_True` is :term:`immortal`. .. c:macro:: Py_RETURN_FALSE diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 61a68f52773882..4790d3b2da4375 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -155,6 +155,7 @@ called with a non-bytes parameter. Return the null-terminated contents of the object *obj* through the output variables *buffer* and *length*. + Returns ``0`` on success. If *length* is ``NULL``, the bytes object may not contain embedded null bytes; diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index aed4ae44c76eea..7198d6bc056eb4 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -108,6 +108,8 @@ This is a pointer to a function with the following signature: Doing so will allow callables such as bound methods to make their onward calls (which include a prepended *self* argument) very efficiently. + .. versionadded:: 3.8 + To call an object that implements vectorcall, use a :ref:`call API ` function as with any other callable. :c:func:`PyObject_Vectorcall` will usually be most efficient. diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 8ee351918006e4..8471c98d044872 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -173,6 +173,33 @@ Dictionary Objects .. versionadded:: 3.4 + +.. c:function:: int PyDict_Pop(PyObject *p, PyObject *key, PyObject **result) + + Remove *key* from dictionary *p* and optionally return the removed value. + Do not raise :exc:`KeyError` if the key missing. + + - If the key is present, set *\*result* to a new reference to the removed + value if *result* is not ``NULL``, and return ``1``. + - If the key is missing, set *\*result* to ``NULL`` if *result* is not + ``NULL``, and return ``0``. + - On error, raise an exception and return ``-1``. + + This is similar to :meth:`dict.pop`, but without the default value and + not raising :exc:`KeyError` if the key missing. + + .. versionadded:: 3.13 + + +.. c:function:: int PyDict_PopString(PyObject *p, const char *key, PyObject **result) + + Similar to :c:func:`PyDict_Pop`, 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_Items(PyObject *p) Return a :c:type:`PyListObject` containing all the items from the dictionary. diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 2139da051e0193..284a9c71e420da 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -88,9 +88,29 @@ Printing and clearing The function is called with a single argument *obj* that identifies the context in which the unraisable exception occurred. If possible, the repr of *obj* will be printed in the warning message. + If *obj* is ``NULL``, only the traceback is printed. An exception must be set when calling this function. + .. versionchanged:: 3.4 + Print a traceback. Print only traceback if *obj* is ``NULL``. + + .. versionchanged:: 3.8 + Use :func:`sys.unraisablehook`. + + +.. c:function:: void PyErr_FormatUnraisable(const char *format, ...) + + Similar to :c:func:`PyErr_WriteUnraisable`, but the *format* and subsequent + parameters help format the warning message; they have the same meaning and + values as in :c:func:`PyUnicode_FromFormat`. + ``PyErr_WriteUnraisable(obj)`` is roughtly equivalent to + ``PyErr_FormatUnraisable("Exception ignored in: %R, obj)``. + If *format* is ``NULL``, only the traceback is printed. + + .. versionadded:: 3.13 + + .. c:function:: void PyErr_DisplayException(PyObject *exc) Print the standard traceback display of ``exc`` to ``sys.stderr``, including @@ -98,6 +118,7 @@ Printing and clearing .. versionadded:: 3.12 + Raising exceptions ================== @@ -520,7 +541,8 @@ Querying the error indicator .. note:: - This function *does not* implicitly set the ``__traceback__`` + This function *does not* implicitly set the + :attr:`~BaseException.__traceback__` attribute on the exception value. If setting the traceback appropriately is desired, the following additional snippet is needed:: @@ -732,7 +754,8 @@ Exception Objects .. c:function:: PyObject* PyException_GetTraceback(PyObject *ex) Return the traceback associated with the exception as a new reference, as - accessible from Python through :attr:`__traceback__`. If there is no + accessible from Python through the :attr:`~BaseException.__traceback__` + attribute. If there is no traceback associated, this returns ``NULL``. @@ -746,8 +769,8 @@ Exception Objects Return the context (another exception instance during whose handling *ex* was raised) associated with the exception as a new reference, as accessible from - Python through :attr:`__context__`. If there is no context associated, this - returns ``NULL``. + Python through the :attr:`~BaseException.__context__` attribute. + If there is no context associated, this returns ``NULL``. .. c:function:: void PyException_SetContext(PyObject *ex, PyObject *ctx) @@ -761,7 +784,8 @@ Exception Objects 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__`. + reference, as accessible from Python through the + :attr:`~BaseException.__cause__` attribute. .. c:function:: void PyException_SetCause(PyObject *ex, PyObject *cause) @@ -770,7 +794,8 @@ Exception Objects it. There is no type check to make sure that *cause* is either an exception instance or ``None``. This steals a reference to *cause*. - :attr:`__suppress_context__` is implicitly set to ``True`` by this function. + The :attr:`~BaseException.__suppress_context__` attribute is implicitly set + to ``True`` by this function. .. c:function:: PyObject* PyException_GetArgs(PyObject *ex) diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 1accee2767a485..6bb1e9b5803b58 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -50,7 +50,7 @@ See also :ref:`Reflection `. .. c:function:: PyObject* PyFrame_GetBuiltins(PyFrameObject *frame) - Get the *frame*'s ``f_builtins`` attribute. + Get the *frame*'s :attr:`~frame.f_builtins` attribute. Return a :term:`strong reference`. The result cannot be ``NULL``. @@ -81,7 +81,7 @@ See also :ref:`Reflection `. .. c:function:: PyObject* PyFrame_GetGlobals(PyFrameObject *frame) - Get the *frame*'s ``f_globals`` attribute. + Get the *frame*'s :attr:`~frame.f_globals` attribute. Return a :term:`strong reference`. The result cannot be ``NULL``. @@ -90,7 +90,7 @@ See also :ref:`Reflection `. .. c:function:: int PyFrame_GetLasti(PyFrameObject *frame) - Get the *frame*'s ``f_lasti`` attribute. + Get the *frame*'s :attr:`~frame.f_lasti` attribute. Returns -1 if ``frame.f_lasti`` is ``None``. @@ -120,7 +120,7 @@ See also :ref:`Reflection `. .. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame) - Get the *frame*'s ``f_locals`` attribute (:class:`dict`). + Get the *frame*'s :attr:`~frame.f_locals` attribute (:class:`dict`). Return a :term:`strong reference`. diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 5857dba82c11c6..e7fb5090c09933 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -34,18 +34,20 @@ There are a few functions specific to Python functions. Return a new function object associated with the code object *code*. *globals* must be a dictionary with the global variables accessible to the function. - The function's docstring and name are retrieved from the code object. *__module__* + The function's docstring and name are retrieved from the code object. + :attr:`~function.__module__` is retrieved from *globals*. The argument defaults, annotations and closure are - set to ``NULL``. *__qualname__* is set to the same value as the code object's - ``co_qualname`` field. + set to ``NULL``. :attr:`~function.__qualname__` is set to the same value as + the code object's :attr:`~codeobject.co_qualname` field. .. c:function:: PyObject* PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) As :c:func:`PyFunction_New`, but also allows setting the function object's - ``__qualname__`` attribute. *qualname* should be a unicode object or ``NULL``; - if ``NULL``, the ``__qualname__`` attribute is set to the same value as the - code object's ``co_qualname`` field. + :attr:`~function.__qualname__` attribute. + *qualname* should be a unicode object or ``NULL``; + if ``NULL``, the :attr:`!__qualname__` attribute is set to the same value as + the code object's :attr:`~codeobject.co_qualname` field. .. versionadded:: 3.3 @@ -62,11 +64,12 @@ There are a few functions specific to Python functions. .. c:function:: PyObject* PyFunction_GetModule(PyObject *op) - Return a :term:`borrowed reference` to the *__module__* attribute of the - function object *op*. It can be *NULL*. + Return a :term:`borrowed reference` to the :attr:`~function.__module__` + attribute of the :ref:`function object ` *op*. + It can be *NULL*. - This is normally a string containing the module name, but can be set to any - other object by Python code. + This is normally a :class:`string ` containing the module name, + but can be set to any other object by Python code. .. c:function:: PyObject* PyFunction_GetDefaults(PyObject *op) diff --git a/Doc/c-api/hash.rst b/Doc/c-api/hash.rst new file mode 100644 index 00000000000000..91d88ae27bc9f4 --- /dev/null +++ b/Doc/c-api/hash.rst @@ -0,0 +1,61 @@ +.. highlight:: c + +PyHash API +---------- + +See also the :c:member:`PyTypeObject.tp_hash` member. + +.. c:type:: Py_hash_t + + Hash value type: signed integer. + + .. versionadded:: 3.2 + +.. c:type:: Py_uhash_t + + Hash value type: unsigned integer. + + .. versionadded:: 3.2 + + +.. c:type:: PyHash_FuncDef + + Hash function definition used by :c:func:`PyHash_GetFuncDef`. + + .. c::member:: Py_hash_t (*const hash)(const void *, Py_ssize_t) + + Hash function. + + .. c:member:: const char *name + + Hash function name (UTF-8 encoded string). + + .. c:member:: const int hash_bits + + Internal size of the hash value in bits. + + .. c:member:: const int seed_bits + + Size of seed input in bits. + + .. versionadded:: 3.4 + + +.. c:function:: PyHash_FuncDef* PyHash_GetFuncDef(void) + + Get the hash function definition. + + .. seealso:: + :pep:`456` "Secure and interchangeable hash algorithm". + + .. versionadded:: 3.4 + + +.. c:function:: Py_hash_t Py_HashPointer(const void *ptr) + + Hash a pointer value: process the pointer value as an integer (cast it to + ``uintptr_t`` internally). The pointer is not dereferenced. + + The function cannot fail: it cannot return ``-1``. + + .. versionadded:: 3.13 diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 137780cc359cf9..51c20b202f091c 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -154,7 +154,7 @@ Importing Modules :class:`~importlib.machinery.SourceFileLoader` otherwise. The module's :attr:`__file__` attribute will be set to the code object's - :attr:`!co_filename`. If applicable, :attr:`__cached__` will also + :attr:`~codeobject.co_filename`. If applicable, :attr:`__cached__` will also be set. This function will reload the module if it was already imported. See diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 60f5c81cff572c..f8fd48e781d6da 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -870,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) @@ -1472,7 +1485,7 @@ 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". +can be made safe in spite of their refcounts by making them :term:`immortal`. In fact, this has been done for the builtin singletons, small integers, and a number of other builtin objects. @@ -1649,7 +1662,8 @@ Python-level trace functions in previous versions. The value passed as the *what* parameter to a :c:type:`Py_tracefunc` function (but not a profiling function) when a line-number event is being reported. - It may be disabled for a frame by setting :attr:`f_trace_lines` to *0* on that frame. + It may be disabled for a frame by setting :attr:`~frame.f_trace_lines` to + *0* on that frame. .. c:var:: int PyTrace_RETURN @@ -1681,7 +1695,7 @@ Python-level trace functions in previous versions. The value for the *what* parameter to :c:type:`Py_tracefunc` functions (but not profiling functions) when a new opcode is about to be executed. This event is not emitted by default: it must be explicitly requested by setting - :attr:`f_trace_opcodes` to *1* on the frame. + :attr:`~frame.f_trace_opcodes` to *1* on the frame. .. c:function:: void PyEval_SetProfile(Py_tracefunc func, PyObject *obj) diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 56b4ee03c1a8fd..47a8fbb2cd9c97 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -253,11 +253,21 @@ PyPreConfig * ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG`` (``6``): :ref:`Python pymalloc memory allocator ` with :ref:`debug hooks `. + * ``PYMEM_ALLOCATOR_MIMALLOC`` (``6``): use ``mimalloc``, a fast + malloc replacement. + * ``PYMEM_ALLOCATOR_MIMALLOC_DEBUG`` (``7``): use ``mimalloc``, a fast + malloc replacement with :ref:`debug hooks `. + ``PYMEM_ALLOCATOR_PYMALLOC`` and ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG`` are not supported if Python is :option:`configured using --without-pymalloc <--without-pymalloc>`. + ``PYMEM_ALLOCATOR_MIMALLOC`` and ``PYMEM_ALLOCATOR_MIMALLOC_DEBUG`` are + not supported if Python is :option:`configured using --without-mimalloc + <--without-mimalloc>` or if the underlying atomic support isn't + available. + See :ref:`Memory Management `. Default: ``PYMEM_ALLOCATOR_NOT_SET``. @@ -716,7 +726,7 @@ PyConfig Set to ``1`` by the :envvar:`PYTHONDUMPREFS` environment variable. - Need a special build of Python with the ``Py_TRACE_REFS`` macro defined: + Needs a special build of Python with the ``Py_TRACE_REFS`` macro defined: see the :option:`configure --with-trace-refs option <--with-trace-refs>`. Default: ``0``. @@ -878,6 +888,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: @@ -1035,7 +1058,7 @@ PyConfig Incremented by the :option:`-d` command line option. Set to the :envvar:`PYTHONDEBUG` environment variable value. - Need a :ref:`debug build of Python ` (the ``Py_DEBUG`` macro + Needs a :ref:`debug build of Python ` (the ``Py_DEBUG`` macro must be defined). Default: ``0``. @@ -1087,6 +1110,7 @@ PyConfig Set by the :option:`-X pycache_prefix=PATH <-X>` command line option and the :envvar:`PYTHONPYCACHEPREFIX` environment variable. + The command-line option takes precedence. If ``NULL``, :data:`sys.pycache_prefix` is set to ``None``. @@ -1130,13 +1154,27 @@ PyConfig Default: ``NULL``. + .. c:member:: wchar_t* run_presite + + ``package.module`` path to module that should be imported before + ``site.py`` is run. + + Set by the :option:`-X presite=package.module <-X>` command-line + option and the :envvar:`PYTHON_PRESITE` environment variable. + The command-line option takes precedence. + + Needs a :ref:`debug build of Python ` (the ``Py_DEBUG`` macro + must be defined). + + Default: ``NULL``. + .. c:member:: int show_ref_count - Show total reference count at exit (excluding immortal objects)? + Show total reference count at exit (excluding :term:`immortal` objects)? Set to ``1`` by :option:`-X showrefcount <-X>` command line option. - Need a :ref:`debug build of Python ` (the ``Py_REF_DEBUG`` + Needs a :ref:`debug build of Python ` (the ``Py_REF_DEBUG`` macro must be defined). Default: ``0``. diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index c15cecd41b89d1..c8b64bad702f50 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -128,6 +128,30 @@ List Objects list is not supported. +.. c:function:: int PyList_Extend(PyObject *list, PyObject *iterable) + + Extend *list* with the contents of *iterable*. This is the same as + ``PyList_SetSlice(list, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, iterable)`` + and analogous to ``list.extend(iterable)`` or ``list += iterable``. + + Raise an exception and return ``-1`` if *list* is not a :class:`list` + object. Return 0 on success. + + .. versionadded:: 3.13 + + +.. c:function:: int PyList_Clear(PyObject *list) + + Remove all items from *list*. This is the same as + ``PyList_SetSlice(list, 0, PY_SSIZE_T_MAX, NULL)`` and analogous to + ``list.clear()`` or ``del list[:]``. + + Raise an exception and return ``-1`` if *list* is not a :class:`list` + object. Return 0 on success. + + .. versionadded:: 3.13 + + .. c:function:: int PyList_Sort(PyObject *list) Sort the items of *list* in place. Return ``0`` on success, ``-1`` on diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 1df8c2b911ca8f..1f392e55078e77 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -391,6 +391,8 @@ Legend: * ``malloc``: system allocators from the standard C library, C functions: :c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`. * ``pymalloc``: :ref:`pymalloc memory allocator `. +* ``mimalloc``: :ref:`mimalloc memory allocator `. The pymalloc + allocator will be used if mimalloc support isn't available. * "+ debug": with :ref:`debug hooks on the Python memory allocators `. * "Debug build": :ref:`Python build in debug mode `. @@ -491,18 +493,18 @@ 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. @@ -626,7 +628,8 @@ The pymalloc allocator Python has a *pymalloc* allocator optimized for small objects (smaller or equal to 512 bytes) with a short lifetime. It uses memory mappings called "arenas" -with a fixed size of 256 KiB. It falls back to :c:func:`PyMem_RawMalloc` and +with a fixed size of either 256 KiB on 32-bit platforms or 1 MiB on 64-bit +platforms. 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 @@ -671,6 +674,16 @@ Customize pymalloc Arena Allocator Set the arena allocator. +.. _mimalloc: + +The mimalloc allocator +====================== + +.. versionadded:: 3.13 + +Python supports the mimalloc allocator when the underlying platform support is available. +mimalloc "is a general purpose allocator with excellent performance characteristics. +Initially developed by Daan Leijen for the runtime systems of the Koka and Lean languages." tracemalloc C API ================= diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst index dd8bfb56104251..f1941fc4bc4e85 100644 --- a/Doc/c-api/none.rst +++ b/Doc/c-api/none.rst @@ -16,10 +16,10 @@ same reason. .. c:var:: PyObject* Py_None The Python ``None`` object, denoting lack of value. This object has no methods - and is `immortal `_. + and is :term:`immortal`. -.. versionchanged:: 3.12 - :c:data:`Py_None` is immortal. + .. versionchanged:: 3.12 + :c:data:`Py_None` is :term:`immortal`. .. c:macro:: Py_RETURN_NONE diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index bf55b5788efa47..a4e3e74861a315 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -489,3 +489,21 @@ Object Protocol :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 118af7a1a8cf90..75e1d46474f1e7 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -17,7 +17,7 @@ of Python objects. 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 + objects are :term:`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. @@ -34,9 +34,10 @@ of Python objects. Set the object *o* reference counter to *refcnt*. - Note that this function has no effect on - `immortal `_ - objects. + On :ref:`Python build with Free Threading `, if + *refcnt* is larger than ``UINT32_MAX``, the object is made :term:`immortal`. + + This function has no effect on :term:`immortal` objects. .. versionadded:: 3.9 @@ -49,6 +50,8 @@ of Python objects. Indicate taking a new :term:`strong reference` to object *o*, indicating it is in use and should not be destroyed. + This function has no effect on :term:`immortal` objects. + 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`. @@ -113,6 +116,8 @@ of Python objects. Release a :term:`strong reference` to object *o*, indicating the reference is no longer used. + This function has no effect on :term:`immortal` objects. + Once the last :term:`strong reference` is released (i.e. the object's reference count reaches 0), the object's type's deallocation diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index 1e8a09509032f5..cba823aa027bd6 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -147,7 +147,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes. Return ``1`` if found and removed, ``0`` if not found (no action taken), and ``-1`` if an 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` + :exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`~frozenset.discard` method, this function does not automatically convert unhashable sets into temporary frozensets. Raise :exc:`SystemError` if *set* is not an instance of :class:`set` or its subtype. @@ -163,4 +163,6 @@ subtypes but not for instances of :class:`frozenset` or its subtypes. .. c:function:: int PySet_Clear(PyObject *set) - Empty an existing set of all elements. + Empty an existing set of all elements. Return ``0`` on + success. Return ``-1`` and 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 9e880c6b7f25ad..27a1757c745d8b 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -119,8 +119,7 @@ Ellipsis Object .. c:var:: PyObject *Py_Ellipsis The Python ``Ellipsis`` object. This object has no methods. Like - :c:data:`Py_None`, it is an `immortal `_. - singleton object. + :c:data:`Py_None`, it is an :term:`immortal` singleton object. .. versionchanged:: 3.12 :c:data:`Py_Ellipsis` is immortal. diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 747cfa62294c21..7d82f7839dfcd7 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -406,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 @@ -415,15 +419,15 @@ Accessing attributes of extension types The string should be static, no copy is made of it. - .. c:member:: Py_ssize_t offset - - The offset in bytes that the member is located on the type’s object struct. - .. c:member:: int type The type of the member in the C struct. See :ref:`PyMemberDef-types` for the possible values. + .. c:member:: Py_ssize_t offset + + The offset in bytes that the member is located on the type’s object struct. + .. c:member:: int flags Zero or more of the :ref:`PyMemberDef-flags`, combined using bitwise OR. @@ -588,7 +592,7 @@ Macro name C type Python type (*): Zero-terminated, UTF8-encoded C string. With :c:macro:`!Py_T_STRING` the C representation is a pointer; - with :c:macro:`!Py_T_STRING_INLINE` the string is stored directly + with :c:macro:`!Py_T_STRING_INPLACE` the string is stored directly in the structure. (**): String of length 1. Only ASCII is accepted. diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index aed625c5f6cdae..e3c54b075114ff 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -291,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 @@ -312,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. diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 0f58326f6c06b7..5aaa8147dd3176 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -461,21 +461,34 @@ 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`: - - * :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` + 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_vectorcall` - * :c:member:`~PyTypeObject.tp_weaklistoffset` - (use :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead) - * :c:member:`~PyTypeObject.tp_dictoffset` - (use :c:macro:`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. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 1fa3f2a6f53735..8a26f237652d12 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -343,13 +343,13 @@ slot typedefs | | :c:type:`PyTypeObject` * | | | | :c:type:`Py_ssize_t` | | +-----------------------------+-----------------------------+----------------------+ -| :c:type:`destructor` | void * | void | +| :c:type:`destructor` | :c:type:`PyObject` * | void | +-----------------------------+-----------------------------+----------------------+ | :c:type:`freefunc` | void * | void | +-----------------------------+-----------------------------+----------------------+ | :c:type:`traverseproc` | .. line-block:: | int | | | | | -| | void * | | +| | :c:type:`PyObject` * | | | | :c:type:`visitproc` | | | | void * | | +-----------------------------+-----------------------------+----------------------+ @@ -426,7 +426,7 @@ slot typedefs | | :c:type:`PyObject` * | | | | :c:type:`Py_buffer` * | | +-----------------------------+-----------------------------+----------------------+ -| :c:type:`inquiry` | void * | int | +| :c:type:`inquiry` | :c:type:`PyObject` * | int | +-----------------------------+-----------------------------+----------------------+ | :c:type:`unaryfunc` | .. line-block:: | :c:type:`PyObject` * | | | | | @@ -1131,6 +1131,9 @@ and :c:data:`PyType_Type` effectively act as defaults.) 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 **Inheritance:** @@ -1368,6 +1371,23 @@ and :c:data:`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 @@ -1451,6 +1471,12 @@ and :c:data:`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 @@ -1801,7 +1827,7 @@ and :c:data:`PyType_Type` effectively act as defaults.) field is ``NULL`` then no :attr:`~object.__dict__` gets created for instances. If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit is set in the - :c:member:`~PyTypeObject.tp_dict` field, then + :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. diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 2a2cb1b8c458e7..5541eaa521803b 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -75,19 +75,19 @@ Python: The following APIs are C macros and static inlined functions for fast checks and access to internal read-only data of Unicode objects: -.. c:function:: int PyUnicode_Check(PyObject *o) +.. c:function:: int PyUnicode_Check(PyObject *obj) - Return true if the object *o* is a Unicode object or an instance of a Unicode + Return true if the object *obj* is a Unicode object or an instance of a Unicode subtype. This function always succeeds. -.. c:function:: int PyUnicode_CheckExact(PyObject *o) +.. c:function:: int PyUnicode_CheckExact(PyObject *obj) - Return true if the object *o* is a Unicode object, but not an instance of a + Return true if the object *obj* is a Unicode object, but not an instance of a subtype. This function always succeeds. -.. c:function:: int PyUnicode_READY(PyObject *o) +.. c:function:: int PyUnicode_READY(PyObject *unicode) Returns ``0``. This API is kept only for backward compatibility. @@ -97,17 +97,17 @@ access to internal read-only data of Unicode objects: This API does nothing since Python 3.12. -.. c:function:: Py_ssize_t PyUnicode_GET_LENGTH(PyObject *o) +.. c:function:: Py_ssize_t PyUnicode_GET_LENGTH(PyObject *unicode) - Return the length of the Unicode string, in code points. *o* has to be a + Return the length of the Unicode string, in code points. *unicode* has to be a Unicode object in the "canonical" representation (not checked). .. versionadded:: 3.3 -.. c:function:: Py_UCS1* PyUnicode_1BYTE_DATA(PyObject *o) - Py_UCS2* PyUnicode_2BYTE_DATA(PyObject *o) - Py_UCS4* PyUnicode_4BYTE_DATA(PyObject *o) +.. c:function:: Py_UCS1* PyUnicode_1BYTE_DATA(PyObject *unicode) + Py_UCS2* PyUnicode_2BYTE_DATA(PyObject *unicode) + Py_UCS4* PyUnicode_4BYTE_DATA(PyObject *unicode) Return a pointer to the canonical representation cast to UCS1, UCS2 or UCS4 integer types for direct character access. No checks are performed if the @@ -129,18 +129,18 @@ access to internal read-only data of Unicode objects: ``PyUnicode_WCHAR_KIND`` has been removed. -.. c:function:: int PyUnicode_KIND(PyObject *o) +.. c:function:: int PyUnicode_KIND(PyObject *unicode) Return one of the PyUnicode kind constants (see above) that indicate how many - bytes per character this Unicode object uses to store its data. *o* has to + bytes per character this Unicode object uses to store its data. *unicode* has to be a Unicode object in the "canonical" representation (not checked). .. versionadded:: 3.3 -.. c:function:: void* PyUnicode_DATA(PyObject *o) +.. c:function:: void* PyUnicode_DATA(PyObject *unicode) - Return a void pointer to the raw Unicode buffer. *o* has to be a Unicode + Return a void pointer to the raw Unicode buffer. *unicode* has to be a Unicode object in the "canonical" representation (not checked). .. versionadded:: 3.3 @@ -168,25 +168,25 @@ access to internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: Py_UCS4 PyUnicode_READ_CHAR(PyObject *o, Py_ssize_t index) +.. c:function:: Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index) - Read a character from a Unicode object *o*, which must be in the "canonical" + Read a character from a Unicode object *unicode*, which must be in the "canonical" representation. This is less efficient than :c:func:`PyUnicode_READ` if you do multiple consecutive reads. .. versionadded:: 3.3 -.. c:function:: Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *o) +.. c:function:: Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *unicode) Return the maximum code point that is suitable for creating another string - based on *o*, which must be in the "canonical" representation. This is + based on *unicode*, which must be in the "canonical" representation. This is always an approximation but more efficient than iterating over the string. .. versionadded:: 3.3 -.. c:function:: int PyUnicode_IsIdentifier(PyObject *o) +.. c:function:: int PyUnicode_IsIdentifier(PyObject *unicode) Return ``1`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. Return ``0`` otherwise. @@ -358,9 +358,9 @@ APIs: .. versionadded:: 3.3 -.. c:function:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) +.. c:function:: PyObject* PyUnicode_FromStringAndSize(const char *str, Py_ssize_t size) - Create a Unicode object from the char buffer *u*. The bytes will be + Create a Unicode object from the char buffer *str*. The bytes will be interpreted as being UTF-8 encoded. The buffer is copied into the new object. The return value might be a shared object, i.e. modification of the data is @@ -369,16 +369,16 @@ APIs: This function raises :exc:`SystemError` when: * *size* < 0, - * *u* is ``NULL`` and *size* > 0 + * *str* is ``NULL`` and *size* > 0 .. versionchanged:: 3.12 - *u* == ``NULL`` with *size* > 0 is not allowed anymore. + *str* == ``NULL`` with *size* > 0 is not allowed anymore. -.. c:function:: PyObject *PyUnicode_FromString(const char *u) +.. c:function:: PyObject *PyUnicode_FromString(const char *str) Create a Unicode object from a UTF-8 encoded null-terminated char buffer - *u*. + *str*. .. c:function:: PyObject* PyUnicode_FromFormat(const char *format, ...) @@ -646,29 +646,29 @@ APIs: .. versionadded:: 3.3 -.. c:function:: PyObject* PyUnicode_Substring(PyObject *str, Py_ssize_t start, \ +.. c:function:: PyObject* PyUnicode_Substring(PyObject *unicode, Py_ssize_t start, \ Py_ssize_t end) - Return a substring of *str*, from character index *start* (included) to + Return a substring of *unicode*, from character index *start* (included) to character index *end* (excluded). Negative indices are not supported. .. versionadded:: 3.3 -.. c:function:: Py_UCS4* PyUnicode_AsUCS4(PyObject *u, Py_UCS4 *buffer, \ +.. c:function:: Py_UCS4* PyUnicode_AsUCS4(PyObject *unicode, Py_UCS4 *buffer, \ Py_ssize_t buflen, int copy_null) - Copy the string *u* into a UCS4 buffer, including a null character, if + Copy the string *unicode* into a UCS4 buffer, including a null character, if *copy_null* is set. Returns ``NULL`` and sets an exception on error (in particular, a :exc:`SystemError` if *buflen* is smaller than the length of - *u*). *buffer* is returned on success. + *unicode*). *buffer* is returned on success. .. versionadded:: 3.3 -.. c:function:: Py_UCS4* PyUnicode_AsUCS4Copy(PyObject *u) +.. c:function:: Py_UCS4* PyUnicode_AsUCS4Copy(PyObject *unicode) - Copy the string *u* into a new UCS4 buffer that is allocated using + Copy the string *unicode* into a new UCS4 buffer that is allocated using :c:func:`PyMem_Malloc`. If this fails, ``NULL`` is returned with a :exc:`MemoryError` set. The returned buffer always has an extra null code point appended. @@ -683,7 +683,7 @@ The current locale encoding can be used to decode text from the operating system. .. c:function:: PyObject* PyUnicode_DecodeLocaleAndSize(const char *str, \ - Py_ssize_t len, \ + Py_ssize_t length, \ const char *errors) Decode a string from UTF-8 on Android and VxWorks, or from the current @@ -788,7 +788,7 @@ conversion function: Accepts a :term:`path-like object`. -.. c:function:: PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) +.. c:function:: PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *str, Py_ssize_t size) Decode a string from the :term:`filesystem encoding and error handler`. @@ -804,7 +804,7 @@ conversion function: handler>` is now used. -.. c:function:: PyObject* PyUnicode_DecodeFSDefault(const char *s) +.. c:function:: PyObject* PyUnicode_DecodeFSDefault(const char *str) Decode a null-terminated string from the :term:`filesystem encoding and error handler`. @@ -841,17 +841,17 @@ wchar_t Support :c:type:`wchar_t` support for platforms which support it: -.. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) +.. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *wstr, Py_ssize_t size) - Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*. + Create a Unicode object from the :c:type:`wchar_t` buffer *wstr* of the given *size*. Passing ``-1`` as the *size* indicates that the function must itself compute the length, - using wcslen. + using :c:func:`!wcslen`. Return ``NULL`` on failure. -.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) +.. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *wstr, Py_ssize_t size) - Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most + Copy the Unicode object contents into the :c:type:`wchar_t` buffer *wstr*. 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*` @@ -915,10 +915,10 @@ Generic Codecs These are the generic codec APIs: -.. c:function:: PyObject* PyUnicode_Decode(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_Decode(const char *str, Py_ssize_t size, \ const char *encoding, const char *errors) - Create a Unicode object by decoding *size* bytes of the encoded string *s*. + Create a Unicode object by decoding *size* bytes of the encoded string *str*. *encoding* and *errors* have the same meaning as the parameters of the same name in the :func:`str` built-in function. The codec to be used is looked up using the Python codec registry. Return ``NULL`` if an exception was raised by @@ -941,13 +941,13 @@ UTF-8 Codecs These are the UTF-8 codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeUTF8(const char *s, Py_ssize_t size, const char *errors) +.. c:function:: PyObject* PyUnicode_DecodeUTF8(const char *str, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string - *s*. Return ``NULL`` if an exception was raised by the codec. + *str*. Return ``NULL`` if an exception was raised by the codec. -.. c:function:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *str, Py_ssize_t size, \ const char *errors, Py_ssize_t *consumed) If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF8`. If @@ -971,8 +971,8 @@ These are the UTF-8 codec APIs: returned buffer always has an extra null byte appended (not included in *size*), regardless of whether there are any other null code points. - In the case of an error, ``NULL`` is returned with an exception set and no - *size* is stored. + On error, set an exception, set *size* to ``-1`` (if it's not NULL) and + return ``NULL``. This caches the UTF-8 representation of the string in the Unicode object, and subsequent calls will return a pointer to the same buffer. The caller is not @@ -1004,7 +1004,7 @@ UTF-32 Codecs These are the UTF-32 codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeUTF32(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeUTF32(const char *str, Py_ssize_t size, \ const char *errors, int *byteorder) Decode *size* bytes from a UTF-32 encoded buffer string and return the @@ -1031,7 +1031,7 @@ These are the UTF-32 codec APIs: Return ``NULL`` if an exception was raised by the codec. -.. c:function:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeUTF32Stateful(const char *str, Py_ssize_t size, \ const char *errors, int *byteorder, Py_ssize_t *consumed) If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF32`. If @@ -1054,7 +1054,7 @@ UTF-16 Codecs These are the UTF-16 codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeUTF16(const char *str, Py_ssize_t size, \ const char *errors, int *byteorder) Decode *size* bytes from a UTF-16 encoded buffer string and return the @@ -1082,7 +1082,7 @@ These are the UTF-16 codec APIs: Return ``NULL`` if an exception was raised by the codec. -.. c:function:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *str, Py_ssize_t size, \ const char *errors, int *byteorder, Py_ssize_t *consumed) If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF16`. If @@ -1105,13 +1105,13 @@ UTF-7 Codecs These are the UTF-7 codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeUTF7(const char *s, Py_ssize_t size, const char *errors) +.. c:function:: PyObject* PyUnicode_DecodeUTF7(const char *str, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the UTF-7 encoded string - *s*. Return ``NULL`` if an exception was raised by the codec. + *str*. Return ``NULL`` if an exception was raised by the codec. -.. c:function:: PyObject* PyUnicode_DecodeUTF7Stateful(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeUTF7Stateful(const char *str, Py_ssize_t size, \ const char *errors, Py_ssize_t *consumed) If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeUTF7`. If @@ -1126,11 +1126,11 @@ Unicode-Escape Codecs These are the "Unicode Escape" codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *s, \ +.. c:function:: PyObject* PyUnicode_DecodeUnicodeEscape(const char *str, \ Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded - string *s*. Return ``NULL`` if an exception was raised by the codec. + string *str*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) @@ -1146,11 +1146,11 @@ Raw-Unicode-Escape Codecs These are the "Raw Unicode Escape" codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *s, \ +.. c:function:: PyObject* PyUnicode_DecodeRawUnicodeEscape(const char *str, \ Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape - encoded string *s*. Return ``NULL`` if an exception was raised by the codec. + encoded string *str*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) @@ -1167,10 +1167,10 @@ These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode ordinals and only these are accepted by the codecs during encoding. -.. c:function:: PyObject* PyUnicode_DecodeLatin1(const char *s, Py_ssize_t size, const char *errors) +.. c:function:: PyObject* PyUnicode_DecodeLatin1(const char *str, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string - *s*. Return ``NULL`` if an exception was raised by the codec. + *str*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) @@ -1187,10 +1187,10 @@ These are the ASCII codec APIs. Only 7-bit ASCII data is accepted. All other codes generate errors. -.. c:function:: PyObject* PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors) +.. c:function:: PyObject* PyUnicode_DecodeASCII(const char *str, Py_ssize_t size, const char *errors) Create a Unicode object by decoding *size* bytes of the ASCII encoded string - *s*. Return ``NULL`` if an exception was raised by the codec. + *str*. Return ``NULL`` if an exception was raised by the codec. .. c:function:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) @@ -1211,10 +1211,10 @@ decode characters. The mapping objects provided must support the These are the mapping codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeCharmap(const char *data, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeCharmap(const char *str, Py_ssize_t length, \ PyObject *mapping, const char *errors) - Create a Unicode object by decoding *size* bytes of the encoded string *s* + Create a Unicode object by decoding *size* bytes of the encoded string *str* using the given *mapping* object. Return ``NULL`` if an exception was raised by the codec. @@ -1241,7 +1241,7 @@ These are the mapping codec APIs: The following codec API is special in that maps Unicode to Unicode. -.. c:function:: PyObject* PyUnicode_Translate(PyObject *str, PyObject *table, const char *errors) +.. c:function:: PyObject* PyUnicode_Translate(PyObject *unicode, PyObject *table, const char *errors) Translate a string by applying a character mapping table to it and return the resulting Unicode object. Return ``NULL`` if an exception was raised by the @@ -1266,13 +1266,13 @@ use the Win32 MBCS converters to implement the conversions. Note that MBCS (or DBCS) is a class of encodings, not just one. The target encoding is defined by the user settings on the machine running the codec. -.. c:function:: PyObject* PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors) +.. c:function:: PyObject* PyUnicode_DecodeMBCS(const char *str, Py_ssize_t size, const char *errors) - Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. + Create a Unicode object by decoding *size* bytes of the MBCS encoded string *str*. Return ``NULL`` if an exception was raised by the codec. -.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeMBCSStateful(const char *str, Py_ssize_t size, \ const char *errors, Py_ssize_t *consumed) If *consumed* is ``NULL``, behave like :c:func:`PyUnicode_DecodeMBCS`. If @@ -1318,7 +1318,7 @@ They all return ``NULL`` or ``-1`` if an exception occurs. Concat two strings giving a new Unicode string. -.. c:function:: PyObject* PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) +.. c:function:: PyObject* PyUnicode_Split(PyObject *unicode, PyObject *sep, Py_ssize_t maxsplit) Split a string giving a list of Unicode strings. If *sep* is ``NULL``, splitting will be done at all whitespace substrings. Otherwise, splits occur at the given @@ -1326,10 +1326,10 @@ They all return ``NULL`` or ``-1`` if an exception occurs. set. Separators are not included in the resulting list. -.. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) +.. c:function:: PyObject* PyUnicode_Splitlines(PyObject *unicode, int keepends) Split a Unicode string at line breaks, returning a list of Unicode strings. - CRLF is considered to be one line break. If *keepend* is ``0``, the line break + CRLF is considered to be one line break. If *keepends* is ``0``, the Line break characters are not included in the resulting strings. @@ -1339,28 +1339,28 @@ They all return ``NULL`` or ``-1`` if an exception occurs. Unicode string. -.. c:function:: Py_ssize_t PyUnicode_Tailmatch(PyObject *str, PyObject *substr, \ +.. c:function:: Py_ssize_t PyUnicode_Tailmatch(PyObject *unicode, PyObject *substr, \ Py_ssize_t start, Py_ssize_t end, int direction) - Return ``1`` if *substr* matches ``str[start:end]`` at the given tail end + Return ``1`` if *substr* matches ``unicode[start:end]`` at the given tail end (*direction* == ``-1`` means to do a prefix match, *direction* == ``1`` a suffix match), ``0`` otherwise. Return ``-1`` if an error occurred. -.. c:function:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, \ +.. c:function:: Py_ssize_t PyUnicode_Find(PyObject *unicode, PyObject *substr, \ Py_ssize_t start, Py_ssize_t end, int direction) - Return the first position of *substr* in ``str[start:end]`` using the given + Return the first position of *substr* in ``unicode[start:end]`` using the given *direction* (*direction* == ``1`` means to do a forward search, *direction* == ``-1`` a backward search). The return value is the index of the first match; a value of ``-1`` indicates that no match was found, and ``-2`` indicates that an error occurred and an exception has been set. -.. c:function:: Py_ssize_t PyUnicode_FindChar(PyObject *str, Py_UCS4 ch, \ +.. c:function:: Py_ssize_t PyUnicode_FindChar(PyObject *unicode, Py_UCS4 ch, \ Py_ssize_t start, Py_ssize_t end, int direction) - Return the first position of the character *ch* in ``str[start:end]`` using + Return the first position of the character *ch* in ``unicode[start:end]`` using the given *direction* (*direction* == ``1`` means to do a forward search, *direction* == ``-1`` a backward search). The return value is the index of the first match; a value of ``-1`` indicates that no match was found, and ``-2`` @@ -1369,20 +1369,20 @@ They all return ``NULL`` or ``-1`` if an exception occurs. .. versionadded:: 3.3 .. versionchanged:: 3.7 - *start* and *end* are now adjusted to behave like ``str[start:end]``. + *start* and *end* are now adjusted to behave like ``unicode[start:end]``. -.. c:function:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, \ +.. c:function:: Py_ssize_t PyUnicode_Count(PyObject *unicode, PyObject *substr, \ Py_ssize_t start, Py_ssize_t end) Return the number of non-overlapping occurrences of *substr* in - ``str[start:end]``. Return ``-1`` if an error occurred. + ``unicode[start:end]``. Return ``-1`` if an error occurred. -.. c:function:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, \ +.. c:function:: PyObject* PyUnicode_Replace(PyObject *unicode, PyObject *substr, \ PyObject *replstr, Py_ssize_t maxcount) - Replace at most *maxcount* occurrences of *substr* in *str* with *replstr* and + Replace at most *maxcount* occurrences of *substr* in *unicode* with *replstr* and return the resulting Unicode object. *maxcount* == ``-1`` means replace all occurrences. @@ -1396,9 +1396,31 @@ They all return ``NULL`` or ``-1`` if an exception occurs. :c:func:`PyErr_Occurred` to check for errors. -.. c:function:: int PyUnicode_CompareWithASCIIString(PyObject *uni, const char *string) +.. c:function:: int PyUnicode_EqualToUTF8AndSize(PyObject *unicode, const char *string, Py_ssize_t size) - Compare a Unicode object, *uni*, with *string* and return ``-1``, ``0``, ``1`` for less + 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 *unicode, const char *string) + + Compare a Unicode object, *unicode*, with *string* and return ``-1``, ``0``, ``1`` for less than, equal, and greater than, respectively. It is best to pass only ASCII-encoded strings, but the function interprets the input string as ISO-8859-1 if it contains non-ASCII characters. @@ -1406,7 +1428,7 @@ They all return ``NULL`` or ``-1`` if an exception occurs. This function does not raise exceptions. -.. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) +.. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) Rich compare two Unicode strings and return one of the following: @@ -1424,29 +1446,29 @@ They all return ``NULL`` or ``-1`` if an exception occurs. ``format % args``. -.. c:function:: int PyUnicode_Contains(PyObject *container, PyObject *element) +.. c:function:: int PyUnicode_Contains(PyObject *unicode, PyObject *substr) - Check whether *element* is contained in *container* and return true or false + Check whether *substr* is contained in *unicode* and return true or false accordingly. - *element* has to coerce to a one element Unicode string. ``-1`` is returned + *substr* has to coerce to a one element Unicode string. ``-1`` is returned if there was an error. -.. c:function:: void PyUnicode_InternInPlace(PyObject **string) +.. c:function:: void PyUnicode_InternInPlace(PyObject **p_unicode) - Intern the argument *\*string* in place. The argument must be the address of a + Intern the argument :c:expr:`*p_unicode` 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 + existing interned string that is the same as :c:expr:`*p_unicode`, it sets :c:expr:`*p_unicode` to 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`). + :c:expr:`*p_unicode` 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.) -.. c:function:: PyObject* PyUnicode_InternFromString(const char *v) +.. c:function:: PyObject* PyUnicode_InternFromString(const char *str) A combination of :c:func:`PyUnicode_FromString` and :c:func:`PyUnicode_InternInPlace`, returning either a new Unicode string diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst index ccbf14e1850f68..48ae54acebe887 100644 --- a/Doc/c-api/utilities.rst +++ b/Doc/c-api/utilities.rst @@ -17,6 +17,7 @@ and parsing function arguments and constructing Python values from C values. marshal.rst arg.rst conversion.rst + hash.rst reflection.rst codec.rst perfmaps.rst diff --git a/Doc/conf.py b/Doc/conf.py index c92ea60ee07094..f2d36fdc70430c 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -24,7 +24,13 @@ 'sphinx.ext.doctest', ] -# Skip if downstream redistributors haven't installed it +# Skip if downstream redistributors haven't installed them +try: + import notfound.extension +except ImportError: + pass +else: + extensions.append('notfound.extension') try: import sphinxext.opengraph except ImportError: @@ -157,6 +163,13 @@ ('envvar', 'USER'), ('envvar', 'USERNAME'), ('envvar', 'USERPROFILE'), + # Deprecated function that was never documented: + ('py:func', 'getargspec'), + ('py:func', 'inspect.getargspec'), + # Undocumented modules that users shouldn't have to worry about + # (implementation details of `os.path`): + ('py:mod', 'ntpath'), + ('py:mod', 'posixpath'), ] # Temporary undocumented names. @@ -288,9 +301,8 @@ "pr_id": os.getenv("READTHEDOCS_VERSION") } -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -html_last_updated_fmt = '%b %d, %Y' +# This 'Last updated on:' timestamp is inserted at the bottom of every page. +html_last_updated_fmt = time.strftime('%b %d, %Y (%H:%M UTC)', time.gmtime()) # Path to find HTML templates. templates_path = ['tools/templates'] 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/data/stable_abi.dat b/Doc/data/stable_abi.dat index c189c78238f40f..811b1bd84d2417 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -388,6 +388,10 @@ function,PyMapping_Values,3.2,, function,PyMem_Calloc,3.7,, function,PyMem_Free,3.2,, function,PyMem_Malloc,3.2,, +function,PyMem_RawCalloc,3.13,, +function,PyMem_RawFree,3.13,, +function,PyMem_RawMalloc,3.13,, +function,PyMem_RawRealloc,3.13,, function,PyMem_Realloc,3.2,, type,PyMemberDef,3.2,,full-abi var,PyMemberDescr_Type,3.2,, @@ -602,6 +606,8 @@ function,PyStructSequence_NewType,3.2,, function,PyStructSequence_SetItem,3.2,, var,PyStructSequence_UnnamedField,3.11,, var,PySuper_Type,3.2,, +function,PySys_Audit,3.13,, +function,PySys_AuditTuple,3.13,, function,PySys_FormatStderr,3.2,, function,PySys_FormatStdout,3.2,, function,PySys_GetObject,3.2,, @@ -755,6 +761,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,, @@ -840,6 +848,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/extending/extending.rst b/Doc/extending/extending.rst index 1ee7f28b2ba220..745fc10a22d161 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -735,7 +735,7 @@ Keyword Parameters for Extension Functions The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows:: int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict, - const char *format, char *kwlist[], ...); + const char *format, char * const *kwlist, ...); The *arg* and *format* parameters are identical to those of the :c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index 9f166eb8a4c3ff..7a92b3257c6cd3 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -296,7 +296,7 @@ An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` table descriptors that are used at runtime is that any attribute defined this way can 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. +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 :c:member:`~PyMethodDef.ml_name` value of ``NULL`` is required. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index a4cd05b0cf019d..601443d5aade94 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -151,9 +151,9 @@ Glossary A :term:`file object` able to read and write :term:`bytes-like objects `. Examples of binary files are files opened in binary mode (``'rb'``, - ``'wb'`` or ``'rb+'``), :data:`sys.stdin.buffer`, - :data:`sys.stdout.buffer`, and instances of :class:`io.BytesIO` and - :class:`gzip.GzipFile`. + ``'wb'`` or ``'rb+'``), :data:`sys.stdin.buffer `, + :data:`sys.stdout.buffer `, and instances of + :class:`io.BytesIO` and :class:`gzip.GzipFile`. See also :term:`text file` for a file object able to read and write :class:`str` objects. @@ -239,7 +239,7 @@ Glossary context manager An object which controls the environment seen in a :keyword:`with` - statement by defining :meth:`__enter__` and :meth:`__exit__` methods. + statement by defining :meth:`~object.__enter__` and :meth:`~object.__exit__` methods. See :pep:`343`. context variable @@ -304,8 +304,9 @@ Glossary :ref:`class definitions ` for more about decorators. descriptor - Any object which defines the methods :meth:`__get__`, :meth:`__set__`, or - :meth:`__delete__`. When a class attribute is a descriptor, its special + Any object which defines the methods :meth:`~object.__get__`, + :meth:`~object.__set__`, or :meth:`~object.__delete__`. + When a class attribute is a descriptor, its special binding behavior is triggered upon attribute lookup. Normally, using *a.b* to get, set or delete an attribute looks up the object named *b* in the class dictionary for *a*, but if *b* is a descriptor, the respective @@ -319,7 +320,8 @@ Glossary dictionary An associative array, where arbitrary keys are mapped to values. The - keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods. + keys can be any object with :meth:`~object.__hash__` and + :meth:`~object.__eq__` methods. Called a hash in Perl. dictionary comprehension @@ -383,7 +385,7 @@ Glossary file object An object exposing a file-oriented API (with methods such as - :meth:`read()` or :meth:`write()`) to an underlying resource. Depending + :meth:`!read` or :meth:`!write`) to an underlying resource. Depending on the way it was created, a file object can mediate access to a real on-disk file or to another type of storage or communication device (for example standard input/output, in-memory buffers, sockets, pipes, @@ -502,7 +504,7 @@ Glossary .. index:: single: generator expression generator expression - An expression that returns an iterator. It looks like a normal expression + An :term:`expression` that returns an :term:`iterator`. It looks like a normal expression followed by a :keyword:`!for` clause defining a loop variable, range, and an optional :keyword:`!if` clause. The combined expression generates values for an enclosing function:: @@ -559,8 +561,9 @@ Glossary hashable An object is *hashable* if it has a hash value which never changes during - its lifetime (it needs a :meth:`__hash__` method), and can be compared to - other objects (it needs an :meth:`__eq__` method). Hashable objects which + its lifetime (it needs a :meth:`~object.__hash__` method), and can be + compared to other objects (it needs an :meth:`~object.__eq__` method). + Hashable objects which compare equal must have the same hash value. Hashability makes an object usable as a dictionary key and a set member, @@ -579,6 +582,16 @@ Glossary :ref:`idle` is a basic editor and interpreter environment which ships with the standard distribution of Python. + immortal + If an object is immortal, its reference count is never modified, and + therefore it is never deallocated. + + Built-in strings and singletons are immortal objects. For example, + :const:`True` and :const:`None` singletons are immmortal. + + See `PEP 683 – Immortal Objects, Using a Fixed Refcount + `_ for more information. + immutable An object with a fixed value. Immutable objects include numbers, strings and tuples. Such an object cannot be altered. A new object has to @@ -636,7 +649,8 @@ Glossary iterables include all sequence types (such as :class:`list`, :class:`str`, and :class:`tuple`) and some non-sequence types like :class:`dict`, :term:`file objects `, and objects of any classes you define - with an :meth:`__iter__` method or with a :meth:`__getitem__` method + with an :meth:`~iterator.__iter__` method or with a + :meth:`~object.__getitem__` method that implements :term:`sequence` semantics. Iterables can be @@ -645,7 +659,7 @@ Glossary as an argument to the built-in function :func:`iter`, it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call - :func:`iter` or deal with iterator objects yourself. The ``for`` + :func:`iter` or deal with iterator objects yourself. The :keyword:`for` statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also :term:`iterator`, :term:`sequence`, and :term:`generator`. @@ -656,8 +670,8 @@ Glossary :func:`next`) return successive items in the stream. When no more data are available a :exc:`StopIteration` exception is raised instead. At this point, the iterator object is exhausted and any further calls to its - :meth:`__next__` method just raise :exc:`StopIteration` again. Iterators - are required to have an :meth:`__iter__` method that returns the iterator + :meth:`!__next__` method just raise :exc:`StopIteration` again. Iterators + are required to have an :meth:`~iterator.__iter__` method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a @@ -671,7 +685,7 @@ Glossary .. impl-detail:: CPython does not consistently apply the requirement that an iterator - define :meth:`__iter__`. + define :meth:`~iterator.__iter__`. key function A key function or collation function is a callable that returns a value @@ -865,7 +879,8 @@ Glossary Old name for the flavor of classes now used for all class objects. In earlier Python versions, only new-style classes could use Python's newer, versatile features like :attr:`~object.__slots__`, descriptors, - properties, :meth:`__getattribute__`, class methods, and static methods. + properties, :meth:`~object.__getattribute__`, class methods, and static + methods. object Any data with state (attributes or value) and defined behavior @@ -945,7 +960,7 @@ Glossary finders implement. path entry hook - A callable on the :data:`sys.path_hook` list which returns a :term:`path + A callable on the :data:`sys.path_hooks` list which returns a :term:`path entry finder` if it knows how to find modules on a specific :term:`path entry`. @@ -1056,7 +1071,7 @@ Glossary reference count The number of references to an object. When the reference count of an object drops to zero, it is deallocated. Some objects are - "immortal" and have reference counts that are never modified, and + :term:`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 @@ -1078,19 +1093,19 @@ Glossary sequence An :term:`iterable` which supports efficient element access using integer - indices via the :meth:`__getitem__` special method and defines a - :meth:`__len__` method that returns the length of the sequence. + indices via the :meth:`~object.__getitem__` special method and defines a + :meth:`~object.__len__` method that returns the length of the sequence. Some built-in sequence types are :class:`list`, :class:`str`, :class:`tuple`, and :class:`bytes`. Note that :class:`dict` also - supports :meth:`__getitem__` and :meth:`__len__`, but is considered a + supports :meth:`~object.__getitem__` and :meth:`!__len__`, but is considered a mapping rather than a sequence because the lookups use arbitrary :term:`immutable` keys rather than integers. The :class:`collections.abc.Sequence` abstract base class defines a much richer interface that goes beyond just - :meth:`__getitem__` and :meth:`__len__`, adding :meth:`count`, - :meth:`index`, :meth:`__contains__`, and - :meth:`__reversed__`. Types that implement this expanded + :meth:`~object.__getitem__` and :meth:`~object.__len__`, adding + :meth:`count`, :meth:`index`, :meth:`~object.__contains__`, and + :meth:`~object.__reversed__`. Types that implement this expanded interface can be registered explicitly using :func:`~abc.ABCMeta.register`. @@ -1138,6 +1153,11 @@ Glossary an :term:`expression` or one of several constructs with a keyword, such as :keyword:`if`, :keyword:`while` or :keyword:`for`. + static type checker + An external tool that reads Python code and analyzes it, looking for + issues such as incorrect types. See also :term:`type hints ` + and the :mod:`typing` module. + strong reference In Python's C API, a strong reference is a reference to an object which is owned by the code holding the reference. The strong @@ -1214,8 +1234,8 @@ Glossary attribute, or a function parameter or return value. Type hints are optional and are not enforced by Python but - they are useful to static type analysis tools, and aid IDEs with code - completion and refactoring. + they are useful to :term:`static type checkers `. + They can also aid IDEs with code completion and refactoring. Type hints of global variables, class attributes, and functions, but not local variables, can be accessed using diff --git a/Doc/howto/annotations.rst b/Doc/howto/annotations.rst index 1134686c947d66..be8c7e6c827f57 100644 --- a/Doc/howto/annotations.rst +++ b/Doc/howto/annotations.rst @@ -153,7 +153,8 @@ on an arbitrary object ``o``: 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`. + :attr:`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`. diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 92701b09c3bca2..060977246149cf 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,2070 +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 - -**Source code:** :source:`Tools/clinic/clinic.py`. - -.. topic:: Abstract - - Argument Clinic is a preprocessor for CPython C files. - It was introduced in Python 3.4 with :pep:`436`, - in order to provide introspection signatures, - and to generate performant and tailor-made boilerplate code - for argument parsing in CPython builtins, - module level functions, and class methods. - This document is divided in four major sections: - - * :ref:`clinic-background` talks about the basic concepts and goals of - Argument Clinic. - * :ref:`clinic-reference` describes the command-line interface and Argument - Clinic terminology. - * :ref:`clinic-tutorial` guides you through all the steps required to - adapt an existing C function to Argument Clinic. - * :ref:`clinic-howtos` details how to handle specific tasks. - - -.. note:: - - 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. - - -.. _clinic-background: - -Background -========== - -Basic concepts --------------- - -When Argument Clinic is run on a file, either via the :ref:`clinic-cli` -or via ``make clinic``, it will scan over the input files looking for -:term:`start lines `: - -.. code-block:: none - - /*[clinic input] - -When it finds one, it reads everything up to the :term:`end line`: - -.. code-block:: none - - [clinic start generated code]*/ - -Everything in between these two lines is Argument Clinic :term:`input`. -When Argument Clinic parses input, it generates :term:`output`. -The output is rewritten into the C file immediately after the input, -followed by a :term:`checksum line`. -All of these lines, including the :term:`start line` and :term:`checksum line`, -are collectively called an Argument Clinic :term:`block`: - -.. code-block:: none - - /*[clinic input] - ... clinic input goes here ... - [clinic start generated code]*/ - ... clinic output goes here ... - /*[clinic end generated code: ...]*/ - -If you run Argument Clinic on the same file a second time, Argument Clinic -will discard the old :term:`output` and write out the new output with a fresh -:term:`checksum line`. -If the :term:`input` hasn't changed, the output won't change either. - -.. note:: - - You should never modify the output of an Argument Clinic block, - as any change will be lost in future Argument Clinic runs; - Argument Clinic will detect an output checksum mismatch and regenerate the - correct output. - If you are not happy with the generated output, - you should instead change the input until it produces the output you want. - - -.. _clinic-reference: - -Reference -========= - - -.. _clinic-terminology: - -Terminology ------------ - -.. glossary:: - - start line - The line ``/*[clinic input]``. - This line marks the beginning of Argument Clinic input. - Note that the *start line* opens a C block comment. - - end line - The line ``[clinic start generated code]*/``. - The *end line* marks the _end_ of Argument Clinic :term:`input`, - but at the same time marks the _start_ of Argument Clinic :term:`output`, - thus the text *"clinic start start generated code"* - Note that the *end line* closes the C block comment opened - by the *start line*. - - checksum - A hash to distinguish unique :term:`inputs ` - and :term:`outputs `. - - checksum line - A line that looks like ``/*[clinic end generated code: ...]*/``. - The three dots will be replaced by a :term:`checksum` generated from the - :term:`input`, and a :term:`checksum` generated from the :term:`output`. - The checksum line marks the end of Argument Clinic generated code, - and is used by Argument Clinic to determine if it needs to regenerate - output. - - input - The text between the :term:`start line` and the :term:`end line`. - Note that the start and end lines open and close a C block comment; - the *input* is thus a part of that same C block comment. - - output - The text between the :term:`end line` and the :term:`checksum line`. - - block - All text from the :term:`start line` to the :term:`checksum line` inclusively. - - -.. _clinic-cli: - -Command-line interface ----------------------- - -The Argument Clinic :abbr:`CLI (Command-Line Interface)` is typically used to -process a single source file, like this: - -.. code-block:: shell-session - - $ python3 ./Tools/clinic/clinic.py foo.c - -The CLI supports the following options: - -.. program:: ./Tools/clinic/clinic.py [-h] [-f] [-o OUTPUT] [-v] \ - [--converters] [--make] [--srcdir SRCDIR] [--limited] [FILE ...] - -.. option:: -h, --help - - Print CLI usage. - -.. option:: -f, --force - - Force output regeneration. - -.. option:: -o, --output OUTPUT - - Redirect file output to OUTPUT - -.. option:: -v, --verbose - - Enable verbose mode. - -.. option:: --converters - - Print a list of all supported converters and return converters. - -.. option:: --make - - Walk :option:`--srcdir` to run over all relevant files. - -.. option:: --srcdir SRCDIR - - The directory tree to walk in :option:`--make` mode. - -.. option:: --exclude EXCLUDE - - A file to exclude in :option:`--make` mode. - This option can be given multiple times. - -.. option:: --limited - - Use the :ref:`Limited API ` to parse arguments in the generated C code. - See :ref:`clinic-howto-limited-capi`. - -.. option:: FILE ... - - The list of files to process. - - -.. _clinic-classes: - -Classes for extending Argument Clinic -------------------------------------- - -.. module:: clinic - -.. class:: CConverter - - The base class for all converters. - See :ref:`clinic-howto-custom-converter` for how to subclass this class. - - .. attribute:: type - - The C type to use for this variable. - :attr:`!type` should be a Python string specifying the type, - e.g. ``'int'``. - If this is a pointer type, the type string should end with ``' *'``. - - .. attribute:: default - - The Python default value for this parameter, as a Python value. - Or the magic value ``unspecified`` if there is no default. - - .. attribute:: py_default - - :attr:`!default` as it should appear in Python code, - as a string. - Or ``None`` if there is no default. - - .. attribute:: c_default - - :attr:`!default` as it should appear in C code, - as a string. - Or ``None`` if there is no default. - - .. attribute:: 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. - - .. attribute:: converter - - The name of the C converter function, as a string. - - .. attribute:: 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. - - .. attribute:: 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`. - - -.. _clinic-tutorial: - -Tutorial -======== - -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 :ref:`advanced concepts ` -you'll see later on in the document, -like :ref:`clinic-howto-return-converters` -and :ref:`clinic-howto-self-converter`. -But we'll keep it simple for this walkthrough so you can learn. - -First, make sure you're working with a freshly updated checkout -of the CPython trunk. - -Next, 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 this tutorial, we'll be using -:py:meth:`_pickle.Pickler.dump `. - -If the call to the :c:func:`!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. -(See :ref:`clinic-howto-advanced-converters` for those scenarios.) - -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 -:c:func:`!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. - -Next, add the following boilerplate above the function, -creating our input block:: - - /*[clinic input] - [clinic start generated code]*/ - -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 :py:func:`help` on your builtin in the future, -the first line will be built automatically based on the function's signature. - -Example docstring summary line:: - - /*[clinic input] - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -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. -(See :pep:`257` regarding docstring conventions.) - -Our example docstring consists solely of a summary line, so the sample -code doesn't have to change for this step. - -Now, 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. - -In our example, :mod:`!_pickle` is the module, :py:class:`!Pickler` is the class, -and :py:meth:`!dump` is the method, so the name becomes -:py:meth:`!_pickle.Pickler.dump`:: - - /*[clinic input] - _pickle.Pickler.dump - - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ - -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:: - - /*[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]*/ - -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; -see :ref:`clinic-howto-default-values` for more information. - -Next, 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 :c:func:`PyArg_Parse` format argument and -specify *that* as its converter, as a quoted string. -The "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]*/ - -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. - -:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged. - -Next, 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 parameters as positional-only in Argument Clinic, -add a ``/`` on a line by itself after the last positional-only parameter, -indented the same as the parameter lines. - -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]*/ - -It can be helpful to write a per-parameter docstring for each parameter. -Since per-parameter docstrings are optional, -you can skip this step if you prefer. - -Nevertheless, 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]*/ - -Save and close the file, then run ``Tools/clinic/clinic.py`` on it. -With luck everything worked---your block now has output, -and a :file:`.c.h` file has been generated! -Reload the file in your text editor to see the 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]*/ - - 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 :file:`.c.h` -file. You'll need to include that in your original :file:`.c` file, -typically right after the clinic module block:: - - #include "clinic/_pickle.c.h" - -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, 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. - -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: input=..., output=...]*/ - { - ... - -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; - } - - ... - -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; 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 */ - }; - -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 ``make regen-global-objects`` -to regenerate the list of precompiled identifiers at this point. - -Finally, 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, -except for one difference: :py:func:`inspect.signature` run on your function -should now provide a valid signature! - -Congratulations, you've ported your first function to work with Argument Clinic! - - -.. _clinic-howtos: - -How-to guides -============= - - -How 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 -:py:meth:`pickle.Pickler.dump`, it'd look like this:: - - /*[clinic input] - pickle.Pickler.dump as pickler_dumper - - ... - -The base function would now be named :c:func:`!pickler_dumper`, -and the impl function would now be named :c:func:`!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 :py:func:`range`, which has -an optional argument on the *left* side of its required argument! -Another example is :py:meth:`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 :py:meth:`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 :c:func:`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). - - -.. _clinic-howto-advanced-converters: - -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 :c:var:`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 -:c:func:`!PyArg_Parse*` call by hand, you could theoretically decide at runtime what -encoding string to pass to that call. 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``. - - -.. _clinic-howto-default-values: -.. _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 :py:data:`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 - -:py:data:`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 :py:attr:`!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 -:py:data:`sys.modules`. That's how it can find :py:data:`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. - - -.. _clinic-howto-return-converters: - -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 (c:func:`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:...]*/ - - -.. _clinic-howto-self-converter: - -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 -:class:`!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 -:class:`!self_converter` but overwriting the :py:attr:`!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 :source:`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 -:py:attr:`!__text_signature__`. - -The ``defining_class`` converter is not compatible with :py:meth:`!__init__` -and :py:meth:`!__new__` methods, which cannot use the :c:macro:`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 -:source:`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`. - - -.. _clinic-howto-custom-converter: - -How to write a custom converter -------------------------------- - -A converter is a Python class that inherits from :py:class:`CConverter`. -The main purpose of a custom converter, is for parameters parsed with -the ``O&`` format unit --- parsing such a parameter means calling -a :c:func:`PyArg_ParseTuple` "converter function". - -Your converter class should be named :samp:`{ConverterName}_converter`. -By following this convention, your converter class will be automatically -registered with Argument Clinic, with its *converter name* being the name of -your converter class with the ``_converter`` suffix stripped off. - -Instead of subclassing :py:meth:`!CConverter.__init__`, -write a :py:meth:`!converter_init` method. -:py:meth:`!converter_init` always accepts a *self* parameter. -After *self*, all additional parameters **must** be keyword-only. -Any arguments passed to the converter in Argument Clinic -will be passed along to your :py:meth:`!converter_init` method. -See :py:class:`CConverter` for a list of members you may wish to specify in -your subclass. - -Here's the simplest example of a custom converter, from :source:`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 named ``ssize_t`` to Argument Clinic. -Parameters declared as ``ssize_t`` will be declared with type :c:type:`Py_ssize_t`, -and will be parsed by the ``'O&'`` format unit, -which will call the :c:func:`!ssize_t_converter` converter C 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 :py:class:`!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 :source:`Tools/clinic/clinic.py`, -specifically the implementation of :py:class:`!CReturnConverter` and -all its subclasses. - - -How to convert ``METH_O`` and ``METH_NOARGS`` functions -------------------------------------------------------- - -To convert a function using :c:macro:`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 :c:macro:`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 :c:macro:`METH_O`. - - -How to convert ``tp_new`` and ``tp_init`` functions ---------------------------------------------------- - -You can convert :c:member:`~PyTypeObject.tp_new` and -:c:member:`~PyTypeObject.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 :c:type:`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 :c:type:`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 :file:`_pickle.c` would be written to - :file:`_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 :c:type:`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 :c:type:`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:...]*/ - - -.. _clinic-howto-limited-capi: - -How to use the Limited C API ----------------------------- - -If Argument Clinic :term:`input` is located within a C source file -that contains ``#define Py_LIMITED_API``, Argument Clinic will generate C code -that uses the :ref:`Limited API ` to parse arguments. The -advantage of this is that the generated code will not use private functions. -However, this *can* result in Argument Clinic generating less efficient code -in some cases. The extent of the performance penalty will depend -on the parameters (types, number, etc.). - -.. versionadded:: 3.13 - - -.. _clinic-howto-override-signature: - -How to override the generated signature ---------------------------------------- - -You can use the ``@text_signature`` directive to override the default generated -signature in the docstring. -This can be useful for complex signatures that Argument Clinic cannot handle. -The ``@text_signature`` directive takes one argument: -the custom signature as a string. -The provided signature is copied verbatim to the generated docstring. - -Example from :source:`Objects/codeobject.c`:: - - /*[clinic input] - @text_signature "($self, /, **changes)" - code.replace - * - co_argcount: int(c_default="self->co_argcount") = unchanged - co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged - # etc ... - - Return a copy of the code object with new values for the specified fields. - [clinic start generated output]*/ - -The generated docstring ends up looking like this: - -.. code-block:: none - - replace($self, /, **changes) - -- - - Return a copy of the code object with new values for the specified fields. - - -.. _clinic-howto-deprecate-positional: -.. _clinic-howto-deprecate-keyword: - -How to deprecate passing parameters positionally or by keyword --------------------------------------------------------------- - -Argument Clinic provides syntax that makes it possible to generate code that -deprecates passing :term:`arguments ` for positional-or-keyword -:term:`parameters ` positionally or by keyword. -For example, say we've got a module-level function :py:func:`!foo.myfunc` -that has five parameters: a positional-only parameter *a*, three -positional-or-keyword parameters *b*, *c* and *d*, and a keyword-only -parameter *e*:: - - /*[clinic input] - module foo - myfunc - a: int - / - b: int - c: int - d: int - * - e: int - [clinic start generated output]*/ - -We now want to make the *b* parameter positional-only and the *d* parameter -keyword-only; -however, we'll have to wait two releases before making these changes, -as mandated by Python's backwards-compatibility policy (see :pep:`387`). -For this example, imagine we're in the development phase for Python 3.12: -that means we'll be allowed to introduce deprecation warnings in Python 3.12 -whenever an argument for the *b* parameter is passed by keyword or an argument -for the *d* parameter is passed positionally, and we'll be allowed to make -them positional-only and keyword-only respectively in Python 3.14 at -the earliest. - -We can use Argument Clinic to emit the desired deprecation warnings -using the ``[from ...]`` syntax, by adding the line ``/ [from 3.14]`` right -below the *b* parameter and adding the line ``* [from 3.14]`` right above -the *d* parameter:: - - /*[clinic input] - module foo - myfunc - a: int - / - b: int - / [from 3.14] - c: int - * [from 3.14] - d: int - * - e: int - [clinic start generated output]*/ - -Next, regenerate Argument Clinic code (``make clinic``), -and add unit tests for the new behaviour. - -The generated code will now emit a :exc:`DeprecationWarning` -when an :term:`argument` for the :term:`parameter` *d* is passed positionally -(e.g ``myfunc(1, 2, 3, 4, e=5)``) or an argument for the parameter *b* is -passed by keyword (e.g ``myfunc(1, b=2, c=3, d=4, e=5)``). -C preprocessor directives are also generated for emitting -compiler warnings if the ``[from ...]`` lines have not been removed -from the Argument Clinic input when the deprecation period is over, -which means when the alpha phase of the specified Python version kicks in. - -Let's return to our example and skip ahead two years: -Python 3.14 development has now entered the alpha phase, -but we forgot all about updating the Argument Clinic code -for :py:func:`!myfunc`! -Luckily for us, compiler warnings are now generated: - -.. code-block:: none - - In file included from Modules/foomodule.c:139: - Modules/clinic/foomodule.c.h:139:8: warning: In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings] - # warning "In 'foomodule.c', update the clinic input of 'mymod.myfunc'. [-W#warnings]" - ^ - -We now close the deprecation phase by making *a* positional-only and *c* -keyword-only; -replace the ``/ [from ...]`` line below *b* with the ``/`` from the line -below *a* and the ``* [from ...]`` line above *d* with the ``*`` from -the line above *e*:: - - /*[clinic input] - module foo - myfunc - a: int - b: int - / - c: int - * - d: int - e: int - [clinic start generated output]*/ - -Finally, run ``make clinic`` to regenerate the Argument Clinic code, -and update your unit tests to reflect the new behaviour. .. note:: - If you forget to update your input block during the alpha and beta phases, - the compiler warning will turn into a compiler error when the - release candidate phase begins. + The Argument Clinic How-TO has been moved to the `Python Developer's Guide + `__. diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 1d9424cb735a46..87274a5133d1cf 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -521,11 +521,11 @@ everyday Python programs. Descriptor protocol ------------------- -``descr.__get__(self, obj, type=None) -> value`` +``descr.__get__(self, obj, type=None)`` -``descr.__set__(self, obj, value) -> None`` +``descr.__set__(self, obj, value)`` -``descr.__delete__(self, obj) -> None`` +``descr.__delete__(self, obj)`` That is all there is to it. Define any of these methods and an object is considered a descriptor and can override default behavior upon being looked up @@ -943,6 +943,10 @@ it can be updated: >>> Movie('Star Wars').director 'J.J. Abrams' +.. testcleanup:: + + conn.close() + Pure Python Equivalents ^^^^^^^^^^^^^^^^^^^^^^^ @@ -1009,17 +1013,23 @@ here is a pure Python equivalent: if obj is None: return self if self.fget is None: - raise AttributeError(f"property '{self._name}' has no getter") + raise AttributeError( + f'property {self._name!r} of {type(obj).__name__!r} object has no getter' + ) return self.fget(obj) def __set__(self, obj, value): if self.fset is None: - raise AttributeError(f"property '{self._name}' has no setter") + raise AttributeError( + f'property {self._name!r} of {type(obj).__name__!r} object has no setter' + ) self.fset(obj, value) def __delete__(self, obj): if self.fdel is None: - raise AttributeError(f"property '{self._name}' has no deleter") + raise AttributeError( + f'property {self._name!r} of {type(obj).__name__!r} object has no deleter' + ) self.fdel(obj) def getter(self, fget): @@ -1050,6 +1060,11 @@ here is a pure Python equivalent: def delx(self): del self.__x x = Property(getx, setx, delx, "I'm the 'x' property.") + no_getter = Property(None, setx, delx, "I'm the 'x' property.") + no_setter = Property(getx, None, delx, "I'm the 'x' property.") + no_deleter = Property(getx, setx, None, "I'm the 'x' property.") + no_doc = Property(getx, setx, delx, None) + # Now do it again but use the decorator style @@ -1088,6 +1103,32 @@ here is a pure Python equivalent: >>> hasattr(ccc, 'x') False + >>> cc = CC() + >>> cc.x = 33 + >>> try: + ... cc.no_getter + ... except AttributeError as e: + ... e.args[0] + ... + "property 'no_getter' of 'CC' object has no getter" + + >>> try: + ... cc.no_setter = 33 + ... except AttributeError as e: + ... e.args[0] + ... + "property 'no_setter' of 'CC' object has no setter" + + >>> try: + ... del cc.no_deleter + ... except AttributeError as e: + ... e.args[0] + ... + "property 'no_deleter' of 'CC' object has no deleter" + + >>> CC.no_doc.__doc__ is None + True + The :func:`property` builtin helps whenever a user interface has granted attribute access and then subsequent changes require the intervention of a method. @@ -1141,6 +1182,16 @@ roughly equivalent to: obj = self.__self__ return func(obj, *args, **kwargs) + def __getattribute__(self, name): + "Emulate method_getset() in Objects/classobject.c" + if name == '__doc__': + return self.__func__.__doc__ + return object.__getattribute__(self, name) + + def __getattr__(self, name): + "Emulate method_getattro() in Objects/classobject.c" + return getattr(self.__func__, name) + To support automatic creation of methods, functions include the :meth:`__get__` method for binding methods during attribute access. This means that functions are non-data descriptors that return bound methods @@ -1291,7 +1342,8 @@ Using the non-data descriptor protocol, a pure Python version of The :func:`functools.update_wrapper` call adds a ``__wrapped__`` attribute that refers to the underlying function. Also it carries forward the attributes necessary to make the wrapper look like the wrapped -function: ``__name__``, ``__qualname__``, ``__doc__``, and ``__annotations__``. +function: :attr:`~function.__name__`, :attr:`~function.__qualname__`, +:attr:`~function.__doc__`, and :attr:`~function.__annotations__`. .. testcode:: :hide: @@ -1420,10 +1472,6 @@ Using the non-data descriptor protocol, a pure Python version of def __get__(self, obj, cls=None): if cls is None: cls = type(obj) - if hasattr(type(self.f), '__get__'): - # This code path was added in Python 3.9 - # and was deprecated in Python 3.11. - return self.f.__get__(cls, cls) return MethodType(self.f, cls) .. testcode:: @@ -1436,11 +1484,6 @@ Using the non-data descriptor protocol, a pure Python version of "Class method that returns a tuple" return (cls.__name__, x, y) - @ClassMethod - @property - def __doc__(cls): - return f'A doc for {cls.__name__!r}' - .. doctest:: :hide: @@ -1453,10 +1496,6 @@ Using the non-data descriptor protocol, a pure Python version of >>> t.cm(11, 22) ('T', 11, 22) - # Check the alternate path for chained descriptors - >>> T.__doc__ - "A doc for 'T'" - # Verify that T uses our emulation >>> type(vars(T)['cm']).__name__ 'ClassMethod' @@ -1481,29 +1520,12 @@ Using the non-data descriptor protocol, a pure Python version of ('T', 11, 22) -The code path for ``hasattr(type(self.f), '__get__')`` was added in -Python 3.9 and makes it possible for :func:`classmethod` to support -chained decorators. For example, a classmethod and property could be -chained together. In Python 3.11, this functionality was deprecated. - -.. testcode:: - - class G: - @classmethod - @property - def __doc__(cls): - return f'A doc for {cls.__name__!r}' - -.. doctest:: - - >>> G.__doc__ - "A doc for 'G'" - The :func:`functools.update_wrapper` call in ``ClassMethod`` adds a ``__wrapped__`` attribute that refers to the underlying function. Also it carries forward the attributes necessary to make the wrapper look -like the wrapped function: ``__name__``, ``__qualname__``, ``__doc__``, -and ``__annotations__``. +like the wrapped function: :attr:`~function.__name__`, +:attr:`~function.__qualname__`, :attr:`~function.__doc__`, +and :attr:`~function.__annotations__`. Member objects and __slots__ diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst index 28749754a54dba..1e9ac9b6761b64 100644 --- a/Doc/howto/enum.rst +++ b/Doc/howto/enum.rst @@ -483,6 +483,7 @@ Dataclass support When inheriting from a :class:`~dataclasses.dataclass`, the :meth:`~Enum.__repr__` omits the inherited class' name. For example:: + >>> from dataclasses import dataclass, field >>> @dataclass ... class CreatureDataMixin: ... size: str @@ -527,7 +528,8 @@ It is possible to modify how enum members are pickled/unpickled by defining :meth:`__reduce_ex__` in the enumeration class. The default method is by-value, but enums with complicated values may want to use by-name:: - >>> class MyEnum(Enum): + >>> import enum + >>> class MyEnum(enum.Enum): ... __reduce_ex__ = enum.pickle_by_enum_name .. note:: @@ -605,9 +607,9 @@ The complete signature is:: start=1, ) -:value: What the new enum class will record as its name. +* *value*: What the new enum class will record as its name. -:names: The enum members. This can be a whitespace- or comma-separated string +* *names*: The enum members. This can be a whitespace- or comma-separated string (values will start at 1 unless otherwise specified):: 'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE' @@ -624,13 +626,13 @@ The complete signature is:: {'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42} -:module: name of module where new enum class can be found. +* *module*: name of module where new enum class can be found. -:qualname: where in module new enum class can be found. +* *qualname*: where in module new enum class can be found. -:type: type to mix in to new enum class. +* *type*: type to mix in to new enum class. -:start: number to start counting at if only names are passed in. +* *start*: number to start counting at if only names are passed in. .. versionchanged:: 3.5 The *start* parameter was added. @@ -770,7 +772,7 @@ be combined with them (but may lose :class:`IntFlag` membership:: >>> Perm.X | 4 - >>> Perm.X | 8 + >>> Perm.X + 8 9 .. note:: @@ -866,7 +868,7 @@ Others While :class:`IntEnum` is part of the :mod:`enum` module, it would be very simple to implement independently:: - class IntEnum(int, Enum): + class IntEnum(int, ReprEnum): # or Enum instead of ReprEnum pass This demonstrates how similar derived enumerations can be defined; for example @@ -874,8 +876,8 @@ a :class:`FloatEnum` that mixes in :class:`float` instead of :class:`int`. Some rules: -1. When subclassing :class:`Enum`, mix-in types must appear before - :class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum` +1. When subclassing :class:`Enum`, mix-in types must appear before the + :class:`Enum` class itself in the sequence of bases, as in the :class:`IntEnum` example above. 2. Mix-in types must be subclassable. For example, :class:`bool` and :class:`range` are not subclassable and will throw an error during Enum @@ -959,30 +961,34 @@ all the members are created it is no longer used. Supported ``_sunder_`` names """""""""""""""""""""""""""" -- ``_name_`` -- name of the member -- ``_value_`` -- value of the member; can be set / modified in ``__new__`` +- :attr:`~Enum._name_` -- name of the member +- :attr:`~Enum._value_` -- value of the member; can be set in ``__new__`` +- :meth:`~Enum._missing_` -- a lookup function used when a value is not found; + may be overridden +- :attr:`~Enum._ignore_` -- a list of names, either as a :class:`list` or a + :class:`str`, that will not be transformed into members, and will be removed + from the final class +- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for + an enum member; may be overridden +- :meth:`~Enum._add_alias_` -- adds a new name as an alias to an existing + member. +- :meth:`~Enum._add_value_alias_` -- adds a new value as an alias to an + existing member. See `MultiValueEnum`_ for an example. -- ``_missing_`` -- a lookup function used when a value is not found; may be - overridden -- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`, - that will not be transformed into members, and will be removed from the final - class -- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent - (class attribute, removed during class creation) -- ``_generate_next_value_`` -- used by the `Functional API`_ and by - :class:`auto` 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 highest + 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. - For :class:`Flag` classes the next value chosen will be the next highest - power-of-two, regardless of the last value seen. + .. versionchanged:: 3.13 + Prior versions would use the last seen value instead of the highest value. .. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_`` .. versionadded:: 3.7 ``_ignore_`` +.. versionadded:: 3.13 ``_add_alias_``, ``_add_value_alias_`` To help keep Python 2 / Python 3 code in sync an :attr:`_order_` attribute can be provided. It will be checked against the actual order of the enumeration @@ -1156,13 +1162,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 @@ -1434,7 +1441,7 @@ alias:: ... GRENE = 2 ... Traceback (most recent call last): - ... + ... ValueError: aliases not allowed in DuplicateFreeEnum: 'GRENE' --> 'GREEN' .. note:: @@ -1444,6 +1451,29 @@ alias:: disallowing aliases, the :func:`unique` decorator can be used instead. +MultiValueEnum +^^^^^^^^^^^^^^^^^ + +Supports having more than one value per member:: + + >>> class MultiValueEnum(Enum): + ... def __new__(cls, value, *values): + ... self = object.__new__(cls) + ... self._value_ = value + ... for v in values: + ... self._add_value_alias_(v) + ... return self + ... + >>> class DType(MultiValueEnum): + ... float32 = 'f', 8 + ... double64 = 'd', 9 + ... + >>> DType('f') + + >>> DType(9) + + + Planet ^^^^^^ 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 875f846aad0051..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. diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst index 8f3787f2d2f145..835c0afad7c6c8 100644 --- a/Doc/howto/isolating-extensions.rst +++ b/Doc/howto/isolating-extensions.rst @@ -339,12 +339,44 @@ That is, heap types should: - 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 +Please refer to the the documentation of :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 -(or another type), ensure that ``Py_TYPE(self)`` is visited only once. +The API for defining heap types grew organically, leaving it +somewhat awkward to use in its current state. +The following sections will guide you through common issues. + + +``tp_traverse`` in Python 3.8 and lower +....................................... + +The requirement to visit the type from ``tp_traverse`` was added in Python 3.9. +If you support Python 3.8 and lower, the traverse function must *not* +visit the type, so it must be more complicated:: + + static int my_traverse(PyObject *self, visitproc visit, void *arg) + { + if (Py_Version >= 0x03090000) { + Py_VISIT(Py_TYPE(self)); + } + return 0; + } + +Unfortunately, :c:data:`Py_Version` was only added in Python 3.11. +As a replacement, use: + +* :c:macro:`PY_VERSION_HEX`, if not using the stable ABI, or +* :py:data:`sys.version_info` (via :c:func:`PySys_GetObject` and + :c:func:`PyArg_ParseTuple`). + + +Delegating ``tp_traverse`` +.......................... + +If your traverse function delegates to the :c:member:`~PyTypeObject.tp_traverse` +of its base class (or another type), ensure that ``Py_TYPE(self)`` is visited +only once. Note that only heap type are expected to visit the type in ``tp_traverse``. For example, if your traverse function includes:: @@ -356,11 +388,70 @@ For example, if your traverse function includes:: if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) { // a heap type's tp_traverse already visited Py_TYPE(self) } else { - Py_VISIT(Py_TYPE(self)); + if (Py_Version >= 0x03090000) { + Py_VISIT(Py_TYPE(self)); + } } -It is not necessary to handle the type's reference count in ``tp_new`` -and ``tp_clear``. +It is not necessary to handle the type's reference count in +:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_clear`. + + +Defining ``tp_dealloc`` +....................... + +If your type has a custom :c:member:`~PyTypeObject.tp_dealloc` function, +it needs to: + +- call :c:func:`PyObject_GC_UnTrack` before any fields are invalidated, and +- decrement the reference count of the type. + +To keep the type valid while ``tp_free`` is called, the type's refcount needs +to be decremented *after* the instance is deallocated. For example:: + + static void my_dealloc(PyObject *self) + { + PyObject_GC_UnTrack(self); + ... + PyTypeObject *type = Py_TYPE(self); + type->tp_free(self); + Py_DECREF(type); + } + +The default ``tp_dealloc`` function does this, so +if your type does *not* override +``tp_dealloc`` you don't need to add it. + + +Not overriding ``tp_free`` +.......................... + +The :c:member:`~PyTypeObject.tp_free` slot of a heap type must be set to +:c:func:`PyObject_GC_Del`. +This is the default; do not override it. + + +Avoiding ``PyObject_New`` +......................... + +GC-tracked objects need to be allocated using GC-aware functions. + +If you use use :c:func:`PyObject_New` or :c:func:`PyObject_NewVar`: + +- Get and call type's :c:member:`~PyTypeObject.tp_alloc` slot, if possible. + That is, replace ``TYPE *o = PyObject_New(TYPE, typeobj)`` with:: + + TYPE *o = typeobj->tp_alloc(typeobj, 0); + + Replace ``o = PyObject_NewVar(TYPE, typeobj, size)`` with the same, + but use size instead of the 0. + +- If the above is not possible (e.g. inside a custom ``tp_alloc``), + call :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`:: + + TYPE *o = PyObject_GC_New(TYPE, typeobj); + + TYPE *o = PyObject_GC_NewVar(TYPE, typeobj, size); Module State Access from Classes diff --git a/Doc/howto/perf_profiling.rst b/Doc/howto/perf_profiling.rst index 61812c19ae6ca9..bb1c00e0aa51d5 100644 --- a/Doc/howto/perf_profiling.rst +++ b/Doc/howto/perf_profiling.rst @@ -97,7 +97,7 @@ Then we can use ``perf report`` to analyze the data: | | | | | |--2.97%--_PyObject_Malloc ... -As you can see, the Python functions are not shown in the output, only ``_Py_Eval_EvalFrameDefault`` +As you can see, the Python functions are not shown in the output, only ``_PyEval_EvalFrameDefault`` (the function that evaluates the Python bytecode) shows up. Unfortunately that's not very useful because all Python functions use the same C function to evaluate bytecode so we cannot know which Python function corresponds to which bytecode-evaluating function. @@ -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 6c30a0dd7d6bcc..501b16d82d4d6f 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -39,7 +39,8 @@ are: #. Once your dependencies are no longer blocking you, use continuous integration 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 +#. Consider using optional :term:`static type checking ` + to make sure your type usage 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``). @@ -395,7 +396,7 @@ comparisons occur, making the mistake much easier to track down. Consider using optional static type checking -------------------------------------------- -Another way to help port your code is to use a static type checker like +Another way to help port your code is to use a :term:`static type checker` like mypy_ or pytype_ on your code. These tools can be used to analyze your code as if it's being run under Python 2, then you can run the tool a second time as if your code is running under Python 3. By running a static type checker twice like diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index c19c48301f5848..5e2f9a9d1837fe 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -245,6 +245,9 @@ You can omit either *m* or *n*; in that case, a reasonable value is assumed for the missing value. Omitting *m* is interpreted as a lower limit of 0, while omitting *n* results in an upper bound of infinity. +The simplest case ``{m}`` matches the preceding item exactly *m* times. +For example, ``a/{2}b`` will only match ``'a//b'``. + Readers of a reductionist bent may notice that the three other quantifiers can all be expressed using this notation. ``{0,}`` is the same as ``*``, ``{1,}`` is equivalent to ``+``, and ``{0,1}`` is the same as ``?``. It's better to use 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/library/__main__.rst b/Doc/library/__main__.rst index fd60d92d4eb0f9..c999253f781b10 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:: @@ -227,7 +227,7 @@ students:: import sys from .student import search_students - student_name = sys.argv[2] if len(sys.argv) >= 2 else '' + student_name = sys.argv[1] if len(sys.argv) >= 2 else '' print(f'Found student: {search_students(student_name)}') Note that ``from .student import search_students`` is an example of a relative @@ -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 diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 0442c298c137ba..297f50a46e0692 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -120,10 +120,13 @@ This module defines the following constants and functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD. .. versionadded:: 3.8 + .. versionchanged:: 3.13 + Added support for GNU/kFreeBSD. + .. function:: stack_size([size]) @@ -208,7 +211,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` diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 274b2d69f0ab5c..c073ea955abaa4 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -21,7 +21,7 @@ The :mod:`collections` module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition, the :mod:`collections.abc` submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, if it is -:term:`hashable` or if it is a mapping. +:term:`hashable` or if it is a :term:`mapping`. This module provides the metaclass :class:`ABCMeta` for defining ABCs and @@ -30,7 +30,7 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: .. class:: ABC A helper class that has :class:`ABCMeta` as its metaclass. With this class, - an abstract base class can be created by simply deriving from :class:`ABC` + an abstract base class can be created by simply deriving from :class:`!ABC` avoiding sometimes confusing metaclass usage, for example:: from abc import ABC @@ -38,11 +38,11 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: class MyABC(ABC): pass - Note that the type of :class:`ABC` is still :class:`ABCMeta`, therefore - inheriting from :class:`ABC` requires the usual precautions regarding + Note that the type of :class:`!ABC` is still :class:`ABCMeta`, therefore + inheriting from :class:`!ABC` requires the usual precautions regarding metaclass usage, as multiple inheritance may lead to metaclass conflicts. One may also define an abstract base class by passing the metaclass - keyword and using :class:`ABCMeta` directly, for example:: + keyword and using :class:`!ABCMeta` directly, for example:: from abc import ABCMeta @@ -65,7 +65,7 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: implementations defined by the registering ABC be callable (not even via :func:`super`). [#]_ - Classes created with a metaclass of :class:`ABCMeta` have the following method: + Classes created with a metaclass of :class:`!ABCMeta` have the following method: .. method:: register(subclass) @@ -86,7 +86,7 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: Returns the registered subclass, to allow usage as a class decorator. .. versionchanged:: 3.4 - To detect calls to :meth:`register`, you can use the + To detect calls to :meth:`!register`, you can use the :func:`get_cache_token` function. You can also override this method in an abstract base class: @@ -96,10 +96,10 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: (Must be defined as a class method.) Check whether *subclass* is considered a subclass of this ABC. This means - that you can customize the behavior of ``issubclass`` further without the + that you can customize the behavior of :func:`issubclass` further without the need to call :meth:`register` on every class you want to consider a subclass of the ABC. (This class method is called from the - :meth:`__subclasscheck__` method of the ABC.) + :meth:`~class.__subclasscheck__` method of the ABC.) This method should return ``True``, ``False`` or ``NotImplemented``. If it returns ``True``, the *subclass* is considered a subclass of this ABC. @@ -142,7 +142,7 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: The ABC ``MyIterable`` defines the standard iterable method, :meth:`~iterator.__iter__`, as an abstract method. The implementation given - here can still be called from subclasses. The :meth:`get_iterator` method + here can still be called from subclasses. The :meth:`!get_iterator` method is also part of the ``MyIterable`` abstract base class, but it does not have to be overridden in non-abstract derived classes. @@ -153,14 +153,14 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance: Finally, the last line makes ``Foo`` a virtual subclass of ``MyIterable``, even though it does not define an :meth:`~iterator.__iter__` method (it uses - the old-style iterable protocol, defined in terms of :meth:`__len__` and - :meth:`__getitem__`). Note that this will not make ``get_iterator`` + the old-style iterable protocol, defined in terms of :meth:`~object.__len__` and + :meth:`~object.__getitem__`). Note that this will not make ``get_iterator`` available as a method of ``Foo``, so it is provided separately. -The :mod:`abc` module also provides the following decorator: +The :mod:`!abc` module also provides the following decorator: .. decorator:: abstractmethod @@ -168,19 +168,19 @@ The :mod:`abc` module also provides the following decorator: Using this decorator requires that the class's metaclass is :class:`ABCMeta` or is derived from it. A class that has a metaclass derived from - :class:`ABCMeta` cannot be instantiated unless all of its abstract methods + :class:`!ABCMeta` cannot be instantiated unless all of its abstract methods and properties are overridden. The abstract methods can be called using any - of the normal 'super' call mechanisms. :func:`abstractmethod` may be used + of the normal 'super' call mechanisms. :func:`!abstractmethod` may be used to declare abstract methods for properties and descriptors. Dynamically adding abstract methods to a class, or attempting to modify the abstraction status of a method or class once it is created, are only supported using the :func:`update_abstractmethods` function. The - :func:`abstractmethod` only affects subclasses derived using regular - inheritance; "virtual subclasses" registered with the ABC's :meth:`register` - method are not affected. + :func:`!abstractmethod` only affects subclasses derived using regular + inheritance; "virtual subclasses" registered with the ABC's + :meth:`~ABCMeta.register` method are not affected. - When :func:`abstractmethod` is applied in combination with other method + When :func:`!abstractmethod` is applied in combination with other method descriptors, it should be applied as the innermost decorator, as shown in the following usage examples:: @@ -216,7 +216,7 @@ The :mod:`abc` module also provides the following decorator: In order to correctly interoperate with the abstract base class machinery, the descriptor must identify itself as abstract using - :attr:`__isabstractmethod__`. In general, this attribute should be ``True`` + :attr:`!__isabstractmethod__`. In general, this attribute should be ``True`` if any of the methods used to compose the descriptor are abstract. For example, Python's built-in :class:`property` does the equivalent of:: @@ -236,7 +236,7 @@ The :mod:`abc` module also provides the following decorator: super-call in a framework that uses cooperative multiple-inheritance. -The :mod:`abc` module also supports the following legacy decorators: +The :mod:`!abc` module also supports the following legacy decorators: .. decorator:: abstractclassmethod @@ -323,7 +323,7 @@ The :mod:`abc` module also supports the following legacy decorators: ... -The :mod:`abc` module also provides the following functions: +The :mod:`!abc` module also provides the following functions: .. function:: get_cache_token() diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 10b3e2dae472e1..4ebbe0e5471c88 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -2483,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-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 04af53b980ff9e..828e506a72c937 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -243,9 +243,9 @@ Scheduling callbacks See the :ref:`concurrency and multithreading ` section of the documentation. -.. versionchanged:: 3.7 - The *context* keyword-only parameter was added. See :pep:`567` - for more details. + .. versionchanged:: 3.7 + The *context* keyword-only parameter was added. See :pep:`567` + for more details. .. _asyncio-pass-keywords: @@ -509,7 +509,7 @@ Opening network connections .. versionchanged:: 3.6 - The socket option :py:const:`~socket.TCP_NODELAY` is set by default + The socket option :ref:`socket.TCP_NODELAY ` is set by default for all TCP connections. .. versionchanged:: 3.7 @@ -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:const:`~socket.SO_REUSEPORT` constant is not + and some Unixes. If the :ref:`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,8 @@ Opening network connections .. versionchanged:: 3.8.1 The *reuse_address* parameter is no longer supported, as using - :py:const:`~sockets.SO_REUSEADDR` poses a significant security concern for + :ref:`socket.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 +617,8 @@ Opening network connections For supported platforms, *reuse_port* can be used as a replacement for similar functionality. With *reuse_port*, - :py:const:`~sockets.SO_REUSEPORT` is used instead, which specifically + :ref:`socket.SO_REUSEPORT ` + is used instead, which specifically prevents processes with differing UIDs from assigning sockets to the same socket address. @@ -661,12 +663,15 @@ Opening network connections Creating network servers ^^^^^^^^^^^^^^^^^^^^^^^^ +.. _loop_create_server: + .. coroutinemethod:: loop.create_server(protocol_factory, \ host=None, port=None, *, \ family=socket.AF_UNSPEC, \ flags=socket.AI_PASSIVE, \ sock=None, backlog=100, ssl=None, \ reuse_address=None, reuse_port=None, \ + keep_alive=None, \ ssl_handshake_timeout=None, \ ssl_shutdown_timeout=None, \ start_serving=True) @@ -731,6 +736,13 @@ Creating network servers set this flag when being created. This option is not supported on Windows. + * *keep_alive* set to ``True`` keeps connections active by enabling the + periodic transmission of messages. + + .. versionchanged:: 3.13 + + Added the *keep_alive* parameter. + * *ssl_handshake_timeout* is (for a TLS server) the time in seconds to wait for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). @@ -756,7 +768,7 @@ Creating network servers .. versionchanged:: 3.6 Added *ssl_handshake_timeout* and *start_serving* parameters. - The socket option :py:const:`~socket.TCP_NODELAY` is set by default + The socket option :ref:`socket.TCP_NODELAY ` is set by default for all TCP connections. .. versionchanged:: 3.11 @@ -774,7 +786,7 @@ Creating network servers *, sock=None, backlog=100, ssl=None, \ ssl_handshake_timeout=None, \ ssl_shutdown_timeout=None, \ - start_serving=True) + start_serving=True, cleanup_socket=True) Similar to :meth:`loop.create_server` but works with the :py:const:`~socket.AF_UNIX` socket family. @@ -784,6 +796,10 @@ Creating network servers :class:`str`, :class:`bytes`, and :class:`~pathlib.Path` paths are supported. + If *cleanup_socket* is True then the Unix socket will automatically + be removed from the filesystem when the server is closed, unless the + socket has been replaced after the server has been created. + See the documentation of the :meth:`loop.create_server` method for information about arguments to this method. @@ -798,6 +814,10 @@ Creating network servers Added the *ssl_shutdown_timeout* parameter. + .. versionchanged:: 3.13 + + Added the *cleanup_socket* parameter. + .. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \ sock, *, ssl=None, ssl_handshake_timeout=None, \ @@ -1191,6 +1211,8 @@ Working with pipes Unix signals ^^^^^^^^^^^^ +.. _loop_add_signal_handler: + .. method:: loop.add_signal_handler(signum, callback, *args) Set *callback* as the handler for the *signum* signal. @@ -1391,6 +1413,14 @@ Enabling debug mode The new :ref:`Python Development Mode ` can now also be used to enable the debug mode. +.. attribute:: loop.slow_callback_duration + + This attribute can be used to set the + minimum execution duration in seconds that is considered "slow". + When debug mode is enabled, "slow" callbacks are logged. + + Default value is 100 milliseconds. + .. seealso:: The :ref:`debug mode of asyncio `. @@ -1411,6 +1441,8 @@ async/await code consider using the high-level :ref:`Subprocess Support on Windows ` for details. +.. _loop_subprocess_exec: + .. coroutinemethod:: loop.subprocess_exec(protocol_factory, *args, \ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \ stderr=subprocess.PIPE, **kwargs) @@ -1605,8 +1637,9 @@ Do not instantiate the :class:`Server` class directly. The sockets that represent existing incoming client connections are left open. - The server is closed asynchronously, use the :meth:`wait_closed` - coroutine to wait until the server is closed. + The server is closed asynchronously; use the :meth:`wait_closed` + coroutine to wait until the server is closed (and no more + connections are active). .. method:: get_loop() @@ -1664,7 +1697,8 @@ Do not instantiate the :class:`Server` class directly. .. coroutinemethod:: wait_closed() - Wait until the :meth:`close` method completes. + Wait until the :meth:`close` method completes and all active + connections have finished. .. attribute:: sockets @@ -1686,13 +1720,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 @@ -1714,7 +1748,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. @@ -1723,6 +1757,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 @@ -1872,7 +1914,7 @@ Set signal handlers for SIGINT and SIGTERM (This ``signals`` example only works on Unix.) -Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` +Register handlers for signals :const:`~signal.SIGINT` and :const:`~signal.SIGTERM` using the :meth:`loop.add_signal_handler` method:: import asyncio 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 d8186b6ce75c79..0736e783bbc8c8 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -204,6 +204,10 @@ StreamReader directly; use :func:`open_connection` and :func:`start_server` instead. + .. method:: feed_eof() + + Acknowledge the EOF. + .. coroutinemethod:: read(n=-1) Read up to *n* bytes from the stream. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 39c1e939d91652..797065c8ccf894 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 shield(something()) + res = await something() *except* that if the coroutine containing it is cancelled, the Task running in ``something()`` is not cancelled. From the point @@ -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 c75ab47404c1e4..5f33c6813e74c0 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -46,9 +46,9 @@ Additionally, there are **low-level** APIs for *library and framework developers* to: * create and manage :ref:`event loops `, which - provide asynchronous APIs for :meth:`networking `, - running :meth:`subprocesses `, - handling :meth:`OS signals `, etc; + provide asynchronous APIs for :ref:`networking `, + running :ref:`subprocesses `, + handling :ref:`OS signals `, etc; * implement efficient protocols using :ref:`transports `; diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst index d201dc963b5995..4ce5c9bcde38ff 100644 --- a/Doc/library/bdb.rst +++ b/Doc/library/bdb.rst @@ -294,7 +294,7 @@ The :mod:`bdb` module also defines two classes: .. method:: set_quit() Set the :attr:`quitting` attribute to ``True``. This raises :exc:`BdbQuit` in - the next call to one of the :meth:`dispatch_\*` methods. + the next call to one of the :meth:`!dispatch_\*` methods. Derived classes and clients can call the following methods to manipulate 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 ec4aeaa04395ac..6a95a4a6e8d183 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -91,7 +91,7 @@ The :mod:`bz2` module contains: and :meth:`~io.IOBase.truncate`. Iteration and the :keyword:`with` statement are supported. - :class:`BZ2File` also provides the following method: + :class:`BZ2File` also provides the following methods: .. method:: peek([n]) @@ -106,14 +106,52 @@ The :mod:`bz2` module contains: .. versionadded:: 3.3 + .. method:: fileno() + + Return the file descriptor for the underlying file. + + .. versionadded:: 3.3 + + .. method:: readable() + + Return whether the file was opened for reading. + + .. versionadded:: 3.3 + + .. method:: seekable() + + Return whether the file supports seeking. + + .. versionadded:: 3.3 + + .. method:: writable() + + Return whether the file was opened for writing. + + .. versionadded:: 3.3 + + .. method:: read1(size=-1) + + Read up to *size* uncompressed bytes, while trying to avoid + making multiple reads from the underlying stream. Reads up to a + buffer's worth of data if size is negative. + + Returns ``b''`` if the file is at EOF. + + .. versionadded:: 3.3 + + .. method:: readinto(b) + + Read bytes into *b*. + + Returns the number of bytes read (0 for EOF). + + .. versionadded:: 3.3 + .. versionchanged:: 3.1 Support for the :keyword:`with` statement was added. - .. versionchanged:: 3.3 - The :meth:`fileno`, :meth:`readable`, :meth:`seekable`, :meth:`writable`, - :meth:`read1` and :meth:`readinto` methods were added. - .. versionchanged:: 3.3 Support was added for *filename* being a :term:`file object` instead of an actual filename. diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index fd5df96dfd0b3d..a79882ed1cca4f 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -26,6 +26,13 @@ interface. key; it defaults to :kbd:`Tab`. If *completekey* is not :const:`None` and :mod:`readline` is available, command completion is done automatically. + The default, ``'tab'``, is treated specially, so that it refers to the + :kbd:`Tab` key on every :data:`readline.backend`. + Specifically, if :data:`readline.backend` is ``editline``, + ``Cmd`` will use ``'^I'`` instead of ``'tab'``. + Note that other values are not treated this way, and might only work + with a specific backend. + The optional arguments *stdin* and *stdout* specify the input and output file objects that the Cmd instance or subclass instance will use for input and output. If not specified, they will default to :data:`sys.stdin` and @@ -35,6 +42,9 @@ interface. :attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be ignored. + .. versionchanged:: 3.13 + ``completekey='tab'`` is replaced by ``'^I'`` for ``editline``. + .. _cmd-objects: @@ -73,7 +83,7 @@ A :class:`Cmd` instance has the following methods: This method will return when the :meth:`postcmd` method returns a true value. The *stop* argument to :meth:`postcmd` is the return value from the command's - corresponding :meth:`do_\*` method. + corresponding :meth:`!do_\*` method. If completion is enabled, completing commands will be done automatically, and completing of commands args is done by calling :meth:`complete_foo` with @@ -88,7 +98,7 @@ A :class:`Cmd` instance has the following methods: :meth:`help_bar`, and if that is not present, prints the docstring of :meth:`do_bar`, if available. With no argument, :meth:`do_help` lists all available help topics (that is, all commands with corresponding - :meth:`help_\*` methods or commands that have docstrings), and also lists any + :meth:`!help_\*` methods or commands that have docstrings), and also lists any undocumented commands. @@ -98,7 +108,7 @@ A :class:`Cmd` instance has the following methods: This may be overridden, but should not normally need to be; see the :meth:`precmd` and :meth:`postcmd` methods for useful execution hooks. The return value is a flag indicating whether interpretation of commands by the - interpreter should stop. If there is a :meth:`do_\*` method for the command + interpreter should stop. If there is a :meth:`!do_\*` method for the command *str*, the return value of that method is returned, otherwise the return value from the :meth:`default` method is returned. @@ -118,7 +128,7 @@ A :class:`Cmd` instance has the following methods: .. method:: Cmd.completedefault(text, line, begidx, endidx) Method called to complete an input line when no command-specific - :meth:`complete_\*` method is available. By default, it returns an empty list. + :meth:`!complete_\*` method is available. By default, it returns an empty list. .. method:: Cmd.columnize(list, displaywidth=80) @@ -199,14 +209,14 @@ Instances of :class:`Cmd` subclasses have some public instance variables: .. attribute:: Cmd.misc_header The header to issue if the help output has a section for miscellaneous help - topics (that is, there are :meth:`help_\*` methods without corresponding - :meth:`do_\*` methods). + topics (that is, there are :meth:`!help_\*` methods without corresponding + :meth:`!do_\*` methods). .. attribute:: Cmd.undoc_header The header to issue if the help output has a section for undocumented commands - (that is, there are :meth:`do_\*` methods without corresponding :meth:`help_\*` + (that is, there are :meth:`!do_\*` methods without corresponding :meth:`!help_\*` methods). diff --git a/Doc/library/cmdline.rst b/Doc/library/cmdline.rst index 4a295e069287d8..b2379befeffcba 100644 --- a/Doc/library/cmdline.rst +++ b/Doc/library/cmdline.rst @@ -12,7 +12,7 @@ The following modules have a command-line interface. * :ref:`compileall ` * :mod:`cProfile`: see :ref:`profile ` * :ref:`difflib ` -* :mod:`dis` +* :ref:`dis ` * :mod:`doctest` * :mod:`!encodings.rot_13` * :mod:`ensurepip` diff --git a/Doc/library/code.rst b/Doc/library/code.rst index 3d7f43c86a0557..091840781bd235 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -23,20 +23,25 @@ build applications which provide an interactive interpreter prompt. ``'__doc__'`` set to ``None``. -.. class:: InteractiveConsole(locals=None, filename="") +.. class:: InteractiveConsole(locals=None, filename="", local_exit=False) Closely emulate the behavior of the interactive Python interpreter. This class builds on :class:`InteractiveInterpreter` and adds prompting using the familiar - ``sys.ps1`` and ``sys.ps2``, and input buffering. + ``sys.ps1`` and ``sys.ps2``, and input buffering. If *local_exit* is True, + ``exit()`` and ``quit()`` in the console will not raise :exc:`SystemExit`, but + instead return to the calling code. + .. versionchanged:: 3.13 + Added *local_exit* parameter. -.. function:: interact(banner=None, readfunc=None, local=None, exitmsg=None) +.. function:: interact(banner=None, readfunc=None, local=None, exitmsg=None, local_exit=False) Convenience function to run a read-eval-print loop. This creates a new instance of :class:`InteractiveConsole` and sets *readfunc* to be used as the :meth:`InteractiveConsole.raw_input` method, if provided. If *local* is provided, it is passed to the :class:`InteractiveConsole` constructor for - use as the default namespace for the interpreter loop. The :meth:`interact` + use as the default namespace for the interpreter loop. If *local_exit* is provided, + it is passed to the :class:`InteractiveConsole` constructor. The :meth:`interact` method of the instance is then run with *banner* and *exitmsg* passed as the banner and exit message to use, if provided. The console object is discarded after use. @@ -44,6 +49,8 @@ build applications which provide an interactive interpreter prompt. .. versionchanged:: 3.6 Added *exitmsg* parameter. + .. versionchanged:: 3.13 + Added *local_exit* parameter. .. function:: compile_command(source, filename="", symbol="single") diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 2db4a67d1973d5..4617624686b1f3 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -520,44 +520,46 @@ The base :class:`Codec` class defines these methods which also define the function interfaces of the stateless encoder and decoder: -.. method:: Codec.encode(input, errors='strict') +.. class:: Codec - Encodes the object *input* and returns a tuple (output object, length consumed). - For instance, :term:`text encoding` converts - a string object to a bytes object using a particular - character set encoding (e.g., ``cp1252`` or ``iso-8859-1``). + .. method:: encode(input, errors='strict') - The *errors* argument defines the error handling to apply. - It defaults to ``'strict'`` handling. + Encodes the object *input* and returns a tuple (output object, length consumed). + For instance, :term:`text encoding` converts + a string object to a bytes object using a particular + character set encoding (e.g., ``cp1252`` or ``iso-8859-1``). - The method may not store state in the :class:`Codec` instance. Use - :class:`StreamWriter` for codecs which have to keep state in order to make - encoding efficient. + The *errors* argument defines the error handling to apply. + It defaults to ``'strict'`` handling. - The encoder must be able to handle zero length input and return an empty object - of the output object type in this situation. + The method may not store state in the :class:`Codec` instance. Use + :class:`StreamWriter` for codecs which have to keep state in order to make + encoding efficient. + The encoder must be able to handle zero length input and return an empty object + of the output object type in this situation. -.. method:: Codec.decode(input, errors='strict') - Decodes the object *input* and returns a tuple (output object, length - consumed). For instance, for a :term:`text encoding`, decoding converts - a bytes object encoded using a particular - character set encoding to a string object. + .. method:: decode(input, errors='strict') - For text encodings and bytes-to-bytes codecs, - *input* must be a bytes object or one which provides the read-only - buffer interface -- for example, buffer objects and memory mapped files. + Decodes the object *input* and returns a tuple (output object, length + consumed). For instance, for a :term:`text encoding`, decoding converts + a bytes object encoded using a particular + character set encoding to a string object. - The *errors* argument defines the error handling to apply. - It defaults to ``'strict'`` handling. + For text encodings and bytes-to-bytes codecs, + *input* must be a bytes object or one which provides the read-only + buffer interface -- for example, buffer objects and memory mapped files. - The method may not store state in the :class:`Codec` instance. Use - :class:`StreamReader` for codecs which have to keep state in order to make - decoding efficient. + The *errors* argument defines the error handling to apply. + It defaults to ``'strict'`` handling. - The decoder must be able to handle zero length input and return an empty object - of the output object type in this situation. + The method may not store state in the :class:`Codec` instance. Use + :class:`StreamReader` for codecs which have to keep state in order to make + decoding efficient. + + The decoder must be able to handle zero length input and return an empty object + of the output object type in this situation. Incremental Encoding and Decoding @@ -705,7 +707,7 @@ Stream Encoding and Decoding The :class:`StreamWriter` and :class:`StreamReader` classes provide generic working interfaces which can be used to implement new encoding submodules very -easily. See :mod:`encodings.utf_8` for an example of how this is done. +easily. See :mod:`!encodings.utf_8` for an example of how this is done. .. _stream-writer-objects: @@ -895,9 +897,10 @@ The design is such that one can use the factory functions returned by the .. class:: StreamRecoder(stream, encode, decode, Reader, Writer, errors='strict') Creates a :class:`StreamRecoder` instance which implements a two-way conversion: - *encode* and *decode* work on the frontend — the data visible to - code calling :meth:`read` and :meth:`write`, while *Reader* and *Writer* - work on the backend — the data in *stream*. + *encode* and *decode* work on the frontend — the data visible to + code calling :meth:`~StreamReader.read` and :meth:`~StreamWriter.write`, + while *Reader* and *Writer* + work on the backend — the data in *stream*. You can use these objects to do transparent transcodings, e.g., from Latin-1 to UTF-8 and back. @@ -1417,8 +1420,8 @@ to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode` | | quotedprintable, | quoted printable. | ``quotetabs=True`` / | | | quoted_printable | | :meth:`quopri.decode` | +----------------------+------------------+------------------------------+------------------------------+ -| uu_codec | uu | Convert the operand using | :meth:`uu.encode` / | -| | | uuencode. | :meth:`uu.decode` | +| uu_codec | uu | Convert the operand using | | +| | | uuencode. | | +----------------------+------------------+------------------------------+------------------------------+ | zlib_codec | zip, zlib | Compress the operand using | :meth:`zlib.compress` / | | | | gzip. | :meth:`zlib.decompress` | diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 43a3286ba832cf..edc078953290d7 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -192,7 +192,7 @@ ABC Inherits from Abstract Methods Mi .. [2] Checking ``isinstance(obj, Iterable)`` detects classes that are registered as :class:`Iterable` or that have an :meth:`__iter__` method, but it does not detect classes that iterate with the - :meth:`__getitem__` method. The only reliable way to determine + :meth:`~object.__getitem__` method. The only reliable way to determine whether an object is :term:`iterable` is to call ``iter(obj)``. @@ -222,7 +222,7 @@ Collections Abstract Base Classes -- Detailed Descriptions Checking ``isinstance(obj, Iterable)`` detects classes that are registered as :class:`Iterable` or that have an :meth:`__iter__` method, but it does - not detect classes that iterate with the :meth:`__getitem__` method. + not detect classes that iterate with the :meth:`~object.__getitem__` method. The only reliable way to determine whether an object is :term:`iterable` is to call ``iter(obj)``. @@ -262,8 +262,8 @@ Collections Abstract Base Classes -- Detailed Descriptions Implementation note: Some of the mixin methods, such as :meth:`__iter__`, :meth:`__reversed__` and :meth:`index`, make - repeated calls to the underlying :meth:`__getitem__` method. - Consequently, if :meth:`__getitem__` is implemented with constant + repeated calls to the underlying :meth:`~object.__getitem__` method. + Consequently, if :meth:`~object.__getitem__` is implemented with constant access speed, the mixin methods will have linear performance; however, if the underlying method is linear (as it would be with a linked list), the mixins will have quadratic performance and will diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 43f4ff077b40e0..233b2c6a771f4a 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 @@ -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 @@ -743,12 +743,12 @@ stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``, If calling :attr:`default_factory` raises an exception this exception is propagated unchanged. - This method is called by the :meth:`__getitem__` method of the + This method is called by the :meth:`~object.__getitem__` method of the :class:`dict` class when the requested key is not found; whatever it - returns or raises is then returned or raised by :meth:`__getitem__`. + returns or raises is then returned or raised by :meth:`~object.__getitem__`. Note that :meth:`__missing__` is *not* called for any operations besides - :meth:`__getitem__`. This means that :meth:`get` will, like normal + :meth:`~object.__getitem__`. This means that :meth:`get` will, like normal dictionaries, return ``None`` as a default rather than using :attr:`default_factory`. @@ -981,6 +981,10 @@ field names, the method and attribute names start with an underscore. Named tuples are also supported by generic function :func:`copy.replace`. + .. versionchanged:: 3.13 + Raise :exc:`TypeError` instead of :exc:`ValueError` for invalid + keyword arguments. + .. attribute:: somenamedtuple._fields Tuple of strings listing the field names. Useful for introspection @@ -1062,20 +1066,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 diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index a7455aeb0ec1cd..df1eefab839cc1 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -26,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 :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 @@ -55,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 @@ -106,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. diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 6503d1fcf70a32..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 @@ -301,6 +305,10 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. 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 @@ -353,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/configparser.rst b/Doc/library/configparser.rst index bb282428c5fffc..12eee47613d186 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -955,7 +955,7 @@ ConfigParser Objects When *converters* is given, it should be a dictionary where each key represents the name of a type converter and each value is a callable implementing the conversion from string to the desired datatype. Every - converter gets its own corresponding :meth:`get*()` method on the parser + converter gets its own corresponding :meth:`!get*()` method on the parser object and section proxies. .. versionchanged:: 3.1 diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 7cd081d1f54f43..aab319cbe7405e 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -45,7 +45,7 @@ Functions and classes provided: This function is a :term:`decorator` that can be used to define a factory function for :keyword:`with` statement context managers, without needing to - create a class or separate :meth:`__enter__` and :meth:`__exit__` methods. + create a class or separate :meth:`~object.__enter__` and :meth:`~object.__exit__` methods. While many objects natively support use in with statements, sometimes a resource needs to be managed that isn't a context manager in its own right, @@ -106,8 +106,8 @@ Functions and classes provided: This function is a :term:`decorator` that can be used to define a factory function for :keyword:`async with` statement asynchronous context managers, - without needing to create a class or separate :meth:`__aenter__` and - :meth:`__aexit__` methods. It must be applied to an :term:`asynchronous + without needing to create a class or separate :meth:`~object.__aenter__` and + :meth:`~object.__aexit__` methods. It must be applied to an :term:`asynchronous generator` function. A simple example:: @@ -304,15 +304,15 @@ Functions and classes provided: This context manager is :ref:`reentrant `. - If the code within the :keyword:`!with` block raises an - :exc:`ExceptionGroup`, suppressed exceptions are removed from the + If the code within the :keyword:`!with` block raises a + :exc:`BaseExceptionGroup`, suppressed exceptions are removed from the group. If any exceptions in the group are not suppressed, a group containing them is re-raised. .. versionadded:: 3.4 .. versionchanged:: 3.12 ``suppress`` now supports suppressing exceptions raised as - part of an :exc:`ExceptionGroup`. + part of an :exc:`BaseExceptionGroup`. .. function:: redirect_stdout(new_target) @@ -515,7 +515,7 @@ Functions and classes provided: # the with statement, even if attempts to open files later # in the list raise an exception - The :meth:`__enter__` method returns the :class:`ExitStack` instance, and + The :meth:`~object.__enter__` method returns the :class:`ExitStack` instance, and performs no additional operations. Each instance maintains a stack of registered callbacks that are called in @@ -543,9 +543,9 @@ Functions and classes provided: .. method:: enter_context(cm) - Enters a new context manager and adds its :meth:`__exit__` method to + Enters a new context manager and adds its :meth:`~object.__exit__` method to the callback stack. The return value is the result of the context - manager's own :meth:`__enter__` method. + manager's own :meth:`~object.__enter__` method. These context managers may suppress exceptions just as they normally would if used directly as part of a :keyword:`with` statement. @@ -556,18 +556,18 @@ Functions and classes provided: .. method:: push(exit) - Adds a context manager's :meth:`__exit__` method to the callback stack. + Adds a context manager's :meth:`~object.__exit__` method to the callback stack. As ``__enter__`` is *not* invoked, this method can be used to cover - part of an :meth:`__enter__` implementation with a context manager's own - :meth:`__exit__` method. + part of an :meth:`~object.__enter__` implementation with a context manager's own + :meth:`~object.__exit__` method. If passed an object that is not a context manager, this method assumes it is a callback with the same signature as a context manager's - :meth:`__exit__` method and adds it directly to the callback stack. + :meth:`~object.__exit__` method and adds it directly to the callback stack. By returning true values, these callbacks can suppress exceptions the - same way context manager :meth:`__exit__` methods can. + same way context manager :meth:`~object.__exit__` methods can. The passed in object is returned from the function, allowing this method to be used as a function decorator. @@ -616,12 +616,12 @@ Functions and classes provided: asynchronous context managers, as well as having coroutines for cleanup logic. - The :meth:`close` method is not implemented, :meth:`aclose` must be used + The :meth:`~ExitStack.close` method is not implemented; :meth:`aclose` must be used instead. .. coroutinemethod:: enter_async_context(cm) - Similar to :meth:`enter_context` but expects an asynchronous context + Similar to :meth:`ExitStack.enter_context` but expects an asynchronous context manager. .. versionchanged:: 3.11 @@ -630,16 +630,16 @@ Functions and classes provided: .. method:: push_async_exit(exit) - Similar to :meth:`push` but expects either an asynchronous context manager + Similar to :meth:`ExitStack.push` but expects either an asynchronous context manager or a coroutine function. .. method:: push_async_callback(callback, /, *args, **kwds) - Similar to :meth:`callback` but expects a coroutine function. + Similar to :meth:`ExitStack.callback` but expects a coroutine function. .. coroutinemethod:: aclose() - Similar to :meth:`close` but properly handles awaitables. + Similar to :meth:`ExitStack.close` but properly handles awaitables. Continuing the example for :func:`asynccontextmanager`:: @@ -714,7 +714,7 @@ Cleaning up in an ``__enter__`` implementation As noted in the documentation of :meth:`ExitStack.push`, this method can be useful in cleaning up an already allocated resource if later -steps in the :meth:`__enter__` implementation fail. +steps in the :meth:`~object.__enter__` implementation fail. Here's an example of doing this for a context manager that accepts resource acquisition and release functions, along with an optional validation function, @@ -871,7 +871,7 @@ And also as a function decorator:: Note that there is one additional limitation when using context managers as function decorators: there's no way to access the return value of -:meth:`__enter__`. If that value is needed, then it is still necessary to use +:meth:`~object.__enter__`. If that value is needed, then it is still necessary to use an explicit ``with`` statement. .. seealso:: diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 64baa69be4af31..4d52254e6d6db5 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. @@ -309,6 +309,8 @@ An example for :class:`Sniffer` use:: # ... process CSV file contents here ... +.. _csv-constants: + The :mod:`csv` module defines the following constants: .. data:: QUOTE_ALL @@ -432,8 +434,8 @@ Dialects support the following attributes: .. attribute:: Dialect.quoting Controls when quotes should be generated by the writer and recognised by the - reader. It can take on any of the :const:`QUOTE_\*` constants (see section - :ref:`csv-contents`) and defaults to :const:`QUOTE_MINIMAL`. + reader. It can take on any of the :ref:`QUOTE_\* constants ` + and defaults to :const:`QUOTE_MINIMAL`. .. attribute:: Dialect.skipinitialspace diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 8af609d53ff4b8..ef3a9a0f5898af 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1403,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 @@ -1737,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:`~_FuncPtr.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:: @@ -2088,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) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 9ab67c21975394..9b8a98f05f7cbb 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -1771,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 d78a6071a50e4b..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. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 0b9d42f32e3bd6..1bab1fb9bd9464 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -38,7 +38,8 @@ on efficient attribute extraction for output formatting and manipulation. 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 + Third-party library that introduces distinct static types to e.g. allow + :term:`static type checkers ` to differentiate between naive and aware datetimes. .. _datetime-naive-aware: 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/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 c553611401d018..9abf19557f989c 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -171,9 +171,12 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. expressed in the ISO 8601 format. If not specified, the strings default to blanks. + >>> import sys + >>> from difflib import * >>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n'] >>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n'] - >>> sys.stdout.writelines(context_diff(s1, s2, fromfile='before.py', tofile='after.py')) + >>> sys.stdout.writelines(context_diff(s1, s2, fromfile='before.py', + ... tofile='after.py')) *** before.py --- after.py *************** @@ -294,13 +297,12 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. For inputs that do not have trailing newlines, set the *lineterm* argument to ``""`` so that the output will be uniformly newline free. - The context diff format normally has a header for filenames and modification + The unified diff format normally has a header for filenames and modification times. Any or all of these may be specified using strings for *fromfile*, *tofile*, *fromfiledate*, and *tofiledate*. The modification times are normally expressed in the ISO 8601 format. If not specified, the strings default to blanks. - >>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n'] >>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n'] >>> sys.stdout.writelines(unified_diff(s1, s2, fromfile='before.py', tofile='after.py')) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index b835f1ea2b0090..5647021d6a9ba6 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -42,6 +42,19 @@ interpreter. bytecode to specialize it for different runtime conditions. The adaptive bytecode can be shown by passing ``adaptive=True``. + .. versionchanged:: 3.12 + The argument of a jump is the offset of the target instruction relative + to the instruction that appears immediately after the jump instruction's + :opcode:`CACHE` entries. + + As a consequence, the presence of the :opcode:`CACHE` instructions is + transparent for forward jumps but needs to be taken into account when + reasoning about backward jumps. + + .. versionchanged:: 3.13 + The output shows logical labels rather than instruction offsets + for jump targets and exception handlers. The ``-O`` command line + option and the ``show_offsets`` argument were added. Example: Given the function :func:`!myfunc`:: @@ -54,15 +67,45 @@ the following command can be used to display the disassembly of .. doctest:: >>> dis.dis(myfunc) - 2 0 RESUME 0 + 2 RESUME 0 - 3 2 LOAD_GLOBAL 1 (len + NULL) - 12 LOAD_FAST 0 (alist) - 14 CALL 1 - 22 RETURN_VALUE + 3 LOAD_GLOBAL 1 (len + NULL) + LOAD_FAST 0 (alist) + CALL 1 + 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] [-O] [infile] + +The following options are accepted: + +.. program:: dis + +.. cmdoption:: -h, --help + + Display usage and exit. + +.. cmdoption:: -C, --show-caches + + Show inline caches. + +.. cmdoption:: -O, --show-offsets + + Show offsets of instructions. + +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 ----------------- @@ -73,7 +116,7 @@ The bytecode analysis API allows pieces of Python code to be wrapped in a code. .. class:: Bytecode(x, *, first_line=None, current_offset=None,\ - show_caches=False, adaptive=False) + show_caches=False, adaptive=False, show_offsets=False) Analyse the bytecode corresponding to a function, generator, asynchronous generator, coroutine, method, string of source code, or a code object (as @@ -98,6 +141,9 @@ code. If *adaptive* is ``True``, :meth:`.dis` will display specialized bytecode that may be different from the original bytecode. + If *show_offsets* is ``True``, :meth:`.dis` will include instruction + offsets in the output. + .. classmethod:: from_traceback(tb, *, show_caches=False) Construct a :class:`Bytecode` instance from the given traceback, setting @@ -220,7 +266,8 @@ operation is being performed, so the intermediate analysis object isn't useful: Added the *show_caches* and *adaptive* parameters. -.. function:: distb(tb=None, *, file=None, show_caches=False, adaptive=False) +.. function:: distb(tb=None, *, file=None, show_caches=False, adaptive=False, + show_offset=False) Disassemble the top-of-stack function of a traceback, using the last traceback if none was passed. The instruction causing the exception is @@ -235,9 +282,12 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.11 Added the *show_caches* and *adaptive* parameters. + .. versionchanged:: 3.13 + Added the *show_offsets* parameter. .. function:: disassemble(code, lasti=-1, *, file=None, show_caches=False, adaptive=False) - disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False) + disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False, + show_offsets=False) Disassemble a code object, indicating the last instruction if *lasti* was provided. The output is divided in the following columns: @@ -262,6 +312,8 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.11 Added the *show_caches* and *adaptive* parameters. + .. versionchanged:: 3.13 + Added the *show_offsets* parameter. .. function:: get_instructions(x, *, first_line=None, show_caches=False, adaptive=False) @@ -276,13 +328,17 @@ operation is being performed, so the intermediate analysis object isn't useful: source line information (if any) is taken directly from the disassembled code object. - The *show_caches* and *adaptive* parameters work as they do in :func:`dis`. + The *adaptive* parameter works as it does in :func:`dis`. .. versionadded:: 3.4 .. versionchanged:: 3.11 Added the *show_caches* and *adaptive* parameters. + .. versionchanged:: 3.13 + The *show_caches* parameter is deprecated and has no effect. The *cache_info* + field of each instruction is populated regardless of its value. + .. function:: findlinestarts(code) @@ -294,8 +350,9 @@ operation is being performed, so the intermediate analysis object isn't useful: Line numbers can be decreasing. Before, they were always increasing. .. versionchanged:: 3.10 - The :pep:`626` ``co_lines`` method is used instead of the ``co_firstlineno`` - and ``co_lnotab`` attributes of the code object. + The :pep:`626` ``co_lines`` method is used instead of the + :attr:`~codeobject.co_firstlineno` and :attr:`~codeobject.co_lnotab` + attributes of the code object. .. versionchanged:: 3.13 Line numbers can be ``None`` for bytecode that does not map to source lines. @@ -429,6 +486,14 @@ details of bytecode instructions as :class:`Instruction` instances: :class:`dis.Positions` object holding the start and end locations that are covered by this instruction. + .. data::cache_info + + Information about the cache entries of this instruction, as + triplets of the form ``(name, size, data)``, where the ``name`` + and ``size`` describe the cache format and data is the contents + of the cache. ``cache_info`` is ``None`` if the instruction does not have + caches. + .. versionadded:: 3.4 .. versionchanged:: 3.11 @@ -440,8 +505,8 @@ details of bytecode instructions as :class:`Instruction` instances: Changed field ``starts_line``. Added fields ``start_offset``, ``cache_offset``, ``end_offset``, - ``baseopname``, ``baseopcode``, ``jump_target``, ``oparg``, and - ``line_number``. + ``baseopname``, ``baseopcode``, ``jump_target``, ``oparg``, + ``line_number`` and ``cache_info``. .. class:: Positions @@ -487,6 +552,14 @@ operations on it as if it was a Python list. The top of the stack corresponds to .. versionadded:: 3.12 +.. opcode:: END_SEND + + Implements ``del STACK[-2]``. + Used to clean up when a generator exits. + + .. versionadded:: 3.12 + + .. opcode:: COPY (i) Push the i-th item to the top of the stack without removing it from its original @@ -781,6 +854,9 @@ iterations of the loop. .. versionchanged:: 3.12 oparg set to be the exception block depth, for efficient closing of generators. + .. versionchanged:: 3.13 + oparg is ``1`` if this instruction is part of a yield-from or await, and ``0`` + otherwise. .. opcode:: SETUP_ANNOTATIONS @@ -802,8 +878,8 @@ iterations of the loop. .. opcode:: RERAISE Re-raises the exception currently on top of the stack. If oparg is non-zero, - pops an additional value from the stack which is used to set ``f_lasti`` - of the current frame. + pops an additional value from the stack which is used to set + :attr:`~frame.f_lasti` of the current frame. .. versionadded:: 3.9 @@ -920,13 +996,13 @@ 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 :ref:`code object `. + :attr:`~codeobject.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` + Implements ``del name``, where *namei* is the index into :attr:`~codeobject.co_names` attribute of the :ref:`code object `. @@ -966,7 +1042,7 @@ iterations of the loop. value = STACK.pop() obj.name = value - where *namei* is the index of name in :attr:`!co_names` of the + where *namei* is the index of name in :attr:`~codeobject.co_names` of the :ref:`code object `. .. opcode:: DELETE_ATTR (namei) @@ -976,7 +1052,7 @@ iterations of the loop. obj = STACK.pop() del obj.name - where *namei* is the index of name into :attr:`!co_names` of the + where *namei* is the index of name into :attr:`~codeobject.co_names` of the :ref:`code object `. @@ -1133,15 +1209,21 @@ iterations of the loop. .. opcode:: LOAD_SUPER_ATTR (namei) - This opcode implements :func:`super` (e.g. ``super().method()`` and - ``super().attr``). It works the same as :opcode:`LOAD_ATTR`, except that - ``namei`` is shifted left by 2 bits instead of 1, and instead of expecting a - single receiver on the stack, it expects three objects (from top of stack - down): ``self`` (the first argument to the current method), ``cls`` (the - class within which the current method was defined), and the global ``super``. + This opcode implements :func:`super`, both in its zero-argument and + two-argument forms (e.g. ``super().method()``, ``super().attr`` and + ``super(cls, self).method()``, ``super(cls, self).attr``). + + It pops three values from the stack (from top of stack down): + - ``self``: the first argument to the current method + - ``cls``: the class within which the current method was defined + - the global ``super`` + + With respect to its argument, it works similarly to :opcode:`LOAD_ATTR`, + except that ``namei`` is shifted left by 2 bits instead of 1. The low bit of ``namei`` signals to attempt a method load, as with - :opcode:`LOAD_ATTR`. + :opcode:`LOAD_ATTR`, which results in pushing ``None`` and the loaded method. + When it is unset a single value is pushed to the stack. The second-low bit of ``namei``, if set, means that this was a two-argument call to :func:`super` (unset means zero-argument). @@ -1333,7 +1415,7 @@ iterations of the loop. Pushes a reference to the object the cell contains on the stack. .. versionchanged:: 3.11 - ``i`` is no longer offset by the length of ``co_varnames``. + ``i`` is no longer offset by the length of :attr:`~codeobject.co_varnames`. .. opcode:: LOAD_FROM_DICT_OR_DEREF (i) @@ -1355,7 +1437,7 @@ iterations of the loop. storage. .. versionchanged:: 3.11 - ``i`` is no longer offset by the length of ``co_varnames``. + ``i`` is no longer offset by the length of :attr:`~codeobject.co_varnames`. .. opcode:: DELETE_DEREF (i) @@ -1366,7 +1448,7 @@ iterations of the loop. .. versionadded:: 3.2 .. versionchanged:: 3.11 - ``i`` is no longer offset by the length of ``co_varnames``. + ``i`` is no longer offset by the length of :attr:`~codeobject.co_varnames`. .. opcode:: COPY_FREE_VARS (n) @@ -1577,11 +1659,12 @@ iterations of the loop. success (``True``) or failure (``False``). -.. opcode:: RESUME (where) +.. opcode:: RESUME (context) A no-op. Performs internal tracing, debugging and optimization checks. - The ``where`` operand marks where the ``RESUME`` occurs: + The ``context`` oparand consists of two parts. The lowest two bits + indicate where the ``RESUME`` occurs: * ``0`` The start of a function, which is neither a generator, coroutine nor an async generator @@ -1589,8 +1672,14 @@ iterations of the loop. * ``2`` After a ``yield from`` expression * ``3`` After an ``await`` expression + The next bit is ``1`` if the RESUME is at except-depth ``1``, and ``0`` + otherwise. + .. versionadded:: 3.11 + .. versionchanged:: 3.13 + The oparg value changed to include information about except-depth + .. opcode:: RETURN_GENERATOR @@ -1606,9 +1695,9 @@ iterations of the loop. Equivalent to ``STACK[-1] = STACK[-2].send(STACK[-1])``. Used in ``yield from`` and ``await`` statements. - If the call raises :exc:`StopIteration`, pop both items, push the - exception's ``value`` attribute, and increment the bytecode counter by - *delta*. + If the call raises :exc:`StopIteration`, pop the top value from the stack, + push the exception's ``value`` attribute, and increment the bytecode counter + by *delta*. .. versionadded:: 3.11 @@ -1638,7 +1727,7 @@ iterations of the loop. Calls an intrinsic function with one argument. Passes ``STACK[-1]`` as the argument and sets ``STACK[-1]`` to the result. Used to implement - functionality that is necessary but not performance critical. + functionality that is not performance critical. The operand determines which intrinsic function is called: @@ -1686,9 +1775,13 @@ iterations of the loop. .. opcode:: CALL_INTRINSIC_2 - Calls an intrinsic function with two arguments. Passes ``STACK[-2]``, ``STACK[-1]`` as the - arguments and sets ``STACK[-1]`` to the result. Used to implement functionality that is - necessary but not performance critical. + Calls an intrinsic function with two arguments. Used to implement functionality + that is not performance critical:: + + arg2 = STACK.pop() + arg1 = STACK.pop() + result = intrinsic2(arg1, arg2) + STACK.push(result) The operand determines which intrinsic function is called: @@ -1784,8 +1877,9 @@ These collections are provided for automatic introspection of bytecode instructions: .. versionchanged:: 3.12 - The collections now contain pseudo instructions as well. These are - opcodes with values ``>= MIN_PSEUDO_OPCODE``. + The collections now contain pseudo instructions and instrumented + instructions as well. These are opcodes with values ``>= MIN_PSEUDO_OPCODE`` + and ``>= MIN_INSTRUMENTED_OPCODE``. .. data:: opname diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 54a8e79a0ef941..fa1b850c531346 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -143,13 +143,13 @@ Simple Usage: Checking Examples in Docstrings --------------------------------------------- The simplest way to start using doctest (but not necessarily the way you'll -continue to do it) is to end each module :mod:`M` with:: +continue to do it) is to end each module :mod:`!M` with:: if __name__ == "__main__": import doctest doctest.testmod() -:mod:`doctest` then examines docstrings in module :mod:`M`. +:mod:`!doctest` then examines docstrings in module :mod:`!M`. Running the module as a script causes the examples in the docstrings to get executed and verified:: @@ -277,13 +277,34 @@ Which Docstrings Are Examined? The module docstring, and all function, class and method docstrings are searched. Objects imported into the module are not searched. -In addition, if ``M.__test__`` exists and "is true", it must be a dict, and each +In addition, there are cases when you want tests to be part of a module but not part +of the help text, which requires that the tests not be included in the docstring. +Doctest looks for a module-level variable called ``__test__`` and uses it to locate other +tests. If ``M.__test__`` exists and is truthy, it must be a dict, and each entry maps a (string) name to a function object, class object, or string. Function and class object docstrings found from ``M.__test__`` are searched, and strings are treated as if they were docstrings. In output, a key ``K`` in -``M.__test__`` appears with name :: +``M.__test__`` appears with name ``M.__test__.K``. - .__test__.K +For example, place this block of code at the top of :file:`example.py`: + +.. code-block:: python + + __test__ = { + 'numbers': """ + >>> factorial(6) + 720 + + >>> [factorial(n) for n in range(6)] + [1, 1, 2, 6, 24, 120] + """ + } + +The value of ``example.__test__["numbers"]`` will be treated as a +docstring and all the tests inside it will be run. It is +important to note that the value can be mapped to a function, +class object, or module; if so, :mod:`!doctest` +searches them recursively for docstrings, which are then scanned for tests. Any classes found are recursively searched similarly, to test docstrings in their contained methods and nested classes. @@ -382,10 +403,10 @@ What's the Execution Context? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default, each time :mod:`doctest` finds a docstring to test, it uses a -*shallow copy* of :mod:`M`'s globals, so that running tests doesn't change the -module's real globals, and so that one test in :mod:`M` can't leave behind +*shallow copy* of :mod:`!M`'s globals, so that running tests doesn't change the +module's real globals, and so that one test in :mod:`!M` can't leave behind crumbs that accidentally allow another test to work. This means examples can -freely use any names defined at top-level in :mod:`M`, and names defined earlier +freely use any names defined at top-level in :mod:`!M`, and names defined earlier in the docstring being run. Examples cannot see names defined in other docstrings. @@ -937,7 +958,8 @@ and :ref:`doctest-simple-testfile`. Optional argument *exclude_empty* defaults to false. If true, objects for which no doctests are found are excluded from consideration. The default is a backward - compatibility hack, so that code still using :meth:`doctest.master.summarize` in + compatibility hack, so that code still using + :meth:`doctest.master.summarize ` in conjunction with :func:`testmod` continues to get output for objects with no tests. The *exclude_empty* argument to the newer :class:`DocTestFinder` constructor defaults to true. @@ -976,7 +998,7 @@ As your collection of doctest'ed modules grows, you'll want a way to run all their doctests systematically. :mod:`doctest` provides two functions that can be used to create :mod:`unittest` test suites from modules and text files containing doctests. To integrate with :mod:`unittest` test discovery, include -a :func:`load_tests` function in your test module:: +a :ref:`load_tests ` function in your test module:: import unittest import doctest @@ -1090,19 +1112,24 @@ from text files and modules with doctests: :func:`DocTestSuite` returns an empty :class:`unittest.TestSuite` if *module* contains no docstrings instead of raising :exc:`ValueError`. +.. exception:: failureException + + When doctests which have been converted to unit tests by :func:`DocFileSuite` + or :func:`DocTestSuite` fail, this exception is raised showing the name of + the file containing the test and a (sometimes approximate) line number. Under the covers, :func:`DocTestSuite` creates a :class:`unittest.TestSuite` out -of :class:`doctest.DocTestCase` instances, and :class:`DocTestCase` is a -subclass of :class:`unittest.TestCase`. :class:`DocTestCase` isn't documented +of :class:`!doctest.DocTestCase` instances, and :class:`!DocTestCase` is a +subclass of :class:`unittest.TestCase`. :class:`!DocTestCase` isn't documented here (it's an internal detail), but studying its code can answer questions about the exact details of :mod:`unittest` integration. Similarly, :func:`DocFileSuite` creates a :class:`unittest.TestSuite` out of -:class:`doctest.DocFileCase` instances, and :class:`DocFileCase` is a subclass -of :class:`DocTestCase`. +:class:`!doctest.DocFileCase` instances, and :class:`!DocFileCase` is a subclass +of :class:`!DocTestCase`. So both ways of creating a :class:`unittest.TestSuite` run instances of -:class:`DocTestCase`. This is important for a subtle reason: when you run +:class:`!DocTestCase`. This is important for a subtle reason: when you run :mod:`doctest` functions yourself, you can control the :mod:`doctest` options in use directly, by passing option flags to :mod:`doctest` functions. However, if you're writing a :mod:`unittest` framework, :mod:`unittest` ultimately controls @@ -1123,14 +1150,14 @@ reporting flags specific to :mod:`unittest` support, via this function: section :ref:`doctest-options`. Only "reporting flags" can be used. This is a module-global setting, and affects all future doctests run by module - :mod:`unittest`: the :meth:`runTest` method of :class:`DocTestCase` looks at - the option flags specified for the test case when the :class:`DocTestCase` + :mod:`unittest`: the :meth:`!runTest` method of :class:`!DocTestCase` looks at + the option flags specified for the test case when the :class:`!DocTestCase` instance was constructed. If no reporting flags were specified (which is the - typical and expected case), :mod:`doctest`'s :mod:`unittest` reporting flags are + typical and expected case), :mod:`!doctest`'s :mod:`unittest` reporting flags are :ref:`bitwise ORed ` into the option flags, and the option flags so augmented are passed to the :class:`DocTestRunner` instance created to run the doctest. If any reporting flags were specified when the - :class:`DocTestCase` instance was constructed, :mod:`doctest`'s + :class:`!DocTestCase` instance was constructed, :mod:`!doctest`'s :mod:`unittest` reporting flags are ignored. The value of the :mod:`unittest` reporting flags in effect before the function @@ -1300,7 +1327,8 @@ Example Objects A dictionary mapping from option flags to ``True`` or ``False``, which is used to override default options for this example. Any option flags not contained in this dictionary are left at their default value (as specified by the - :class:`DocTestRunner`'s :attr:`optionflags`). By default, no options are set. + :class:`DocTestRunner`'s :ref:`optionflags `). + By default, no options are set. .. _doctest-doctestfinder: @@ -1539,7 +1567,7 @@ DocTestRunner objects The output of each example is checked using the :class:`DocTestRunner`'s output checker, and the results are formatted by the - :meth:`DocTestRunner.report_\*` methods. + :meth:`!DocTestRunner.report_\*` methods. .. method:: summarize(verbose=None) @@ -1714,12 +1742,12 @@ code under the debugger: module) of the object with the doctests of interest. The result is a string, containing the object's docstring converted to a Python script, as described for :func:`script_from_examples` above. For example, if module :file:`a.py` - contains a top-level function :func:`f`, then :: + contains a top-level function :func:`!f`, then :: import a, doctest print(doctest.testsource(a, "a.f")) - prints a script version of function :func:`f`'s docstring, with doctests + prints a script version of function :func:`!f`'s docstring, with doctests converted to code, and the rest placed in comments. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 5bef155a4af310..c4c322a82e1f44 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -367,7 +367,7 @@ Here are the methods of the :class:`Message` class: .. method:: get(name, failobj=None) Return the value of the named header field. This is identical to - :meth:`__getitem__` except that optional *failobj* is returned if the + :meth:`~object.__getitem__` except that optional *failobj* is returned if the named header is missing (defaults to ``None``). Here are some additional useful methods: 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.errors.rst b/Doc/library/email.errors.rst index 194a98696f437d..56aea6598b8615 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -58,6 +58,15 @@ The following exception classes are defined in the :mod:`email.errors` module: :class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g. :class:`~email.mime.image.MIMEImage`). +.. exception:: MessageDefect() + + This is the base class for all defects found when parsing email messages. + It is derived from :exc:`ValueError`. + +.. exception:: HeaderDefect() + + This is the base class for all defects found when parsing email headers. + It is derived from :exc:`MessageDefect`. Here is the list of the defects that the :class:`~email.parser.FeedParser` can find while parsing messages. Note that the defects are added to the message diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 225f498781fa86..f58d93da6ed687 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -247,7 +247,7 @@ message objects. .. method:: get(name, failobj=None) Return the value of the named header field. This is identical to - :meth:`__getitem__` except that optional *failobj* is returned if the + :meth:`~object.__getitem__` except that optional *failobj* is returned if the named header is missing (*failobj* defaults to ``None``). 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/enum.rst b/Doc/library/enum.rst index 7653865f0b9b36..20222bfb3611ab 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -165,7 +165,7 @@ Data Types to subclass *EnumType* -- see :ref:`Subclassing EnumType ` for details. - *EnumType* is responsible for setting the correct :meth:`!__repr__`, + ``EnumType`` is responsible for setting the correct :meth:`!__repr__`, :meth:`!__str__`, :meth:`!__format__`, and :meth:`!__reduce__` methods on the final *enum*, as well as creating the enum members, properly handling duplicates, providing iteration over the enum class, etc. @@ -198,11 +198,12 @@ Data Types >>> some_var = Color.RED >>> some_var in Color True + >>> Color.RED.value in Color + True - .. note:: + .. versionchanged:: 3.12 - In Python 3.12 it will be possible to check for member values and not - just members; until then, a ``TypeError`` will be raised if a + Before Python 3.12, a ``TypeError`` is raised if a non-Enum-member is used in a containment check. .. method:: EnumType.__dir__(cls) @@ -234,6 +235,10 @@ Data Types >>> len(Color) 3 + .. attribute:: EnumType.__members__ + + Returns a mapping of every enum name to its member, including aliases + .. method:: EnumType.__reversed__(cls) Returns each member in *cls* in reverse definition order:: @@ -241,9 +246,19 @@ Data Types >>> list(reversed(Color)) [, , ] + .. method:: EnumType._add_alias_ + + Adds a new name as an alias to an existing member. Raises a + :exc:`NameError` if the name is already assigned to a different member. + + .. method:: EnumType._add_value_alias_ + + Adds a new value as an alias to an existing member. Raises a + :exc:`ValueError` if the value is already linked with a different member. + .. versionadded:: 3.11 - Before 3.11 ``enum`` used ``EnumMeta`` type, which is kept as an alias. + Before 3.11 ``EnumType`` was called ``EnumMeta``, which is still available as an alias. .. class:: Enum @@ -405,7 +420,7 @@ Data Types .. class:: IntEnum - *IntEnum* is the same as *Enum*, but its members are also integers and can be + *IntEnum* is the same as :class:`Enum`, but its members are also integers and can be used anywhere that an integer can be used. If any integer operation is performed with an *IntEnum* member, the resulting value loses its enumeration status. @@ -436,7 +451,7 @@ Data Types .. class:: StrEnum - *StrEnum* is the same as *Enum*, but its members are also strings and can be used + ``StrEnum`` is the same as :class:`Enum`, but its members are also strings and can be used in most of the same places that a string can be used. The result of any string operation performed on or with a *StrEnum* member is not part of the enumeration. @@ -548,7 +563,7 @@ Data Types .. method:: __invert__(self): - Returns all the flags in *type(self)* that are not in self:: + Returns all the flags in *type(self)* that are not in *self*:: >>> ~white @@ -575,7 +590,7 @@ Data Types .. class:: IntFlag - *IntFlag* is the same as *Flag*, but its members are also integers and can be + ``IntFlag`` is the same as :class:`Flag`, but its members are also integers and can be used anywhere that an integer can be used. >>> from enum import IntFlag, auto @@ -595,12 +610,12 @@ Data Types >>> Color.RED + 2 3 - If a *Flag* operation is performed with an *IntFlag* member and: + If a :class:`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 :class:`FlagBoundary` setting - The *repr()* of unnamed zero-valued flags has changed. It is now: + The :func:`repr()` of unnamed zero-valued flags has changed. It is now: >>> Color(0) @@ -625,8 +640,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 @@ -696,7 +711,7 @@ Data Types .. class:: FlagBoundary - *FlagBoundary* controls how out-of-range values are handled in *Flag* and its + ``FlagBoundary`` controls how out-of-range values are handled in :class:`Flag` and its subclasses. .. attribute:: STRICT @@ -719,7 +734,7 @@ Data Types .. attribute:: CONFORM - Out-of-range values have invalid values removed, leaving a valid *Flag* + Out-of-range values have invalid values removed, leaving a valid :class:`Flag` value:: >>> from enum import Flag, CONFORM, auto @@ -733,7 +748,7 @@ Data Types .. attribute:: EJECT - Out-of-range values lose their *Flag* membership and revert to :class:`int`. + Out-of-range values lose their :class:`Flag` membership and revert to :class:`int`. >>> from enum import Flag, EJECT, auto >>> class EjectFlag(Flag, boundary=EJECT): @@ -746,7 +761,7 @@ Data Types .. attribute:: KEEP - Out-of-range values are kept, and the *Flag* membership is kept. + Out-of-range values are kept, and the :class:`Flag` membership is kept. This is the default for :class:`IntFlag`:: >>> from enum import Flag, KEEP, auto @@ -768,37 +783,41 @@ Supported ``__dunder__`` names :attr:`~EnumType.__members__` is a read-only ordered mapping of ``member_name``:``member`` items. It is only available on the class. -:meth:`~object.__new__`, if specified, must create and return the enum members; it is -also a very good idea to set the member's :attr:`!_value_` appropriately. Once -all the members are created it is no longer used. +:meth:`~object.__new__`, if specified, must create and return the enum members; +it is also a very good idea to set the member's :attr:`!_value_` appropriately. +Once all the members are created it is no longer used. Supported ``_sunder_`` names """""""""""""""""""""""""""" -- ``_name_`` -- name of the member -- ``_value_`` -- value of the member; can be set / modified in ``__new__`` - -- ``_missing_`` -- a lookup function used when a value is not found; may be - overridden -- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`, - that will not be transformed into members, and will be removed from the final - class -- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent - (class attribute, removed during class creation) -- ``_generate_next_value_`` -- used to get an appropriate value for an enum - member; may be overridden - - .. note:: - - For standard :class:`Enum` classes the next value chosen is the last value seen - incremented by one. - - For :class:`Flag` classes the next value chosen will be the next highest - power-of-two, regardless of the last value seen. +- :meth:`~EnumType._add_alias_` -- adds a new name as an alias to an existing + member. +- :meth:`~EnumType._add_value_alias_` -- adds a new value as an alias to an + existing member. +- :attr:`~Enum._name_` -- name of the member +- :attr:`~Enum._value_` -- value of the member; can be set in ``__new__`` +- :meth:`~Enum._missing_` -- a lookup function used when a value is not found; + may be overridden +- :attr:`~Enum._ignore_` -- a list of names, either as a :class:`list` or a + :class:`str`, that will not be transformed into members, and will be removed + from the final class +- :attr:`~Enum._order_` -- used in Python 2/3 code to ensure member order is + consistent (class attribute, removed during class creation) +- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for + an enum member; may be overridden + + .. note:: + + For standard :class:`Enum` classes the next value chosen is the highest + value seen incremented by one. + + For :class:`Flag` classes the next value chosen will be the next highest + power-of-two. .. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_`` .. versionadded:: 3.7 ``_ignore_`` +.. versionadded:: 3.13 ``_add_alias_``, ``_add_value_alias_`` --------------- @@ -808,20 +827,20 @@ Utilities and Decorators .. class:: auto *auto* can be used in place of a value. If used, the *Enum* machinery will - call an *Enum*'s :meth:`~Enum._generate_next_value_` to get an appropriate value. - For *Enum* and *IntEnum* that appropriate value will be the last value plus - one; for *Flag* and *IntFlag* it will be the first power-of-two greater - than the highest value; for *StrEnum* it will be the lower-cased version of + call an :class:`Enum`'s :meth:`~Enum._generate_next_value_` to get an appropriate value. + For :class:`Enum` and :class:`IntEnum` that appropriate value will be the last value plus + one; for :class:`Flag` and :class:`IntFlag` it will be the first power-of-two greater + than the highest value; for :class:`StrEnum` it will be the lower-cased version of the member's name. Care must be taken if mixing *auto()* with manually specified values. *auto* instances are only resolved when at the top level of an assignment: - * ``FIRST = auto()`` will work (auto() is replaced with ``1``); - * ``SECOND = auto(), -2`` will work (auto is replaced with ``2``, so ``2, -2`` is - used to create the ``SECOND`` enum member; - * ``THREE = [auto(), -3]`` will *not* work (``, -3`` is used to - create the ``THREE`` enum member) + * ``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/exceptions.rst b/Doc/library/exceptions.rst index fae0cf621323c8..04686b6db0036c 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -38,36 +38,48 @@ information on defining exceptions is available in the Python Tutorial under Exception context ----------------- -When raising a new exception while another exception -is already being handled, the new exception's -:attr:`__context__` attribute is automatically set to the handled -exception. An exception may be handled when an :keyword:`except` or -:keyword:`finally` clause, or a :keyword:`with` statement, is used. - -This implicit exception context can be -supplemented with an explicit cause by using :keyword:`!from` with -:keyword:`raise`:: - - raise new_exc from original_exc - -The expression following :keyword:`from` must be an exception or ``None``. It -will be set as :attr:`__cause__` on the raised exception. Setting -:attr:`__cause__` also implicitly sets the :attr:`__suppress_context__` -attribute to ``True``, so that using ``raise new_exc from None`` -effectively replaces the old exception with the new one for display -purposes (e.g. converting :exc:`KeyError` to :exc:`AttributeError`), while -leaving the old exception available in :attr:`__context__` for introspection -when debugging. - -The default traceback display code shows these chained exceptions in -addition to the traceback for the exception itself. An explicitly chained -exception in :attr:`__cause__` is always shown when present. An implicitly -chained exception in :attr:`__context__` is shown only if :attr:`__cause__` -is :const:`None` and :attr:`__suppress_context__` is false. - -In either case, the exception itself is always shown after any chained -exceptions so that the final line of the traceback always shows the last -exception that was raised. +.. index:: pair: exception; chaining + __cause__ (exception attribute) + __context__ (exception attribute) + __suppress_context__ (exception attribute) + +Three attributes on exception objects provide information about the context in +which an the exception was raised: + +.. attribute:: BaseException.__context__ + BaseException.__cause__ + BaseException.__suppress_context__ + + When raising a new exception while another exception + is already being handled, the new exception's + :attr:`!__context__` attribute is automatically set to the handled + exception. An exception may be handled when an :keyword:`except` or + :keyword:`finally` clause, or a :keyword:`with` statement, is used. + + This implicit exception context can be + supplemented with an explicit cause by using :keyword:`!from` with + :keyword:`raise`:: + + raise new_exc from original_exc + + The expression following :keyword:`from` must be an exception or ``None``. It + will be set as :attr:`!__cause__` on the raised exception. Setting + :attr:`!__cause__` also implicitly sets the :attr:`!__suppress_context__` + attribute to ``True``, so that using ``raise new_exc from None`` + effectively replaces the old exception with the new one for display + purposes (e.g. converting :exc:`KeyError` to :exc:`AttributeError`), while + leaving the old exception available in :attr:`!__context__` for introspection + when debugging. + + The default traceback display code shows these chained exceptions in + addition to the traceback for the exception itself. An explicitly chained + exception in :attr:`!__cause__` is always shown when present. An implicitly + chained exception in :attr:`!__context__` is shown only if :attr:`!__cause__` + is :const:`None` and :attr:`!__suppress_context__` is false. + + In either case, the exception itself is always shown after any chained + exceptions so that the final line of the traceback always shows the last + exception that was raised. Inheriting from built-in exceptions @@ -126,6 +138,12 @@ The following exceptions are used mostly as base classes for other exceptions. tb = sys.exception().__traceback__ raise OtherException(...).with_traceback(tb) + .. attribute:: __traceback__ + + A writable field that holds the + :ref:`traceback object ` associated with this + exception. See also: :ref:`raise`. + .. method:: add_note(note) Add the string ``note`` to the exception's notes which appear in the standard @@ -220,10 +238,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. @@ -423,9 +447,11 @@ The following exceptions are the exceptions that are usually raised. :meth:`~iterator.__next__` method to signal that there are no further items produced by the iterator. - The exception object has a single attribute :attr:`value`, which is - given as an argument when constructing the exception, and defaults - to :const:`None`. + .. attribute:: StopIteration.value + + The exception object has a single attribute :attr:`!value`, which is + given as an argument when constructing the exception, and defaults + to :const:`None`. When a :term:`generator` or :term:`coroutine` function returns, a new :exc:`StopIteration` instance is @@ -921,8 +947,10 @@ their subgroups based on the types of the contained exceptions. true for the exceptions that should be in the subgroup. The nesting structure of the current exception is preserved in the result, - as are the values of its :attr:`message`, :attr:`__traceback__`, - :attr:`__cause__`, :attr:`__context__` and :attr:`__notes__` fields. + as are the values of its :attr:`message`, + :attr:`~BaseException.__traceback__`, :attr:`~BaseException.__cause__`, + :attr:`~BaseException.__context__` and + :attr:`~BaseException.__notes__` fields. Empty nested groups are omitted from the result. The condition is checked for all exceptions in the nested exception group, @@ -948,10 +976,14 @@ their subgroups based on the types of the contained exceptions. and :meth:`split` return instances of the subclass rather than :exc:`ExceptionGroup`. - :meth:`subgroup` and :meth:`split` copy the :attr:`__traceback__`, - :attr:`__cause__`, :attr:`__context__` and :attr:`__notes__` fields from + :meth:`subgroup` and :meth:`split` copy the + :attr:`~BaseException.__traceback__`, + :attr:`~BaseException.__cause__`, :attr:`~BaseException.__context__` and + :attr:`~BaseException.__notes__` fields from the original exception group to the one returned by :meth:`derive`, so - these fields do not need to be updated by :meth:`derive`. :: + these fields do not need to be updated by :meth:`derive`. + + .. doctest:: >>> class MyGroup(ExceptionGroup): ... def derive(self, excs): diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 969a79fa873395..309ad652d4af34 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -18,7 +18,7 @@ interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines. For a complete description of these calls, see :manpage:`fcntl(2)` and :manpage:`ioctl(2)` Unix manual pages. -.. include:: ../includes/wasm-notavail.rst +.. availability:: Unix, not Emscripten, not WASI. All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 35206097064284..c731b6fd333275 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -57,7 +57,8 @@ are always available. They are listed here in alphabetical order. .. function:: abs(x) Return the absolute value of a number. The argument may be an - integer, a floating point number, or an object implementing :meth:`__abs__`. + integer, a floating point number, or an object implementing + :meth:`~object.__abs__`. If the argument is a complex number, its magnitude is returned. @@ -235,7 +236,7 @@ are always available. They are listed here in alphabetical order. :const:`False` if not. If this returns ``True``, it is still possible that a call fails, but if it is ``False``, calling *object* will never succeed. Note that classes are callable (calling a class returns a new instance); - instances are callable if their class has a :meth:`__call__` method. + instances are callable if their class has a :meth:`~object.__call__` method. .. versionadded:: 3.2 This function was first removed in Python 3.0 and then brought back @@ -285,7 +286,7 @@ are always available. They are listed here in alphabetical order. ``__name__``, ``__qualname__``, ``__doc__`` and ``__annotations__``) and have a new ``__wrapped__`` attribute. - .. versionchanged:: 3.11 + .. deprecated-removed:: 3.11 3.13 Class methods can no longer wrap other :term:`descriptors ` such as :func:`property`. @@ -432,15 +433,18 @@ are always available. They are listed here in alphabetical order. Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object. - If the object has a method named :meth:`__dir__`, this method will be called and + If the object has a method named :meth:`~object.__dir__`, + this method will be called and must return the list of attributes. This allows objects that implement a custom - :func:`__getattr__` or :func:`__getattribute__` function to customize the way + :func:`~object.__getattr__` or :func:`~object.__getattribute__` function + to customize the way :func:`dir` reports their attributes. - If the object does not provide :meth:`__dir__`, the function tries its best to - gather information from the object's :attr:`~object.__dict__` attribute, if defined, and + If the object does not provide :meth:`~object.__dir__`, + the function tries its best to gather information from the object's + :attr:`~object.__dict__` attribute, if defined, and from its type object. The resulting list is not necessarily complete and may - be inaccurate when the object has a custom :func:`__getattr__`. + be inaccurate when the object has a custom :func:`~object.__getattr__`. The default :func:`dir` mechanism behaves differently with different types of objects, as it attempts to produce the most relevant, rather than complete, @@ -664,7 +668,7 @@ are always available. They are listed here in alphabetical order. sign: "+" | "-" infinity: "Infinity" | "inf" nan: "nan" - digitpart: `digit` (["_"] `digit`)* + digitpart: `!digit` (["_"] `!digit`)* number: [`digitpart`] "." `digitpart` | `digitpart` ["."] exponent: ("e" | "E") ["+" | "-"] `digitpart` floatnumber: number [`exponent`] @@ -727,8 +731,8 @@ are always available. They are listed here in alphabetical order. A call to ``format(value, format_spec)`` is translated to ``type(value).__format__(value, format_spec)`` which bypasses the instance - dictionary when searching for the value's :meth:`__format__` method. A - :exc:`TypeError` exception is raised if the method search reaches + dictionary when searching for the value's :meth:`~object.__format__` method. + A :exc:`TypeError` exception is raised if the method search reaches :mod:`object` and the *format_spec* is non-empty, or if either the *format_spec* or the return value are not strings. @@ -792,9 +796,9 @@ are always available. They are listed here in alphabetical order. .. note:: - For objects with custom :meth:`__hash__` methods, note that :func:`hash` + For objects with custom :meth:`~object.__hash__` methods, + note that :func:`hash` truncates the return value based on the bit width of the host machine. - See :meth:`__hash__ ` for details. .. function:: help() help(request) @@ -982,8 +986,9 @@ are always available. They are listed here in alphabetical order. Return an :term:`iterator` object. The first argument is interpreted very differently depending on the presence of the second argument. Without a second argument, *object* must be a collection object which supports the - :term:`iterable` protocol (the :meth:`__iter__` method), or it must support - the sequence protocol (the :meth:`__getitem__` method with integer arguments + :term:`iterable` protocol (the :meth:`~object.__iter__` method), + or it must support + the sequence protocol (the :meth:`~object.__getitem__` method with integer arguments starting at ``0``). If it does not support either of those protocols, :exc:`TypeError` is raised. If the second argument, *sentinel*, is given, then *object* must be a callable object. The iterator created in this case @@ -1158,8 +1163,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) @@ -1221,7 +1226,7 @@ are always available. They are listed here in alphabetical order. *buffering* is an optional integer used to set the buffering policy. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select line - buffering (only usable in text mode), and an integer > 1 to indicate the size + buffering (only usable when writing in text mode), and an integer > 1 to indicate the size in bytes of a fixed-size chunk buffer. Note that specifying a buffer size this way applies for binary buffered I/O, but ``TextIOWrapper`` (i.e., files opened with ``mode='r+'``) would have another buffering. To disable buffering in @@ -1360,28 +1365,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. @@ -1500,38 +1505,44 @@ are always available. They are listed here in alphabetical order. """Get the current voltage.""" return self._voltage - The ``@property`` decorator turns the :meth:`voltage` method into a "getter" + The ``@property`` decorator turns the :meth:`!voltage` method into a "getter" for a read-only attribute with the same name, and it sets the docstring for *voltage* to "Get the current voltage." - A property object has :attr:`~property.getter`, :attr:`~property.setter`, - and :attr:`~property.deleter` methods usable as decorators that create a - copy of the property with the corresponding accessor function set to the - decorated function. This is best explained with an example:: + .. decorator:: property.getter + .. decorator:: property.setter + .. decorator:: property.deleter - class C: - def __init__(self): - self._x = None + A property object has ``getter``, ``setter``, + and ``deleter`` methods usable as decorators that create a + copy of the property with the corresponding accessor function set to the + decorated function. This is best explained with an example: - @property - def x(self): - """I'm the 'x' property.""" - return self._x + .. testcode:: - @x.setter - def x(self, value): - self._x = value + class C: + def __init__(self): + self._x = None - @x.deleter - def x(self): - del self._x + @property + def x(self): + """I'm the 'x' property.""" + return self._x + + @x.setter + def x(self, value): + self._x = value + + @x.deleter + def x(self): + del self._x - This code is exactly equivalent to the first example. Be sure to give the - additional functions the same name as the original property (``x`` in this - case.) + This code is exactly equivalent to the first example. Be sure to give the + additional functions the same name as the original property (``x`` in this + case.) - The returned property object also has the attributes ``fget``, ``fset``, and - ``fdel`` corresponding to the constructor arguments. + The returned property object also has the attributes ``fget``, ``fset``, and + ``fdel`` corresponding to the constructor arguments. .. versionchanged:: 3.5 The docstrings of property objects are now writeable. @@ -1554,7 +1565,8 @@ are always available. They are listed here in alphabetical order. representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this - function returns for its instances by defining a :meth:`__repr__` method. + function returns for its instances + by defining a :meth:`~object.__repr__` method. If :func:`sys.displayhook` is not accessible, this function will raise :exc:`RuntimeError`. @@ -1562,9 +1574,9 @@ are always available. They are listed here in alphabetical order. .. function:: reversed(seq) Return a reverse :term:`iterator`. *seq* must be an object which has - a :meth:`__reversed__` method or supports the sequence protocol (the - :meth:`__len__` method and the :meth:`__getitem__` method with integer - arguments starting at ``0``). + a :meth:`~object.__reversed__` method or supports the sequence protocol (the + :meth:`~object.__len__` method and the :meth:`~object.__getitem__` method + with integer arguments starting at ``0``). .. function:: round(number, ndigits=None) @@ -1635,13 +1647,21 @@ are always available. They are listed here in alphabetical order. Return a :term:`slice` object representing the set of indices specified by ``range(start, stop, step)``. The *start* and *step* arguments default to - ``None``. Slice objects have read-only data attributes :attr:`~slice.start`, - :attr:`~slice.stop`, and :attr:`~slice.step` which merely return the argument - values (or their default). They have no other explicit functionality; - however, they are used by NumPy and other third-party packages. + ``None``. + + .. attribute:: slice.start + .. attribute:: slice.stop + .. attribute:: slice.step + + Slice objects have read-only data attributes :attr:`!start`, + :attr:`!stop`, and :attr:`!step` which merely return the argument + values (or their default). They have no other explicit functionality; + however, they are used by NumPy and other third-party packages. + Slice objects are also generated when extended indexing syntax is used. For example: ``a[start:stop:step]`` or ``a[start:stop, i]``. See - :func:`itertools.islice` for an alternate version that returns an iterator. + :func:`itertools.islice` for an alternate version that returns an + :term:`iterator`. .. versionchanged:: 3.12 Slice objects are now :term:`hashable` (provided :attr:`~slice.start`, @@ -1808,7 +1828,8 @@ are always available. They are listed here in alphabetical order. Note that :func:`super` is implemented as part of the binding process for explicit dotted attribute lookups such as ``super().__getitem__(name)``. - It does so by implementing its own :meth:`__getattribute__` method for searching + It does so by implementing its own :meth:`~object.__getattribute__` method + for searching classes in a predictable order that supports cooperative multiple inheritance. Accordingly, :func:`super` is undefined for implicit lookups using statements or operators such as ``super()[name]``. diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 331c071cda7692..82277aa52aee01 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -42,8 +42,8 @@ The :mod:`gc` module provides the following functions: With no arguments, run a full collection. The optional argument *generation* may be an integer specifying which generation to collect (from 0 to 2). A - :exc:`ValueError` is raised if the generation number is invalid. The number of - unreachable objects found is returned. + :exc:`ValueError` is raised if the generation number is invalid. The sum of + collected objects and uncollectable objects is returned. The free lists maintained for a number of built-in types are cleared whenever a full collection or collection of the highest generation (2) diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index d5bbe67fb30a62..54c84d45a59856 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -43,10 +43,13 @@ The :mod:`getpass` module provides two functions: Return the "login name" of the user. This function checks the environment variables :envvar:`LOGNAME`, - :envvar:`USER`, :envvar:`LNAME` and :envvar:`USERNAME`, in order, and + :envvar:`USER`, :envvar:`!LNAME` and :envvar:`USERNAME`, in order, and returns the value of the first one which is set to a non-empty string. If none are set, the login name from the password database is returned on - systems which support the :mod:`pwd` module, otherwise, an exception is - raised. + systems which support the :mod:`pwd` module, otherwise, an :exc:`OSError` + is raised. In general, this function should be preferred over :func:`os.getlogin()`. + + .. versionchanged:: 3.13 + Previously, various exceptions beyond just :exc:`OSError` were raised. diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 88a65b980d310f..41beac3e0c7396 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. @@ -260,7 +257,7 @@ are the methods of :class:`!NullTranslations`: .. method:: info() - Return the "protected" :attr:`_info` variable, a dictionary containing + Return a dictionary containing the metadata found in the message catalog file. @@ -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 @@ -299,9 +296,9 @@ are the methods of :class:`!NullTranslations`: The :class:`GNUTranslations` class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The :mod:`gettext` module provides one additional class derived from +The :mod:`!gettext` module provides one additional class derived from :class:`NullTranslations`: :class:`GNUTranslations`. This class overrides -:meth:`_parse` to enable reading GNU :program:`gettext` format :file:`.mo` files +:meth:`!_parse` to enable reading GNU :program:`gettext` format :file:`.mo` files in both big-endian and little-endian format. :class:`GNUTranslations` parses optional metadata out of the translation @@ -309,16 +306,16 @@ catalog. It is convention with GNU :program:`gettext` to include metadata as the translation for the empty string. This metadata is in :rfc:`822`\ -style ``key: value`` pairs, and should contain the ``Project-Id-Version`` key. If the key ``Content-Type`` is found, then the ``charset`` property is used to -initialize the "protected" :attr:`_charset` instance variable, defaulting to +initialize the "protected" :attr:`!_charset` instance variable, defaulting to ``None`` if not found. If the charset encoding is specified, then all message 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 -"protected" :attr:`_info` instance variable. +"protected" :attr:`!_info` instance variable. If the :file:`.mo` file's magic number is invalid, the major version number is unexpected, or if other problems occur while reading the file, instantiating a @@ -404,7 +401,7 @@ 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 @@ -432,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') @@ -504,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. @@ -581,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. @@ -606,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 @@ -639,9 +636,9 @@ implementations, and valuable experience to the creation of this module: .. rubric:: Footnotes -.. [#] The default locale directory is system dependent; for example, on RedHat Linux +.. [#] The default locale directory is system dependent; for example, on Red Hat Linux it is :file:`/usr/share/locale`, but on Solaris it is :file:`/usr/lib/locale`. - The :mod:`gettext` module does not try to support these system dependent + The :mod:`!gettext` module does not try to support these system dependent defaults; instead its default is :file:`{sys.base_prefix}/share/locale` (see :data:`sys.base_prefix`). For this reason, it is always best to call :func:`bindtextdomain` with an explicit absolute path at the start of your diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 0e4cfe7ebed797..6e4f72c19ff4c9 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -34,9 +34,7 @@ unlike :func:`fnmatch.fnmatch` or :func:`pathlib.Path.glob`. For a literal match, wrap the meta-characters in brackets. For example, ``'[?]'`` matches the character ``'?'``. - -.. seealso:: - The :mod:`pathlib` module offers high-level path objects. +The :mod:`glob` module defines the following functions: .. function:: glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, \ @@ -117,7 +115,48 @@ For example, ``'[?]'`` matches the character ``'?'``. .. versionadded:: 3.4 -For example, consider a directory containing the following files: +.. function:: translate(pathname, *, recursive=False, include_hidden=False, seps=None) + + Convert the given path specification to a regular expression for use with + :func:`re.match`. The path specification can contain shell-style wildcards. + + For example: + + >>> import glob, re + >>> + >>> regex = glob.translate('**/*.txt', recursive=True, include_hidden=True) + >>> regex + '(?s:(?:.+/)?[^/]*\\.txt)\\Z' + >>> reobj = re.compile(regex) + >>> reobj.match('foo/bar/baz.txt') + + + Path separators and segments are meaningful to this function, unlike + :func:`fnmatch.translate`. By default wildcards do not match path + separators, and ``*`` pattern segments match precisely one path segment. + + If *recursive* is true, the pattern segment "``**``" will match any number + of path segments. If "``**``" occurs in any position other than a full + pattern segment, :exc:`ValueError` is raised. + + If *include_hidden* is true, wildcards can match path segments that start + with a dot (``.``). + + A sequence of path separators may be supplied to the *seps* argument. If + not given, :data:`os.sep` and :data:`~os.altsep` (if available) are used. + + .. seealso:: + + :meth:`pathlib.PurePath.match` and :meth:`pathlib.Path.glob` methods, + which call this function to implement pattern matching and globbing. + + .. versionadded:: 3.13 + + +Examples +-------- + +Consider a directory containing the following files: :file:`1.gif`, :file:`2.txt`, :file:`card.gif` and a subdirectory :file:`sub` which contains only the file :file:`3.txt`. :func:`glob` will produce the following results. Notice how any leading components of the path are @@ -146,6 +185,7 @@ default. For example, consider a directory containing :file:`card.gif` and ['.card.gif'] .. seealso:: + The :mod:`fnmatch` module offers shell-style filename (not path) expansion. - Module :mod:`fnmatch` - Shell-style filename (not path) expansion +.. seealso:: + The :mod:`pathlib` module offers high-level path objects. diff --git a/Doc/library/graphlib.rst b/Doc/library/graphlib.rst index fdd8f39ef4e1c4..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 diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 8f88f82e1c21ad..274a353103b488 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -10,7 +10,7 @@ This module provides access to the Unix group database. It is available on all Unix versions. -.. include:: ../includes/wasm-notavail.rst +.. availability:: Unix, not Emscripten, not WASI. Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 6a4f2c76ae4e10..50cde09fa10a9d 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -105,7 +105,7 @@ The module defines the following items: should only be provided in compression mode. If omitted or ``None``, the current time is used. See the :attr:`mtime` attribute for more details. - Calling a :class:`GzipFile` object's :meth:`close` method does not close + Calling a :class:`GzipFile` object's :meth:`!close` method does not close *fileobj*, since you might wish to append more material after the compressed data. This also allows you to pass an :class:`io.BytesIO` object opened for writing as *fileobj*, and retrieve the resulting memory buffer using the @@ -268,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 :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/hmac.rst b/Doc/library/hmac.rst index b2ca0455d3745c..43012e03c580e8 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -14,7 +14,7 @@ This module implements the HMAC algorithm as described by :rfc:`2104`. -.. function:: new(key, msg=None, digestmod='') +.. function:: new(key, msg=None, digestmod) Return a new hmac object. *key* is a bytes or bytearray object giving the secret key. If *msg* is present, the method call ``update(msg)`` is made. @@ -27,10 +27,9 @@ This module implements the HMAC algorithm as described by :rfc:`2104`. Parameter *msg* can be of any type supported by :mod:`hashlib`. Parameter *digestmod* can be the name of a hash algorithm. - .. deprecated-removed:: 3.4 3.8 - MD5 as implicit default digest for *digestmod* is deprecated. - The digestmod parameter is now required. Pass it as a keyword - argument to avoid awkwardness when you do not have an initial msg. + .. versionchanged:: 3.8 + The *digestmod* argument is now required. Pass it as a keyword + argument to avoid awkwardness when you do not have an initial *msg*. .. function:: digest(key, msg, digest) @@ -114,11 +113,9 @@ A hash object has the following attributes: .. versionadded:: 3.4 -.. deprecated:: 3.9 - - The undocumented attributes ``HMAC.digest_cons``, ``HMAC.inner``, and - ``HMAC.outer`` are internal implementation details and will be removed in - Python 3.10. +.. versionchanged:: 3.10 + Removed the undocumented attributes ``HMAC.digest_cons``, ``HMAC.inner``, + and ``HMAC.outer``. This module also provides the following helper function: 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.cookies.rst b/Doc/library/http.cookies.rst index a2c1eb00d8b33d..e91972fe621a48 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -18,16 +18,17 @@ cookie value. The module formerly strictly applied the parsing rules described in the :rfc:`2109` and :rfc:`2068` specifications. It has since been discovered that -MSIE 3.0x doesn't follow the character rules outlined in those specs and also -many current day browsers and servers have relaxed parsing rules when comes to -Cookie handling. As a result, the parsing rules used are a bit less strict. +MSIE 3.0x didn't follow the character rules outlined in those specs; many +current-day browsers and servers have also relaxed parsing rules when it comes +to cookie handling. As a result, this module now uses parsing rules that are a +bit less strict than they once were. The character set, :data:`string.ascii_letters`, :data:`string.digits` and ``!#$%&'*+-.^_`|~:`` denote the set of valid characters allowed by this module -in Cookie name (as :attr:`~Morsel.key`). +in a cookie name (as :attr:`~Morsel.key`). .. versionchanged:: 3.3 - Allowed ':' as a valid Cookie name character. + Allowed ':' as a valid cookie name character. .. note:: @@ -54,9 +55,10 @@ in Cookie name (as :attr:`~Morsel.key`). .. class:: SimpleCookie([input]) - This class derives from :class:`BaseCookie` and overrides :meth:`value_decode` - and :meth:`value_encode`. SimpleCookie supports strings as cookie values. - When setting the value, SimpleCookie calls the builtin :func:`str()` to convert + This class derives from :class:`BaseCookie` and overrides :meth:`~BaseCookie.value_decode` + and :meth:`~BaseCookie.value_encode`. :class:`!SimpleCookie` supports + strings as cookie values. When setting the value, :class:`!SimpleCookie` + calls the builtin :func:`str` to convert the value to a string. Values received from HTTP are kept as strings. .. seealso:: @@ -129,17 +131,17 @@ Morsel Objects Abstract a key/value pair, which has some :rfc:`2109` attributes. Morsels are dictionary-like objects, whose set of keys is constant --- the valid - :rfc:`2109` attributes, which are - - * ``expires`` - * ``path`` - * ``comment`` - * ``domain`` - * ``max-age`` - * ``secure`` - * ``version`` - * ``httponly`` - * ``samesite`` + :rfc:`2109` attributes, which are: + + .. attribute:: expires + path + comment + domain + max-age + secure + version + httponly + samesite The attribute :attr:`httponly` specifies that the cookie is only transferred in HTTP requests, and is not accessible through JavaScript. This is intended @@ -152,7 +154,7 @@ Morsel Objects The keys are case-insensitive and their default value is ``''``. .. versionchanged:: 3.5 - :meth:`~Morsel.__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value` + :meth:`!__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value` into account. .. versionchanged:: 3.7 diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 6f79b222790094..64bddd23f82933 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -65,10 +65,10 @@ provides three different variants: The handler will parse the request and the headers, then call a method specific to the request type. The method name is constructed from the - request. For example, for the request method ``SPAM``, the :meth:`do_SPAM` + request. For example, for the request method ``SPAM``, the :meth:`!do_SPAM` method will be called with no arguments. All of the relevant information is stored in instance variables of the handler. Subclasses should not need to - override or extend the :meth:`__init__` method. + override or extend the :meth:`!__init__` method. :class:`BaseHTTPRequestHandler` has the following instance variables: @@ -187,13 +187,13 @@ provides three different variants: Calls :meth:`handle_one_request` once (or, if persistent connections are enabled, multiple times) to handle incoming HTTP requests. You should - never need to override it; instead, implement appropriate :meth:`do_\*` + never need to override it; instead, implement appropriate :meth:`!do_\*` methods. .. method:: handle_one_request() This method will parse and dispatch the request to the appropriate - :meth:`do_\*` method. You should never need to override it. + :meth:`!do_\*` method. You should never need to override it. .. method:: handle_expect_100() diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 3211da50dc745c..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. diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index d2cc769e2c8400..1df7d8d772a274 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -41,7 +41,7 @@ and metadata defined by the `Core metadata specifications ` + You can use :ref:`packages_distributions() ` to get a mapping between them. By default, distribution metadata can live on the file system diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst index 3de97e80311a17..a5adf0b8546dbf 100644 --- a/Doc/library/importlib.resources.rst +++ b/Doc/library/importlib.resources.rst @@ -50,7 +50,7 @@ for example, a package and its resources can be imported from a zip file using ``get_resource_reader(fullname)`` method as specified by :class:`importlib.resources.abc.ResourceReader`. -.. data:: Anchor +.. class:: Anchor Represents an anchor for resources, either a :class:`module object ` or a module name as a string. Defined as @@ -63,7 +63,7 @@ for example, a package and its resources can be imported from a zip file using (think files). A Traversable may contain other containers (think subdirectories). - *anchor* is an optional :data:`Anchor`. If the anchor is a + *anchor* is an optional :class:`Anchor`. If the anchor is a package, resources are resolved from that package. If a module, resources are resolved adjacent to that module (in the same package or the package root). If the anchor is omitted, the caller's module @@ -72,10 +72,10 @@ for example, a package and its resources can be imported from a zip file using .. versionadded:: 3.9 .. versionchanged:: 3.12 - "package" parameter was renamed to "anchor". "anchor" can now + *package* parameter was renamed to *anchor*. *anchor* can now be a non-package module and if omitted will default to the caller's - module. "package" is still accepted for compatibility but will raise - a DeprecationWarning. Consider passing the anchor positionally or + module. *package* is still accepted for compatibility but will raise + a :exc:`DeprecationWarning`. Consider passing the anchor positionally or using ``importlib_resources >= 5.10`` for a compatible interface on older Pythons. @@ -96,4 +96,4 @@ for example, a package and its resources can be imported from a zip file using .. versionadded:: 3.9 .. versionchanged:: 3.12 - Added support for ``traversable`` representing a directory. + Added support for *traversable* representing a directory. diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index fc954724bb72fe..2402bc5cd3ee2c 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1145,7 +1145,7 @@ find and load modules. .. versionadded:: 3.4 -.. class:: NamespaceLoader(name, path, path_finder): +.. class:: NamespaceLoader(name, path, path_finder) A concrete implementation of :class:`importlib.abc.InspectLoader` for namespace packages. This is an alias for a private class and is only made diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index fe0ed135029f0f..f8b3e39c4f54f0 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -1,6 +1,11 @@ :mod:`inspect` --- Inspect live objects ======================================= +.. testsetup:: * + + import inspect + from inspect import * + .. module:: inspect :synopsis: Extract information and source code from live objects. @@ -268,7 +273,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes): :func:`getmembers` will only return class attributes defined in the metaclass when the argument is a class and those attributes have been - listed in the metaclass' custom :meth:`__dir__`. + listed in the metaclass' custom :meth:`~object.__dir__`. .. function:: getmembers_static(object[, predicate]) @@ -387,7 +392,11 @@ attributes (see :ref:`import-mod-attrs` for module attributes): Return ``True`` if the object can be used in :keyword:`await` expression. Can also be used to distinguish generator-based coroutines from regular - generators:: + generators: + + .. testcode:: + + import types def gen(): yield @@ -404,13 +413,15 @@ attributes (see :ref:`import-mod-attrs` for module attributes): .. function:: isasyncgenfunction(object) Return ``True`` if the object is an :term:`asynchronous generator` function, - for example:: + for example: - >>> async def agen(): - ... yield 1 - ... - >>> inspect.isasyncgenfunction(agen) - True + .. doctest:: + + >>> async def agen(): + ... yield 1 + ... + >>> inspect.isasyncgenfunction(agen) + True .. versionadded:: 3.6 @@ -476,12 +487,13 @@ attributes (see :ref:`import-mod-attrs` for module attributes): has a :meth:`~object.__get__` method but not a :meth:`~object.__set__` method, but beyond that the set of attributes varies. A :attr:`~definition.__name__` attribute is usually - sensible, and :attr:`__doc__` often is. + sensible, and :attr:`!__doc__` often is. Methods implemented via descriptors that also pass one of the other tests return ``False`` from the :func:`ismethoddescriptor` test, simply because the other tests promise more -- you can, e.g., count on having the - :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`. + :attr:`~method.__func__` attribute (etc) when an object passes + :func:`ismethod`. .. function:: isdatadescriptor(object) @@ -492,7 +504,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes): Examples are properties (defined in Python), getsets, and members. The latter two are defined in C and there are more specific tests available for those types, which is robust across Python implementations. Typically, data - descriptors will also have :attr:`~definition.__name__` and :attr:`__doc__` attributes + descriptors will also have :attr:`~definition.__name__` and :attr:`!__doc__` attributes (properties, getsets, and members have both of these attributes), but this is not guaranteed. @@ -614,13 +626,16 @@ Introspecting callables with the Signature object .. versionadded:: 3.3 -The Signature object represents the call signature of a callable object and its -return annotation. To retrieve a Signature object, use the :func:`signature` +The :class:`Signature` object represents the call signature of a callable object +and its return annotation. To retrieve a :class:`!Signature` object, +use the :func:`!signature` function. .. function:: signature(callable, *, follow_wrapped=True, globals=None, locals=None, eval_str=False) - Return a :class:`Signature` object for the given ``callable``:: + Return a :class:`Signature` object for the given *callable*: + + .. doctest:: >>> from inspect import signature >>> def foo(a, *, b:int, **kwargs): @@ -629,10 +644,10 @@ function. >>> sig = signature(foo) >>> str(sig) - '(a, *, b:int, **kwargs)' + '(a, *, b: int, **kwargs)' >>> str(sig.parameters['b']) - 'b:int' + 'b: int' >>> sig.parameters['b'].annotation @@ -640,32 +655,36 @@ function. Accepts a wide range of Python callables, from plain functions and classes to :func:`functools.partial` objects. + If the passed object has a ``__signature__`` attribute, this function + returns it without further computations. + For objects defined in modules using stringized annotations (``from __future__ import annotations``), :func:`signature` will attempt to automatically un-stringize the annotations using - :func:`inspect.get_annotations()`. The - ``global``, ``locals``, and ``eval_str`` parameters are passed - into :func:`inspect.get_annotations()` when resolving the - annotations; see the documentation for :func:`inspect.get_annotations()` + :func:`get_annotations`. The + *globals*, *locals*, and *eval_str* parameters are passed + into :func:`get_annotations` when resolving the + annotations; see the documentation for :func:`get_annotations` for instructions on how to use these parameters. Raises :exc:`ValueError` if no signature can be provided, and :exc:`TypeError` if that type of object is not supported. Also, - if the annotations are stringized, and ``eval_str`` is not false, - the ``eval()`` call(s) to un-stringize the annotations could - potentially raise any kind of exception. + if the annotations are stringized, and *eval_str* is not false, + the ``eval()`` call(s) to un-stringize the annotations in :func:`get_annotations` + could potentially raise any kind of exception. A slash(/) in the signature of a function denotes that the parameters prior to it are positional-only. For more info, see :ref:`the FAQ entry on positional-only parameters `. - .. versionadded:: 3.5 - ``follow_wrapped`` parameter. Pass ``False`` to get a signature of - ``callable`` specifically (``callable.__wrapped__`` will not be used to + .. versionchanged:: 3.5 + The *follow_wrapped* parameter was added. + Pass ``False`` to get a signature of + *callable* specifically (``callable.__wrapped__`` will not be used to unwrap decorated callables.) - .. versionadded:: 3.10 - ``globals``, ``locals``, and ``eval_str`` parameters. + .. versionchanged:: 3.10 + The *globals*, *locals*, and *eval_str* parameters were added. .. note:: @@ -676,7 +695,8 @@ function. .. class:: Signature(parameters=None, *, return_annotation=Signature.empty) - A Signature object represents the call signature of a function and its return + A :class:`!Signature` object represents the call signature of a function + and its return annotation. For each parameter accepted by the function it stores a :class:`Parameter` object in its :attr:`parameters` collection. @@ -686,14 +706,14 @@ function. positional-only first, then positional-or-keyword, and that parameters with defaults follow parameters without defaults. - The optional *return_annotation* argument, can be an arbitrary Python object, - is the "return" annotation of the callable. + The optional *return_annotation* argument can be an arbitrary Python object. + It represents the "return" annotation of the callable. - Signature objects are *immutable*. Use :meth:`Signature.replace` or + :class:`!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`. + :class:`!Signature` objects are now picklable and :term:`hashable`. .. attribute:: Signature.empty @@ -730,13 +750,15 @@ function. .. method:: Signature.replace(*[, parameters][, return_annotation]) - 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 + Create a new :class:`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 + :class:`!Signature`, pass in :attr:`Signature.empty`. - :: + .. doctest:: >>> def test(a, b): ... pass @@ -746,36 +768,50 @@ function. >>> str(new_sig) "(a, b) -> 'new return anno'" - Signature objects are also supported by generic function + :class:`Signature` objects are also supported by the generic function :func:`copy.replace`. - .. classmethod:: Signature.from_callable(obj, *, follow_wrapped=True, globalns=None, localns=None) + .. method:: format(*, max_width=None) + + Create a string representation of the :class:`Signature` object. + + If *max_width* is passed, the method will attempt to fit + the signature into lines of at most *max_width* characters. + If the signature is longer than *max_width*, + all parameters will be on separate lines. + + .. versionadded:: 3.13 + + .. classmethod:: Signature.from_callable(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=False) Return a :class:`Signature` (or its subclass) object for a given callable - ``obj``. Pass ``follow_wrapped=False`` to get a signature of ``obj`` - without unwrapping its ``__wrapped__`` chain. ``globalns`` and - ``localns`` will be used as the namespaces when resolving annotations. + *obj*. + + This method simplifies subclassing of :class:`Signature`: - This method simplifies subclassing of :class:`Signature`:: + .. testcode:: - class MySignature(Signature): - pass - sig = MySignature.from_callable(min) - assert isinstance(sig, MySignature) + class MySignature(Signature): + pass + sig = MySignature.from_callable(sum) + assert isinstance(sig, MySignature) + + Its behavior is otherwise identical to that of :func:`signature`. .. versionadded:: 3.5 - .. versionadded:: 3.10 - ``globalns`` and ``localns`` parameters. + .. versionchanged:: 3.10 + The *globals*, *locals*, and *eval_str* parameters were added. .. class:: Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty) - Parameter objects are *immutable*. Instead of modifying a Parameter object, + :class:`!Parameter` objects are *immutable*. + Instead of modifying a :class:`!Parameter` object, 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`. + Parameter objects are now picklable and :term:`hashable`. .. attribute:: Parameter.empty @@ -794,7 +830,7 @@ function. expressions. .. versionchanged:: 3.6 - These parameter names are exposed by this module as names like + These parameter names are now exposed by this module as names like ``implicit0``. .. attribute:: Parameter.default @@ -844,7 +880,9 @@ function. | | definition. | +------------------------+----------------------------------------------+ - Example: print all keyword-only arguments without default values:: + Example: print all keyword-only arguments without default values: + + .. doctest:: >>> def foo(a, b, *, c, d=10): ... pass @@ -858,11 +896,13 @@ function. .. attribute:: Parameter.kind.description - Describes a enum value of Parameter.kind. + Describes a enum value of :attr:`Parameter.kind`. .. versionadded:: 3.8 - Example: print all descriptions of arguments:: + Example: print all descriptions of arguments: + + .. doctest:: >>> def foo(a, b, *, c, d=10): ... pass @@ -877,12 +917,12 @@ function. .. method:: Parameter.replace(*[, name][, kind][, default][, annotation]) - Create a new Parameter instance based on the instance replaced was invoked - on. To override a :class:`Parameter` attribute, pass the corresponding + Create a new :class:`Parameter` instance based on the instance replaced was invoked + on. To override a :class:`!Parameter` attribute, pass the corresponding argument. To remove a default value or/and an annotation from a - Parameter, pass :attr:`Parameter.empty`. + :class:`!Parameter`, pass :attr:`Parameter.empty`. - :: + .. doctest:: >>> from inspect import Parameter >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42) @@ -893,12 +933,13 @@ function. 'foo=42' >>> str(param.replace(default=Parameter.empty, annotation='spam')) - "foo:'spam'" + "foo: 'spam'" - Parameter objects are also supported by generic function :func:`copy.replace`. + :class:`Parameter` objects are also supported by the generic function + :func:`copy.replace`. .. versionchanged:: 3.4 - In Python 3.3 Parameter objects were allowed to have ``name`` set + In Python 3.3 :class:`Parameter` objects were allowed to have ``name`` set to ``None`` if their ``kind`` was set to ``POSITIONAL_ONLY``. This is no longer permitted. @@ -951,18 +992,20 @@ function. For variable-keyword arguments (``**kwargs``) the default is an empty dict. - :: + .. doctest:: - >>> def foo(a, b='ham', *args): pass - >>> ba = inspect.signature(foo).bind('spam') - >>> ba.apply_defaults() - >>> ba.arguments - {'a': 'spam', 'b': 'ham', 'args': ()} + >>> def foo(a, b='ham', *args): pass + >>> ba = inspect.signature(foo).bind('spam') + >>> ba.apply_defaults() + >>> ba.arguments + {'a': 'spam', 'b': 'ham', 'args': ()} .. versionadded:: 3.5 The :attr:`args` and :attr:`kwargs` properties can be used to invoke - functions:: + functions: + + .. testcode:: def test(a, *, b): ... @@ -1081,20 +1124,22 @@ Classes and functions ``**`` arguments, if any) to their values from *args* and *kwds*. In case of invoking *func* incorrectly, i.e. whenever ``func(*args, **kwds)`` would raise an exception because of incompatible signature, an exception of the same type - and the same or similar message is raised. For example:: - - >>> from inspect import getcallargs - >>> def f(a, b=1, *pos, **named): - ... pass - ... - >>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)} - True - >>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} - True - >>> getcallargs(f) - Traceback (most recent call last): - ... - TypeError: f() missing 1 required positional argument: 'a' + and the same or similar message is raised. For example: + + .. doctest:: + + >>> from inspect import getcallargs + >>> def f(a, b=1, *pos, **named): + ... pass + ... + >>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)} + True + >>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} + True + >>> getcallargs(f) + Traceback (most recent call last): + ... + TypeError: f() missing 1 required positional argument: 'a' .. versionadded:: 3.2 @@ -1180,9 +1225,10 @@ Classes and functions * If ``obj`` is a class, ``globals`` defaults to ``sys.modules[obj.__module__].__dict__`` and ``locals`` defaults to the ``obj`` class namespace. - * If ``obj`` is a callable, ``globals`` defaults to ``obj.__globals__``, + * If ``obj`` is a callable, ``globals`` defaults to + :attr:`obj.__globals__ `, although if ``obj`` is a wrapped function (using - ``functools.update_wrapper()``) it is first unwrapped. + :func:`functools.update_wrapper`) it is first unwrapped. Calling ``get_annotations`` is best practice for accessing the annotations dict of any object. See :ref:`annotations-howto` for @@ -1396,7 +1442,8 @@ Fetching attributes statically Both :func:`getattr` and :func:`hasattr` can trigger code execution when fetching or checking for the existence of attributes. Descriptors, like -properties, will be invoked and :meth:`__getattr__` and :meth:`__getattribute__` +properties, will be invoked and :meth:`~object.__getattr__` and +:meth:`~object.__getattribute__` may be called. For cases where you want passive introspection, like documentation tools, this @@ -1406,7 +1453,8 @@ but avoids executing code when it fetches attributes. .. function:: getattr_static(obj, attr, default=None) Retrieve attributes without triggering dynamic lookup via the - descriptor protocol, :meth:`__getattr__` or :meth:`__getattribute__`. + descriptor protocol, :meth:`~object.__getattr__` + or :meth:`~object.__getattribute__`. Note: this function may not be able to retrieve all attributes that getattr can fetch (like dynamically created attributes) @@ -1463,10 +1511,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 @@ -1478,10 +1527,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 @@ -1494,10 +1544,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 @@ -1546,8 +1597,8 @@ updated as expected: Code Objects Bit Flags ---------------------- -Python code objects have a ``co_flags`` attribute, which is a bitmap of -the following flags: +Python code objects have a :attr:`~codeobject.co_flags` attribute, +which is a bitmap of the following flags: .. data:: CO_OPTIMIZED @@ -1555,8 +1606,8 @@ the following flags: .. data:: CO_NEWLOCALS - If set, a new dict will be created for the frame's ``f_locals`` when - the code object is executed. + If set, a new dict will be created for the frame's :attr:`~frame.f_locals` + when the code object is executed. .. data:: CO_VARARGS @@ -1655,6 +1706,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 01088879218cb4..6736aa9ee2b0ef 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -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:`!readinto` and :meth:`!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 diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index 9c2dff55703273..1de36b643c4dca 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -219,6 +219,13 @@ write code that handles both IP versions correctly. Address objects are ``True`` if the address is reserved for link-local usage. See :RFC:`3927`. + .. attribute:: ipv6_mapped + + :class:`IPv4Address` object representing the IPv4-mapped IPv6 address. See :RFC:`4291`. + + .. versionadded:: 3.13 + + .. _iana-ipv4-special-registry: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml .. _iana-ipv6-special-registry: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 5846d784c88ccc..56c66f670c74dd 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -41,7 +41,7 @@ operator can be mapped across two vectors to form an efficient dot-product: ================== ================= ================================================= ========================================= Iterator Arguments Results Example ================== ================= ================================================= ========================================= -:func:`count` start, [step] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` +:func:`count` [start[, step]] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` :func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` ================== ================= ================================================= ========================================= @@ -798,10 +798,10 @@ which incur interpreter overhead. "Return first n items of the iterable as a list" return list(islice(iterable, n)) - def prepend(value, iterator): - "Prepend a single value in front of an iterator" + def prepend(value, iterable): + "Prepend a single value in front of an iterable" # prepend(1, [2, 3, 4]) --> 1 2 3 4 - return chain([value], iterator) + return chain([value], iterable) def tabulate(function, start=0): "Return function(0), function(1), ..." @@ -914,14 +914,15 @@ which incur interpreter overhead. # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF args = [iter(iterable)] * n - if incomplete == 'fill': - return zip_longest(*args, fillvalue=fillvalue) - if incomplete == 'strict': - return zip(*args, strict=True) - if incomplete == 'ignore': - return zip(*args) - else: - raise ValueError('Expected fill, strict, or ignore') + match incomplete: + case 'fill': + return zip_longest(*args, fillvalue=fillvalue) + case 'strict': + return zip(*args, strict=True) + case 'ignore': + return zip(*args) + case _: + raise ValueError('Expected fill, strict, or ignore') def sliding_window(iterable, n): # sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG diff --git a/Doc/library/json.rst b/Doc/library/json.rst index b337b5f9960e8e..0ce4b697145cb3 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -714,7 +714,7 @@ specified, :data:`sys.stdin` and :data:`sys.stdout` will be used respectively: Command line options ^^^^^^^^^^^^^^^^^^^^ -.. cmdoption:: infile +.. option:: infile The JSON file to be validated or pretty-printed: @@ -734,36 +734,36 @@ Command line options 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 :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/locale.rst b/Doc/library/locale.rst index afd5677deac3f8..a7201199191215 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -303,13 +303,13 @@ The :mod:`locale` module defines the following exception and functions: *language code* and *encoding* may be ``None`` if their values cannot be determined. - .. deprecated-removed:: 3.11 3.13 + .. deprecated-removed:: 3.11 3.15 .. function:: getlocale(category=LC_CTYPE) Returns the current setting for the given locale category as sequence containing - *language code*, *encoding*. *category* may be one of the :const:`LC_\*` values + *language code*, *encoding*. *category* may be one of the :const:`!LC_\*` values except :const:`LC_ALL`. It defaults to :const:`LC_CTYPE`. Except for the code ``'C'``, the language code corresponds to :rfc:`1766`. @@ -454,11 +454,16 @@ The :mod:`locale` module defines the following exception and functions: .. data:: LC_CTYPE - .. index:: pair: module; string + Locale category for the character type functions. Most importantly, this + category defines the text encoding, i.e. how bytes are interpreted as + Unicode codepoints. See :pep:`538` and :pep:`540` for how this variable + might be automatically coerced to ``C.UTF-8`` to avoid issues created by + invalid settings in containers or incompatible settings passed over remote + SSH connections. - Locale category for the character type functions. Depending on the settings of - this category, the functions of module :mod:`string` dealing with case change - their behaviour. + Python doesn't internally use locale-dependent character transformation functions + from ``ctype.h``. Instead, an internal ``pyctype.h`` provides locale-independent + equivalents like :c:macro:`!Py_TOLOWER`. .. data:: LC_COLLATE diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 53fbd073c26702..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 diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 2a825db54aed5c..2dd4bd081b0429 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -656,9 +656,7 @@ supports sending logging messages to a remote or local Unix syslog. to the other end. This method is called during handler initialization, but it's not regarded as an error if the other end isn't listening at this point - the method will be called again when emitting an event, if - but it's not regarded as an error if the other end isn't listening yet - --- the method will be called again when emitting an event, - if there is no socket at that point. + there is no socket at that point. .. versionadded:: 3.11 diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 434e7ac9061186..0d69c3bc01d1e2 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -333,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 @@ -354,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 91df07d914cae2..05ffaf6c9b336e 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -167,7 +167,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. Return a representation of the message corresponding to *key*. If no such message exists, *default* is returned if the method was called as :meth:`get` and a :exc:`KeyError` exception is raised if the method was - called as :meth:`__getitem__`. The message is represented as an instance + called as :meth:`~object.__getitem__`. The message is represented as an instance of the appropriate format-specific :class:`Message` subclass unless a custom message factory was specified when the :class:`Mailbox` instance was initialized. @@ -424,6 +424,108 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. remove the underlying message while the returned file remains open. + .. method:: get_flags(key) + + Return as a string the flags that are set on the message + corresponding to *key*. + This is the same as ``get_message(key).get_flags()`` but much + faster, because it does not open the message file. + Use this method when iterating over the keys to determine which + messages are interesting to get. + + If you do have a :class:`MaildirMessage` object, use + its :meth:`~MaildirMessage.get_flags` method instead, because + changes made by the message's :meth:`~MaildirMessage.set_flags`, + :meth:`~MaildirMessage.add_flag` and :meth:`~MaildirMessage.remove_flag` + methods are not reflected here until the mailbox's + :meth:`__setitem__` method is called. + + .. versionadded:: 3.13 + + + .. method:: set_flags(key, flags) + + On the message corresponding to *key*, set the flags specified + by *flags* and unset all others. + Calling ``some_mailbox.set_flags(key, flags)`` is similar to :: + + one_message = some_mailbox.get_message(key) + one_message.set_flags(flags) + some_mailbox[key] = one_message + + but faster, because it does not open the message file. + + If you do have a :class:`MaildirMessage` object, use + its :meth:`~MaildirMessage.set_flags` method instead, because + changes made with this mailbox method will not be visible to the + message object's method, :meth:`~MaildirMessage.get_flags`. + + .. versionadded:: 3.13 + + + .. method:: add_flag(key, flag) + + On the message corresponding to *key*, set the flags specified + by *flag* without changing other flags. To add more than one + flag at a time, *flag* may be a string of more than one character. + + Considerations for using this method versus the message object's + :meth:`~MaildirMessage.add_flag` method are similar to + those for :meth:`set_flags`; see the discussion there. + + .. versionadded:: 3.13 + + + .. method:: remove_flag(key, flag) + + On the message corresponding to *key*, unset the flags specified + by *flag* without changing other flags. To remove more than one + flag at a time, *flag* may be a string of more than one character. + + Considerations for using this method versus the message object's + :meth:`~MaildirMessage.remove_flag` method are similar to + those for :meth:`set_flags`; see the discussion there. + + .. versionadded:: 3.13 + + + .. method:: get_info(key) + + Return a string containing the info for the message + corresponding to *key*. + This is the same as ``get_message(key).get_info()`` but much + faster, because it does not open the message file. + Use this method when iterating over the keys to determine which + messages are interesting to get. + + If you do have a :class:`MaildirMessage` object, use + its :meth:`~MaildirMessage.get_info` method instead, because + changes made by the message's :meth:`~MaildirMessage.set_info` method + are not reflected here until the mailbox's :meth:`__setitem__` method + is called. + + .. versionadded:: 3.13 + + + .. method:: set_info(key, info) + + Set the info of the message corresponding to *key* to *info*. + Calling ``some_mailbox.set_info(key, flags)`` is similar to :: + + one_message = some_mailbox.get_message(key) + one_message.set_info(info) + some_mailbox[key] = one_message + + but faster, because it does not open the message file. + + If you do have a :class:`MaildirMessage` object, use + its :meth:`~MaildirMessage.set_info` method instead, because + changes made with this mailbox method will not be visible to the + message object's method, :meth:`~MaildirMessage.get_info`. + + .. versionadded:: 3.13 + + .. seealso:: `maildir man page from Courier `_ @@ -838,7 +940,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. .. note:: A message is typically moved from :file:`new` to :file:`cur` after its - mailbox has been accessed, whether or not the message is has been + mailbox has been accessed, whether or not the message has been read. A message ``msg`` has been read if ``"S" in msg.get_flags()`` is ``True``. diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index 69afadff1f5f42..3fa69e717329e4 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -19,7 +19,7 @@ the current file position, and :meth:`seek` through the file to different positi A memory-mapped file is created by the :class:`~mmap.mmap` constructor, which is different on Unix and on Windows. In either case you must provide a file descriptor for a file opened for update. If you wish to map an existing Python -file object, use its :meth:`fileno` method to obtain the correct value for the +file object, use its :meth:`~io.IOBase.fileno` method to obtain the correct value for the *fileno* parameter. Otherwise, you can open the file using the :func:`os.open` function, which returns a file descriptor directly (the file still needs to be closed when done). @@ -285,6 +285,14 @@ To map anonymous memory, -1 should be passed as the fileno along with the length values are ``os.SEEK_CUR`` or ``1`` (seek relative to the current position) and ``os.SEEK_END`` or ``2`` (seek relative to the file's end). + .. versionchanged:: 3.13 + Return the new absolute position instead of ``None``. + + .. method:: seekable() + + Return whether the file supports seeking, and the return value is always ``True``. + + .. versionadded:: 3.13 .. method:: size() diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 2f0f1f800fdc94..789a84b02d59d2 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -996,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() @@ -2214,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. @@ -2249,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 @@ -2571,7 +2582,7 @@ multiple connections at the same time. **Windows**: An item in *object_list* must either be an integer handle which is waitable (according to the definition used by the documentation of the Win32 function ``WaitForMultipleObjects()``) - or it can be an object with a :meth:`fileno` method which returns a + or it can be an object with a :meth:`~io.IOBase.fileno` method which returns a socket handle or pipe handle. (Note that pipe handles and socket handles are **not** waitable handles.) @@ -2619,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 @@ -2775,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. - - 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`. + 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`. .. _multiprocessing-programming: diff --git a/Doc/library/multiprocessing.shared_memory.rst b/Doc/library/multiprocessing.shared_memory.rst index f453e6403d932d..671130d9b29fc0 100644 --- a/Doc/library/multiprocessing.shared_memory.rst +++ b/Doc/library/multiprocessing.shared_memory.rst @@ -36,7 +36,7 @@ or other communications requiring the serialization/deserialization and copying of data. -.. class:: SharedMemory(name=None, create=False, size=0) +.. class:: SharedMemory(name=None, create=False, size=0, *, track=True) Creates a new shared memory block or attaches to an existing shared memory block. Each shared memory block is assigned a unique name. @@ -64,26 +64,45 @@ copying of data. memory block may be larger or equal to the size requested. When attaching to an existing shared memory block, the ``size`` parameter is ignored. + *track*, when enabled, registers the shared memory block with a resource + tracker process on platforms where the OS does not do this automatically. + The resource tracker ensures proper cleanup of the shared memory even + if all other processes with access to the memory exit without doing so. + Python processes created from a common ancestor using :mod:`multiprocessing` + facilities share a single resource tracker process, and the lifetime of + shared memory segments is handled automatically among these processes. + Python processes created in any other way will receive their own + resource tracker when accessing shared memory with *track* enabled. + This will cause the shared memory to be deleted by the resource tracker + of the first process that terminates. + To avoid this issue, users of :mod:`subprocess` or standalone Python + processes should set *track* to ``False`` when there is already another + process in place that does the bookkeeping. + *track* is ignored on Windows, which has its own tracking and + automatically deletes shared memory when all handles to it have been closed. + + .. versionchanged:: 3.13 Added *track* parameter. + .. method:: close() - Closes access to the shared memory from this instance. In order to - ensure proper cleanup of resources, all instances should call - ``close()`` once the instance is no longer needed. Note that calling - ``close()`` does not cause the shared memory block itself to be - destroyed. + Closes the file descriptor/handle to the shared memory from this + instance. :meth:`close()` should be called once access to the shared + memory block from this instance is no longer needed. Depending + on operating system, the underlying memory may or may not be freed + even if all handles to it have been closed. To ensure proper cleanup, + use the :meth:`unlink()` method. .. method:: unlink() - Requests that the underlying shared memory block be destroyed. In - order to ensure proper cleanup of resources, ``unlink()`` should be - called once (and only once) across all processes which have need - for the shared memory block. After requesting its destruction, a - shared memory block may or may not be immediately destroyed and - this behavior may differ across platforms. Attempts to access data - inside the shared memory block after ``unlink()`` has been called may - result in memory access errors. Note: the last process relinquishing - its hold on a shared memory block may call ``unlink()`` and - :meth:`close()` in either order. + Deletes the underlying shared memory block. This should be called only + once per shared memory block regardless of the number of handles to it, + even in other processes. + :meth:`unlink()` and :meth:`close()` can be called in any order, but + trying to access data inside a shared memory block after :meth:`unlink()` + may result in memory access errors, depending on platform. + + This method has no effect on Windows, where the only way to delete a + shared memory block is to close all handles. .. attribute:: buf 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 57c67bcf3aa12e..96f2c287875d41 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -306,7 +306,7 @@ expect a function argument. itemgetter(*items) Return a callable object that fetches *item* from its operand using the - operand's :meth:`__getitem__` method. If multiple items are specified, + operand's :meth:`~object.__getitem__` method. If multiple items are specified, returns a tuple of lookup values. For example: * After ``f = itemgetter(2)``, the call ``f(r)`` returns ``r[2]``. @@ -326,7 +326,7 @@ expect a function argument. return tuple(obj[item] for item in items) return g - The items can be any type accepted by the operand's :meth:`__getitem__` + The items can be any type accepted by the operand's :meth:`~object.__getitem__` method. Dictionaries accept any :term:`hashable` value. Lists, tuples, and strings accept an index or a slice: diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 6f9e0853bc8947..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 diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 4ffd520f9ecd8b..9d2a3d65069253 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2160,9 +2160,12 @@ features: for possible values of *mode*. As of Python 3.3, this is equivalent to ``os.chmod(path, mode, follow_symlinks=False)``. + ``lchmod()`` is not part of POSIX, but Unix implementations may have it if + changing the mode of symbolic links is supported. + .. audit-event:: os.chmod path,mode,dir_fd os.lchmod - .. availability:: Unix. + .. availability:: Unix, not Linux, FreeBSD >= 1.3, NetBSD >= 1.3, not OpenBSD .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -3781,6 +3784,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 ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3959,7 +4173,7 @@ to be ignored. The "l" and "v" variants of the :func:`exec\* ` functions differ in how command-line arguments are passed. The "l" variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the - individual parameters simply become additional parameters to the :func:`execl\*` + individual parameters simply become additional parameters to the :func:`!execl\*` functions. The "v" variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the *args* parameter. In either case, the arguments to the child process should start with @@ -4497,7 +4711,7 @@ written in Python, such as a mail server's external command delivery program. command-line arguments are passed. The "l" variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the individual parameters simply become additional parameters to the - :func:`spawnl\*` functions. The "v" variants are good when the number of + :func:`!spawnl\*` functions. The "v" variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the *args* parameter. In either case, the arguments to the child process must start with the name of the command being run. @@ -4547,7 +4761,7 @@ written in Python, such as a mail server's external command delivery program. P_NOWAITO Possible values for the *mode* parameter to the :func:`spawn\* ` family of - functions. If either of these values is given, the :func:`spawn\*` functions + functions. If either of these values is given, the :func:`spawn\* ` functions will return as soon as the new process has been created, with the process id as the return value. @@ -4557,7 +4771,7 @@ written in Python, such as a mail server's external command delivery program. .. data:: P_WAIT Possible value for the *mode* parameter to the :func:`spawn\* ` family of - functions. If this is given as *mode*, the :func:`spawn\*` functions will not + functions. If this is given as *mode*, the :func:`spawn\* ` functions will not return until the new process has run to completion and will return the exit code of the process the run is successful, or ``-signal`` if a signal kills the process. @@ -5141,8 +5355,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: @@ -5183,15 +5401,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() @@ -5202,6 +5423,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 diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 48d6176d26bb8f..60791725c2323d 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -306,7 +306,7 @@ Pure paths provide the following methods and properties: .. attribute:: PurePath.pathmod The implementation of the :mod:`os.path` module used for low-level path - operations: either ``posixpath`` or ``ntpath``. + operations: either :mod:`posixpath` or :mod:`ntpath`. .. versionadded:: 3.13 @@ -595,6 +595,9 @@ Pure paths provide the following methods and properties: >>> PurePath('a/b.py').match(pattern) True + .. versionchanged:: 3.12 + Accepts an object implementing the :class:`os.PathLike` interface. + As with other methods, case-sensitivity follows platform defaults:: >>> PurePosixPath('b.py').match('*.PY') @@ -850,6 +853,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`. @@ -981,15 +1020,21 @@ call fails (for example because the path doesn't exist). future Python release, patterns with this ending will match both files and directories. Add a trailing slash to match only directories. -.. method:: Path.group() +.. method:: Path.group(*, follow_symlinks=True) - Return the name of the group owning the file. :exc:`KeyError` is raised + Return the name of the group owning the file. :exc:`KeyError` is raised if the file's gid isn't found in the system database. + This method normally follows symlinks; to get the group of the symlink, add + the argument ``follow_symlinks=False``. + .. versionchanged:: 3.13 Raises :exc:`UnsupportedOperation` if the :mod:`grp` module is not available. In previous versions, :exc:`NotImplementedError` was raised. + .. versionchanged:: 3.13 + The *follow_symlinks* parameter was added. + .. method:: Path.is_dir(*, follow_symlinks=True) @@ -1255,15 +1300,21 @@ call fails (for example because the path doesn't exist). '#!/usr/bin/env python3\n' -.. method:: Path.owner() +.. method:: Path.owner(*, follow_symlinks=True) - Return the name of the user owning the file. :exc:`KeyError` is raised + Return the name of the user owning the file. :exc:`KeyError` is raised if the file's uid isn't found in the system database. + This method normally follows symlinks; to get the owner of the symlink, add + the argument ``follow_symlinks=False``. + .. versionchanged:: 3.13 Raises :exc:`UnsupportedOperation` if the :mod:`pwd` module is not available. In previous versions, :exc:`NotImplementedError` was raised. + .. versionchanged:: 3.13 + The *follow_symlinks* parameter was added. + .. method:: Path.read_bytes() @@ -1278,7 +1329,7 @@ call fails (for example because the path doesn't exist). .. versionadded:: 3.5 -.. method:: Path.read_text(encoding=None, errors=None) +.. method:: Path.read_text(encoding=None, errors=None, newline=None) Return the decoded contents of the pointed-to file as a string:: @@ -1293,6 +1344,8 @@ call fails (for example because the path doesn't exist). .. versionadded:: 3.5 + .. versionchanged:: 3.13 + The *newline* parameter was added. .. method:: Path.readlink() diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 002eeef4c09b5d..2495dcf50bb17f 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -570,17 +570,34 @@ can be overridden by the local file. Start an interactive interpreter (using the :mod:`code` module) whose global namespace contains all the (global and local) names found in the current - scope. + scope. Use ``exit()`` or ``quit()`` to exit the interpreter and return to + the debugger. + + .. note:: + + Because interact creates a new global namespace with the current global + and local namespace for execution, assignment to variables will not + affect the original namespaces. + However, modification to the mutable objects will be reflected in the + original namespaces. .. versionadded:: 3.2 + .. versionadded:: 3.13 + ``exit()`` and ``quit()`` can be used to exit :pdbcmd:`interact` + command. + + .. versionchanged:: 3.13 + :pdbcmd:`interact` directs its output to the debugger's + output channel rather than :data:`sys.stderr`. + .. _debugger-aliases: .. pdbcommand:: alias [name [command]] Create an alias called *name* that executes *command*. The *command* must *not* be enclosed in quotes. Replaceable parameters can be indicated by - ``%1``, ``%2``, and so on, while ``%*`` is replaced by all the parameters. + ``%1``, ``%2``, ... and ``%9``, while ``%*`` is replaced by all the parameters. If *command* is omitted, the current alias for *name* is shown. If no arguments are given, all aliases are listed. diff --git a/Doc/library/pickletools.rst b/Doc/library/pickletools.rst index 76f5b0cadf975a..41930f8cbe8412 100644 --- a/Doc/library/pickletools.rst +++ b/Doc/library/pickletools.rst @@ -53,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/posix.rst b/Doc/library/posix.rst index 0413f9d02a8d57..5871574b442667 100644 --- a/Doc/library/posix.rst +++ b/Doc/library/posix.rst @@ -11,6 +11,8 @@ This module provides access to operating system functionality that is standardized by the C Standard and the POSIX standard (a thinly disguised Unix interface). +.. availability:: Unix. + .. index:: pair: module; os **Do not import this module directly.** Instead, import the module :mod:`os`, diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 69274b0c354a25..cc059b66fcb84b 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -82,8 +82,8 @@ the following:: The first line indicates that 214 calls were monitored. Of those calls, 207 were :dfn:`primitive`, meaning that the call was not induced via recursion. The -next line: ``Ordered by: cumulative time``, indicates that the text string in the -far right column was used to sort the output. The column headings include: +next line: ``Ordered by: cumulative time`` indicates the output is sorted +by the ``cumtime`` values. The column headings include: ncalls for the number of calls. @@ -135,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 ad4981c97119fa..af9378464edb9f 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -16,6 +16,8 @@ The :mod:`pty` module defines operations for handling the pseudo-terminal concept: starting another process and being able to write to and read from its controlling terminal programmatically. +.. availability:: Unix. + Pseudo-terminal handling is highly platform dependent. This code is mainly tested on Linux, FreeBSD, and macOS (it is supposed to work on other POSIX platforms but it's not been thoroughly tested). diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst index 300419301b9ff5..dbe68cd14ec4d4 100644 --- a/Doc/library/pwd.rst +++ b/Doc/library/pwd.rst @@ -10,7 +10,7 @@ This module provides access to the Unix user account and password database. It is available on all Unix versions. -.. include:: ../includes/wasm-notavail.rst +.. availability:: Unix, not Emscripten, not WASI. Password database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``passwd`` structure (Attribute field below, diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 5501db8f87de81..38c416f9ad0305 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -139,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/random.rst b/Doc/library/random.rst index 76ae97a8be7e63..feaf260caf3568 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -220,8 +220,8 @@ Functions for sequences generated. For example, a sequence of length 2080 is the largest that can fit within the period of the Mersenne Twister random number generator. - .. deprecated-removed:: 3.9 3.11 - The optional parameter *random*. + .. versionchanged:: 3.11 + Removed the optional parameter *random*. .. function:: sample(population, k, *, counts=None) @@ -407,9 +407,9 @@ Alternative Generator Class that implements the default pseudo-random number generator used by the :mod:`random` module. - .. deprecated-removed:: 3.9 3.11 + .. versionchanged:: 3.11 Formerly the *seed* could be any hashable object. Now it is limited to: - :class:`NoneType`, :class:`int`, :class:`float`, :class:`str`, + ``None``, :class:`int`, :class:`float`, :class:`str`, :class:`bytes`, or :class:`bytearray`. .. class:: SystemRandom([seed]) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 60696007f4abc8..302f7224de4a7a 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 @@ -1093,12 +1093,12 @@ Functions Exceptions ^^^^^^^^^^ -.. exception:: error(msg, pattern=None, pos=None) +.. exception:: PatternError(msg, pattern=None, pos=None) Exception raised when a string passed to one of the functions here is not a valid regular expression (for example, it might contain unmatched parentheses) or when some other error occurs during compilation or matching. It is never an - error if a string contains no match for a pattern. The error instance has + error if a string contains no match for a pattern. The ``PatternError`` instance has the following additional attributes: .. attribute:: msg @@ -1124,6 +1124,10 @@ Exceptions .. versionchanged:: 3.5 Added additional attributes. + .. versionchanged:: 3.13 + ``PatternError`` was originally named ``error``; the latter is kept as an alias for + backward compatibility. + .. _re-objects: Regular Expression Objects diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 8fb0eca8df74d8..2e0f45ced30b9c 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -27,16 +27,15 @@ Readline library in general. .. note:: The underlying Readline library API may be implemented by - the ``libedit`` library instead of GNU readline. + the ``editline`` (``libedit``) library instead of GNU readline. On macOS the :mod:`readline` module detects which library is being used at run time. - The configuration file for ``libedit`` is different from that + The configuration file for ``editline`` is different from that of GNU readline. If you programmatically load configuration strings - you can check for the text "libedit" in :const:`readline.__doc__` - to differentiate between GNU readline and libedit. + you can use :data:`backend` to determine which library is being used. - If you use *editline*/``libedit`` readline emulation on macOS, the + If you use ``editline``/``libedit`` readline emulation on macOS, the initialization file located in your home directory is named ``.editrc``. For example, the following content in ``~/.editrc`` will turn ON *vi* keybindings and TAB completion:: @@ -44,6 +43,12 @@ Readline library in general. python:bind -v python:bind ^I rl_complete +.. data:: backend + + The name of the underlying Readline library being used, either + ``"readline"`` or ``"editline"``. + + .. versionadded:: 3.13 Init file --------- diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst index 5ebb0a7780c37b..678a11c6f45490 100644 --- a/Doc/library/reprlib.rst +++ b/Doc/library/reprlib.rst @@ -10,7 +10,7 @@ -------------- -The :mod:`reprlib` module provides a means for producing object representations +The :mod:`!reprlib` module provides a means for producing object representations with limits on the size of the resulting strings. This is used in the Python debugger and may be useful in other contexts as well. @@ -58,29 +58,31 @@ This module provides a class, an instance, and a function: limits on most sizes. In addition to size-limiting tools, the module also provides a decorator for -detecting recursive calls to :meth:`__repr__` and substituting a placeholder -string instead. +detecting recursive calls to :meth:`~object.__repr__` and substituting a +placeholder string instead. .. index:: single: ...; placeholder .. decorator:: recursive_repr(fillvalue="...") - Decorator for :meth:`__repr__` methods to detect recursive calls within the + Decorator for :meth:`~object.__repr__` methods to detect recursive calls within the same thread. If a recursive call is made, the *fillvalue* is returned, - otherwise, the usual :meth:`__repr__` call is made. For example: - - >>> from reprlib import recursive_repr - >>> class MyList(list): - ... @recursive_repr() - ... def __repr__(self): - ... return '<' + '|'.join(map(repr, self)) + '>' - ... - >>> m = MyList('abc') - >>> m.append(m) - >>> m.append('x') - >>> print(m) - <'a'|'b'|'c'|...|'x'> + otherwise, the usual :meth:`!__repr__` call is made. For example: + + .. doctest:: + + >>> from reprlib import recursive_repr + >>> class MyList(list): + ... @recursive_repr() + ... def __repr__(self): + ... return '<' + '|'.join(map(repr, self)) + '>' + ... + >>> m = MyList('abc') + >>> m.append(m) + >>> m.append('x') + >>> print(m) + <'a'|'b'|'c'|...|'x'> .. versionadded:: 3.2 @@ -148,10 +150,10 @@ which format specific object types. with no line breaks or indentation, like the standard :func:`repr`. For example: - .. code-block:: pycon + .. doctest:: indent >>> example = [ - 1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham'] + ... 1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham'] >>> import reprlib >>> aRepr = reprlib.Repr() >>> print(aRepr.repr(example)) @@ -160,7 +162,7 @@ which format specific object types. If :attr:`~Repr.indent` is set to a string, each recursion level is placed on its own line, indented by that string: - .. code-block:: pycon + .. doctest:: indent >>> aRepr.indent = '-->' >>> print(aRepr.repr(example)) @@ -181,7 +183,7 @@ which format specific object types. Setting :attr:`~Repr.indent` to a positive integer value behaves as if it was set to a string with that number of spaces: - .. code-block:: pycon + .. doctest:: indent >>> aRepr.indent = 4 >>> print(aRepr.repr(example)) @@ -234,7 +236,9 @@ Subclassing Repr Objects The use of dynamic dispatching by :meth:`Repr.repr1` allows subclasses of :class:`Repr` to add support for additional built-in object types or to modify the handling of types already supported. This example shows how special support -for file objects could be added:: +for file objects could be added: + +.. testcode:: import reprlib import sys @@ -248,3 +252,7 @@ for file objects could be added:: aRepr = MyRepr() print(aRepr.repr(sys.stdin)) # prints '' + +.. testoutput:: + + diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index a5324c82c63484..4e58b043f1da31 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -13,7 +13,7 @@ This module provides basic mechanisms for measuring and controlling system resources utilized by a program. -.. include:: ../includes/wasm-notavail.rst +.. availability:: Unix, not Emscripten, not WASI. Symbolic constants are used to specify particular system resources and to request usage information about either the current process or its children. @@ -277,7 +277,7 @@ These functions are used to retrieve resource usage information: This function returns an object that describes the resources consumed by either the current process or its children, as specified by the *who* parameter. The - *who* parameter should be specified using one of the :const:`RUSAGE_\*` + *who* parameter should be specified using one of the :const:`!RUSAGE_\*` constants described below. A simple example:: @@ -353,7 +353,7 @@ These functions are used to retrieve resource usage information: Returns the number of bytes in a system page. (This need not be the same as the hardware page size.) -The following :const:`RUSAGE_\*` symbols are passed to the :func:`getrusage` +The following :const:`!RUSAGE_\*` symbols are passed to the :func:`getrusage` function to specify which processes information should be provided for. diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index dd50bac37e49b8..76cbf91412f763 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -21,7 +21,7 @@ It defines a :class:`BaseSelector` abstract base class, along with several concrete implementations (:class:`KqueueSelector`, :class:`EpollSelector`...), that can be used to wait for I/O readiness notification on multiple file objects. In the following, "file object" refers to any object with a -:meth:`fileno()` method, or a raw file descriptor. See :term:`file object`. +:meth:`~io.IOBase.fileno` method, or a raw file descriptor. See :term:`file object`. :class:`DefaultSelector` is an alias to the most efficient implementation available on the current platform: this should be the default choice for most diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index 01314f491f47a7..88802d717d7383 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -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 @@ -149,13 +149,14 @@ Restrictions .. class:: BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8') - A subclass of :class:`Shelf` which exposes :meth:`first`, :meth:`!next`, - :meth:`previous`, :meth:`last` and :meth:`set_location` which are available - in the third-party :mod:`bsddb` module from `pybsddb + A subclass of :class:`Shelf` which exposes :meth:`!first`, :meth:`!next`, + :meth:`!previous`, :meth:`!last` and :meth:`!set_location` methods. + These are available + in the third-party :mod:`!bsddb` module from `pybsddb `_ but not in other database modules. The *dict* object passed to the constructor must support those methods. This is generally accomplished by calling one of - :func:`bsddb.hashopen`, :func:`bsddb.btopen` or :func:`bsddb.rnopen`. The + :func:`!bsddb.hashopen`, :func:`!bsddb.btopen` or :func:`!bsddb.rnopen`. The optional *protocol*, *writeback*, and *keyencoding* parameters have the same interpretation as for the :class:`Shelf` class. diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 4390a8e22306fa..f61ef8b0ecc7ba 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -343,6 +343,12 @@ Directory and files operations .. versionchanged:: 3.12 Added the *onexc* parameter, deprecated *onerror*. + .. versionchanged:: 3.13 + :func:`!rmtree` now ignores :exc:`FileNotFoundError` exceptions for all + but the top-level path. + Exceptions other than :exc:`OSError` and subclasses of :exc:`!OSError` + are now always propagated to the caller. + .. attribute:: rmtree.avoids_symlink_attacks Indicates whether the current platform and implementation provides a @@ -476,6 +482,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/site.rst b/Doc/library/site.rst index ea3b2e996574ef..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: @@ -191,7 +199,7 @@ Module contents :file:`~/Library/Python/{X.Y}` for macOS framework builds, and :file:`{%APPDATA%}\\Python` for Windows. This value is used to compute the installation directories for scripts, data files, Python modules, - etc. for the 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/socket.rst b/Doc/library/socket.rst index 83957c87990440..4bfb0d8c2cfeac 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -23,7 +23,7 @@ all modern Unix systems, Windows, MacOS, and probably additional platforms. The Python interface is a straightforward transliteration of the Unix system call and library interface for sockets to Python's object-oriented style: the -:func:`.socket` function returns a :dfn:`socket object` whose methods implement +:func:`~socket.socket` function returns a :dfn:`socket object` whose methods implement the various socket system calls. Parameter types are somewhat higher-level than in the C interface: as with :meth:`read` and :meth:`write` operations on Python files, buffer allocation on receive operations is automatic, and buffer length @@ -185,7 +185,7 @@ created. Socket addresses are represented as follows: .. versionadded:: 3.7 - :const:`AF_PACKET` is a low-level interface directly to network devices. - The packets are represented by the tuple + The addresses are represented by the tuple ``(ifname, proto[, pkttype[, hatype[, addr]]])`` where: - *ifname* - String specifying the device name. @@ -193,7 +193,6 @@ created. Socket addresses are represented as follows: May be :data:`ETH_P_ALL` to capture all protocols, one of the :ref:`ETHERTYPE_* constants ` or any other Ethernet protocol number. - Value must be in network-byte-order. - *pkttype* - Optional integer specifying the packet type: - ``PACKET_HOST`` (the default) - Packet addressed to the local host. @@ -207,14 +206,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 @@ -312,7 +311,7 @@ Exceptions The accompanying value is a pair ``(error, string)`` representing an error returned by a library call. *string* represents the description of *error*, as returned by the :c:func:`gai_strerror` C function. The - numeric *error* value will match one of the :const:`EAI_\*` constants + numeric *error* value will match one of the :const:`!EAI_\*` constants defined in this module. .. versionchanged:: 3.3 @@ -348,10 +347,15 @@ Constants AF_INET6 These constants represent the address (and protocol) families, used for the - first argument to :func:`.socket`. If the :const:`AF_UNIX` constant is not + first argument to :func:`~socket.socket`. If the :const:`AF_UNIX` constant is not defined then this protocol is unsupported. More constants may be available depending on the system. +.. data:: AF_UNSPEC + + :const:`AF_UNSPEC` means that + :func:`getaddrinfo` should return socket addresses for any + address family (either IPv4, IPv6, or any other) that can be used. .. data:: SOCK_STREAM SOCK_DGRAM @@ -360,7 +364,7 @@ Constants SOCK_SEQPACKET These constants represent the socket types, used for the second argument to - :func:`.socket`. More constants may be available depending on the system. + :func:`~socket.socket`. More constants may be available depending on the system. (Only :const:`SOCK_STREAM` and :const:`SOCK_DGRAM` appear to be generally useful.) @@ -380,6 +384,8 @@ Constants .. versionadded:: 3.2 +.. _socket-unix-constants: + .. data:: SO_* SOMAXCONN MSG_* @@ -397,7 +403,7 @@ Constants Many constants of these forms, documented in the Unix documentation on sockets and/or the IP protocol, are also defined in the socket module. They are - generally used in arguments to the :meth:`setsockopt` and :meth:`getsockopt` + generally used in arguments to the :meth:`~socket.setsockopt` and :meth:`~socket.getsockopt` methods of socket objects. In most cases, only those symbols that are defined in the Unix header files are defined; for a few symbols, default values are provided. @@ -763,7 +769,7 @@ The following functions all create :ref:`socket objects `. Build a pair of connected socket objects using the given address family, socket type, and protocol number. Address family, socket type, and protocol number are - as for the :func:`.socket` function above. The default family is :const:`AF_UNIX` + as for the :func:`~socket.socket` function above. The default family is :const:`AF_UNIX` if defined on the platform; otherwise, the default is :const:`AF_INET`. The newly created sockets are :ref:`non-inheritable `. @@ -858,8 +864,8 @@ The following functions all create :ref:`socket objects `. .. function:: fromfd(fd, family, type, proto=0) Duplicate the file descriptor *fd* (an integer as returned by a file object's - :meth:`fileno` method) and build a socket object from the result. Address - family, socket type and protocol number are as for the :func:`.socket` function + :meth:`~io.IOBase.fileno` method) and build a socket object from the result. Address + family, socket type and protocol number are as for the :func:`~socket.socket` function above. The file descriptor should refer to a socket, but this is not checked --- subsequent operations on the object may fail if the file descriptor is invalid. This function is rarely needed, but can be used to get or set socket options on @@ -924,7 +930,7 @@ The :mod:`socket` module also offers various network-related services: ``(family, type, proto, canonname, sockaddr)`` In these tuples, *family*, *type*, *proto* are all integers and are - meant to be passed to the :func:`.socket` function. *canonname* will be + meant to be passed to the :func:`~socket.socket` function. *canonname* will be a string representing the canonical name of the *host* if :const:`AI_CANONNAME` is part of the *flags* argument; else *canonname* will be empty. *sockaddr* is a tuple describing a socket address, whose @@ -1040,7 +1046,7 @@ The :mod:`socket` module also offers various network-related services: .. function:: getprotobyname(protocolname) Translate an internet protocol name (for example, ``'icmp'``) to a constant - suitable for passing as the (optional) third argument to the :func:`.socket` + suitable for passing as the (optional) third argument to the :func:`~socket.socket` function. This is usually only needed for sockets opened in "raw" mode (:const:`SOCK_RAW`); for the normal socket modes, the correct protocol is chosen automatically if the protocol is omitted or zero. @@ -1324,7 +1330,7 @@ The :mod:`socket` module also offers various network-related services: Send the list of file descriptors *fds* over an :const:`AF_UNIX` socket *sock*. The *fds* parameter is a sequence of file descriptors. - Consult :meth:`sendmsg` for the documentation of these parameters. + Consult :meth:`~socket.sendmsg` for the documentation of these parameters. .. availability:: Unix, Windows, not Emscripten, not WASI. @@ -1338,7 +1344,7 @@ The :mod:`socket` module also offers various network-related services: Receive up to *maxfds* file descriptors from an :const:`AF_UNIX` socket *sock*. Return ``(msg, list(fds), flags, addr)``. - Consult :meth:`recvmsg` for the documentation of these parameters. + Consult :meth:`~socket.recvmsg` for the documentation of these parameters. .. availability:: Unix, Windows, not Emscripten, not WASI. @@ -1511,7 +1517,7 @@ to sockets. .. method:: socket.getsockopt(level, optname[, buflen]) Return the value of the given socket option (see the Unix man page - :manpage:`getsockopt(2)`). The needed symbolic constants (:const:`SO_\*` etc.) + :manpage:`getsockopt(2)`). The needed symbolic constants (:ref:`SO_\* etc. `) are defined in this module. If *buflen* is absent, an integer option is assumed and its integer value is returned by the function. If *buflen* is present, it specifies the maximum length of the buffer used to receive the option in, and @@ -1931,8 +1937,8 @@ to sockets. .. index:: pair: module; struct Set the value of the given socket option (see the Unix manual page - :manpage:`setsockopt(2)`). The needed symbolic constants are defined in the - :mod:`socket` module (:const:`SO_\*` etc.). The value can be an integer, + :manpage:`setsockopt(2)`). The needed symbolic constants are defined in this + module (:ref:`!SO_\* etc. `). The value can be an integer, ``None`` or a :term:`bytes-like object` representing a buffer. In the later case it is up to the caller to ensure that the bytestring contains the proper bits (see the optional built-in module :mod:`struct` for a way to @@ -2057,10 +2063,10 @@ Example Here are four minimal example programs using the TCP/IP protocol: a server that echoes all data that it receives back (servicing only one client), and a client -using it. Note that a server must perform the sequence :func:`.socket`, +using it. Note that a server must perform the sequence :func:`~socket.socket`, :meth:`~socket.bind`, :meth:`~socket.listen`, :meth:`~socket.accept` (possibly repeating the :meth:`~socket.accept` to service more than one client), while a -client only needs the sequence :func:`.socket`, :meth:`~socket.connect`. Also +client only needs the sequence :func:`~socket.socket`, :meth:`~socket.connect`. Also note that the server does not :meth:`~socket.sendall`/:meth:`~socket.recv` on the socket it is listening on but on the new socket returned by :meth:`~socket.accept`. @@ -2100,7 +2106,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 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 0abdab52340dfd..6dbb34a84a4c40 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. @@ -529,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: @@ -992,9 +992,8 @@ Connection objects Added support for disabling the authorizer using ``None``. .. versionchanged:: 3.13 - - Passing *authorizer_callback* as a keyword argument to is deprecated. - The parameter will become positional-only in Python 3.15. + 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) @@ -1012,9 +1011,8 @@ Connection objects exception. .. versionchanged:: 3.13 - - Passing *progress_handler* as a keyword argument to is deprecated. - The parameter will become positional-only in Python 3.15. + 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) @@ -1041,9 +1039,8 @@ Connection objects .. versionadded:: 3.3 .. versionchanged:: 3.13 - - Passing *trace_callback* as a keyword argument to is deprecated. - The parameter will become positional-only in Python 3.15. + Passing *trace_callback* as a keyword argument is deprecated. + The parameter will become positional-only in Python 3.15. .. method:: enable_load_extension(enabled, /) @@ -1157,6 +1154,10 @@ Connection objects f.write('%s\n' % line) con.close() + .. seealso:: + + :ref:`sqlite3-howto-encoding` + .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) @@ -1223,6 +1224,10 @@ Connection objects .. versionadded:: 3.7 + .. seealso:: + + :ref:`sqlite3-howto-encoding` + .. method:: getlimit(category, /) Get a connection runtime limit. @@ -1444,39 +1449,8 @@ Connection objects and returns a text representation of it. The callable is invoked for SQLite values with the ``TEXT`` data type. By default, this attribute is set to :class:`str`. - If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. - - Example: - .. testcode:: - - con = sqlite3.connect(":memory:") - cur = con.cursor() - - AUSTRIA = "Österreich" - - # by default, rows are returned as str - cur.execute("SELECT ?", (AUSTRIA,)) - row = cur.fetchone() - assert row[0] == AUSTRIA - - # but we can make sqlite3 always return bytestrings ... - con.text_factory = bytes - cur.execute("SELECT ?", (AUSTRIA,)) - row = cur.fetchone() - assert type(row[0]) is bytes - # the bytestrings will be encoded in UTF-8, unless you stored garbage in the - # database ... - assert row[0] == AUSTRIA.encode("utf-8") - - # we can also implement a custom text_factory ... - # here we implement one that appends "foo" to all strings - con.text_factory = lambda x: x.decode("utf-8") + "foo" - cur.execute("SELECT ?", ("bar",)) - row = cur.fetchone() - assert row[0] == "barfoo" - - con.close() + See :ref:`sqlite3-howto-encoding` for more details. .. attribute:: total_changes @@ -1528,7 +1502,7 @@ Cursor objects .. method:: execute(sql, parameters=(), /) - Execute SQL a single SQL statement, + Execute a single SQL statement, optionally binding Python values using :ref:`placeholders `. @@ -1635,7 +1609,6 @@ Cursor objects COMMIT; """) - .. method:: fetchone() If :attr:`~Cursor.row_factory` is ``None``, @@ -2440,9 +2413,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:: @@ -2614,6 +2587,47 @@ With some adjustments, the above recipe can be adapted to use a instead of a :class:`~collections.namedtuple`. +.. _sqlite3-howto-encoding: + +How to handle non-UTF-8 text encodings +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, :mod:`!sqlite3` uses :class:`str` to adapt SQLite values +with the ``TEXT`` data type. +This works well for UTF-8 encoded text, but it might fail for other encodings +and invalid UTF-8. +You can use a custom :attr:`~Connection.text_factory` to handle such cases. + +Because of SQLite's `flexible typing`_, it is not uncommon to encounter table +columns with the ``TEXT`` data type containing non-UTF-8 encodings, +or even arbitrary data. +To demonstrate, let's assume we have a database with ISO-8859-2 (Latin-2) +encoded text, for example a table of Czech-English dictionary entries. +Assuming we now have a :class:`Connection` instance :py:data:`!con` +connected to this database, +we can decode the Latin-2 encoded text using this :attr:`~Connection.text_factory`: + +.. testcode:: + + con.text_factory = lambda data: str(data, encoding="latin2") + +For invalid UTF-8 or arbitrary data in stored in ``TEXT`` table columns, +you can use the following technique, borrowed from the :ref:`unicode-howto`: + +.. testcode:: + + con.text_factory = lambda data: str(data, errors="surrogateescape") + +.. note:: + + The :mod:`!sqlite3` module API does not support strings + containing surrogates. + +.. seealso:: + + :ref:`unicode-howto` + + .. _sqlite3-explanation: Explanation diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 92cf3de2a7b4cf..0db233e2dde33c 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -908,6 +908,12 @@ Constants .. versionadded:: 3.7 +.. data:: HAS_PSK + + Whether the OpenSSL library has built-in support for TLS-PSK. + + .. versionadded:: 3.13 + .. data:: CHANNEL_BINDING_TYPES List of supported TLS channel binding types. Strings in this list @@ -1398,18 +1404,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. @@ -2006,6 +2012,100 @@ to speed up repeated connections from the same clients. >>> ssl.create_default_context().verify_mode # doctest: +SKIP +.. method:: SSLContext.set_psk_client_callback(callback) + + Enables TLS-PSK (pre-shared key) authentication on a client-side connection. + + In general, certificate based authentication should be preferred over this method. + + The parameter ``callback`` is a callable object with the signature: + ``def callback(hint: str | None) -> tuple[str | None, bytes]``. + The ``hint`` parameter is an optional identity hint sent by the server. + The return value is a tuple in the form (client-identity, psk). + Client-identity is an optional string which may be used by the server to + select a corresponding PSK for the client. The string must be less than or + equal to ``256`` octets when UTF-8 encoded. PSK is a + :term:`bytes-like object` representing the pre-shared key. Return a zero + length PSK to reject the connection. + + Setting ``callback`` to :const:`None` removes any existing callback. + + .. note:: + When using TLS 1.3: + + - the ``hint`` parameter is always :const:`None`. + - client-identity must be a non-empty string. + + Example usage:: + + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + context.maximum_version = ssl.TLSVersion.TLSv1_2 + context.set_ciphers('PSK') + + # A simple lambda: + psk = bytes.fromhex('c0ffee') + context.set_psk_client_callback(lambda hint: (None, psk)) + + # A table using the hint from the server: + psk_table = { 'ServerId_1': bytes.fromhex('c0ffee'), + 'ServerId_2': bytes.fromhex('facade') + } + def callback(hint): + return 'ClientId_1', psk_table.get(hint, b'') + context.set_psk_client_callback(callback) + + This method will raise :exc:`NotImplementedError` if :data:`HAS_PSK` is + ``False``. + + .. versionadded:: 3.13 + +.. method:: SSLContext.set_psk_server_callback(callback, identity_hint=None) + + Enables TLS-PSK (pre-shared key) authentication on a server-side connection. + + In general, certificate based authentication should be preferred over this method. + + The parameter ``callback`` is a callable object with the signature: + ``def callback(identity: str | None) -> bytes``. + The ``identity`` parameter is an optional identity sent by the client which can + be used to select a corresponding PSK. + The return value is a :term:`bytes-like object` representing the pre-shared key. + Return a zero length PSK to reject the connection. + + Setting ``callback`` to :const:`None` removes any existing callback. + + The parameter ``identity_hint`` is an optional identity hint string sent to + the client. The string must be less than or equal to ``256`` octets when + UTF-8 encoded. + + .. note:: + When using TLS 1.3 the ``identity_hint`` parameter is not sent to the client. + + Example usage:: + + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.maximum_version = ssl.TLSVersion.TLSv1_2 + context.set_ciphers('PSK') + + # A simple lambda: + psk = bytes.fromhex('c0ffee') + context.set_psk_server_callback(lambda identity: psk) + + # A table using the identity of the client: + psk_table = { 'ClientId_1': bytes.fromhex('c0ffee'), + 'ClientId_2': bytes.fromhex('facade') + } + def callback(identity): + return psk_table.get(identity, b'') + context.set_psk_server_callback(callback, 'ServerId_1') + + This method will raise :exc:`NotImplementedError` if :data:`HAS_PSK` is + ``False``. + + .. versionadded:: 3.13 + .. index:: single: certificates .. index:: single: X509 certificate diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index a8a79012565321..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 diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index a351559a84f1ce..9028ff5c134fa9 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -44,13 +44,14 @@ 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:`~object.__bool__` method that returns ``False`` or a :meth:`__len__` method that +:meth:`~object.__bool__` method that returns ``False`` or a +:meth:`~object.__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`` @@ -197,7 +198,7 @@ exception. Two more operations with the same syntactic priority, :keyword:`in` and :keyword:`not in`, are supported by types that are :term:`iterable` or -implement the :meth:`__contains__` method. +implement the :meth:`~object.__contains__` method. .. _typesnumeric: @@ -717,7 +718,7 @@ that's defined for any rational number, and hence applies to all instances of :class:`int` and :class:`fractions.Fraction`, and all finite instances of :class:`float` and :class:`decimal.Decimal`. Essentially, this function is given by reduction modulo ``P`` for a fixed prime ``P``. The value of ``P`` is -made available to Python as the :attr:`modulus` attribute of +made available to Python as the :attr:`~sys.hash_info.modulus` attribute of :data:`sys.hash_info`. .. impl-detail:: @@ -804,6 +805,7 @@ number, :class:`float`, or :class:`complex`:: hash_value = -2 return hash_value +.. _bltin-boolean-values: .. _typebool: Boolean Type - :class:`bool` @@ -905,9 +907,9 @@ Generator Types --------------- Python's :term:`generator`\s provide a convenient way to implement the iterator -protocol. If a container object's :meth:`__iter__` method is implemented as a +protocol. If a container object's :meth:`~iterator.__iter__` method is implemented as a generator, it will automatically return an iterator object (technically, a -generator object) supplying the :meth:`__iter__` and :meth:`~generator.__next__` +generator object) supplying the :meth:`!__iter__` and :meth:`~generator.__next__` methods. More information about generators can be found in :ref:`the documentation for the yield expression `. @@ -2266,7 +2268,7 @@ expression support in the :mod:`re` module). Return a copy of the string in which each character has been mapped through the given translation table. The table must be an object that implements - indexing via :meth:`__getitem__`, typically a :term:`mapping` or + indexing via :meth:`~object.__getitem__`, typically a :term:`mapping` or :term:`sequence`. When indexed by a Unicode ordinal (an integer), the table object can do any of the following: return a Unicode ordinal or a string, to map the character to one or more other characters; return @@ -3671,7 +3673,7 @@ The conversion types are: +------------+-----------------------------------------------------+-------+ | ``'b'`` | Bytes (any object that follows the | \(5) | | | :ref:`buffer protocol ` or has | | -| | :meth:`__bytes__`). | | +| | :meth:`~object.__bytes__`). | | +------------+-----------------------------------------------------+-------+ | ``'s'`` | ``'s'`` is an alias for ``'b'`` and should only | \(6) | | | be used for Python2/3 code bases. | | @@ -4409,7 +4411,8 @@ The constructors for both classes work the same: :meth:`symmetric_difference_update` methods will accept any iterable as an argument. - Note, the *elem* argument to the :meth:`__contains__`, :meth:`remove`, and + Note, the *elem* argument to the :meth:`~object.__contains__`, + :meth:`remove`, and :meth:`discard` methods may be a set. To support searching for an equivalent frozenset, a temporary one is created from *elem*. @@ -4754,14 +4757,17 @@ support membership tests: .. versionadded:: 3.10 -Keys views are set-like since their entries are unique and :term:`hashable`. If all -values are hashable, so that ``(key, value)`` pairs are unique and hashable, -then the items view is also set-like. (Values views are not treated as set-like +Keys views are set-like since their entries are unique and :term:`hashable`. +Items views also have set-like operations since the (key, value) pairs +are unique and the keys are hashable. +If all values in an items view are hashable as well, +then the items view can interoperate with other sets. +(Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class :class:`collections.abc.Set` are available (for example, ``==``, ``<``, or ``^``). While using set operators, -set-like views accept any iterable as the other operand, unlike sets which only -accept sets as the input. +set-like views accept any iterable as the other operand, +unlike sets which only accept sets as the input. An example of dictionary view usage:: @@ -4856,7 +4862,7 @@ before the statement body is executed and exited when the statement ends: The exception passed in should never be reraised explicitly - instead, this method should return a false value to indicate that the method completed successfully and does not want to suppress the raised exception. This allows - context management code to easily detect whether or not an :meth:`__exit__` + context management code to easily detect whether or not an :meth:`~object.__exit__` method has actually failed. Python defines several context managers to support easy thread synchronisation, @@ -5232,9 +5238,11 @@ instantiated from the type:: TypeError: cannot create 'types.UnionType' instances .. note:: - The :meth:`__or__` method for type objects was added to support the syntax - ``X | Y``. If a metaclass implements :meth:`__or__`, the Union may - override it:: + The :meth:`!__or__` method for type objects was added to support the syntax + ``X | Y``. If a metaclass implements :meth:`!__or__`, the Union may + override it: + + .. doctest:: >>> class M(type): ... def __or__(self, other): @@ -5246,7 +5254,7 @@ instantiated from the type:: >>> C | int 'Hello' >>> int | C - int | __main__.C + int | C .. seealso:: @@ -5320,25 +5328,30 @@ Methods .. index:: pair: object; method Methods are functions that are called using the attribute notation. There are -two flavors: built-in methods (such as :meth:`append` on lists) and class -instance methods. Built-in methods are described with the types that support -them. +two flavors: :ref:`built-in methods ` (such as :meth:`append` +on lists) and :ref:`class instance method `. +Built-in methods are described with the types that support them. If you access a method (a function defined in a class namespace) through an instance, you get a special object: a :dfn:`bound method` (also called -:dfn:`instance method`) object. When called, it will add the ``self`` argument +:ref:`instance method `) object. When called, it will add +the ``self`` argument to the argument list. Bound methods have two special read-only attributes: -``m.__self__`` is the object on which the method operates, and ``m.__func__`` is +:attr:`m.__self__ ` is the object on which the method +operates, and :attr:`m.__func__ ` is the function implementing the method. Calling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)``. -Like function objects, bound method objects support getting arbitrary +Like :ref:`function objects `, bound method objects support +getting arbitrary attributes. However, since method attributes are actually stored on the -underlying function object (``meth.__func__``), setting method attributes on +underlying function object (:attr:`method.__func__`), setting method attributes on bound methods is disallowed. Attempting to set an attribute on a method results in an :exc:`AttributeError` being raised. In order to set a method -attribute, you need to explicitly set it on the underlying function object:: +attribute, you need to explicitly set it on the underlying function object: + +.. doctest:: >>> class C: ... def method(self): @@ -5353,7 +5366,7 @@ attribute, you need to explicitly set it on the underlying function object:: >>> c.method.whoami 'my name is method' -See :ref:`types` for more information. +See :ref:`instance-methods` for more information. .. index:: object; code, code object @@ -5371,10 +5384,10 @@ Code objects are used by the implementation to represent "pseudo-compiled" executable Python code such as a function body. They differ from function objects because they don't contain a reference to their global execution environment. Code objects are returned by the built-in :func:`compile` function -and can be extracted from function objects through their :attr:`__code__` -attribute. See also the :mod:`code` module. +and can be extracted from function objects through their +:attr:`~function.__code__` attribute. See also the :mod:`code` module. -Accessing ``__code__`` raises an :ref:`auditing event ` +Accessing :attr:`~function.__code__` raises an :ref:`auditing event ` ``object.__getattr__`` with arguments ``obj`` and ``"__code__"``. .. index:: @@ -5448,8 +5461,9 @@ It is written as ``NotImplemented``. Internal Objects ---------------- -See :ref:`types` for this information. It describes stack frame objects, -traceback objects, and slice objects. +See :ref:`types` for this information. It describes +:ref:`stack frame objects `, +:ref:`traceback objects `, and slice objects. .. _specialattrs: 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/subprocess.rst b/Doc/library/subprocess.rst index 04340cca9e4a59..d6b892a7ed957d 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -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: @@ -791,9 +791,10 @@ Instances of the :class:`Popen` class have the following methods: .. note:: - The function is implemented using a busy loop (non-blocking call and - short sleeps). Use the :mod:`asyncio` module for an asynchronous wait: - see :class:`asyncio.create_subprocess_exec`. + When the ``timeout`` parameter is not ``None``, then (on POSIX) the + function is implemented using a busy loop (non-blocking call and short + sleeps). Use the :mod:`asyncio` module for an asynchronous wait: see + :class:`asyncio.create_subprocess_exec`. .. versionchanged:: 3.3 *timeout* was added. diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 85eae5f3822575..46159dcef940e7 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -207,3 +207,21 @@ Examining Symbol Tables Return the namespace bound to this name. If more than one or no namespace is bound to this name, a :exc:`ValueError` is raised. + + +.. _symtable-cli: + +Command-Line Usage +------------------ + +.. versionadded:: 3.13 + +The :mod:`symtable` module can be executed as a script from the command line. + +.. code-block:: sh + + python -m symtable [infile...] + +Symbol tables are generated for the specified Python source files and +dumped to stdout. +If no input file is specified, the content is read from stdin. diff --git a/Doc/library/sys.monitoring.rst b/Doc/library/sys.monitoring.rst index 7b02b95fd766a7..762581b7eda7f1 100644 --- a/Doc/library/sys.monitoring.rst +++ b/Doc/library/sys.monitoring.rst @@ -1,14 +1,16 @@ :mod:`sys.monitoring` --- Execution event monitoring ==================================================== -.. module:: sys.monitoring - :synopsis: Access and control event monitoring +.. module:: sys.monitoring + :synopsis: Access and control event monitoring + +.. versionadded:: 3.12 ----------------- .. note:: - ``sys.monitoring`` is a namespace within the ``sys`` module, + :mod:`sys.monitoring` is a namespace within the :mod:`sys` module, not an independent module, so there is no need to ``import sys.monitoring``, simply ``import sys`` and then use ``sys.monitoring``. @@ -18,45 +20,52 @@ 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 +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`_ +* `Events`_ +* :ref:`Callbacks ` Tool identifiers ---------------- -A tool identifier is an integer and associated name. +A tool identifier is an integer and the 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. +Identifiers are integers in the range 0 to 5 inclusive. Registering and using tools ''''''''''''''''''''''''''' -.. function:: use_tool_id(id: int, name: str) -> None +.. function:: use_tool_id(tool_id: int, name: str, /) -> None + + Must be called before *tool_id* can be used. + *tool_id* must be in the range 0 to 5 inclusive. + Raises a :exc:`ValueError` if *tool_id* is in use. - 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(tool_id: int, /) -> None -.. function:: free_tool_id(id: int) -> None + Should be called once a tool no longer requires *tool_id*. + +.. note:: - Should be called once a tool no longer requires ``id``. + :func:`free_tool_id` will not disable global or local events associated + with *tool_id*, nor will it unregister any callback functions. This + function is only intended to be used to notify the VM that the + particular *tool_id* is no longer in use. -.. function:: get_tool(id: int) -> str | None +.. function:: get_tool(tool_id: int, /) -> str | None - Returns the name of the tool if ``id`` is in use, + Returns the name of the tool if *tool_id* is in use, otherwise it returns ``None``. - ``id`` must be in the range 0 to 5 inclusive. + *tool_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:: @@ -75,48 +84,89 @@ 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`_. +.. monitoring-event:: BRANCH + + A conditional branch is taken (or not). + +.. monitoring-event:: CALL + + A call in Python code (event occurs before the call). + +.. monitoring-event:: C_RAISE + + An exception raised from any callable, except for Python functions (event occurs after the exit). + +.. monitoring-event:: C_RETURN + + Return from any callable, except for Python functions (event occurs after the return). + +.. monitoring-event:: EXCEPTION_HANDLED + + An exception is handled. + +.. monitoring-event:: INSTRUCTION + + A VM instruction is about to be executed. + +.. monitoring-event:: JUMP + + An unconditional jump in the control flow graph is made. + +.. monitoring-event:: LINE + + An instruction is about to be executed that has a different line number from the preceding instruction. + +.. monitoring-event:: PY_RESUME + + Resumption of a Python function (for generator and coroutine functions), except for ``throw()`` calls. + +.. monitoring-event:: PY_RETURN + + Return from a Python function (occurs immediately before the return, the callee's frame will be on the stack). + +.. monitoring-event:: PY_START + + Start of a Python function (occurs immediately after the call, the callee's frame will be on the stack) + +.. monitoring-event:: PY_THROW + + A Python function is resumed by a ``throw()`` call. + +.. monitoring-event:: PY_UNWIND + + Exit from a Python function during exception unwinding. + +.. monitoring-event:: PY_YIELD + + Yield from a Python function (occurs immediately before the yield, the callee's frame will be on the stack). + +.. monitoring-event:: RAISE + + An exception is raised, except those that cause a :monitoring-event:`STOP_ITERATION` event. + +.. monitoring-event:: RERAISE + + An exception is re-raised, for example at the end of a :keyword:`finally` block. + +.. monitoring-event:: STOP_ITERATION + + An artificial :exc:`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``. +For example, to specify both :monitoring-event:`PY_RETURN` and :monitoring-event:`PY_START` +events, use the expression ``PY_RETURN | PY_START``. + +.. monitoring-event:: NO_EVENTS + + An alias for ``0`` so users can do explict comparisions like:: + + if get_events(DEBUGGER_ID) == NO_EVENTS: + ... Events are divided into three groups: @@ -127,16 +177,16 @@ 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 +* :monitoring-event:`PY_START` +* :monitoring-event:`PY_RESUME` +* :monitoring-event:`PY_RETURN` +* :monitoring-event:`PY_YIELD` +* :monitoring-event:`CALL` +* :monitoring-event:`LINE` +* :monitoring-event:`INSTRUCTION` +* :monitoring-event:`JUMP` +* :monitoring-event:`BRANCH` +* :monitoring-event:`STOP_ITERATION` Ancillary events '''''''''''''''' @@ -144,12 +194,13 @@ Ancillary events Ancillary events can be monitored like other events, but are controlled by another event: -* C_RAISE -* C_RETURN +* :monitoring-event:`C_RAISE` +* :monitoring-event:`C_RETURN` -The ``C_RETURN`` and ``C_RAISE`` events are are controlled by the ``CALL`` -event. ``C_RETURN`` and ``C_RAISE`` events will only be seen if the -corresponding ``CALL`` event is being monitored. +The :monitoring-event:`C_RETURN` and :monitoring-event:`C_RAISE` events +are controlled by the :monitoring-event:`CALL` event. +:monitoring-event:`C_RETURN` and :monitoring-event:`C_RAISE` events will only be seen if the +corresponding :monitoring-event:`CALL` event is being monitored. Other events '''''''''''' @@ -159,30 +210,31 @@ program and cannot be individually disabled. The other events that can be monitored are: -* PY_THROW -* PY_UNWIND -* RAISE -* EXCEPTION_HANDLED +* :monitoring-event:`PY_THROW` +* :monitoring-event:`PY_UNWIND` +* :monitoring-event:`RAISE` +* :monitoring-event:`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 +specifies that a :exc:`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``. +and coroutines, the :monitoring-event:`STOP_ITERATION` event is provided. +:monitoring-event:`STOP_ITERATION` can be locally disabled, unlike :monitoring-event:`RAISE`. Turning events on and off ------------------------- -In order to monitor an event, it must be turned on and a callback registered. +In order to monitor an event, it must be turned on and a corresponding callback +must be registered. Events can be turned on or off by setting the events either globally or for a particular code object. @@ -192,14 +244,14 @@ Setting events globally Events can be controlled globally by modifying the set of events being monitored. -.. function:: get_events(tool_id: int) -> int +.. function:: get_events(tool_id: int, /) -> int Returns the ``int`` representing all the active events. -.. function:: set_events(tool_id: int, event_set: int) +.. function:: set_events(tool_id: int, event_set: int, /) -> None - Activates all events which are set in ``event_set``. - Raises a ``ValueError`` if ``tool_id`` is not in use. + Activates all events which are set in *event_set*. + Raises a :exc:`ValueError` if *tool_id* is not in use. No events are active by default. @@ -208,14 +260,14 @@ 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 +.. function:: get_local_events(tool_id: int, code: CodeType, /) -> int - Returns all the local events for ``code`` + Returns all the local events for *code* -.. function:: set_local_events(tool_id: int, code: CodeType, event_set: int) +.. function:: set_local_events(tool_id: int, code: CodeType, event_set: int, /) -> None - Activates all the local events for ``code`` which are set in ``event_set``. - Raises a ``ValueError`` if ``tool_id`` is not in use. + Activates all the local events for *code* which are set in *event_set*. + Raises a :exc:`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, @@ -225,8 +277,13 @@ regardless of the local events. Disabling events '''''''''''''''' +.. data:: DISABLE + + A special value that can be returned from a callback function to disable + events for the current code location. + Local events can be disabled for a specific code location by returning -``sys.monitoring.DISABLE`` from a callback function. This does not change +:data:`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 @@ -234,19 +291,26 @@ 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. +.. function:: restart_events() -> None + + Enable all the events that were disabled by :data:`sys.monitoring.DISABLE` + for all tools. + + +.. _callbacks: Registering callback functions ------------------------------ To register a callable for events call -.. function:: register_callback(tool_id: int, event: int, func: Callable | None) -> Callable | None +.. 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`` + Registers the callable *func* for the *event* with the given *tool_id* - If another callback was registered for the given ``tool_id`` and ``event``, + If another callback was registered for the given *tool_id* and *event*, it is unregistered and returned. - Otherwise ``register_callback`` returns ``None``. + Otherwise :func:`register_callback` returns ``None``. Functions can be unregistered by calling @@ -254,47 +318,51 @@ Functions can be unregistered by calling Callback functions can be registered and unregistered at any time. -Registering or unregistering a callback function will generate a ``sys.audit`` event. +Registering or unregistering a callback function will generate a :func:`sys.audit` event. Callback function arguments ''''''''''''''''''''''''''' +.. data:: MISSING + + A special value that is passed to a callback function to indicate + that there are no arguments to the call. + 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``:: +* :monitoring-event:`PY_START` and :monitoring-event:`PY_RESUME`:: func(code: CodeType, instruction_offset: int) -> DISABLE | Any -* ``PY_RETURN`` and ``PY_YIELD``: +* :monitoring-event:`PY_RETURN` and :monitoring-event:`PY_YIELD`:: - ``func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any`` + func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any -* ``CALL``, ``C_RAISE`` and ``C_RETURN``: +* :monitoring-event:`CALL`, :monitoring-event:`C_RAISE` and :monitoring-event:`C_RETURN`:: - ``func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any`` + func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any - If there are no arguments, ``arg0`` is set to ``MISSING``. + If there are no arguments, *arg0* is set to :data:`sys.monitoring.MISSING`. -* ``RAISE``, ``RERAISE``, ``EXCEPTION_HANDLED``, ``PY_UNWIND``, ``PY_THROW`` and ``STOP_ITERATION``: +* :monitoring-event:`RAISE`, :monitoring-event:`RERAISE`, :monitoring-event:`EXCEPTION_HANDLED`, + :monitoring-event:`PY_UNWIND`, :monitoring-event:`PY_THROW` and :monitoring-event:`STOP_ITERATION`:: - ``func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any`` + func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any -* ``LINE``: +* :monitoring-event:`LINE`:: - ``func(code: CodeType, line_number: int) -> DISABLE | Any`` + func(code: CodeType, line_number: int) -> DISABLE | Any -* ``BRANCH`` and ``JUMP``: +* :monitoring-event:`BRANCH` and :monitoring-event:`JUMP`:: - ``func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any`` + func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any - Note that the ``destination_offset`` is where the code will next execute. + 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`` - +* :monitoring-event:`INSTRUCTION`:: + func(code: CodeType, instruction_offset: int) -> DISABLE | Any diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index f9f556306f5827..aaf79205d44282 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -175,7 +175,11 @@ always available. Call ``func(*args)``, while tracing is enabled. The tracing state is saved, and restored afterwards. This is intended to be called from a debugger from - a checkpoint, to recursively debug some other code. + a checkpoint, to recursively debug or profile some other code. + + Tracing is suspended while calling a tracing function set by + :func:`settrace` or :func:`setprofile` to avoid infinite recursion. + :func:`!call_tracing` enables explicit recursion of the tracing function. .. data:: copyright @@ -827,7 +831,7 @@ always available. 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 + objects are :term:`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. @@ -1178,8 +1182,8 @@ always available. names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes have interned keys. - Interned strings are not immortal; you must keep a reference to the return - value of :func:`intern` around to benefit from it. + Interned strings are not :term:`immortal`; you must keep a reference to the + return value of :func:`intern` around to benefit from it. .. function:: is_finalizing() @@ -1201,6 +1205,18 @@ always available. .. versionadded:: 3.12 +.. function:: _is_interned(string) + + Return :const:`True` if the given string is "interned", :const:`False` + otherwise. + + .. versionadded:: 3.13 + + .. impl-detail:: + + It is not guaranteed to exist in all implementations of Python. + + .. data:: last_type last_value last_traceback @@ -1473,13 +1489,16 @@ always available. its return value is not used, so it can simply return ``None``. Error in the profile function will cause itself unset. + .. note:: + The same tracing mechanism is used for :func:`!setprofile` as :func:`settrace`. + To trace calls with :func:`!setprofile` inside a tracing function + (e.g. in a debugger breakpoint), see :func:`call_tracing`. + Profile functions should have three arguments: *frame*, *event*, and *arg*. *frame* is the current stack frame. *event* is a string: ``'call'``, ``'return'``, ``'c_call'``, ``'c_return'``, or ``'c_exception'``. *arg* depends on the event type. - .. audit-event:: sys.setprofile "" sys.setprofile - The events have the following meaning: ``'call'`` @@ -1501,6 +1520,9 @@ always available. ``'c_exception'`` A C function has raised an exception. *arg* is the C function object. + .. audit-event:: sys.setprofile "" sys.setprofile + + .. function:: setrecursionlimit(limit) Set the maximum depth of the Python interpreter stack to *limit*. This limit @@ -1554,13 +1576,16 @@ always available. function to be used for the new scope, or ``None`` if the scope shouldn't be traced. - The local trace function should return a reference to itself (or to another - function for further tracing in that scope), or ``None`` to turn off tracing - in that scope. + The local trace function should return a reference to itself, or to another + function which would then be used as the local trace function for the scope. If there is any error occurred in the trace function, it will be unset, just like ``settrace(None)`` is called. + .. note:: + Tracing is disabled while calling the trace function (e.g. a function set by + :func:`!settrace`). For recursive tracing see :func:`call_tracing`. + The events have the following meaning: ``'call'`` @@ -1575,7 +1600,8 @@ 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 :ref:`frame `. + :attr:`~frame.f_trace_lines` to :const:`False` on that + :ref:`frame `. ``'return'`` A function (or other code block) is about to return. The local trace @@ -1593,7 +1619,7 @@ 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 + requested by setting :attr:`~frame.f_trace_opcodes` to :const:`True` on the :ref:`frame `. Note that as an exception is propagated down the chain of callers, an @@ -1623,8 +1649,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:`~frame.f_trace_lines` and + :attr:`~frame.f_trace_opcodes` attributes added to frames .. function:: set_asyncgen_hooks(firstiter, finalizer) @@ -1781,7 +1807,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:!buffer` attribute. + do not support the :attr:`!buffer` attribute. .. data:: __stdin__ diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index c625c1e1d72954..2faab212e46eff 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -9,7 +9,7 @@ .. versionadded:: 3.2 -**Source code:** :source:`Lib/sysconfig.py` +**Source code:** :source:`Lib/sysconfig` .. index:: single: configuration information @@ -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,27 +70,24 @@ 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*. +- *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. @@ -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() diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index f29ef03267b1ba..7b27fc7e85b62d 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -11,11 +11,11 @@ This module provides an interface to the Unix ``syslog`` library routines. Refer to the Unix manual pages for a detailed description of the ``syslog`` facility. +.. availability:: Unix, not Emscripten, not WASI. + This module wraps the system ``syslog`` family of routines. A pure Python library that can speak to a syslog server is available in the -:mod:`logging.handlers` module as :class:`SysLogHandler`. - -.. include:: ../includes/wasm-notavail.rst +:mod:`logging.handlers` module as :class:`~logging.handlers.SysLogHandler`. The module defines the following functions: @@ -107,22 +107,62 @@ The module defines the following functions: The module defines the following constants: -Priority levels (high to low): - :const:`LOG_EMERG`, :const:`LOG_ALERT`, :const:`LOG_CRIT`, :const:`LOG_ERR`, - :const:`LOG_WARNING`, :const:`LOG_NOTICE`, :const:`LOG_INFO`, - :const:`LOG_DEBUG`. - -Facilities: - :const:`LOG_KERN`, :const:`LOG_USER`, :const:`LOG_MAIL`, :const:`LOG_DAEMON`, - :const:`LOG_AUTH`, :const:`LOG_LPR`, :const:`LOG_NEWS`, :const:`LOG_UUCP`, - :const:`LOG_CRON`, :const:`LOG_SYSLOG`, :const:`LOG_LOCAL0` to - :const:`LOG_LOCAL7`, and, if defined in ````, - :const:`LOG_AUTHPRIV`. - -Log options: - :const:`LOG_PID`, :const:`LOG_CONS`, :const:`LOG_NDELAY`, and, if defined - in ````, :const:`LOG_ODELAY`, :const:`LOG_NOWAIT`, and - :const:`LOG_PERROR`. + +.. data:: LOG_EMERG + LOG_ALERT + LOG_CRIT + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG + + Priority levels (high to low). + + +.. data:: LOG_AUTH + LOG_AUTHPRIV + LOG_CRON + LOG_DAEMON + LOG_FTP + LOG_INSTALL + LOG_KERN + LOG_LAUNCHD + LOG_LPR + LOG_MAIL + LOG_NETINFO + LOG_NEWS + LOG_RAS + LOG_REMOTEAUTH + LOG_SYSLOG + LOG_USER + LOG_UUCP + LOG_LOCAL0 + LOG_LOCAL1 + LOG_LOCAL2 + LOG_LOCAL3 + LOG_LOCAL4 + LOG_LOCAL5 + LOG_LOCAL6 + LOG_LOCAL7 + + Facilities, depending on availability in ```` for :const:`LOG_AUTHPRIV`, + :const:`LOG_FTP`, :const:`LOG_NETINFO`, :const:`LOG_REMOTEAUTH`, + :const:`LOG_INSTALL` and :const:`LOG_RAS`. + + .. versionchanged:: 3.13 + Added :const:`LOG_FTP`, :const:`LOG_NETINFO`, :const:`LOG_REMOTEAUTH`, + :const:`LOG_INSTALL`, :const:`LOG_RAS`, and :const:`LOG_LAUNCHD`. + +.. data:: LOG_PID + LOG_CONS + LOG_NDELAY + LOG_ODELAY + LOG_NOWAIT + LOG_PERROR + + Log options, depending on availability in ```` for + :const:`LOG_ODELAY`, :const:`LOG_NOWAIT` and :const:`LOG_PERROR`. Examples diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 62d67bc577c7d0..3e5723a66780ca 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -1156,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 097f7087eccab9..9add8500c7788c 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -18,7 +18,7 @@ This module creates temporary files and directories. It works on all supported platforms. :class:`TemporaryFile`, :class:`NamedTemporaryFile`, :class:`TemporaryDirectory`, and :class:`SpooledTemporaryFile` are high-level interfaces which provide automatic cleanup and can be used as -context managers. :func:`mkstemp` and +:term:`context managers `. :func:`mkstemp` and :func:`mkdtemp` are lower-level functions which require manual cleanup. All the user-callable functions and constructors take additional arguments which @@ -41,7 +41,7 @@ The module defines the following user-callable items: this; your code should not rely on a temporary file created using this function having or not having a visible name in the file system. - The resulting object can be used as a context manager (see + The resulting object can be used as a :term:`context manager` (see :ref:`tempfile-examples`). On completion of the context or destruction of the file object the temporary file will be removed from the filesystem. @@ -87,9 +87,9 @@ The module defines the following user-callable items: determine whether and how the named file should be automatically deleted. The returned object is always a :term:`file-like object` whose :attr:`!file` - attribute is the underlying true file object. This :term:`file-like object` + attribute is the underlying true file object. This file-like object can be used in a :keyword:`with` statement, just like a normal file. The - name of the temporary file can be retrieved from the :attr:`name` attribute + name of the temporary file can be retrieved from the :attr:`!name` attribute of the returned file-like object. On Unix, unlike with the :func:`TemporaryFile`, the directory entry does not get unlinked immediately after the file creation. @@ -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` @@ -147,22 +147,24 @@ The module defines the following user-callable items: This class operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or - until the file's :func:`fileno` method is called, at which point the + until the file's :func:`~io.IOBase.fileno` method is called, at which point the contents are written to disk and operation proceeds as with :func:`TemporaryFile`. - The resulting file has one additional method, :func:`rollover`, which - causes the file to roll over to an on-disk file regardless of its size. + .. method:: SpooledTemporaryFile.rollover - The returned object is a file-like object whose :attr:`_file` attribute + The resulting file has one additional method, :meth:`!rollover`, which + causes the file to roll over to an on-disk file regardless of its size. + + The returned object is a file-like object whose :attr:`!_file` attribute is either an :class:`io.BytesIO` or :class:`io.TextIOWrapper` object (depending on whether binary or text *mode* was specified) or a true file - object, depending on whether :func:`rollover` has been called. This + object, depending on whether :meth:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like a normal file. .. versionchanged:: 3.3 - the truncate method now accepts a ``size`` argument. + the truncate method now accepts a *size* argument. .. versionchanged:: 3.8 Added *errors* parameter. @@ -176,24 +178,28 @@ The module defines the following user-callable items: .. class:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False, *, delete=True) This class securely creates a temporary directory using the same rules as :func:`mkdtemp`. - The resulting object can be used as a context manager (see + The resulting object can be used as a :term:`context manager` (see :ref:`tempfile-examples`). On completion of the context or destruction of the temporary directory object, the newly created temporary directory and all its contents are removed from the filesystem. - The directory name can be retrieved from the :attr:`name` attribute of the - returned object. When the returned object is used as a context manager, the - :attr:`name` will be assigned to the target of the :keyword:`!as` clause in - the :keyword:`with` statement, if there is one. + .. attribute:: TemporaryDirectory.name + + The directory name can be retrieved from the :attr:`!name` attribute of the + returned object. When the returned object is used as a :term:`context manager`, the + :attr:`!name` will be assigned to the target of the :keyword:`!as` clause in + the :keyword:`with` statement, if there is one. - The directory can be explicitly cleaned up by calling the - :func:`cleanup` method. If *ignore_cleanup_errors* is true, any unhandled - exceptions during explicit or implicit cleanup (such as a - :exc:`PermissionError` removing open files on Windows) will be ignored, - and the remaining removable items deleted on a "best-effort" basis. - Otherwise, errors will be raised in whatever context cleanup occurs - (the :func:`cleanup` call, exiting the context manager, when the object - is garbage-collected or during interpreter shutdown). + .. method:: TemporaryDirectory.cleanup + + The directory can be explicitly cleaned up by calling the + :meth:`!cleanup` method. If *ignore_cleanup_errors* is true, any unhandled + exceptions during explicit or implicit cleanup (such as a + :exc:`PermissionError` removing open files on Windows) will be ignored, + and the remaining removable items deleted on a "best-effort" basis. + Otherwise, errors will be raised in whatever context cleanup occurs + (the :meth:`!cleanup` call, exiting the context manager, when the object + is garbage-collected or during interpreter shutdown). The *delete* parameter can be used to disable cleanup of the directory tree upon exiting the context. While it may seem unusual for a context manager @@ -404,13 +410,13 @@ Here are some examples of typical usage of the :mod:`tempfile` module:: # create a temporary file using a context manager # close the file, use the name to open the file again - >>> with tempfile.TemporaryFile(delete_on_close=False) as fp: - ... fp.write(b'Hello world!') - ... fp.close() - # the file is closed, but not removed - # open the file again by using its name - ... with open(fp.name) as f - ... f.read() + >>> with tempfile.NamedTemporaryFile(delete_on_close=False) as fp: + ... fp.write(b'Hello world!') + ... fp.close() + ... # the file is closed, but not removed + ... # open the file again by using its name + ... with open(fp.name, mode='rb') as f: + ... f.read() b'Hello world!' >>> # file is now removed diff --git a/Doc/library/termios.rst b/Doc/library/termios.rst index fb1ff567d49e5c..57705ddc4e6470 100644 --- a/Doc/library/termios.rst +++ b/Doc/library/termios.rst @@ -16,6 +16,8 @@ complete description of these calls, see :manpage:`termios(3)` Unix manual page. It is only available for those Unix versions that support POSIX *termios* style tty I/O control configured during installation. +.. availability:: Unix. + All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by ``sys.stdin.fileno()``, or a :term:`file object`, such as ``sys.stdin`` itself. @@ -43,10 +45,20 @@ The module defines the following functions: Set the tty attributes for file descriptor *fd* from the *attributes*, which is a list like the one returned by :func:`tcgetattr`. The *when* argument - determines when the attributes are changed: :const:`TCSANOW` to change - immediately, :const:`TCSADRAIN` to change after transmitting all queued output, - or :const:`TCSAFLUSH` to change after transmitting all queued output and - discarding all queued input. + determines when the attributes are changed: + + .. data:: TCSANOW + + Change attributes immediately. + + .. data:: TCSADRAIN + + Change attributes after transmitting all queued output. + + .. data:: TCSAFLUSH + + Change attributes after transmitting all queued output and + discarding all queued input. .. function:: tcsendbreak(fd, duration) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index de60151bb32ce1..6cbdc39b3c024d 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -159,6 +159,9 @@ guidelines to be followed: Running tests using the command-line interface ---------------------------------------------- +.. module:: test.regrtest + :synopsis: Drives the regression test suite. + The :mod:`test` package can be run as a script to drive Python's regression test suite, thanks to the :option:`-m` option: :program:`python -m test`. Under the hood, it uses :mod:`test.regrtest`; the call :program:`python -m @@ -498,44 +501,6 @@ The :mod:`test.support` module defines the following functions: rather than looking directly in the path directories. -.. function:: match_test(test) - - Determine whether *test* matches the patterns set in :func:`set_match_tests`. - - -.. function:: set_match_tests(accept_patterns=None, ignore_patterns=None) - - Define match patterns on test filenames and test method names for filtering tests. - - -.. function:: run_unittest(*classes) - - Execute :class:`unittest.TestCase` subclasses passed to the function. The - function scans the classes for methods starting with the prefix ``test_`` - and executes the tests individually. - - It is also legal to pass strings as parameters; these should be keys in - ``sys.modules``. Each associated module will be scanned by - ``unittest.TestLoader.loadTestsFromModule()``. This is usually seen in the - following :func:`test_main` function:: - - def test_main(): - support.run_unittest(__name__) - - This will run all tests defined in the named module. - - -.. function:: run_doctest(module, verbosity=None, optionflags=0) - - Run :func:`doctest.testmod` on the given *module*. Return - ``(failure_count, test_count)``. - - If *verbosity* is ``None``, :func:`doctest.testmod` is run with verbosity - set to :data:`verbose`. Otherwise, it is run with verbosity set to - ``None``. *optionflags* is passed as ``optionflags`` to - :func:`doctest.testmod`. - - .. function:: get_pagesize() Get size of a page in bytes. @@ -1043,7 +1008,7 @@ The :mod:`test.support` module defines the following classes: :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__`. + On both platforms, the old value is restored by :meth:`~object.__exit__`. .. class:: SaveSignals() diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index e2952ce3cc2ca3..7445410f91808c 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -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 23d8cd158abd5d..b85b7f008d1594 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -127,10 +127,13 @@ This module defines the following functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD. .. versionadded:: 3.8 + .. versionchanged:: 3.13 + Added support for GNU/kFreeBSD. + .. function:: enumerate() diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 6ffe4ac4284140..577600881676b3 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -71,8 +71,8 @@ An explanation of some terminology and conventions is in order. * On the other hand, the precision of :func:`.time` and :func:`sleep` is better than their Unix equivalents: times are expressed as floating point numbers, :func:`.time` returns the most accurate time available (using Unix - :c:func:`gettimeofday` where available), and :func:`sleep` will accept a time - with a nonzero fraction (Unix :c:func:`select` is used to implement this, where + :c:func:`!gettimeofday` where available), and :func:`sleep` will accept a time + with a nonzero fraction (Unix :c:func:`!select` is used to implement this, where available). * The time value as returned by :func:`gmtime`, :func:`localtime`, and @@ -84,12 +84,14 @@ An explanation of some terminology and conventions is in order. See :class:`struct_time` for a description of these objects. .. versionchanged:: 3.3 - The :class:`struct_time` type was extended to provide the :attr:`tm_gmtoff` - and :attr:`tm_zone` attributes when platform supports corresponding + The :class:`struct_time` type was extended to provide + the :attr:`~struct_time.tm_gmtoff` and :attr:`~struct_time.tm_zone` + attributes when platform supports corresponding ``struct tm`` members. .. versionchanged:: 3.6 - The :class:`struct_time` attributes :attr:`tm_gmtoff` and :attr:`tm_zone` + The :class:`struct_time` attributes + :attr:`~struct_time.tm_gmtoff` and :attr:`~struct_time.tm_zone` are now available on all platforms. * Use the following functions to convert between time representations: @@ -501,6 +503,8 @@ Functions When used with the :func:`strptime` function, the ``%p`` directive only affects the output hour field if the ``%I`` directive is used to parse the hour. + .. _leap-second: + (2) The range really is ``0`` to ``61``; value ``60`` is valid in timestamps representing `leap seconds`_ and value ``61`` is supported @@ -571,32 +575,55 @@ Functions tuple` interface: values can be accessed by index and by attribute name. The following values are present: - +-------+-------------------+---------------------------------+ - | Index | Attribute | Values | - +=======+===================+=================================+ - | 0 | :attr:`tm_year` | (for example, 1993) | - +-------+-------------------+---------------------------------+ - | 1 | :attr:`tm_mon` | range [1, 12] | - +-------+-------------------+---------------------------------+ - | 2 | :attr:`tm_mday` | range [1, 31] | - +-------+-------------------+---------------------------------+ - | 3 | :attr:`tm_hour` | range [0, 23] | - +-------+-------------------+---------------------------------+ - | 4 | :attr:`tm_min` | range [0, 59] | - +-------+-------------------+---------------------------------+ - | 5 | :attr:`tm_sec` | range [0, 61]; see **(2)** in | - | | | :func:`strftime` description | - +-------+-------------------+---------------------------------+ - | 6 | :attr:`tm_wday` | range [0, 6], Monday is 0 | - +-------+-------------------+---------------------------------+ - | 7 | :attr:`tm_yday` | range [1, 366] | - +-------+-------------------+---------------------------------+ - | 8 | :attr:`tm_isdst` | 0, 1 or -1; see below | - +-------+-------------------+---------------------------------+ - | N/A | :attr:`tm_zone` | abbreviation of timezone name | - +-------+-------------------+---------------------------------+ - | N/A | :attr:`tm_gmtoff` | offset east of UTC in seconds | - +-------+-------------------+---------------------------------+ + .. list-table:: + + * - Index + - Attribute + - Values + + * - 0 + - .. attribute:: tm_year + - (for example, 1993) + + * - 1 + - .. attribute:: tm_mon + - range [1, 12] + + * - 2 + - .. attribute:: tm_day + - range [1, 31] + + * - 3 + - .. attribute:: tm_hour + - range [0, 23] + + * - 4 + - .. attribute:: tm_min + - range [0, 59] + + * - 5 + - .. attribute:: tm_sec + - range [0, 61]; see :ref:`Note (2) ` in :func:`strftime` + + * - 6 + - .. attribute:: tm_wday + - range [0, 6]; Monday is 0 + + * - 7 + - .. attribute:: tm_yday + - range [1, 366] + + * - 8 + - .. attribute:: tm_isdst + - 0, 1 or -1; see below + + * - N/A + - .. attribute:: tm_zone + - abbreviation of timezone name + + * - N/A + - .. attribute:: tm_gmtoff + - offset east of UTC in seconds Note that unlike the C structure, the month value is a range of [1, 12], not [0, 11]. @@ -917,8 +944,8 @@ Timezone Constants For the above Timezone constants (:data:`altzone`, :data:`daylight`, :data:`timezone`, and :data:`tzname`), the value is determined by the timezone rules in effect at module load time or the last time :func:`tzset` is called and may be incorrect - for times in the past. It is recommended to use the :attr:`tm_gmtoff` and - :attr:`tm_zone` results from :func:`localtime` to obtain timezone information. + for times in the past. It is recommended to use the :attr:`~struct_time.tm_gmtoff` and + :attr:`~struct_time.tm_zone` results from :func:`localtime` to obtain timezone information. .. seealso:: diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index b3d2a1b9e0600f..616f8365b80f6c 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -151,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)``. @@ -214,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.messagebox.rst b/Doc/library/tkinter.messagebox.rst index 56c1d6c132afd2..56090a0a0e424b 100644 --- a/Doc/library/tkinter.messagebox.rst +++ b/Doc/library/tkinter.messagebox.rst @@ -11,7 +11,8 @@ The :mod:`tkinter.messagebox` module provides a template base class as well as a variety of convenience methods for commonly used configurations. The message -boxes are modal and will return a subset of (True, False, OK, None, Yes, No) based on +boxes are modal and will return a subset of (``True``, ``False``, ``None``, +:data:`OK`, :data:`CANCEL`, :data:`YES`, :data:`NO`) based on the user's selection. Common message box styles and layouts include but are not limited to: @@ -19,21 +20,175 @@ limited to: .. class:: Message(master=None, **options) - Create a default information message box. + Create a message window with an application-specified message, an icon + and a set of buttons. + Each of the buttons in the message window is identified by a unique symbolic name (see the *type* options). + + The following options are supported: + + *command* + Specifies the function to invoke when the user closes the dialog. + The name of the button clicked by the user to close the dialog is + passed as argument. + This is only available on macOS. + + *default* + Gives the :ref:`symbolic name ` of the default button + for this message window (:data:`OK`, :data:`CANCEL`, and so on). + If this option is not specified, the first button in the dialog will + be made the default. + + *detail* + Specifies an auxiliary message to the main message given by the + *message* option. + The message detail will be presented beneath the main message and, + where supported by the OS, in a less emphasized font than the main + message. + + *icon* + Specifies an :ref:`icon ` to display. + If this option is not specified, then the :data:`INFO` icon will be + displayed. + + *message* + Specifies the message to display in this message box. + The default value is an empty string. + + *parent* + Makes the specified window the logical parent of the message box. + The message box is displayed on top of its parent window. + + *title* + Specifies a string to display as the title of the message box. + This option is ignored on macOS, where platform guidelines forbid + the use of a title on this kind of dialog. + + *type* + Arranges for a :ref:`predefined set of buttons ` + to be displayed. + + .. method:: show(**options) + + Display a message window and wait for the user to select one of the buttons. Then return the symbolic name of the selected button. + Keyword arguments can override options specified in the constructor. + **Information message box** -.. method:: showinfo(title=None, message=None, **options) +.. function:: showinfo(title=None, message=None, **options) + + Creates and displays an information message box with the specified title + and message. **Warning message boxes** -.. method:: showwarning(title=None, message=None, **options) - showerror(title=None, message=None, **options) +.. function:: showwarning(title=None, message=None, **options) + + Creates and displays a warning message box with the specified title + and message. + +.. function:: showerror(title=None, message=None, **options) + + Creates and displays an error message box with the specified title + and message. **Question message boxes** -.. method:: askquestion(title=None, message=None, **options) - askokcancel(title=None, message=None, **options) - askretrycancel(title=None, message=None, **options) - askyesno(title=None, message=None, **options) - askyesnocancel(title=None, message=None, **options) +.. function:: askquestion(title=None, message=None, *, type=YESNO, **options) + + Ask a question. By default shows buttons :data:`YES` and :data:`NO`. + Returns the symbolic name of the selected button. + +.. function:: askokcancel(title=None, message=None, **options) + + Ask if operation should proceed. Shows buttons :data:`OK` and :data:`CANCEL`. + Returns ``True`` if the answer is ok and ``False`` otherwise. + +.. function:: askretrycancel(title=None, message=None, **options) + + Ask if operation should be retried. Shows buttons :data:`RETRY` and :data:`CANCEL`. + Return ``True`` if the answer is yes and ``False`` otherwise. + +.. function:: askyesno(title=None, message=None, **options) + + Ask a question. Shows buttons :data:`YES` and :data:`NO`. + Returns ``True`` if the answer is yes and ``False`` otherwise. + +.. function:: askyesnocancel(title=None, message=None, **options) + + Ask a question. Shows buttons :data:`YES`, :data:`NO` and :data:`CANCEL`. + Return ``True`` if the answer is yes, ``None`` if cancelled, and ``False`` + otherwise. + + +.. _messagebox-buttons: + +Symbolic names of buttons: + +.. data:: ABORT + :value: 'abort' +.. data:: RETRY + :value: 'retry' +.. data:: IGNORE + :value: 'ignore' +.. data:: OK + :value: 'ok' +.. data:: CANCEL + :value: 'cancel' +.. data:: YES + :value: 'yes' +.. data:: NO + :value: 'no' + +.. _messagebox-types: + +Predefined sets of buttons: + +.. data:: ABORTRETRYIGNORE + :value: 'abortretryignore' + + Displays three buttons whose symbolic names are :data:`ABORT`, + :data:`RETRY` and :data:`IGNORE`. + +.. data:: OK + :value: 'ok' + :noindex: + + Displays one button whose symbolic name is :data:`OK`. + +.. data:: OKCANCEL + :value: 'okcancel' + + Displays two buttons whose symbolic names are :data:`OK` and + :data:`CANCEL`. + +.. data:: RETRYCANCEL + :value: 'retrycancel' + + Displays two buttons whose symbolic names are :data:`RETRY` and + :data:`CANCEL`. + +.. data:: YESNO + :value: 'yesno' + + Displays two buttons whose symbolic names are :data:`YES` and + :data:`NO`. + +.. data:: YESNOCANCEL + :value: 'yesnocancel' + + Displays three buttons whose symbolic names are :data:`YES`, + :data:`NO` and :data:`CANCEL`. + +.. _messagebox-icons: + +Icon images: + +.. data:: ERROR + :value: 'error' +.. data:: INFO + :value: 'info' +.. data:: QUESTION + :value: 'question' +.. data:: WARNING + :value: 'warning' diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 76cccc4e9dc9bc..e084d8554c7c09 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -58,8 +58,8 @@ details that are unchanged. * `Modern Tkinter for Busy Python Developers `_ By Mark Roseman. (ISBN 978-1999149567) - * `Python and Tkinter Programming `_ - By Alan Moore. (ISBN 978-1788835886) + * `Python GUI programming with Tkinter `_ + By Alan D. Moore. (ISBN 978-1788835886) * `Programming Python `_ By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101) @@ -232,6 +232,9 @@ The modules that provide Tk support include: Additional modules: +.. module:: _tkinter + :synopsis: A binary module that contains the low-level interface to Tcl/Tk. + :mod:`_tkinter` A binary module that contains the low-level interface to Tcl/Tk. It is automatically imported by the main :mod:`tkinter` module, @@ -529,24 +532,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 9f2f9eb858afd4..6e01ec7b291255 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -104,33 +104,33 @@ Standard Options 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. | - +-----------+--------------------------------------------------------------+ +.. 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". @@ -1391,32 +1391,42 @@ option. If you don't know the class name of a widget, use the method .. method:: element_create(elementname, etype, *args, **kw) Create a new element in the current theme, of the given *etype* which is - expected to be either "image", "from" or "vsapi". The latter is only - available in Tk 8.6a for Windows XP and Vista and is not described here. + expected to be either "image", "from" or "vsapi". + The latter is only available in Tk 8.6 on Windows. If "image" is used, *args* should contain the default image name followed 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. + + Example:: + + img1 = tkinter.PhotoImage(master=root, file='button.png') + img1 = tkinter.PhotoImage(master=root, file='button-pressed.png') + img1 = tkinter.PhotoImage(master=root, file='button-active.png') + style = ttk.Style(root) + style.element_create('Button.button', 'image', + img1, ('pressed', img2), ('active', img3), + border=(2, 4), sticky='we') If "from" is used as the value of *etype*, :meth:`element_create` will clone an existing @@ -1425,6 +1435,68 @@ option. If you don't know the class name of a widget, use the method If this element to clone from is not specified, an empty element will be used. *kw* is discarded. + Example:: + + style = ttk.Style(root) + style.element_create('plain.background', 'from', 'default') + + If "vsapi" is used as the value of *etype*, :meth:`element_create` + will create a new element in the current theme whose visual appearance + is drawn using the Microsoft Visual Styles API which is responsible + for the themed styles on Windows XP and Vista. + *args* is expected to contain the Visual Styles class and part as + given in the Microsoft documentation followed by an optional sequence + of tuples of ttk states and the corresponding Visual Styles API state + value. + *kw* may have the following options: + + padding=padding + Specify the element's interior padding. + *padding* is a list of up to four integers specifying the left, + top, right and bottom padding quantities respectively. + If fewer than four elements are specified, bottom defaults to top, + right defaults to left, and top defaults to left. + In other words, a list of three numbers specify the left, vertical, + and right padding; a list of two numbers specify the horizontal + and the vertical padding; a single number specifies the same + padding all the way around the widget. + This option may not be mixed with any other options. + + margins=padding + Specifies the elements exterior padding. + *padding* is a list of up to four integers specifying the left, top, + right and bottom padding quantities respectively. + This option may not be mixed with any other options. + + width=width + Specifies the width for the element. + If this option is set then the Visual Styles API will not be queried + for the recommended size or the part. + If this option is set then *height* should also be set. + The *width* and *height* options cannot be mixed with the *padding* + or *margins* options. + + height=height + Specifies the height of the element. + See the comments for *width*. + + Example:: + + style = ttk.Style(root) + style.element_create('pin', 'vsapi', 'EXPLORERBAR', 3, [ + ('pressed', '!selected', 3), + ('active', '!selected', 2), + ('pressed', 'selected', 6), + ('active', 'selected', 5), + ('selected', 4), + ('', 1)]) + style.layout('Explorer.Pin', + [('Explorer.Pin.pin', {'sticky': 'news'})]) + pin = ttk.Checkbutton(style='Explorer.Pin') + pin.pack(expand=True, fill='both') + + .. versionchanged:: 3.13 + Added support of the "vsapi" element factory. .. method:: element_names() @@ -1504,22 +1576,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/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..8854905e192b45 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`. @@ -187,7 +187,8 @@ Programmatic Interface Merge in data from another :class:`CoverageResults` object. - .. method:: write_results(show_missing=True, summary=False, coverdir=None) + .. method:: write_results(show_missing=True, summary=False, coverdir=None,\ + *, ignore_missing_files=False) Write coverage results. Set *show_missing* to show lines that had no hits. Set *summary* to include in the output the coverage summary per @@ -195,6 +196,13 @@ Programmatic Interface result files will be output. If ``None``, the results for each source file are placed in its directory. + If *ignore_missing_files* is ``True``, coverage counts for files that no + longer exist are silently ignored. Otherwise, a missing file will + raise a :exc:`FileNotFoundError`. + + .. versionchanged:: 3.13 + Added *ignore_missing_files* parameter. + A simple example demonstrating the use of the programmatic interface:: import sys diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index 67ee73d4b2e1e5..dfbd04de243a3c 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -16,7 +16,8 @@ interpreter. .. index:: pair: object; traceback -The module uses traceback objects --- these are objects of type :class:`types.TracebackType`, +The module uses :ref:`traceback objects ` --- these are +objects of type :class:`types.TracebackType`, which are assigned to the ``__traceback__`` field of :class:`BaseException` instances. .. seealso:: @@ -66,7 +67,8 @@ The module defines the following functions: The optional *limit* argument has the same meaning as for :func:`print_tb`. If *chain* is true (the default), then chained exceptions (the - :attr:`__cause__` or :attr:`__context__` attributes of the exception) will be + :attr:`~BaseException.__cause__` or :attr:`~BaseException.__context__` + attributes of the exception) will be printed as well, like the interpreter itself does when printing an unhandled exception. @@ -135,7 +137,7 @@ The module defines the following functions: text line is not ``None``. -.. function:: format_exception_only(exc, /[, value]) +.. function:: format_exception_only(exc, /[, value], *, show_group=False) 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 @@ -149,6 +151,10 @@ The module defines the following functions: can be passed as the first argument. If *value* is provided, the first argument is ignored in order to provide backwards compatibility. + 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.10 The *etype* parameter has been renamed to *exc* and is now positional-only. @@ -156,6 +162,9 @@ The module defines the following functions: .. versionchanged:: 3.11 The returned list now includes any notes attached to the exception. + .. versionchanged:: 3.13 + *show_group* parameter was added. + .. function:: format_exception(exc, /[, value, tb], limit=None, chain=True) @@ -205,7 +214,8 @@ The module defines the following functions: .. function:: walk_tb(tb) - Walk a traceback following ``tb_next`` yielding the frame and line number + Walk a traceback following :attr:`~traceback.tb_next` yielding the frame and + line number for each frame. This helper is used with :meth:`StackSummary.extract`. .. versionadded:: 3.5 @@ -225,10 +235,11 @@ capture data for later printing in a lightweight fashion. Capture an exception for later rendering. *limit*, *lookup_lines* and *capture_locals* are as for the :class:`StackSummary` class. - If *compact* is true, only data that is required by :class:`TracebackException`'s - ``format`` method is saved in the class attributes. In particular, the - ``__context__`` field is calculated only if ``__cause__`` is ``None`` and - ``__suppress_context__`` is false. + If *compact* is true, only data that is required by + :class:`!TracebackException`'s :meth:`format` method + is saved in the class attributes. In particular, the + :attr:`__context__` field is calculated only if :attr:`__cause__` is + ``None`` and :attr:`__suppress_context__` is false. Note that when locals are captured, they are also shown in the traceback. @@ -246,27 +257,31 @@ capture data for later printing in a lightweight fashion. .. attribute:: __cause__ - A :class:`TracebackException` of the original ``__cause__``. + A :class:`!TracebackException` of the original + :attr:`~BaseException.__cause__`. .. attribute:: __context__ - A :class:`TracebackException` of the original ``__context__``. + A :class:`!TracebackException` of the original + :attr:`~BaseException.__context__`. .. attribute:: exceptions If ``self`` represents an :exc:`ExceptionGroup`, this field holds a list of - :class:`TracebackException` instances representing the nested exceptions. + :class:`!TracebackException` instances representing the nested exceptions. Otherwise it is ``None``. .. versionadded:: 3.11 .. attribute:: __suppress_context__ - The ``__suppress_context__`` value from the original exception. + The :attr:`~BaseException.__suppress_context__` value from the original + exception. .. attribute:: __notes__ - The ``__notes__`` value from the original exception, or ``None`` + The :attr:`~BaseException.__notes__` value from the original exception, + or ``None`` if the exception does not have any notes. If it is not ``None`` is it formatted in the traceback after the exception string. @@ -280,6 +295,14 @@ capture data for later printing in a lightweight fashion. The class of the original traceback. + .. deprecated:: 3.13 + + .. attribute:: exc_type_str + + String display of the class of the original exception. + + .. versionadded:: 3.13 + .. attribute:: filename For syntax errors - the file name where the error occurred. @@ -332,8 +355,8 @@ capture data for later printing in a lightweight fashion. Format the exception. - If *chain* is not ``True``, ``__cause__`` and ``__context__`` will not - be formatted. + If *chain* is not ``True``, :attr:`__cause__` and :attr:`__context__` + will not be formatted. The return value is a generator of strings, each ending in a newline and some containing internal newlines. :func:`~traceback.print_exception` @@ -508,27 +531,32 @@ The output for the example would look similar to this: *** print_tb: File "", line 10, in lumberjack() + ~~~~~~~~~~^^ *** print_exception: Traceback (most recent call last): File "", line 10, in lumberjack() + ~~~~~~~~~~^^ File "", line 4, in lumberjack bright_side_of_life() + ~~~~~~~~~~~~~~~~~~~^^ IndexError: tuple index out of range *** print_exc: Traceback (most recent call last): File "", line 10, in lumberjack() + ~~~~~~~~~~^^ File "", line 4, in lumberjack bright_side_of_life() + ~~~~~~~~~~~~~~~~~~~^^ IndexError: tuple index out of range *** format_exc, first and last line: Traceback (most recent call last): IndexError: tuple index out of range *** format_exception: ['Traceback (most recent call last):\n', - ' File "", line 10, in \n lumberjack()\n', - ' File "", line 4, in lumberjack\n bright_side_of_life()\n', + ' File "", line 10, in \n lumberjack()\n ~~~~~~~~~~^^\n', + ' File "", line 4, in lumberjack\n bright_side_of_life()\n ~~~~~~~~~~~~~~~~~~~^^\n', ' File "", line 7, in bright_side_of_life\n return tuple()[0]\n ~~~~~~~^^^\n', 'IndexError: tuple index out of range\n'] *** extract_tb: @@ -536,8 +564,8 @@ The output for the example would look similar to this: , line 4 in lumberjack>, , line 7 in bright_side_of_life>] *** format_tb: - [' File "", line 10, in \n lumberjack()\n', - ' File "", line 4, in lumberjack\n bright_side_of_life()\n', + [' File "", line 10, in \n lumberjack()\n ~~~~~~~~~~^^\n', + ' File "", line 4, in lumberjack\n bright_side_of_life()\n ~~~~~~~~~~~~~~~~~~~^^\n', ' File "", line 7, in bright_side_of_life\n return tuple()[0]\n ~~~~~~~^^^\n'] *** tb_lineno: 10 diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index fc7f98c7931fa5..20ba7d7e0a45b3 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -15,6 +15,8 @@ The :mod:`tty` module defines functions for putting the tty into cbreak and raw modes. +.. availability:: Unix. + Because it requires the :mod:`termios` module, it will work only on Unix. The :mod:`tty` module defines the following functions: @@ -43,6 +45,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 +56,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/types.rst b/Doc/library/types.rst index 54c3907dec98cc..8ce67cf77253c3 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -378,17 +378,15 @@ Standard names are defined for the following types: .. data:: FrameType - The type of frame objects such as found in ``tb.tb_frame`` if ``tb`` is a - traceback object. - - See :ref:`the language reference ` for details of the - available attributes and operations. + The type of :ref:`frame objects ` such as found in + :attr:`tb.tb_frame ` if ``tb`` is a traceback object. .. data:: GetSetDescriptorType The type of objects defined in extension modules with ``PyGetSetDef``, such - as ``FrameType.f_locals`` or ``array.array.typecode``. This type is used as + as :attr:`FrameType.f_locals ` or ``array.array.typecode``. + This type is used as descriptor for object attributes; it has the same purpose as the :class:`property` type, but for classes defined in extension modules. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 8f691932201225..ba2845eb17ddcc 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -18,8 +18,8 @@ .. note:: The Python runtime does not enforce function and variable type annotations. - They can be used by third party tools such as type checkers, IDEs, linters, - etc. + They can be used by third party tools such as :term:`type checkers `, + IDEs, linters, etc. -------------- @@ -304,7 +304,7 @@ a callable with any arbitrary parameter list would be acceptable: x = concat # Also OK ``Callable`` cannot express complex signatures such as functions that take a -variadic number of arguments, :func:`overloaded functions `, or +variadic number of arguments, :ref:`overloaded functions `, or functions that have keyword-only parameters. However, these signatures can be expressed by defining a :class:`Protocol` class with a :meth:`~object.__call__` method: @@ -526,7 +526,7 @@ A user-defined class can be defined as a generic class. self.logger.info('%s: %s', self.name, message) This syntax indicates that the class ``LoggedVar`` is parameterised around a -single :class:`type variable ` ``T`` . This also makes ``T`` valid as +single :ref:`type variable ` ``T`` . This also makes ``T`` valid as a type within the class body. Generic classes implicitly inherit from :class:`Generic`. For compatibility @@ -1145,16 +1145,13 @@ These can be used as types in annotations. They all support subscription using from collections.abc import Callable from threading import Lock - from typing import Concatenate, ParamSpec, TypeVar - - P = ParamSpec('P') - R = TypeVar('R') + from typing import Concatenate # Use this lock to ensure that only one thread is executing a function # at any time. my_lock = Lock() - def with_lock(f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: + def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''A type-safe decorator which provides a lock.''' def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Provide the lock as the first argument. @@ -1493,7 +1490,7 @@ These can be used as types in annotations. They all support subscription using Typing operator to conceptually mark an object as having been unpacked. For example, using the unpack operator ``*`` on a - :class:`type variable tuple ` is equivalent to using ``Unpack`` + :ref:`type variable tuple ` is equivalent to using ``Unpack`` to mark the type variable tuple as having been unpacked:: Ts = TypeVarTuple('Ts') @@ -1584,6 +1581,8 @@ without the dedicated syntax, as documented below. ... # Etc. +.. _typevar: + .. class:: TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False) Type variable. @@ -1728,9 +1727,11 @@ without the dedicated syntax, as documented below. :ref:`type parameter ` syntax introduced by :pep:`695`. The ``infer_variance`` parameter was added. +.. _typevartuple: + .. class:: TypeVarTuple(name) - Type variable tuple. A specialized form of :class:`type variable ` + Type variable tuple. A specialized form of :ref:`type variable ` that enables *variadic* generics. Type variable tuples can be declared in :ref:`type parameter lists ` @@ -1848,7 +1849,7 @@ without the dedicated syntax, as documented below. .. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False) Parameter specification variable. A specialized version of - :class:`type variables `. + :ref:`type variables `. In :ref:`type parameter lists `, parameter specifications can be declared with two asterisks (``**``):: @@ -1950,7 +1951,7 @@ without the dedicated syntax, as documented below. .. doctest:: - >>> from typing import ParamSpec + >>> from typing import ParamSpec, get_origin >>> P = ParamSpec("P") >>> get_origin(P.args) is P True @@ -2772,6 +2773,8 @@ Functions and decorators .. versionadded:: 3.11 +.. _overload: + .. decorator:: overload Decorator for creating overloaded functions and methods. @@ -3053,14 +3056,14 @@ Introspection helpers Return the set of members defined in a :class:`Protocol`. - :: + .. doctest:: >>> from typing import Protocol, get_protocol_members >>> class P(Protocol): ... def a(self) -> str: ... ... b: int - >>> get_protocol_members(P) - frozenset({'a', 'b'}) + >>> get_protocol_members(P) == frozenset({'a', 'b'}) + True Raise :exc:`TypeError` for arguments that are not Protocols. diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 49f7d453ee1c3a..d6ac4d09300d9f 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -818,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) @@ -1437,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 @@ -1707,7 +1707,7 @@ Keywords can be used in the :func:`patch.dict` call to set values in the diction :func:`patch.dict` can be used with dictionary like objects that aren't actually dictionaries. At the very minimum they must support item getting, setting, deleting and either iteration or membership test. This corresponds to the -magic methods :meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__` and either +magic methods :meth:`~object.__getitem__`, :meth:`__setitem__`, :meth:`__delitem__` and either :meth:`__iter__` or :meth:`__contains__`. >>> class Container: @@ -2531,8 +2531,8 @@ are closed properly and is becoming common:: f.write('something') The issue is that even if you mock out the call to :func:`open` it is the -*returned object* that is used as a context manager (and has :meth:`__enter__` and -:meth:`__exit__` called). +*returned object* that is used as a context manager (and has :meth:`~object.__enter__` and +:meth:`~object.__exit__` called). Mocking context managers with a :class:`MagicMock` is common enough and fiddly enough that a helper function is useful. :: diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 4c28e8fae8b088..c04e6c378cc3b1 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) @@ -390,8 +390,8 @@ testing code:: widget = Widget('The widget') self.assertEqual(widget.size(), (50, 50)) -Note that in order to test something, we use one of the :meth:`assert\*` -methods provided by the :class:`TestCase` base class. If the test fails, an +Note that in order to test something, we use one of the :ref:`assert\* methods ` +provided by the :class:`TestCase` base class. If the test fails, an exception will be raised with an explanatory message, and :mod:`unittest` will identify the test case as a :dfn:`failure`. Any other exceptions will be treated as :dfn:`errors`. @@ -1571,6 +1571,14 @@ Test cases .. versionadded:: 3.8 + .. attribute:: loop_factory + + The *loop_factory* passed to :class:`asyncio.Runner`. Override + in subclasses with :class:`asyncio.EventLoop` to avoid using the + asyncio policy system. + + .. versionadded:: 3.13 + .. coroutinemethod:: asyncSetUp() Method called to prepare the test fixture. This is called after :meth:`setUp`. @@ -1932,14 +1940,14 @@ Loading and running tests String giving the prefix of method names which will be interpreted as test methods. The default value is ``'test'``. - This affects :meth:`getTestCaseNames` and all the :meth:`loadTestsFrom\*` + This affects :meth:`getTestCaseNames` and all the ``loadTestsFrom*`` methods. .. attribute:: sortTestMethodsUsing Function to be used to compare method names when sorting them in - :meth:`getTestCaseNames` and all the :meth:`loadTestsFrom\*` methods. + :meth:`getTestCaseNames` and all the ``loadTestsFrom*`` methods. .. attribute:: suiteClass @@ -1948,7 +1956,7 @@ Loading and running tests methods on the resulting object are needed. The default value is the :class:`TestSuite` class. - This affects all the :meth:`loadTestsFrom\*` methods. + This affects all the ``loadTestsFrom*`` methods. .. attribute:: testNamePatterns @@ -1961,7 +1969,7 @@ Loading and running tests so unlike patterns passed to the ``-k`` option, simple substring patterns will have to be converted using ``*`` wildcards. - This affects all the :meth:`loadTestsFrom\*` methods. + This affects all the ``loadTestsFrom*`` methods. .. versionadded:: 3.7 @@ -1995,7 +2003,7 @@ Loading and running tests A list containing 2-tuples of :class:`TestCase` instances and strings holding formatted tracebacks. Each tuple represents a test where a failure - was explicitly signalled using the :meth:`TestCase.assert\*` methods. + was explicitly signalled using the :ref:`assert\* methods `. .. attribute:: skipped @@ -2318,6 +2326,8 @@ Loading and running tests test names. +.. _load_tests-protocol: + load_tests Protocol ################### diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index a5bcb5b1e643bf..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) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index a672d8753b7f2f..040e28e9124014 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -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() @@ -712,8 +712,8 @@ The following attribute and methods should only be used by classes derived from .. note:: The convention has been adopted that subclasses defining - :meth:`_request` or :meth:`_response` methods are named - :class:`\*Processor`; all others are named :class:`\*Handler`. + :meth:`!_request` or :meth:`!_response` methods are named + :class:`!\*Processor`; all others are named :class:`!\*Handler`. .. attribute:: BaseHandler.parent @@ -833,9 +833,9 @@ HTTPRedirectHandler Objects .. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl) Return a :class:`Request` or ``None`` in response to a redirect. This is called - by the default implementations of the :meth:`http_error_30\*` methods when a + by the default implementations of the :meth:`!http_error_30\*` methods when a redirection is received from the server. If a redirection should take place, - return a new :class:`Request` to allow :meth:`http_error_30\*` to perform the + return a new :class:`Request` to allow :meth:`!http_error_30\*` to perform the redirect to *newurl*. Otherwise, raise :exc:`~urllib.error.HTTPError` if no other handler should try to handle this URL, or return ``None`` if you can't but another handler might. @@ -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 adf01770656754..e2d231da38fd9a 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -289,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/warnings.rst b/Doc/library/warnings.rst index 884de08eab1b16..a9c469707e8227 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -522,6 +522,56 @@ Available Functions and calls to :func:`simplefilter`. +.. decorator:: deprecated(msg, *, category=DeprecationWarning, stacklevel=1) + + Decorator to indicate that a class, function or overload is deprecated. + + When this decorator is applied to an object, + deprecation warnings may be emitted at runtime when the object is used. + :term:`static type checkers ` + will also generate a diagnostic on usage of the deprecated object. + + Usage:: + + from warnings import deprecated + from typing import overload + + @deprecated("Use B instead") + class A: + pass + + @deprecated("Use g instead") + def f(): + pass + + @overload + @deprecated("int support is deprecated") + def g(x: int) -> int: ... + @overload + def g(x: str) -> int: ... + + The warning specified by *category* will be emitted at runtime + on use of deprecated objects. For functions, that happens on calls; + for classes, on instantiation and on creation of subclasses. + If the *category* is ``None``, no warning is emitted at runtime. + The *stacklevel* determines where the + warning is emitted. If it is ``1`` (the default), the warning + is emitted at the direct caller of the deprecated object; if it + is higher, it is emitted further up the stack. + Static type checker behavior is not affected by the *category* + and *stacklevel* arguments. + + The deprecation message passed to the decorator is saved in the + ``__deprecated__`` attribute on the decorated object. + If applied to an overload, the decorator + must be after the :func:`@overload ` decorator + for the attribute to exist on the overload as returned by + :func:`typing.get_overloads`. + + .. versionadded:: 3.13 + See :pep:`702`. + + Available Context Managers -------------------------- diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 39a4c1ba142338..be9e56b04c1fbf 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -180,7 +180,7 @@ also provides these miscellaneous utilities: print(chunk) .. versionchanged:: 3.11 - Support for :meth:`__getitem__` method has been removed. + Support for :meth:`~object.__getitem__` method has been removed. :mod:`wsgiref.headers` -- WSGI response header tools @@ -201,7 +201,7 @@ manipulation of WSGI response headers using a mapping-like interface. an empty list. :class:`Headers` objects support typical mapping operations including - :meth:`__getitem__`, :meth:`get`, :meth:`__setitem__`, :meth:`setdefault`, + :meth:`~object.__getitem__`, :meth:`get`, :meth:`__setitem__`, :meth:`setdefault`, :meth:`__delitem__` and :meth:`__contains__`. For each of these methods, the key is the header name (treated case-insensitively), and the value is the first value associated with that header name. Setting a header diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst index d1df465a598e53..843c2fd7fdb937 100644 --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -115,7 +115,7 @@ DOMEventStream Objects .. class:: DOMEventStream(stream, parser, bufsize) .. versionchanged:: 3.11 - Support for :meth:`__getitem__` method has been removed. + Support for :meth:`~object.__getitem__` method has been removed. .. method:: getEvent() diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index b387240a3716cc..d0e1b248d595d1 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -734,7 +734,7 @@ NamedNodeMap Objects attribute node. Get its value with the :attr:`value` attribute. There are also experimental methods that give this class more mapping behavior. -You can use them or you can use the standardized :meth:`getAttribute\*` family +You can use them or you can use the standardized :meth:`!getAttribute\*` family of methods on the :class:`Element` objects. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 54c93008503c02..57cfbb8d92244b 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -154,6 +154,7 @@ elements, call :meth:`XMLPullParser.read_events`. Here is an example:: ... print(elem.tag, 'text=', elem.text) ... end + mytag text= sometext more text The obvious use case is applications that operate in a non-blocking fashion where the XML data is being received from a socket or read incrementally from @@ -621,7 +622,9 @@ Functions *parser* is an optional parser instance. If not given, the standard :class:`XMLParser` parser is used. *parser* must be a subclass of :class:`XMLParser` and can only use the default :class:`TreeBuilder` as a - target. Returns an :term:`iterator` providing ``(event, elem)`` pairs. + target. Returns an :term:`iterator` providing ``(event, elem)`` pairs; + it has a ``root`` attribute that references the root element of the + resulting XML tree once *source* is fully read. Note that while :func:`iterparse` builds the tree incrementally, it issues blocking reads on *source* (or the file it names). As such, it's unsuitable diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index 1e49b6568dfc28..909022ea4ba6a4 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -73,7 +73,7 @@ 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 - :const:`pyexpat.EXPAT_VERSION`. + :const:`!pyexpat.EXPAT_VERSION`. 2. :mod:`xml.etree.ElementTree` doesn't expand external entities and raises a :exc:`~xml.etree.ElementTree.ParseError` when an entity occurs. 3. :mod:`xml.dom.minidom` doesn't expand external entities and simply returns diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 016369d2b89d2c..ca1ea455f0acfc 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -84,12 +84,12 @@ alone XML-RPC servers. Register a function that can respond to XML-RPC requests. If *name* is given, it will be the method name associated with *function*, otherwise - ``function.__name__`` will be used. *name* is a string, and may contain + :attr:`function.__name__` will be used. *name* is a string, and may contain characters not legal in Python identifiers, including the period character. This method can also be used as a decorator. When used as a decorator, *name* can only be given as a keyword argument to register *function* under - *name*. If no *name* is given, ``function.__name__`` will be used. + *name*. If no *name* is given, :attr:`function.__name__` will be used. .. versionchanged:: 3.7 :meth:`register_function` can be used as a decorator. @@ -298,12 +298,12 @@ requests sent to Python CGI scripts. Register a function that can respond to XML-RPC requests. If *name* is given, it will be the method name associated with *function*, otherwise - ``function.__name__`` will be used. *name* is a string, and may contain + :attr:`function.__name__` will be used. *name* is a string, and may contain characters not legal in Python identifiers, including the period character. This method can also be used as a decorator. When used as a decorator, *name* can only be given as a keyword argument to register *function* under - *name*. If no *name* is given, ``function.__name__`` will be used. + *name*. If no *name* is given, :attr:`function.__name__` will be used. .. versionchanged:: 3.7 :meth:`register_function` can be used as a decorator. diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst index 7c01fc102fca07..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. 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 82039fd9aaf9d0..8aad93062a5a88 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -1040,3 +1040,29 @@ https://www.w3.org/TR/xml-c14n2-testcases/ and is distributed under the THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +mimalloc +-------- + +MIT License + +Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 12ad18d4119617..7a735095bdecb2 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -489,37 +489,37 @@ The execution of the :keyword:`with` statement with one "item" proceeds as follo #. The context expression (the expression given in the :token:`~python-grammar:with_item`) is evaluated to obtain a context manager. -#. The context manager's :meth:`__enter__` is loaded for later use. +#. The context manager's :meth:`~object.__enter__` is loaded for later use. -#. The context manager's :meth:`__exit__` is loaded for later use. +#. The context manager's :meth:`~object.__exit__` is loaded for later use. -#. The context manager's :meth:`__enter__` method is invoked. +#. The context manager's :meth:`~object.__enter__` method is invoked. #. If a target was included in the :keyword:`with` statement, the return value - from :meth:`__enter__` is assigned to it. + from :meth:`~object.__enter__` is assigned to it. .. note:: - The :keyword:`with` statement guarantees that if the :meth:`__enter__` - method returns without an error, then :meth:`__exit__` will always be + The :keyword:`with` statement guarantees that if the :meth:`~object.__enter__` + method returns without an error, then :meth:`~object.__exit__` will always be called. Thus, if an error occurs during the assignment to the target list, it will be treated the same as an error occurring within the suite would be. See step 7 below. #. The suite is executed. -#. The context manager's :meth:`__exit__` method is invoked. If an exception +#. The context manager's :meth:`~object.__exit__` method is invoked. If an exception caused the suite to be exited, its type, value, and traceback are passed as - arguments to :meth:`__exit__`. Otherwise, three :const:`None` arguments are + arguments to :meth:`~object.__exit__`. Otherwise, three :const:`None` arguments are supplied. If the suite was exited due to an exception, and the return value from the - :meth:`__exit__` method was false, the exception is reraised. If the return + :meth:`~object.__exit__` method was false, the exception is reraised. If the return value was true, the exception is suppressed, and execution continues with the statement following the :keyword:`with` statement. If the suite was exited for any reason other than an exception, the return - value from :meth:`__exit__` is ignored, and execution proceeds at the normal + value from :meth:`~object.__exit__` is ignored, and execution proceeds at the normal location for the kind of exit that was taken. The following code:: @@ -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. @@ -1058,7 +1058,7 @@ subject value: .. note:: Key-value pairs are matched using the two-argument form of the mapping subject's ``get()`` method. Matched key-value pairs must already be present in the mapping, and not created on-the-fly via :meth:`__missing__` or - :meth:`__getitem__`. + :meth:`~object.__getitem__`. In simple terms ``{KEY1: P1, KEY2: P2, ... }`` matches only if all the following happens: @@ -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:: @@ -1259,7 +1261,8 @@ except that the original function is not temporarily bound to the name ``func``. A list of :ref:`type parameters ` may be given in square brackets between the function's name and the opening parenthesis for its parameter list. This indicates to static type checkers that the function is generic. At runtime, -the type parameters can be retrieved from the function's ``__type_params__`` +the type parameters can be retrieved from the function's +:attr:`~function.__type_params__` attribute. See :ref:`generic-functions` for more. .. versionchanged:: 3.12 @@ -1838,36 +1841,36 @@ 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) :c:macro:`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) :c:macro:`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. .. [#] A string literal appearing as the first statement in the function body is - transformed into the function's ``__doc__`` attribute and therefore the - function's :term:`docstring`. + transformed into the function's :attr:`~function.__doc__` attribute and + therefore the function's :term:`docstring`. .. [#] A string literal appearing as the first statement in the class body is transformed into the namespace's ``__doc__`` item and therefore the class's diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index cc81f73f824352..5e3757e1f5c6f6 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -88,7 +88,7 @@ Some objects contain references to "external" resources such as open files or windows. It is understood that these resources are freed when the object is garbage-collected, but since garbage collection is not guaranteed to happen, such objects also provide an explicit way to release the external resource, -usually a :meth:`close` method. Programs are strongly recommended to explicitly +usually a :meth:`!close` method. Programs are strongly recommended to explicitly close such objects. The ':keyword:`try`...\ :keyword:`finally`' statement and the ':keyword:`with`' statement provide convenient ways to do this. @@ -519,6 +519,8 @@ These are the types to which the function call operation (see section :ref:`calls`) can be applied: +.. _user-defined-funcs: + User-defined functions ^^^^^^^^^^^^^^^^^^^^^^ @@ -532,9 +534,34 @@ 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: +Special read-only attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + single: __closure__ (function attribute) + single: __globals__ (function attribute) + pair: global; namespace + +.. list-table:: + :header-rows: 1 + + * - Attribute + - Meaning + + * - .. attribute:: function.__globals__ + - A reference to the :class:`dictionary ` that holds the function's + :ref:`global variables ` -- the global namespace of the module + in which the function was defined. + + * - .. attribute:: function.__closure__ + - ``None`` or a :class:`tuple` of cells that contain bindings for the + function's free variables. -.. tabularcolumns:: |l|L|l| + 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. + +Special writable attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. index:: single: __doc__ (function attribute) @@ -542,97 +569,84 @@ Special attributes: 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. +Most of these attributes check the type of the assigned value: + +.. list-table:: + :header-rows: 1 + + * - Attribute + - Meaning + + * - .. attribute:: function.__doc__ + - The function's documentation string, or ``None`` if unavailable. + Not inherited by subclasses. + + * - .. attribute:: function.__name__ + - The function's name. + See also: :attr:`__name__ attributes `. + + * - .. attribute:: function.__qualname__ + - The function's :term:`qualified name`. + See also: :attr:`__qualname__ attributes `. + + .. versionadded:: 3.3 + + * - .. attribute:: function.__module__ + - The name of the module the function was defined in, + or ``None`` if unavailable. + + * - .. attribute:: function.__defaults__ + - A :class:`tuple` containing default :term:`parameter` values + for those parameters that have defaults, + or ``None`` if no parameters have a default value. + + * - .. attribute:: function.__code__ + - The :ref:`code object ` representing + the compiled function body. + + * - .. attribute:: function.__dict__ + - The namespace supporting arbitrary function attributes. + See also: :attr:`__dict__ attributes `. + + * - .. attribute:: function.__annotations__ + - A :class:`dictionary ` containing annotations of + :term:`parameters `. + The keys of the dictionary are the parameter names, + and ``'return'`` for the return annotation, if provided. + See also: :ref:`annotations-howto`. + + * - .. attribute:: function.__kwdefaults__ + - A :class:`dictionary ` containing defaults for keyword-only + :term:`parameters `. + + * - .. attribute:: function.__type_params__ + - A :class:`tuple` containing the :ref:`type parameters ` of + a :ref:`generic function `. + + .. versionadded:: 3.12 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.* +dot-notation is used to get and set such attributes. + +.. impl-detail:: -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. + CPython's current implementation only supports function attributes + on user-defined functions. Function attributes on + :ref:`built-in functions ` may be supported in the + future. 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. +:ref:`code object ` +(accessible via the :attr:`~function.__code__` attribute). + +.. _instance-methods: Instance methods ^^^^^^^^^^^^^^^^ @@ -652,43 +666,66 @@ callable object (normally a user-defined function). 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. +Special read-only attributes: + +.. list-table:: + + * - .. attribute:: method.__self__ + - Refers to the class instance object to which the method is + :ref:`bound ` + + * - .. attribute:: method.__func__ + - Refers to the original :ref:`function object ` + + * - .. attribute:: method.__doc__ + - The method's documentation + (same as :attr:`method.__func__.__doc__ `). + A :class:`string ` if the original function had a docstring, else + ``None``. + + * - .. attribute:: method.__name__ + - The name of the method + (same as :attr:`method.__func__.__name__ `) + + * - .. attribute:: method.__module__ + - 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. +attributes on the underlying :ref:`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. +user-defined :ref:`function object ` or a +:class:`classmethod` object. + +.. _method-binding: 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 +:ref:`function object ` from a class via one of its +instances, its :attr:`~method.__self__` attribute is the instance, and the +method object is said to be *bound*. The new method's :attr:`~method.__func__` +attribute is the original function object. + +When an instance method object is created by retrieving a :class:`classmethod` +object from a class or instance, its :attr:`~method.__self__` attribute is the +class itself, and its :attr:`~method.__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 +(:attr:`~method.__func__`) is called, inserting the class instance +(:attr:`~method.__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 +When an instance method object is derived from a :class:`classmethod` object, the +"class instance" stored in :attr:`~method.__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 +Note that the transformation from :ref:`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 @@ -754,6 +791,8 @@ is raised and the asynchronous iterator will have reached the end of the set of values to be yielded. +.. _builtin-functions: + Built-in functions ^^^^^^^^^^^^^^^^^^ @@ -766,11 +805,17 @@ 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. +* :attr:`!__doc__` is the function's documentation string, or ``None`` if + unavailable. See :attr:`function.__doc__`. +* :attr:`!__name__` is the function's name. See :attr:`function.__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. + See :attr:`function.__module__`. + + +.. _builtin-methods: Built-in methods ^^^^^^^^^^^^^^^^ @@ -783,8 +828,9 @@ Built-in methods 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*. +this case, the special read-only attribute :attr:`!__self__` is set to the object +denoted by *alist*. (The attribute has the same semantics as it does with +:attr:`other instance methods `.) Classes @@ -793,7 +839,7 @@ 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 +:meth:`!__new__` and, in the typical case, to :meth:`~object.__init__` to initialize the new instance. @@ -816,7 +862,8 @@ 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__`` +:class:`dictionary ` object (this is the dictionary referenced by the +:attr:`~function.__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 @@ -897,10 +944,11 @@ https://www.python.org/download/releases/2.3/mro/. pair: object; dictionary pair: class; attribute -When a class attribute reference (for class :class:`C`, say) would yield a +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 +:attr:`~method.__self__` attribute is :class:`!C`. +When it would yield a :class:`staticmethod` 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__`. @@ -968,7 +1016,7 @@ 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 +object whose :attr:`~method.__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 @@ -1075,57 +1123,111 @@ indirectly) to mutable objects. 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. +Special read-only attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + + * - .. attribute:: codeobject.co_name + - The function name + + * - .. attribute:: codeobject.co_qualname + - The fully qualified function name + + * - .. attribute:: codeobject.co_argcount + - The total number of positional :term:`parameters ` + (including positional-only parameters and parameters with default values) + that the function has + + * - .. attribute:: codeobject.co_posonlyargcount + - The number of positional-only :term:`parameters ` + (including arguments with default values) that the function has + + * - .. attribute:: codeobject.co_kwonlyargcount + - The number of keyword-only :term:`parameters ` + (including arguments with default values) that the function has + + * - .. attribute:: codeobject.co_nlocals + - The number of :ref:`local variables ` used by the function + (including parameters) + + * - .. attribute:: codeobject.co_varnames + - A :class:`tuple` containing the names of the local variables in the + function (starting with the parameter names) + + * - .. attribute:: codeobject.co_cellvars + - A :class:`tuple` containing the names of :ref:`local variables ` + that are referenced by nested functions inside the function + + * - .. attribute:: codeobject.co_freevars + - A :class:`tuple` containing the names of free variables in the function + + * - .. attribute:: codeobject.co_code + - A string representing the sequence of :term:`bytecode` instructions in + the function + + * - .. attribute:: codeobject.co_consts + - A :class:`tuple` containing the literals used by the :term:`bytecode` in + the function + + * - .. attribute:: codeobject.co_names + - A :class:`tuple` containing the names used by the :term:`bytecode` in + the function + + * - .. attribute:: codeobject.co_filename + - The name of the file from which the code was compiled + + * - .. attribute:: codeobject.co_firstlineno + - The line number of the first line of the function + + * - .. attribute:: codeobject.co_lnotab + - A string encoding the mapping from :term:`bytecode` offsets to line + numbers. For details, see the source code of the interpreter. + + .. deprecated:: 3.12 + This attribute of code objects is deprecated, and may be removed in + Python 3.14. + + * - .. attribute:: codeobject.co_stacksize + - The required stack size of the code object + + * - .. attribute:: codeobject.co_flags + - An :class:`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 following flag bits are defined for :attr:`~codeobject.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. +if the function is a generator. See :ref:`inspect-module-co-flags` for details +on the semantics of each flags that might be present. Future feature declarations (``from __future__ import division``) also use bits -in :attr:`co_flags` to indicate whether a code object was compiled with a +in :attr:`~codeobject.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. +Other bits in :attr:`~codeobject.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 +If a code object represents a function, the first item in +:attr:`~codeobject.co_consts` is the documentation string of the function, or ``None`` if undefined. +The :meth:`!co_positions` method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + .. method:: codeobject.co_positions() - Returns an iterable over the source code positions of each bytecode + Returns an iterable over the source code positions of each :term:`bytecode` instruction in the code object. - The iterator returns tuples containing the ``(start_line, end_line, + The iterator returns :class:`tuple`\s 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 @@ -1161,8 +1263,9 @@ 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. +Frame objects represent execution frames. They may occur in +:ref:`traceback objects `, +and are also passed to registered trace functions. .. index:: single: f_back (frame attribute) @@ -1172,16 +1275,36 @@ Frame objects represent execution frames. They may occur in traceback objects 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). +Special read-only attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + + * - .. attribute:: frame.f_back + - Points to the previous stack frame (towards the caller), + or ``None`` if this is the bottom stack frame -Accessing ``f_code`` raises an :ref:`auditing event ` -``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. + * - .. attribute:: frame.f_code + - The :ref:`code object ` being executed in this frame. + Accessing this attribute raises an :ref:`auditing event ` + ``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. + + * - .. attribute:: frame.f_locals + - The dictionary used by the frame to look up + :ref:`local variables ` + + * - .. attribute:: frame.f_globals + - The dictionary used by the frame to look up + :ref:`global variables ` + + * - .. attribute:: frame.f_builtins + - The dictionary used by the frame to look up + :ref:`built-in (intrinsic) names ` + + * - .. attribute:: frame.f_lasti + - The "precise instruction" of the frame object + (this is an index into the :term:`bytecode` string of the + :ref:`code object `) .. index:: single: f_trace (frame attribute) @@ -1189,35 +1312,54 @@ Accessing ``f_code`` raises an :ref:`auditing event ` 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`. +Special writable attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + + * - .. attribute:: frame.f_trace + - If not ``None``, this is a function called for various events during + code execution (this is used by debuggers). Normally an event is + triggered for each new source line (see :attr:`~frame.f_trace_lines`). -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. + * - .. attribute:: frame.f_trace_lines + - Set this attribute to :const:`False` to disable triggering a tracing + event for each source line. -: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. + * - .. attribute:: frame.f_trace_opcodes + - Set this attribute to :const:`True` to allow per-opcode events to be + requested. Note that this may lead to + undefined interpreter behaviour if exceptions raised by the trace + function escape to the function being traced. + + * - .. attribute:: frame.f_lineno + - 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 this attribute. + +Frame object methods +~~~~~~~~~~~~~~~~~~~~ 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 + This method clears all references to :ref:`local variables ` held by the + frame. Also, if the frame belonged to a :term:`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). + objects (for example when catching an :ref:`exception ` + and storing its :ref:`traceback ` for later use). - :exc:`RuntimeError` is raised if the frame is currently executing. + :exc:`RuntimeError` is raised if the frame is currently executing + or suspended. .. versionadded:: 3.4 + .. versionchanged:: 3.13 + Attempting to clear a suspended frame raises :exc:`RuntimeError` + (as has always been the case for executing frames). + .. _traceback-objects: @@ -1235,26 +1377,31 @@ Traceback objects single: sys.exception single: sys.last_traceback -Traceback objects represent a stack trace of an exception. A traceback object +Traceback objects represent the stack trace of an :ref:`exception `. +A traceback object is implicitly created when an exception occurs, and may also be explicitly created by calling :class:`types.TracebackType`. +.. versionchanged:: 3.7 + Traceback objects can now be explicitly instantiated from Python code. + 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 +tuple returned by :func:`sys.exc_info`, and as the +:attr:`~BaseException.__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``. +as :data:`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. +to determine how the :attr:`~traceback.tb_next` attributes should be linked to +form a full stack trace. .. index:: single: tb_frame (traceback attribute) @@ -1263,27 +1410,40 @@ full stack trace. 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. + +.. list-table:: + + * - .. attribute:: traceback.tb_frame + - Points to the execution :ref:`frame ` of the current + level. + + Accessing this attribute raises an + :ref:`auditing event ` ``object.__getattr__`` with arguments + ``obj`` and ``"tb_frame"``. + + * - .. attribute:: traceback.tb_lineno + - Gives the line number where the exception occurred + + * - .. attribute:: traceback.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 +line number of its :ref:`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"``. +:keyword:`finally` clause. .. 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. +.. attribute:: traceback.tb_next -.. versionchanged:: 3.7 - Traceback objects can now be explicitly instantiated from Python code, - and the ``tb_next`` attribute of existing instances can be updated. + The 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 + This attribute is now writable Slice objects @@ -1751,7 +1911,8 @@ access (use of, assignment to, or deletion of ``x.name``) for class instances. .. note:: This method may still be bypassed when looking up special methods as the - result of implicit invocation via language syntax or built-in functions. + result of implicit invocation via language syntax or + :ref:`built-in functions `. See :ref:`special-lookup`. .. audit-event:: object.__getattr__ obj,name object.__getattribute__ @@ -1896,13 +2057,17 @@ class' :attr:`~object.__dict__`. Called to delete the attribute on an instance *instance* of the owner class. +Instances of descriptors may also have the :attr:`!__objclass__` attribute +present: + +.. attribute:: object.__objclass__ -The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module -as specifying the class where this object was defined (setting this -appropriately can assist in runtime introspection of dynamic class attributes). -For callables, it may indicate that an instance of the given type (or a -subclass) is expected or required as the first positional argument (for example, -CPython sets this attribute for unbound methods that are implemented in C). + The attribute :attr:`!__objclass__` is interpreted by the :mod:`inspect` module + as specifying the class where this object was defined (setting this + appropriately can assist in runtime introspection of dynamic class attributes). + For callables, it may indicate that an instance of the given type (or a + subclass) is expected or required as the first positional argument (for example, + CPython sets this attribute for unbound methods that are implemented in C). .. _descriptor-invocation: @@ -1983,13 +2148,14 @@ For instance bindings, the precedence of descriptor invocation depends on which descriptor methods are defined. A descriptor can define any combination of :meth:`~object.__get__`, :meth:`~object.__set__` and :meth:`~object.__delete__`. If it does not -define :meth:`__get__`, then accessing the attribute will return the descriptor +define :meth:`!__get__`, then accessing the attribute will return the descriptor object itself unless there is a value in the object's instance dictionary. If -the descriptor defines :meth:`__set__` and/or :meth:`__delete__`, it is a data +the descriptor defines :meth:`!__set__` and/or :meth:`!__delete__`, it is a data descriptor; if it defines neither, it is a non-data descriptor. Normally, data -descriptors define both :meth:`__get__` and :meth:`__set__`, while non-data -descriptors have just the :meth:`__get__` method. Data descriptors with -:meth:`__get__` and :meth:`__set__` (and/or :meth:`__delete__`) defined always override a redefinition in an +descriptors define both :meth:`!__get__` and :meth:`!__set__`, while non-data +descriptors have just the :meth:`!__get__` method. Data descriptors with +:meth:`!__get__` and :meth:`!__set__` (and/or :meth:`!__delete__`) defined +always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances. @@ -2566,16 +2732,17 @@ either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers *k* for which ``0 <= k < N`` where *N* is the length of the sequence, or :class:`slice` objects, which define a range of items. It is also recommended that mappings provide the methods -:meth:`keys`, :meth:`values`, :meth:`items`, :meth:`get`, :meth:`clear`, -:meth:`setdefault`, :meth:`pop`, :meth:`popitem`, :meth:`!copy`, and -:meth:`update` behaving similar to those for Python's standard :class:`dictionary ` +:meth:`!keys`, :meth:`!values`, :meth:`!items`, :meth:`!get`, :meth:`!clear`, +:meth:`!setdefault`, :meth:`!pop`, :meth:`!popitem`, :meth:`!copy`, and +:meth:`!update` behaving similar to those for Python's standard :class:`dictionary ` objects. The :mod:`collections.abc` module provides a :class:`~collections.abc.MutableMapping` :term:`abstract base class` to help create those methods from a base set of -:meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__delitem__`, and :meth:`keys`. -Mutable sequences should provide methods :meth:`append`, :meth:`count`, -:meth:`index`, :meth:`extend`, :meth:`insert`, :meth:`pop`, :meth:`remove`, -:meth:`reverse` and :meth:`sort`, like Python standard :class:`list` +:meth:`~object.__getitem__`, :meth:`~object.__setitem__`, +:meth:`~object.__delitem__`, and :meth:`!keys`. +Mutable sequences should provide methods :meth:`!append`, :meth:`!count`, +:meth:`!index`, :meth:`!extend`, :meth:`!insert`, :meth:`!pop`, :meth:`!remove`, +:meth:`!reverse` and :meth:`!sort`, like Python standard :class:`list` objects. Finally, sequence types should implement addition (meaning concatenation) and multiplication (meaning repetition) by defining the methods @@ -2588,7 +2755,7 @@ operator; for mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the :meth:`~object.__iter__` method to allow efficient iteration -through the container; for mappings, :meth:`__iter__` should iterate +through the container; for mappings, :meth:`!__iter__` should iterate through the object's keys; for sequences, it should iterate through the values. .. method:: object.__len__(self) @@ -2939,7 +3106,7 @@ For more information on context managers, see :ref:`typecontextmanager`. (i.e., prevent it from being propagated), it should return a true value. Otherwise, the exception will be processed normally upon exit from this method. - Note that :meth:`__exit__` methods should not reraise the passed-in exception; + Note that :meth:`~object.__exit__` methods should not reraise the passed-in exception; this is the caller's responsibility. @@ -3167,7 +3334,7 @@ generators, coroutines do not directly support iteration. to the :meth:`~generator.send` method of the iterator that caused the coroutine to suspend. The result (return value, :exc:`StopIteration`, or other exception) is the same as when - iterating over the :meth:`__await__` return value, described above. + iterating over the :meth:`!__await__` return value, described above. .. method:: coroutine.throw(value) coroutine.throw(type[, value[, traceback]]) @@ -3257,12 +3424,12 @@ Asynchronous context managers can be used in an :keyword:`async with` statement. .. method:: object.__aenter__(self) - Semantically similar to :meth:`__enter__`, the only + Semantically similar to :meth:`~object.__enter__`, the only difference being that it must return an *awaitable*. .. method:: object.__aexit__(self, exc_type, exc_value, traceback) - Semantically similar to :meth:`__exit__`, the only + Semantically similar to :meth:`~object.__exit__`, the only difference being that it must return an *awaitable*. An example of an asynchronous context manager class:: diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 8e0346ccc718de..3f6d5bfafee9d1 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. @@ -823,12 +823,18 @@ An attribute reference is a primary followed by a period and a name: The primary must evaluate to an object of a type that supports attribute references, which most objects do. This object is then asked to produce the -attribute whose name is the identifier. This production can be customized by -overriding the :meth:`__getattr__` method. If this attribute is not available, -the exception :exc:`AttributeError` is raised. Otherwise, the type and value of -the object produced is determined by the object. Multiple evaluations of the -same attribute reference may yield different objects. +attribute whose name is the identifier. The type and value produced is +determined by the object. Multiple evaluations of the same attribute +reference may yield different objects. +This production can be customized by overriding the +:meth:`~object.__getattribute__` method or the :meth:`~object.__getattr__` +method. The :meth:`!__getattribute__` method is called first and either +returns a value or raises :exc:`AttributeError` if the attribute is not +available. + +If an :exc:`AttributeError` is raised and the object has a :meth:`!__getattr__` +method, that method is called as a fallback. .. _subscriptions: @@ -889,7 +895,7 @@ to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The resulting value must be a nonnegative integer less than the number of items in the sequence, and the subscription selects the item whose index is that value (counting from zero). Since the support for negative indices and slicing -occurs in the object's :meth:`__getitem__` method, subclasses overriding +occurs in the object's :meth:`~object.__getitem__` method, subclasses overriding this method will need to explicitly add that support. .. index:: @@ -944,7 +950,7 @@ slice list contains no proper slice). single: step (slice object attribute) The semantics for a slicing are as follows. The primary is indexed (using the -same :meth:`__getitem__` method as +same :meth:`~object.__getitem__` method as normal subscription) with a key that is constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple containing the conversion of the slice items; otherwise, the conversion of the @@ -1670,7 +1676,7 @@ If an exception is raised during the iteration, it is as if :keyword:`in` raised that exception. Lastly, the old-style iteration protocol is tried: if a class defines -:meth:`__getitem__`, ``x in y`` is ``True`` if and only if there is a non-negative +:meth:`~object.__getitem__`, ``x in y`` is ``True`` if and only if there is a non-negative integer index *i* such that ``x is y[i] or x == y[i]``, and no lower integer index raises the :exc:`IndexError` exception. (If any other exception is raised, it is as if :keyword:`in` raised that exception). @@ -1781,10 +1787,11 @@ Or, when processing a file stream in chunks: while chunk := file.read(9000): process(chunk) -Assignment expressions must be surrounded by parentheses when used -as sub-expressions in slicing, conditional, lambda, -keyword-argument, and comprehension-if expressions -and in ``assert`` and ``with`` statements. +Assignment expressions must be surrounded by parentheses when +used as expression statements and when used as sub-expressions in +slicing, conditional, lambda, +keyword-argument, and comprehension-if expressions and +in ``assert``, ``with``, and ``assignment`` statements. In all other places where they can be used, parentheses are not required, including in ``if`` and ``while`` statements. diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 0f416a5c583f85..a7beeea29b4556 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 @@ -559,7 +559,7 @@ listed below. functionality, for example getting data associated with a loader. It is **strongly** recommended that you rely on :attr:`__spec__` - instead instead of this attribute. + instead of this attribute. .. versionchanged:: 3.12 The value of ``__loader__`` is expected to be the same as @@ -580,7 +580,7 @@ listed below. relative imports for main modules, as defined in :pep:`366`. It is **strongly** recommended that you rely on :attr:`__spec__` - instead instead of this attribute. + instead of this attribute. .. versionchanged:: 3.6 The value of ``__package__`` is expected to be the same as @@ -650,7 +650,7 @@ listed below. from a file, that atypical scenario may be appropriate. It is **strongly** recommended that you rely on :attr:`__spec__` - instead instead of ``__cached__``. + instead of ``__cached__``. .. _package-path-rules: @@ -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/introduction.rst b/Doc/reference/introduction.rst index 81f0a5c5d43883..cf186705e6e987 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -90,7 +90,8 @@ Notation .. index:: BNF, grammar, syntax, notation -The descriptions of lexical analysis and syntax use a modified BNF grammar +The descriptions of lexical analysis and syntax use a modified +`Backus–Naur form (BNF) `_ grammar notation. This uses the following style of definition: .. productionlist:: notation diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index e54e0ebb7fae96..0adfb0365934e4 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -657,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 @@ -708,10 +708,12 @@ and formatted string literals may be concatenated with plain string literals. single: ! (exclamation); in formatted string literal single: : (colon); in formatted string literal single: = (equals); for help in debugging using string literals + .. _f-strings: +.. _formatted-string-literals: -Formatted string literals -------------------------- +f-strings +--------- .. versionadded:: 3.6 diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index a9e65be1eda340..34c3a620b87223 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -578,7 +578,7 @@ The :dfn:`type` of the exception is the exception instance's class, the .. index:: pair: object; traceback A traceback object is normally created automatically when an exception is raised -and attached to it as the :attr:`__traceback__` attribute, which is writable. +and attached to it as the :attr:`~BaseException.__traceback__` attribute. You can create an exception and set your own traceback in one step using the :meth:`~BaseException.with_traceback` exception method (which returns the same exception instance, with its traceback set to its argument), like so:: @@ -592,11 +592,13 @@ same exception instance, with its traceback set to its argument), like so:: The ``from`` clause is used for exception chaining: if given, the second *expression* must be another exception class or instance. If the second expression is an exception instance, it will be attached to the raised -exception as the :attr:`__cause__` attribute (which is writable). If the +exception as the :attr:`~BaseException.__cause__` attribute (which is writable). If the expression is an exception class, the class will be instantiated and the resulting exception instance will be attached to the raised exception as the -:attr:`__cause__` attribute. If the raised exception is not handled, both -exceptions will be printed:: +:attr:`!__cause__` attribute. If the raised exception is not handled, both +exceptions will be printed: + +.. code-block:: pycon >>> try: ... print(1 / 0) @@ -605,19 +607,24 @@ exceptions will be printed:: ... Traceback (most recent call last): File "", line 2, in + print(1 / 0) + ~~^~~ ZeroDivisionError: division by zero The above exception was the direct cause of the following exception: Traceback (most recent call last): File "", line 4, in + raise RuntimeError("Something bad happened") from exc RuntimeError: Something bad happened A similar mechanism works implicitly if a new exception is raised when an exception is already being handled. An exception may be handled when an :keyword:`except` or :keyword:`finally` clause, or a :keyword:`with` statement, is used. The previous exception is then -attached as the new exception's :attr:`__context__` attribute:: +attached as the new exception's :attr:`~BaseException.__context__` attribute: + +.. code-block:: pycon >>> try: ... print(1 / 0) @@ -626,16 +633,21 @@ attached as the new exception's :attr:`__context__` attribute:: ... Traceback (most recent call last): File "", line 2, in + print(1 / 0) + ~~^~~ ZeroDivisionError: division by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 4, in + raise RuntimeError("Something bad happened") RuntimeError: Something bad happened Exception chaining can be explicitly suppressed by specifying :const:`None` in -the ``from`` clause:: +the ``from`` clause: + +.. doctest:: >>> try: ... print(1 / 0) @@ -653,8 +665,8 @@ and information about handling exceptions is in section :ref:`try`. :const:`None` is now permitted as ``Y`` in ``raise X from Y``. .. versionadded:: 3.3 - The ``__suppress_context__`` attribute to suppress automatic display of the - exception context. + The :attr:`~BaseException.__suppress_context__` attribute to suppress + automatic display of the exception context. .. versionchanged:: 3.11 If the traceback of the active exception is modified in an :keyword:`except` diff --git a/Doc/requirements-oldest-sphinx.txt b/Doc/requirements-oldest-sphinx.txt index d3ef5bc17650ae..597341d99ffeaa 100644 --- a/Doc/requirements-oldest-sphinx.txt +++ b/Doc/requirements-oldest-sphinx.txt @@ -13,16 +13,15 @@ python-docs-theme>=2022.1 # Sphinx 4.2 comes from ``needs_sphinx = '4.2'`` in ``Doc/conf.py``. alabaster==0.7.13 -Babel==2.12.1 +Babel==2.13.0 certifi==2023.7.22 -charset-normalizer==3.2.0 -colorama==0.4.6 -docutils==0.16 +charset-normalizer==3.3.0 +docutils==0.17.1 idna==3.4 imagesize==1.4.1 -Jinja2==2.11.3 -MarkupSafe==1.1.1 -packaging==23.1 +Jinja2==3.1.2 +MarkupSafe==2.1.3 +packaging==23.2 Pygments==2.16.1 requests==2.31.0 snowballstemmer==2.2.0 @@ -33,4 +32,4 @@ sphinxcontrib-htmlhelp==2.0.1 sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 -urllib3==2.0.4 +urllib3==2.0.7 diff --git a/Doc/requirements.txt b/Doc/requirements.txt index d4f23ea8c400fe..04334fd5a464d4 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -11,7 +11,9 @@ sphinx==6.2.1 blurb +sphinx-autobuild sphinxext-opengraph==0.7.5 +sphinx-notfound-page==1.0.0 # The theme used by the documentation is stored separately, so we need # to install that as well. diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore index f217da9052ca78..75d50fee33a064 100644 --- a/Doc/tools/.nitignore +++ b/Doc/tools/.nitignore @@ -14,49 +14,38 @@ Doc/c-api/memory.rst Doc/c-api/memoryview.rst Doc/c-api/module.rst Doc/c-api/object.rst -Doc/c-api/set.rst Doc/c-api/stable.rst Doc/c-api/structures.rst Doc/c-api/sys.rst Doc/c-api/type.rst Doc/c-api/typeobj.rst Doc/extending/extending.rst -Doc/extending/newtypes.rst Doc/glossary.rst Doc/howto/descriptor.rst Doc/howto/enum.rst Doc/howto/isolating-extensions.rst Doc/howto/logging.rst Doc/howto/urllib2.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-policy.rst -Doc/library/asyncio-stream.rst Doc/library/asyncio-subprocess.rst Doc/library/asyncio-task.rst Doc/library/bdb.rst Doc/library/bisect.rst -Doc/library/bz2.rst Doc/library/calendar.rst Doc/library/cmd.rst -Doc/library/codecs.rst Doc/library/collections.abc.rst Doc/library/collections.rst Doc/library/concurrent.futures.rst Doc/library/configparser.rst -Doc/library/contextlib.rst Doc/library/csv.rst Doc/library/datetime.rst Doc/library/dbm.rst Doc/library/decimal.rst -Doc/library/doctest.rst Doc/library/email.charset.rst Doc/library/email.compat32-message.rst Doc/library/email.errors.rst -Doc/library/email.headerregistry.rst Doc/library/email.mime.rst Doc/library/email.parser.rst Doc/library/email.policy.rst @@ -65,16 +54,10 @@ Doc/library/exceptions.rst Doc/library/faulthandler.rst Doc/library/fcntl.rst Doc/library/ftplib.rst -Doc/library/functions.rst Doc/library/functools.rst -Doc/library/getpass.rst -Doc/library/gettext.rst -Doc/library/gzip.rst Doc/library/http.client.rst Doc/library/http.cookiejar.rst -Doc/library/http.cookies.rst Doc/library/http.server.rst -Doc/library/importlib.resources.rst Doc/library/importlib.rst Doc/library/inspect.rst Doc/library/locale.rst @@ -87,7 +70,6 @@ Doc/library/multiprocessing.rst Doc/library/multiprocessing.shared_memory.rst Doc/library/numbers.rst Doc/library/optparse.rst -Doc/library/os.path.rst Doc/library/os.rst Doc/library/pickle.rst Doc/library/pickletools.rst @@ -99,33 +81,23 @@ Doc/library/pydoc.rst Doc/library/pyexpat.rst Doc/library/random.rst Doc/library/readline.rst -Doc/library/reprlib.rst Doc/library/resource.rst Doc/library/rlcompleter.rst Doc/library/select.rst -Doc/library/selectors.rst -Doc/library/shelve.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/stdtypes.rst Doc/library/string.rst Doc/library/subprocess.rst -Doc/library/sys_path_init.rst -Doc/library/syslog.rst Doc/library/tarfile.rst -Doc/library/tempfile.rst Doc/library/termios.rst Doc/library/test.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/unittest.mock.rst Doc/library/unittest.rst Doc/library/urllib.parse.rst @@ -134,7 +106,6 @@ Doc/library/wsgiref.rst Doc/library/xml.dom.minidom.rst Doc/library/xml.dom.pulldom.rst Doc/library/xml.dom.rst -Doc/library/xml.rst Doc/library/xml.sax.handler.rst Doc/library/xml.sax.reader.rst Doc/library/xml.sax.rst @@ -147,8 +118,6 @@ Doc/reference/expressions.rst Doc/reference/import.rst Doc/reference/simple_stmts.rst Doc/tutorial/datastructures.rst -Doc/tutorial/introduction.rst -Doc/using/cmdline.rst Doc/using/windows.rst Doc/whatsnew/2.0.rst Doc/whatsnew/2.1.rst diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py index 3551bfa4c0f133..42c2f10e0be260 100644 --- a/Doc/tools/extensions/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -126,7 +126,7 @@ def add_annotations(self, app, doctree): f"Object type mismatch in limited API annotation " f"for {name}: {record['role']!r} != {objtype!r}") stable_added = record['added'] - message = ' Part of the ' + message = sphinx_gettext(' Part of the ') emph_node = nodes.emphasis(message, message, classes=['stableabi']) ref_node = addnodes.pending_xref( @@ -134,40 +134,40 @@ def add_annotations(self, app, doctree): reftype='ref', refexplicit="False") struct_abi_kind = record['struct_abi_kind'] if struct_abi_kind in {'opaque', 'members'}: - ref_node += nodes.Text('Limited API') + ref_node += nodes.Text(sphinx_gettext('Limited API')) else: - ref_node += nodes.Text('Stable ABI') + ref_node += nodes.Text(sphinx_gettext('Stable ABI')) emph_node += ref_node if struct_abi_kind == 'opaque': - emph_node += nodes.Text(' (as an opaque struct)') + emph_node += nodes.Text(sphinx_gettext(' (as an opaque struct)')) elif struct_abi_kind == 'full-abi': - emph_node += nodes.Text(' (including all members)') + emph_node += nodes.Text(sphinx_gettext(' (including all members)')) if record['ifdef_note']: emph_node += nodes.Text(' ' + record['ifdef_note']) if stable_added == '3.2': # Stable ABI was introduced in 3.2. pass else: - emph_node += nodes.Text(f' since version {stable_added}') + emph_node += nodes.Text(sphinx_gettext(' since version %s') % stable_added) emph_node += nodes.Text('.') if struct_abi_kind == 'members': emph_node += nodes.Text( - ' (Only some members are part of the stable ABI.)') + sphinx_gettext(' (Only some members are part of the stable ABI.)')) node.insert(0, emph_node) # Unstable API annotation. if name.startswith('PyUnstable'): warn_node = nodes.admonition( classes=['unstable-c-api', 'warning']) - message = 'This is ' + message = sphinx_gettext('This is ') emph_node = nodes.emphasis(message, message) ref_node = addnodes.pending_xref( 'Unstable API', refdomain="std", reftarget='unstable-c-api', reftype='ref', refexplicit="False") - ref_node += nodes.Text('Unstable API') + ref_node += nodes.Text(sphinx_gettext('Unstable API')) emph_node += ref_node - emph_node += nodes.Text('. It may change without warning in minor releases.') + emph_node += nodes.Text(sphinx_gettext('. It may change without warning in minor releases.')) warn_node += emph_node node.insert(0, warn_node) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 3cf4d236604bcb..31c2544caf601c 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 @@ -127,8 +127,8 @@ class Availability(SphinxDirective): # known platform, libc, and threading implementations known_platforms = frozenset({ "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", - "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", "Unix", "VxWorks", - "WASI", "Windows", "macOS", + "GNU/kFreeBSD", "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", + "Unix", "VxWorks", "WASI", "Windows", "macOS", # libc "BSD libc", "glibc", "musl", # POSIX platforms with pthreads @@ -607,6 +607,13 @@ def parse_pdb_command(env, sig, signode): return fullname +def parse_monitoring_event(env, sig, signode): + """Transform a monitoring event signature into RST nodes.""" + signode += addnodes.desc_addname('sys.monitoring.events.', 'sys.monitoring.events.') + signode += addnodes.desc_name(sig, sig) + return sig + + def process_audit_events(app, doctree, fromdocname): for node in doctree.traverse(audit_event_list): break @@ -707,6 +714,7 @@ def setup(app): app.add_builder(PydocTopicsBuilder) app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature) app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command) + app.add_object_type('monitoring-event', 'monitoring-event', '%s (monitoring event)', parse_monitoring_event) app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction) app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod) app.add_directive_to_domain('py', 'coroutinefunction', PyCoroutineFunction) diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html index 7920e0619f9337..b5353d6fb77ab4 100644 --- a/Doc/tools/templates/download.html +++ b/Doc/tools/templates/download.html @@ -49,12 +49,12 @@

Unpacking

Unix users should download the .tar.bz2 archives; these are bzipped tar archives and can be handled in the usual way using tar and the bzip2 -program. The InfoZIP unzip program can be +program. The Info-ZIP unzip program can be used to handle the ZIP archives if desired. The .tar.bz2 archives provide the best compression and fastest download times.

Windows users can use the ZIP archives since those are customary on that -platform. These are created on Unix using the InfoZIP zip program.

+platform. These are created on Unix using the Info-ZIP zip program.

Problems

diff --git a/Doc/tools/templates/dummy.html b/Doc/tools/templates/dummy.html index bab4aaeb4604b8..3a0acab8836b11 100644 --- a/Doc/tools/templates/dummy.html +++ b/Doc/tools/templates/dummy.html @@ -9,6 +9,16 @@ In extensions/c_annotations.py: +{% trans %} Part of the {% endtrans %} +{% trans %}Limited API{% endtrans %} +{% trans %}Stable ABI{% endtrans %} +{% trans %} (as an opaque struct){% endtrans %} +{% trans %} (including all members){% endtrans %} +{% trans %} since version %s{% endtrans %} +{% trans %} (Only some members are part of the stable ABI.){% endtrans %} +{% trans %}This is {% endtrans %} +{% trans %}Unstable API{% endtrans %} +{% trans %}. It may change without warning in minor releases.{% endtrans %} {% trans %}Return value: Always NULL.{% endtrans %} {% trans %}Return value: New reference.{% endtrans %} {% trans %}Return value: Borrowed reference.{% endtrans %} diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 7b92e1a51b6e67..3bf138ca225ee5 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -769,8 +769,10 @@ data from a string buffer instead, and pass it as an argument. or arithmetic operators, and assigning such a "pseudo-file" to sys.stdin will 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 +:ref:`Instance method objects ` have attributes, too: +:attr:`m.__self__ ` is the instance +object with the method :meth:`!m`, and :attr:`m.__func__ ` is +the :ref:`function object ` corresponding to the method. diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 1ec59767e9ce12..4058ebe8efdb42 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -108,8 +108,7 @@ The :keyword:`try` statement works as follows. * If an exception occurs which does not match the exception named in the *except clause*, it is passed on to outer :keyword:`try` statements; if no handler is - found, it is an *unhandled exception* and execution stops with a message as - shown above. + found, it is an *unhandled exception* and execution stops with an error message. A :keyword:`try` statement may have more than one *except clause*, to specify handlers for different exceptions. At most one handler will be executed. diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index b88055a41fd1ff..0795e2fef98830 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:: @@ -150,7 +150,7 @@ section. See `Examples of Floating Point Problems `_ for a pleasant summary of how binary floating-point works and the kinds of problems commonly encountered in practice. Also see -`The Perils of Floating Point `_ +`The Perils of Floating Point `_ for a more complete account of other common surprises. As that says near the end, "there are no easy answers." Still, don't be unduly diff --git a/Doc/tutorial/interactive.rst b/Doc/tutorial/interactive.rst index 0d3896a4832b59..4e054c4e6c2c32 100644 --- a/Doc/tutorial/interactive.rst +++ b/Doc/tutorial/interactive.rst @@ -51,4 +51,4 @@ bpython_. .. _GNU Readline: https://tiswww.case.edu/php/chet/readline/rltop.html .. _IPython: https://ipython.org/ -.. _bpython: https://www.bpython-interpreter.org/ +.. _bpython: https://bpython-interpreter.org/ diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 0fc75c7d7532e2..4536ab9486d39c 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -428,7 +428,7 @@ type, i.e. it is possible to change their content:: [1, 8, 27, 64, 125] You can also add new items at the end of the list, by using -the :meth:`~list.append` *method* (we will see more about methods later):: +the :meth:`!list.append` *method* (we will see more about methods later):: >>> cubes.append(216) # add the cube of 6 >>> cubes.append(7 ** 3) # and the cube of 7 @@ -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/stdlib.rst b/Doc/tutorial/stdlib.rst index 6bae279c5e9cde..63f4b5e1ce0207 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -153,7 +153,7 @@ The :mod:`random` module provides tools for making random selections:: 'apple' >>> random.sample(range(100), 10) # sampling without replacement [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] - >>> random.random() # random float + >>> random.random() # random float from the interval [0.0, 1.0) 0.17970987693706186 >>> random.randrange(6) # random integer chosen from range(6) 4 diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 921b6a6961c7b2..dac4956b551dd3 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. @@ -103,7 +103,7 @@ source. :option:`-I` option can be used to run the script in isolated mode where :data:`sys.path` contains neither the current directory nor the user's - site-packages directory. All :envvar:`PYTHON*` environment variables are + site-packages directory. All ``PYTHON*`` environment variables are ignored, too. Many standard library modules contain code that is invoked on their execution @@ -161,7 +161,7 @@ source. :option:`-I` option can be used to run the script in isolated mode where :data:`sys.path` contains neither the script's directory nor the user's - site-packages directory. All :envvar:`PYTHON*` environment variables are + site-packages directory. All ``PYTHON*`` environment variables are ignored, too. .. audit-event:: cpython.run_file filename @@ -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,15 +278,15 @@ Miscellaneous options it's ignored. -.. cmdoption:: -E +.. option:: -E - Ignore all :envvar:`PYTHON*` environment variables, e.g. + Ignore all ``PYTHON*`` environment variables, e.g. :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. See also the :option:`-P` and :option:`-I` (isolated) options. -.. cmdoption:: -i +.. 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,20 +297,20 @@ 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. In isolated mode :data:`sys.path` contains neither the script's directory nor - the user's site-packages directory. All :envvar:`PYTHON*` environment + the user's site-packages directory. All ``PYTHON*`` environment variables are ignored, too. Further restrictions may be imposed to prevent the user from injecting malicious code. .. 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,21 +348,21 @@ 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 randomization is enabled by default. On previous versions of Python, this option turns on hash randomization, - so that the :meth:`__hash__` values of str and bytes objects + so that the :meth:`~object.__hash__` values of str and bytes objects are "salted" with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python. @@ -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: @@ -535,17 +535,30 @@ Miscellaneous options location indicators when the interpreter displays tracebacks. See also :envvar:`PYTHONNODEBUGRANGES`. * ``-X frozen_modules`` determines whether or not frozen modules are - ignored by the import machinery. A value of "on" means they get - imported and "off" means they are ignored. The default is "on" + ignored by the import machinery. A value of ``on`` means they get + imported and ``off`` means they are ignored. The default is ``on`` if this is an installed Python (the normal case). If it's under - development (running from the source tree) then the default is "off". - Note that the "importlib_bootstrap" and "importlib_bootstrap_external" - frozen modules are always used, even if this flag is set to "off". + development (running from the source tree) then the default is ``off``. + Note that the :mod:`!importlib_bootstrap` and + :mod:`!importlib_bootstrap_external` frozen modules are always used, even + if this flag is set to ``off``. See also :envvar:`PYTHON_FROZEN_MODULES`. * ``-X perf`` enables support for the Linux ``perf`` profiler. When this option is provided, the ``perf`` profiler will be able to report Python calls. This option is only available on some platforms and will do nothing if is not supported on the current system. The default value is "off". See also :envvar:`PYTHONPERFSUPPORT` and :ref:`perf_profiling`. + * :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. + * :samp:`-X presite={package.module}` specifies a module that should be + imported before the :mod:`site` module is executed and before the + :mod:`__main__` module exists. Therefore, the imported module isn't + :mod:`__main__`. This can be used to execute code early during Python + initialization. Python needs to be :ref:`built in debug mode ` + for this option to exist. See also :envvar:`PYTHON_PRESITE`. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -577,9 +590,7 @@ Miscellaneous options .. versionadded:: 3.10 The ``-X warn_default_encoding`` option. - - .. deprecated-removed:: 3.9 3.10 - The ``-X oldparser`` option. + Removed the ``-X oldparser`` option. .. versionadded:: 3.11 The ``-X no_debug_ranges`` option. @@ -593,11 +604,38 @@ Miscellaneous options .. versionadded:: 3.12 The ``-X perf`` option. + .. versionadded:: 3.13 + The ``-X cpu_count`` option. + + .. versionadded:: 3.13 + The ``-X presite`` option. + +Controlling Color +~~~~~~~~~~~~~~~~~ + +The Python interpreter is configured by default to use colors to highlight +output in certain situations such as when displaying tracebacks. This +behavior can be controlled by setting different environment variables. + +Setting the environment variable ``TERM`` to ``dumb`` will disable color. + +If the environment variable ``FORCE_COLOR`` is set, then color will be +enabled regardless of the value of TERM. This is useful on CI systems which +aren’t terminals but can none-the-less display ANSI escape sequences. + +If the environment variable ``NO_COLOR`` is set, Python will disable all color +in the output. This takes precedence over ``FORCE_COLOR``. + +All these environment variables are used also by other tools to control color +output. To control the color output only in the Python interpreter, the +:envvar:`PYTHON_COLORS` environment variable can be used. This variable takes +precedence over ``NO_COLOR``, which in turn takes precedence over +``FORCE_COLOR``. Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. cmdoption:: -J +.. option:: -J Reserved for use by Jython_. @@ -811,7 +849,7 @@ conflict. Defines the :data:`user base directory `, which is used to compute the path of the :data:`user site-packages directory ` - and installation paths for + and :ref:`installation paths ` for ``python -m pip install --user``. .. seealso:: @@ -851,9 +889,10 @@ conflict. If this environment variable is set to a non-empty string, :func:`faulthandler.enable` is called at startup: install a handler for - :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS` and - :const:`SIGILL` signals to dump the Python traceback. This is equivalent to - :option:`-X` ``faulthandler`` option. + :const:`~signal.SIGSEGV`, :const:`~signal.SIGFPE`, + :const:`~signal.SIGABRT`, :const:`~signal.SIGBUS` and + :const:`~signal.SIGILL` signals to dump the Python traceback. + This is equivalent to :option:`-X` ``faulthandler`` option. .. versionadded:: 3.3 @@ -902,6 +941,9 @@ conflict. * ``pymalloc``: use the :ref:`pymalloc allocator ` for :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. + * ``mimalloc``: use the :ref:`mimalloc allocator ` for + :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 `: @@ -909,6 +951,7 @@ conflict. allocators `. * ``malloc_debug``: same as ``malloc`` but also install debug hooks. * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks. + * ``mimalloc_debug``: same as ``mimalloc`` but also install debug hooks. .. versionchanged:: 3.7 Added the ``"default"`` allocator. @@ -1063,6 +1106,35 @@ 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 + +.. envvar:: PYTHON_FROZEN_MODULES + + If this variable is set to ``on`` or ``off``, it determines whether or not + frozen modules are ignored by the import machinery. A value of ``on`` means + they get imported and ``off`` means they are ignored. The default is ``on`` + for non-debug builds (the normal case) and ``off`` for debug builds. + Note that the :mod:`!importlib_bootstrap` and + :mod:`!importlib_bootstrap_external` frozen modules are always used, even + if this flag is set to ``off``. + + See also the :option:`-X frozen_modules <-X>` command-line option. + + .. versionadded:: 3.13 + +.. envvar:: PYTHON_COLORS + + If this variable is set to ``1``, the interpreter will colorize various kinds + of output. Setting it to ``0`` deactivates this behavior. + + .. versionadded:: 3.13 Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ @@ -1072,13 +1144,33 @@ Debug-mode variables If set, Python will dump objects and reference counts still alive after shutting down the interpreter. - Need Python configured with the :option:`--with-trace-refs` build option. + Needs Python configured with the :option:`--with-trace-refs` build option. -.. envvar:: PYTHONDUMPREFSFILE=FILENAME +.. envvar:: PYTHONDUMPREFSFILE If set, Python will dump objects and reference counts still alive - after shutting down the interpreter into a file called *FILENAME*. + after shutting down the interpreter into a file under the path given + as the value to this environment variable. - Need Python configured with the :option:`--with-trace-refs` build option. + Needs Python configured with the :option:`--with-trace-refs` build option. .. versionadded:: 3.11 + +.. envvar:: PYTHON_PRESITE + + If this variable is set to a module, that module will be imported + early in the interpreter lifecycle, before the :mod:`site` module is + executed, and before the :mod:`__main__` module is created. + Therefore, the imported module is not treated as :mod:`__main__`. + + This can be used to execute code early during Python initialization. + + To import a submodule, use ``package.module`` as the value, like in + an import statement. + + See also the :option:`-X presite <-X>` command-line option, + which takes precedence over this variable. + + Needs Python configured with the :option:`--with-pydebug` build option. + + .. versionadded:: 3.13 diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 83b4c7aa0481e9..cb7eda42fe3fad 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -74,14 +74,21 @@ files. Commands to regenerate all generated files:: 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:: +configure script +---------------- + +The ``make regen-configure`` command regenerates the ``aclocal.m4`` file and +the ``configure`` script using the ``Tools/build/regen-configure.sh`` shell +script which uses an Ubuntu container to get the same tools versions and have a +reproducible output. + +The container is optional, the following command can be run locally:: autoreconf -ivf -Werror +The generated files can change depending on the exact ``autoconf-archive``, +``aclocal`` and ``pkg-config`` versions. + .. _configure-options: @@ -97,7 +104,7 @@ 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) of the :mod:`sqlite3` module. @@ -107,12 +114,12 @@ General Options .. 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. @@ -122,7 +129,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*. @@ -135,7 +142,7 @@ 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 :const:`zoneinfo.TZPATH`. See the :ref:`Compile-time configuration @@ -147,7 +154,7 @@ 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. @@ -156,7 +163,7 @@ General Options .. versionadded:: 3.9 -.. cmdoption:: --with-dbmliborder= +.. option:: --with-dbmliborder= Override order to check db backends for the :mod:`dbm` module @@ -166,7 +173,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). @@ -174,13 +181,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``). @@ -190,7 +197,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). @@ -202,7 +209,7 @@ General Options .. 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. @@ -213,7 +220,7 @@ General Options .. versionadded:: 3.11 -.. cmdoption:: --enable-pystats +.. option:: --enable-pystats Turn on internal Python performance statistics gathering. @@ -280,21 +287,26 @@ General Options .. versionadded:: 3.11 -.. cmdoption:: --disable-gil +.. _free-threading-build: + +.. option:: --disable-gil Enables **experimental** support for running Python without the - :term:`global interpreter lock` (GIL). + :term:`global interpreter lock` (GIL): free threading build. + + Defines the ``Py_GIL_DISABLED`` macro and adds ``"t"`` to + :data:`sys.abiflags`. See :pep:`703` "Making the Global Interpreter Lock Optional in CPython". .. versionadded:: 3.13 -.. cmdoption:: PKG_CONFIG +.. option:: PKG_CONFIG Path to ``pkg-config`` utility. -.. cmdoption:: PKG_CONFIG_LIBDIR -.. cmdoption:: PKG_CONFIG_PATH +.. option:: PKG_CONFIG_LIBDIR +.. option:: PKG_CONFIG_PATH ``pkg-config`` options. @@ -302,19 +314,19 @@ General Options C compiler options ------------------ -.. cmdoption:: CC +.. option:: CC C compiler command. -.. cmdoption:: CFLAGS +.. option:: CFLAGS C compiler flags. -.. cmdoption:: CPP +.. option:: CPP C preprocessor command. -.. cmdoption:: CPPFLAGS +.. option:: CPPFLAGS C preprocessor flags, e.g. :samp:`-I{include_dir}`. @@ -322,15 +334,15 @@ C compiler options Linker options -------------- -.. cmdoption:: LDFLAGS +.. option:: LDFLAGS Linker flags, e.g. :samp:`-L{library_directory}`. -.. cmdoption:: LIBS +.. option:: LIBS Libraries to pass to the linker, e.g. :samp:`-l{library}`. -.. cmdoption:: MACHDEP +.. option:: MACHDEP Name for machine-dependent library files. @@ -340,80 +352,80 @@ Options for third-party dependencies .. versionadded:: 3.11 -.. cmdoption:: BZIP2_CFLAGS -.. cmdoption:: BZIP2_LIBS +.. option:: BZIP2_CFLAGS +.. option:: BZIP2_LIBS C compiler and linker flags to link Python to ``libbz2``, used by :mod:`bz2` module, overriding ``pkg-config``. -.. cmdoption:: CURSES_CFLAGS -.. cmdoption:: CURSES_LIBS +.. option:: CURSES_CFLAGS +.. option:: CURSES_LIBS C compiler and linker flags for ``libncurses`` or ``libncursesw``, used by :mod:`curses` module, overriding ``pkg-config``. -.. cmdoption:: GDBM_CFLAGS -.. cmdoption:: GDBM_LIBS +.. option:: GDBM_CFLAGS +.. option:: GDBM_LIBS C compiler and linker flags for ``gdbm``. -.. cmdoption:: LIBB2_CFLAGS -.. cmdoption:: LIBB2_LIBS +.. option:: LIBB2_CFLAGS +.. option:: LIBB2_LIBS C compiler and linker flags for ``libb2`` (:ref:`BLAKE2 `), used by :mod:`hashlib` module, overriding ``pkg-config``. -.. cmdoption:: LIBEDIT_CFLAGS -.. cmdoption:: LIBEDIT_LIBS +.. option:: LIBEDIT_CFLAGS +.. option:: LIBEDIT_LIBS C compiler and linker flags for ``libedit``, used by :mod:`readline` module, overriding ``pkg-config``. -.. cmdoption:: LIBFFI_CFLAGS -.. cmdoption:: LIBFFI_LIBS +.. option:: LIBFFI_CFLAGS +.. option:: LIBFFI_LIBS C compiler and linker flags for ``libffi``, used by :mod:`ctypes` module, overriding ``pkg-config``. -.. cmdoption:: LIBLZMA_CFLAGS -.. cmdoption:: LIBLZMA_LIBS +.. option:: LIBLZMA_CFLAGS +.. option:: LIBLZMA_LIBS C compiler and linker flags for ``liblzma``, used by :mod:`lzma` module, overriding ``pkg-config``. -.. cmdoption:: LIBREADLINE_CFLAGS -.. cmdoption:: LIBREADLINE_LIBS +.. option:: LIBREADLINE_CFLAGS +.. option:: LIBREADLINE_LIBS C compiler and linker flags for ``libreadline``, used by :mod:`readline` module, overriding ``pkg-config``. -.. cmdoption:: LIBSQLITE3_CFLAGS -.. cmdoption:: LIBSQLITE3_LIBS +.. option:: LIBSQLITE3_CFLAGS +.. option:: LIBSQLITE3_LIBS C compiler and linker flags for ``libsqlite3``, used by :mod:`sqlite3` module, overriding ``pkg-config``. -.. cmdoption:: LIBUUID_CFLAGS -.. cmdoption:: LIBUUID_LIBS +.. option:: LIBUUID_CFLAGS +.. option:: LIBUUID_LIBS C compiler and linker flags for ``libuuid``, used by :mod:`uuid` module, overriding ``pkg-config``. -.. cmdoption:: PANEL_CFLAGS -.. cmdoption:: PANEL_LIBS +.. 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``. -.. cmdoption:: TCLTK_CFLAGS -.. cmdoption:: TCLTK_LIBS +.. option:: TCLTK_CFLAGS +.. option:: TCLTK_LIBS C compiler and linker flags for TCLTK, overriding ``pkg-config``. -.. cmdoption:: ZLIB_CFLAGS -.. cmdoption:: ZLIB_LIBS +.. option:: ZLIB_CFLAGS +.. option:: ZLIB_LIBS C compiler and linker flags for ``libzlib``, used by :mod:`gzip` module, overriding ``pkg-config``. @@ -422,7 +434,7 @@ Options for third-party dependencies WebAssembly Options ------------------- -.. cmdoption:: --with-emscripten-target=[browser|node] +.. option:: --with-emscripten-target=[browser|node] Set build flavor for ``wasm32-emscripten``. @@ -431,7 +443,7 @@ WebAssembly Options .. versionadded:: 3.11 -.. cmdoption:: --enable-wasm-dynamic-linking +.. option:: --enable-wasm-dynamic-linking Turn on dynamic linking support for WASM. @@ -440,7 +452,7 @@ WebAssembly Options .. versionadded:: 3.11 -.. cmdoption:: --enable-wasm-pthreads +.. option:: --enable-wasm-pthreads Turn on pthreads support for WASM. @@ -450,7 +462,7 @@ WebAssembly Options Install Options --------------- -.. cmdoption:: --prefix=PREFIX +.. option:: --prefix=PREFIX Install architecture-independent files in PREFIX. On Unix, it defaults to :file:`/usr/local`. @@ -460,20 +472,20 @@ Install Options 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 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). .. versionadded:: 3.10 -.. cmdoption:: --with-ensurepip=[upgrade|install|no] +.. option:: --with-ensurepip=[upgrade|install|no] Select the :mod:`ensurepip` command run on Python installation: @@ -492,7 +504,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). @@ -518,7 +530,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). @@ -533,7 +548,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 @@ -558,32 +573,39 @@ also be used to improve performance. .. versionadded:: 3.12 -.. cmdoption:: BOLT_APPLY_FLAGS +.. option:: BOLT_APPLY_FLAGS Arguments to ``llvm-bolt`` when creating a `BOLT optimized binary `_. .. versionadded:: 3.12 -.. cmdoption:: BOLT_INSTRUMENT_FLAGS +.. option:: BOLT_INSTRUMENT_FLAGS Arguments to ``llvm-bolt`` when instrumenting binaries. .. versionadded:: 3.12 -.. cmdoption:: --with-computed-gotos +.. option:: --with-computed-gotos Enable computed gotos in evaluation loop (enabled by default on supported compilers). -.. cmdoption:: --without-pymalloc +.. option:: --without-mimalloc + + Disable the fast mimalloc allocator :ref:`mimalloc ` + (enabled by default). + + See also :envvar:`PYTHONMALLOC` environment variable. + +.. 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. @@ -592,11 +614,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). @@ -652,12 +674,12 @@ See also the :ref:`Python Development Mode ` and the 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). @@ -678,7 +700,7 @@ Debug options .. versionadded:: 3.8 -.. cmdoption:: --with-assertions +.. option:: --with-assertions Build with C assertions enabled (default is no): ``assert(...);`` and ``_PyObject_ASSERT(...);``. @@ -691,11 +713,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). @@ -704,19 +726,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). @@ -727,11 +749,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). @@ -742,23 +764,23 @@ 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 (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=readline|editline +.. option:: --with-readline=readline|editline Designate a backend library for the :mod:`readline` module. @@ -767,7 +789,7 @@ Libraries options .. versionadded:: 3.10 -.. cmdoption:: --without-readline +.. option:: --without-readline Don't build the :mod:`readline` module (built by default). @@ -775,21 +797,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: @@ -804,7 +826,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``: @@ -817,7 +839,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: @@ -830,7 +852,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: @@ -852,19 +874,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. @@ -880,7 +902,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``). @@ -894,21 +916,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. @@ -919,7 +941,7 @@ the version of the cross compiled host Python. ac_cv_file__dev_ptmx=yes ac_cv_file__dev_ptc=no -.. cmdoption:: HOSTRUNNER +.. option:: HOSTRUNNER Program to run CPython for the host platform for cross-compilation. diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 2476e60a26d485..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 @@ -891,6 +892,13 @@ minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the not provably i386/32-bit". To request a specific environment, use the new :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 executable :envvar:`PATH` for a Python executable matching the name provided @@ -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 :file:`python{XX}.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 :data:`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 ================== diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index c2b0ae8c76302a..6d6e51006d5bd8 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -671,9 +671,9 @@ errors. If you absolutely must use 2.0 but can't fix your code, you can edit ``NO_STRICT_LIST_APPEND`` to preserve the old behaviour; this isn't recommended. Some of the functions in the :mod:`socket` module are still forgiving in this -way. For example, :func:`socket.connect( ('hostname', 25) )` is the correct -form, passing a tuple representing an IP address, but :func:`socket.connect( -'hostname', 25 )` also works. :func:`socket.connect_ex` and :func:`socket.bind` +way. For example, ``socket.connect( ('hostname', 25) )`` is the correct +form, passing a tuple representing an IP address, but ``socket.connect('hostname', 25)`` +also works. :meth:`socket.connect_ex ` and :meth:`socket.bind ` are similarly easy-going. 2.0alpha1 tightened these functions up, but because the documentation actually used the erroneous multiple argument form, many people wrote code which would break with the stricter checking. GvR backed out diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index f0e1ded75a9d27..6d2d3cc02b8768 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -424,7 +424,8 @@ PEP 232: Function Attributes In Python 2.1, functions can now have arbitrary information attached to them. People were often using docstrings to hold information about functions and -methods, because the ``__doc__`` attribute was the only way of attaching any +methods, because the :attr:`~function.__doc__` attribute was the only way of +attaching any information to a function. For example, in the Zope web application server, functions are marked as safe for public access by having a docstring, and in John Aycock's SPARK parsing framework, docstrings hold parts of the BNF grammar diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index d9ead57413cbbf..6dfe79cef00987 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -424,22 +424,22 @@ Another significant addition to 2.2 is an iteration interface at both the C and Python levels. Objects can define how they can be looped over by callers. In Python versions up to 2.1, the usual way to make ``for item in obj`` work is -to define a :meth:`__getitem__` method that looks something like this:: +to define a :meth:`~object.__getitem__` method that looks something like this:: def __getitem__(self, index): return -:meth:`__getitem__` is more properly used to define an indexing operation on an +:meth:`~object.__getitem__` is more properly used to define an indexing operation on an object so that you can write ``obj[5]`` to retrieve the sixth element. It's a bit misleading when you're using this only to support :keyword:`for` loops. Consider some file-like object that wants to be looped over; the *index* parameter is essentially meaningless, as the class probably assumes that a -series of :meth:`__getitem__` calls will be made with *index* incrementing by -one each time. In other words, the presence of the :meth:`__getitem__` method +series of :meth:`~object.__getitem__` calls will be made with *index* incrementing by +one each time. In other words, the presence of the :meth:`~object.__getitem__` method doesn't mean that using ``file[5]`` to randomly access the sixth element will work, though it really should. -In Python 2.2, iteration can be implemented separately, and :meth:`__getitem__` +In Python 2.2, iteration can be implemented separately, and :meth:`~object.__getitem__` methods can be limited to classes that really do support random access. The basic idea of iterators is simple. A new built-in function, ``iter(obj)`` or ``iter(C, sentinel)``, is used to get an iterator. ``iter(obj)`` returns diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index ec1ca417ee139d..0c77b339a182c9 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -925,7 +925,7 @@ Deletion is more straightforward:: >>> a [1, 3] -One can also now pass slice objects to the :meth:`__getitem__` methods of the +One can also now pass slice objects to the :meth:`~object.__getitem__` methods of the built-in sequences:: >>> range(10).__getitem__(slice(0, 5, 2)) @@ -1362,7 +1362,7 @@ complete list of changes, or look through the CVS logs for all the details. :mod:`os` module. (Contributed by Gustavo Niemeyer, Geert Jansen, and Denis S. Otkidach.) -* In the :mod:`os` module, the :func:`\*stat` family of functions can now report +* In the :mod:`os` module, the :func:`!\*stat` family of functions can now report fractions of a second in a timestamp. Such time stamps are represented as floats, similar to the value returned by :func:`time.time`. @@ -1596,7 +1596,7 @@ complete list of changes, or look through the CVS logs for all the details. module. Adding the mix-in as a superclass provides the full dictionary interface - whenever the class defines :meth:`__getitem__`, :meth:`__setitem__`, + whenever the class defines :meth:`~object.__getitem__`, :meth:`__setitem__`, :meth:`__delitem__`, and :meth:`keys`. For example:: >>> import UserDict @@ -1998,13 +1998,13 @@ Some of the more notable changes are: It would be difficult to detect any resulting difference from Python code, apart from a slight speed up when Python is run without :option:`-O`. - C extensions that access the :attr:`f_lineno` field of frame objects should + C extensions that access the :attr:`~frame.f_lineno` field of frame objects should instead call ``PyCode_Addr2Line(f->f_code, f->f_lasti)``. This will have the added effect of making the code work as desired under "python -O" in earlier versions of Python. A nifty new feature is that trace functions can now assign to the - :attr:`f_lineno` attribute of frame objects, changing the line that will be + :attr:`~frame.f_lineno` attribute of frame objects, changing the line that will be executed next. A ``jump`` command has been added to the :mod:`pdb` debugger taking advantage of this new feature. (Implemented by Richie Hindle.) diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index cab321c3e54d18..bc748dd44f5f8e 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -324,7 +324,8 @@ function, as previously described. In other words, ``@A @B @C(args)`` becomes:: Getting this right can be slightly brain-bending, but it's not too difficult. -A small related change makes the :attr:`func_name` attribute of functions +A small related change makes the :attr:`func_name ` +attribute of functions writable. This attribute is used to display function names in tracebacks, so decorators should change the name of any new function that's constructed and returned. @@ -1163,7 +1164,7 @@ complete list of changes, or look through the CVS logs for all the details. * A number of functions were added to the :mod:`locale` module, such as :func:`bind_textdomain_codeset` to specify a particular encoding and a family of - :func:`l\*gettext` functions that return messages in the chosen encoding. + :func:`!l\*gettext` functions that return messages in the chosen encoding. (Contributed by Gustavo Niemeyer.) * Some keyword arguments were added to the :mod:`logging` package's diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 2df6d603207a10..627c918dd6d8b4 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -575,15 +575,15 @@ structure is:: with-block The expression is evaluated, and it should result in an object that supports the -context management protocol (that is, has :meth:`__enter__` and :meth:`__exit__` +context management protocol (that is, has :meth:`~object.__enter__` and :meth:`~object.__exit__` methods. -The object's :meth:`__enter__` is called before *with-block* is executed and +The object's :meth:`~object.__enter__` is called before *with-block* is executed and therefore can run set-up code. It also may return a value that is bound to the name *variable*, if given. (Note carefully that *variable* is *not* assigned the result of *expression*.) -After execution of the *with-block* is finished, the object's :meth:`__exit__` +After execution of the *with-block* is finished, the object's :meth:`~object.__exit__` method is called, even if the block raised an exception, and can therefore run clean-up code. @@ -609,7 +609,7 @@ part-way through the block. .. note:: In this case, *f* is the same object created by :func:`open`, because - :meth:`file.__enter__` returns *self*. + :meth:`~object.__enter__` returns *self*. The :mod:`threading` module's locks and condition variables also support the ':keyword:`with`' statement:: @@ -652,10 +652,10 @@ underlying implementation and should keep reading. A high-level explanation of the context management protocol is: * The expression is evaluated and should result in an object called a "context - manager". The context manager must have :meth:`__enter__` and :meth:`__exit__` + manager". The context manager must have :meth:`~object.__enter__` and :meth:`~object.__exit__` methods. -* The context manager's :meth:`__enter__` method is called. The value returned +* The context manager's :meth:`~object.__enter__` method is called. The value returned is assigned to *VAR*. If no ``'as VAR'`` clause is present, the value is simply discarded. @@ -669,7 +669,7 @@ A high-level explanation of the context management protocol is: if you do the author of the code containing the ':keyword:`with`' statement will never realize anything went wrong. -* If *BLOCK* didn't raise an exception, the :meth:`__exit__` method is still +* If *BLOCK* didn't raise an exception, the :meth:`~object.__exit__` method is still called, but *type*, *value*, and *traceback* are all ``None``. Let's think through an example. I won't present detailed code but will only @@ -703,7 +703,7 @@ rolled back if there's an exception. Here's the basic interface for def rollback (self): "Rolls back current transaction" -The :meth:`__enter__` method is pretty easy, having only to start a new +The :meth:`~object.__enter__` method is pretty easy, having only to start a new transaction. For this application the resulting cursor object would be a useful result, so the method will return it. The user can then add ``as cursor`` to their ':keyword:`with`' statement to bind the cursor to a variable name. :: @@ -715,7 +715,7 @@ their ':keyword:`with`' statement to bind the cursor to a variable name. :: cursor = self.cursor() return cursor -The :meth:`__exit__` method is the most complicated because it's where most of +The :meth:`~object.__exit__` method is the most complicated because it's where most of the work has to be done. The method has to check if an exception occurred. If there was no exception, the transaction is committed. The transaction is rolled back if there was an exception. @@ -748,10 +748,10 @@ are useful for writing objects for use with the ':keyword:`with`' statement. The decorator is called :func:`contextmanager`, and lets you write a single generator function instead of defining a new class. The generator should yield exactly one value. The code up to the :keyword:`yield` will be executed as the -:meth:`__enter__` method, and the value yielded will be the method's return +:meth:`~object.__enter__` method, and the value yielded will be the method's return value that will get bound to the variable in the ':keyword:`with`' statement's :keyword:`!as` clause, if any. The code after the :keyword:`yield` will be -executed in the :meth:`__exit__` method. Any exception raised in the block will +executed in the :meth:`~object.__exit__` method. Any exception raised in the block will be raised by the :keyword:`!yield` statement. Our database example from the previous section could be written using this @@ -1167,10 +1167,10 @@ marked in the following list. * It's now illegal to mix iterating over a file with ``for line in file`` and calling the file object's :meth:`read`/:meth:`readline`/:meth:`readlines` - methods. Iteration uses an internal buffer and the :meth:`read\*` methods + methods. Iteration uses an internal buffer and the :meth:`!read\*` methods don't use that buffer. Instead they would return the data following the buffer, causing the data to appear out of order. Mixing iteration and these - methods will now trigger a :exc:`ValueError` from the :meth:`read\*` method. + methods will now trigger a :exc:`ValueError` from the :meth:`!read\*` method. (Implemented by Thomas Wouters.) .. Patch 1397960 @@ -1347,7 +1347,7 @@ complete list of changes, or look through the SVN logs for all the details. :func:`input` function to allow opening files in binary or :term:`universal newlines` mode. Another new parameter, *openhook*, lets you use a function other than :func:`open` to open the input files. Once you're iterating over - the set of files, the :class:`FileInput` object's new :meth:`fileno` returns + the set of files, the :class:`FileInput` object's new :meth:`~fileinput.fileno` returns the file descriptor for the currently opened file. (Contributed by Georg Brandl.) diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index f3912d42180bfd..e8c1709c42abac 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -269,15 +269,15 @@ structure is:: with-block The expression is evaluated, and it should result in an object that supports the -context management protocol (that is, has :meth:`__enter__` and :meth:`__exit__` +context management protocol (that is, has :meth:`~object.__enter__` and :meth:`~object.__exit__` methods). -The object's :meth:`__enter__` is called before *with-block* is executed and +The object's :meth:`~object.__enter__` is called before *with-block* is executed and therefore can run set-up code. It also may return a value that is bound to the name *variable*, if given. (Note carefully that *variable* is *not* assigned the result of *expression*.) -After execution of the *with-block* is finished, the object's :meth:`__exit__` +After execution of the *with-block* is finished, the object's :meth:`~object.__exit__` method is called, even if the block raised an exception, and can therefore run clean-up code. @@ -296,7 +296,7 @@ part-way through the block. .. note:: In this case, *f* is the same object created by :func:`open`, because - :meth:`file.__enter__` returns *self*. + :meth:`~object.__enter__` returns *self*. The :mod:`threading` module's locks and condition variables also support the ':keyword:`with`' statement:: @@ -339,16 +339,16 @@ underlying implementation and should keep reading. A high-level explanation of the context management protocol is: * The expression is evaluated and should result in an object called a "context - manager". The context manager must have :meth:`__enter__` and :meth:`__exit__` + manager". The context manager must have :meth:`~object.__enter__` and :meth:`~object.__exit__` methods. -* The context manager's :meth:`__enter__` method is called. The value returned +* The context manager's :meth:`~object.__enter__` method is called. The value returned is assigned to *VAR*. If no ``as VAR`` clause is present, the value is simply discarded. * The code in *BLOCK* is executed. -* If *BLOCK* raises an exception, the context manager's :meth:`__exit__` method +* If *BLOCK* raises an exception, the context manager's :meth:`~object.__exit__` method is called with three arguments, the exception details (``type, value, traceback``, the same values returned by :func:`sys.exc_info`, which can also be ``None`` if no exception occurred). The method's return value controls whether an exception @@ -357,7 +357,7 @@ A high-level explanation of the context management protocol is: if you do the author of the code containing the ':keyword:`with`' statement will never realize anything went wrong. -* If *BLOCK* didn't raise an exception, the :meth:`__exit__` method is still +* If *BLOCK* didn't raise an exception, the :meth:`~object.__exit__` method is still called, but *type*, *value*, and *traceback* are all ``None``. Let's think through an example. I won't present detailed code but will only @@ -391,7 +391,7 @@ rolled back if there's an exception. Here's the basic interface for def rollback(self): "Rolls back current transaction" -The :meth:`__enter__` method is pretty easy, having only to start a new +The :meth:`~object.__enter__` method is pretty easy, having only to start a new transaction. For this application the resulting cursor object would be a useful result, so the method will return it. The user can then add ``as cursor`` to their ':keyword:`with`' statement to bind the cursor to a variable name. :: @@ -403,7 +403,7 @@ their ':keyword:`with`' statement to bind the cursor to a variable name. :: cursor = self.cursor() return cursor -The :meth:`__exit__` method is the most complicated because it's where most of +The :meth:`~object.__exit__` method is the most complicated because it's where most of the work has to be done. The method has to check if an exception occurred. If there was no exception, the transaction is committed. The transaction is rolled back if there was an exception. @@ -436,10 +436,10 @@ are useful when writing objects for use with the ':keyword:`with`' statement. The decorator is called :func:`contextmanager`, and lets you write a single generator function instead of defining a new class. The generator should yield exactly one value. The code up to the :keyword:`yield` will be executed as the -:meth:`__enter__` method, and the value yielded will be the method's return +:meth:`~object.__enter__` method, and the value yielded will be the method's return value that will get bound to the variable in the ':keyword:`with`' statement's :keyword:`!as` clause, if any. The code after the :keyword:`!yield` will be -executed in the :meth:`__exit__` method. Any exception raised in the block will +executed in the :meth:`~object.__exit__` method. Any exception raised in the block will be raised by the :keyword:`!yield` statement. Using this decorator, our database example from the previous section @@ -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:: @@ -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: - * :c:macro:`PyBUF_WRITABLE` indicates that the memory must be writable. +* :c:macro:`PyBUF_WRITABLE` indicates that the memory must be writable. - * :c:macro:`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. - * :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. +* :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. @@ -1677,8 +1677,9 @@ Some smaller changes made to the core Python language are: (:issue:`1591665`) * Instance method objects have new attributes for the object and function - comprising the method; the new synonym for :attr:`im_self` is - :attr:`__self__`, and :attr:`im_func` is also available as :attr:`__func__`. + comprising the method; the new synonym for :attr:`!im_self` is + :attr:`~method.__self__`, and :attr:`!im_func` is also available as + :attr:`~method.__func__`. The old names are still supported in Python 2.6, but are gone in 3.0. * An obscure change: when you use the :func:`locals` function inside a @@ -1737,7 +1738,7 @@ Optimizations (Contributed by Antoine Pitrou.) Memory usage is reduced by using pymalloc for the Unicode string's data. -* The ``with`` statement now stores the :meth:`__exit__` method on the stack, +* The ``with`` statement now stores the :meth:`~object.__exit__` method on the stack, producing a small speedup. (Implemented by Jeffrey Yasskin.) * To reduce memory usage, the garbage collector will now clear internal @@ -1850,8 +1851,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 +1874,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. diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index e82e8e4db1abcd..5af700bd5d3506 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -858,9 +858,11 @@ Some smaller changes made to the core Python language are: .. XXX bytearray doesn't seem to be documented -* When using ``@classmethod`` and ``@staticmethod`` to wrap +* When using :class:`@classmethod ` and + :class:`@staticmethod ` to wrap methods as class or static methods, the wrapper object now - exposes the wrapped function as their :attr:`__func__` attribute. + exposes the wrapped function as their :attr:`~method.__func__` + attribute. (Contributed by Amaury Forgeot d'Arc, after a suggestion by George Sakkis; :issue:`5982`.) @@ -930,8 +932,8 @@ Optimizations Several performance enhancements have been added: * A new opcode was added to perform the initial setup for - :keyword:`with` statements, looking up the :meth:`__enter__` and - :meth:`__exit__` methods. (Contributed by Benjamin Peterson.) + :keyword:`with` statements, looking up the :meth:`~object.__enter__` and + :meth:`~object.__exit__` methods. (Contributed by Benjamin Peterson.) * The garbage collector now performs better for one common usage pattern: when many objects are being allocated without deallocating @@ -1415,7 +1417,7 @@ changes, or look through the Subversion logs for all the details. :func:`~math.lgamma` for the natural log of the Gamma function. (Contributed by Mark Dickinson and nirinA raseliarison; :issue:`3366`.) -* The :mod:`multiprocessing` module's :class:`Manager*` classes +* The :mod:`multiprocessing` module's :class:`!Manager*` classes can now be passed a callable that will be called whenever a subprocess is started, along with a set of arguments that will be passed to the callable. @@ -2368,7 +2370,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 @@ -2383,8 +2385,8 @@ Port-Specific Changes: Mac OS X Port-Specific Changes: FreeBSD ----------------------------------- -* FreeBSD 7.1's :const:`SO_SETFIB` constant, used with - :func:`~socket.getsockopt`/:func:`~socket.setsockopt` to select an +* FreeBSD 7.1's :const:`SO_SETFIB` constant, used with the :func:`~socket.socket` methods + :func:`~socket.socket.getsockopt`/:func:`~socket.socket.setsockopt` to select an alternate routing table, is now available in the :mod:`socket` module. (Added by Kyle VanderBeek; :issue:`8235`.) @@ -2404,7 +2406,7 @@ Other Changes and Fixes :issue:`5464`.) * When importing a module from a :file:`.pyc` or :file:`.pyo` file - with an existing :file:`.py` counterpart, the :attr:`co_filename` + with an existing :file:`.py` counterpart, the :attr:`~codeobject.co_filename` attributes of the resulting code objects are overwritten when the original filename is obsolete. This can happen if the file has been renamed, moved, or is accessed through different paths. (Patch by @@ -2449,13 +2451,13 @@ that may require changes to your code: (Changed by Eric Smith; :issue:`5920`.) * Because of an optimization for the :keyword:`with` statement, the special - methods :meth:`__enter__` and :meth:`__exit__` must belong to the object's + methods :meth:`~object.__enter__` and :meth:`~object.__exit__` must belong to the object's type, and cannot be directly attached to the object's instance. This affects new-style classes (derived from :class:`object`) and C extension types. (:issue:`6101`.) * Due to a bug in Python 2.6, the *exc_value* parameter to - :meth:`__exit__` methods was often the string representation of the + :meth:`~object.__exit__` methods was often the string representation of the exception, not an instance. This was fixed in 2.7, so *exc_value* will be an instance as expected. (Fixed by Florent Xicluna; :issue:`7853`.) diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index b0c2529e780213..89e12062abaddd 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -711,7 +711,7 @@ new powerful features added: {Exception}({args})` instead of :samp:`raise {Exception}, {args}`. Additionally, you can no longer explicitly specify a traceback; instead, if you *have* to do this, you can assign directly to the - :attr:`__traceback__` attribute (see below). + :attr:`~BaseException.__traceback__` attribute (see below). * :pep:`3110`: Catching exceptions. You must now use :samp:`except {SomeException} as {variable}` instead @@ -725,7 +725,7 @@ new powerful features added: handler block. This usually happens due to a bug in the handler block; we call this a *secondary* exception. In this case, the original exception (that was being handled) is saved as the - :attr:`__context__` attribute of the secondary exception. + :attr:`~BaseException.__context__` attribute of the secondary exception. Explicit chaining is invoked with this syntax:: raise SecondaryException() from primary_exception @@ -733,14 +733,15 @@ new powerful features added: (where *primary_exception* is any expression that produces an exception object, probably an exception that was previously caught). In this case, the primary exception is stored on the - :attr:`__cause__` attribute of the secondary exception. The + :attr:`~BaseException.__cause__` attribute of the secondary exception. The traceback printed when an unhandled exception occurs walks the chain - of :attr:`__cause__` and :attr:`__context__` attributes and prints a + of :attr:`!__cause__` and :attr:`~BaseException.__context__` attributes and + prints a separate traceback for each component of the chain, with the primary exception at the top. (Java users may recognize this behavior.) * :pep:`3134`: Exception objects now store their traceback as the - :attr:`__traceback__` attribute. This means that an exception + :attr:`~BaseException.__traceback__` attribute. This means that an exception object now contains all the information pertaining to an exception, and there are fewer reasons to use :func:`sys.exc_info` (though the latter is not removed). @@ -779,14 +780,15 @@ Operators And Special Methods * Removed support for :attr:`__members__` and :attr:`__methods__`. -* The function attributes named :attr:`func_X` have been renamed to - use the :data:`__X__` form, freeing up these names in the function +* The function attributes named :attr:`!func_X` have been renamed to + use the :attr:`!__X__` form, freeing up these names in the function attribute namespace for user-defined attributes. To wit, - :attr:`func_closure`, :attr:`func_code`, :attr:`func_defaults`, - :attr:`func_dict`, :attr:`func_doc`, :attr:`func_globals`, - :attr:`func_name` were renamed to :attr:`__closure__`, - :attr:`__code__`, :attr:`__defaults__`, :attr:`~object.__dict__`, - :attr:`__doc__`, :attr:`__globals__`, :attr:`~definition.__name__`, + :attr:`!func_closure`, :attr:`!func_code`, :attr:`!func_defaults`, + :attr:`!func_dict`, :attr:`!func_doc`, :attr:`!func_globals`, + :attr:`!func_name` were renamed to :attr:`~function.__closure__`, + :attr:`~function.__code__`, :attr:`~function.__defaults__`, + :attr:`~function.__dict__`, :attr:`~function.__doc__`, + :attr:`~function.__globals__`, :attr:`~function.__name__`, respectively. * :meth:`!__nonzero__` is now :meth:`~object.__bool__`. diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 20cabbd25cc686..2da90b7ed55744 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 @@ -399,9 +399,11 @@ PEP 626: Precise line numbers for debugging and other tools PEP 626 brings more precise and reliable line numbers for debugging, profiling and coverage tools. Tracing events, with the correct line number, are generated for all lines of code executed and only for lines of code that are executed. -The ``f_lineno`` attribute of frame objects will always contain the expected line number. +The :attr:`~frame.f_lineno` attribute of frame objects will always contain the +expected line number. -The ``co_lnotab`` attribute of code objects is deprecated and will be removed in 3.12. +The :attr:`~codeobject.co_lnotab` attribute of code objects is deprecated and +will be removed in 3.12. Code that needs to convert from offset to line number should use the new ``co_lines()`` method instead. PEP 634: Structural Pattern Matching @@ -433,16 +435,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 ~~~~~~~~~~~~~~~~~~~~ @@ -1959,11 +1961,11 @@ Changes in the C API source_buf = PyBytes_AsString(source_bytes_object); code = Py_CompileString(source_buf, filename, Py_file_input); - * For ``FrameObject`` objects, the ``f_lasti`` member now represents a wordcode + * For ``FrameObject`` objects, the :attr:`~frame.f_lasti` member now represents a wordcode offset instead of a simple offset into the bytecode string. This means that this number needs to be multiplied by 2 to be used with APIs that expect a byte offset instead (like :c:func:`PyCode_Addr2Line` for example). Notice as well that the - ``f_lasti`` member of ``FrameObject`` objects is not considered stable: please + :attr:`!f_lasti` member of ``FrameObject`` objects is not considered stable: please use :c:func:`PyFrame_GetLineNumber` instead. CPython bytecode changes @@ -2211,16 +2213,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 257025da91a7ed..8db133b90a7a4b 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -1798,7 +1798,7 @@ Standard Library * :func:`importlib.resources.path` * The :func:`locale.getdefaultlocale` function is deprecated and will be - removed in Python 3.13. Use :func:`locale.setlocale`, + removed in Python 3.15. Use :func:`locale.setlocale`, :func:`locale.getpreferredencoding(False) ` and :func:`locale.getlocale` functions instead. (Contributed by Victor Stinner in :gh:`90817`.) @@ -2458,11 +2458,12 @@ Porting to Python 3.11 * ``f_valuestack``: removed. The Python frame object is now created lazily. A side effect is that the - ``f_back`` member must not be accessed directly, since its value is now also + :attr:`~frame.f_back` member must not be accessed directly, + since its value is now also computed lazily. The :c:func:`PyFrame_GetBack` function must be called instead. - Debuggers that accessed the ``f_locals`` directly *must* call + Debuggers that accessed the :attr:`~frame.f_locals` directly *must* call :c:func:`PyFrame_GetLocals` instead. They no longer need to call :c:func:`PyFrame_FastToLocalsWithError` or :c:func:`PyFrame_LocalsToFast`, in fact they should not call those functions. The necessary updating of the diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index ec39616d7c9d2b..8551b35438e2c3 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -46,7 +46,7 @@ researching a change. This article explains the new features in Python 3.12, compared to 3.11. -Python 3.12 will be released on October 2, 2023. +Python 3.12 was released on October 2, 2023. For full details, see the :ref:`changelog `. .. seealso:: @@ -121,7 +121,7 @@ Significant improvements in the standard library: * 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 up to 64% faster. + producing tokens via the :mod:`tokenize` module is up to 64% faster. Security improvements: @@ -303,7 +303,7 @@ 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 :pep:`the PEG parser <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`: @@ -716,6 +716,9 @@ importlib.resources * :func:`importlib.resources.as_file` now supports resource directories. (Contributed by Jason R. Coombs in :gh:`97930`.) +* Rename first parameter of :func:`importlib.resources.files` to *anchor*. + (Contributed by Jason R. Coombs in :gh:`100598`.) + inspect ------- @@ -835,8 +838,7 @@ shutil * :func:`shutil.rmtree` now accepts a new argument *onexc* which is an error handler like *onerror* but which expects an exception instance - rather than a *(typ, val, tb)* triplet. *onerror* is deprecated and - will be removed in Python 3.14. + rather than a *(typ, val, tb)* triplet. *onerror* is deprecated. (Contributed by Irit Katriel in :gh:`102828`.) * :func:`shutil.which` now consults the *PATHEXT* environment variable to @@ -1258,8 +1260,8 @@ Deprecated :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`.) +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` is deprecated; + use *onexc* instead. (Contributed by Irit Katriel in :gh:`102828`.) * :mod:`sqlite3`: @@ -1286,8 +1288,9 @@ Deprecated * :mod:`typing`: - * :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` - and :class:`collections.abc.Sized`. (:gh:`94309`.) + * :class:`typing.Hashable` and :class:`typing.Sized`, aliases for + :class:`collections.abc.Hashable` and :class:`collections.abc.Sized` respectively, are + deprecated. (:gh:`94309`.) * :class:`typing.ByteString`, deprecated since Python 3.9, now causes a :exc:`DeprecationWarning` to be emitted when it is used. @@ -1320,7 +1323,8 @@ Deprecated ``int``, convert to int explicitly: ``~int(x)``. (Contributed by Tim Hoffmann in :gh:`103487`.) -* Accessing ``co_lnotab`` on code objects was deprecated in Python 3.10 via :pep:`626`, +* Accessing :attr:`~codeobject.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`.) @@ -1360,7 +1364,6 @@ Other modules: APIs: * :class:`!configparser.LegacyInterpolation` (:gh:`90765`) -* :func:`locale.getdefaultlocale` (:gh:`90817`) * ``locale.resetlocale()`` (:gh:`90817`) * :meth:`!turtle.RawTurtle.settiltangle` (:gh:`50096`) * :func:`!unittest.findTestCases` (:gh:`50096`) @@ -1428,7 +1431,18 @@ and will be removed in Python 3.14. * The ``__package__`` and ``__cached__`` attributes on module objects. -* The ``co_lnotab`` attribute of code objects. +* The :attr:`~codeobject.co_lnotab` attribute of code objects. + +Pending Removal in Python 3.15 +------------------------------ + +The following APIs have been deprecated +and will be removed in Python 3.15. + +APIs: + +* :func:`locale.getdefaultlocale` (:gh:`90817`) + Pending Removal in Future Versions ---------------------------------- @@ -1626,7 +1640,10 @@ locale 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`, +smtpd +----- + +* The ``smtpd`` 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. @@ -1759,6 +1776,14 @@ Others (*ssl_context* in :mod:`imaplib`) instead. (Contributed by Victor Stinner in :gh:`94172`.) +* Remove ``Jython`` compatibility hacks from several stdlib modules and tests. + (Contributed by Nikita Sobolev in :gh:`99482`.) + +* Remove ``_use_broken_old_ctypes_structure_semantics_`` flag + from :mod:`ctypes` module. + (Contributed by Nikita Sobolev in :gh:`99285`.) + + .. _whatsnew312-porting-to-python312: Porting to Python 3.12 @@ -1870,6 +1895,15 @@ Changes in the Python API * Mixing tabs and spaces as indentation in the same file is not supported anymore and will raise a :exc:`TabError`. +* The :mod:`threading` module now expects the :mod:`!_thread` module to have + an ``_is_main_interpreter`` attribute. It is a function with no + arguments that returns ``True`` if the current interpreter is the + main interpreter. + + Any library or application that provides a custom ``_thread`` module + should provide ``_is_main_interpreter()``. + (See :gh:`112826`.) + Build Changes ============= @@ -2123,7 +2157,7 @@ Porting to Python 3.12 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 :c:macro:`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. @@ -2398,22 +2432,15 @@ Removed * 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`.) - -* Remove ``Jython`` compatibility hacks from several stdlib modules and tests. - (Contributed by Nikita Sobolev in :gh:`99482`.) - -* Remove ``_use_broken_old_ctypes_structure_semantics_`` flag - from :mod:`ctypes` module. - (Contributed by Nikita Sobolev in :gh:`99285`.) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index c9e6ca8bf88866..d599ba9ae6fac8 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -65,12 +65,33 @@ Summary -- Release highlights .. PEP-sized items next. +Important deprecations, removals or restrictions: + +* :ref:`PEP 594 `: The remaining 19 "dead batteries" + have been removed from the standard library: + :mod:`!aifc`, :mod:`!audioop`, :mod:`!cgi`, :mod:`!cgitb`, :mod:`!chunk`, + :mod:`!crypt`, :mod:`!imghdr`, :mod:`!mailcap`, :mod:`!msilib`, :mod:`!nis`, + :mod:`!nntplib`, :mod:`!ossaudiodev`, :mod:`!pipes`, :mod:`!sndhdr`, :mod:`!spwd`, + :mod:`!sunau`, :mod:`!telnetlib`, :mod:`!uu` and :mod:`!xdrlib`. + +* :pep:`602` ("Annual Release Cycle for Python") has been updated: + + * Python 3.9 - 3.12 have one and a half years of full support, + followed by three and a half years of security fixes. + * Python 3.13 and later have two years of full support, + followed by three years of security fixes. New Features ============ +Improved Error Messages +----------------------- +* The interpreter now colorizes error messages when displaying tracebacks by default. + This feature can be controlled via the new :envvar:`PYTHON_COLORS` environment + variable as well as the canonical ``NO_COLOR`` and ``FORCE_COLOR`` environment + variables. (Contributed by Pablo Galindo Salgado in :gh:`112730`.) Other Language Changes ====================== @@ -91,6 +112,25 @@ Other Language Changes 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`.) + +* Fixed a bug where a :keyword:`global` declaration in an :keyword:`except` block + is rejected when the global is used in the :keyword:`else` block. + (Contributed by Irit Katriel in :gh:`111123`.) + +* Added a new environment variable :envvar:`PYTHON_FROZEN_MODULES`. It + determines whether or not frozen modules are ignored by the import machinery, + equivalent of the :option:`-X frozen_modules <-X>` command-line option. + (Contributed by Yilei Yang in :gh:`111374`.) + New Modules =========== @@ -115,6 +155,13 @@ array It can be used instead of ``'u'`` type code, which is deprecated. (Contributed by Inada Naoki in :gh:`80480`.) +asyncio +------- + +* :meth:`asyncio.loop.create_unix_server` will now automatically remove + the Unix socket when the server is closed. + (Contributed by Pierre Ossman in :gh:`111246`.) + copy ---- @@ -127,6 +174,15 @@ copy any user classes which define the :meth:`!__replace__` method. (Contributed by Serhiy Storchaka in :gh:`108751`.) +dis +--- + +* Change the output of :mod:`dis` module functions to show logical + labels for jump targets and exception handlers, rather than offsets. + The offsets can be added with the new ``-O`` command line option or + the ``show_offsets`` parameter. + (Contributed by Irit Katriel in :gh:`112137`.) + dbm --- @@ -142,6 +198,13 @@ doctest :attr:`doctest.TestResults.skipped` attributes. (Contributed by Victor Stinner in :gh:`108794`.) +glob +---- + +* Add :func:`glob.translate` function that converts a path specification with + shell-style wildcards to a regular expression. + (Contributed by Barney Gale in :gh:`72904`.) + io -- @@ -151,6 +214,20 @@ and only logged in :ref:`Python Development Mode ` or on :ref:`Python built on debug mode `. (Contributed by Victor Stinner in :gh:`62948`.) +ipaddress +--------- + +* Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which returns the IPv4-mapped IPv6 address. + (Contributed by Charles Machalow in :gh:`109466`.) + +mmap +---- + +* The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.seekable` method + that can be used where it requires a file-like object with seekable and + the :meth:`~mmap.mmap.seek` method return the new absolute position. + (Contributed by Donghee Na and Sylvie Liberman in :gh:`111835`.) + opcode ------ @@ -163,6 +240,27 @@ opcode 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 ------- @@ -170,13 +268,19 @@ 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`.) * Add *follow_symlinks* keyword-only argument to :meth:`pathlib.Path.glob`, - :meth:`~pathlib.Path.rglob`, :meth:`~pathlib.Path.is_file`, and - :meth:`~pathlib.Path.is_dir`. - (Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.) + :meth:`~pathlib.Path.rglob`, :meth:`~pathlib.Path.is_file`, + :meth:`~pathlib.Path.is_dir`, :meth:`~pathlib.Path.owner`, + :meth:`~pathlib.Path.group`. + (Contributed by Barney Gale in :gh:`77609` and :gh:`105793`, and + Kamil Turek in :gh:`107962`). pdb --- @@ -189,6 +293,16 @@ pdb identified and executed. (Contributed by Tian Gao in :gh:`108464`.) +* ``sys.path[0]`` will no longer be replaced by the directory of the script + being debugged when ``sys.flags.safe_path`` is set (via the :option:`-P` + command line option or :envvar:`PYTHONSAFEPATH` environment variable). + (Contributed by Tian Gao and Christian Walther in :gh:`111762`.) + +re +-- +* Rename :exc:`!re.error` to :exc:`re.PatternError` for improved clarity. + :exc:`!re.error` is kept for backward compatibility. + sqlite3 ------- @@ -196,6 +310,13 @@ sqlite3 object is not :meth:`closed ` explicitly. (Contributed by Erlend E. Aasland in :gh:`105539`.) +sys +--- + +* Add the :func:`sys._is_interned` function to test if the string was interned. + This function is not guaranteed to exist in all implementations of Python. + (Contributed by Serhiy Storchaka in :gh:`78573`.) + tkinter ------- @@ -205,6 +326,11 @@ tkinter :meth:`!tk_busy_current`, and :meth:`!tk_busy_status`. (Contributed by Miguel, klappnase and Serhiy Storchaka in :gh:`72684`.) +* Add support of the "vsapi" element type in + the :meth:`~tkinter.ttk.Style.element_create` method of + :class:`tkinter.ttk.Style`. + (Contributed by Serhiy Storchaka in :gh:`68166`.) + traceback --------- @@ -212,6 +338,12 @@ traceback to format the nested exceptions of a :exc:`BaseExceptionGroup` instance, recursively. (Contributed by Irit Katriel in :gh:`105292`.) +* Add the field *exc_type_str* to :class:`~traceback.TracebackException`, which + holds a string display of the *exc_type*. Deprecate the field *exc_type* + which holds the type object itself. Add parameter *save_exc_type* (default + ``True``) to indicate whether ``exc_type`` should be saved. + (Contributed by Irit Katriel in :gh:`112332`.) + typing ------ @@ -220,6 +352,12 @@ typing check whether a class is a :class:`typing.Protocol`. (Contributed by Jelle Zijlstra in :gh:`104873`.) +unicodedata +----------- + +* The Unicode database has been updated to version 15.1.0. (Contributed by + James Gerity in :gh:`109559`.) + venv ---- @@ -230,6 +368,15 @@ venv (using ``--without-scm-ignore-files``). (Contributed by Brett Cannon in :gh:`108125`.) +warnings +-------- + +* The new :func:`warnings.deprecated` decorator provides a way to communicate + deprecations to :term:`static type checkers ` and + to warn on usage of deprecated classes and functions. A runtime deprecation + warning may also be emitted when a decorated function or class is used at runtime. + See :pep:`702`. (Contributed by Jelle Zijlstra in :gh:`104003`.) + Optimizations ============= @@ -265,6 +412,11 @@ Deprecated security and functionality bugs. This includes removal of the ``--cgi`` flag to the ``python -m http.server`` command line in 3.15. +* :mod:`traceback`: + + * The field *exc_type* of :class:`traceback.TracebackException` is + deprecated. Use *exc_type_str* instead. + * :mod:`typing`: * Creating a :class:`typing.NamedTuple` class using keyword arguments to denote @@ -324,6 +476,24 @@ Deprecated 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`.) + +* Emit deprecation warning for non-integer numbers in :mod:`gettext` functions + and methods that consider plural forms even if the translation was not found. + (Contributed by Serhiy Storchaka in :gh:`88434`.) + +* Calling :meth:`frame.clear` on a suspended frame raises :exc:`RuntimeError` + (as has always been the case for an executing frame). + (Contributed by Irit Katriel in :gh:`79932`.) + +* Assignment to a function's :attr:`~function.__code__` attribute where the new code + object's type does not match the function's type, is deprecated. The + different types are: plain function, generator, async generator and + coroutine. + (Contributed by Irit Katriel in :gh:`81137`.) + Pending Removal in Python 3.14 ------------------------------ @@ -413,7 +583,8 @@ Pending Removal in Python 3.14 * date and datetime adapter, date and timestamp converter: see the :mod:`sqlite3` documentation for suggested replacement recipes. -* :class:`types.CodeType`: Accessing ``co_lnotab`` was deprecated in :pep:`626` +* :class:`types.CodeType`: Accessing :attr:`~codeobject.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. @@ -438,6 +609,13 @@ Pending Removal in Python 3.15 rarely used. No direct replacement exists. *Anything* is better than CGI to interface a web server with a request handler. +* :class:`locale`: :func:`locale.getdefaultlocale` was deprecated in Python 3.11 + and originally planned for removal in Python 3.13 (:gh:`90817`), + but removal has been postponed to Python 3.15. + Use :func:`locale.setlocale()`, :func:`locale.getencoding()` and + :func:`locale.getlocale()` instead. + (Contributed by Hugo van Kemenade in :gh:`111187`.) + * :class:`typing.NamedTuple`: * The undocumented keyword argument syntax for creating NamedTuple classes @@ -535,25 +713,6 @@ although there is currently no date scheduled for their removal. * ``EntryPoints`` tuple interface. * Implicit ``None`` on return values. -* :mod:`importlib.resources`: First parameter to files is renamed to 'anchor'. -* :mod:`importlib.resources` deprecated methods: - - * ``contents()`` - * ``is_resource()`` - * ``open_binary()`` - * ``open_text()`` - * ``path()`` - * ``read_binary()`` - * ``read_text()`` - - Use ``files()`` instead. Refer to `importlib-resources: Migrating from Legacy - `_ - for migration advice. - -* :func:`locale.getdefaultlocale`: use :func:`locale.setlocale()`, - :func:`locale.getencoding()` and :func:`locale.getlocale()` instead - (:gh:`90817`) - * :mod:`mailbox`: Use of StringIO input and text mode is deprecated, use BytesIO and binary mode instead. @@ -588,7 +747,7 @@ although there is currently no date scheduled for their removal. * :mod:`!sre_compile`, :mod:`!sre_constants` and :mod:`!sre_parse` modules. -* ``types.CodeType.co_lnotab``: use the ``co_lines`` attribute instead. +* :attr:`~codeobject.co_lnotab`: use the ``co_lines`` attribute instead. * :class:`typing.Text` (:gh:`92332`). @@ -638,178 +797,162 @@ although there is currently no date scheduled for their removal. Removed ======= -* :pep:`594`: Remove the :mod:`!telnetlib` module, deprecated in Python 3.11: - use the projects `telnetlib3 `_ or - `Exscript `_ instead. - (Contributed by Victor Stinner in :gh:`104773`.) - -* Remove the ``2to3`` program and the :mod:`!lib2to3` module, - deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104780`.) - -* Namespaces ``typing.io`` and ``typing.re``, deprecated in Python 3.8, - are now removed. The items in those namespaces can be imported directly - from :mod:`typing`. (Contributed by Sebastian Rittau in :gh:`92871`.) - -* Remove the untested and undocumented :mod:`webbrowser` :class:`!MacOSX` class, - deprecated in Python 3.11. - Use the :class:`!MacOSXOSAScript` class (introduced in Python 3.2) instead. - (Contributed by Hugo van Kemenade in :gh:`104804`.) +.. _whatsnew313-pep594: -* Remove support for using :class:`pathlib.Path` objects as context managers. - This functionality was deprecated and made a no-op in Python 3.9. +PEP 594: dead batteries +----------------------- -* Remove the undocumented :class:`!configparser.LegacyInterpolation` class, - deprecated in the docstring since Python 3.2, - and with a deprecation warning since Python 3.11. - (Contributed by Hugo van Kemenade in :gh:`104886`.) +* :pep:`594` removed 19 modules from the standard library, + deprecated in Python 3.11: -* Remove the :meth:`!turtle.RawTurtle.settiltangle` method, - deprecated in docs since Python 3.1 - and with a deprecation warning since Python 3.11. - (Contributed by Hugo van Kemenade in :gh:`104876`.) + * :mod:`!aifc`. + (Contributed by Victor Stinner in :gh:`104773`.) -* Removed the following :mod:`unittest` functions, deprecated in Python 3.11: + * :mod:`!audioop`. + (Contributed by Victor Stinner in :gh:`104773`.) - * :func:`!unittest.findTestCases` - * :func:`!unittest.makeSuite` - * :func:`!unittest.getTestCaseNames` + * :mod:`!chunk`. + (Contributed by Victor Stinner in :gh:`104773`.) - Use :class:`~unittest.TestLoader` methods instead: + * :mod:`!cgi` and :mod:`!cgitb`. - * :meth:`unittest.TestLoader.loadTestsFromModule` - * :meth:`unittest.TestLoader.loadTestsFromTestCase` - * :meth:`unittest.TestLoader.getTestCaseNames` + * ``cgi.FieldStorage`` can typically be replaced with + :func:`urllib.parse.parse_qsl` for ``GET`` and ``HEAD`` requests, + and the :mod:`email.message` module or `multipart + `__ PyPI project for ``POST`` and + ``PUT``. - (Contributed by Hugo van Kemenade in :gh:`104835`.) + * ``cgi.parse()`` can be replaced by calling :func:`urllib.parse.parse_qs` + directly on the desired query string, except for ``multipart/form-data`` + input, which can be handled as described for ``cgi.parse_multipart()``. -* :pep:`594`: Remove the :mod:`!cgi` and :mod:`!cgitb` modules, - deprecated in Python 3.11. + * ``cgi.parse_header()`` can be replaced with the functionality in the + :mod:`email` package, which implements the same MIME RFCs. For example, + with :class:`email.message.EmailMessage`:: - * ``cgi.FieldStorage`` can typically be replaced with - :func:`urllib.parse.parse_qsl` for ``GET`` and ``HEAD`` requests, and the - :mod:`email.message` module or `multipart - `__ PyPI project for ``POST`` and - ``PUT``. + from email.message import EmailMessage + msg = EmailMessage() + msg['content-type'] = 'application/json; charset="utf8"' + main, params = msg.get_content_type(), msg['content-type'].params - * ``cgi.parse()`` can be replaced by calling :func:`urllib.parse.parse_qs` - directly on the desired query string, except for ``multipart/form-data`` - input, which can be handled as described for ``cgi.parse_multipart()``. + * ``cgi.parse_multipart()`` can be replaced with the functionality in the + :mod:`email` package (e.g. :class:`email.message.EmailMessage` and + :class:`email.message.Message`) which implements the same MIME RFCs, or + with the `multipart `__ PyPI project. - * ``cgi.parse_multipart()`` can be replaced with the functionality in the - :mod:`email` package (e.g. :class:`email.message.EmailMessage` and - :class:`email.message.Message`) which implements the same MIME RFCs, or - with the `multipart `__ PyPI project. + (Contributed by Victor Stinner in :gh:`104773`.) - * ``cgi.parse_header()`` can be replaced with the functionality in the - :mod:`email` package, which implements the same MIME RFCs. For example, - with :class:`email.message.EmailMessage`:: + * :mod:`!crypt` module and its private :mod:`!_crypt` extension. + The :mod:`hashlib` module is a potential replacement for certain use cases. + Otherwise, the following PyPI projects can be used: - from email.message import EmailMessage - msg = EmailMessage() - msg['content-type'] = 'application/json; charset="utf8"' - main, params = msg.get_content_type(), msg['content-type'].params + * `bcrypt `_: + Modern password hashing for your software and your servers. + * `passlib `_: + Comprehensive password hashing framework supporting over 30 schemes. + * `argon2-cffi `_: + The secure Argon2 password hashing algorithm. + * `legacycrypt `_: + Wrapper to the POSIX crypt library call and associated functionality. - (Contributed by Victor Stinner in :gh:`104773`.) + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!sndhdr` module, deprecated in Python 3.11: use - the projects `filetype `_, `puremagic - `_, or `python-magic - `_ instead. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!imghdr`: use the projects + `filetype `_, + `puremagic `_, + or `python-magic `_ instead. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!pipes` module, deprecated in Python 3.11: - use the :mod:`subprocess` module instead. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!mailcap`. + The :mod:`mimetypes` module provides an alternative. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!ossaudiodev` module, deprecated in Python 3.11: - use the `pygame project `_ for audio playback. - (Contributed by Victor Stinner in :gh:`104780`.) + * :mod:`!msilib`. + (Contributed by Zachary Ware in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!sunau` module, deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!nis`. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!mailcap` module, deprecated in Python 3.11. - The :mod:`mimetypes` module provides an alternative. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!nntplib`: + the `PyPI nntplib project `_ + can be used instead. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!spwd` module, deprecated in Python 3.11: - the `python-pam project `_ can be used - instead. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!ossaudiodev`: use the + `pygame project `_ for audio playback. + (Contributed by Victor Stinner in :gh:`104780`.) -* :pep:`594`: Remove the :mod:`!nntplib` module, deprecated in Python 3.11: - the `PyPI nntplib project `_ can be used - instead. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!pipes`: use the :mod:`subprocess` module instead. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!nis` module, deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!sndhdr`: use the projects + `filetype `_, + `puremagic `_, or + `python-magic `_ instead. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!xdrlib` module, deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!spwd`: + the `python-pam project `_ + can be used instead. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!msilib` module, deprecated in Python 3.11. - (Contributed by Zachary Ware in :gh:`104773`.) + * :mod:`!sunau`. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!crypt` module and its private :mod:`!_crypt` - extension, deprecated in Python 3.11. - The :mod:`hashlib` module is a potential replacement for certain use cases. - Otherwise, the following PyPI projects can be used: + * :mod:`!telnetlib`, use the projects + `telnetlib3 `_ or + `Exscript `_ instead. + (Contributed by Victor Stinner in :gh:`104773`.) - * `bcrypt `_: - Modern password hashing for your software and your servers. - * `passlib `_: - Comprehensive password hashing framework supporting over 30 schemes. - * `argon2-cffi `_: - The secure Argon2 password hashing algorithm. - * `legacycrypt `_: - Wrapper to the POSIX crypt library call and associated functionality. + * :mod:`!uu`: the :mod:`base64` module is a modern alternative. + (Contributed by Victor Stinner in :gh:`104773`.) - (Contributed by Victor Stinner in :gh:`104773`.) + * :mod:`!xdrlib`. + (Contributed by Victor Stinner in :gh:`104773`.) -* :pep:`594`: Remove the :mod:`!uu` module, deprecated in Python 3.11: - the :mod:`base64` module is a modern alternative. - (Contributed by Victor Stinner in :gh:`104773`.) +2to3 +---- -* :pep:`594`: Remove the :mod:`!aifc` module, deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104773`.) +* Remove the ``2to3`` program and the :mod:`!lib2to3` module, + deprecated in Python 3.11. + (Contributed by Victor Stinner in :gh:`104780`.) -* :pep:`594`: Remove the :mod:`!audioop` module, deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104773`.) +configparser +------------ -* :pep:`594`: Remove the :mod:`!chunk` module, deprecated in Python 3.11. - (Contributed by Victor Stinner in :gh:`104773`.) +* Remove the undocumented :class:`!configparser.LegacyInterpolation` class, + deprecated in the docstring since Python 3.2, + and with a deprecation warning since Python 3.11. + (Contributed by Hugo van Kemenade in :gh:`104886`.) -* Remove support for the keyword-argument method of creating - :class:`typing.TypedDict` types, deprecated in Python 3.11. - (Contributed by Tomas Roun in :gh:`104786`.) +importlib +--------- -* :pep:`594`: Remove the :mod:`!imghdr` module, deprecated in Python 3.11: - use the projects - `filetype `_, - `puremagic `_, - or `python-magic `_ instead. - (Contributed by Victor Stinner in :gh:`104773`.) +* Remove :mod:`importlib.resources` deprecated methods: -* Remove the untested and undocumented :meth:`!unittest.TestProgram.usageExit` - method, deprecated in Python 3.11. - (Contributed by Hugo van Kemenade in :gh:`104992`.) + * ``contents()`` + * ``is_resource()`` + * ``open_binary()`` + * ``open_text()`` + * ``path()`` + * ``read_binary()`` + * ``read_text()`` -* Remove the :mod:`!tkinter.tix` module, deprecated in Python 3.6. The - third-party Tix library which the module wrapped is unmaintained. - (Contributed by Zachary Ware in :gh:`75552`.) + Use :func:`importlib.resources.files()` instead. Refer to `importlib-resources: Migrating from Legacy + `_ + for migration advice. + (Contributed by Jason R. Coombs in :gh:`106532`.) -* 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``. The new macros were - added in Python 3.8 and the old macros were deprecated in Python 3.11. - (Contributed by Irit Katriel in :gh:`105111`.) +locale +------ * Remove ``locale.resetlocale()`` function deprecated in Python 3.11: use ``locale.setlocale(locale.LC_ALL, "")`` instead. (Contributed by Victor Stinner in :gh:`104783`.) +logging +------- + * :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` @@ -817,6 +960,69 @@ Removed :func:`logging.warning` function. (Contributed by Victor Stinner in :gh:`105376`.) +pathlib +------- + +* Remove support for using :class:`pathlib.Path` objects as context managers. + This functionality was deprecated and made a no-op in Python 3.9. + +re +-- + +* Remove undocumented, never working, and deprecated ``re.template`` function + and ``re.TEMPLATE`` flag (and ``re.T`` alias). + (Contributed by Serhiy Storchaka and Nikita Sobolev in :gh:`105687`.) + +tkinter +------- + +* Remove the :mod:`!tkinter.tix` module, deprecated in Python 3.6. The + third-party Tix library which the module wrapped is unmaintained. + (Contributed by Zachary Ware in :gh:`75552`.) + +turtle +------ + +* Remove the :meth:`!turtle.RawTurtle.settiltangle` method, + deprecated in docs since Python 3.1 + and with a deprecation warning since Python 3.11. + (Contributed by Hugo van Kemenade in :gh:`104876`.) + +typing +------ + +* Namespaces ``typing.io`` and ``typing.re``, deprecated in Python 3.8, + are now removed. The items in those namespaces can be imported directly + from :mod:`typing`. (Contributed by Sebastian Rittau in :gh:`92871`.) + +* Remove support for the keyword-argument method of creating + :class:`typing.TypedDict` types, deprecated in Python 3.11. + (Contributed by Tomas Roun in :gh:`104786`.) + +unittest +-------- + +* 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` + + (Contributed by Hugo van Kemenade in :gh:`104835`.) + +* Remove the untested and undocumented :meth:`!unittest.TestProgram.usageExit` + method, deprecated in Python 3.11. + (Contributed by Hugo van Kemenade in :gh:`104992`.) + +urllib +------ + * Remove *cafile*, *capath* and *cadefault* parameters of the :func:`urllib.request.urlopen` function, deprecated in Python 3.6: use the *context* parameter instead. Please use @@ -825,15 +1031,32 @@ Removed certificates for you. (Contributed by Victor Stinner in :gh:`105382`.) +webbrowser +---------- + +* Remove the untested and undocumented :mod:`webbrowser` :class:`!MacOSX` class, + deprecated in Python 3.11. + Use the :class:`!MacOSXOSAScript` class (introduced in Python 3.2) instead. + (Contributed by Hugo van Kemenade in :gh:`104804`.) + * Remove deprecated ``webbrowser.MacOSXOSAScript._name`` attribute. Use :attr:`webbrowser.MacOSXOSAScript.name ` attribute instead. (Contributed by Nikita Sobolev in :gh:`105546`.) -* Remove undocumented, never working, and deprecated ``re.template`` function - and ``re.TEMPLATE`` flag (and ``re.T`` alias). - (Contributed by Serhiy Storchaka and Nikita Sobolev in :gh:`105687`.) +Others +------ + +* None yet +CPython bytecode changes +======================== + +* The oparg of ``YIELD_VALUE`` is now ``1`` if the yield is part of a + yield-from or await, and ``0`` otherwise. The oparg of ``RESUME`` was + changed to add a bit indicating whether the except-depth is 1, which + is needed to optimize closing of generators. + (Contributed by Irit Katriel in :gh:`111354`.) Porting to Python 3.13 ====================== @@ -841,34 +1064,38 @@ Porting to Python 3.13 This section lists previously described changes and other bugfixes that may require changes to your code. -* The old trashcan macros ``Py_TRASHCAN_SAFE_BEGIN`` and ``Py_TRASHCAN_SAFE_END`` - were removed. They should be replaced by the new macros ``Py_TRASHCAN_BEGIN`` - and ``Py_TRASHCAN_END``. +Changes in the Python API +------------------------- - A tp_dealloc function that has the old macros, such as:: +* :meth:`!tkinter.Text.count` now always returns an integer if one or less + counting options are specified. + Previously it could return a single count as a 1-tuple, an integer (only if + option ``"update"`` was specified) or ``None`` if no items found. + The result is now the same if ``wantobjects`` is set to ``0``. + (Contributed by Serhiy Storchaka in :gh:`97928`.) - static void - mytype_dealloc(mytype *p) - { - PyObject_GC_UnTrack(p); - Py_TRASHCAN_SAFE_BEGIN(p); - ... - Py_TRASHCAN_SAFE_END - } +* Functions :c:func:`PyDict_GetItem`, :c:func:`PyDict_GetItemString`, + :c:func:`PyMapping_HasKey`, :c:func:`PyMapping_HasKeyString`, + :c:func:`PyObject_HasAttr`, :c:func:`PyObject_HasAttrString`, and + :c:func:`PySys_GetObject`, which clear all errors occurred during calling + the function, report now them using :func:`sys.unraisablehook`. + You can consider to replace these functions with other functions as + recomended in the documentation. + (Contributed by Serhiy Storchaka in :gh:`106672`.) - should migrate to the new macros as follows:: +* An :exc:`OSError` is now raised by :func:`getpass.getuser` for any failure to + retrieve a username, instead of :exc:`ImportError` on non-Unix platforms or + :exc:`KeyError` on Unix platforms where the password database is empty. - static void - mytype_dealloc(mytype *p) - { - PyObject_GC_UnTrack(p); - Py_TRASHCAN_BEGIN(p, mytype_dealloc) - ... - Py_TRASHCAN_END - } +* The :mod:`threading` module now expects the :mod:`!_thread` module to have + an ``_is_main_interpreter`` attribute. It is a function with no + arguments that returns ``True`` if the current interpreter is the + main interpreter. - Note that ``Py_TRASHCAN_BEGIN`` has a second argument which - should be the deallocation function it is in. + Any library or application that provides a custom ``_thread`` module + must provide ``_is_main_interpreter()``, just like the module's + other "private" attributes. + (See :gh:`112826`.) Build Changes @@ -889,6 +1116,12 @@ Build Changes * Building CPython now requires a compiler with support for the C11 atomic library, GCC built-in atomic functions, or MSVC interlocked intrinsics. +* The ``errno``, ``md5``, ``resource``, ``winsound``, ``_ctypes_test``, + ``_multiprocessing.posixshmem``, ``_scproxy``, ``_stat``, + ``_testimportmultiple`` and ``_uuid`` C extensions are now built with the + :ref:`limited C API `. + (Contributed by Victor Stinner in :gh:`85283`.) + C API Changes ============= @@ -902,6 +1135,16 @@ New Features APIs accepting the format codes always use ``Py_ssize_t`` for ``#`` formats. (Contributed by Inada Naoki in :gh:`104922`.) +* The *keywords* parameter of :c:func:`PyArg_ParseTupleAndKeywords` and + :c:func:`PyArg_VaParseTupleAndKeywords` has now type :c:expr:`char * const *` + in C and :c:expr:`const char * const *` in C++, instead of :c:expr:`char **`. + It makes these functions compatible with arguments of type + :c:expr:`const char * const *`, :c:expr:`const char **` or + :c:expr:`char * const *` in C++ and :c:expr:`char * const *` in C + without an explicit type cast. + This can be overridden with the :c:macro:`PY_CXX_CONST` macro. + (Contributed by Serhiy Storchaka in :gh:`65210`.) + * Add :c:func:`PyImport_AddModuleRef`: similar to :c:func:`PyImport_AddModule`, but return a :term:`strong reference` instead of a :term:`borrowed reference`. @@ -943,7 +1186,6 @@ New Features * 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. (Contributed by Victor Stinner in :gh:`106168`.) * Add :c:func:`PyModule_Add` function: similar to @@ -977,6 +1219,62 @@ New Features 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`.) + +* :c:func:`PyArg_ParseTupleAndKeywords` now supports non-ASCII keyword + parameter names. + (Contributed by Serhiy Storchaka in :gh:`110815`.) + +* Add :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawCalloc`, + :c:func:`PyMem_RawRealloc` and :c:func:`PyMem_RawFree` to the limited C API + (version 3.13). + (Contributed by Victor Stinner in :gh:`85283`.) + +* Add :c:func:`PySys_Audit` and :c:func:`PySys_AuditTuple` functions to the + limited C API. + (Contributed by Victor Stinner in :gh:`85283`.) + +* Add :c:func:`PyErr_FormatUnraisable` function: similar to + :c:func:`PyErr_WriteUnraisable`, but allow to customize the warning mesage. + (Contributed by Serhiy Storchaka in :gh:`108082`.) + +* Add :c:func:`PyList_Extend` and :c:func:`PyList_Clear` functions: similar to + Python ``list.extend()`` and ``list.clear()`` methods. + (Contributed by Victor Stinner in :gh:`111138`.) + +* Add :c:func:`PyDict_Pop` and :c:func:`PyDict_PopString` functions: remove a + key from a dictionary and optionally return the removed value. This is + similar to :meth:`dict.pop`, but without the default value and not raising + :exc:`KeyError` if the key missing. + (Contributed by Stefan Behnel and Victor Stinner in :gh:`111262`.) + +* Add :c:func:`Py_HashPointer` function to hash a pointer. + (Contributed by Victor Stinner in :gh:`111545`.) + + Porting to Python 3.13 ---------------------- @@ -986,11 +1284,6 @@ Porting to Python 3.13 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: ``close()``, ``getpagesize()``, ``getpid()`` and ``sysconf()``. - (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 @@ -999,13 +1292,48 @@ Porting to Python 3.13 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`. +* 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`.) + +* The old trashcan macros ``Py_TRASHCAN_SAFE_BEGIN`` and ``Py_TRASHCAN_SAFE_END`` + were removed. They should be replaced by the new macros ``Py_TRASHCAN_BEGIN`` + and ``Py_TRASHCAN_END``. + + A tp_dealloc function that has the old macros, such as:: + + static void + mytype_dealloc(mytype *p) + { + PyObject_GC_UnTrack(p); + Py_TRASHCAN_SAFE_BEGIN(p); + ... + Py_TRASHCAN_SAFE_END + } + + should migrate to the new macros as follows:: + + static void + mytype_dealloc(mytype *p) + { + PyObject_GC_UnTrack(p); + Py_TRASHCAN_BEGIN(p, mytype_dealloc) + ... + Py_TRASHCAN_END + } + + Note that ``Py_TRASHCAN_BEGIN`` has a second argument which + should be the deallocation function it is in. + +* On Windows, ``Python.h`` no longer includes the ```` standard + header file. If needed, it should now be included explicitly. For example, it + provides ``offsetof()`` function, and ``size_t`` and ``ptrdiff_t`` types. + Including ```` explicitly was already needed by all other + platforms, the ``HAVE_STDDEF_H`` macro is only defined on Windows. (Contributed by Victor Stinner in :gh:`108765`.) + Deprecated ---------- @@ -1052,6 +1380,14 @@ Deprecated Removed ------- +* Removed chained :class:`classmethod` descriptors (introduced in + :issue:`19072`). This can no longer be used to wrap other descriptors + such as :class:`property`. The core design of this feature was flawed + and caused a number of downstream problems. To "pass-through" a + :class:`classmethod`, consider using the :attr:`!__wrapped__` + attribute that was added in Python 3.10. (Contributed by Raymond + Hettinger in :gh:`89519`.) + * 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 @@ -1078,37 +1414,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`.) @@ -1134,6 +1470,12 @@ Removed Configuration ` instead (:pep:`587`), added to Python 3.8. (Contributed by Victor Stinner in :gh:`105145`.) +* 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``. The new macros were + added in Python 3.8 and the old macros were deprecated in Python 3.11. + (Contributed by Irit Katriel in :gh:`105111`.) + * Remove ``PyEval_InitThreads()`` and ``PyEval_ThreadsInitialized()`` functions, deprecated in Python 3.9. Since Python 3.7, ``Py_Initialize()`` always creates the GIL: calling ``PyEval_InitThreads()`` did nothing and @@ -1150,20 +1492,6 @@ Removed (Contributed by Victor Stinner in :gh:`105182`.) -* 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. - (Contributed by Victor Stinner in :gh:`106084`.) - * Remove private ``_PyObject_FastCall()`` function: use ``PyObject_Vectorcall()`` which is available since Python 3.8 (:pep:`590`). @@ -1267,3 +1595,16 @@ 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`.) + + +Regression Test Changes +======================= + +* Python built with :file:`configure` :option:`--with-pydebug` now + supports a :option:`-X presite=package.module <-X>` command-line + option. If used, it specifies a module that should be imported early + in the lifecycle of the interpreter, before ``site.py`` is executed. + (Contributed by Łukasz Langa in :gh:`110769`.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index df32b76b6d7b03..5ef76968e9d86b 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -791,8 +791,9 @@ functools * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute pointing to the original callable function. This allows wrapped functions to - be introspected. It also copies :attr:`__annotations__` if defined. And now - it also gracefully skips over missing attributes such as :attr:`__doc__` which + be introspected. It also copies :attr:`~function.__annotations__` if + defined. And now it also gracefully skips over missing attributes such as + :attr:`~function.__doc__` which might not be defined for the wrapped callable. In the above example, the cache can be removed by recovering the original diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index e440193d6f3d29..5674bc7f359b72 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -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: @@ -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 diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 2ddab76814369e..72d12461d8f730 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -1936,7 +1936,7 @@ Other Improvements * The :ref:`python ` command has a new :ref:`option `, ``-I``, which causes it to run in "isolated mode", which means that :data:`sys.path` contains neither the script's directory nor - the user's ``site-packages`` directory, and all :envvar:`PYTHON*` environment + the user's ``site-packages`` directory, and all :envvar:`!PYTHON*` environment variables are ignored (it implies both ``-s`` and ``-E``). Other restrictions may also be applied in the future, with the goal being to isolate the execution of a script from the user's environment. This is @@ -2405,8 +2405,8 @@ Changes in the Python API storage). (:issue:`17094`.) * Parameter names in ``__annotations__`` dicts are now mangled properly, - similarly to ``__kwdefaults__``. (Contributed by Yury Selivanov in - :issue:`20625`.) + similarly to :attr:`~function.__kwdefaults__`. + (Contributed by Yury Selivanov in :issue:`20625`.) * :attr:`hashlib.hash.name` now always returns the identifier in lower case. Previously some builtin hashes had uppercase names, but now that it is a diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index ae6affcab664c6..a32866094ffeb5 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -1947,7 +1947,8 @@ traceback --------- New :func:`~traceback.walk_stack` and :func:`~traceback.walk_tb` -functions to conveniently traverse frame and traceback objects. +functions to conveniently traverse frame and +:ref:`traceback objects `. (Contributed by Robert Collins in :issue:`17911`.) New lightweight classes: :class:`~traceback.TracebackException`, diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index c15d8be651fd17..5a3cea0ec87cb2 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -2160,14 +2160,15 @@ Changes in the Python API * :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg** argument is not set. Previously only ``NULL`` was returned. -* The format of the ``co_lnotab`` attribute of code objects changed to support +* The format of the :attr:`~codeobject.co_lnotab` attribute of code objects + changed to support a negative line number delta. By default, Python does not emit bytecode with - a negative line number delta. Functions using ``frame.f_lineno``, + a negative line number delta. Functions using :attr:`frame.f_lineno`, ``PyFrame_GetLineNumber()`` or ``PyCode_Addr2Line()`` are not affected. - Functions directly decoding ``co_lnotab`` should be updated to use a signed + Functions directly decoding :attr:`!co_lnotab` should be updated to use a signed 8-bit integer type for the line number delta, but this is only required to support applications using a negative line number delta. See - ``Objects/lnotab_notes.txt`` for the ``co_lnotab`` format and how to decode + ``Objects/lnotab_notes.txt`` for the :attr:`!co_lnotab` format and how to decode it, and see the :pep:`511` for the rationale. * The functions in the :mod:`compileall` module now return booleans instead diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index eb083737b0b7ed..616e51571388a8 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -525,8 +525,8 @@ Other Language Changes * In order to better support dynamic creation of stack traces, :class:`types.TracebackType` can now be instantiated from Python code, and - the ``tb_next`` attribute on :ref:`tracebacks ` is now - writable. + the :attr:`~traceback.tb_next` attribute on + :ref:`tracebacks ` is now writable. (Contributed by Nathaniel J. Smith in :issue:`30579`.) * When using the :option:`-m` switch, ``sys.path[0]`` is now eagerly expanded @@ -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) @@ -1891,7 +1891,7 @@ Other CPython Implementation Changes * Trace hooks may now opt out of receiving the ``line`` and opt into receiving the ``opcode`` events from the interpreter by setting the corresponding new - ``f_trace_lines`` and ``f_trace_opcodes`` attributes on the + :attr:`~frame.f_trace_lines` and :attr:`~frame.f_trace_opcodes` attributes on the frame being traced. (Contributed by Nick Coghlan in :issue:`31344`.) * Fixed some consistency problems with namespace package module attributes. @@ -2144,9 +2144,9 @@ The following features and APIs have been removed from Python 3.7: * Removed support of the *exclude* argument in :meth:`tarfile.TarFile.add`. It was deprecated in Python 2.7 and 3.2. Use the *filter* argument instead. -* The ``splitunc()`` function in the :mod:`ntpath` module was deprecated in - Python 3.1, and has now been removed. Use the :func:`~os.path.splitdrive` - function instead. +* The :func:`!ntpath.splitunc` function was deprecated in + Python 3.1, and has now been removed. Use :func:`~os.path.splitdrive` + instead. * :func:`collections.namedtuple` no longer supports the *verbose* parameter or ``_source`` attribute which showed the generated source code for the diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index e15180c89f594c..e4dcb9bf872e28 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 @@ -1653,7 +1653,7 @@ Deprecated deprecated and will be prohibited in Python 3.9. (Contributed by Elvis Pranskevichus in :issue:`34075`.) -* The :meth:`__getitem__` methods of :class:`xml.dom.pulldom.DOMEventStream`, +* The :meth:`~object.__getitem__` methods of :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` and :class:`fileinput.FileInput` have been deprecated. diff --git a/Grammar/python.gram b/Grammar/python.gram index 73aaa796b075bc..c9269b058bc7f6 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -124,6 +124,7 @@ simple_stmt[stmt_ty] (memo): | &'nonlocal' nonlocal_stmt compound_stmt[stmt_ty]: + | invalid_compound_stmt | &('def' | '@' | 'async') function_def | &'if' if_stmt | &('class' | '@') class_def @@ -391,8 +392,8 @@ for_stmt[stmt_ty]: with_stmt[stmt_ty]: | invalid_with_stmt_indent - | 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { - 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 { + CHECK_VERSION(stmt_ty, 9, "Parenthesized context managers are", _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), 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 { @@ -1128,7 +1129,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 { @@ -1297,6 +1299,10 @@ invalid_import_from_targets: | import_from_as_names ',' NEWLINE { RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") } +invalid_compound_stmt: + | a='elif' named_expression ':' { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "'elif' must match an if-statement here") } + | a='else' ':' { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "'else' must match a valid statement here") } + 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 ':'") } @@ -1368,11 +1374,11 @@ invalid_for_stmt: | ['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 [type_params] '(' [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 ':'") } - | a='class' NAME ['(' [arguments] ')'] ':' NEWLINE !INDENT { + | 'class' NAME [type_params] ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | a='class' NAME [type_params] ['(' [arguments] ')'] ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) } invalid_double_starred_kvpairs: diff --git a/Include/Python.h b/Include/Python.h index 7312cc87d5cc33..196751c3201e62 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -22,22 +22,28 @@ #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 -// 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. +// , , and headers are no longer used +// by Python, but kept for the backward compatibility of existing third party C +// extensions. They are not included by limited C API version 3.11 and newer. +// +// The and headers are not included by limited C API +// version 3.13 and newer. #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 # include // errno # include // FILE* # include // getenv() # include // memcpy() #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000 +# include // tolower() +# ifndef MS_WINDOWS +# include // close() +# endif +#endif // Include Python header files diff --git a/Include/boolobject.h b/Include/boolobject.h index 976fa35201d035..19aef5b1b87c6a 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -7,7 +7,7 @@ extern "C" { #endif -PyAPI_DATA(PyTypeObject) PyBool_Type; +// PyBool_Type is declared by object.h #define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type) diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 1f495f19df280b..4e7b7a46703a6d 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -2,6 +2,28 @@ # error "this header file must not be included directly" #endif +/* === Object Protocol ================================================== */ + +/* Like PyObject_CallMethod(), but expect a _Py_Identifier* + as the method name. */ +PyAPI_FUNC(PyObject*) _PyObject_CallMethodId( + PyObject *obj, + _Py_Identifier *name, + const char *format, ...); + +/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) + format to a Python dictionary ("kwargs" dict). + + The type of kwnames keys is not checked. The final function getting + arguments is responsible to check if all keys are strings, for example using + PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). + + Duplicate keys are merged using the last value. If duplicate keys must raise + an exception, the caller is responsible to implement an explicit keys on + kwnames. */ +PyAPI_FUNC(PyObject*) _PyStack_AsDict(PyObject *const *values, PyObject *kwnames); + + /* === Vectorcall protocol (PEP 590) ============================= */ // PyVectorcall_NARGS() is exported as a function for the stable ABI. @@ -16,6 +38,16 @@ _PyVectorcall_NARGS(size_t n) PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); +// Backwards compatibility aliases (PEP 590) for API that was provisional +// in Python 3.8 +#define _PyObject_Vectorcall PyObject_Vectorcall +#define _PyObject_VectorcallMethod PyObject_VectorcallMethod +#define _PyObject_FastCallDict PyObject_VectorcallDict +#define _PyVectorcall_Function PyVectorcall_Function +#define _PyObject_CallOneArg PyObject_CallOneArg +#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs +#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg + /* Same as PyObject_Vectorcall except that keyword arguments are passed as dict, which may be NULL if there are no keyword arguments. */ PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 45b09a1265df80..cf715c55a2b3b8 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -167,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 265f5397b45116..0d587505ef7f85 100644 --- a/Include/cpython/compile.h +++ b/Include/cpython/compile.h @@ -68,15 +68,3 @@ typedef struct { #define PY_INVALID_STACK_EFFECT INT_MAX PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg); PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump); - -PyAPI_FUNC(int) PyUnstable_OpcodeIsValid(int opcode); -PyAPI_FUNC(int) PyUnstable_OpcodeHasArg(int opcode); -PyAPI_FUNC(int) PyUnstable_OpcodeHasConst(int opcode); -PyAPI_FUNC(int) PyUnstable_OpcodeHasName(int opcode); -PyAPI_FUNC(int) PyUnstable_OpcodeHasJump(int opcode); -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/complexobject.h b/Include/cpython/complexobject.h index b524ec42c24371..fbdc6a91fe895c 100644 --- a/Include/cpython/complexobject.h +++ b/Include/cpython/complexobject.h @@ -7,6 +7,16 @@ typedef struct { double imag; } Py_complex; +// Operations on complex numbers. +PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) _Py_c_abs(Py_complex); + + /* Complex object interface */ /* diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index b05ca3ef453816..944965fb9e5351 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -32,6 +32,9 @@ typedef struct { PyDictValues *ma_values; } PyDictObject; +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyDict_SetDefault( PyObject *mp, PyObject *key, PyObject *defaultobj); @@ -46,6 +49,11 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key); +PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); + +PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result); +PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result); +PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value); /* Dictionary watchers */ diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index ee130467824daa..87c059c521cbc9 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -180,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; @@ -204,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. @@ -220,6 +225,12 @@ typedef struct PyConfig { // If non-zero, turns on statistics gathering. int _pystats; #endif + +#ifdef Py_DEBUG + // If not empty, import a non-__main__ module before site.py is executed. + // PYTHON_PRESITE=package.module or -X presite=package.module + wchar_t *run_presite; +#endif } PyConfig; PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index 661610548733fd..8ade1b164681f9 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -39,8 +39,11 @@ static inline void PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { PyListObject *list = _PyList_CAST(op); assert(0 <= index); - assert(index < Py_SIZE(list)); + assert(index < list->allocated); list->ob_item[index] = value; } #define PyList_SET_ITEM(op, index, value) \ PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) + +PyAPI_FUNC(int) PyList_Extend(PyObject *self, PyObject *iterable); +PyAPI_FUNC(int) PyList_Clear(PyObject *self); diff --git a/Include/cpython/longintrepr.h b/Include/cpython/longintrepr.h index fb82f83dc50e42..f5ccbb704e8bb8 100644 --- a/Include/cpython/longintrepr.h +++ b/Include/cpython/longintrepr.h @@ -89,6 +89,16 @@ 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 57834173490c99..fd1be29ed397d1 100644 --- a/Include/cpython/longobject.h +++ b/Include/cpython/longobject.h @@ -7,3 +7,50 @@ 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); +// _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_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); + +/* For use by the gcd function in mathmodule.c */ +PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h deleted file mode 100644 index cfc2c2cdb5a7f4..00000000000000 --- a/Include/cpython/modsupport.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef Py_CPYTHON_MODSUPPORT_H -# error "this header file must not be included directly" -#endif - -PyAPI_FUNC(int) _PyArg_UnpackStack( - PyObject *const *args, - Py_ssize_t nargs, - const char *name, - Py_ssize_t min, - Py_ssize_t max, - ...); - -PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); -PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); -#define _PyArg_NoKeywords(funcname, kwargs) \ - ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) -#define _PyArg_NoPositional(funcname, args) \ - ((args) == NULL || _PyArg_NoPositional((funcname), (args))) - -#define _Py_ANY_VARARGS(n) ((n) == PY_SSIZE_T_MAX) - -PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); -PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, - Py_ssize_t, Py_ssize_t); -#define _PyArg_CheckPositional(funcname, nargs, min, max) \ - ((!_Py_ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ - || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) - -typedef struct _PyArg_Parser { - int initialized; - const char *format; - const char * const *keywords; - const char *fname; - const char *custom_msg; - int pos; /* number of positional-only arguments */ - int min; /* minimal number of arguments */ - int max; /* maximal number of positional arguments */ - PyObject *kwtuple; /* tuple of keyword parameter names */ - struct _PyArg_Parser *next; -} _PyArg_Parser; - -PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_ParseStack( - PyObject *const *args, - Py_ssize_t nargs, - const char *format, - ...); -PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( - PyObject *const *args, - Py_ssize_t nargs, - PyObject *kwnames, - struct _PyArg_Parser *, - ...); -PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - PyObject **buf); - -PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - int vararg, PyObject **buf); - -#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ - (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ - (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \ - _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ - (minpos), (maxpos), (minkw), (buf))) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index e5987191cfe08c..762e8a3b86ee1e 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -14,6 +14,44 @@ 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 @@ -238,6 +276,8 @@ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *); + PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); @@ -425,7 +465,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; \ } \ @@ -444,8 +484,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 47536108a9665e..d521eac79d1b97 100644 --- a/Include/cpython/optimizer.h +++ b/Include/cpython/optimizer.h @@ -6,15 +6,33 @@ extern "C" { #endif +typedef struct _PyExecutorLinkListNode { + struct _PyExecutorObject *next; + struct _PyExecutorObject *previous; +} _PyExecutorLinkListNode; + + +/* Bloom filter with m = 256 + * https://en.wikipedia.org/wiki/Bloom_filter */ +#define BLOOM_FILTER_WORDS 8 + +typedef struct _bloom_filter { + uint32_t bits[BLOOM_FILTER_WORDS]; +} _PyBloomFilter; + typedef struct { uint8_t opcode; uint8_t oparg; + uint8_t valid; + uint8_t linked; + _PyBloomFilter bloom; + _PyExecutorLinkListNode links; } _PyVMData; typedef struct _PyExecutorObject { 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); + _Py_CODEUNIT *(*execute)(struct _PyExecutorObject *self, struct _PyInterpreterFrame *frame, PyObject **stack_pointer); _PyVMData vm_data; /* Used by the VM, but opaque to the optimizer */ /* Data needed by the executor goes here, but is opaque to the VM */ } _PyExecutorObject; @@ -27,6 +45,8 @@ typedef int (*optimize_func)(_PyOptimizerObject* self, PyCodeObject *code, _Py_C typedef struct _PyOptimizerObject { PyObject_HEAD optimize_func optimize; + /* These thresholds are treated as signed so do not exceed INT16_MAX + * Use INT16_MAX to indicate that the optimizer should never be called */ uint16_t resume_threshold; uint16_t backedge_threshold; /* Data needed by the optimizer goes here, but is opaque to the VM */ @@ -45,11 +65,21 @@ _PyOptimizer_BackEdge(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_ extern _PyOptimizerObject _PyOptimizer_Default; +void _Py_ExecutorInit(_PyExecutorObject *, _PyBloomFilter *); +void _Py_ExecutorClear(_PyExecutorObject *); +void _Py_BloomFilter_Init(_PyBloomFilter *); +void _Py_BloomFilter_Add(_PyBloomFilter *bloom, void *obj); +PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj); +PyAPI_FUNC(void) _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj); +extern void _Py_Executors_InvalidateAll(PyInterpreterState *interp); + /* For testing */ PyAPI_FUNC(PyObject *)PyUnstable_Optimizer_NewCounter(void); PyAPI_FUNC(PyObject *)PyUnstable_Optimizer_NewUOpOptimizer(void); #define OPTIMIZER_BITS_IN_COUNTER 4 +/* Minimum of 16 additional executions before retry */ +#define MINIMUM_TIER2_BACKOFF 4 #ifdef __cplusplus } diff --git a/Include/cpython/pthread_stubs.h b/Include/cpython/pthread_stubs.h index d95ee03d8308ce..e542eaa5bff0cf 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; @@ -67,6 +83,7 @@ PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread, void *(*start_routine)(void *), void *restrict arg); PyAPI_FUNC(int) pthread_detach(pthread_t thread); +PyAPI_FUNC(int) pthread_join(pthread_t thread, void** value_ptr); PyAPI_FUNC(pthread_t) pthread_self(void); PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__)); PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr); diff --git a/Include/cpython/pyatomic.h b/Include/cpython/pyatomic.h index 7a783058c173aa..5314a70436bfc3 100644 --- a/Include/cpython/pyatomic.h +++ b/Include/cpython/pyatomic.h @@ -463,6 +463,12 @@ _Py_atomic_load_ptr_acquire(const void *obj); static inline void _Py_atomic_store_ptr_release(void *obj, void *value); +static inline void +_Py_atomic_store_int_release(int *obj, int value); + +static inline int +_Py_atomic_load_int_acquire(const int *obj); + // --- _Py_atomic_fence ------------------------------------------------------ diff --git a/Include/cpython/pyatomic_gcc.h b/Include/cpython/pyatomic_gcc.h index f1a38c7b52871a..70f2b7e1b5706a 100644 --- a/Include/cpython/pyatomic_gcc.h +++ b/Include/cpython/pyatomic_gcc.h @@ -487,6 +487,14 @@ static inline void _Py_atomic_store_ptr_release(void *obj, void *value) { __atomic_store_n((void **)obj, value, __ATOMIC_RELEASE); } +static inline void +_Py_atomic_store_int_release(int *obj, int value) +{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); } + +static inline int +_Py_atomic_load_int_acquire(const int *obj) +{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); } + // --- _Py_atomic_fence ------------------------------------------------------ diff --git a/Include/cpython/pyatomic_msc.h b/Include/cpython/pyatomic_msc.h index 287ed43b5714cd..601a0cf65afc1c 100644 --- a/Include/cpython/pyatomic_msc.h +++ b/Include/cpython/pyatomic_msc.h @@ -912,6 +912,32 @@ _Py_atomic_store_ptr_release(void *obj, void *value) #endif } +static inline void +_Py_atomic_store_int_release(int *obj, int value) +{ +#if defined(_M_X64) || defined(_M_IX86) + *(int volatile *)obj = value; +#elif defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(unsigned __int32); + __stlr32((unsigned __int32 volatile *)obj, (unsigned __int32)value); +#else +# error "no implementation of _Py_atomic_store_int_release" +#endif +} + +static inline int +_Py_atomic_load_int_acquire(const int *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(int volatile *)obj; +#elif defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(unsigned __int32); + return (int)__ldar32((unsigned __int32 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_int_acquire" +#endif +} + // --- _Py_atomic_fence ------------------------------------------------------ diff --git a/Include/cpython/pyatomic_std.h b/Include/cpython/pyatomic_std.h index bf74a90887c634..a05bfaec47e89d 100644 --- a/Include/cpython/pyatomic_std.h +++ b/Include/cpython/pyatomic_std.h @@ -854,6 +854,23 @@ _Py_atomic_store_ptr_release(void *obj, void *value) memory_order_release); } +static inline void +_Py_atomic_store_int_release(int *obj, int value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int)*)obj, value, + memory_order_release); +} + +static inline int +_Py_atomic_load_int_acquire(const int *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(int)*)obj, + memory_order_acquire); +} + + // --- _Py_atomic_fence ------------------------------------------------------ diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index da96eec4b35aab..479b908fb7058a 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -120,4 +120,6 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc( const char *func, const char *message); +PyAPI_FUNC(void) PyErr_FormatUnraisable(const char *, ...); + #define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message)) diff --git a/Include/cpython/pyhash.h b/Include/cpython/pyhash.h new file mode 100644 index 00000000000000..396c208e1b106a --- /dev/null +++ b/Include/cpython/pyhash.h @@ -0,0 +1,39 @@ +#ifndef Py_CPYTHON_HASH_H +# error "this header file must not be included directly" +#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 + +/* Helpers for hash functions */ +PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double); + +// Kept for backward compatibility +#define _Py_HashPointer Py_HashPointer + + +/* hash function definition */ +typedef struct { + Py_hash_t (*const hash)(const void *, Py_ssize_t); + const char *name; + const int hash_bits; + const int seed_bits; +} PyHash_FuncDef; + +PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); + +PyAPI_FUNC(Py_hash_t) Py_HashPointer(const void *ptr); diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 11b280afa8435b..d425a233f71000 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -81,5 +81,3 @@ PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig( typedef void (*atexit_datacallbackfunc)(void *); PyAPI_FUNC(int) PyUnstable_AtExit( PyInterpreterState *, atexit_datacallbackfunc, void *); - -PyAPI_FUNC(int) Py_IsFinalizing(void); diff --git a/Include/cpython/pymem.h b/Include/cpython/pymem.h index b75f1c4d2425dd..76b3221f7b9f39 100644 --- a/Include/cpython/pymem.h +++ b/Include/cpython/pymem.h @@ -2,12 +2,6 @@ # error "this header file must not be included directly" #endif -PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); -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); - - typedef enum { /* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */ PYMEM_DOMAIN_RAW, @@ -29,6 +23,10 @@ typedef enum { PYMEM_ALLOCATOR_PYMALLOC = 5, PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6, #endif +#ifdef WITH_MIMALLOC + PYMEM_ALLOCATOR_MIMALLOC = 7, + PYMEM_ALLOCATOR_MIMALLOC_DEBUG = 8, +#endif } PyMemAllocatorName; diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 5e184d0ca0944b..56172d231c44f4 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -92,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; @@ -136,6 +149,13 @@ struct _ts { struct _py_trashcan trash; + /* Tagged pointer to top-most critical section, or zero if there is no + * active critical section. Critical sections are only used in + * `--disable-gil` builds (i.e., when Py_GIL_DISABLED is defined to 1). In the + * default build, this field is always zero. + */ + uintptr_t critical_section; + /* Called when a thread state is deleted normally, but not when it * is destroyed after fork(). * Pain: to prevent rare but fatal shutdown errors (issue 18808), @@ -194,7 +214,11 @@ struct _ts { }; -#ifdef __wasi__ +#ifdef Py_DEBUG + // A debug build is likely built with low optimization level which implies + // higher stack memory usage than a release build: use a lower limit. +# define Py_C_RECURSION_LIMIT 500 +#elif defined(__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. @@ -209,7 +233,11 @@ struct _ts { /* 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); + +// Alias kept for backward compatibility +#define _PyThreadState_UncheckedGet PyThreadState_GetUnchecked + // Disable tracing and profiling. PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); @@ -226,6 +254,11 @@ PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate); The function returns 1 if _PyGILState_check_enabled is non-zero. */ PyAPI_FUNC(int) PyGILState_Check(void); +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +PyAPI_FUNC(PyObject*) _PyThread_CurrentFrames(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); @@ -244,80 +277,3 @@ PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc( PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc( PyInterpreterState *interp, _PyFrameEvalFunction eval_frame); - - -/* cross-interpreter data */ - -// _PyCrossInterpreterData is similar to Py_buffer as an effectively -// opaque struct that holds data outside the object machinery. This -// is necessary to pass safely between interpreters in the same process. -typedef struct _xid _PyCrossInterpreterData; - -typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *); -typedef void (*xid_freefunc)(void *); - -struct _xid { - // data is the cross-interpreter-safe derivation of a Python object - // (see _PyObject_GetCrossInterpreterData). It will be NULL if the - // new_object func (below) encodes the data. - void *data; - // obj is the Python object from which the data was derived. This - // is non-NULL only if the data remains bound to the object in some - // way, such that the object must be "released" (via a decref) when - // the data is released. In that case the code that sets the field, - // likely a registered "crossinterpdatafunc", is responsible for - // ensuring it owns the reference (i.e. incref). - PyObject *obj; - // interp is the ID of the owning interpreter of the original - // object. It corresponds to the active interpreter when - // _PyObject_GetCrossInterpreterData() was called. This should only - // be set by the cross-interpreter machinery. - // - // We use the ID rather than the PyInterpreterState to avoid issues - // with deleted interpreters. Note that IDs are never re-used, so - // each one will always correspond to a specific interpreter - // (whether still alive or not). - int64_t interp; - // new_object is a function that returns a new object in the current - // interpreter given the data. The resulting object (a new - // reference) will be equivalent to the original object. This field - // is required. - xid_newobjectfunc new_object; - // free is called when the data is released. If it is NULL then - // nothing will be done to free the data. For some types this is - // okay (e.g. bytes) and for those types this field should be set - // to NULL. However, for most the data was allocated just for - // cross-interpreter use, so it must be freed when - // _PyCrossInterpreterData_Release is called or the memory will - // leak. In that case, at the very least this field should be set - // to PyMem_RawFree (the default if not explicitly set to NULL). - // The call will happen with the original interpreter activated. - xid_freefunc free; -}; - -PyAPI_FUNC(void) _PyCrossInterpreterData_Init( - _PyCrossInterpreterData *data, - PyInterpreterState *interp, void *shared, PyObject *obj, - xid_newobjectfunc new_object); -PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize( - _PyCrossInterpreterData *, - PyInterpreterState *interp, const size_t, PyObject *, - xid_newobjectfunc); -PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( - PyInterpreterState *, _PyCrossInterpreterData *); - -PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); -PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); -PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); -PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *); - -PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); - -/* cross-interpreter data registry */ - -typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *, - _PyCrossInterpreterData *); - -PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); -PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *); -PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); diff --git a/Include/cpython/pystats.h b/Include/cpython/pystats.h index 150e16faa96ca1..ba67eefef3e37a 100644 --- a/Include/cpython/pystats.h +++ b/Include/cpython/pystats.h @@ -86,10 +86,6 @@ typedef struct _object_stats { 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; /* Temporary value used during GC */ uint64_t object_visits; } ObjectStats; @@ -100,10 +96,37 @@ typedef struct _gc_stats { uint64_t objects_collected; } GCStats; +typedef struct _uop_stats { + uint64_t execution_count; + uint64_t miss; +} 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; + uint64_t low_confidence; + 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; diff --git a/Include/cpython/pythread.h b/Include/cpython/pythread.h index cd2aab72d52df3..03f710a9f7ef2e 100644 --- a/Include/cpython/pythread.h +++ b/Include/cpython/pythread.h @@ -2,6 +2,14 @@ # error "this header file must not be included directly" #endif +// 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; + #define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) #ifdef HAVE_PTHREAD_H diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h index e028fb7ecd5230..a3ac07f538a94f 100644 --- a/Include/cpython/sysmodule.h +++ b/Include/cpython/sysmodule.h @@ -4,8 +4,19 @@ typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); -PyAPI_FUNC(int) PySys_Audit( - const char *event, - const char *argFormat, - ...); PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); + +typedef struct { + FILE* perf_map; + PyThread_type_lock map_lock; +} PerfMapState; + +PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void); +PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry( + const void *code_addr, + unsigned int code_size, + const char *entry_name); +PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void); +PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename); +PyAPI_FUNC(int) PyUnstable_PerfTrampoline_CompileCode(PyCodeObject *); +PyAPI_FUNC(int) PyUnstable_PerfTrampoline_SetPersistAfterFork(int enable); diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 859ab7178e920a..d9b54bce83202d 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -9,6 +9,7 @@ Py_DEPRECATED(3.13) typedef wchar_t PY_UNICODE_TYPE; Py_DEPRECATED(3.13) typedef wchar_t Py_UNICODE; + /* --- Internal Unicode Operations ---------------------------------------- */ // Static inline functions to work with surrogates @@ -43,6 +44,7 @@ static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) { return (0xDC00 + (ch & 0x3FF)); } + /* --- Unicode Type ------------------------------------------------------- */ /* ASCII-only strings created through PyUnicode_New use the PyASCIIObject @@ -375,6 +377,7 @@ static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op) #define PyUnicode_MAX_CHAR_VALUE(op) \ PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) + /* === Public API ========================================================= */ /* With PEP 393, this is the recommended way to allocate a new unicode object. @@ -440,6 +443,123 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( const void *buffer, Py_ssize_t size); + +/* --- _PyUnicodeWriter API ----------------------------------------------- */ + +typedef struct { + PyObject *buffer; + void *data; + int kind; + Py_UCS4 maxchar; + Py_ssize_t size; + Py_ssize_t pos; + + /* minimum number of allocated characters (default: 0) */ + Py_ssize_t min_length; + + /* minimum character (default: 127, ASCII) */ + Py_UCS4 min_char; + + /* If non-zero, overallocate the buffer (default: 0). */ + unsigned char overallocate; + + /* If readonly is 1, buffer is a shared string (cannot be modified) + and size is set to 0. */ + 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. +PyAPI_FUNC(void) +_PyUnicodeWriter_Init(_PyUnicodeWriter *writer); + +/* Prepare the buffer to write 'length' characters + with the specified maximum character. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \ + (((MAXCHAR) <= (WRITER)->maxchar \ + && (LENGTH) <= (WRITER)->size - (WRITER)->pos) \ + ? 0 \ + : (((LENGTH) == 0) \ + ? 0 \ + : _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR)))) + +/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro + instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, + Py_ssize_t length, Py_UCS4 maxchar); + +/* Prepare the buffer to have at least the kind KIND. + For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will + support characters in range U+000-U+FFFF. + + Return 0 on success, raise an exception and return -1 on error. */ +#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ + ((KIND) <= (WRITER)->kind \ + ? 0 \ + : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) + +/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind() + macro instead. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, + int kind); + +/* Append a Unicode character. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, + Py_UCS4 ch + ); + +/* Append a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, + PyObject *str /* Unicode string */ + ); + +/* Append a substring of a Unicode string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, + PyObject *str, /* Unicode string */ + Py_ssize_t start, + Py_ssize_t end + ); + +/* Append an ASCII-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, + const char *str, /* ASCII-encoded byte string */ + Py_ssize_t len /* number of bytes, or -1 if unknown */ + ); + +/* Append a latin1-encoded byte string. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) +_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, + const char *str, /* latin1-encoded byte string */ + Py_ssize_t len /* length in bytes */ + ); + +/* Get the value of the writer as a Unicode string. Clear the + buffer of the writer. Raise an exception and return NULL + on error. */ +PyAPI_FUNC(PyObject *) +_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer); + +/* Deallocate memory of a writer (clear its internal buffer). */ +PyAPI_FUNC(void) +_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); + + /* --- Manage the default encoding ---------------------------------------- */ /* Returns a pointer to the default encoding (UTF-8) of the @@ -448,12 +568,19 @@ 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); +// Alias kept for backward compatibility +#define _PyUnicode_AsString PyUnicode_AsUTF8 + + /* === Characters Type APIs =============================================== */ /* These should not be used directly. Use the Py_UNICODE_IS* and @@ -567,3 +694,10 @@ static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) { || Py_UNICODE_ISDIGIT(ch) || Py_UNICODE_ISNUMERIC(ch)); } + + +/* === Misc functions ===================================================== */ + +// Return an interned Unicode object for an Identifier; may fail if there is no +// memory. +PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); diff --git a/Include/errcode.h b/Include/errcode.h index 8d44e9ae559193..dac5cf068c99d6 100644 --- a/Include/errcode.h +++ b/Include/errcode.h @@ -19,24 +19,25 @@ extern "C" { #endif -#define E_OK 10 /* No error */ -#define E_EOF 11 /* End Of File */ -#define E_INTR 12 /* Interrupted */ -#define E_TOKEN 13 /* Bad token */ -#define E_SYNTAX 14 /* Syntax error */ -#define E_NOMEM 15 /* Ran out of memory */ -#define E_DONE 16 /* Parsing complete */ -#define E_ERROR 17 /* Execution error */ -#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ -#define E_OVERFLOW 19 /* Node had too many children */ -#define E_TOODEEP 20 /* Too many indentation levels */ -#define E_DEDENT 21 /* No matching outer block for dedent */ -#define E_DECODE 22 /* Error in decoding into Unicode */ -#define E_EOFS 23 /* EOF in triple-quoted string */ -#define E_EOLS 24 /* EOL in single-quoted string */ -#define E_LINECONT 25 /* Unexpected characters after a line continuation */ -#define E_BADSINGLE 27 /* Ill-formed single statement input */ -#define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */ +#define E_OK 10 /* No error */ +#define E_EOF 11 /* End Of File */ +#define E_INTR 12 /* Interrupted */ +#define E_TOKEN 13 /* Bad token */ +#define E_SYNTAX 14 /* Syntax error */ +#define E_NOMEM 15 /* Ran out of memory */ +#define E_DONE 16 /* Parsing complete */ +#define E_ERROR 17 /* Execution error */ +#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ +#define E_OVERFLOW 19 /* Node had too many children */ +#define E_TOODEEP 20 /* Too many indentation levels */ +#define E_DEDENT 21 /* No matching outer block for dedent */ +#define E_DECODE 22 /* Error in decoding into Unicode */ +#define E_EOFS 23 /* EOF in triple-quoted string */ +#define E_EOLS 24 /* EOL in single-quoted string */ +#define E_LINECONT 25 /* Unexpected characters after a line continuation */ +#define E_BADSINGLE 27 /* Ill-formed single statement input */ +#define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */ +#define E_COLUMNOVERFLOW 29 /* Column offset overflow */ #ifdef __cplusplus } diff --git a/Include/internal/mimalloc/mimalloc.h b/Include/internal/mimalloc/mimalloc.h new file mode 100644 index 00000000000000..821129e7690b1b --- /dev/null +++ b/Include/internal/mimalloc/mimalloc.h @@ -0,0 +1,565 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_H +#define MIMALLOC_H + +#define MI_MALLOC_VERSION 212 // major + 2 digits minor + +// ------------------------------------------------------ +// Compiler specific attributes +// ------------------------------------------------------ + +#ifdef __cplusplus + #if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 + #define mi_attr_noexcept noexcept + #else + #define mi_attr_noexcept throw() + #endif +#else + #define mi_attr_noexcept +#endif + +#if defined(__cplusplus) && (__cplusplus >= 201703) + #define mi_decl_nodiscard [[nodiscard]] +#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // includes clang, icc, and clang-cl + #define mi_decl_nodiscard __attribute__((warn_unused_result)) +#elif defined(_HAS_NODISCARD) + #define mi_decl_nodiscard _NODISCARD +#elif (_MSC_VER >= 1700) + #define mi_decl_nodiscard _Check_return_ +#else + #define mi_decl_nodiscard +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) + #if !defined(MI_SHARED_LIB) + #define mi_decl_export + #elif defined(MI_SHARED_LIB_EXPORT) + #define mi_decl_export __declspec(dllexport) + #else + #define mi_decl_export __declspec(dllimport) + #endif + #if defined(__MINGW32__) + #define mi_decl_restrict + #define mi_attr_malloc __attribute__((malloc)) + #else + #if (_MSC_VER >= 1900) && !defined(__EDG__) + #define mi_decl_restrict __declspec(allocator) __declspec(restrict) + #else + #define mi_decl_restrict __declspec(restrict) + #endif + #define mi_attr_malloc + #endif + #define mi_cdecl __cdecl + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) +#elif defined(__GNUC__) // includes clang and icc + #if defined(MI_SHARED_LIB) && defined(MI_SHARED_LIB_EXPORT) + #define mi_decl_export __attribute__((visibility("default"))) + #else + #define mi_decl_export + #endif + #define mi_cdecl // leads to warnings... __attribute__((cdecl)) + #define mi_decl_restrict + #define mi_attr_malloc __attribute__((malloc)) + #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5) + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) + #elif defined(__INTEL_COMPILER) + #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) + #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) + #define mi_attr_alloc_align(p) + #else + #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) + #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) + #define mi_attr_alloc_align(p) __attribute__((alloc_align(p))) + #endif +#else + #define mi_cdecl + #define mi_decl_export + #define mi_decl_restrict + #define mi_attr_malloc + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) +#endif + +// ------------------------------------------------------ +// Includes +// ------------------------------------------------------ + +#include // size_t +#include // bool +#include // INTPTR_MAX + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------------------------------------------ +// Standard malloc interface +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_export void* mi_expand(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); + +mi_decl_export void mi_free(void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; + +// ------------------------------------------------------ +// Extended functionality +// ------------------------------------------------------ +#define MI_SMALL_WSIZE_MAX (128) +#define MI_SMALL_SIZE_MAX (MI_SMALL_WSIZE_MAX*sizeof(void*)) + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); + +mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept; + + +// ------------------------------------------------------ +// Internals +// ------------------------------------------------------ + +typedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg); +mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept; + +typedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg); +mi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept; + +typedef void (mi_cdecl mi_error_fun)(int err, void* arg); +mi_decl_export void mi_register_error(mi_error_fun* fun, void* arg); + +mi_decl_export void mi_collect(bool force) mi_attr_noexcept; +mi_decl_export int mi_version(void) mi_attr_noexcept; +mi_decl_export void mi_stats_reset(void) mi_attr_noexcept; +mi_decl_export void mi_stats_merge(void) mi_attr_noexcept; +mi_decl_export void mi_stats_print(void* out) mi_attr_noexcept; // backward compatibility: `out` is ignored and should be NULL +mi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; + +mi_decl_export void mi_process_init(void) mi_attr_noexcept; +mi_decl_export void mi_thread_init(void) mi_attr_noexcept; +mi_decl_export void mi_thread_done(void) mi_attr_noexcept; +mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; + +mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, + size_t* current_rss, size_t* peak_rss, + size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept; + +// ------------------------------------------------------------------------------------- +// Aligned allocation +// Note that `alignment` always follows `size` for consistency with unaligned +// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`. +// ------------------------------------------------------------------------------------- + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); + + +// ------------------------------------------------------------------------------------- +// Heaps: first-class, but can only allocate from the same thread that created it. +// ------------------------------------------------------------------------------------- + +struct mi_heap_s; +typedef struct mi_heap_s mi_heap_t; + +mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void); +mi_decl_export void mi_heap_delete(mi_heap_t* heap); +mi_decl_export void mi_heap_destroy(mi_heap_t* heap); +mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap); +mi_decl_export mi_heap_t* mi_heap_get_default(void); +mi_decl_export mi_heap_t* mi_heap_get_backing(void); +mi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); + +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); +mi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); + + +// -------------------------------------------------------------------------------- +// Zero initialized re-allocation. +// Only valid on memory that was originally allocated with zero initialization too. +// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. +// see +// -------------------------------------------------------------------------------- + +mi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); + +mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3); + +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); + +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3,4) mi_attr_alloc_align(5); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3,4); + + +// ------------------------------------------------------ +// Analysis +// ------------------------------------------------------ + +mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p); +mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p); +mi_decl_export bool mi_check_owned(const void* p); + +// An area of heap space contains blocks of a single size. +typedef struct mi_heap_area_s { + void* blocks; // start of the area containing heap blocks + size_t reserved; // bytes reserved for this area (virtual) + size_t committed; // current available bytes for this area + size_t used; // number of allocated blocks + size_t block_size; // size in bytes of each block + size_t full_block_size; // size in bytes of a full block including padding and metadata. +} mi_heap_area_t; + +typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); + +mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); + +// Experimental +mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept; + +mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept; +mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept; + +mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept; +mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept; + +mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept; + +// Experimental: heaps associated with specific memory arena's +typedef int mi_arena_id_t; +mi_decl_export void* mi_arena_area(mi_arena_id_t arena_id, size_t* size); +mi_decl_export int mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept; +mi_decl_export int mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept; +mi_decl_export bool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept; + +#if MI_MALLOC_VERSION >= 182 +// Create a heap that only allocates in the specified arena +mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id); +#endif + +// deprecated +mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept; + + +// ------------------------------------------------------ +// Convenience +// ------------------------------------------------------ + +#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) +#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) +#define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp))) +#define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp))) +#define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp))) +#define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp))) + +#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) +#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) +#define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp))) +#define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp))) +#define mi_heap_reallocn_tp(hp,p,tp,n) ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp))) +#define mi_heap_recalloc_tp(hp,p,tp,n) ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp))) + + +// ------------------------------------------------------ +// Options +// ------------------------------------------------------ + +typedef enum mi_option_e { + // stable options + mi_option_show_errors, // print error messages + mi_option_show_stats, // print statistics on termination + mi_option_verbose, // print verbose messages + // the following options are experimental (see src/options.h) + mi_option_eager_commit, // eager commit segments? (after `eager_commit_delay` segments) (=1) + mi_option_arena_eager_commit, // eager commit arenas? Use 2 to enable just on overcommit systems (=2) + mi_option_purge_decommits, // should a memory purge decommit (or only reset) (=1) + mi_option_allow_large_os_pages, // allow large (2MiB) OS pages, implies eager commit + mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB/page) at startup + mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node + mi_option_reserve_os_memory, // reserve specified amount of OS memory in an arena at startup + mi_option_deprecated_segment_cache, + mi_option_deprecated_page_reset, + mi_option_abandoned_page_purge, // immediately purge delayed purges on thread termination + mi_option_deprecated_segment_reset, + mi_option_eager_commit_delay, + mi_option_purge_delay, // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all. + mi_option_use_numa_nodes, // 0 = use all available numa nodes, otherwise use at most N nodes. + mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only programmatically reserved arenas) + mi_option_os_tag, // tag used for OS logging (macOS only for now) + mi_option_max_errors, // issue at most N error messages + mi_option_max_warnings, // issue at most N warning messages + mi_option_max_segment_reclaim, + mi_option_destroy_on_exit, // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe. + mi_option_arena_reserve, // initial memory size in KiB for arena reservation (1GiB on 64-bit) + mi_option_arena_purge_mult, + mi_option_purge_extend_delay, + _mi_option_last, + // legacy option names + mi_option_large_os_pages = mi_option_allow_large_os_pages, + mi_option_eager_region_commit = mi_option_arena_eager_commit, + mi_option_reset_decommits = mi_option_purge_decommits, + mi_option_reset_delay = mi_option_purge_delay, + mi_option_abandoned_page_reset = mi_option_abandoned_page_purge +} mi_option_t; + + +mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option); +mi_decl_export void mi_option_enable(mi_option_t option); +mi_decl_export void mi_option_disable(mi_option_t option); +mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable); +mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable); + +mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option); +mi_decl_nodiscard mi_decl_export long mi_option_get_clamp(mi_option_t option, long min, long max); +mi_decl_nodiscard mi_decl_export size_t mi_option_get_size(mi_option_t option); +mi_decl_export void mi_option_set(mi_option_t option, long value); +mi_decl_export void mi_option_set_default(mi_option_t option, long value); + + +// ------------------------------------------------------------------------------------------------------- +// "mi" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions. +// (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.) +// note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing. +// ------------------------------------------------------------------------------------------------------- + +mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; +mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_good_size(size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; + +mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); + +mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export int mi_reallocarr(void* p, size_t count, size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_export int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept; +mi_decl_export int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept; + +mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; +mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept; +mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept; + +// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`. +// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception). +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size) mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(1, 2); +mi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize) mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(2, 3); + +#ifdef __cplusplus +} +#endif + +// --------------------------------------------------------------------------------------------- +// Implement the C++ std::allocator interface for use in STL containers. +// (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally) +// --------------------------------------------------------------------------------------------- +#ifdef __cplusplus + +#include // std::size_t +#include // PTRDIFF_MAX +#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 +#include // std::true_type +#include // std::forward +#endif + +template struct _mi_stl_allocator_common { + typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef value_type& reference; + typedef value_type const& const_reference; + typedef value_type* pointer; + typedef value_type const* const_pointer; + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using propagate_on_container_copy_assignment = std::true_type; + using propagate_on_container_move_assignment = std::true_type; + using propagate_on_container_swap = std::true_type; + template void construct(U* p, Args&& ...args) { ::new(p) U(std::forward(args)...); } + template void destroy(U* p) mi_attr_noexcept { p->~U(); } + #else + void construct(pointer p, value_type const& val) { ::new(p) value_type(val); } + void destroy(pointer p) { p->~value_type(); } + #endif + + size_type max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); } + pointer address(reference x) const { return &x; } + const_pointer address(const_reference x) const { return &x; } +}; + +template struct mi_stl_allocator : public _mi_stl_allocator_common { + using typename _mi_stl_allocator_common::size_type; + using typename _mi_stl_allocator_common::value_type; + using typename _mi_stl_allocator_common::pointer; + template struct rebind { typedef mi_stl_allocator other; }; + + mi_stl_allocator() mi_attr_noexcept = default; + mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default; + template mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept { } + mi_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T* p, size_type) { mi_free(p); } + + #if (__cplusplus >= 201703L) // C++17 + mi_decl_nodiscard T* allocate(size_type count) { return static_cast(mi_new_n(count, sizeof(T))); } + mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); } + #else + mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast(mi_new_n(count, sizeof(value_type))); } + #endif + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using is_always_equal = std::true_type; + #endif +}; + +template bool operator==(const mi_stl_allocator& , const mi_stl_allocator& ) mi_attr_noexcept { return true; } +template bool operator!=(const mi_stl_allocator& , const mi_stl_allocator& ) mi_attr_noexcept { return false; } + + +#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900) // C++11 +#define MI_HAS_HEAP_STL_ALLOCATOR 1 + +#include // std::shared_ptr + +// Common base class for STL allocators in a specific heap +template struct _mi_heap_stl_allocator_common : public _mi_stl_allocator_common { + using typename _mi_stl_allocator_common::size_type; + using typename _mi_stl_allocator_common::value_type; + using typename _mi_stl_allocator_common::pointer; + + _mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp) { } /* will not delete nor destroy the passed in heap */ + + #if (__cplusplus >= 201703L) // C++17 + mi_decl_nodiscard T* allocate(size_type count) { return static_cast(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(T))); } + mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); } + #else + mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(value_type))); } + #endif + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using is_always_equal = std::false_type; + #endif + + void collect(bool force) { mi_heap_collect(this->heap.get(), force); } + template bool is_equal(const _mi_heap_stl_allocator_common& x) const { return (this->heap == x.heap); } + +protected: + std::shared_ptr heap; + template friend struct _mi_heap_stl_allocator_common; + + _mi_heap_stl_allocator_common() { + mi_heap_t* hp = mi_heap_new(); + this->heap.reset(hp, (_mi_destroy ? &heap_destroy : &heap_delete)); /* calls heap_delete/destroy when the refcount drops to zero */ + } + _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common& x) mi_attr_noexcept : heap(x.heap) { } + template _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common& x) mi_attr_noexcept : heap(x.heap) { } + +private: + static void heap_delete(mi_heap_t* hp) { if (hp != NULL) { mi_heap_delete(hp); } } + static void heap_destroy(mi_heap_t* hp) { if (hp != NULL) { mi_heap_destroy(hp); } } +}; + +// STL allocator allocation in a specific heap +template struct mi_heap_stl_allocator : public _mi_heap_stl_allocator_common { + using typename _mi_heap_stl_allocator_common::size_type; + mi_heap_stl_allocator() : _mi_heap_stl_allocator_common() { } // creates fresh heap that is deleted when the destructor is called + mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common(hp) { } // no delete nor destroy on the passed in heap + template mi_heap_stl_allocator(const mi_heap_stl_allocator& x) mi_attr_noexcept : _mi_heap_stl_allocator_common(x) { } + + mi_heap_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T* p, size_type) { mi_free(p); } + template struct rebind { typedef mi_heap_stl_allocator other; }; +}; + +template bool operator==(const mi_heap_stl_allocator& x, const mi_heap_stl_allocator& y) mi_attr_noexcept { return (x.is_equal(y)); } +template bool operator!=(const mi_heap_stl_allocator& x, const mi_heap_stl_allocator& y) mi_attr_noexcept { return (!x.is_equal(y)); } + + +// STL allocator allocation in a specific heap, where `free` does nothing and +// the heap is destroyed in one go on destruction -- use with care! +template struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_allocator_common { + using typename _mi_heap_stl_allocator_common::size_type; + mi_heap_destroy_stl_allocator() : _mi_heap_stl_allocator_common() { } // creates fresh heap that is destroyed when the destructor is called + mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common(hp) { } // no delete nor destroy on the passed in heap + template mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator& x) mi_attr_noexcept : _mi_heap_stl_allocator_common(x) { } + + mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T*, size_type) { /* do nothing as we destroy the heap on destruct. */ } + template struct rebind { typedef mi_heap_destroy_stl_allocator other; }; +}; + +template bool operator==(const mi_heap_destroy_stl_allocator& x, const mi_heap_destroy_stl_allocator& y) mi_attr_noexcept { return (x.is_equal(y)); } +template bool operator!=(const mi_heap_destroy_stl_allocator& x, const mi_heap_destroy_stl_allocator& y) mi_attr_noexcept { return (!x.is_equal(y)); } + +#endif // C++11 + +#endif // __cplusplus + +#endif diff --git a/Include/internal/mimalloc/mimalloc/atomic.h b/Include/internal/mimalloc/mimalloc/atomic.h new file mode 100644 index 00000000000000..eb8478ceed6adf --- /dev/null +++ b/Include/internal/mimalloc/mimalloc/atomic.h @@ -0,0 +1,385 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_ATOMIC_H +#define MIMALLOC_ATOMIC_H + +// -------------------------------------------------------------------------------------------- +// Atomics +// We need to be portable between C, C++, and MSVC. +// We base the primitives on the C/C++ atomics and create a mimimal wrapper for MSVC in C compilation mode. +// This is why we try to use only `uintptr_t` and `*` as atomic types. +// To gain better insight in the range of used atomics, we use explicitly named memory order operations +// instead of passing the memory order as a parameter. +// ----------------------------------------------------------------------------------------------- + +#if defined(__cplusplus) +// Use C++ atomics +#include +#define _Atomic(tp) std::atomic +#define mi_atomic(name) std::atomic_##name +#define mi_memory_order(name) std::memory_order_##name +#if !defined(ATOMIC_VAR_INIT) || (__cplusplus >= 202002L) // c++20, see issue #571 + #define MI_ATOMIC_VAR_INIT(x) x +#else + #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) +#endif +#elif defined(_MSC_VER) +// Use MSVC C wrapper for C11 atomics +#define _Atomic(tp) tp +#define MI_ATOMIC_VAR_INIT(x) x +#define mi_atomic(name) mi_atomic_##name +#define mi_memory_order(name) mi_memory_order_##name +#else +// Use C11 atomics +#include +#define mi_atomic(name) atomic_##name +#define mi_memory_order(name) memory_order_##name +#if !defined(ATOMIC_VAR_INIT) || (__STDC_VERSION__ >= 201710L) // c17, see issue #735 + #define MI_ATOMIC_VAR_INIT(x) x +#else + #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) +#endif +#endif + +// Various defines for all used memory orders in mimalloc +#define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail) \ + mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail) + +#define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail) \ + mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail) + +#define mi_atomic_load_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_load_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_store_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_store_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) +#define mi_atomic_exchange_release(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_exchange_acq_rel(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_cas_weak_release(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed)) +#define mi_atomic_cas_weak_acq_rel(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire)) +#define mi_atomic_cas_strong_release(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed)) +#define mi_atomic_cas_strong_acq_rel(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire)) + +#define mi_atomic_add_relaxed(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed)) +#define mi_atomic_sub_relaxed(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed)) +#define mi_atomic_add_acq_rel(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_sub_acq_rel(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_and_acq_rel(p,x) mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel)) +#define mi_atomic_or_acq_rel(p,x) mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel)) + +#define mi_atomic_increment_relaxed(p) mi_atomic_add_relaxed(p,(uintptr_t)1) +#define mi_atomic_decrement_relaxed(p) mi_atomic_sub_relaxed(p,(uintptr_t)1) +#define mi_atomic_increment_acq_rel(p) mi_atomic_add_acq_rel(p,(uintptr_t)1) +#define mi_atomic_decrement_acq_rel(p) mi_atomic_sub_acq_rel(p,(uintptr_t)1) + +static inline void mi_atomic_yield(void); +static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add); +static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub); + + +#if defined(__cplusplus) || !defined(_MSC_VER) + +// In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value) +// We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well +#define mi_atomic_load_ptr_acquire(tp,p) mi_atomic_load_acquire(p) +#define mi_atomic_load_ptr_relaxed(tp,p) mi_atomic_load_relaxed(p) + +// In C++ we need to add casts to help resolve templates if NULL is passed +#if defined(__cplusplus) +#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,(tp*)x) +#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,(tp*)x) +#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,(tp*)des) +#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des) +#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,(tp*)des) +#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,(tp*)x) +#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,(tp*)x) +#else +#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,x) +#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,x) +#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,des) +#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,des) +#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,des) +#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,x) +#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,x) +#endif + +// These are used by the statistics +static inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) { + return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed)); +} +static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) { + int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p); + while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, ¤t, x)) { /* nothing */ }; +} + +// Used by timers +#define mi_atomic_loadi64_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_loadi64_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_storei64_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_storei64_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) + +#define mi_atomic_casi64_strong_acq_rel(p,e,d) mi_atomic_cas_strong_acq_rel(p,e,d) +#define mi_atomic_addi64_acq_rel(p,i) mi_atomic_add_acq_rel(p,i) + + +#elif defined(_MSC_VER) + +// MSVC C compilation wrapper that uses Interlocked operations to model C11 atomics. +#define WIN32_LEAN_AND_MEAN +#include +#include +#ifdef _WIN64 +typedef LONG64 msc_intptr_t; +#define MI_64(f) f##64 +#else +typedef LONG msc_intptr_t; +#define MI_64(f) f +#endif + +typedef enum mi_memory_order_e { + mi_memory_order_relaxed, + mi_memory_order_consume, + mi_memory_order_acquire, + mi_memory_order_release, + mi_memory_order_acq_rel, + mi_memory_order_seq_cst +} mi_memory_order; + +static inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add); +} +static inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub)); +} +static inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x); +} +static inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x); +} +static inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) { + (void)(mo1); (void)(mo2); + uintptr_t read = (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected)); + if (read == *expected) { + return true; + } + else { + *expected = read; + return false; + } +} +static inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) { + return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2); +} +static inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) { + (void)(mo); + return (uintptr_t)MI_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange); +} +static inline void mi_atomic_thread_fence(mi_memory_order mo) { + (void)(mo); + _Atomic(uintptr_t) x = 0; + mi_atomic_exchange_explicit(&x, 1, mo); +} +static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) { + (void)(mo); +#if defined(_M_IX86) || defined(_M_X64) + return *p; +#else + uintptr_t x = *p; + if (mo > mi_memory_order_relaxed) { + while (!mi_atomic_compare_exchange_weak_explicit((_Atomic(uintptr_t)*)p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ }; + } + return x; +#endif +} +static inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { + (void)(mo); +#if defined(_M_IX86) || defined(_M_X64) + *p = x; +#else + mi_atomic_exchange_explicit(p, x, mo); +#endif +} +static inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) { + (void)(mo); +#if defined(_M_X64) + return *p; +#else + int64_t old = *p; + int64_t x = old; + while ((old = InterlockedCompareExchange64(p, x, old)) != x) { + x = old; + } + return x; +#endif +} +static inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) { + (void)(mo); +#if defined(x_M_IX86) || defined(_M_X64) + *p = x; +#else + InterlockedExchange64(p, x); +#endif +} + +// These are used by the statistics +static inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) { +#ifdef _WIN64 + return (int64_t)mi_atomic_addi((int64_t*)p, add); +#else + int64_t current; + int64_t sum; + do { + current = *p; + sum = current + add; + } while (_InterlockedCompareExchange64(p, sum, current) != current); + return current; +#endif +} +static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) { + int64_t current; + do { + current = *p; + } while (current < x && _InterlockedCompareExchange64(p, x, current) != current); +} + +static inline void mi_atomic_addi64_acq_rel(volatile _Atomic(int64_t*)p, int64_t i) { + mi_atomic_addi64_relaxed(p, i); +} + +static inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p, int64_t* exp, int64_t des) { + int64_t read = _InterlockedCompareExchange64(p, des, *exp); + if (read == *exp) { + return true; + } + else { + *exp = read; + return false; + } +} + +// The pointer macros cast to `uintptr_t`. +#define mi_atomic_load_ptr_acquire(tp,p) (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p)) +#define mi_atomic_load_ptr_relaxed(tp,p) (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p)) +#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x)) +#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x)) +#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) +#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) +#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) +#define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x) +#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x) + +#define mi_atomic_loadi64_acquire(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_loadi64_relaxed(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed)) + + +#endif + + +// Atomically add a signed value; returns the previous value. +static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) { + return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add); +} + +// Atomically subtract a signed value; returns the previous value. +static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) { + return (intptr_t)mi_atomic_addi(p, -sub); +} + +typedef _Atomic(uintptr_t) mi_atomic_once_t; + +// Returns true only on the first invocation +static inline bool mi_atomic_once( mi_atomic_once_t* once ) { + if (mi_atomic_load_relaxed(once) != 0) return false; // quick test + uintptr_t expected = 0; + return mi_atomic_cas_strong_acq_rel(once, &expected, (uintptr_t)1); // try to set to 1 +} + +typedef _Atomic(uintptr_t) mi_atomic_guard_t; + +// Allows only one thread to execute at a time +#define mi_atomic_guard(guard) \ + uintptr_t _mi_guard_expected = 0; \ + for(bool _mi_guard_once = true; \ + _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,(uintptr_t)1); \ + (mi_atomic_store_release(guard,(uintptr_t)0), _mi_guard_once = false) ) + + + +// Yield +#if defined(__cplusplus) +#include +static inline void mi_atomic_yield(void) { + std::this_thread::yield(); +} +#elif defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +static inline void mi_atomic_yield(void) { + YieldProcessor(); +} +#elif defined(__SSE2__) +#include +static inline void mi_atomic_yield(void) { + _mm_pause(); +} +#elif (defined(__GNUC__) || defined(__clang__)) && \ + (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__armel__) || defined(__ARMEL__) || \ + defined(__aarch64__) || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)) || defined(__POWERPC__) +#if defined(__x86_64__) || defined(__i386__) +static inline void mi_atomic_yield(void) { + __asm__ volatile ("pause" ::: "memory"); +} +#elif defined(__aarch64__) +static inline void mi_atomic_yield(void) { + __asm__ volatile("wfe"); +} +#elif (defined(__arm__) && __ARM_ARCH__ >= 7) +static inline void mi_atomic_yield(void) { + __asm__ volatile("yield" ::: "memory"); +} +#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__) +#ifdef __APPLE__ +static inline void mi_atomic_yield(void) { + __asm__ volatile ("or r27,r27,r27" ::: "memory"); +} +#else +static inline void mi_atomic_yield(void) { + __asm__ __volatile__ ("or 27,27,27" ::: "memory"); +} +#endif +#elif defined(__armel__) || defined(__ARMEL__) +static inline void mi_atomic_yield(void) { + __asm__ volatile ("nop" ::: "memory"); +} +#endif +#elif defined(__sun) +// Fallback for other archs +#include +static inline void mi_atomic_yield(void) { + smt_pause(); +} +#elif defined(__wasi__) +#include +static inline void mi_atomic_yield(void) { + sched_yield(); +} +#else +#include +static inline void mi_atomic_yield(void) { + sleep(0); +} +#endif + + +#endif // __MIMALLOC_ATOMIC_H diff --git a/Include/internal/mimalloc/mimalloc/internal.h b/Include/internal/mimalloc/mimalloc/internal.h new file mode 100644 index 00000000000000..f076bc6a40f977 --- /dev/null +++ b/Include/internal/mimalloc/mimalloc/internal.h @@ -0,0 +1,979 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_INTERNAL_H +#define MIMALLOC_INTERNAL_H + + +// -------------------------------------------------------------------------- +// This file contains the interal API's of mimalloc and various utility +// functions and macros. +// -------------------------------------------------------------------------- + +#include "mimalloc/types.h" +#include "mimalloc/track.h" + +#if (MI_DEBUG>0) +#define mi_trace_message(...) _mi_trace_message(__VA_ARGS__) +#else +#define mi_trace_message(...) +#endif + +#define MI_CACHE_LINE 64 +#if defined(_MSC_VER) +#pragma warning(disable:4127) // suppress constant conditional warning (due to MI_SECURE paths) +#pragma warning(disable:26812) // unscoped enum warning +#define mi_decl_noinline __declspec(noinline) +#define mi_decl_thread __declspec(thread) +#define mi_decl_cache_align __declspec(align(MI_CACHE_LINE)) +#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc +#define mi_decl_noinline __attribute__((noinline)) +#define mi_decl_thread __thread +#define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE))) +#else +#define mi_decl_noinline +#define mi_decl_thread __thread // hope for the best :-) +#define mi_decl_cache_align +#endif + +#if defined(__EMSCRIPTEN__) && !defined(__wasi__) +#define __wasi__ +#endif + +#if defined(__cplusplus) +#define mi_decl_externc extern "C" +#else +#define mi_decl_externc +#endif + +// pthreads +#if !defined(_WIN32) && !defined(__wasi__) +#define MI_USE_PTHREADS +#include +#endif + +// "options.c" +void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message); +void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...); +void _mi_warning_message(const char* fmt, ...); +void _mi_verbose_message(const char* fmt, ...); +void _mi_trace_message(const char* fmt, ...); +void _mi_options_init(void); +void _mi_error_message(int err, const char* fmt, ...); + +// random.c +void _mi_random_init(mi_random_ctx_t* ctx); +void _mi_random_init_weak(mi_random_ctx_t* ctx); +void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx); +void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx); +uintptr_t _mi_random_next(mi_random_ctx_t* ctx); +uintptr_t _mi_heap_random_next(mi_heap_t* heap); +uintptr_t _mi_os_random_weak(uintptr_t extra_seed); +static inline uintptr_t _mi_random_shuffle(uintptr_t x); + +// init.c +extern mi_decl_cache_align mi_stats_t _mi_stats_main; +extern mi_decl_cache_align const mi_page_t _mi_page_empty; +bool _mi_is_main_thread(void); +size_t _mi_current_thread_count(void); +bool _mi_preloading(void); // true while the C runtime is not initialized yet +mi_threadid_t _mi_thread_id(void) mi_attr_noexcept; +mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap +void _mi_thread_done(mi_heap_t* heap); +void _mi_thread_data_collect(void); + +// os.c +void _mi_os_init(void); // called from process init +void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* stats); +void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* stats); +void _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* stats); + +size_t _mi_os_page_size(void); +size_t _mi_os_good_alloc_size(size_t size); +bool _mi_os_has_overcommit(void); +bool _mi_os_has_virtual_reserve(void); + +bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_reset(void* addr, size_t size, mi_stats_t* tld_stats); +bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); +bool _mi_os_protect(void* addr, size_t size); +bool _mi_os_unprotect(void* addr, size_t size); +bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats); + +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* stats); +void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats); + +void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size); +bool _mi_os_use_large_page(size_t size, size_t alignment); +size_t _mi_os_large_page_size(void); + +void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid); + +// arena.c +mi_arena_id_t _mi_arena_id_none(void); +void _mi_arena_free(void* p, size_t size, size_t still_committed_size, mi_memid_t memid, mi_stats_t* stats); +void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld); +void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld); +bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id); +bool _mi_arena_contains(const void* p); +void _mi_arena_collect(bool force_purge, mi_stats_t* stats); +void _mi_arena_unsafe_destroy_all(mi_stats_t* stats); + +// "segment-map.c" +void _mi_segment_map_allocated_at(const mi_segment_t* segment); +void _mi_segment_map_freed_at(const mi_segment_t* segment); + +// "segment.c" +mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld); +void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld); +void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld); +bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld); +void _mi_segment_thread_collect(mi_segments_tld_t* tld); + +#if MI_HUGE_PAGE_ABANDON +void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block); +#else +void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block); +#endif + +uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page +void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld); +void _mi_abandoned_await_readers(void); +void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld); + +// "page.c" +void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept mi_attr_malloc; + +void _mi_page_retire(mi_page_t* page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks +void _mi_page_unfull(mi_page_t* page); +void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page +void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread... +void _mi_heap_delayed_free_all(mi_heap_t* heap); +bool _mi_heap_delayed_free_partial(mi_heap_t* heap); +void _mi_heap_collect_retired(mi_heap_t* heap, bool force); + +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append); +void _mi_deferred_free(mi_heap_t* heap, bool force); + +void _mi_page_free_collect(mi_page_t* page,bool force); +void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments + +size_t _mi_bin_size(uint8_t bin); // for stats +uint8_t _mi_bin(size_t size); // for stats + +// "heap.c" +void _mi_heap_destroy_pages(mi_heap_t* heap); +void _mi_heap_collect_abandon(mi_heap_t* heap); +void _mi_heap_set_default_direct(mi_heap_t* heap); +bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid); +void _mi_heap_unsafe_destroy_all(void); + +// "stats.c" +void _mi_stats_done(mi_stats_t* stats); +mi_msecs_t _mi_clock_now(void); +mi_msecs_t _mi_clock_end(mi_msecs_t start); +mi_msecs_t _mi_clock_start(void); + +// "alloc.c" +void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept; // called from `_mi_malloc_generic` +void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept; +void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned` +void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept; +mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p); +bool _mi_free_delayed_block(mi_block_t* block); +void _mi_free_generic(const mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept; // for runtime integration +void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size); + +// option.c, c primitives +char _mi_toupper(char c); +int _mi_strnicmp(const char* s, const char* t, size_t n); +void _mi_strlcpy(char* dest, const char* src, size_t dest_size); +void _mi_strlcat(char* dest, const char* src, size_t dest_size); +size_t _mi_strlen(const char* s); +size_t _mi_strnlen(const char* s, size_t max_len); + + +#if MI_DEBUG>1 +bool _mi_page_is_valid(mi_page_t* page); +#endif + + +// ------------------------------------------------------ +// Branches +// ------------------------------------------------------ + +#if defined(__GNUC__) || defined(__clang__) +#define mi_unlikely(x) (__builtin_expect(!!(x),false)) +#define mi_likely(x) (__builtin_expect(!!(x),true)) +#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) +#define mi_unlikely(x) (x) [[unlikely]] +#define mi_likely(x) (x) [[likely]] +#else +#define mi_unlikely(x) (x) +#define mi_likely(x) (x) +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + + +/* ----------------------------------------------------------- + Error codes passed to `_mi_fatal_error` + All are recoverable but EFAULT is a serious error and aborts by default in secure mode. + For portability define undefined error codes using common Unix codes: + +----------------------------------------------------------- */ +#include +#ifndef EAGAIN // double free +#define EAGAIN (11) +#endif +#ifndef ENOMEM // out of memory +#define ENOMEM (12) +#endif +#ifndef EFAULT // corrupted free-list or meta-data +#define EFAULT (14) +#endif +#ifndef EINVAL // trying to free an invalid pointer +#define EINVAL (22) +#endif +#ifndef EOVERFLOW // count*size overflow +#define EOVERFLOW (75) +#endif + + +/* ----------------------------------------------------------- + Inlined definitions +----------------------------------------------------------- */ +#define MI_UNUSED(x) (void)(x) +#if (MI_DEBUG>0) +#define MI_UNUSED_RELEASE(x) +#else +#define MI_UNUSED_RELEASE(x) MI_UNUSED(x) +#endif + +#define MI_INIT4(x) x(),x(),x(),x() +#define MI_INIT8(x) MI_INIT4(x),MI_INIT4(x) +#define MI_INIT16(x) MI_INIT8(x),MI_INIT8(x) +#define MI_INIT32(x) MI_INIT16(x),MI_INIT16(x) +#define MI_INIT64(x) MI_INIT32(x),MI_INIT32(x) +#define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x) +#define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x) + + +#include +// initialize a local variable to zero; use memset as compilers optimize constant sized memset's +#define _mi_memzero_var(x) memset(&x,0,sizeof(x)) + +// Is `x` a power of two? (0 is considered a power of two) +static inline bool _mi_is_power_of_two(uintptr_t x) { + return ((x & (x - 1)) == 0); +} + +// Is a pointer aligned? +static inline bool _mi_is_aligned(void* p, size_t alignment) { + mi_assert_internal(alignment != 0); + return (((uintptr_t)p % alignment) == 0); +} + +// Align upwards +static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) { + mi_assert_internal(alignment != 0); + uintptr_t mask = alignment - 1; + if ((alignment & mask) == 0) { // power of two? + return ((sz + mask) & ~mask); + } + else { + return (((sz + mask)/alignment)*alignment); + } +} + +// Align downwards +static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) { + mi_assert_internal(alignment != 0); + uintptr_t mask = alignment - 1; + if ((alignment & mask) == 0) { // power of two? + return (sz & ~mask); + } + else { + return ((sz / alignment) * alignment); + } +} + +// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`. +static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) { + mi_assert_internal(divider != 0); + return (divider == 0 ? size : ((size + divider - 1) / divider)); +} + +// Is memory zero initialized? +static inline bool mi_mem_is_zero(const void* p, size_t size) { + for (size_t i = 0; i < size; i++) { + if (((uint8_t*)p)[i] != 0) return false; + } + return true; +} + + +// Align a byte size to a size in _machine words_, +// i.e. byte size == `wsize*sizeof(void*)`. +static inline size_t _mi_wsize_from_size(size_t size) { + mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t)); + return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); +} + +// Overflow detecting multiply +#if __has_builtin(__builtin_umul_overflow) || (defined(__GNUC__) && (__GNUC__ >= 5)) +#include // UINT_MAX, ULONG_MAX +#if defined(_CLOCK_T) // for Illumos +#undef _CLOCK_T +#endif +static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { + #if (SIZE_MAX == ULONG_MAX) + return __builtin_umull_overflow(count, size, (unsigned long *)total); + #elif (SIZE_MAX == UINT_MAX) + return __builtin_umul_overflow(count, size, (unsigned int *)total); + #else + return __builtin_umulll_overflow(count, size, (unsigned long long *)total); + #endif +} +#else /* __builtin_umul_overflow is unavailable */ +static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { + #define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX) + *total = count * size; + // note: gcc/clang optimize this to directly check the overflow flag + return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW) && size > 0 && (SIZE_MAX / size) < count); +} +#endif + +// Safe multiply `count*size` into `total`; return `true` on overflow. +static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) { + if (count==1) { // quick check for the case where count is one (common for C++ allocators) + *total = size; + return false; + } + else if mi_unlikely(mi_mul_overflow(count, size, total)) { + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "allocation request is too large (%zu * %zu bytes)\n", count, size); + #endif + *total = SIZE_MAX; + return true; + } + else return false; +} + + +/*---------------------------------------------------------------------------------------- + Heap functions +------------------------------------------------------------------------------------------- */ + +extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap + +static inline bool mi_heap_is_backing(const mi_heap_t* heap) { + return (heap->tld->heap_backing == heap); +} + +static inline bool mi_heap_is_initialized(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + return (heap != &_mi_heap_empty); +} + +static inline uintptr_t _mi_ptr_cookie(const void* p) { + extern mi_heap_t _mi_heap_main; + mi_assert_internal(_mi_heap_main.cookie != 0); + return ((uintptr_t)p ^ _mi_heap_main.cookie); +} + +/* ----------------------------------------------------------- + Pages +----------------------------------------------------------- */ + +static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) { + mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE)); + const size_t idx = _mi_wsize_from_size(size); + mi_assert_internal(idx < MI_PAGES_DIRECT); + return heap->pages_free_direct[idx]; +} + +// Segment that contains the pointer +// Large aligned blocks may be aligned at N*MI_SEGMENT_SIZE (inside a huge segment > MI_SEGMENT_SIZE), +// and we need align "down" to the segment info which is `MI_SEGMENT_SIZE` bytes before it; +// therefore we align one byte before `p`. +static inline mi_segment_t* _mi_ptr_segment(const void* p) { + mi_assert_internal(p != NULL); + return (mi_segment_t*)(((uintptr_t)p - 1) & ~MI_SEGMENT_MASK); +} + +static inline mi_page_t* mi_slice_to_page(mi_slice_t* s) { + mi_assert_internal(s->slice_offset== 0 && s->slice_count > 0); + return (mi_page_t*)(s); +} + +static inline mi_slice_t* mi_page_to_slice(mi_page_t* p) { + mi_assert_internal(p->slice_offset== 0 && p->slice_count > 0); + return (mi_slice_t*)(p); +} + +// Segment belonging to a page +static inline mi_segment_t* _mi_page_segment(const mi_page_t* page) { + mi_segment_t* segment = _mi_ptr_segment(page); + mi_assert_internal(segment == NULL || ((mi_slice_t*)page >= segment->slices && (mi_slice_t*)page < segment->slices + segment->slice_entries)); + return segment; +} + +static inline mi_slice_t* mi_slice_first(const mi_slice_t* slice) { + mi_slice_t* start = (mi_slice_t*)((uint8_t*)slice - slice->slice_offset); + mi_assert_internal(start >= _mi_ptr_segment(slice)->slices); + mi_assert_internal(start->slice_offset == 0); + mi_assert_internal(start + start->slice_count > slice); + return start; +} + +// Get the page containing the pointer (performance critical as it is called in mi_free) +static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) { + mi_assert_internal(p > (void*)segment); + ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment; + mi_assert_internal(diff > 0 && diff <= (ptrdiff_t)MI_SEGMENT_SIZE); + size_t idx = (size_t)diff >> MI_SEGMENT_SLICE_SHIFT; + mi_assert_internal(idx <= segment->slice_entries); + mi_slice_t* slice0 = (mi_slice_t*)&segment->slices[idx]; + mi_slice_t* slice = mi_slice_first(slice0); // adjust to the block that holds the page data + mi_assert_internal(slice->slice_offset == 0); + mi_assert_internal(slice >= segment->slices && slice < segment->slices + segment->slice_entries); + return mi_slice_to_page(slice); +} + +// Quick page start for initialized pages +static inline uint8_t* _mi_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) { + return _mi_segment_page_start(segment, page, page_size); +} + +// Get the page containing the pointer +static inline mi_page_t* _mi_ptr_page(void* p) { + return _mi_segment_page_of(_mi_ptr_segment(p), p); +} + +// Get the block size of a page (special case for huge objects) +static inline size_t mi_page_block_size(const mi_page_t* page) { + const size_t bsize = page->xblock_size; + mi_assert_internal(bsize > 0); + if mi_likely(bsize < MI_HUGE_BLOCK_SIZE) { + return bsize; + } + else { + size_t psize; + _mi_segment_page_start(_mi_page_segment(page), page, &psize); + return psize; + } +} + +static inline bool mi_page_is_huge(const mi_page_t* page) { + return (_mi_page_segment(page)->kind == MI_SEGMENT_HUGE); +} + +// Get the usable block size of a page without fixed padding. +// This may still include internal padding due to alignment and rounding up size classes. +static inline size_t mi_page_usable_block_size(const mi_page_t* page) { + return mi_page_block_size(page) - MI_PADDING_SIZE; +} + +// size of a segment +static inline size_t mi_segment_size(mi_segment_t* segment) { + return segment->segment_slices * MI_SEGMENT_SLICE_SIZE; +} + +static inline uint8_t* mi_segment_end(mi_segment_t* segment) { + return (uint8_t*)segment + mi_segment_size(segment); +} + +// Thread free access +static inline mi_block_t* mi_page_thread_free(const mi_page_t* page) { + return (mi_block_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & ~3); +} + +static inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) { + return (mi_delayed_t)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & 3); +} + +// Heap access +static inline mi_heap_t* mi_page_heap(const mi_page_t* page) { + return (mi_heap_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xheap)); +} + +static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) { + mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING); + mi_atomic_store_release(&page->xheap,(uintptr_t)heap); +} + +// Thread free flag helpers +static inline mi_block_t* mi_tf_block(mi_thread_free_t tf) { + return (mi_block_t*)(tf & ~0x03); +} +static inline mi_delayed_t mi_tf_delayed(mi_thread_free_t tf) { + return (mi_delayed_t)(tf & 0x03); +} +static inline mi_thread_free_t mi_tf_make(mi_block_t* block, mi_delayed_t delayed) { + return (mi_thread_free_t)((uintptr_t)block | (uintptr_t)delayed); +} +static inline mi_thread_free_t mi_tf_set_delayed(mi_thread_free_t tf, mi_delayed_t delayed) { + return mi_tf_make(mi_tf_block(tf),delayed); +} +static inline mi_thread_free_t mi_tf_set_block(mi_thread_free_t tf, mi_block_t* block) { + return mi_tf_make(block, mi_tf_delayed(tf)); +} + +// are all blocks in a page freed? +// note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`. +static inline bool mi_page_all_free(const mi_page_t* page) { + mi_assert_internal(page != NULL); + return (page->used == 0); +} + +// are there any available blocks? +static inline bool mi_page_has_any_available(const mi_page_t* page) { + mi_assert_internal(page != NULL && page->reserved > 0); + return (page->used < page->reserved || (mi_page_thread_free(page) != NULL)); +} + +// are there immediately available blocks, i.e. blocks available on the free list. +static inline bool mi_page_immediate_available(const mi_page_t* page) { + mi_assert_internal(page != NULL); + return (page->free != NULL); +} + +// is more than 7/8th of a page in use? +static inline bool mi_page_mostly_used(const mi_page_t* page) { + if (page==NULL) return true; + uint16_t frac = page->reserved / 8U; + return (page->reserved - page->used <= frac); +} + +static inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) { + return &((mi_heap_t*)heap)->pages[_mi_bin(size)]; +} + + + +//----------------------------------------------------------- +// Page flags +//----------------------------------------------------------- +static inline bool mi_page_is_in_full(const mi_page_t* page) { + return page->flags.x.in_full; +} + +static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) { + page->flags.x.in_full = in_full; +} + +static inline bool mi_page_has_aligned(const mi_page_t* page) { + return page->flags.x.has_aligned; +} + +static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) { + page->flags.x.has_aligned = has_aligned; +} + + +/* ------------------------------------------------------------------- +Encoding/Decoding the free list next pointers + +This is to protect against buffer overflow exploits where the +free list is mutated. Many hardened allocators xor the next pointer `p` +with a secret key `k1`, as `p^k1`. This prevents overwriting with known +values but might be still too weak: if the attacker can guess +the pointer `p` this can reveal `k1` (since `p^k1^p == k1`). +Moreover, if multiple blocks can be read as well, the attacker can +xor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot +about the pointers (and subsequently `k1`). + +Instead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<> (MI_INTPTR_BITS - shift)))); +} +static inline uintptr_t mi_rotr(uintptr_t x, uintptr_t shift) { + shift %= MI_INTPTR_BITS; + return (shift==0 ? x : ((x >> shift) | (x << (MI_INTPTR_BITS - shift)))); +} + +static inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) { + void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]); + return (p==null ? NULL : p); +} + +static inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) { + uintptr_t x = (uintptr_t)(p==NULL ? null : p); + return mi_rotl(x ^ keys[1], keys[0]) + keys[0]; +} + +static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) { + mi_track_mem_defined(block,sizeof(mi_block_t)); + mi_block_t* next; + #ifdef MI_ENCODE_FREELIST + next = (mi_block_t*)mi_ptr_decode(null, block->next, keys); + #else + MI_UNUSED(keys); MI_UNUSED(null); + next = (mi_block_t*)block->next; + #endif + mi_track_mem_noaccess(block,sizeof(mi_block_t)); + return next; +} + +static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) { + mi_track_mem_undefined(block,sizeof(mi_block_t)); + #ifdef MI_ENCODE_FREELIST + block->next = mi_ptr_encode(null, next, keys); + #else + MI_UNUSED(keys); MI_UNUSED(null); + block->next = (mi_encoded_t)next; + #endif + mi_track_mem_noaccess(block,sizeof(mi_block_t)); +} + +static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) { + #ifdef MI_ENCODE_FREELIST + mi_block_t* next = mi_block_nextx(page,block,page->keys); + // check for free list corruption: is `next` at least in the same page? + // TODO: check if `next` is `page->block_size` aligned? + if mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next)) { + _mi_error_message(EFAULT, "corrupted free list entry of size %zub at %p: value 0x%zx\n", mi_page_block_size(page), block, (uintptr_t)next); + next = NULL; + } + return next; + #else + MI_UNUSED(page); + return mi_block_nextx(page,block,NULL); + #endif +} + +static inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) { + #ifdef MI_ENCODE_FREELIST + mi_block_set_nextx(page,block,next, page->keys); + #else + MI_UNUSED(page); + mi_block_set_nextx(page,block,next,NULL); + #endif +} + + +// ------------------------------------------------------------------- +// commit mask +// ------------------------------------------------------------------- + +static inline void mi_commit_mask_create_empty(mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + cm->mask[i] = 0; + } +} + +static inline void mi_commit_mask_create_full(mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + cm->mask[i] = ~((size_t)0); + } +} + +static inline bool mi_commit_mask_is_empty(const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if (cm->mask[i] != 0) return false; + } + return true; +} + +static inline bool mi_commit_mask_is_full(const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if (cm->mask[i] != ~((size_t)0)) return false; + } + return true; +} + +// defined in `segment.c`: +size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total); +size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx); + +#define mi_commit_mask_foreach(cm,idx,count) \ + idx = 0; \ + while ((count = _mi_commit_mask_next_run(cm,&idx)) > 0) { + +#define mi_commit_mask_foreach_end() \ + idx += count; \ + } + + + +/* ----------------------------------------------------------- + memory id's +----------------------------------------------------------- */ + +static inline mi_memid_t _mi_memid_create(mi_memkind_t memkind) { + mi_memid_t memid; + _mi_memzero_var(memid); + memid.memkind = memkind; + return memid; +} + +static inline mi_memid_t _mi_memid_none(void) { + return _mi_memid_create(MI_MEM_NONE); +} + +static inline mi_memid_t _mi_memid_create_os(bool committed, bool is_zero, bool is_large) { + mi_memid_t memid = _mi_memid_create(MI_MEM_OS); + memid.initially_committed = committed; + memid.initially_zero = is_zero; + memid.is_pinned = is_large; + return memid; +} + + +// ------------------------------------------------------------------- +// Fast "random" shuffle +// ------------------------------------------------------------------- + +static inline uintptr_t _mi_random_shuffle(uintptr_t x) { + if (x==0) { x = 17; } // ensure we don't get stuck in generating zeros +#if (MI_INTPTR_SIZE==8) + // by Sebastiano Vigna, see: + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9UL; + x ^= x >> 27; + x *= 0x94d049bb133111ebUL; + x ^= x >> 31; +#elif (MI_INTPTR_SIZE==4) + // by Chris Wellons, see: + x ^= x >> 16; + x *= 0x7feb352dUL; + x ^= x >> 15; + x *= 0x846ca68bUL; + x ^= x >> 16; +#endif + return x; +} + +// ------------------------------------------------------------------- +// Optimize numa node access for the common case (= one node) +// ------------------------------------------------------------------- + +int _mi_os_numa_node_get(mi_os_tld_t* tld); +size_t _mi_os_numa_node_count_get(void); + +extern _Atomic(size_t) _mi_numa_node_count; +static inline int _mi_os_numa_node(mi_os_tld_t* tld) { + if mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1) { return 0; } + else return _mi_os_numa_node_get(tld); +} +static inline size_t _mi_os_numa_node_count(void) { + const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count); + if mi_likely(count > 0) { return count; } + else return _mi_os_numa_node_count_get(); +} + + + +// ----------------------------------------------------------------------- +// Count bits: trailing or leading zeros (with MI_INTPTR_BITS on all zero) +// ----------------------------------------------------------------------- + +#if defined(__GNUC__) + +#include // LONG_MAX +#define MI_HAVE_FAST_BITSCAN +static inline size_t mi_clz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (INTPTR_MAX == LONG_MAX) + return __builtin_clzl(x); +#else + return __builtin_clzll(x); +#endif +} +static inline size_t mi_ctz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (INTPTR_MAX == LONG_MAX) + return __builtin_ctzl(x); +#else + return __builtin_ctzll(x); +#endif +} + +#elif defined(_MSC_VER) + +#include // LONG_MAX +#include // BitScanReverse64 +#define MI_HAVE_FAST_BITSCAN +static inline size_t mi_clz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; + unsigned long idx; +#if (INTPTR_MAX == LONG_MAX) + _BitScanReverse(&idx, x); +#else + _BitScanReverse64(&idx, x); +#endif + return ((MI_INTPTR_BITS - 1) - idx); +} +static inline size_t mi_ctz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; + unsigned long idx; +#if (INTPTR_MAX == LONG_MAX) + _BitScanForward(&idx, x); +#else + _BitScanForward64(&idx, x); +#endif + return idx; +} + +#else +static inline size_t mi_ctz32(uint32_t x) { + // de Bruijn multiplication, see + static const unsigned char debruijn[32] = { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + if (x==0) return 32; + return debruijn[((x & -(int32_t)x) * 0x077CB531UL) >> 27]; +} +static inline size_t mi_clz32(uint32_t x) { + // de Bruijn multiplication, see + static const uint8_t debruijn[32] = { + 31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1, + 23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0 + }; + if (x==0) return 32; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + return debruijn[(uint32_t)(x * 0x07C4ACDDUL) >> 27]; +} + +static inline size_t mi_clz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (MI_INTPTR_BITS <= 32) + return mi_clz32((uint32_t)x); +#else + size_t count = mi_clz32((uint32_t)(x >> 32)); + if (count < 32) return count; + return (32 + mi_clz32((uint32_t)x)); +#endif +} +static inline size_t mi_ctz(uintptr_t x) { + if (x==0) return MI_INTPTR_BITS; +#if (MI_INTPTR_BITS <= 32) + return mi_ctz32((uint32_t)x); +#else + size_t count = mi_ctz32((uint32_t)x); + if (count < 32) return count; + return (32 + mi_ctz32((uint32_t)(x>>32))); +#endif +} + +#endif + +// "bit scan reverse": Return index of the highest bit (or MI_INTPTR_BITS if `x` is zero) +static inline size_t mi_bsr(uintptr_t x) { + return (x==0 ? MI_INTPTR_BITS : MI_INTPTR_BITS - 1 - mi_clz(x)); +} + + +// --------------------------------------------------------------------------------- +// Provide our own `_mi_memcpy` for potential performance optimizations. +// +// For now, only on Windows with msvc/clang-cl we optimize to `rep movsb` if +// we happen to run on x86/x64 cpu's that have "fast short rep movsb" (FSRM) support +// (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017). See also issue #201 and pr #253. +// --------------------------------------------------------------------------------- + +#if !MI_TRACK_ENABLED && defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) +#include +extern bool _mi_cpu_has_fsrm; +static inline void _mi_memcpy(void* dst, const void* src, size_t n) { + if (_mi_cpu_has_fsrm) { + __movsb((unsigned char*)dst, (const unsigned char*)src, n); + } + else { + memcpy(dst, src, n); + } +} +static inline void _mi_memzero(void* dst, size_t n) { + if (_mi_cpu_has_fsrm) { + __stosb((unsigned char*)dst, 0, n); + } + else { + memset(dst, 0, n); + } +} +#else +static inline void _mi_memcpy(void* dst, const void* src, size_t n) { + memcpy(dst, src, n); +} +static inline void _mi_memzero(void* dst, size_t n) { + memset(dst, 0, n); +} +#endif + +// ------------------------------------------------------------------------------- +// The `_mi_memcpy_aligned` can be used if the pointers are machine-word aligned +// This is used for example in `mi_realloc`. +// ------------------------------------------------------------------------------- + +#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) +// On GCC/CLang we provide a hint that the pointers are word aligned. +static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) { + mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0)); + void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE); + const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE); + _mi_memcpy(adst, asrc, n); +} + +static inline void _mi_memzero_aligned(void* dst, size_t n) { + mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0); + void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE); + _mi_memzero(adst, n); +} +#else +// Default fallback on `_mi_memcpy` +static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) { + mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0)); + _mi_memcpy(dst, src, n); +} + +static inline void _mi_memzero_aligned(void* dst, size_t n) { + mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0); + _mi_memzero(dst, n); +} +#endif + + +#endif diff --git a/Include/internal/mimalloc/mimalloc/prim.h b/Include/internal/mimalloc/mimalloc/prim.h new file mode 100644 index 00000000000000..4b9e4dc4194d77 --- /dev/null +++ b/Include/internal/mimalloc/mimalloc/prim.h @@ -0,0 +1,323 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_PRIM_H +#define MIMALLOC_PRIM_H + + +// -------------------------------------------------------------------------- +// This file specifies the primitive portability API. +// Each OS/host needs to implement these primitives, see `src/prim` +// for implementations on Window, macOS, WASI, and Linux/Unix. +// +// note: on all primitive functions, we always have result parameters != NUL, and: +// addr != NULL and page aligned +// size > 0 and page aligned +// return value is an error code an int where 0 is success. +// -------------------------------------------------------------------------- + +// OS memory configuration +typedef struct mi_os_mem_config_s { + size_t page_size; // 4KiB + size_t large_page_size; // 2MiB + size_t alloc_granularity; // smallest allocation size (on Windows 64KiB) + bool has_overcommit; // can we reserve more memory than can be actually committed? + bool must_free_whole; // must allocated blocks be freed as a whole (false for mmap, true for VirtualAlloc) + bool has_virtual_reserve; // supports virtual address space reservation? (if true we can reserve virtual address space without using commit or physical memory) +} mi_os_mem_config_t; + +// Initialize +void _mi_prim_mem_init( mi_os_mem_config_t* config ); + +// Free OS memory +int _mi_prim_free(void* addr, size_t size ); + +// Allocate OS memory. Return NULL on error. +// The `try_alignment` is just a hint and the returned pointer does not have to be aligned. +// If `commit` is false, the virtual memory range only needs to be reserved (with no access) +// which will later be committed explicitly using `_mi_prim_commit`. +// `is_zero` is set to true if the memory was zero initialized (as on most OS's) +// pre: !commit => !allow_large +// try_alignment >= _mi_os_page_size() and a power of 2 +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr); + +// Commit memory. Returns error code or 0 on success. +// For example, on Linux this would make the memory PROT_READ|PROT_WRITE. +// `is_zero` is set to true if the memory was zero initialized (e.g. on Windows) +int _mi_prim_commit(void* addr, size_t size, bool* is_zero); + +// Decommit memory. Returns error code or 0 on success. The `needs_recommit` result is true +// if the memory would need to be re-committed. For example, on Windows this is always true, +// but on Linux we could use MADV_DONTNEED to decommit which does not need a recommit. +// pre: needs_recommit != NULL +int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit); + +// Reset memory. The range keeps being accessible but the content might be reset. +// Returns error code or 0 on success. +int _mi_prim_reset(void* addr, size_t size); + +// Protect memory. Returns error code or 0 on success. +int _mi_prim_protect(void* addr, size_t size, bool protect); + +// Allocate huge (1GiB) pages possibly associated with a NUMA node. +// `is_zero` is set to true if the memory was zero initialized (as on most OS's) +// pre: size > 0 and a multiple of 1GiB. +// numa_node is either negative (don't care), or a numa node number. +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr); + +// Return the current NUMA node +size_t _mi_prim_numa_node(void); + +// Return the number of logical NUMA nodes +size_t _mi_prim_numa_node_count(void); + +// Clock ticks +mi_msecs_t _mi_prim_clock_now(void); + +// Return process information (only for statistics) +typedef struct mi_process_info_s { + mi_msecs_t elapsed; + mi_msecs_t utime; + mi_msecs_t stime; + size_t current_rss; + size_t peak_rss; + size_t current_commit; + size_t peak_commit; + size_t page_faults; +} mi_process_info_t; + +void _mi_prim_process_info(mi_process_info_t* pinfo); + +// Default stderr output. (only for warnings etc. with verbose enabled) +// msg != NULL && _mi_strlen(msg) > 0 +void _mi_prim_out_stderr( const char* msg ); + +// Get an environment variable. (only for options) +// name != NULL, result != NULL, result_size >= 64 +bool _mi_prim_getenv(const char* name, char* result, size_t result_size); + + +// Fill a buffer with strong randomness; return `false` on error or if +// there is no strong randomization available. +bool _mi_prim_random_buf(void* buf, size_t buf_len); + +// Called on the first thread start, and should ensure `_mi_thread_done` is called on thread termination. +void _mi_prim_thread_init_auto_done(void); + +// Called on process exit and may take action to clean up resources associated with the thread auto done. +void _mi_prim_thread_done_auto_done(void); + +// Called when the default heap for a thread changes +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap); + + +//------------------------------------------------------------------- +// Thread id: `_mi_prim_thread_id()` +// +// Getting the thread id should be performant as it is called in the +// fast path of `_mi_free` and we specialize for various platforms as +// inlined definitions. Regular code should call `init.c:_mi_thread_id()`. +// We only require _mi_prim_thread_id() to return a unique id +// for each thread (unequal to zero). +//------------------------------------------------------------------- + +// defined in `init.c`; do not use these directly +extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from +extern bool _mi_process_is_initialized; // has mi_process_init been called? + +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept; + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { + // Windows: works on Intel and ARM in both 32- and 64-bit + return (uintptr_t)NtCurrentTeb(); +} + +// We use assembly for a fast thread id on the main platforms. The TLS layout depends on +// both the OS and libc implementation so we use specific tests for each main platform. +// If you test on another platform and it works please send a PR :-) +// see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register. +#elif defined(__GNUC__) && ( \ + (defined(__GLIBC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \ + || (defined(__APPLE__) && (defined(__x86_64__) || defined(__aarch64__))) \ + || (defined(__BIONIC__) && (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__))) \ + || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \ + || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \ + ) + +static inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept { + void* res; + const size_t ofs = (slot*sizeof(void*)); + #if defined(__i386__) + __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86 32-bit always uses GS + #elif defined(__APPLE__) && defined(__x86_64__) + __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS + #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4) + __asm__("movl %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x32 ABI + #elif defined(__x86_64__) + __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS + #elif defined(__arm__) + void** tcb; MI_UNUSED(ofs); + __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); + res = tcb[slot]; + #elif defined(__aarch64__) + void** tcb; MI_UNUSED(ofs); + #if defined(__APPLE__) // M1, issue #343 + __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb)); + #else + __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); + #endif + res = tcb[slot]; + #endif + return res; +} + +// setting a tls slot is only used on macOS for now +static inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexcept { + const size_t ofs = (slot*sizeof(void*)); + #if defined(__i386__) + __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS + #elif defined(__APPLE__) && defined(__x86_64__) + __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOS uses GS + #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4) + __asm__("movl %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x32 ABI + #elif defined(__x86_64__) + __asm__("movq %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS + #elif defined(__arm__) + void** tcb; MI_UNUSED(ofs); + __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); + tcb[slot] = value; + #elif defined(__aarch64__) + void** tcb; MI_UNUSED(ofs); + #if defined(__APPLE__) // M1, issue #343 + __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb)); + #else + __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); + #endif + tcb[slot] = value; + #endif +} + +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { + #if defined(__BIONIC__) + // issue #384, #495: on the Bionic libc (Android), slot 1 is the thread id + // see: /~https://github.com/aosp-mirror/platform_bionic/blob/c44b1d0676ded732df4b3b21c5f798eacae93228/libc/platform/bionic/tls_defines.h#L86 + return (uintptr_t)mi_prim_tls_slot(1); + #else + // in all our other targets, slot 0 is the thread id + // glibc: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysdeps/x86_64/nptl/tls.h + // apple: /~https://github.com/apple/darwin-xnu/blob/main/libsyscall/os/tsd.h#L36 + return (uintptr_t)mi_prim_tls_slot(0); + #endif +} + +#else + +// otherwise use portable C, taking the address of a thread local variable (this is still very fast on most platforms). +static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept { + return (uintptr_t)&_mi_heap_default; +} + +#endif + + + +/* ---------------------------------------------------------------------------------------- +The thread local default heap: `_mi_prim_get_default_heap()` +This is inlined here as it is on the fast path for allocation functions. + +On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a +__thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures +that the storage will always be available (allocated on the thread stacks). + +On some platforms though we cannot use that when overriding `malloc` since the underlying +TLS implementation (or the loader) will call itself `malloc` on a first access and recurse. +We try to circumvent this in an efficient way: +- macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the + loader itself calls `malloc` even before the modules are initialized. +- OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS). +- DragonFly: defaults are working but seem slow compared to freeBSD (see PR #323) +------------------------------------------------------------------------------------------- */ + +static inline mi_heap_t* mi_prim_get_default_heap(void); + +#if defined(MI_MALLOC_OVERRIDE) +#if defined(__APPLE__) // macOS + #define MI_TLS_SLOT 89 // seems unused? + // #define MI_TLS_RECURSE_GUARD 1 + // other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89) + // see +#elif defined(__OpenBSD__) + // use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16) + // see + #define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24) + // #elif defined(__DragonFly__) + // #warning "mimalloc is not working correctly on DragonFly yet." + // #define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) +#elif defined(__ANDROID__) + // See issue #381 + #define MI_TLS_PTHREAD +#endif +#endif + + +#if defined(MI_TLS_SLOT) + +static inline mi_heap_t* mi_prim_get_default_heap(void) { + mi_heap_t* heap = (mi_heap_t*)mi_prim_tls_slot(MI_TLS_SLOT); + if mi_unlikely(heap == NULL) { + #ifdef __GNUC__ + __asm(""); // prevent conditional load of the address of _mi_heap_empty + #endif + heap = (mi_heap_t*)&_mi_heap_empty; + } + return heap; +} + +#elif defined(MI_TLS_PTHREAD_SLOT_OFS) + +static inline mi_heap_t** mi_prim_tls_pthread_heap_slot(void) { + pthread_t self = pthread_self(); + #if defined(__DragonFly__) + if (self==NULL) return NULL; + #endif + return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS); +} + +static inline mi_heap_t* mi_prim_get_default_heap(void) { + mi_heap_t** pheap = mi_prim_tls_pthread_heap_slot(); + if mi_unlikely(pheap == NULL) return _mi_heap_main_get(); + mi_heap_t* heap = *pheap; + if mi_unlikely(heap == NULL) return (mi_heap_t*)&_mi_heap_empty; + return heap; +} + +#elif defined(MI_TLS_PTHREAD) + +extern pthread_key_t _mi_heap_default_key; +static inline mi_heap_t* mi_prim_get_default_heap(void) { + mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key)); + return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); +} + +#else // default using a thread local variable; used on most platforms. + +static inline mi_heap_t* mi_prim_get_default_heap(void) { + #if defined(MI_TLS_RECURSE_GUARD) + if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get(); + #endif + return _mi_heap_default; +} + +#endif // mi_prim_get_default_heap() + + + +#endif // MIMALLOC_PRIM_H diff --git a/Include/internal/mimalloc/mimalloc/track.h b/Include/internal/mimalloc/mimalloc/track.h new file mode 100644 index 00000000000000..fa1a048d846a9c --- /dev/null +++ b/Include/internal/mimalloc/mimalloc/track.h @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_TRACK_H +#define MIMALLOC_TRACK_H + +/* ------------------------------------------------------------------------------------------------------ +Track memory ranges with macros for tools like Valgrind address sanitizer, or other memory checkers. +These can be defined for tracking allocation: + + #define mi_track_malloc_size(p,reqsize,size,zero) + #define mi_track_free_size(p,_size) + +The macros are set up such that the size passed to `mi_track_free_size` +always matches the size of `mi_track_malloc_size`. (currently, `size == mi_usable_size(p)`). +The `reqsize` is what the user requested, and `size >= reqsize`. +The `size` is either byte precise (and `size==reqsize`) if `MI_PADDING` is enabled, +or otherwise it is the usable block size which may be larger than the original request. +Use `_mi_block_size_of(void* p)` to get the full block size that was allocated (including padding etc). +The `zero` parameter is `true` if the allocated block is zero initialized. + +Optional: + + #define mi_track_align(p,alignedp,offset,size) + #define mi_track_resize(p,oldsize,newsize) + #define mi_track_init() + +The `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block. +The corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`). +The `mi_track_resize` is currently unused but could be called on reallocations within a block. +`mi_track_init` is called at program start. + +The following macros are for tools like asan and valgrind to track whether memory is +defined, undefined, or not accessible at all: + + #define mi_track_mem_defined(p,size) + #define mi_track_mem_undefined(p,size) + #define mi_track_mem_noaccess(p,size) + +-------------------------------------------------------------------------------------------------------*/ + +#if MI_TRACK_VALGRIND +// valgrind tool + +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 1 // track free of individual blocks on heap_destroy +#define MI_TRACK_TOOL "valgrind" + +#include +#include + +#define mi_track_malloc_size(p,reqsize,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero) +#define mi_track_free_size(p,_size) VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/) +#define mi_track_resize(p,oldsize,newsize) VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/) +#define mi_track_mem_defined(p,size) VALGRIND_MAKE_MEM_DEFINED(p,size) +#define mi_track_mem_undefined(p,size) VALGRIND_MAKE_MEM_UNDEFINED(p,size) +#define mi_track_mem_noaccess(p,size) VALGRIND_MAKE_MEM_NOACCESS(p,size) + +#elif MI_TRACK_ASAN +// address sanitizer + +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 0 +#define MI_TRACK_TOOL "asan" + +#include + +#define mi_track_malloc_size(p,reqsize,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size) +#define mi_track_free_size(p,size) ASAN_POISON_MEMORY_REGION(p,size) +#define mi_track_mem_defined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size) +#define mi_track_mem_undefined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size) +#define mi_track_mem_noaccess(p,size) ASAN_POISON_MEMORY_REGION(p,size) + +#elif MI_TRACK_ETW +// windows event tracing + +#define MI_TRACK_ENABLED 1 +#define MI_TRACK_HEAP_DESTROY 1 +#define MI_TRACK_TOOL "ETW" + +#define WIN32_LEAN_AND_MEAN +#include +#include "../src/prim/windows/etw.h" + +#define mi_track_init() EventRegistermicrosoft_windows_mimalloc(); +#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size) +#define mi_track_free_size(p,size) EventWriteETW_MI_FREE((UINT64)(p), size) + +#else +// no tracking + +#define MI_TRACK_ENABLED 0 +#define MI_TRACK_HEAP_DESTROY 0 +#define MI_TRACK_TOOL "none" + +#define mi_track_malloc_size(p,reqsize,size,zero) +#define mi_track_free_size(p,_size) + +#endif + +// ------------------- +// Utility definitions + +#ifndef mi_track_resize +#define mi_track_resize(p,oldsize,newsize) mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false) +#endif + +#ifndef mi_track_align +#define mi_track_align(p,alignedp,offset,size) mi_track_mem_noaccess(p,offset) +#endif + +#ifndef mi_track_init +#define mi_track_init() +#endif + +#ifndef mi_track_mem_defined +#define mi_track_mem_defined(p,size) +#endif + +#ifndef mi_track_mem_undefined +#define mi_track_mem_undefined(p,size) +#endif + +#ifndef mi_track_mem_noaccess +#define mi_track_mem_noaccess(p,size) +#endif + + +#if MI_PADDING +#define mi_track_malloc(p,reqsize,zero) \ + if ((p)!=NULL) { \ + mi_assert_internal(mi_usable_size(p)==(reqsize)); \ + mi_track_malloc_size(p,reqsize,reqsize,zero); \ + } +#else +#define mi_track_malloc(p,reqsize,zero) \ + if ((p)!=NULL) { \ + mi_assert_internal(mi_usable_size(p)>=(reqsize)); \ + mi_track_malloc_size(p,reqsize,mi_usable_size(p),zero); \ + } +#endif + +#endif diff --git a/Include/internal/mimalloc/mimalloc/types.h b/Include/internal/mimalloc/mimalloc/types.h new file mode 100644 index 00000000000000..7616f37e4b978f --- /dev/null +++ b/Include/internal/mimalloc/mimalloc/types.h @@ -0,0 +1,670 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_TYPES_H +#define MIMALLOC_TYPES_H + +// -------------------------------------------------------------------------- +// This file contains the main type definitions for mimalloc: +// mi_heap_t : all data for a thread-local heap, contains +// lists of all managed heap pages. +// mi_segment_t : a larger chunk of memory (32GiB) from where pages +// are allocated. +// mi_page_t : a mimalloc page (usually 64KiB or 512KiB) from +// where objects are allocated. +// -------------------------------------------------------------------------- + + +#include // ptrdiff_t +#include // uintptr_t, uint16_t, etc +#include "mimalloc/atomic.h" // _Atomic + +#ifdef _MSC_VER +#pragma warning(disable:4214) // bitfield is not int +#endif + +// Minimal alignment necessary. On most platforms 16 bytes are needed +// due to SSE registers for example. This must be at least `sizeof(void*)` +#ifndef MI_MAX_ALIGN_SIZE +#define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t) +#endif + +// ------------------------------------------------------ +// Variants +// ------------------------------------------------------ + +// Define NDEBUG in the release version to disable assertions. +// #define NDEBUG + +// Define MI_TRACK_ to enable tracking support +// #define MI_TRACK_VALGRIND 1 +// #define MI_TRACK_ASAN 1 +// #define MI_TRACK_ETW 1 + +// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance). +// #define MI_STAT 1 + +// Define MI_SECURE to enable security mitigations +// #define MI_SECURE 1 // guard page around metadata +// #define MI_SECURE 2 // guard page around each mimalloc page +// #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free) +// #define MI_SECURE 4 // checks for double free. (may be more expensive) + +#if !defined(MI_SECURE) +#define MI_SECURE 0 +#endif + +// Define MI_DEBUG for debug mode +// #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free. +// #define MI_DEBUG 2 // + internal assertion checks +// #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON) +#if !defined(MI_DEBUG) +#if !defined(NDEBUG) || defined(_DEBUG) +#define MI_DEBUG 2 +#else +#define MI_DEBUG 0 +#endif +#endif + +// Reserve extra padding at the end of each block to be more resilient against heap block overflows. +// The padding can detect buffer overflow on free. +#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW)) +#define MI_PADDING 1 +#endif + +// Check padding bytes; allows byte-precise buffer overflow detection +#if !defined(MI_PADDING_CHECK) && MI_PADDING && (MI_SECURE>=3 || MI_DEBUG>=1) +#define MI_PADDING_CHECK 1 +#endif + + +// Encoded free lists allow detection of corrupted free lists +// and can detect buffer overflows, modify after free, and double `free`s. +#if (MI_SECURE>=3 || MI_DEBUG>=1) +#define MI_ENCODE_FREELIST 1 +#endif + + +// We used to abandon huge pages but to eagerly deallocate if freed from another thread, +// but that makes it not possible to visit them during a heap walk or include them in a +// `mi_heap_destroy`. We therefore instead reset/decommit the huge blocks if freed from +// another thread so most memory is available until it gets properly freed by the owning thread. +// #define MI_HUGE_PAGE_ABANDON 1 + + +// ------------------------------------------------------ +// Platform specific values +// ------------------------------------------------------ + +// ------------------------------------------------------ +// Size of a pointer. +// We assume that `sizeof(void*)==sizeof(intptr_t)` +// and it holds for all platforms we know of. +// +// However, the C standard only requires that: +// p == (void*)((intptr_t)p)) +// but we also need: +// i == (intptr_t)((void*)i) +// or otherwise one might define an intptr_t type that is larger than a pointer... +// ------------------------------------------------------ + +#if INTPTR_MAX > INT64_MAX +# define MI_INTPTR_SHIFT (4) // assume 128-bit (as on arm CHERI for example) +#elif INTPTR_MAX == INT64_MAX +# define MI_INTPTR_SHIFT (3) +#elif INTPTR_MAX == INT32_MAX +# define MI_INTPTR_SHIFT (2) +#else +#error platform pointers must be 32, 64, or 128 bits +#endif + +#if SIZE_MAX == UINT64_MAX +# define MI_SIZE_SHIFT (3) +typedef int64_t mi_ssize_t; +#elif SIZE_MAX == UINT32_MAX +# define MI_SIZE_SHIFT (2) +typedef int32_t mi_ssize_t; +#else +#error platform objects must be 32 or 64 bits +#endif + +#if (SIZE_MAX/2) > LONG_MAX +# define MI_ZU(x) x##ULL +# define MI_ZI(x) x##LL +#else +# define MI_ZU(x) x##UL +# define MI_ZI(x) x##L +#endif + +#define MI_INTPTR_SIZE (1< 4 +#define MI_SEGMENT_SHIFT ( 9 + MI_SEGMENT_SLICE_SHIFT) // 32MiB +#else +#define MI_SEGMENT_SHIFT ( 7 + MI_SEGMENT_SLICE_SHIFT) // 4MiB on 32-bit +#endif + +#define MI_SMALL_PAGE_SHIFT (MI_SEGMENT_SLICE_SHIFT) // 64KiB +#define MI_MEDIUM_PAGE_SHIFT ( 3 + MI_SMALL_PAGE_SHIFT) // 512KiB + + +// Derived constants +#define MI_SEGMENT_SIZE (MI_ZU(1)<= 655360) +#error "mimalloc internal: define more bins" +#endif + +// Maximum slice offset (15) +#define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1) + +// Used as a special value to encode block sizes in 32 bits. +#define MI_HUGE_BLOCK_SIZE ((uint32_t)(2*MI_GiB)) + +// blocks up to this size are always allocated aligned +#define MI_MAX_ALIGN_GUARANTEE (8*MI_MAX_ALIGN_SIZE) + +// Alignments over MI_ALIGNMENT_MAX are allocated in dedicated huge page segments +#define MI_ALIGNMENT_MAX (MI_SEGMENT_SIZE >> 1) + + +// ------------------------------------------------------ +// Mimalloc pages contain allocated blocks +// ------------------------------------------------------ + +// The free lists use encoded next fields +// (Only actually encodes when MI_ENCODED_FREELIST is defined.) +typedef uintptr_t mi_encoded_t; + +// thread id's +typedef size_t mi_threadid_t; + +// free lists contain blocks +typedef struct mi_block_s { + mi_encoded_t next; +} mi_block_t; + + +// The delayed flags are used for efficient multi-threaded free-ing +typedef enum mi_delayed_e { + MI_USE_DELAYED_FREE = 0, // push on the owning heap thread delayed list + MI_DELAYED_FREEING = 1, // temporary: another thread is accessing the owning heap + MI_NO_DELAYED_FREE = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list + MI_NEVER_DELAYED_FREE = 3 // sticky, only resets on page reclaim +} mi_delayed_t; + + +// The `in_full` and `has_aligned` page flags are put in a union to efficiently +// test if both are false (`full_aligned == 0`) in the `mi_free` routine. +#if !MI_TSAN +typedef union mi_page_flags_s { + uint8_t full_aligned; + struct { + uint8_t in_full : 1; + uint8_t has_aligned : 1; + } x; +} mi_page_flags_t; +#else +// under thread sanitizer, use a byte for each flag to suppress warning, issue #130 +typedef union mi_page_flags_s { + uint16_t full_aligned; + struct { + uint8_t in_full; + uint8_t has_aligned; + } x; +} mi_page_flags_t; +#endif + +// Thread free list. +// We use the bottom 2 bits of the pointer for mi_delayed_t flags +typedef uintptr_t mi_thread_free_t; + +// A page contains blocks of one specific size (`block_size`). +// Each page has three list of free blocks: +// `free` for blocks that can be allocated, +// `local_free` for freed blocks that are not yet available to `mi_malloc` +// `thread_free` for freed blocks by other threads +// The `local_free` and `thread_free` lists are migrated to the `free` list +// when it is exhausted. The separate `local_free` list is necessary to +// implement a monotonic heartbeat. The `thread_free` list is needed for +// avoiding atomic operations in the common case. +// +// +// `used - |thread_free|` == actual blocks that are in use (alive) +// `used - |thread_free| + |free| + |local_free| == capacity` +// +// We don't count `freed` (as |free|) but use `used` to reduce +// the number of memory accesses in the `mi_page_all_free` function(s). +// +// Notes: +// - Access is optimized for `mi_free` and `mi_page_alloc` (in `alloc.c`) +// - Using `uint16_t` does not seem to slow things down +// - The size is 8 words on 64-bit which helps the page index calculations +// (and 10 words on 32-bit, and encoded free lists add 2 words. Sizes 10 +// and 12 are still good for address calculation) +// - To limit the structure size, the `xblock_size` is 32-bits only; for +// blocks > MI_HUGE_BLOCK_SIZE the size is determined from the segment page size +// - `thread_free` uses the bottom bits as a delayed-free flags to optimize +// concurrent frees where only the first concurrent free adds to the owning +// heap `thread_delayed_free` list (see `alloc.c:mi_free_block_mt`). +// The invariant is that no-delayed-free is only set if there is +// at least one block that will be added, or as already been added, to +// the owning heap `thread_delayed_free` list. This guarantees that pages +// will be freed correctly even if only other threads free blocks. +typedef struct mi_page_s { + // "owned" by the segment + uint32_t slice_count; // slices in this page (0 if not a page) + uint32_t slice_offset; // distance from the actual page data slice (0 if a page) + uint8_t is_committed : 1; // `true` if the page virtual memory is committed + uint8_t is_zero_init : 1; // `true` if the page was initially zero initialized + + // layout like this to optimize access in `mi_malloc` and `mi_free` + uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear` + uint16_t reserved; // number of blocks reserved in memory + mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits) + uint8_t free_is_zero : 1; // `true` if the blocks in the free list are zero initialized + uint8_t retire_expire : 7; // expiration count for retired blocks + + mi_block_t* free; // list of available free blocks (`malloc` allocates from this list) + uint32_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`) + uint32_t xblock_size; // size available in each block (always `>0`) + mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`) + + #if (MI_ENCODE_FREELIST || MI_PADDING) + uintptr_t keys[2]; // two random keys to encode the free lists (see `_mi_block_next`) or padding canary + #endif + + _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads + _Atomic(uintptr_t) xheap; + + struct mi_page_s* next; // next page owned by this thread with the same `block_size` + struct mi_page_s* prev; // previous page owned by this thread with the same `block_size` + + // 64-bit 9 words, 32-bit 12 words, (+2 for secure) + #if MI_INTPTR_SIZE==8 + uintptr_t padding[1]; + #endif +} mi_page_t; + + + +// ------------------------------------------------------ +// Mimalloc segments contain mimalloc pages +// ------------------------------------------------------ + +typedef enum mi_page_kind_e { + MI_PAGE_SMALL, // small blocks go into 64KiB pages inside a segment + MI_PAGE_MEDIUM, // medium blocks go into medium pages inside a segment + MI_PAGE_LARGE, // larger blocks go into a page of just one block + MI_PAGE_HUGE, // huge blocks (> 16 MiB) are put into a single page in a single segment. +} mi_page_kind_t; + +typedef enum mi_segment_kind_e { + MI_SEGMENT_NORMAL, // MI_SEGMENT_SIZE size with pages inside. + MI_SEGMENT_HUGE, // > MI_LARGE_SIZE_MAX segment with just one huge page inside. +} mi_segment_kind_t; + +// ------------------------------------------------------ +// A segment holds a commit mask where a bit is set if +// the corresponding MI_COMMIT_SIZE area is committed. +// The MI_COMMIT_SIZE must be a multiple of the slice +// size. If it is equal we have the most fine grained +// decommit (but setting it higher can be more efficient). +// The MI_MINIMAL_COMMIT_SIZE is the minimal amount that will +// be committed in one go which can be set higher than +// MI_COMMIT_SIZE for efficiency (while the decommit mask +// is still tracked in fine-grained MI_COMMIT_SIZE chunks) +// ------------------------------------------------------ + +#define MI_MINIMAL_COMMIT_SIZE (1*MI_SEGMENT_SLICE_SIZE) +#define MI_COMMIT_SIZE (MI_SEGMENT_SLICE_SIZE) // 64KiB +#define MI_COMMIT_MASK_BITS (MI_SEGMENT_SIZE / MI_COMMIT_SIZE) +#define MI_COMMIT_MASK_FIELD_BITS MI_SIZE_BITS +#define MI_COMMIT_MASK_FIELD_COUNT (MI_COMMIT_MASK_BITS / MI_COMMIT_MASK_FIELD_BITS) + +#if (MI_COMMIT_MASK_BITS != (MI_COMMIT_MASK_FIELD_COUNT * MI_COMMIT_MASK_FIELD_BITS)) +#error "the segment size must be exactly divisible by the (commit size * size_t bits)" +#endif + +typedef struct mi_commit_mask_s { + size_t mask[MI_COMMIT_MASK_FIELD_COUNT]; +} mi_commit_mask_t; + +typedef mi_page_t mi_slice_t; +typedef int64_t mi_msecs_t; + + +// Memory can reside in arena's, direct OS allocated, or statically allocated. The memid keeps track of this. +typedef enum mi_memkind_e { + MI_MEM_NONE, // not allocated + MI_MEM_EXTERNAL, // not owned by mimalloc but provided externally (via `mi_manage_os_memory` for example) + MI_MEM_STATIC, // allocated in a static area and should not be freed (for arena meta data for example) + MI_MEM_OS, // allocated from the OS + MI_MEM_OS_HUGE, // allocated as huge os pages + MI_MEM_OS_REMAP, // allocated in a remapable area (i.e. using `mremap`) + MI_MEM_ARENA // allocated from an arena (the usual case) +} mi_memkind_t; + +static inline bool mi_memkind_is_os(mi_memkind_t memkind) { + return (memkind >= MI_MEM_OS && memkind <= MI_MEM_OS_REMAP); +} + +typedef struct mi_memid_os_info { + void* base; // actual base address of the block (used for offset aligned allocations) + size_t alignment; // alignment at allocation +} mi_memid_os_info_t; + +typedef struct mi_memid_arena_info { + size_t block_index; // index in the arena + mi_arena_id_t id; // arena id (>= 1) + bool is_exclusive; // the arena can only be used for specific arena allocations +} mi_memid_arena_info_t; + +typedef struct mi_memid_s { + union { + mi_memid_os_info_t os; // only used for MI_MEM_OS + mi_memid_arena_info_t arena; // only used for MI_MEM_ARENA + } mem; + bool is_pinned; // `true` if we cannot decommit/reset/protect in this memory (e.g. when allocated using large OS pages) + bool initially_committed;// `true` if the memory was originally allocated as committed + bool initially_zero; // `true` if the memory was originally zero initialized + mi_memkind_t memkind; +} mi_memid_t; + + +// Segments are large allocated memory blocks (8mb on 64 bit) from +// the OS. Inside segments we allocated fixed size _pages_ that +// contain blocks. +typedef struct mi_segment_s { + // constant fields + mi_memid_t memid; // memory id for arena allocation + bool allow_decommit; + bool allow_purge; + size_t segment_size; + + // segment fields + mi_msecs_t purge_expire; + mi_commit_mask_t purge_mask; + mi_commit_mask_t commit_mask; + + _Atomic(struct mi_segment_s*) abandoned_next; + + // from here is zero initialized + struct mi_segment_s* next; // the list of freed segments in the cache (must be first field, see `segment.c:mi_segment_init`) + + size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`) + size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long) + size_t used; // count of pages in use + uintptr_t cookie; // verify addresses in debug mode: `mi_ptr_cookie(segment) == segment->cookie` + + size_t segment_slices; // for huge segments this may be different from `MI_SLICES_PER_SEGMENT` + size_t segment_info_slices; // initial slices we are using segment info and possible guard pages. + + // layout like this to optimize access in `mi_free` + mi_segment_kind_t kind; + size_t slice_entries; // entries in the `slices` array, at most `MI_SLICES_PER_SEGMENT` + _Atomic(mi_threadid_t) thread_id; // unique id of the thread owning this segment + + mi_slice_t slices[MI_SLICES_PER_SEGMENT+1]; // one more for huge blocks with large alignment +} mi_segment_t; + + +// ------------------------------------------------------ +// Heaps +// Provide first-class heaps to allocate from. +// A heap just owns a set of pages for allocation and +// can only be allocate/reallocate from the thread that created it. +// Freeing blocks can be done from any thread though. +// Per thread, the segments are shared among its heaps. +// Per thread, there is always a default heap that is +// used for allocation; it is initialized to statically +// point to an empty heap to avoid initialization checks +// in the fast path. +// ------------------------------------------------------ + +// Thread local data +typedef struct mi_tld_s mi_tld_t; + +// Pages of a certain block size are held in a queue. +typedef struct mi_page_queue_s { + mi_page_t* first; + mi_page_t* last; + size_t block_size; +} mi_page_queue_t; + +#define MI_BIN_FULL (MI_BIN_HUGE+1) + +// Random context +typedef struct mi_random_cxt_s { + uint32_t input[16]; + uint32_t output[16]; + int output_available; + bool weak; +} mi_random_ctx_t; + + +// In debug mode there is a padding structure at the end of the blocks to check for buffer overflows +#if (MI_PADDING) +typedef struct mi_padding_s { + uint32_t canary; // encoded block value to check validity of the padding (in case of overflow) + uint32_t delta; // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes) +} mi_padding_t; +#define MI_PADDING_SIZE (sizeof(mi_padding_t)) +#define MI_PADDING_WSIZE ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE) +#else +#define MI_PADDING_SIZE 0 +#define MI_PADDING_WSIZE 0 +#endif + +#define MI_PAGES_DIRECT (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1) + + +// A heap owns a set of pages. +struct mi_heap_s { + mi_tld_t* tld; + mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size. + mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin") + _Atomic(mi_block_t*) thread_delayed_free; + mi_threadid_t thread_id; // thread this heap belongs too + mi_arena_id_t arena_id; // arena id if the heap belongs to a specific arena (or 0) + uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`) + uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list + mi_random_ctx_t random; // random number context used for secure allocation + size_t page_count; // total number of pages in the `pages` queues. + size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues) + size_t page_retired_max; // largest retired index into the `pages` array. + mi_heap_t* next; // list of heaps per thread + bool no_reclaim; // `true` if this heap should not reclaim abandoned pages +}; + + + +// ------------------------------------------------------ +// Debug +// ------------------------------------------------------ + +#if !defined(MI_DEBUG_UNINIT) +#define MI_DEBUG_UNINIT (0xD0) +#endif +#if !defined(MI_DEBUG_FREED) +#define MI_DEBUG_FREED (0xDF) +#endif +#if !defined(MI_DEBUG_PADDING) +#define MI_DEBUG_PADDING (0xDE) +#endif + +#if (MI_DEBUG) +// use our own assertion to print without memory allocation +void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func ); +#define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__)) +#else +#define mi_assert(x) +#endif + +#if (MI_DEBUG>1) +#define mi_assert_internal mi_assert +#else +#define mi_assert_internal(x) +#endif + +#if (MI_DEBUG>2) +#define mi_assert_expensive mi_assert +#else +#define mi_assert_expensive(x) +#endif + +// ------------------------------------------------------ +// Statistics +// ------------------------------------------------------ + +#ifndef MI_STAT +#if (MI_DEBUG>0) +#define MI_STAT 2 +#else +#define MI_STAT 0 +#endif +#endif + +typedef struct mi_stat_count_s { + int64_t allocated; + int64_t freed; + int64_t peak; + int64_t current; +} mi_stat_count_t; + +typedef struct mi_stat_counter_s { + int64_t total; + int64_t count; +} mi_stat_counter_t; + +typedef struct mi_stats_s { + mi_stat_count_t segments; + mi_stat_count_t pages; + mi_stat_count_t reserved; + mi_stat_count_t committed; + mi_stat_count_t reset; + mi_stat_count_t purged; + mi_stat_count_t page_committed; + mi_stat_count_t segments_abandoned; + mi_stat_count_t pages_abandoned; + mi_stat_count_t threads; + mi_stat_count_t normal; + mi_stat_count_t huge; + mi_stat_count_t large; + mi_stat_count_t malloc; + mi_stat_count_t segments_cache; + mi_stat_counter_t pages_extended; + mi_stat_counter_t mmap_calls; + mi_stat_counter_t commit_calls; + mi_stat_counter_t reset_calls; + mi_stat_counter_t purge_calls; + mi_stat_counter_t page_no_retire; + mi_stat_counter_t searches; + mi_stat_counter_t normal_count; + mi_stat_counter_t huge_count; + mi_stat_counter_t large_count; +#if MI_STAT>1 + mi_stat_count_t normal_bins[MI_BIN_HUGE+1]; +#endif +} mi_stats_t; + + +void _mi_stat_increase(mi_stat_count_t* stat, size_t amount); +void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount); +void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount); + +#if (MI_STAT) +#define mi_stat_increase(stat,amount) _mi_stat_increase( &(stat), amount) +#define mi_stat_decrease(stat,amount) _mi_stat_decrease( &(stat), amount) +#define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount) +#else +#define mi_stat_increase(stat,amount) (void)0 +#define mi_stat_decrease(stat,amount) (void)0 +#define mi_stat_counter_increase(stat,amount) (void)0 +#endif + +#define mi_heap_stat_counter_increase(heap,stat,amount) mi_stat_counter_increase( (heap)->tld->stats.stat, amount) +#define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount) +#define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount) + +// ------------------------------------------------------ +// Thread Local data +// ------------------------------------------------------ + +// A "span" is is an available range of slices. The span queues keep +// track of slice spans of at most the given `slice_count` (but more than the previous size class). +typedef struct mi_span_queue_s { + mi_slice_t* first; + mi_slice_t* last; + size_t slice_count; +} mi_span_queue_t; + +#define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT) + +// OS thread local data +typedef struct mi_os_tld_s { + size_t region_idx; // start point for next allocation + mi_stats_t* stats; // points to tld stats +} mi_os_tld_t; + + +// Segments thread local data +typedef struct mi_segments_tld_s { + mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments + size_t count; // current number of segments; + size_t peak_count; // peak number of segments + size_t current_size; // current size of all segments + size_t peak_size; // peak size of all segments + mi_stats_t* stats; // points to tld stats + mi_os_tld_t* os; // points to os stats +} mi_segments_tld_t; + +// Thread local data +struct mi_tld_s { + unsigned long long heartbeat; // monotonic heartbeat count + bool recurse; // true if deferred was called; used to prevent infinite recursion. + mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted) + mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates) + mi_segments_tld_t segments; // segment tld + mi_os_tld_t os; // os tld + mi_stats_t stats; // statistics +}; + +#endif diff --git a/Include/internal/pycore_ast_state.h b/Include/internal/pycore_ast_state.h index 0c0d53f3e5d7e9..6ffd30aca7b11b 100644 --- a/Include/internal/pycore_ast_state.h +++ b/Include/internal/pycore_ast_state.h @@ -2,6 +2,9 @@ #ifndef Py_INTERNAL_AST_STATE_H #define Py_INTERNAL_AST_STATE_H + +#include "pycore_lock.h" // _PyOnceFlag + #ifdef __cplusplus extern "C" { #endif @@ -11,7 +14,8 @@ extern "C" { #endif struct ast_state { - int initialized; + _PyOnceFlag once; + int finalized; int recursion_depth; int recursion_limit; PyObject *AST_type; diff --git a/Include/internal/pycore_atexit.h b/Include/internal/pycore_atexit.h index 3966df70e2616f..4dcda8f517c787 100644 --- a/Include/internal/pycore_atexit.h +++ b/Include/internal/pycore_atexit.h @@ -1,5 +1,8 @@ #ifndef Py_INTERNAL_ATEXIT_H #define Py_INTERNAL_ATEXIT_H + +#include "pycore_lock.h" // PyMutex + #ifdef __cplusplus extern "C" { #endif @@ -15,7 +18,7 @@ extern "C" { typedef void (*atexit_callbackfunc)(void); struct _atexit_runtime_state { - PyThread_type_lock mutex; + PyMutex mutex; #define NEXITFUNCS 32 atexit_callbackfunc callbacks[NEXITFUNCS]; int ncallbacks; diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h deleted file mode 100644 index 22ce971a64f3df..00000000000000 --- a/Include/internal/pycore_atomic.h +++ /dev/null @@ -1,557 +0,0 @@ -#ifndef Py_INTERNAL_ATOMIC_H -#define Py_INTERNAL_ATOMIC_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pyconfig.h" // HAVE_STD_ATOMIC -#include "dynamic_annotations.h" // _Py_ANNOTATE_MEMORY_ORDER - -#ifdef HAVE_STD_ATOMIC -# include // atomic_store_explicit() -#endif - - -#if defined(_MSC_VER) -# 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 - * the draft at - * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf. - * Operations and types are named the same except with a _Py_ prefix - * and have the same semantics. - * - * Beware, the implementations here are deep magic. - */ - -#if defined(HAVE_STD_ATOMIC) - -typedef enum _Py_memory_order { - _Py_memory_order_relaxed = memory_order_relaxed, - _Py_memory_order_acquire = memory_order_acquire, - _Py_memory_order_release = memory_order_release, - _Py_memory_order_acq_rel = memory_order_acq_rel, - _Py_memory_order_seq_cst = memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - atomic_uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - atomic_int _value; -} _Py_atomic_int; - -#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ - atomic_signal_fence(ORDER) - -#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ - atomic_thread_fence(ORDER) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER) - -// Use builtin atomic operations in GCC >= 4.7 and clang -#elif defined(HAVE_BUILTIN_ATOMIC) - -typedef enum _Py_memory_order { - _Py_memory_order_relaxed = __ATOMIC_RELAXED, - _Py_memory_order_acquire = __ATOMIC_ACQUIRE, - _Py_memory_order_release = __ATOMIC_RELEASE, - _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL, - _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST -} _Py_memory_order; - -typedef struct _Py_atomic_address { - uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - int _value; -} _Py_atomic_int; - -#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ - __atomic_signal_fence(ORDER) - -#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ - __atomic_thread_fence(ORDER) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - (assert((ORDER) == __ATOMIC_RELAXED \ - || (ORDER) == __ATOMIC_SEQ_CST \ - || (ORDER) == __ATOMIC_RELEASE), \ - __atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)) - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - (assert((ORDER) == __ATOMIC_RELAXED \ - || (ORDER) == __ATOMIC_SEQ_CST \ - || (ORDER) == __ATOMIC_ACQUIRE \ - || (ORDER) == __ATOMIC_CONSUME), \ - __atomic_load_n(&((ATOMIC_VAL)->_value), ORDER)) - -/* Only support GCC (for expression statements) and x86 (for simple - * atomic semantics) and MSVC x86/x64/ARM */ -#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64)) -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - int _value; -} _Py_atomic_int; - - -static __inline__ void -_Py_atomic_signal_fence(_Py_memory_order order) -{ - if (order != _Py_memory_order_relaxed) - __asm__ volatile("":::"memory"); -} - -static __inline__ void -_Py_atomic_thread_fence(_Py_memory_order order) -{ - if (order != _Py_memory_order_relaxed) - __asm__ volatile("mfence":::"memory"); -} - -/* Tell the race checker about this operation's effects. */ -static __inline__ void -_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) -{ - (void)address; /* shut up -Wunused-parameter */ - switch(order) { - case _Py_memory_order_release: - case _Py_memory_order_acq_rel: - case _Py_memory_order_seq_cst: - _Py_ANNOTATE_HAPPENS_BEFORE(address); - break; - case _Py_memory_order_relaxed: - case _Py_memory_order_acquire: - break; - } - switch(order) { - case _Py_memory_order_acquire: - case _Py_memory_order_acq_rel: - case _Py_memory_order_seq_cst: - _Py_ANNOTATE_HAPPENS_AFTER(address); - break; - case _Py_memory_order_relaxed: - case _Py_memory_order_release: - break; - } -} - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - __extension__ ({ \ - __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ - __typeof__(atomic_val->_value) new_val = NEW_VAL;\ - volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \ - _Py_memory_order order = ORDER; \ - _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ - \ - /* Perform the operation. */ \ - _Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \ - switch(order) { \ - case _Py_memory_order_release: \ - _Py_atomic_signal_fence(_Py_memory_order_release); \ - /* fallthrough */ \ - case _Py_memory_order_relaxed: \ - *volatile_data = new_val; \ - break; \ - \ - case _Py_memory_order_acquire: \ - case _Py_memory_order_acq_rel: \ - case _Py_memory_order_seq_cst: \ - __asm__ volatile("xchg %0, %1" \ - : "+r"(new_val) \ - : "m"(atomic_val->_value) \ - : "memory"); \ - break; \ - } \ - _Py_ANNOTATE_IGNORE_WRITES_END(); \ - }) - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - __extension__ ({ \ - __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ - __typeof__(atomic_val->_value) result; \ - volatile __typeof__(result) *volatile_data = &atomic_val->_value; \ - _Py_memory_order order = ORDER; \ - _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ - \ - /* Perform the operation. */ \ - _Py_ANNOTATE_IGNORE_READS_BEGIN(); \ - switch(order) { \ - case _Py_memory_order_release: \ - case _Py_memory_order_acq_rel: \ - case _Py_memory_order_seq_cst: \ - /* Loads on x86 are not releases by default, so need a */ \ - /* thread fence. */ \ - _Py_atomic_thread_fence(_Py_memory_order_release); \ - break; \ - default: \ - /* No fence */ \ - break; \ - } \ - result = *volatile_data; \ - switch(order) { \ - case _Py_memory_order_acquire: \ - case _Py_memory_order_acq_rel: \ - case _Py_memory_order_seq_cst: \ - /* Loads on x86 are automatically acquire operations so */ \ - /* can get by with just a compiler fence. */ \ - _Py_atomic_signal_fence(_Py_memory_order_acquire); \ - break; \ - default: \ - /* No fence */ \ - break; \ - } \ - _Py_ANNOTATE_IGNORE_READS_END(); \ - result; \ - }) - -#elif defined(_MSC_VER) -/* _Interlocked* functions provide a full memory barrier and are therefore - enough for acq_rel and seq_cst. If the HLE variants aren't available - in hardware they will fall back to a full memory barrier as well. - - This might affect performance but likely only in some very specific and - hard to measure scenario. -*/ -#if defined(_M_IX86) || defined(_M_X64) -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - volatile uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - volatile int _value; -} _Py_atomic_int; - - -#if defined(_M_X64) -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ - break; \ - default: \ - _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ - break; \ - } -#else -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); -#endif - -#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ - break; \ - default: \ - _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ - break; \ - } - -#if defined(_M_X64) -/* This has to be an intptr_t for now. - gil_created() uses -1 as a sentinel value, if this returns - a uintptr_t it will do an unsigned compare and crash -*/ -inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { - __int64 old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) - -#else -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) -#endif - -inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { - long old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange((volatile long*)value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - if (sizeof((ATOMIC_VAL)->_value) == 8) { \ - _Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \ - _Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) } - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - ( \ - sizeof((ATOMIC_VAL)->_value) == 8 ? \ - _Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \ - _Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \ - ) -#elif defined(_M_ARM) || defined(_M_ARM64) -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - volatile uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - volatile int _value; -} _Py_atomic_int; - - -#if defined(_M_ARM64) -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ - break; \ - default: \ - _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ - break; \ - } -#else -#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); -#endif - -#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ - switch (ORDER) { \ - case _Py_memory_order_acquire: \ - _InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ - break; \ - case _Py_memory_order_release: \ - _InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ - break; \ - default: \ - _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ - break; \ - } - -#if defined(_M_ARM64) -/* This has to be an intptr_t for now. - gil_created() uses -1 as a sentinel value, if this returns - a uintptr_t it will do an unsigned compare and crash -*/ -inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { - uintptr_t old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_acq(value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange64_rel(value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange64(value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) - -#else -#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) -#endif - -inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { - int old; - switch (order) { - case _Py_memory_order_acquire: - { - do { - old = *value; - } while(_InterlockedCompareExchange_acq(value, old, old) != old); - break; - } - case _Py_memory_order_release: - { - do { - old = *value; - } while(_InterlockedCompareExchange_rel(value, old, old) != old); - break; - } - case _Py_memory_order_relaxed: - old = *value; - break; - default: - { - do { - old = *value; - } while(_InterlockedCompareExchange(value, old, old) != old); - break; - } - } - return old; -} - -#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ - _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) - -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - if (sizeof((ATOMIC_VAL)->_value) == 8) { \ - _Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \ - _Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } - -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - ( \ - sizeof((ATOMIC_VAL)->_value) == 8 ? \ - _Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \ - _Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \ - ) -#endif -#else /* !gcc x86 !_msc_ver */ -typedef enum _Py_memory_order { - _Py_memory_order_relaxed, - _Py_memory_order_acquire, - _Py_memory_order_release, - _Py_memory_order_acq_rel, - _Py_memory_order_seq_cst -} _Py_memory_order; - -typedef struct _Py_atomic_address { - uintptr_t _value; -} _Py_atomic_address; - -typedef struct _Py_atomic_int { - int _value; -} _Py_atomic_int; -/* Fall back to other compilers and processors by assuming that simple - volatile accesses are atomic. This is false, so people should port - this. */ -#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0) -#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0) -#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ - ((ATOMIC_VAL)->_value = NEW_VAL) -#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ - ((ATOMIC_VAL)->_value) -#endif - -/* Standardized shortcuts. */ -#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ - _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst) -#define _Py_atomic_load(ATOMIC_VAL) \ - _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst) - -/* Python-local extensions */ - -#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ - _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed) -#define _Py_atomic_load_relaxed(ATOMIC_VAL) \ - _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed) - -#ifdef __cplusplus -} -#endif -#endif /* Py_INTERNAL_ATOMIC_H */ diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h index 8846155b38defb..c92028a01299e2 100644 --- a/Include/internal/pycore_call.h +++ b/Include/internal/pycore_call.h @@ -31,18 +31,6 @@ PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult( PyObject *result, const char *where); -/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple) - format to a Python dictionary ("kwargs" dict). - - The type of kwnames keys is not checked. The final function getting - arguments is responsible to check if all keys are strings, for example using - PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments(). - - Duplicate keys are merged using the last value. If duplicate keys must raise - an exception, the caller is responsible to implement an explicit keys on - kwnames. */ -extern PyObject* _PyStack_AsDict(PyObject *const *values, PyObject *kwnames); - extern PyObject* _PyObject_Call_Prepend( PyThreadState *tstate, PyObject *callable, @@ -75,13 +63,6 @@ PyAPI_FUNC(PyObject*) _PyObject_CallMethod( PyObject *name, const char *format, ...); -/* Like PyObject_CallMethod(), but expect a _Py_Identifier* - as the method name. */ -extern PyObject* _PyObject_CallMethodId( - PyObject *obj, - _Py_Identifier *name, - const char *format, ...); - extern PyObject* _PyObject_CallMethodIdObjArgs( PyObject *obj, _Py_Identifier *name, diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 23d0fa399d7e6f..a357bfa3a26064 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -8,6 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "dynamic_annotations.h" // _Py_ANNOTATE_RWLOCK_CREATE + #include "pycore_interp.h" // PyInterpreterState.eval_frame #include "pycore_pystate.h" // _PyThreadState_GET() @@ -20,6 +22,8 @@ PyAPI_FUNC(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyO extern int _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); +extern int _PyEval_SetOpcodeTrace(PyFrameObject *f, bool enable); + // Helper to look up a builtin object // Export for 'array' shared extension PyAPI_FUNC(PyObject*) _PyEval_GetBuiltin(PyObject *); @@ -37,16 +41,19 @@ PyAPI_FUNC(int) _PyEval_MakePendingCalls(PyThreadState *); #endif extern void _Py_FinishPendingCalls(PyThreadState *tstate); -extern void _PyEval_InitState(PyInterpreterState *, PyThread_type_lock); -extern void _PyEval_FiniState(struct _ceval_state *ceval); +extern void _PyEval_InitState(PyInterpreterState *); 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, _Py_pending_call_func func, void *arg, - int mainthreadonly); + int flags); extern void _PyEval_SignalAsyncExc(PyInterpreterState *interp); #ifdef HAVE_FORK @@ -93,6 +100,7 @@ extern int _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *); extern void _PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *); extern int _PyPerfTrampoline_Init(int activate); extern int _PyPerfTrampoline_Fini(void); +extern void _PyPerfTrampoline_FreeArenas(void); extern int _PyIsPerfTrampolineActive(void); extern PyStatus _PyPerfTrampoline_AfterFork_Child(void); #ifdef PY_HAVE_PERF_TRAMPOLINE @@ -116,12 +124,11 @@ _PyEval_Vector(PyThreadState *tstate, PyObject *kwnames); extern int _PyEval_ThreadsInitialized(void); -extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil); +extern void _PyEval_InitGIL(PyThreadState *tstate, int own_gil); 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); @@ -193,6 +200,39 @@ int _PyEval_UnpackIterable(PyThreadState *tstate, PyObject *v, int argcnt, int a 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 } #endif diff --git a/Include/internal/pycore_ceval_state.h b/Include/internal/pycore_ceval_state.h index d0af5b542233e0..28738980eb49be 100644 --- a/Include/internal/pycore_ceval_state.h +++ b/Include/internal/pycore_ceval_state.h @@ -8,6 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_lock.h" // PyMutex #include "pycore_gil.h" // struct _gil_runtime_state @@ -15,17 +16,14 @@ typedef int (*_Py_pending_call_func)(void *); struct _pending_calls { int busy; - PyThread_type_lock lock; + PyMutex mutex; /* 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 { _Py_pending_call_func func; void *arg; + int flags; } calls[NPENDINGCALLS]; int first; int last; @@ -58,15 +56,11 @@ struct _ceval_runtime_state { struct code_arena_st *code_arena; struct trampoline_api_st trampoline_api; FILE *map_file; + Py_ssize_t persist_after_fork; #else int _not_used; #endif } perf; - /* Request for checking signals. It is shared by all interpreters (see - bpo-40513). Any thread of any interpreter can receive a signal, but only - the main thread of the main interpreter can handle signals: see - _Py_ThreadCanHandleSignals(). */ - _Py_atomic_int signals_pending; /* Pending calls to be made only on the main thread. */ struct _pending_calls pending_mainthread; }; @@ -76,6 +70,7 @@ struct _ceval_runtime_state { { \ .status = PERF_STATUS_NO_INIT, \ .extra_code_index = -1, \ + .persist_after_fork = 0, \ } #else # define _PyEval_RUNTIME_PERF_INIT {0} @@ -87,14 +82,12 @@ struct _ceval_state { * the fast path in the eval loop. * It is by far the hottest field in this struct and * should be placed at the beginning. */ - _Py_atomic_int eval_breaker; - /* Request for dropping the GIL */ - _Py_atomic_int gil_drop_request; + 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 a77fa11baf8413..73df6c3568ffe0 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -271,6 +271,8 @@ extern int _PyStaticCode_Init(PyCodeObject *co); #ifdef Py_STATS +#include "pycore_bitutils.h" // _Py_bit_length + #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) @@ -282,6 +284,17 @@ extern int _PyStaticCode_Init(PyCodeObject *co); #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) #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_STAT_INC(opname, name) do { if (_Py_stats) { assert(opname < 512); _Py_stats->optimization_stats.opcode[opname].name++; } } 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); @@ -296,6 +309,10 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #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_STAT_INC(opname, name) ((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. @@ -377,27 +394,29 @@ write_varint(uint8_t *ptr, unsigned int val) val >>= 6; written++; } - *ptr = val; + *ptr = (uint8_t)val; return written; } static inline int write_signed_varint(uint8_t *ptr, int val) { + unsigned int uval; if (val < 0) { - val = ((-val)<<1) | 1; + // (unsigned int)(-val) has an undefined behavior for INT_MIN + uval = ((0 - (unsigned int)val) << 1) | 1; } else { - val = val << 1; + uval = (unsigned int)val << 1; } - return write_varint(ptr, val); + return write_varint(ptr, uval); } static inline int write_location_entry_start(uint8_t *ptr, int code, int length) { assert((code & 15) == code); - *ptr = 128 | (code << 3) | (length - 1); + *ptr = 128 | (uint8_t)(code << 3) | (uint8_t)(length - 1); return 1; } @@ -437,9 +456,9 @@ write_location_entry_start(uint8_t *ptr, int code, int length) static inline uint16_t -adaptive_counter_bits(int value, int backoff) { - return (value << ADAPTIVE_BACKOFF_BITS) | - (backoff & ((1< MAX_BACKOFF_VALUE) { backoff = MAX_BACKOFF_VALUE; } - unsigned int value = (1 << backoff) - 1; + uint16_t value = (uint16_t)(1 << backoff) - 1; return adaptive_counter_bits(value, backoff); } diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index a5a7146f5ee917..e5870759ba74f1 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -102,6 +102,20 @@ int _PyCompile_EnsureArrayLargeEnough( int _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj); + +// Export for '_opcode' extention module +PyAPI_FUNC(int) _PyCompile_OpcodeIsValid(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasArg(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasConst(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasName(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasJump(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasFree(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasLocal(int opcode); +PyAPI_FUNC(int) _PyCompile_OpcodeHasExc(int opcode); + +PyAPI_FUNC(PyObject*) _PyCompile_GetUnaryIntrinsicName(int index); +PyAPI_FUNC(PyObject*) _PyCompile_GetBinaryIntrinsicName(int index); + /* Access compiler internals for unit testing */ // Export for '_testinternalcapi' shared extension diff --git a/Include/internal/pycore_complexobject.h b/Include/internal/pycore_complexobject.h index a6fee9d23f3a9f..54713536eedc46 100644 --- a/Include/internal/pycore_complexobject.h +++ b/Include/internal/pycore_complexobject.h @@ -10,16 +10,6 @@ extern "C" { #include "pycore_unicodeobject.h" // _PyUnicodeWriter -// 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); -PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); -PyAPI_FUNC(double) _Py_c_abs(Py_complex); - /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ extern int _PyComplex_FormatAdvancedWriter( diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h index 489e67d4ec4f9f..34c21aaad43197 100644 --- a/Include/internal/pycore_condvar.h +++ b/Include/internal/pycore_condvar.h @@ -5,18 +5,8 @@ # error "this header requires Py_BUILD_CORE define" #endif -#ifndef MS_WINDOWS -# include // _POSIX_THREADS -#endif +#include "pycore_pythread.h" // _POSIX_THREADS -#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 #ifdef _POSIX_THREADS /* diff --git a/Include/internal/pycore_critical_section.h b/Include/internal/pycore_critical_section.h new file mode 100644 index 00000000000000..bf2bbfffc38bd0 --- /dev/null +++ b/Include/internal/pycore_critical_section.h @@ -0,0 +1,242 @@ +#ifndef Py_INTERNAL_CRITICAL_SECTION_H +#define Py_INTERNAL_CRITICAL_SECTION_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_lock.h" // PyMutex +#include "pycore_pystate.h" // _PyThreadState_GET() +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Implementation of Python critical sections +// +// Conceptually, critical sections are a deadlock avoidance layer on top of +// per-object locks. These helpers, in combination with those locks, replace +// our usage of the global interpreter lock to provide thread-safety for +// otherwise thread-unsafe objects, such as dict. +// +// NOTE: These APIs are no-ops in non-free-threaded builds. +// +// Straightforward per-object locking could introduce deadlocks that were not +// present when running with the GIL. Threads may hold locks for multiple +// objects simultaneously because Python operations can nest. If threads were +// to acquire the same locks in different orders, they would deadlock. +// +// One way to avoid deadlocks is to allow threads to hold only the lock (or +// locks) for a single operation at a time (typically a single lock, but some +// operations involve two locks). When a thread begins a nested operation it +// could suspend the locks for any outer operation: before beginning the nested +// operation, the locks for the outer operation are released and when the +// nested operation completes, the locks for the outer operation are +// reacquired. +// +// To improve performance, this API uses a variation of the above scheme. +// Instead of immediately suspending locks any time a nested operation begins, +// locks are only suspended if the thread would block. This reduces the number +// of lock acquisitions and releases for nested operations, while still +// avoiding deadlocks. +// +// Additionally, the locks for any active operation are suspended around +// other potentially blocking operations, such as I/O. This is because the +// interaction between locks and blocking operations can lead to deadlocks in +// the same way as the interaction between multiple locks. +// +// Each thread's critical sections and their corresponding locks are tracked in +// a stack in `PyThreadState.critical_section`. When a thread calls +// `_PyThreadState_Detach()`, such as before a blocking I/O operation or when +// waiting to acquire a lock, the thread suspends all of its active critical +// sections, temporarily releasing the associated locks. When the thread calls +// `_PyThreadState_Attach()`, it resumes the top-most (i.e., most recent) +// critical section by reacquiring the associated lock or locks. See +// `_PyCriticalSection_Resume()`. +// +// NOTE: Only the top-most critical section is guaranteed to be active. +// Operations that need to lock two objects at once must use +// `Py_BEGIN_CRITICAL_SECTION2()`. You *CANNOT* use nested critical sections +// to lock more than one object at once, because the inner critical section +// may suspend the outer critical sections. This API does not provide a way +// to lock more than two objects at once (though it could be added later +// if actually needed). +// +// NOTE: Critical sections implicitly behave like reentrant locks because +// attempting to acquire the same lock will suspend any outer (earlier) +// critical sections. However, they are less efficient for this use case than +// purposefully designed reentrant locks. +// +// Example usage: +// Py_BEGIN_CRITICAL_SECTION(op); +// ... +// Py_END_CRITICAL_SECTION(); +// +// To lock two objects at once: +// Py_BEGIN_CRITICAL_SECTION2(op1, op2); +// ... +// Py_END_CRITICAL_SECTION2(); + + +// Tagged pointers to critical sections use the two least significant bits to +// mark if the pointed-to critical section is inactive and whether it is a +// _PyCriticalSection2 object. +#define _Py_CRITICAL_SECTION_INACTIVE 0x1 +#define _Py_CRITICAL_SECTION_TWO_MUTEXES 0x2 +#define _Py_CRITICAL_SECTION_MASK 0x3 + +#ifdef Py_GIL_DISABLED +# define Py_BEGIN_CRITICAL_SECTION(op) \ + { \ + _PyCriticalSection _cs; \ + _PyCriticalSection_Begin(&_cs, &_PyObject_CAST(op)->ob_mutex) + +# define Py_END_CRITICAL_SECTION() \ + _PyCriticalSection_End(&_cs); \ + } + +# define Py_BEGIN_CRITICAL_SECTION2(a, b) \ + { \ + _PyCriticalSection2 _cs2; \ + _PyCriticalSection2_Begin(&_cs2, &_PyObject_CAST(a)->ob_mutex, &_PyObject_CAST(b)->ob_mutex) + +# define Py_END_CRITICAL_SECTION2() \ + _PyCriticalSection2_End(&_cs2); \ + } +#else /* !Py_GIL_DISABLED */ +// The critical section APIs are no-ops with the GIL. +# define Py_BEGIN_CRITICAL_SECTION(op) +# define Py_END_CRITICAL_SECTION() +# define Py_BEGIN_CRITICAL_SECTION2(a, b) +# define Py_END_CRITICAL_SECTION2() +#endif /* !Py_GIL_DISABLED */ + +typedef struct { + // Tagged pointer to an outer active critical section (or 0). + // The two least-significant-bits indicate whether the pointed-to critical + // section is inactive and whether it is a _PyCriticalSection2 object. + uintptr_t prev; + + // Mutex used to protect critical section + PyMutex *mutex; +} _PyCriticalSection; + +// A critical section protected by two mutexes. Use +// _PyCriticalSection2_Begin and _PyCriticalSection2_End. +typedef struct { + _PyCriticalSection base; + + PyMutex *mutex2; +} _PyCriticalSection2; + +static inline int +_PyCriticalSection_IsActive(uintptr_t tag) +{ + return tag != 0 && (tag & _Py_CRITICAL_SECTION_INACTIVE) == 0; +} + +// Resumes the top-most critical section. +PyAPI_FUNC(void) +_PyCriticalSection_Resume(PyThreadState *tstate); + +// (private) slow path for locking the mutex +PyAPI_FUNC(void) +_PyCriticalSection_BeginSlow(_PyCriticalSection *c, PyMutex *m); + +PyAPI_FUNC(void) +_PyCriticalSection2_BeginSlow(_PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2, + int is_m1_locked); + +static inline void +_PyCriticalSection_Begin(_PyCriticalSection *c, PyMutex *m) +{ + if (PyMutex_LockFast(&m->v)) { + PyThreadState *tstate = _PyThreadState_GET(); + c->mutex = m; + c->prev = tstate->critical_section; + tstate->critical_section = (uintptr_t)c; + } + else { + _PyCriticalSection_BeginSlow(c, m); + } +} + +// Removes the top-most critical section from the thread's stack of critical +// sections. If the new top-most critical section is inactive, then it is +// resumed. +static inline void +_PyCriticalSection_Pop(_PyCriticalSection *c) +{ + PyThreadState *tstate = _PyThreadState_GET(); + uintptr_t prev = c->prev; + tstate->critical_section = prev; + + if ((prev & _Py_CRITICAL_SECTION_INACTIVE) != 0) { + _PyCriticalSection_Resume(tstate); + } +} + +static inline void +_PyCriticalSection_End(_PyCriticalSection *c) +{ + PyMutex_Unlock(c->mutex); + _PyCriticalSection_Pop(c); +} + +static inline void +_PyCriticalSection2_Begin(_PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2) +{ + if (m1 == m2) { + // If the two mutex arguments are the same, treat this as a critical + // section with a single mutex. + c->mutex2 = NULL; + _PyCriticalSection_Begin(&c->base, m1); + return; + } + + if ((uintptr_t)m2 < (uintptr_t)m1) { + // Sort the mutexes so that the lower address is locked first. + // The exact order does not matter, but we need to acquire the mutexes + // in a consistent order to avoid lock ordering deadlocks. + PyMutex *tmp = m1; + m1 = m2; + m2 = tmp; + } + + if (PyMutex_LockFast(&m1->v)) { + if (PyMutex_LockFast(&m2->v)) { + PyThreadState *tstate = _PyThreadState_GET(); + c->base.mutex = m1; + c->mutex2 = m2; + c->base.prev = tstate->critical_section; + + uintptr_t p = (uintptr_t)c | _Py_CRITICAL_SECTION_TWO_MUTEXES; + tstate->critical_section = p; + } + else { + _PyCriticalSection2_BeginSlow(c, m1, m2, 1); + } + } + else { + _PyCriticalSection2_BeginSlow(c, m1, m2, 0); + } +} + +static inline void +_PyCriticalSection2_End(_PyCriticalSection2 *c) +{ + if (c->mutex2) { + PyMutex_Unlock(c->mutex2); + } + PyMutex_Unlock(c->base.mutex); + _PyCriticalSection_Pop(&c->base); +} + +PyAPI_FUNC(void) +_PyCriticalSection_SuspendAll(PyThreadState *tstate); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CRITICAL_SECTION_H */ diff --git a/Include/internal/pycore_crossinterp.h b/Include/internal/pycore_crossinterp.h new file mode 100644 index 00000000000000..d6e297a7e8e6db --- /dev/null +++ b/Include/internal/pycore_crossinterp.h @@ -0,0 +1,293 @@ +#ifndef Py_INTERNAL_CROSSINTERP_H +#define Py_INTERNAL_CROSSINTERP_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_lock.h" // PyMutex +#include "pycore_pyerrors.h" + +/**************/ +/* exceptions */ +/**************/ + +PyAPI_DATA(PyObject *) PyExc_InterpreterError; +PyAPI_DATA(PyObject *) PyExc_InterpreterNotFoundError; + + +/***************************/ +/* cross-interpreter calls */ +/***************************/ + +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); + + +/**************************/ +/* cross-interpreter data */ +/**************************/ + +typedef struct _xid _PyCrossInterpreterData; +typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *); +typedef void (*xid_freefunc)(void *); + +// _PyCrossInterpreterData is similar to Py_buffer as an effectively +// opaque struct that holds data outside the object machinery. This +// is necessary to pass safely between interpreters in the same process. +struct _xid { + // data is the cross-interpreter-safe derivation of a Python object + // (see _PyObject_GetCrossInterpreterData). It will be NULL if the + // new_object func (below) encodes the data. + void *data; + // obj is the Python object from which the data was derived. This + // is non-NULL only if the data remains bound to the object in some + // way, such that the object must be "released" (via a decref) when + // the data is released. In that case the code that sets the field, + // likely a registered "crossinterpdatafunc", is responsible for + // ensuring it owns the reference (i.e. incref). + PyObject *obj; + // interp is the ID of the owning interpreter of the original + // object. It corresponds to the active interpreter when + // _PyObject_GetCrossInterpreterData() was called. This should only + // be set by the cross-interpreter machinery. + // + // We use the ID rather than the PyInterpreterState to avoid issues + // with deleted interpreters. Note that IDs are never re-used, so + // each one will always correspond to a specific interpreter + // (whether still alive or not). + int64_t interpid; + // new_object is a function that returns a new object in the current + // interpreter given the data. The resulting object (a new + // reference) will be equivalent to the original object. This field + // is required. + xid_newobjectfunc new_object; + // free is called when the data is released. If it is NULL then + // nothing will be done to free the data. For some types this is + // okay (e.g. bytes) and for those types this field should be set + // to NULL. However, for most the data was allocated just for + // cross-interpreter use, so it must be freed when + // _PyCrossInterpreterData_Release is called or the memory will + // leak. In that case, at the very least this field should be set + // to PyMem_RawFree (the default if not explicitly set to NULL). + // The call will happen with the original interpreter activated. + xid_freefunc free; +}; + +PyAPI_FUNC(_PyCrossInterpreterData *) _PyCrossInterpreterData_New(void); +PyAPI_FUNC(void) _PyCrossInterpreterData_Free(_PyCrossInterpreterData *data); + + +/* defining cross-interpreter data */ + +PyAPI_FUNC(void) _PyCrossInterpreterData_Init( + _PyCrossInterpreterData *data, + PyInterpreterState *interp, void *shared, PyObject *obj, + xid_newobjectfunc new_object); +PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize( + _PyCrossInterpreterData *, + PyInterpreterState *interp, const size_t, PyObject *, + xid_newobjectfunc); +PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( + PyInterpreterState *, _PyCrossInterpreterData *); + + +/* using cross-interpreter data */ + +PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); +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 *); + + +/* 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. + +typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *, + _PyCrossInterpreterData *); + +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 { + int global; /* builtin types or heap types */ + int initialized; + PyMutex mutex; + struct _xidregitem *head; +}; + +PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); +PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *); +PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); + + +/*****************************/ +/* runtime state & lifecycle */ +/*****************************/ + +struct _xi_runtime_state { + // builtin types + // XXX Remove this field once we have a tp_* slot. + struct _xidregistry registry; +}; + +struct _xi_state { + // heap types + // XXX Remove this field once we have a tp_* slot. + struct _xidregistry registry; + + // heap types + PyObject *PyExc_NotShareableError; +}; + +extern PyStatus _PyXI_Init(PyInterpreterState *interp); +extern void _PyXI_Fini(PyInterpreterState *interp); + +extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp); +extern void _PyXI_FiniTypes(PyInterpreterState *interp); + + +/***************************/ +/* short-term data sharing */ +/***************************/ + +// Ultimately we'd like to preserve enough information about the +// exception and traceback that we could re-constitute (or at least +// simulate, a la traceback.TracebackException), and even chain, a copy +// of the exception in the calling interpreter. + +typedef struct _excinfo { + struct _excinfo_type { + PyTypeObject *builtin; + const char *name; + const char *qualname; + const char *module; + } type; + const char *msg; + const char *errdisplay; +} _PyXI_excinfo; + + +typedef enum error_code { + _PyXI_ERR_NO_ERROR = 0, + _PyXI_ERR_UNCAUGHT_EXCEPTION = -1, + _PyXI_ERR_OTHER = -2, + _PyXI_ERR_NO_MEMORY = -3, + _PyXI_ERR_ALREADY_RUNNING = -4, + _PyXI_ERR_MAIN_NS_FAILURE = -5, + _PyXI_ERR_APPLY_NS_FAILURE = -6, + _PyXI_ERR_NOT_SHAREABLE = -7, +} _PyXI_errcode; + + +typedef struct _sharedexception { + // The originating interpreter. + PyInterpreterState *interp; + // The kind of error to propagate. + _PyXI_errcode code; + // The exception information to propagate, if applicable. + // This is populated only for some error codes, + // but always for _PyXI_ERR_UNCAUGHT_EXCEPTION. + _PyXI_excinfo uncaught; +} _PyXI_error; + +PyAPI_FUNC(PyObject *) _PyXI_ApplyError(_PyXI_error *err); + + +typedef struct xi_session _PyXI_session; +typedef struct _sharedns _PyXI_namespace; + +PyAPI_FUNC(void) _PyXI_FreeNamespace(_PyXI_namespace *ns); +PyAPI_FUNC(_PyXI_namespace *) _PyXI_NamespaceFromNames(PyObject *names); +PyAPI_FUNC(int) _PyXI_FillNamespaceFromDict( + _PyXI_namespace *ns, + PyObject *nsobj, + _PyXI_session *session); +PyAPI_FUNC(int) _PyXI_ApplyNamespace( + _PyXI_namespace *ns, + PyObject *nsobj, + PyObject *dflt); + + +// A cross-interpreter session involves entering an interpreter +// (_PyXI_Enter()), doing some work with it, and finally exiting +// that interpreter (_PyXI_Exit()). +// +// At the boundaries of the session, both entering and exiting, +// data may be exchanged between the previous interpreter and the +// target one in a thread-safe way that does not violate the +// isolation between interpreters. This includes setting objects +// in the target's __main__ module on the way in, and capturing +// uncaught exceptions on the way out. +struct xi_session { + // Once a session has been entered, this is the tstate that was + // current before the session. If it is different from cur_tstate + // then we must have switched interpreters. Either way, this will + // be the current tstate once we exit the session. + PyThreadState *prev_tstate; + // Once a session has been entered, this is the current tstate. + // It must be current when the session exits. + PyThreadState *init_tstate; + // This is true if init_tstate needs cleanup during exit. + int own_init_tstate; + + // This is true if, while entering the session, init_thread took + // "ownership" of the interpreter's __main__ module. This means + // it is the only thread that is allowed to run code there. + // (Caveat: for now, users may still run exec() against the + // __main__ module's dict, though that isn't advisable.) + int running; + // This is a cached reference to the __dict__ of the entered + // interpreter's __main__ module. It is looked up when at the + // beginning of the session as a convenience. + PyObject *main_ns; + + // This is set if the interpreter is entered and raised an exception + // that needs to be handled in some special way during exit. + _PyXI_errcode *error_override; + // This is set if exit captured an exception to propagate. + _PyXI_error *error; + + // -- pre-allocated memory -- + _PyXI_error _error; + _PyXI_errcode _error_override; +}; + +PyAPI_FUNC(int) _PyXI_Enter( + _PyXI_session *session, + PyInterpreterState *interp, + PyObject *nsupdates); +PyAPI_FUNC(void) _PyXI_Exit(_PyXI_session *session); + +PyAPI_FUNC(PyObject *) _PyXI_ApplyCapturedException(_PyXI_session *session); +PyAPI_FUNC(int) _PyXI_HasCapturedException(_PyXI_session *session); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CROSSINTERP_H */ diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 47b5948f66343a..d96870e9197bbf 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -19,9 +19,6 @@ 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); @@ -44,14 +41,9 @@ 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, @@ -119,7 +111,11 @@ extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); extern int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value); extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); -extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); +extern int _PyDict_Pop_KnownHash( + PyDictObject *dict, + PyObject *key, + Py_hash_t hash, + PyObject **result); #define DKIX_EMPTY (-1) #define DKIX_DUMMY (-2) /* Used internally */ diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h index ac62a4d300720a..c5cfdf4ce8f823 100644 --- a/Include/internal/pycore_dtoa.h +++ b/Include/internal/pycore_dtoa.h @@ -35,6 +35,9 @@ struct _dtoa_state { /* The size of the Bigint freelist */ #define Bigint_Kmax 7 +/* The size of the cached powers of 5 array */ +#define Bigint_Pow5size 8 + #ifndef PRIVATE_MEM #define PRIVATE_MEM 2304 #endif @@ -42,9 +45,10 @@ struct _dtoa_state { ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) struct _dtoa_state { - /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ + // p5s is an array of powers of 5 of the form: + // 5**(2**(i+2)) for 0 <= i < Bigint_Pow5size + struct Bigint *p5s[Bigint_Pow5size]; // XXX This should be freed during runtime fini. - struct Bigint *p5s; struct Bigint *freelist[Bigint_Kmax+1]; double preallocated[Bigint_PREALLOC_SIZE]; double *preallocated_next; @@ -57,9 +61,6 @@ struct _dtoa_state { #endif // !Py_USING_MEMORY_DEBUGGER -/* These functions are used by modules compiled as C extension like math: - they must be exported. */ - 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); @@ -67,6 +68,11 @@ extern void _Py_dg_freedtoa(char *s); #endif // _PY_SHORT_FLOAT_REPR == 1 + +extern PyStatus _PyDtoa_Init(PyInterpreterState *interp); +extern void _PyDtoa_Fini(PyInterpreterState *interp); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index 2f89da2c6ecd91..5c55282fa39e6f 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -320,6 +320,10 @@ PyAPI_FUNC(char*) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject extern int _PyFile_Flush(PyObject *); +#ifndef MS_WINDOWS +extern int _Py_GetTicksPerSecond(long *ticks_per_second); +#endif + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index c8fad1562d8443..0f9e7333cf1e1c 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -36,13 +36,17 @@ extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); /* other API */ typedef enum _framestate { - FRAME_CREATED = -2, - FRAME_SUSPENDED = -1, + FRAME_CREATED = -3, + FRAME_SUSPENDED = -2, + FRAME_SUSPENDED_YIELD_FROM = -1, FRAME_EXECUTING = 0, FRAME_COMPLETED = 1, FRAME_CLEARED = 4 } PyFrameState; +#define FRAME_STATE_SUSPENDED(S) ((S) == FRAME_SUSPENDED || (S) == FRAME_SUSPENDED_YIELD_FROM) +#define FRAME_STATE_FINISHED(S) ((S) >= FRAME_COMPLETED) + enum _frameowner { FRAME_OWNED_BY_THREAD = 0, FRAME_OWNED_BY_GENERATOR = 1, @@ -58,26 +62,16 @@ typedef struct _PyInterpreterFrame { PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ - // NOTE: This is not necessarily the last instruction started in the given - // frame. Rather, it is the code unit *prior to* the *next* instruction. For - // example, it may be an inline CACHE entry, an instruction we just jumped - // over, or (in the case of a newly-created frame) a totally invalid value: - _Py_CODEUNIT *prev_instr; + _Py_CODEUNIT *instr_ptr; /* Instruction currently executing (or about to begin) */ int stacktop; /* Offset of TOS from localsplus */ - /* The return_offset determines where a `RETURN` should go in the caller, - * relative to `prev_instr`. - * It is only meaningful to the callee, - * so it needs to be set in any CALL (to a Python function) - * or SEND (to a coroutine or generator). - * If there is no callee, then it is meaningless. */ - uint16_t return_offset; + uint16_t return_offset; /* Only relevant during a function call */ char owner; /* Locals and stack */ PyObject *localsplus[1]; } _PyInterpreterFrame; #define _PyInterpreterFrame_LASTI(IF) \ - ((int)((IF)->prev_instr - _PyCode_CODE(_PyFrame_GetCode(IF)))) + ((int)((IF)->instr_ptr - _PyCode_CODE(_PyFrame_GetCode(IF)))) static inline PyCodeObject *_PyFrame_GetCode(_PyInterpreterFrame *f) { assert(PyCode_Check(f->f_executable)); @@ -134,7 +128,7 @@ _PyFrame_Initialize( frame->f_locals = locals; frame->stacktop = code->co_nlocalsplus; frame->frame_obj = NULL; - frame->prev_instr = _PyCode_CODE(code) - 1; + frame->instr_ptr = _PyCode_CODE(code); frame->return_offset = 0; frame->owner = FRAME_OWNED_BY_THREAD; @@ -185,7 +179,7 @@ _PyFrame_IsIncomplete(_PyInterpreterFrame *frame) return true; } return frame->owner != FRAME_OWNED_BY_GENERATOR && - frame->prev_instr < _PyCode_CODE(_PyFrame_GetCode(frame)) + _PyFrame_GetCode(frame)->_co_firsttraceable; + frame->instr_ptr < _PyCode_CODE(_PyFrame_GetCode(frame)) + _PyFrame_GetCode(frame)->_co_firsttraceable; } static inline _PyInterpreterFrame * @@ -282,7 +276,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; @@ -297,7 +291,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->instr_ptr = _PyCode_CODE(code); frame->owner = FRAME_OWNED_BY_THREAD; frame->return_offset = 0; return frame; diff --git a/Include/internal/pycore_gil.h b/Include/internal/pycore_gil.h index a1a15070eef461..19b0d23a68568a 100644 --- a/Include/internal/pycore_gil.h +++ b/Include/internal/pycore_gil.h @@ -8,7 +8,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atomic.h" // _Py_atomic_address #include "pycore_condvar.h" // PyCOND_T #ifndef Py_HAVE_CONDVAR @@ -25,10 +24,10 @@ 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; + int locked; /* Number of GIL switches since the beginning. */ unsigned long switch_number; /* This condition variable allows one or several threads to wait diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index ec65192d9f84be..583960a51db28b 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -826,6 +826,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_exception_handler)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_soon)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(callback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cancel)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(capath)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(category)); @@ -897,7 +898,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dont_inherit)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst_dir_fd)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(duration)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(e)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eager_start)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(effective_ids)); @@ -943,7 +943,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flush)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(follow_symlinks)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(frequency)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(from_param)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromlist)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromtimestamp)); @@ -975,6 +974,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hook)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(id)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ident)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(identity_hint)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ignore)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(imag)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(importlib)); @@ -998,6 +998,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)); @@ -1194,7 +1195,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sleep)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sock)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sort)); - _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sound)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source_traceback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 5d8b468f8f25b0..958e0889c42e55 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -315,6 +315,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(call) STRUCT_FOR_ID(call_exception_handler) STRUCT_FOR_ID(call_soon) + STRUCT_FOR_ID(callback) STRUCT_FOR_ID(cancel) STRUCT_FOR_ID(capath) STRUCT_FOR_ID(category) @@ -386,7 +387,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(dont_inherit) STRUCT_FOR_ID(dst) STRUCT_FOR_ID(dst_dir_fd) - STRUCT_FOR_ID(duration) STRUCT_FOR_ID(e) STRUCT_FOR_ID(eager_start) STRUCT_FOR_ID(effective_ids) @@ -432,7 +432,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(flush) STRUCT_FOR_ID(follow_symlinks) STRUCT_FOR_ID(format) - STRUCT_FOR_ID(frequency) STRUCT_FOR_ID(from_param) STRUCT_FOR_ID(fromlist) STRUCT_FOR_ID(fromtimestamp) @@ -464,6 +463,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(hook) STRUCT_FOR_ID(id) STRUCT_FOR_ID(ident) + STRUCT_FOR_ID(identity_hint) STRUCT_FOR_ID(ignore) STRUCT_FOR_ID(imag) STRUCT_FOR_ID(importlib) @@ -487,6 +487,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) @@ -683,7 +684,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(sleep) STRUCT_FOR_ID(sock) STRUCT_FOR_ID(sort) - STRUCT_FOR_ID(sound) STRUCT_FOR_ID(source) STRUCT_FOR_ID(source_traceback) STRUCT_FOR_ID(src) diff --git a/Include/internal/pycore_identifier.h b/Include/internal/pycore_identifier.h index 0e015a40c831f4..cda28810a48196 100644 --- a/Include/internal/pycore_identifier.h +++ b/Include/internal/pycore_identifier.h @@ -10,42 +10,8 @@ extern "C" { # 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 diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 117e46bb86285d..c84f87a831bf38 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -9,6 +9,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_lock.h" // PyMutex #include "pycore_hashtable.h" // _Py_hashtable_t #include "pycore_time.h" // _PyTime_t @@ -47,7 +48,7 @@ struct _import_runtime_state { Py_ssize_t last_module_index; struct { /* A lock to guard the cache. */ - PyThread_type_lock mutex; + PyMutex mutex; /* 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) diff --git a/Include/internal/pycore_importdl.h b/Include/internal/pycore_importdl.h new file mode 100644 index 00000000000000..c8583582b358ac --- /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_GIL_DISABLED +# 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_instruments.h b/Include/internal/pycore_instruments.h index 97dcfb9f8672f7..eae8371ef7f9b8 100644 --- a/Include/internal/pycore_instruments.h +++ b/Include/internal/pycore_instruments.h @@ -63,6 +63,8 @@ typedef uint32_t _PyMonitoringEventSet; PyObject *_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj); int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events); +int _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet events); +int _PyMonitoring_GetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet *events); extern int _Py_call_instrumentation(PyThreadState *tstate, int event, diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 0912bd175fe4f7..04d7a6a615e370 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -12,10 +12,10 @@ extern "C" { #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 +#include "pycore_crossinterp.h" // struct _xidregistry #include "pycore_dict_state.h" // struct _Py_dict_state #include "pycore_dtoa.h" // struct _dtoa_state #include "pycore_exceptions.h" // struct _Py_exc_state @@ -29,6 +29,7 @@ extern "C" { #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_tstate.h" // _PyThreadStateImpl #include "pycore_tuple.h" // struct _Py_tuple_state #include "pycore_typeobject.h" // struct types_state #include "pycore_unicodeobject.h" // struct _Py_unicode_state @@ -39,6 +40,10 @@ struct _Py_long_state { int max_str_digits; }; + +/* cross-interpreter data registry */ + + /* interpreter state */ /* PyInterpreterState holds the global state for one of the runtime's @@ -67,12 +72,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. @@ -92,7 +98,7 @@ 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; @@ -148,6 +154,9 @@ struct _is { Py_ssize_t co_extra_user_count; freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; + /* cross-interpreter data and utils */ + struct _xi_state xi; + #ifdef HAVE_FORK PyObject *before_forkers; PyObject *after_forkers_parent; @@ -186,12 +195,12 @@ struct _is { struct types_state types; struct callable_cache callable_cache; _PyOptimizerObject *optimizer; + _PyExecutorObject *executor_list_head; uint16_t optimizer_resume_threshold; uint16_t optimizer_backedge_threshold; uint32_t next_func_version; _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 */ @@ -202,8 +211,9 @@ struct _is { struct _Py_interp_cached_objects cached_objects; struct _Py_interp_static_objects static_objects; - /* the initial PyInterpreterState.threads.head */ - PyThreadState _initial_thread; + /* the initial PyInterpreterState.threads.head */ + _PyThreadStateImpl _initial_thread; + Py_ssize_t _interactive_src_count; }; @@ -214,7 +224,7 @@ 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 @@ -224,7 +234,7 @@ _PyInterpreterState_GetFinalizingID(PyInterpreterState *interp) { 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); } @@ -237,26 +247,12 @@ _PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tst } -/* 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; -}; - -extern PyInterpreterState* _PyInterpreterState_LookUpID(int64_t); +// Export for the _xxinterpchannels module. +PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t); -extern int _PyInterpreterState_IDInitref(PyInterpreterState *); -extern int _PyInterpreterState_IDIncref(PyInterpreterState *); -extern void _PyInterpreterState_IDDecref(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); extern const PyConfig* _PyInterpreterState_GetConfig(PyInterpreterState *interp); diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h index 056be2c80c8ce6..55d67b32bc8a63 100644 --- a/Include/internal/pycore_list.h +++ b/Include/internal/pycore_list.h @@ -51,8 +51,8 @@ _PyList_AppendTakeRef(PyListObject *self, PyObject *newitem) Py_ssize_t allocated = self->allocated; assert((size_t)len + 1 < PY_SSIZE_T_MAX); if (allocated > len) { - Py_SET_SIZE(self, len + 1); PyList_SET_ITEM(self, len, newitem); + Py_SET_SIZE(self, len + 1); return 0; } return _PyList_AppendTakeRefListResize(self, newitem); diff --git a/Include/internal/pycore_lock.h b/Include/internal/pycore_lock.h index c4bb76a40e7b12..03ad1c9fd584b5 100644 --- a/Include/internal/pycore_lock.h +++ b/Include/internal/pycore_lock.h @@ -32,13 +32,21 @@ extern "C" { // PyMutex_Lock(&m); // ... // PyMutex_Unlock(&m); -typedef struct _PyMutex { - uint8_t v; -} PyMutex; + +// NOTE: In Py_GIL_DISABLED builds, `struct _PyMutex` is defined in Include/object.h. +// The Py_GIL_DISABLED builds need the definition in Include/object.h for the +// `ob_mutex` field in PyObject. For the default (non-free-threaded) build, +// we define the struct here to avoid exposing it in the public API. +#ifndef Py_GIL_DISABLED +struct _PyMutex { uint8_t v; }; +#endif + +typedef struct _PyMutex PyMutex; #define _Py_UNLOCKED 0 #define _Py_LOCKED 1 #define _Py_HAS_PARKED 2 +#define _Py_ONCE_INITIALIZED 4 // (private) slow path for locking the mutex PyAPI_FUNC(void) _PyMutex_LockSlow(PyMutex *m); @@ -46,6 +54,13 @@ PyAPI_FUNC(void) _PyMutex_LockSlow(PyMutex *m); // (private) slow path for unlocking the mutex PyAPI_FUNC(void) _PyMutex_UnlockSlow(PyMutex *m); +static inline int +PyMutex_LockFast(uint8_t *lock_bits) +{ + uint8_t expected = _Py_UNLOCKED; + return _Py_atomic_compare_exchange_uint8(lock_bits, &expected, _Py_LOCKED); +} + // Locks the mutex. // // If the mutex is currently locked, the calling thread will be parked until @@ -77,6 +92,13 @@ PyMutex_IsLocked(PyMutex *m) return (_Py_atomic_load_uint8(&m->v) & _Py_LOCKED) != 0; } +// Re-initializes the mutex after a fork to the unlocked state. +static inline void +_PyMutex_at_fork_reinit(PyMutex *m) +{ + memset(m, 0, sizeof(*m)); +} + typedef enum _PyLockFlags { // Do not detach/release the GIL when waiting on the lock. _Py_LOCK_DONT_DETACH = 0, @@ -93,6 +115,16 @@ typedef enum _PyLockFlags { extern PyLockStatus _PyMutex_LockTimed(PyMutex *m, _PyTime_t timeout_ns, _PyLockFlags flags); +// Lock a mutex with aditional options. See _PyLockFlags for details. +static inline void +PyMutex_LockFlags(PyMutex *m, _PyLockFlags flags) +{ + uint8_t expected = _Py_UNLOCKED; + if (!_Py_atomic_compare_exchange_uint8(&m->v, &expected, _Py_LOCKED)) { + _PyMutex_LockTimed(m, -1, flags); + } +} + // Unlock a mutex, returns 0 if the mutex is not locked (used for improved // error messages). extern int _PyMutex_TryUnlock(PyMutex *m); @@ -152,6 +184,35 @@ _PyRawMutex_Unlock(_PyRawMutex *m) _PyRawMutex_UnlockSlow(m); } +// A data structure that can be used to run initialization code once in a +// thread-safe manner. The C++11 equivalent is std::call_once. +typedef struct { + uint8_t v; +} _PyOnceFlag; + +// Type signature for one-time initialization functions. The function should +// return 0 on success and -1 on failure. +typedef int _Py_once_fn_t(void *arg); + +// (private) slow path for one time initialization +PyAPI_FUNC(int) +_PyOnceFlag_CallOnceSlow(_PyOnceFlag *flag, _Py_once_fn_t *fn, void *arg); + +// Calls `fn` once using `flag`. The `arg` is passed to the call to `fn`. +// +// Returns 0 on success and -1 on failure. +// +// If `fn` returns 0 (success), then subsequent calls immediately return 0. +// If `fn` returns -1 (failure), then subsequent calls will retry the call. +static inline int +_PyOnceFlag_CallOnce(_PyOnceFlag *flag, _Py_once_fn_t *fn, void *arg) +{ + if (_Py_atomic_load_uint8(&flag->v) == _Py_ONCE_INITIALIZED) { + return 0; + } + return _PyOnceFlag_CallOnceSlow(flag, fn, arg); +} + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index 3c253ed7ff556b..ec27df9e416c58 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -47,24 +47,6 @@ 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. @@ -128,57 +110,11 @@ extern PyObject* _PyLong_FromBytes(const char *, Py_ssize_t, int); // 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); @@ -363,7 +299,7 @@ _PyLong_FlipSign(PyLongObject *op) { #define _PyLong_DIGIT_INIT(val) \ { \ - .ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \ + .ob_base = _PyObject_HEAD_INIT(&PyLong_Type), \ .long_value = { \ .lv_tag = TAG_FROM_SIGN_AND_SIZE( \ (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \ diff --git a/Include/internal/pycore_mimalloc.h b/Include/internal/pycore_mimalloc.h new file mode 100644 index 00000000000000..c29dc82a42762a --- /dev/null +++ b/Include/internal/pycore_mimalloc.h @@ -0,0 +1,19 @@ +#ifndef Py_INTERNAL_MIMALLOC_H +#define Py_INTERNAL_MIMALLOC_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#if defined(MIMALLOC_H) || defined(MIMALLOC_TYPES_H) +# error "pycore_mimalloc.h must be included before mimalloc.h" +#endif + +#include "pycore_pymem.h" +#define MI_DEBUG_UNINIT PYMEM_CLEANBYTE +#define MI_DEBUG_FREED PYMEM_DEADBYTE +#define MI_DEBUG_PADDING PYMEM_FORBIDDENBYTE + +#include "mimalloc.h" + +#endif // Py_INTERNAL_MIMALLOC_H diff --git a/Include/internal/pycore_modsupport.h b/Include/internal/pycore_modsupport.h index e577c6ba856b77..3d3cd6722528e9 100644 --- a/Include/internal/pycore_modsupport.h +++ b/Include/internal/pycore_modsupport.h @@ -1,5 +1,8 @@ #ifndef Py_INTERNAL_MODSUPPORT_H #define Py_INTERNAL_MODSUPPORT_H + +#include "pycore_lock.h" // _PyOnceFlag + #ifdef __cplusplus extern "C" { #endif @@ -13,6 +16,24 @@ extern int _PyArg_NoKwnames(const char *funcname, PyObject *kwnames); #define _PyArg_NoKwnames(funcname, kwnames) \ ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames))) +// Export for '_bz2' shared extension +PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); +#define _PyArg_NoPositional(funcname, args) \ + ((args) == NULL || _PyArg_NoPositional((funcname), (args))) + +// Export for '_asyncio' shared extension +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); +#define _PyArg_NoKeywords(funcname, kwargs) \ + ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) + +// Export for 'zlib' shared extension +PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, + Py_ssize_t, Py_ssize_t); +#define _Py_ANY_VARARGS(n) ((n) == PY_SSIZE_T_MAX) +#define _PyArg_CheckPositional(funcname, nargs, min, max) \ + ((!_Py_ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ + || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) + extern PyObject ** _Py_VaBuildStack( PyObject **small_stack, Py_ssize_t small_stack_len, @@ -22,6 +43,81 @@ extern PyObject ** _Py_VaBuildStack( extern PyObject* _PyModule_CreateInitialized(PyModuleDef*, int apiver); +// Export for '_curses' shared extension +PyAPI_FUNC(int) _PyArg_ParseStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *format, + ...); + +extern int _PyArg_UnpackStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *name, + Py_ssize_t min, + Py_ssize_t max, + ...); + +// Export for '_heapq' shared extension +PyAPI_FUNC(void) _PyArg_BadArgument( + const char *fname, + const char *displayname, + const char *expected, + PyObject *arg); + +// --- _PyArg_Parser API --------------------------------------------------- + +typedef struct _PyArg_Parser { + const char *format; + const char * const *keywords; + const char *fname; + const char *custom_msg; + _PyOnceFlag once; /* atomic one-time initialization flag */ + int is_kwtuple_owned; /* does this parser own the kwtuple object? */ + int pos; /* number of positional-only arguments */ + int min; /* minimal number of arguments */ + int max; /* maximal number of positional arguments */ + PyObject *kwtuple; /* tuple of keyword parameter names */ + struct _PyArg_Parser *next; +} _PyArg_Parser; + +// Export for '_testclinic' shared extension +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); + +// Export for '_dbm' shared extension +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames, + struct _PyArg_Parser *, + ...); + +// Export for 'math' shared extension +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwargs, + PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, + int maxpos, + int minkw, + PyObject **buf); +#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ + (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ + (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \ + _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ + (minpos), (maxpos), (minkw), (buf))) + +// Export for '_testclinic' shared extension +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + int vararg, PyObject **buf); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 2d50f42c9c614d..f413b8451e5ab4 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -54,16 +54,24 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); Furthermore, we can't use designated initializers in Extensions since these are not supported pre-C++20. Thus, keeping an internal copy here is the most backwards compatible solution */ +#if defined(Py_GIL_DISABLED) +#define _PyObject_HEAD_INIT(type) \ + { \ + .ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL, \ + .ob_type = (type) \ + } +#else #define _PyObject_HEAD_INIT(type) \ { \ .ob_refcnt = _Py_IMMORTAL_REFCNT, \ .ob_type = (type) \ - }, + } +#endif #define _PyVarObject_HEAD_INIT(type, size) \ { \ - .ob_base = _PyObject_HEAD_INIT(type) \ + .ob_base = _PyObject_HEAD_INIT(type), \ .ob_size = size \ - }, + } extern void _Py_NO_RETURN _Py_FatalRefcountErrorFunc( const char *func, @@ -95,24 +103,63 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) #ifdef Py_REF_DEBUG _Py_AddRefTotal(_PyInterpreterState_GET(), n); #endif +#if !defined(Py_GIL_DISABLED) op->ob_refcnt += n; +#else + if (_Py_IsOwnedByCurrentThread(op)) { + uint32_t local = op->ob_ref_local; + Py_ssize_t refcnt = (Py_ssize_t)local + n; +# if PY_SSIZE_T_MAX > UINT32_MAX + if (refcnt > (Py_ssize_t)UINT32_MAX) { + // Make the object immortal if the 32-bit local reference count + // would overflow. + refcnt = _Py_IMMORTAL_REFCNT_LOCAL; + } +# endif + _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, (uint32_t)refcnt); + } + else { + _Py_atomic_add_ssize(&op->ob_ref_shared, (n << _Py_REF_SHARED_SHIFT)); + } +#endif } #define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n) static inline void _Py_SetImmortal(PyObject *op) { if (op) { +#ifdef Py_GIL_DISABLED + op->ob_tid = _Py_UNOWNED_TID; + op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL; + op->ob_ref_shared = 0; +#else op->ob_refcnt = _Py_IMMORTAL_REFCNT; +#endif } } #define _Py_SetImmortal(op) _Py_SetImmortal(_PyObject_CAST(op)) +// Makes an immortal object mortal again with the specified refcnt. Should only +// be used during runtime finalization. +static inline void _Py_SetMortal(PyObject *op, Py_ssize_t refcnt) +{ + if (op) { + assert(_Py_IsImmortal(op)); +#ifdef Py_GIL_DISABLED + op->ob_tid = _Py_UNOWNED_TID; + op->ob_ref_local = 0; + op->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED); +#else + op->ob_refcnt = refcnt; +#endif + } +} + /* _Py_ClearImmortal() should only be used during runtime finalization. */ static inline void _Py_ClearImmortal(PyObject *op) { if (op) { - assert(op->ob_refcnt == _Py_IMMORTAL_REFCNT); - op->ob_refcnt = 1; + _Py_SetMortal(op, 1); Py_DECREF(op); } } @@ -122,6 +169,7 @@ static inline void _Py_ClearImmortal(PyObject *op) op = NULL; \ } while (0) +#if !defined(Py_GIL_DISABLED) static inline void _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) { @@ -161,6 +209,37 @@ _Py_DECREF_NO_DEALLOC(PyObject *op) #endif } +#else +// TODO: implement Py_DECREF specializations for Py_GIL_DISABLED build +static inline void +_Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) +{ + Py_DECREF(op); +} + +static inline void +_Py_DECREF_NO_DEALLOC(PyObject *op) +{ + Py_DECREF(op); +} + +static inline int +_Py_REF_IS_MERGED(Py_ssize_t ob_ref_shared) +{ + return (ob_ref_shared & _Py_REF_SHARED_FLAG_MASK) == _Py_REF_MERGED; +} + +static inline int +_Py_REF_IS_QUEUED(Py_ssize_t ob_ref_shared) +{ + return (ob_ref_shared & _Py_REF_SHARED_FLAG_MASK) == _Py_REF_QUEUED; +} + +// Merge the local and shared reference count fields and add `extra` to the +// refcount when merging. +Py_ssize_t _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra); +#endif // !defined(Py_GIL_DISABLED) + #ifdef Py_REF_DEBUG # undef _Py_DEC_REFTOTAL #endif diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h index b0dbf53d4e3d15..17572dba65487d 100644 --- a/Include/internal/pycore_obmalloc.h +++ b/Include/internal/pycore_obmalloc.h @@ -665,7 +665,9 @@ struct _obmalloc_global_state { struct _obmalloc_state { struct _obmalloc_pools pools; struct _obmalloc_mgmt mgmt; +#if WITH_PYMALLOC_RADIX_TREE struct _obmalloc_usage usage; +#endif }; diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 16c1637e496033..2c512d97c421c9 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -25,61 +25,7 @@ ((OP) == POP_BLOCK) || \ 0) -#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 -#define _BINARY_OP_SUBTRACT_INT 305 -#define _GUARD_BOTH_FLOAT 306 -#define _BINARY_OP_MULTIPLY_FLOAT 307 -#define _BINARY_OP_ADD_FLOAT 308 -#define _BINARY_OP_SUBTRACT_FLOAT 309 -#define _GUARD_BOTH_UNICODE 310 -#define _BINARY_OP_ADD_UNICODE 311 -#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 _LOAD_ATTR_SLOT 321 -#define _GUARD_DORV_VALUES 322 -#define _STORE_ATTR_INSTANCE_VALUE 323 -#define _GUARD_TYPE_VERSION_STORE 324 -#define _STORE_ATTR_SLOT 325 -#define _IS_NONE 326 -#define _ITER_CHECK_LIST 327 -#define _ITER_JUMP_LIST 328 -#define _IS_ITER_EXHAUSTED_LIST 329 -#define _ITER_NEXT_LIST 330 -#define _ITER_CHECK_TUPLE 331 -#define _ITER_JUMP_TUPLE 332 -#define _IS_ITER_EXHAUSTED_TUPLE 333 -#define _ITER_NEXT_TUPLE 334 -#define _ITER_CHECK_RANGE 335 -#define _ITER_JUMP_RANGE 336 -#define _IS_ITER_EXHAUSTED_RANGE 337 -#define _ITER_NEXT_RANGE 338 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 339 -#define _GUARD_KEYS_VERSION 340 -#define _LOAD_ATTR_METHOD_WITH_VALUES 341 -#define _LOAD_ATTR_METHOD_NO_DICT 342 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 343 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 344 -#define _CHECK_PEP_523 345 -#define _CHECK_FUNCTION_EXACT_ARGS 346 -#define _CHECK_STACK_SPACE 347 -#define _INIT_CALL_PY_EXACT_ARGS 348 -#define _PUSH_FRAME 349 -#define _POP_JUMP_IF_FALSE 350 -#define _POP_JUMP_IF_TRUE 351 -#define _JUMP_TO_TOP 352 -#define _SAVE_CURRENT_IP 353 -#define _INSERT 354 +#include "pycore_uop_ids.h" extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump); #ifdef NEED_OPCODE_METADATA @@ -129,6 +75,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case UNARY_NOT: return 1; + case _SPECIALIZE_TO_BOOL: + return 1; + case _TO_BOOL: + return 1; case TO_BOOL: return 1; case TO_BOOL_BOOL: @@ -183,6 +133,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 2; case BINARY_OP_INPLACE_ADD_UNICODE: return 2; + case _SPECIALIZE_BINARY_SUBSCR: + return 2; + case _BINARY_SUBSCR: + return 2; case BINARY_SUBSCR: return 2; case BINARY_SLICE: @@ -203,6 +157,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return (oparg-1) + 2; case SET_ADD: return (oparg-1) + 2; + case _SPECIALIZE_STORE_SUBSCR: + return 2; + case _STORE_SUBSCR: + return 3; case STORE_SUBSCR: return 3; case STORE_SUBSCR_LIST_INT: @@ -235,6 +193,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case GET_AWAITABLE: return 1; + case _SPECIALIZE_SEND: + return 2; + case _SEND: + return 2; case SEND: return 2; case SEND_GEN: @@ -259,6 +221,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case DELETE_NAME: return 0; + case _SPECIALIZE_UNPACK_SEQUENCE: + return 1; + case _UNPACK_SEQUENCE: + return 1; case UNPACK_SEQUENCE: return 1; case UNPACK_SEQUENCE_TWO_TUPLE: @@ -269,6 +235,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case UNPACK_EX: return 1; + case _SPECIALIZE_STORE_ATTR: + return 1; + case _STORE_ATTR: + return 2; case STORE_ATTR: return 2; case DELETE_ATTR: @@ -283,6 +253,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case LOAD_NAME: return 0; + case _SPECIALIZE_LOAD_GLOBAL: + return 0; + case _LOAD_GLOBAL: + return 0; case LOAD_GLOBAL: return 0; case _GUARD_GLOBALS_VERSION: @@ -337,6 +311,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return (oparg - 1) + 3; case INSTRUMENTED_LOAD_SUPER_ATTR: return 3; + case _SPECIALIZE_LOAD_SUPER_ATTR: + return 3; + case _LOAD_SUPER_ATTR: + return 3; case LOAD_SUPER_ATTR: return 3; case LOAD_SUPER_METHOD: @@ -349,6 +327,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 3; case LOAD_SUPER_ATTR_METHOD: return 3; + case _SPECIALIZE_LOAD_ATTR: + return 1; + case _LOAD_ATTR: + return 1; case LOAD_ATTR: return 1; case LOAD_METHOD: @@ -361,14 +343,26 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { 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: @@ -383,12 +377,14 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 2; case STORE_ATTR_WITH_HINT: return 2; - case _GUARD_TYPE_VERSION_STORE: - return 1; case _STORE_ATTR_SLOT: return 2; case STORE_ATTR_SLOT: return 2; + case _SPECIALIZE_COMPARE_OP: + return 2; + case _COMPARE_OP: + return 2; case COMPARE_OP: return 2; case COMPARE_OP_FLOAT: @@ -419,12 +415,16 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 0; case ENTER_EXECUTOR: return 0; - case POP_JUMP_IF_FALSE: + case _POP_JUMP_IF_FALSE: return 1; - case POP_JUMP_IF_TRUE: + case _POP_JUMP_IF_TRUE: return 1; case _IS_NONE: return 1; + case POP_JUMP_IF_TRUE: + return 1; + case POP_JUMP_IF_FALSE: + return 1; case POP_JUMP_IF_NONE: return 1; case POP_JUMP_IF_NOT_NONE: @@ -445,6 +445,12 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case GET_YIELD_FROM_ITER: return 1; + case _SPECIALIZE_FOR_ITER: + return 1; + case _FOR_ITER: + return 1; + case _FOR_ITER_TIER_TWO: + return 1; case FOR_ITER: return 1; case INSTRUMENTED_FOR_ITER: @@ -453,7 +459,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case _ITER_JUMP_LIST: return 1; - case _IS_ITER_EXHAUSTED_LIST: + case _GUARD_NOT_EXHAUSTED_LIST: return 1; case _ITER_NEXT_LIST: return 1; @@ -463,7 +469,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case _ITER_JUMP_TUPLE: return 1; - case _IS_ITER_EXHAUSTED_TUPLE: + case _GUARD_NOT_EXHAUSTED_TUPLE: return 1; case _ITER_NEXT_TUPLE: return 1; @@ -473,7 +479,7 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 1; case _ITER_JUMP_RANGE: return 1; - case _IS_ITER_EXHAUSTED_RANGE: + case _GUARD_NOT_EXHAUSTED_RANGE: return 1; case _ITER_NEXT_RANGE: return 1; @@ -509,14 +515,26 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { 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 INSTRUMENTED_CALL: return 0; + case _SPECIALIZE_CALL: + return oparg + 2; + case _CALL: + return oparg + 2; case CALL: return oparg + 2; case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: @@ -595,6 +613,10 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 2; case COPY: return (oparg-1) + 1; + case _SPECIALIZE_BINARY_OP: + return 2; + case _BINARY_OP: + return 2; case BINARY_OP: return 2; case SWAP: @@ -619,20 +641,26 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) { return 0; case RESERVED: return 0; - case _POP_JUMP_IF_FALSE: + case _GUARD_IS_TRUE_POP: return 1; - case _POP_JUMP_IF_TRUE: + case _GUARD_IS_FALSE_POP: + return 1; + case _GUARD_IS_NONE_POP: + return 1; + case _GUARD_IS_NOT_NONE_POP: return 1; case _JUMP_TO_TOP: return 0; case _SET_IP: return 0; - case _SAVE_CURRENT_IP: + case _SAVE_RETURN_OFFSET: return 0; case _EXIT_TRACE: return 0; case _INSERT: return oparg + 1; + case _CHECK_VALIDITY: + return 0; default: return -1; } @@ -687,6 +715,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case UNARY_NOT: return 1; + case _SPECIALIZE_TO_BOOL: + return 1; + case _TO_BOOL: + return 1; case TO_BOOL: return 1; case TO_BOOL_BOOL: @@ -741,6 +773,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case BINARY_OP_INPLACE_ADD_UNICODE: return 0; + case _SPECIALIZE_BINARY_SUBSCR: + return 2; + case _BINARY_SUBSCR: + return 1; case BINARY_SUBSCR: return 1; case BINARY_SLICE: @@ -761,6 +797,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return (oparg-1) + 1; case SET_ADD: return (oparg-1) + 1; + case _SPECIALIZE_STORE_SUBSCR: + return 2; + case _STORE_SUBSCR: + return 0; case STORE_SUBSCR: return 0; case STORE_SUBSCR_LIST_INT: @@ -793,6 +833,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 2; case GET_AWAITABLE: return 1; + case _SPECIALIZE_SEND: + return 2; + case _SEND: + return 2; case SEND: return 2; case SEND_GEN: @@ -817,6 +861,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case DELETE_NAME: return 0; + case _SPECIALIZE_UNPACK_SEQUENCE: + return 1; + case _UNPACK_SEQUENCE: + return oparg; case UNPACK_SEQUENCE: return oparg; case UNPACK_SEQUENCE_TWO_TUPLE: @@ -827,6 +875,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return oparg; case UNPACK_EX: return (oparg & 0xFF) + (oparg >> 8) + 1; + case _SPECIALIZE_STORE_ATTR: + return 1; + case _STORE_ATTR: + return 0; case STORE_ATTR: return 0; case DELETE_ATTR: @@ -841,8 +893,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case LOAD_NAME: return 1; - case LOAD_GLOBAL: + case _SPECIALIZE_LOAD_GLOBAL: + return 0; + case _LOAD_GLOBAL: return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_GLOBAL: + return (oparg & 1 ? 1 : 0) + 1; case _GUARD_GLOBALS_VERSION: return 0; case _GUARD_BUILTINS_VERSION: @@ -895,22 +951,30 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return (oparg - 1) + 1; case INSTRUMENTED_LOAD_SUPER_ATTR: return ((oparg & 1) ? 1 : 0) + 1; - case LOAD_SUPER_ATTR: + case _SPECIALIZE_LOAD_SUPER_ATTR: + return 3; + case _LOAD_SUPER_ATTR: return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_SUPER_ATTR: + return (oparg & 1 ? 1 : 0) + 1; case LOAD_SUPER_METHOD: - return ((oparg & 1) ? 1 : 0) + 1; + return (oparg & 1 ? 1 : 0) + 1; case LOAD_ZERO_SUPER_METHOD: - return ((oparg & 1) ? 1 : 0) + 1; + return (oparg & 1 ? 1 : 0) + 1; case LOAD_ZERO_SUPER_ATTR: - return ((oparg & 1) ? 1 : 0) + 1; + return (oparg & 1 ? 1 : 0) + 1; case LOAD_SUPER_ATTR_ATTR: return 1; case LOAD_SUPER_ATTR_METHOD: return 2; - case LOAD_ATTR: + case _SPECIALIZE_LOAD_ATTR: + return 1; + case _LOAD_ATTR: return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR: + return (oparg & 1 ? 1 : 0) + 1; case LOAD_METHOD: - return ((oparg & 1) ? 1 : 0) + 1; + return (oparg & 1 ? 1 : 0) + 1; case _GUARD_TYPE_VERSION: return 1; case _CHECK_MANAGED_OBJECT_HAS_VALUES: @@ -919,16 +983,28 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { 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; + 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 LOAD_ATTR_CLASS: + 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; case LOAD_ATTR_PROPERTY: return 1; case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: @@ -941,12 +1017,14 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case STORE_ATTR_WITH_HINT: return 0; - case _GUARD_TYPE_VERSION_STORE: - return 1; case _STORE_ATTR_SLOT: return 0; case STORE_ATTR_SLOT: return 0; + case _SPECIALIZE_COMPARE_OP: + return 2; + case _COMPARE_OP: + return 1; case COMPARE_OP: return 1; case COMPARE_OP_FLOAT: @@ -977,12 +1055,16 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case ENTER_EXECUTOR: return 0; - case POP_JUMP_IF_FALSE: + case _POP_JUMP_IF_FALSE: return 0; - case POP_JUMP_IF_TRUE: + case _POP_JUMP_IF_TRUE: return 0; case _IS_NONE: return 1; + case POP_JUMP_IF_TRUE: + return 0; + case POP_JUMP_IF_FALSE: + return 0; case POP_JUMP_IF_NONE: return 0; case POP_JUMP_IF_NOT_NONE: @@ -1003,6 +1085,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case GET_YIELD_FROM_ITER: return 1; + case _SPECIALIZE_FOR_ITER: + return 1; + case _FOR_ITER: + return 2; + case _FOR_ITER_TIER_TWO: + return 2; case FOR_ITER: return 2; case INSTRUMENTED_FOR_ITER: @@ -1011,8 +1099,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case _ITER_JUMP_LIST: return 1; - case _IS_ITER_EXHAUSTED_LIST: - return 2; + case _GUARD_NOT_EXHAUSTED_LIST: + return 1; case _ITER_NEXT_LIST: return 2; case FOR_ITER_LIST: @@ -1021,8 +1109,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case _ITER_JUMP_TUPLE: return 1; - case _IS_ITER_EXHAUSTED_TUPLE: - return 2; + case _GUARD_NOT_EXHAUSTED_TUPLE: + return 1; case _ITER_NEXT_TUPLE: return 2; case FOR_ITER_TUPLE: @@ -1031,8 +1119,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case _ITER_JUMP_RANGE: return 1; - case _IS_ITER_EXHAUSTED_RANGE: - return 2; + case _GUARD_NOT_EXHAUSTED_RANGE: + return 1; case _ITER_NEXT_RANGE: return 2; case FOR_ITER_RANGE: @@ -1067,14 +1155,26 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { 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 INSTRUMENTED_CALL: return 0; + case _SPECIALIZE_CALL: + return oparg + 2; + case _CALL: + return 1; case CALL: return 1; case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: @@ -1090,11 +1190,11 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { case _INIT_CALL_PY_EXACT_ARGS: return 1; case _PUSH_FRAME: - return 1; + return 0; case CALL_BOUND_METHOD_EXACT_ARGS: - return 1; + return 0; case CALL_PY_EXACT_ARGS: - return 1; + return 0; case CALL_PY_WITH_DEFAULTS: return 1; case CALL_TYPE_1: @@ -1153,6 +1253,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 1; case COPY: return (oparg-1) + 2; + case _SPECIALIZE_BINARY_OP: + return 2; + case _BINARY_OP: + return 1; case BINARY_OP: return 1; case SWAP: @@ -1177,20 +1281,26 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) { return 0; case RESERVED: return 0; - case _POP_JUMP_IF_FALSE: + case _GUARD_IS_TRUE_POP: return 0; - case _POP_JUMP_IF_TRUE: + case _GUARD_IS_FALSE_POP: + return 0; + case _GUARD_IS_NONE_POP: + return 0; + case _GUARD_IS_NOT_NONE_POP: return 0; case _JUMP_TO_TOP: return 0; case _SET_IP: return 0; - case _SAVE_CURRENT_IP: + case _SAVE_RETURN_OFFSET: return 0; case _EXIT_TRACE: return 0; case _INSERT: return oparg + 1; + case _CHECK_VALIDITY: + return 0; default: return -1; } @@ -1203,6 +1313,7 @@ enum InstructionFormat { INSTR_FMT_IBC0, INSTR_FMT_IBC00, INSTR_FMT_IBC000, + INSTR_FMT_IBC0000000, INSTR_FMT_IBC00000000, INSTR_FMT_IX, INSTR_FMT_IXC, @@ -1224,6 +1335,7 @@ enum InstructionFormat { #define HAS_EVAL_BREAK_FLAG (64) #define HAS_DEOPT_FLAG (128) #define HAS_ERROR_FLAG (256) +#define HAS_ESCAPES_FLAG (512) #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)) @@ -1233,6 +1345,7 @@ enum InstructionFormat { #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)) +#define OPCODE_HAS_ESCAPES(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ESCAPES_FLAG)) struct opcode_metadata { bool valid_entry; @@ -1251,11 +1364,11 @@ struct opcode_macro_expansion { #define OPARG_CACHE_4 4 #define OPARG_TOP 5 #define OPARG_BOTTOM 6 -#define OPARG_SET_IP 7 +#define OPARG_SAVE_RETURN_OFFSET 7 -#define OPCODE_METADATA_FMT(OP) (_PyOpcode_opcode_metadata[(OP)].instr_format) +#define OPCODE_METADATA_FLAGS(OP) (_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG | HAS_JUMP_FLAG)) #define SAME_OPCODE_METADATA(OP1, OP2) \ - (OPCODE_METADATA_FMT(OP1) == OPCODE_METADATA_FMT(OP2)) + (OPCODE_METADATA_FLAGS(OP1) == OPCODE_METADATA_FLAGS(OP2)) #define OPCODE_METADATA_SIZE 512 #define OPCODE_UOP_NAME_SIZE 512 @@ -1265,35 +1378,37 @@ extern const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SI #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 | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, + [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_CLOSURE] = { true, 0, 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 }, [LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG }, [STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, - [STORE_FAST_MAYBE_NULL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, + [STORE_FAST_MAYBE_NULL] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [STORE_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [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_IX, 0 }, - [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [END_SEND] = { true, INSTR_FMT_IX, 0 }, - [INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, - [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [UNARY_NOT] = { true, INSTR_FMT_IX, 0 }, - [TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG }, + [_SPECIALIZE_TO_BOOL] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG }, + [_TO_BOOL] = { true, INSTR_FMT_IXC0, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_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 }, @@ -1309,61 +1424,73 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = { [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_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG }, + [_BINARY_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ESCAPES_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, 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 | 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 | HAS_ERROR_FLAG }, - [END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, - [CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG }, + [_STORE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [STORE_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DELETE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [INTERPRETER_EXIT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [_POP_FRAME] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [GET_AITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [GET_ANEXT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [GET_AWAITABLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_SEND] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG }, + [_SEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [POP_EXCEPT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, 0 }, - [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 }, + [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DELETE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_UNPACK_SEQUENCE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_STORE_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG }, + [_STORE_ATTR] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_ATTR] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DELETE_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DELETE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_LOAD_GLOBAL] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG }, + [_LOAD_GLOBAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, @@ -1371,173 +1498,200 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = { [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 }, + [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DELETE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG }, [COPY_FREE_VARS] = { 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 | 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 }, + [BUILD_STRING] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BUILD_SET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BUILD_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BUILD_CONST_KEY_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [DICT_MERGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG }, + [_SPECIALIZE_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ZERO_SUPER_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ZERO_SUPER_ATTR] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_LOAD_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG }, + [_LOAD_ATTR] = { true, INSTR_FMT_IBC0000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_METHOD] = { true, 0, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, - [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG }, + [_CHECK_ATTR_WITH_HINT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [_LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_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 }, + [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_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 }, - [_GUARD_TYPE_VERSION_STORE] = { true, INSTR_FMT_IXC0, 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 }, + [_STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG }, + [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [_STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG }, + [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_COMPARE_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, [IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_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 }, + [CONTAINS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 | 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 | 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 }, + [JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [JUMP] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [JUMP_NO_INTERRUPT] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, + [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG }, [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, HAS_ERROR_FLAG }, - [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 }, [MATCH_SEQUENCE] = { 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 }, + [MATCH_KEYS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [GET_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_FOR_ITER] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_FOR_ITER_TIER_TWO] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [_GUARD_NOT_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, [_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 }, + [_GUARD_NOT_EXHAUSTED_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, [_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 }, + [_GUARD_NOT_EXHAUSTED_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_ITER_NEXT_RANGE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BEFORE_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [SETUP_FINALLY] = { true, 0, HAS_ARG_FLAG }, + [SETUP_CLEANUP] = { true, 0, HAS_ARG_FLAG }, + [SETUP_WITH] = { true, 0, HAS_ARG_FLAG }, + [POP_BLOCK] = { true, 0, 0 }, [PUSH_EXC_INFO] = { true, INSTR_FMT_IX, 0 }, [_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_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_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 }, - [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_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [_SPECIALIZE_CALL] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_CALL] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [_INIT_CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_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_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG }, + [CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_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_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_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_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_CALL_FUNCTION_EX] = { 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, HAS_ERROR_FLAG }, - [BUILD_SLICE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [BUILD_SLICE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_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 }, + [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [_SPECIALIZE_BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_BINARY_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, + [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [SWAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, + [INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG }, + [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, 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 }, + [CACHE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [RESERVED] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG }, + [_GUARD_IS_TRUE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_GUARD_IS_FALSE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_GUARD_IS_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, + [_GUARD_IS_NOT_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_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 }, + [_SET_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG }, + [_SAVE_RETURN_OFFSET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [_EXIT_TRACE] = { true, INSTR_FMT_IX, 0 }, [_INSERT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [_CHECK_VALIDITY] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, }; #endif // NEED_OPCODE_METADATA @@ -1560,7 +1714,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [END_SEND] = { .nuops = 1, .uops = { { END_SEND, 0, 0 } } }, [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { UNARY_NEGATIVE, 0, 0 } } }, [UNARY_NOT] = { .nuops = 1, .uops = { { UNARY_NOT, 0, 0 } } }, - [TO_BOOL] = { .nuops = 1, .uops = { { TO_BOOL, 0, 0 } } }, + [TO_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL, 0, 0 } } }, [TO_BOOL_BOOL] = { .nuops = 1, .uops = { { TO_BOOL_BOOL, 0, 0 } } }, [TO_BOOL_INT] = { .nuops = 1, .uops = { { TO_BOOL_INT, 0, 0 } } }, [TO_BOOL_LIST] = { .nuops = 1, .uops = { { TO_BOOL_LIST, 0, 0 } } }, @@ -1575,7 +1729,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [BINARY_OP_ADD_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_ADD_FLOAT, 0, 0 } } }, [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, 0, 0 } } }, [BINARY_OP_ADD_UNICODE] = { .nuops = 2, .uops = { { _GUARD_BOTH_UNICODE, 0, 0 }, { _BINARY_OP_ADD_UNICODE, 0, 0 } } }, - [BINARY_SUBSCR] = { .nuops = 1, .uops = { { BINARY_SUBSCR, 0, 0 } } }, + [BINARY_SUBSCR] = { .nuops = 1, .uops = { { _BINARY_SUBSCR, 0, 0 } } }, [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 } } }, @@ -1584,14 +1738,14 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_DICT, 0, 0 } } }, [LIST_APPEND] = { .nuops = 1, .uops = { { LIST_APPEND, 0, 0 } } }, [SET_ADD] = { .nuops = 1, .uops = { { SET_ADD, 0, 0 } } }, - [STORE_SUBSCR] = { .nuops = 1, .uops = { { STORE_SUBSCR, 0, 0 } } }, + [STORE_SUBSCR] = { .nuops = 1, .uops = { { _STORE_SUBSCR, 0, 0 } } }, [STORE_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { STORE_SUBSCR_LIST_INT, 0, 0 } } }, [STORE_SUBSCR_DICT] = { .nuops = 1, .uops = { { STORE_SUBSCR_DICT, 0, 0 } } }, [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 = 3, .uops = { { _SET_IP, 7, 0 }, { _SAVE_CURRENT_IP, 0, 0 }, { _POP_FRAME, 0, 0 } } }, - [RETURN_CONST] = { .nuops = 4, .uops = { { LOAD_CONST, 0, 0 }, { _SET_IP, 7, 0 }, { _SAVE_CURRENT_IP, 0, 0 }, { _POP_FRAME, 0, 0 } } }, + [RETURN_VALUE] = { .nuops = 1, .uops = { { _POP_FRAME, 0, 0 } } }, + [RETURN_CONST] = { .nuops = 2, .uops = { { LOAD_CONST, 0, 0 }, { _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 } } }, @@ -1600,22 +1754,23 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { LOAD_BUILD_CLASS, 0, 0 } } }, [STORE_NAME] = { .nuops = 1, .uops = { { STORE_NAME, 0, 0 } } }, [DELETE_NAME] = { .nuops = 1, .uops = { { DELETE_NAME, 0, 0 } } }, - [UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE, 0, 0 } } }, + [UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, 0, 0 } } }, [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_TWO_TUPLE, 0, 0 } } }, [UNPACK_SEQUENCE_TUPLE] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_TUPLE, 0, 0 } } }, [UNPACK_SEQUENCE_LIST] = { .nuops = 1, .uops = { { UNPACK_SEQUENCE_LIST, 0, 0 } } }, [UNPACK_EX] = { .nuops = 1, .uops = { { UNPACK_EX, 0, 0 } } }, - [STORE_ATTR] = { .nuops = 1, .uops = { { STORE_ATTR, 0, 0 } } }, + [STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, 0, 0 } } }, [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_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] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } }, [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 } } }, + [MAKE_CELL] = { .nuops = 1, .uops = { { MAKE_CELL, 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 } } }, [LOAD_DEREF] = { .nuops = 1, .uops = { { LOAD_DEREF, 0, 0 } } }, @@ -1635,12 +1790,15 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [MAP_ADD] = { .nuops = 1, .uops = { { MAP_ADD, 0, 0 } } }, [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] = { .nuops = 1, .uops = { { _LOAD_ATTR, 0, 0 } } }, [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 } } }, - [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION_STORE, 2, 1 }, { _GUARD_DORV_VALUES, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } }, - [STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION_STORE, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } }, - [COMPARE_OP] = { .nuops = 1, .uops = { { COMPARE_OP, 0, 0 } } }, + [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 } } }, [COMPARE_OP_STR] = { .nuops = 1, .uops = { { COMPARE_OP_STR, 0, 0 } } }, @@ -1648,6 +1806,10 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [CONTAINS_OP] = { .nuops = 1, .uops = { { CONTAINS_OP, 0, 0 } } }, [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { CHECK_EG_MATCH, 0, 0 } } }, [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { CHECK_EXC_MATCH, 0, 0 } } }, + [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, 0, 0 } } }, + [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 0, 0 } } }, + [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 0, 0 } } }, + [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 0, 0 } } }, [GET_LEN] = { .nuops = 1, .uops = { { GET_LEN, 0, 0 } } }, [MATCH_CLASS] = { .nuops = 1, .uops = { { MATCH_CLASS, 0, 0 } } }, [MATCH_MAPPING] = { .nuops = 1, .uops = { { MATCH_MAPPING, 0, 0 } } }, @@ -1655,12 +1817,21 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [MATCH_KEYS] = { .nuops = 1, .uops = { { MATCH_KEYS, 0, 0 } } }, [GET_ITER] = { .nuops = 1, .uops = { { GET_ITER, 0, 0 } } }, [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { GET_YIELD_FROM_ITER, 0, 0 } } }, + [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, 0, 0 } } }, + [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, 0, 0 }, { _ITER_JUMP_LIST, 0, 0 }, { _ITER_NEXT_LIST, 0, 0 } } }, + [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, 0, 0 }, { _ITER_JUMP_TUPLE, 0, 0 }, { _ITER_NEXT_TUPLE, 0, 0 } } }, + [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, 0, 0 }, { _ITER_JUMP_RANGE, 0, 0 }, { _ITER_NEXT_RANGE, 0, 0 } } }, + [BEFORE_ASYNC_WITH] = { .nuops = 1, .uops = { { BEFORE_ASYNC_WITH, 0, 0 } } }, + [BEFORE_WITH] = { .nuops = 1, .uops = { { BEFORE_WITH, 0, 0 } } }, [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { WITH_EXCEPT_START, 0, 0 } } }, [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 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 } } }, - [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 9, .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 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } }, - [CALL_PY_EXACT_ARGS] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } }, + [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_RETURN_OFFSET, 7, 3 }, { _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_RETURN_OFFSET, 7, 3 }, { _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 } } }, @@ -1682,7 +1853,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { FORMAT_SIMPLE, 0, 0 } } }, [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { FORMAT_WITH_SPEC, 0, 0 } } }, [COPY] = { .nuops = 1, .uops = { { COPY, 0, 0 } } }, - [BINARY_OP] = { .nuops = 1, .uops = { { BINARY_OP, 0, 0 } } }, + [BINARY_OP] = { .nuops = 1, .uops = { { _BINARY_OP, 0, 0 } } }, [SWAP] = { .nuops = 1, .uops = { { SWAP, 0, 0 } } }, }; #endif // NEED_OPCODE_METADATA @@ -1692,6 +1863,8 @@ extern const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE]; const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = { [_EXIT_TRACE] = "_EXIT_TRACE", [_SET_IP] = "_SET_IP", + [_SPECIALIZE_TO_BOOL] = "_SPECIALIZE_TO_BOOL", + [_TO_BOOL] = "_TO_BOOL", [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT", [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT", [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT", @@ -1703,36 +1876,70 @@ const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = { [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE", [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE", [_BINARY_OP_INPLACE_ADD_UNICODE] = "_BINARY_OP_INPLACE_ADD_UNICODE", + [_SPECIALIZE_BINARY_SUBSCR] = "_SPECIALIZE_BINARY_SUBSCR", + [_BINARY_SUBSCR] = "_BINARY_SUBSCR", + [_SPECIALIZE_STORE_SUBSCR] = "_SPECIALIZE_STORE_SUBSCR", + [_STORE_SUBSCR] = "_STORE_SUBSCR", [_POP_FRAME] = "_POP_FRAME", + [_SPECIALIZE_SEND] = "_SPECIALIZE_SEND", + [_SEND] = "_SEND", + [_SPECIALIZE_UNPACK_SEQUENCE] = "_SPECIALIZE_UNPACK_SEQUENCE", + [_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE", + [_SPECIALIZE_STORE_ATTR] = "_SPECIALIZE_STORE_ATTR", + [_STORE_ATTR] = "_STORE_ATTR", + [_SPECIALIZE_LOAD_GLOBAL] = "_SPECIALIZE_LOAD_GLOBAL", + [_LOAD_GLOBAL] = "_LOAD_GLOBAL", [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION", [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION", [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE", [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS", + [_SPECIALIZE_LOAD_SUPER_ATTR] = "_SPECIALIZE_LOAD_SUPER_ATTR", + [_LOAD_SUPER_ATTR] = "_LOAD_SUPER_ATTR", + [_SPECIALIZE_LOAD_ATTR] = "_SPECIALIZE_LOAD_ATTR", + [_LOAD_ATTR] = "_LOAD_ATTR", [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION", [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES", [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE", + [_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", - [_GUARD_TYPE_VERSION_STORE] = "_GUARD_TYPE_VERSION_STORE", [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT", + [_SPECIALIZE_COMPARE_OP] = "_SPECIALIZE_COMPARE_OP", + [_COMPARE_OP] = "_COMPARE_OP", + [_POP_JUMP_IF_FALSE] = "_POP_JUMP_IF_FALSE", + [_POP_JUMP_IF_TRUE] = "_POP_JUMP_IF_TRUE", [_IS_NONE] = "_IS_NONE", + [_SPECIALIZE_FOR_ITER] = "_SPECIALIZE_FOR_ITER", + [_FOR_ITER] = "_FOR_ITER", + [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO", [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST", [_ITER_JUMP_LIST] = "_ITER_JUMP_LIST", - [_IS_ITER_EXHAUSTED_LIST] = "_IS_ITER_EXHAUSTED_LIST", + [_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_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", + [_GUARD_NOT_EXHAUSTED_TUPLE] = "_GUARD_NOT_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", + [_GUARD_NOT_EXHAUSTED_RANGE] = "_GUARD_NOT_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", + [_SPECIALIZE_CALL] = "_SPECIALIZE_CALL", + [_CALL] = "_CALL", [_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", @@ -1740,11 +1947,16 @@ const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = { [_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", + [_SPECIALIZE_BINARY_OP] = "_SPECIALIZE_BINARY_OP", + [_BINARY_OP] = "_BINARY_OP", + [_GUARD_IS_TRUE_POP] = "_GUARD_IS_TRUE_POP", + [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP", + [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP", + [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP", [_JUMP_TO_TOP] = "_JUMP_TO_TOP", - [_SAVE_CURRENT_IP] = "_SAVE_CURRENT_IP", + [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET", [_INSERT] = "_INSERT", + [_CHECK_VALIDITY] = "_CHECK_VALIDITY", }; #endif // NEED_OPCODE_METADATA @@ -1978,6 +2190,7 @@ extern const uint8_t _PyOpcode_Caches[256]; #ifdef NEED_OPCODE_METADATA const uint8_t _PyOpcode_Caches[256] = { [TO_BOOL] = 3, + [BINARY_OP_INPLACE_ADD_UNICODE] = 1, [BINARY_SUBSCR] = 1, [STORE_SUBSCR] = 1, [SEND] = 1, @@ -1987,14 +2200,14 @@ const uint8_t _PyOpcode_Caches[256] = { [LOAD_SUPER_ATTR] = 1, [LOAD_ATTR] = 9, [COMPARE_OP] = 1, - [POP_JUMP_IF_FALSE] = 1, + [JUMP_BACKWARD] = 1, [POP_JUMP_IF_TRUE] = 1, + [POP_JUMP_IF_FALSE] = 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 diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h index c4acb00a4b291e..208bfb2f75308b 100644 --- a/Include/internal/pycore_opcode_utils.h +++ b/Include/internal/pycore_opcode_utils.h @@ -58,6 +58,14 @@ extern "C" { #define MAKE_FUNCTION_ANNOTATIONS 0x04 #define MAKE_FUNCTION_CLOSURE 0x08 +/* Values used in the oparg for RESUME */ +#define RESUME_AT_FUNC_START 0 +#define RESUME_AFTER_YIELD 1 +#define RESUME_AFTER_YIELD_FROM 2 +#define RESUME_AFTER_AWAIT 3 + +#define RESUME_OPARG_LOCATION_MASK 0x3 +#define RESUME_OPARG_DEPTH1_MASK 0x4 #ifdef __cplusplus } diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index f9f16c48cbc21c..b052460b44b791 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -13,6 +13,11 @@ extern "C" { int _Py_uop_analyze_and_optimize(PyCodeObject *code, _PyUOpInstruction *trace, int trace_len, int curr_stackentries); +extern PyTypeObject _PyCounterExecutor_Type; +extern PyTypeObject _PyCounterOptimizer_Type; +extern PyTypeObject _PyDefaultOptimizer_Type; +extern PyTypeObject _PyUOpExecutor_Type; +extern PyTypeObject _PyUOpOptimizer_Type; #ifdef __cplusplus } 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_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 184eb35e52b47b..0f16fb894d17e1 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -170,11 +170,6 @@ Py_DEPRECATED(3.12) extern void _PyErr_ChainExceptions(PyObject *, PyObject *, P // 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 78bf0c7d07eb10..0ce08900e96f0b 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -5,35 +5,24 @@ # error "this header requires Py_BUILD_CORE define" #endif -/* Helpers for hash functions */ -extern Py_hash_t _Py_HashDouble(PyObject *, double); +// Similar to Py_HashPointer(), but don't replace -1 with -2. +static inline Py_hash_t +_Py_HashPointerRaw(const void *ptr) +{ + uintptr_t x = (uintptr_t)ptr; + Py_BUILD_ASSERT(sizeof(x) == sizeof(ptr)); -// Export for '_decimal' shared extension -PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); + // Bottom 3 or 4 bits are likely to be 0; rotate x by 4 to the right + // to avoid excessive hash collisions for dicts and sets. + x = (x >> 4) | (x << (8 * sizeof(uintptr_t) - 4)); -// Similar to _Py_HashPointer(), but don't replace -1 with -2 -extern Py_hash_t _Py_HashPointerRaw(const void*); + Py_BUILD_ASSERT(sizeof(x) == sizeof(Py_hash_t)); + return (Py_hash_t)x; +} // 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 diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index ec003a1dad2595..c675098685764c 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -40,7 +40,6 @@ extern void _PySys_FiniTypes(PyInterpreterState *interp); extern int _PyBuiltins_AddExceptions(PyObject * bltinmod); extern PyStatus _Py_HashRandomization_Init(const PyConfig *); -extern PyStatus _PyTime_Init(void); extern PyStatus _PyGC_Init(PyInterpreterState *interp); extern PyStatus _PyAtExit_Init(PyInterpreterState *interp); extern int _Py_Deepfreeze_Init(void); @@ -64,7 +63,7 @@ extern void _PyArg_Fini(void); extern void _Py_FinalizeAllocatedBlocks(_PyRuntimeState *); extern PyStatus _PyGILState_Init(PyInterpreterState *interp); -extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate); +extern void _PyGILState_SetTstate(PyThreadState *tstate); extern void _PyGILState_Fini(PyInterpreterState *interp); extern void _PyGC_DumpShutdownStats(PyInterpreterState *interp); @@ -114,6 +113,9 @@ extern int _Py_LegacyLocaleDetected(int warn); // Export for 'readline' shared extension PyAPI_FUNC(char*) _Py_SetLocaleFromEnv(int category); +// Export for special main.c string compiling with source tracebacks +int _PyRun_SimpleStringFlagsWithName(const char *command, const char* name, PyCompilerFlags *flags); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 6b5113714dbeb2..8631ca34a5e616 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -1,5 +1,8 @@ #ifndef Py_INTERNAL_PYMEM_H #define Py_INTERNAL_PYMEM_H + +#include "pycore_lock.h" // PyMutex + #ifdef __cplusplus extern "C" { #endif @@ -30,7 +33,7 @@ typedef struct { } debug_alloc_api_t; struct _pymem_allocators { - PyThread_type_lock mutex; + PyMutex mutex; struct { PyMemAllocatorEx raw; PyMemAllocatorEx mem; diff --git a/Include/internal/pycore_pymem_init.h b/Include/internal/pycore_pymem_init.h index 119fa16fb911ae..360fb9218a9cda 100644 --- a/Include/internal/pycore_pymem_init.h +++ b/Include/internal/pycore_pymem_init.h @@ -18,17 +18,30 @@ extern void * _PyMem_RawRealloc(void *, void *, size_t); extern void _PyMem_RawFree(void *, void *); #define PYRAW_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} -#ifdef WITH_PYMALLOC +#ifdef Py_GIL_DISABLED +// Py_GIL_DISABLED requires mimalloc +extern void* _PyObject_MiMalloc(void *, size_t); +extern void* _PyObject_MiCalloc(void *, size_t, size_t); +extern void _PyObject_MiFree(void *, void *); +extern void* _PyObject_MiRealloc(void *, void *, size_t); +# define PYOBJ_ALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree} +extern void* _PyMem_MiMalloc(void *, size_t); +extern void* _PyMem_MiCalloc(void *, size_t, size_t); +extern void _PyMem_MiFree(void *, void *); +extern void* _PyMem_MiRealloc(void *, void *, size_t); +# define PYMEM_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree} +#elif defined(WITH_PYMALLOC) extern void* _PyObject_Malloc(void *, size_t); extern void* _PyObject_Calloc(void *, size_t, size_t); extern void _PyObject_Free(void *, void *); extern void* _PyObject_Realloc(void *, void *, size_t); # define PYOBJ_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +# define PYMEM_ALLOC PYOBJ_ALLOC #else # define PYOBJ_ALLOC PYRAW_ALLOC +# define PYMEM_ALLOC PYOBJ_ALLOC #endif // WITH_PYMALLOC -#define PYMEM_ALLOC PYOBJ_ALLOC extern void* _PyMem_DebugRawMalloc(void *, size_t); extern void* _PyMem_DebugRawCalloc(void *, size_t, size_t); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 2e568f8aeeb152..c031a38cd6bfa3 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -11,6 +11,33 @@ extern "C" { #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. Use _Py_IsMainInterpreter() to check if it's the main interpreter. */ static inline int @@ -44,6 +71,12 @@ _Py_IsMainInterpreterFinalizing(PyInterpreterState *interp) 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) @@ -87,7 +120,7 @@ PyAPI_FUNC(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) { @@ -98,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) @@ -134,18 +182,15 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) { // PyThreadState functions -extern PyThreadState * _PyThreadState_New(PyInterpreterState *interp); +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 - thread id to that thread's current frame. -*/ -extern PyObject* _PyThread_CurrentFrames(void); - /* The implementation of sys._current_exceptions() Returns a dict mapping thread id to that thread's current exception. */ @@ -175,9 +220,9 @@ PyAPI_FUNC(int) _PyState_AddModule( extern int _PyOS_InterruptOccurred(PyThreadState *tstate); #define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) + PyMutex_LockFlags(&(runtime)->interpreters.mutex, _Py_LOCK_DONT_DETACH) #define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) + PyMutex_Unlock(&(runtime)->interpreters.mutex) // Get the configuration of the current interpreter. // The caller must hold the GIL. diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h index 5ec2abda91e86b..9c9a09f60f3441 100644 --- a/Include/internal/pycore_pythread.h +++ b/Include/internal/pycore_pythread.h @@ -8,30 +8,31 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "dynamic_annotations.h" // _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX + +// 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 @@ -44,6 +45,8 @@ extern "C" { #if defined(HAVE_PTHREAD_STUBS) +#include // bool + // pthread_key struct py_stub_tls_entry { bool in_use; @@ -83,6 +86,69 @@ extern int _PyThread_at_fork_reinit(PyThread_type_lock *lock); #endif /* HAVE_FORK */ +// unset: -1 seconds, in nanoseconds +#define PyThread_UNSET_TIMEOUT ((_PyTime_t)(-1 * 1000 * 1000 * 1000)) + +// Exported for the _xxinterpchannels module. +PyAPI_FUNC(int) PyThread_ParseTimeoutArg( + PyObject *arg, + int blocking, + PY_TIMEOUT_T *timeout); + +/* Helper to acquire an interruptible lock with a timeout. If the lock acquire + * is interrupted, signal handlers are run, and if they raise an exception, + * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE + * are returned, depending on whether the lock can be acquired within the + * timeout. + */ +// Exported for the _xxinterpchannels module. +PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed_with_retries( + PyThread_type_lock, + PY_TIMEOUT_T microseconds); + +typedef unsigned long long PyThread_ident_t; +typedef Py_uintptr_t PyThread_handle_t; + +#define PY_FORMAT_THREAD_IDENT_T "llu" +#define Py_PARSE_THREAD_IDENT_T "K" + +PyAPI_FUNC(PyThread_ident_t) PyThread_get_thread_ident_ex(void); + +/* Thread joining APIs. + * + * These APIs have a strict contract: + * - Either PyThread_join_thread or PyThread_detach_thread must be called + * exactly once with the given handle. + * - Calling neither PyThread_join_thread nor PyThread_detach_thread results + * in a resource leak until the end of the process. + * - Any other usage, such as calling both PyThread_join_thread and + * PyThread_detach_thread, or calling them more than once (including + * simultaneously), results in undefined behavior. + */ +PyAPI_FUNC(int) PyThread_start_joinable_thread(void (*func)(void *), + void *arg, + PyThread_ident_t* ident, + PyThread_handle_t* handle); +/* + * Join a thread started with `PyThread_start_joinable_thread`. + * This function cannot be interrupted. It returns 0 on success, + * a non-zero value on failure. + */ +PyAPI_FUNC(int) PyThread_join_thread(PyThread_handle_t); +/* + * Detach a thread started with `PyThread_start_joinable_thread`, such + * that its resources are relased as soon as it exits. + * This function cannot be interrupted. It returns 0 on success, + * a non-zero value on failure. + */ +PyAPI_FUNC(int) PyThread_detach_thread(PyThread_handle_t); + +/* + * Obtain the new thread ident and handle in a forked child process. + */ +PyAPI_FUNC(void) PyThread_update_thread_after_fork(PyThread_ident_t* ident, + PyThread_handle_t* handle); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index cc3a3420befa3d..e3348296ea61b7 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -9,8 +9,8 @@ extern "C" { #endif #include "pycore_atexit.h" // struct _atexit_runtime_state -#include "pycore_atomic.h" // _Py_atomic_address #include "pycore_ceval_state.h" // struct _ceval_runtime_state +#include "pycore_crossinterp.h" // struct _xidregistry #include "pycore_faulthandler.h" // struct _faulthandler_runtime_state #include "pycore_floatobject.h" // struct _Py_float_runtime_state #include "pycore_import.h" // struct _import_runtime_state @@ -21,13 +21,11 @@ extern "C" { #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_state struct _getargs_runtime_state { - PyThread_type_lock mutex; struct _PyArg_Parser *static_parsers; }; @@ -88,7 +86,7 @@ typedef struct _Py_DebugOffsets { struct _interpreter_frame { off_t previous; off_t executable; - off_t prev_instr; + off_t instr_ptr; off_t localsplus; off_t owner; } interpreter_frame; @@ -170,12 +168,12 @@ 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; + PyMutex mutex; /* The linked list of interpreters, newest first. */ PyInterpreterState *head; /* The runtime's initial interpreter, which has a special role @@ -200,16 +198,12 @@ typedef struct pyruntimestate { possible to facilitate out-of-process observability tools. */ - // XXX Remove this field once we have a tp_* slot. - struct _xidregistry { - PyThread_type_lock mutex; - struct _xidregitem *head; - } xidregistry; + /* cross-interpreter data and utils */ + struct _xi_runtime_state xi; struct _pymem_allocators allocators; struct _obmalloc_global_state obmalloc; struct pyhash_runtime_state pyhash_state; - struct _time_runtime_state time; struct _pythread_runtime_state threads; struct _signals_runtime_state signals; @@ -240,7 +234,7 @@ typedef struct pyruntimestate { Py_OpenCodeHookFunction open_code_hook; void *open_code_userdata; struct { - PyThread_type_lock mutex; + PyMutex mutex; _Py_AuditHookEntry *head; } audit_hooks; @@ -302,7 +296,7 @@ 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 @@ -312,7 +306,7 @@ _PyRuntimeState_GetFinalizingID(_PyRuntimeState *runtime) { 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); } diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 2deba02a89f33c..d324a94278839c 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -58,7 +58,7 @@ extern PyTypeObject _PyExc_MemoryError; .interpreter_frame = { \ .previous = offsetof(_PyInterpreterFrame, previous), \ .executable = offsetof(_PyInterpreterFrame, f_executable), \ - .prev_instr = offsetof(_PyInterpreterFrame, prev_instr), \ + .instr_ptr = offsetof(_PyInterpreterFrame, instr_ptr), \ .localsplus = offsetof(_PyInterpreterFrame, localsplus), \ .owner = offsetof(_PyInterpreterFrame, owner), \ }, \ @@ -95,6 +95,11 @@ extern PyTypeObject _PyExc_MemoryError; until _PyInterpreterState_Enable() is called. */ \ .next_id = -1, \ }, \ + .xi = { \ + .registry = { \ + .global = 1, \ + }, \ + }, \ /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ in accordance with the specification. */ \ .autoTSSkey = Py_tss_NEEDS_INIT, \ @@ -129,13 +134,13 @@ extern PyTypeObject _PyExc_MemoryError; .latin1 = _Py_str_latin1_INIT, \ }, \ .tuple_empty = { \ - .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0) \ + .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0), \ }, \ .hamt_bitmap_node_empty = { \ - .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0) \ + .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0), \ }, \ .context_token_missing = { \ - .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type) \ + .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type), \ }, \ }, \ }, \ @@ -172,19 +177,26 @@ extern PyTypeObject _PyExc_MemoryError; .singletons = { \ ._not_used = 1, \ .hamt_empty = { \ - .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type) \ + .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type), \ .h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \ }, \ .last_resort_memory_error = { \ - _PyObject_HEAD_INIT(&_PyExc_MemoryError) \ + _PyObject_HEAD_INIT(&_PyExc_MemoryError), \ + .args = (PyObject*)&_Py_SINGLETON(tuple_empty) \ }, \ }, \ }, \ - ._initial_thread = _PyThreadState_INIT, \ + ._initial_thread = _PyThreadStateImpl_INIT, \ + } + +#define _PyThreadStateImpl_INIT \ + { \ + .base = _PyThreadState_INIT, \ } #define _PyThreadState_INIT \ { \ + ._whence = _PyThreadState_WHENCE_NOTSET, \ .py_recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ .context_ver = 1, \ } @@ -204,7 +216,7 @@ extern PyTypeObject _PyExc_MemoryError; #define _PyBytes_SIMPLE_INIT(CH, LEN) \ { \ - _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)) \ + _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)), \ .ob_shash = -1, \ .ob_sval = { (CH) }, \ } @@ -215,7 +227,7 @@ extern PyTypeObject _PyExc_MemoryError; #define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \ { \ - .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type) \ + .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type), \ .length = sizeof(LITERAL) - 1, \ .hash = -1, \ .state = { \ diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 2f3ca1aa2dd3b0..e7d3e6c9627593 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -824,6 +824,7 @@ extern "C" { INIT_ID(call), \ INIT_ID(call_exception_handler), \ INIT_ID(call_soon), \ + INIT_ID(callback), \ INIT_ID(cancel), \ INIT_ID(capath), \ INIT_ID(category), \ @@ -895,7 +896,6 @@ extern "C" { INIT_ID(dont_inherit), \ INIT_ID(dst), \ INIT_ID(dst_dir_fd), \ - INIT_ID(duration), \ INIT_ID(e), \ INIT_ID(eager_start), \ INIT_ID(effective_ids), \ @@ -941,7 +941,6 @@ extern "C" { INIT_ID(flush), \ INIT_ID(follow_symlinks), \ INIT_ID(format), \ - INIT_ID(frequency), \ INIT_ID(from_param), \ INIT_ID(fromlist), \ INIT_ID(fromtimestamp), \ @@ -973,6 +972,7 @@ extern "C" { INIT_ID(hook), \ INIT_ID(id), \ INIT_ID(ident), \ + INIT_ID(identity_hint), \ INIT_ID(ignore), \ INIT_ID(imag), \ INIT_ID(importlib), \ @@ -996,6 +996,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), \ @@ -1192,7 +1193,6 @@ extern "C" { INIT_ID(sleep), \ INIT_ID(sock), \ INIT_ID(sort), \ - INIT_ID(sound), \ INIT_ID(source), \ INIT_ID(source_traceback), \ INIT_ID(src), \ diff --git a/Include/internal/pycore_semaphore.h b/Include/internal/pycore_semaphore.h index 2a4ecb7147acee..4c37df7b39a48a 100644 --- a/Include/internal/pycore_semaphore.h +++ b/Include/internal/pycore_semaphore.h @@ -7,7 +7,8 @@ # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_time.h" // _PyTime_t +#include "pycore_pythread.h" // _POSIX_SEMAPHORES +#include "pycore_time.h" // _PyTime_t #ifdef MS_WINDOWS # define WIN32_LEAN_AND_MEAN @@ -26,6 +27,7 @@ # include #endif + #ifdef __cplusplus extern "C" { #endif diff --git a/Include/internal/pycore_signal.h b/Include/internal/pycore_signal.h index b38b1d30112b60..47213a34ab77b5 100644 --- a/Include/internal/pycore_signal.h +++ b/Include/internal/pycore_signal.h @@ -10,7 +10,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atomic.h" // _Py_atomic_address #include // NSIG @@ -38,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 { @@ -63,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; diff --git a/Include/internal/pycore_time.h b/Include/internal/pycore_time.h index d8ea63a7242ccc..dabbd7b41556cd 100644 --- a/Include/internal/pycore_time.h +++ b/Include/internal/pycore_time.h @@ -52,16 +52,6 @@ extern "C" { #endif -struct _time_runtime_state { -#ifdef HAVE_TIMES - int ticks_per_second_initialized; - long ticks_per_second; -#else - int _not_used; -#endif -}; - - #ifdef __clang__ struct timeval; #endif @@ -143,6 +133,10 @@ PyAPI_FUNC(int) _PyTime_ObjectToTimespec( // Export for '_socket' shared extension. PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); +// 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) \ @@ -241,7 +235,7 @@ PyAPI_FUNC(int) _PyTime_AsTimevalTime_t( #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); +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. @@ -259,13 +253,6 @@ 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. -extern _PyTime_t _PyTime_MulDiv(_PyTime_t ticks, - _PyTime_t mul, - _PyTime_t div); - // Structure used by time.get_clock_info() typedef struct { const char *implementation; @@ -361,6 +348,32 @@ PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout); PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline); +// --- _PyTimeFraction ------------------------------------------------------- + +typedef struct { + _PyTime_t numer; + _PyTime_t denom; +} _PyTimeFraction; + +// Set a fraction. +// Return 0 on success. +// Return -1 if the fraction is invalid. +extern int _PyTimeFraction_Set( + _PyTimeFraction *frac, + _PyTime_t numer, + _PyTime_t denom); + +// Compute ticks * frac.numer / frac.denom. +// Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. +extern _PyTime_t _PyTimeFraction_Mul( + _PyTime_t ticks, + const _PyTimeFraction *frac); + +// Compute a clock resolution: frac.numer / frac.denom / 1e9. +extern double _PyTimeFraction_Resolution( + const _PyTimeFraction *frac); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_traceback.h b/Include/internal/pycore_traceback.h index 01b3f5b6b26d2e..10922bff98bd4b 100644 --- a/Include/internal/pycore_traceback.h +++ b/Include/internal/pycore_traceback.h @@ -95,9 +95,8 @@ extern 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). */ -extern int _PyTraceBack_Print_Indented( - PyObject *tb, int indent, const char* margin, - const char *header_margin, const char *header, PyObject *f); +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 *); diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h new file mode 100644 index 00000000000000..17f3e865641773 --- /dev/null +++ b/Include/internal/pycore_tstate.h @@ -0,0 +1,26 @@ +#ifndef Py_INTERNAL_TSTATE_H +#define Py_INTERNAL_TSTATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +// Every PyThreadState is actually allocated as a _PyThreadStateImpl. The +// PyThreadState fields are exposed as part of the C API, although most fields +// are intended to be private. The _PyThreadStateImpl fields not exposed. +typedef struct _PyThreadStateImpl { + // semi-public fields are in PyThreadState. + PyThreadState base; + + // TODO: add private fields here +} _PyThreadStateImpl; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TSTATE_H */ diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 27c6c8731cb3f9..f983de56049631 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -135,6 +135,8 @@ extern PyObject* _Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute); extern PyObject* _Py_type_getattro(PyTypeObject *type, PyObject *name); +extern PyObject* _Py_BaseObject_RichCompare(PyObject* self, PyObject* other, int op); + extern PyObject* _Py_slot_tp_getattro(PyObject *self, PyObject *name); extern PyObject* _Py_slot_tp_getattr_hook(PyObject *self, PyObject *name); @@ -143,6 +145,11 @@ extern PyTypeObject _PyBufferWrapper_Type; extern PyObject* _PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *meth_found); + +// This is exported for the _testinternalcapi module. +PyAPI_FUNC(PyObject *) _PyType_GetModuleName(PyTypeObject *); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_ucnhash.h b/Include/internal/pycore_ucnhash.h index 187dd68e7347ff..1561dfbb3150d3 100644 --- a/Include/internal/pycore_ucnhash.h +++ b/Include/internal/pycore_ucnhash.h @@ -28,6 +28,8 @@ typedef struct { } _PyUnicode_Name_CAPI; +extern _PyUnicode_Name_CAPI* _PyUnicode_GetNameCAPI(void); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 360a9e1819f8e8..7ee540154b23d8 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -8,6 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_lock.h" // PyMutex #include "pycore_fileutils.h" // _Py_error_handler #include "pycore_identifier.h" // _Py_Identifier #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI @@ -73,122 +74,6 @@ extern Py_UCS4 _PyUnicode_FindMaxChar ( /* --- _PyUnicodeWriter API ----------------------------------------------- */ -typedef struct { - PyObject *buffer; - void *data; - int kind; - Py_UCS4 maxchar; - Py_ssize_t size; - Py_ssize_t pos; - - /* minimum number of allocated characters (default: 0) */ - Py_ssize_t min_length; - - /* minimum character (default: 127, ASCII) */ - Py_UCS4 min_char; - - /* If non-zero, overallocate the buffer (default: 0). */ - unsigned char overallocate; - - /* If readonly is 1, buffer is a shared string (cannot be modified) - and size is set to 0. */ - 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. -// -// Export the _PyUnicodeWriter API for '_multibytecodec' shared extension. -PyAPI_FUNC(void) -_PyUnicodeWriter_Init(_PyUnicodeWriter *writer); - -/* Prepare the buffer to write 'length' characters - with the specified maximum character. - - Return 0 on success, raise an exception and return -1 on error. */ -#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \ - (((MAXCHAR) <= (WRITER)->maxchar \ - && (LENGTH) <= (WRITER)->size - (WRITER)->pos) \ - ? 0 \ - : (((LENGTH) == 0) \ - ? 0 \ - : _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR)))) - -/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro - instead. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, - Py_ssize_t length, Py_UCS4 maxchar); - -/* Prepare the buffer to have at least the kind KIND. - For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will - support characters in range U+000-U+FFFF. - - Return 0 on success, raise an exception and return -1 on error. */ -#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ - ((KIND) <= (WRITER)->kind \ - ? 0 \ - : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) - -/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind() - macro instead. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - int kind); - -/* Append a Unicode character. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, - Py_UCS4 ch - ); - -/* Append a Unicode string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, - PyObject *str /* Unicode string */ - ); - -/* Append a substring of a Unicode string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, - PyObject *str, /* Unicode string */ - Py_ssize_t start, - Py_ssize_t end - ); - -/* Append an ASCII-encoded byte string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, - const char *str, /* ASCII-encoded byte string */ - Py_ssize_t len /* number of bytes, or -1 if unknown */ - ); - -/* Append a latin1-encoded byte string. - Return 0 on success, raise an exception and return -1 on error. */ -PyAPI_FUNC(int) -_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, - const char *str, /* latin1-encoded byte string */ - Py_ssize_t len /* length in bytes */ - ); - -/* Get the value of the writer as a Unicode string. Clear the - buffer of the writer. Raise an exception and return NULL - on error. */ -PyAPI_FUNC(PyObject *) -_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer); - -/* Deallocate memory of a writer (clear its internal buffer). */ -PyAPI_FUNC(void) -_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer); - - /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ extern int _PyUnicode_FormatAdvancedWriter( @@ -366,11 +251,6 @@ 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. -// 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 *); @@ -398,7 +278,7 @@ extern PyTypeObject _PyUnicodeASCIIIter_Type; /* --- Other API ---------------------------------------------------------- */ struct _Py_unicode_runtime_ids { - PyThread_type_lock lock; + PyMutex mutex; // next_index value must be preserved when Py_Initialize()/Py_Finalize() // is called multiple times: see _PyUnicode_FromId() implementation. Py_ssize_t next_index; @@ -434,6 +314,10 @@ struct _Py_unicode_state { extern void _PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p); extern void _PyUnicode_ClearInterned(PyInterpreterState *interp); +// Like PyUnicode_AsUTF8(), but check for embedded null characters. +// Export for '_sqlite3' shared extension. +PyAPI_FUNC(const char *) _PyUnicode_AsUTF8NoNUL(PyObject *); + #ifdef __cplusplus } diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 887fa6bcfd5983..098afba0cd7bce 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -786,6 +786,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(call_soon); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(callback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(cancel); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -999,9 +1002,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(dst_dir_fd); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(duration); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(e); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1137,9 +1137,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(format); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(frequency); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(from_param); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1233,6 +1230,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(ident); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(identity_hint); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(ignore); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); @@ -1302,6 +1302,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); @@ -1890,9 +1893,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(sort); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); - string = &_Py_ID(sound); - assert(_PyUnicode_CheckConsistency(string, 1)); - _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(source); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h new file mode 100644 index 00000000000000..c96ea51ae1acb6 --- /dev/null +++ b/Include/internal/pycore_uop_ids.h @@ -0,0 +1,268 @@ +// This file is generated by Tools/cases_generator/uop_id_generator.py +// from: +// Python/bytecodes.c +// Do not edit! +#ifndef Py_CORE_UOP_IDS_H +#define Py_CORE_UOP_IDS_H +#ifdef __cplusplus +extern "C" { +#endif + +#define _EXIT_TRACE 300 +#define _SET_IP 301 +#define _NOP NOP +#define _RESUME RESUME +#define _RESUME_CHECK RESUME_CHECK +#define _INSTRUMENTED_RESUME INSTRUMENTED_RESUME +#define _LOAD_FAST_CHECK LOAD_FAST_CHECK +#define _LOAD_FAST LOAD_FAST +#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR +#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST +#define _LOAD_CONST LOAD_CONST +#define _STORE_FAST STORE_FAST +#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST +#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST +#define _POP_TOP POP_TOP +#define _PUSH_NULL PUSH_NULL +#define _INSTRUMENTED_END_FOR INSTRUMENTED_END_FOR +#define _END_SEND END_SEND +#define _INSTRUMENTED_END_SEND INSTRUMENTED_END_SEND +#define _UNARY_NEGATIVE UNARY_NEGATIVE +#define _UNARY_NOT UNARY_NOT +#define _SPECIALIZE_TO_BOOL 302 +#define _TO_BOOL 303 +#define _TO_BOOL_BOOL TO_BOOL_BOOL +#define _TO_BOOL_INT TO_BOOL_INT +#define _TO_BOOL_LIST TO_BOOL_LIST +#define _TO_BOOL_NONE TO_BOOL_NONE +#define _TO_BOOL_STR TO_BOOL_STR +#define _TO_BOOL_ALWAYS_TRUE TO_BOOL_ALWAYS_TRUE +#define _UNARY_INVERT UNARY_INVERT +#define _GUARD_BOTH_INT 304 +#define _BINARY_OP_MULTIPLY_INT 305 +#define _BINARY_OP_ADD_INT 306 +#define _BINARY_OP_SUBTRACT_INT 307 +#define _GUARD_BOTH_FLOAT 308 +#define _BINARY_OP_MULTIPLY_FLOAT 309 +#define _BINARY_OP_ADD_FLOAT 310 +#define _BINARY_OP_SUBTRACT_FLOAT 311 +#define _GUARD_BOTH_UNICODE 312 +#define _BINARY_OP_ADD_UNICODE 313 +#define _BINARY_OP_INPLACE_ADD_UNICODE 314 +#define _SPECIALIZE_BINARY_SUBSCR 315 +#define _BINARY_SUBSCR 316 +#define _BINARY_SLICE BINARY_SLICE +#define _STORE_SLICE STORE_SLICE +#define _BINARY_SUBSCR_LIST_INT BINARY_SUBSCR_LIST_INT +#define _BINARY_SUBSCR_STR_INT BINARY_SUBSCR_STR_INT +#define _BINARY_SUBSCR_TUPLE_INT BINARY_SUBSCR_TUPLE_INT +#define _BINARY_SUBSCR_DICT BINARY_SUBSCR_DICT +#define _BINARY_SUBSCR_GETITEM BINARY_SUBSCR_GETITEM +#define _LIST_APPEND LIST_APPEND +#define _SET_ADD SET_ADD +#define _SPECIALIZE_STORE_SUBSCR 317 +#define _STORE_SUBSCR 318 +#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT +#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT +#define _DELETE_SUBSCR DELETE_SUBSCR +#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1 +#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2 +#define _RAISE_VARARGS RAISE_VARARGS +#define _INTERPRETER_EXIT INTERPRETER_EXIT +#define _POP_FRAME 319 +#define _INSTRUMENTED_RETURN_VALUE INSTRUMENTED_RETURN_VALUE +#define _INSTRUMENTED_RETURN_CONST INSTRUMENTED_RETURN_CONST +#define _GET_AITER GET_AITER +#define _GET_ANEXT GET_ANEXT +#define _GET_AWAITABLE GET_AWAITABLE +#define _SPECIALIZE_SEND 320 +#define _SEND 321 +#define _SEND_GEN SEND_GEN +#define _INSTRUMENTED_YIELD_VALUE INSTRUMENTED_YIELD_VALUE +#define _YIELD_VALUE YIELD_VALUE +#define _POP_EXCEPT POP_EXCEPT +#define _RERAISE RERAISE +#define _END_ASYNC_FOR END_ASYNC_FOR +#define _CLEANUP_THROW CLEANUP_THROW +#define _LOAD_ASSERTION_ERROR LOAD_ASSERTION_ERROR +#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS +#define _STORE_NAME STORE_NAME +#define _DELETE_NAME DELETE_NAME +#define _SPECIALIZE_UNPACK_SEQUENCE 322 +#define _UNPACK_SEQUENCE 323 +#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE +#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE +#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST +#define _UNPACK_EX UNPACK_EX +#define _SPECIALIZE_STORE_ATTR 324 +#define _STORE_ATTR 325 +#define _DELETE_ATTR DELETE_ATTR +#define _STORE_GLOBAL STORE_GLOBAL +#define _DELETE_GLOBAL DELETE_GLOBAL +#define _LOAD_LOCALS LOAD_LOCALS +#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS +#define _LOAD_NAME LOAD_NAME +#define _SPECIALIZE_LOAD_GLOBAL 326 +#define _LOAD_GLOBAL 327 +#define _GUARD_GLOBALS_VERSION 328 +#define _GUARD_BUILTINS_VERSION 329 +#define _LOAD_GLOBAL_MODULE 330 +#define _LOAD_GLOBAL_BUILTINS 331 +#define _DELETE_FAST DELETE_FAST +#define _MAKE_CELL MAKE_CELL +#define _DELETE_DEREF DELETE_DEREF +#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF +#define _LOAD_DEREF LOAD_DEREF +#define _STORE_DEREF STORE_DEREF +#define _COPY_FREE_VARS COPY_FREE_VARS +#define _BUILD_STRING BUILD_STRING +#define _BUILD_TUPLE BUILD_TUPLE +#define _BUILD_LIST BUILD_LIST +#define _LIST_EXTEND LIST_EXTEND +#define _SET_UPDATE SET_UPDATE +#define _BUILD_SET BUILD_SET +#define _BUILD_MAP BUILD_MAP +#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS +#define _BUILD_CONST_KEY_MAP BUILD_CONST_KEY_MAP +#define _DICT_UPDATE DICT_UPDATE +#define _DICT_MERGE DICT_MERGE +#define _MAP_ADD MAP_ADD +#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR +#define _SPECIALIZE_LOAD_SUPER_ATTR 332 +#define _LOAD_SUPER_ATTR 333 +#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR +#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD +#define _SPECIALIZE_LOAD_ATTR 334 +#define _LOAD_ATTR 335 +#define _GUARD_TYPE_VERSION 336 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES 337 +#define _LOAD_ATTR_INSTANCE_VALUE 338 +#define _CHECK_ATTR_MODULE 339 +#define _LOAD_ATTR_MODULE 340 +#define _CHECK_ATTR_WITH_HINT 341 +#define _LOAD_ATTR_WITH_HINT 342 +#define _LOAD_ATTR_SLOT 343 +#define _CHECK_ATTR_CLASS 344 +#define _LOAD_ATTR_CLASS 345 +#define _LOAD_ATTR_PROPERTY LOAD_ATTR_PROPERTY +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN +#define _GUARD_DORV_VALUES 346 +#define _STORE_ATTR_INSTANCE_VALUE 347 +#define _STORE_ATTR_WITH_HINT STORE_ATTR_WITH_HINT +#define _STORE_ATTR_SLOT 348 +#define _SPECIALIZE_COMPARE_OP 349 +#define _COMPARE_OP 350 +#define _COMPARE_OP_FLOAT COMPARE_OP_FLOAT +#define _COMPARE_OP_INT COMPARE_OP_INT +#define _COMPARE_OP_STR COMPARE_OP_STR +#define _IS_OP IS_OP +#define _CONTAINS_OP CONTAINS_OP +#define _CHECK_EG_MATCH CHECK_EG_MATCH +#define _CHECK_EXC_MATCH CHECK_EXC_MATCH +#define _IMPORT_NAME IMPORT_NAME +#define _IMPORT_FROM IMPORT_FROM +#define _JUMP_FORWARD JUMP_FORWARD +#define _JUMP_BACKWARD JUMP_BACKWARD +#define _ENTER_EXECUTOR ENTER_EXECUTOR +#define _POP_JUMP_IF_FALSE 351 +#define _POP_JUMP_IF_TRUE 352 +#define _IS_NONE 353 +#define _JUMP_BACKWARD_NO_INTERRUPT JUMP_BACKWARD_NO_INTERRUPT +#define _GET_LEN GET_LEN +#define _MATCH_CLASS MATCH_CLASS +#define _MATCH_MAPPING MATCH_MAPPING +#define _MATCH_SEQUENCE MATCH_SEQUENCE +#define _MATCH_KEYS MATCH_KEYS +#define _GET_ITER GET_ITER +#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER +#define _SPECIALIZE_FOR_ITER 354 +#define _FOR_ITER 355 +#define _FOR_ITER_TIER_TWO 356 +#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER +#define _ITER_CHECK_LIST 357 +#define _ITER_JUMP_LIST 358 +#define _GUARD_NOT_EXHAUSTED_LIST 359 +#define _ITER_NEXT_LIST 360 +#define _ITER_CHECK_TUPLE 361 +#define _ITER_JUMP_TUPLE 362 +#define _GUARD_NOT_EXHAUSTED_TUPLE 363 +#define _ITER_NEXT_TUPLE 364 +#define _ITER_CHECK_RANGE 365 +#define _ITER_JUMP_RANGE 366 +#define _GUARD_NOT_EXHAUSTED_RANGE 367 +#define _ITER_NEXT_RANGE 368 +#define _FOR_ITER_GEN FOR_ITER_GEN +#define _BEFORE_ASYNC_WITH BEFORE_ASYNC_WITH +#define _BEFORE_WITH BEFORE_WITH +#define _WITH_EXCEPT_START WITH_EXCEPT_START +#define _PUSH_EXC_INFO PUSH_EXC_INFO +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 369 +#define _GUARD_KEYS_VERSION 370 +#define _LOAD_ATTR_METHOD_WITH_VALUES 371 +#define _LOAD_ATTR_METHOD_NO_DICT 372 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 373 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 374 +#define _CHECK_ATTR_METHOD_LAZY_DICT 375 +#define _LOAD_ATTR_METHOD_LAZY_DICT 376 +#define _INSTRUMENTED_CALL INSTRUMENTED_CALL +#define _SPECIALIZE_CALL 377 +#define _CALL 378 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 379 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 380 +#define _CHECK_PEP_523 381 +#define _CHECK_FUNCTION_EXACT_ARGS 382 +#define _CHECK_STACK_SPACE 383 +#define _INIT_CALL_PY_EXACT_ARGS 384 +#define _PUSH_FRAME 385 +#define _CALL_PY_WITH_DEFAULTS CALL_PY_WITH_DEFAULTS +#define _CALL_TYPE_1 CALL_TYPE_1 +#define _CALL_STR_1 CALL_STR_1 +#define _CALL_TUPLE_1 CALL_TUPLE_1 +#define _CALL_ALLOC_AND_ENTER_INIT CALL_ALLOC_AND_ENTER_INIT +#define _EXIT_INIT_CHECK EXIT_INIT_CHECK +#define _CALL_BUILTIN_CLASS CALL_BUILTIN_CLASS +#define _CALL_BUILTIN_O CALL_BUILTIN_O +#define _CALL_BUILTIN_FAST CALL_BUILTIN_FAST +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS CALL_BUILTIN_FAST_WITH_KEYWORDS +#define _CALL_LEN CALL_LEN +#define _CALL_ISINSTANCE CALL_ISINSTANCE +#define _CALL_LIST_APPEND CALL_LIST_APPEND +#define _CALL_METHOD_DESCRIPTOR_O CALL_METHOD_DESCRIPTOR_O +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS +#define _CALL_METHOD_DESCRIPTOR_NOARGS CALL_METHOD_DESCRIPTOR_NOARGS +#define _CALL_METHOD_DESCRIPTOR_FAST CALL_METHOD_DESCRIPTOR_FAST +#define _INSTRUMENTED_CALL_KW INSTRUMENTED_CALL_KW +#define _CALL_KW CALL_KW +#define _INSTRUMENTED_CALL_FUNCTION_EX INSTRUMENTED_CALL_FUNCTION_EX +#define _CALL_FUNCTION_EX CALL_FUNCTION_EX +#define _MAKE_FUNCTION MAKE_FUNCTION +#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE +#define _RETURN_GENERATOR RETURN_GENERATOR +#define _BUILD_SLICE BUILD_SLICE +#define _CONVERT_VALUE CONVERT_VALUE +#define _FORMAT_SIMPLE FORMAT_SIMPLE +#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC +#define _COPY COPY +#define _SPECIALIZE_BINARY_OP 386 +#define _BINARY_OP 387 +#define _SWAP SWAP +#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION +#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD +#define _INSTRUMENTED_JUMP_BACKWARD INSTRUMENTED_JUMP_BACKWARD +#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE +#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE +#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE +#define _GUARD_IS_TRUE_POP 388 +#define _GUARD_IS_FALSE_POP 389 +#define _GUARD_IS_NONE_POP 390 +#define _GUARD_IS_NOT_NONE_POP 391 +#define _JUMP_TO_TOP 392 +#define _SAVE_RETURN_OFFSET 393 +#define _INSERT 394 +#define _CHECK_VALIDITY 395 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_IDS_H */ diff --git a/Include/internal/pycore_uops.h b/Include/internal/pycore_uops.h index d8a7d978f1304e..153884f4bd2902 100644 --- a/Include/internal/pycore_uops.h +++ b/Include/internal/pycore_uops.h @@ -10,11 +10,12 @@ extern "C" { #include "pycore_frame.h" // _PyInterpreterFrame -#define _Py_UOP_MAX_TRACE_LENGTH 128 +#define _Py_UOP_MAX_TRACE_LENGTH 512 typedef struct { - uint32_t opcode; - uint32_t oparg; + uint16_t opcode; + uint16_t oparg; + uint32_t target; uint64_t operand; // A cache entry } _PyUOpInstruction; @@ -23,7 +24,7 @@ typedef struct { _PyUOpInstruction trace[1]; } _PyUOpExecutorObject; -_PyInterpreterFrame *_PyUopExecute( +_Py_CODEUNIT *_PyUOpExecute( _PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer); diff --git a/Include/internal/pycore_weakref.h b/Include/internal/pycore_weakref.h index 51b2bb6b11ede9..eacbe14c903289 100644 --- a/Include/internal/pycore_weakref.h +++ b/Include/internal/pycore_weakref.h @@ -8,6 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION() + static inline PyObject* _PyWeakref_GET_REF(PyObject *ref_obj) { assert(PyWeakref_Check(ref_obj)); PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj); @@ -35,15 +37,20 @@ static inline PyObject* _PyWeakref_GET_REF(PyObject *ref_obj) { static inline int _PyWeakref_IS_DEAD(PyObject *ref_obj) { assert(PyWeakref_Check(ref_obj)); + int is_dead; + Py_BEGIN_CRITICAL_SECTION(ref_obj); PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj); PyObject *obj = ref->wr_object; if (obj == Py_None) { // clear_weakref() was called - return 1; + is_dead = 1; } - - // See _PyWeakref_GET_REF() for the rationale of this test - return (Py_REFCNT(obj) == 0); + else { + // See _PyWeakref_GET_REF() for the rationale of this test + is_dead = (Py_REFCNT(obj) == 0); + } + Py_END_CRITICAL_SECTION(); + return is_dead; } extern Py_ssize_t _PyWeakref_GetWeakrefCount(PyWeakReference *head); diff --git a/Include/longobject.h b/Include/longobject.h index 7393254cd24a9b..51005efff636fa 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -7,7 +7,7 @@ extern "C" { /* Long (arbitrary precision) integer object interface */ -PyAPI_DATA(PyTypeObject) PyLong_Type; +// PyLong_Type is declared by object.h #define PyLong_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) diff --git a/Include/modsupport.h b/Include/modsupport.h index 6efe9dfaa9089e..ea4c0fce9f4562 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -9,10 +9,10 @@ extern "C" { PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); + const char *, PY_CXX_CONST char * const *, ...); PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, va_list); + const char *, PY_CXX_CONST char * const *, va_list); PyAPI_FUNC(int) PyArg_ValidateKeywordArguments(PyObject *); PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); @@ -134,12 +134,6 @@ PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, #endif /* New in 3.5 */ -#ifndef Py_LIMITED_API -# define Py_CPYTHON_MODSUPPORT_H -# include "cpython/modsupport.h" -# undef Py_CPYTHON_MODSUPPORT_H -#endif - #ifdef __cplusplus } #endif diff --git a/Include/moduleobject.h b/Include/moduleobject.h index ea08145381cee6..42b87cc4e91012 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -73,19 +73,23 @@ struct PyModuleDef_Slot { #define Py_mod_create 1 #define Py_mod_exec 2 -#define Py_mod_multiple_interpreters 3 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030c0000 +# define Py_mod_multiple_interpreters 3 +#endif #ifndef Py_LIMITED_API #define _Py_mod_LAST_SLOT 3 #endif -/* for Py_mod_multiple_interpreters: */ -#define Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED ((void *)0) -#define Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED ((void *)1) -#define Py_MOD_PER_INTERPRETER_GIL_SUPPORTED ((void *)2) - #endif /* New in 3.5 */ +/* for Py_mod_multiple_interpreters: */ +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030c0000 +# define Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED ((void *)0) +# define Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED ((void *)1) +# define Py_MOD_PER_INTERPRETER_GIL_SUPPORTED ((void *)2) +#endif + struct PyModuleDef { PyModuleDef_Base m_base; const char* m_name; diff --git a/Include/object.h b/Include/object.h index 9058558e3cd4d9..bd576b0bd43211 100644 --- a/Include/object.h +++ b/Include/object.h @@ -88,7 +88,7 @@ having all the lower 32 bits set, which will avoid the reference count to go beyond the refcount limit. Immortality checks for reference count decreases will be done by checking the bit sign flag in the lower 32 bits. */ -#define _Py_IMMORTAL_REFCNT UINT_MAX +#define _Py_IMMORTAL_REFCNT _Py_CAST(Py_ssize_t, UINT_MAX) #else /* @@ -103,12 +103,32 @@ immortality, but the execution would still be correct. Reference count increases and decreases will first go through an immortality check by comparing the reference count field to the immortality reference count. */ -#define _Py_IMMORTAL_REFCNT (UINT_MAX >> 2) +#define _Py_IMMORTAL_REFCNT _Py_CAST(Py_ssize_t, UINT_MAX >> 2) #endif +// Py_GIL_DISABLED builds indicate immortal objects using `ob_ref_local`, which is +// always 32-bits. +#ifdef Py_GIL_DISABLED +#define _Py_IMMORTAL_REFCNT_LOCAL UINT32_MAX +#endif + +// Kept for backward compatibility. It was needed by Py_TRACE_REFS build. +#define _PyObject_EXTRA_INIT + // Make all internal uses of PyObject_HEAD_INIT immortal while preserving the // C-API expectation that the refcnt will be set to 1. -#ifdef Py_BUILD_CORE +#if defined(Py_GIL_DISABLED) +#define PyObject_HEAD_INIT(type) \ + { \ + 0, \ + 0, \ + { 0 }, \ + 0, \ + _Py_IMMORTAL_REFCNT_LOCAL, \ + 0, \ + (type), \ + }, +#elif defined(Py_BUILD_CORE) #define PyObject_HEAD_INIT(type) \ { \ { _Py_IMMORTAL_REFCNT }, \ @@ -142,6 +162,7 @@ check by comparing the reference count field to the immortality reference count. * by hand. Similarly every pointer to a variable-size Python object can, * in addition, be cast to PyVarObject*. */ +#ifndef Py_GIL_DISABLED struct _object { #if (defined(__GNUC__) || defined(__clang__)) \ && !(defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L) @@ -166,6 +187,40 @@ struct _object { PyTypeObject *ob_type; }; +#else +// Objects that are not owned by any thread use a thread id (tid) of zero. +// This includes both immortal objects and objects whose reference count +// fields have been merged. +#define _Py_UNOWNED_TID 0 + +// The shared reference count uses the two least-significant bits to store +// flags. The remaining bits are used to store the reference count. +#define _Py_REF_SHARED_SHIFT 2 +#define _Py_REF_SHARED_FLAG_MASK 0x3 + +// The shared flags are initialized to zero. +#define _Py_REF_SHARED_INIT 0x0 +#define _Py_REF_MAYBE_WEAKREF 0x1 +#define _Py_REF_QUEUED 0x2 +#define _Py_REF_MERGED 0x3 + +// Create a shared field from a refcnt and desired flags +#define _Py_REF_SHARED(refcnt, flags) (((refcnt) << _Py_REF_SHARED_SHIFT) + (flags)) + +// NOTE: In non-free-threaded builds, `struct _PyMutex` is defined in +// pycore_lock.h. See pycore_lock.h for more details. +struct _PyMutex { uint8_t v; }; + +struct _object { + uintptr_t ob_tid; // thread id (or zero) + uint16_t _padding; + struct _PyMutex ob_mutex; // per-object lock + uint8_t ob_gc_bits; // gc-related state + uint32_t ob_ref_local; // local reference count + Py_ssize_t ob_ref_shared; // shared (atomic) reference count + PyTypeObject *ob_type; +}; +#endif /* Cast argument to PyObject* type. */ #define _PyObject_CAST(op) _Py_CAST(PyObject*, (op)) @@ -183,9 +238,76 @@ typedef struct { PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y); #define Py_Is(x, y) ((x) == (y)) +#if defined(Py_GIL_DISABLED) && !defined(Py_LIMITED_API) +static inline uintptr_t +_Py_ThreadId(void) +{ + uintptr_t tid; +#if defined(_MSC_VER) && defined(_M_X64) + tid = __readgsqword(48); +#elif defined(_MSC_VER) && defined(_M_IX86) + tid = __readfsdword(24); +#elif defined(_MSC_VER) && defined(_M_ARM64) + tid = __getReg(18); +#elif defined(__i386__) + __asm__("movl %%gs:0, %0" : "=r" (tid)); // 32-bit always uses GS +#elif defined(__MACH__) && defined(__x86_64__) + __asm__("movq %%gs:0, %0" : "=r" (tid)); // x86_64 macOSX uses GS +#elif defined(__x86_64__) + __asm__("movq %%fs:0, %0" : "=r" (tid)); // x86_64 Linux, BSD uses FS +#elif defined(__arm__) + __asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid)); +#elif defined(__aarch64__) && defined(__APPLE__) + __asm__ ("mrs %0, tpidrro_el0" : "=r" (tid)); +#elif defined(__aarch64__) + __asm__ ("mrs %0, tpidr_el0" : "=r" (tid)); +#elif defined(__powerpc64__) + #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer) + tid = (uintptr_t)__builtin_thread_pointer(); + #else + // r13 is reserved for use as system thread ID by the Power 64-bit ABI. + register uintptr_t tp __asm__ ("r13"); + __asm__("" : "=r" (tp)); + tid = tp; + #endif +#elif defined(__powerpc__) + #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer) + tid = (uintptr_t)__builtin_thread_pointer(); + #else + // r2 is reserved for use as system thread ID by the Power 32-bit ABI. + register uintptr_t tp __asm__ ("r2"); + __asm__ ("" : "=r" (tp)); + tid = tp; + #endif +#elif defined(__s390__) && defined(__GNUC__) + // Both GCC and Clang have supported __builtin_thread_pointer + // for s390 from long time ago. + tid = (uintptr_t)__builtin_thread_pointer(); +#else + # error "define _Py_ThreadId for this platform" +#endif + return tid; +} + +static inline Py_ALWAYS_INLINE int +_Py_IsOwnedByCurrentThread(PyObject *ob) +{ + return ob->ob_tid == _Py_ThreadId(); +} +#endif static inline Py_ssize_t Py_REFCNT(PyObject *ob) { +#if !defined(Py_GIL_DISABLED) return ob->ob_refcnt; +#else + uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local); + if (local == _Py_IMMORTAL_REFCNT_LOCAL) { + return _Py_IMMORTAL_REFCNT; + } + Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared); + return _Py_STATIC_CAST(Py_ssize_t, local) + + Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT); +#endif } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 # define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob)) @@ -216,10 +338,12 @@ static inline Py_ssize_t Py_SIZE(PyObject *ob) { static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op) { -#if SIZEOF_VOID_P > 4 - return _Py_CAST(PY_INT32_T, op->ob_refcnt) < 0; +#if defined(Py_GIL_DISABLED) + return (op->ob_ref_local == _Py_IMMORTAL_REFCNT_LOCAL); +#elif SIZEOF_VOID_P > 4 + return (_Py_CAST(PY_INT32_T, op->ob_refcnt) < 0); #else - return op->ob_refcnt == _Py_IMMORTAL_REFCNT; + return (op->ob_refcnt == _Py_IMMORTAL_REFCNT); #endif } #define _Py_IsImmortal(op) _Py_IsImmortal(_PyObject_CAST(op)) @@ -232,7 +356,15 @@ static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { #endif +// Py_SET_REFCNT() implementation for stable ABI +PyAPI_FUNC(void) _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt); + static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { +#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030d0000 + // Stable ABI implements Py_SET_REFCNT() as a function call + // on limited C API version 3.13 and newer. + _Py_SetRefcnt(ob, refcnt); +#else // This immortal check is for code that is unaware of immortal objects. // The runtime tracks these objects and we should avoid as much // as possible having extensions inadvertently change the refcnt @@ -240,7 +372,33 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { if (_Py_IsImmortal(ob)) { return; } + +#ifndef Py_GIL_DISABLED ob->ob_refcnt = refcnt; +#else + if (_Py_IsOwnedByCurrentThread(ob)) { + if ((size_t)refcnt > (size_t)UINT32_MAX) { + // On overflow, make the object immortal + ob->ob_tid = _Py_UNOWNED_TID; + ob->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL; + ob->ob_ref_shared = 0; + } + else { + // Set local refcount to desired refcount and shared refcount + // to zero, but preserve the shared refcount flags. + ob->ob_ref_local = _Py_STATIC_CAST(uint32_t, refcnt); + ob->ob_ref_shared &= _Py_REF_SHARED_FLAG_MASK; + } + } + else { + // Set local refcount to zero and shared refcount to desired refcount. + // Mark the object as merged. + ob->ob_tid = _Py_UNOWNED_TID; + ob->ob_ref_local = 0; + ob->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED); + } +#endif // Py_GIL_DISABLED +#endif // Py_LIMITED_API+0 < 0x030d0000 } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 # define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt)) @@ -618,11 +776,26 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op) #else // Non-limited C API and limited C API for Python 3.9 and older access // directly PyObject.ob_refcnt. -#if SIZEOF_VOID_P > 4 +#if defined(Py_GIL_DISABLED) + uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local); + uint32_t new_local = local + 1; + if (new_local == 0) { + // local is equal to _Py_IMMORTAL_REFCNT: do nothing + return; + } + if (_Py_IsOwnedByCurrentThread(op)) { + _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, new_local); + } + else { + _Py_atomic_add_ssize(&op->ob_ref_shared, (1 << _Py_REF_SHARED_SHIFT)); + } +#elif SIZEOF_VOID_P > 4 // Portable saturated add, branching on the carry flag and set low bits PY_UINT32_T cur_refcnt = op->ob_refcnt_split[PY_BIG_ENDIAN]; PY_UINT32_T new_refcnt = cur_refcnt + 1; if (new_refcnt == 0) { + // cur_refcnt is equal to _Py_IMMORTAL_REFCNT: the object is immortal, + // do nothing return; } op->ob_refcnt_split[PY_BIG_ENDIAN] = new_refcnt; @@ -643,6 +816,19 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op) # define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op)) #endif + +#if !defined(Py_LIMITED_API) && defined(Py_GIL_DISABLED) +// Implements Py_DECREF on objects not owned by the current thread. +PyAPI_FUNC(void) _Py_DecRefShared(PyObject *); +PyAPI_FUNC(void) _Py_DecRefSharedDebug(PyObject *, const char *, int); + +// Called from Py_DECREF by the owning thread when the local refcount reaches +// zero. The call will deallocate the object if the shared refcount is also +// zero. Otherwise, the thread gives up ownership and merges the reference +// count fields. +PyAPI_FUNC(void) _Py_MergeZeroLocalRefcount(PyObject *); +#endif + #if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) // Stable ABI implements Py_DECREF() as a function call on limited C API // version 3.12 and newer, and on Python built in debug mode. _Py_DecRef() was @@ -657,6 +843,52 @@ static inline void Py_DECREF(PyObject *op) { } #define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) +#elif defined(Py_GIL_DISABLED) && defined(Py_REF_DEBUG) +static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) +{ + uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local); + if (local == _Py_IMMORTAL_REFCNT_LOCAL) { + return; + } + _Py_DECREF_STAT_INC(); + _Py_DECREF_DecRefTotal(); + if (_Py_IsOwnedByCurrentThread(op)) { + if (local == 0) { + _Py_NegativeRefcount(filename, lineno, op); + } + local--; + _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, local); + if (local == 0) { + _Py_MergeZeroLocalRefcount(op); + } + } + else { + _Py_DecRefSharedDebug(op, filename, lineno); + } +} +#define Py_DECREF(op) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) + +#elif defined(Py_GIL_DISABLED) +static inline void Py_DECREF(PyObject *op) +{ + uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local); + if (local == _Py_IMMORTAL_REFCNT_LOCAL) { + return; + } + _Py_DECREF_STAT_INC(); + if (_Py_IsOwnedByCurrentThread(op)) { + local--; + _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, local); + if (local == 0) { + _Py_MergeZeroLocalRefcount(op); + } + } + else { + _Py_DecRefShared(op); + } +} +#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) + #elif defined(Py_REF_DEBUG) static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) { diff --git a/Include/objimpl.h b/Include/objimpl.h index 967e2776767756..ff5fa7a8c1d3d8 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -35,7 +35,7 @@ Functions and macros for modules that implement new object types. fields, this also fills in the ob_size field. - PyObject_Free(op) releases the memory allocated for an object. It does not - run a destructor -- it only frees the memory. PyObject_Free is identical. + run a destructor -- it only frees the memory. - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't allocate memory. Instead of a 'type' parameter, they take a pointer to a diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index ba25bd459c1bcd..e2e27ca00fd47b 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -1,4 +1,4 @@ -// This file is generated by Tools/cases_generator/generate_cases.py +// This file is generated by Tools/cases_generator/opcode_id_generator.py // from: // Python/bytecodes.c // Do not edit! @@ -55,7 +55,6 @@ extern "C" { #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 @@ -200,7 +199,6 @@ extern "C" { #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 @@ -233,6 +231,9 @@ extern "C" { #define SETUP_WITH 266 #define STORE_FAST_MAYBE_NULL 267 +#define HAVE_ARGUMENT 45 +#define MIN_INSTRUMENTED_OPCODE 236 + #ifdef __cplusplus } #endif diff --git a/Include/patchlevel.h b/Include/patchlevel.h index ae9d36c12d6eaf..fad79ecfda7b28 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 2 /* Version as a string */ -#define PY_VERSION "3.13.0a0" +#define PY_VERSION "3.13.0a2+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/pyhash.h b/Include/pyhash.h index 6e969f86fa2625..3e23e2758808d7 100644 --- a/Include/pyhash.h +++ b/Include/pyhash.h @@ -4,19 +4,6 @@ extern "C" { #endif -#ifndef Py_LIMITED_API -/* hash function definition */ -typedef struct { - Py_hash_t (*const hash)(const void *, Py_ssize_t); - const char *name; - const int hash_bits; - const int seed_bits; -} PyHash_FuncDef; - -PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); -#endif - - /* Cutoff for small string DJBX33A optimization in range [1, cutoff). * * About 50% of the strings in a typical Python application are smaller than @@ -60,6 +47,12 @@ PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); # endif /* uint64_t && uint32_t && aligned */ #endif /* Py_HASH_ALGORITHM */ +#ifndef Py_LIMITED_API +# define Py_CPYTHON_HASH_H +# include "cpython/pyhash.h" +# undef Py_CPYTHON_HASH_H +#endif + #ifdef __cplusplus } #endif 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 806e41955efd7f..615abe103ca038 100644 --- a/Include/pymacconfig.h +++ b/Include/pymacconfig.h @@ -7,7 +7,9 @@ #define PY_MACCONFIG_H #ifdef __APPLE__ +#undef ALIGNOF_MAX_ALIGN_T #undef SIZEOF_LONG +#undef SIZEOF_LONG_DOUBLE #undef SIZEOF_PTHREAD_T #undef SIZEOF_SIZE_T #undef SIZEOF_TIME_T @@ -20,6 +22,7 @@ #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 #undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #undef HAVE_GCC_ASM_FOR_X87 +#undef HAVE_GCC_ASM_FOR_X64 #undef VA_LIST_IS_ARRAY #if defined(__LP64__) && defined(__x86_64__) @@ -74,8 +77,14 @@ # define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif -#ifdef __i386__ +#if defined(__i386__) || defined(__x86_64__) # define HAVE_GCC_ASM_FOR_X87 +# define ALIGNOF_MAX_ALIGN_T 16 +# define HAVE_GCC_ASM_FOR_X64 1 +# define SIZEOF_LONG_DOUBLE 16 +#else +# define ALIGNOF_MAX_ALIGN_T 8 +# define SIZEOF_LONG_DOUBLE 8 #endif #endif // __APPLE__ diff --git a/Include/pymem.h b/Include/pymem.h index 68e33f90b7b913..a80da99e1dd7fc 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -87,6 +87,17 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); #define PyMem_DEL(p) PyMem_Free((p)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 +// Memory allocator which doesn't require the GIL to be held. +// Usually, it's just a thin wrapper to functions of the standard C library: +// malloc(), calloc(), realloc() and free(). The difference is that +// tracemalloc can track these memory allocations. +PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +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); +#endif + #ifndef Py_LIMITED_API # define Py_CPYTHON_PYMEM_H # include "cpython/pymem.h" diff --git a/Include/pyport.h b/Include/pyport.h index 40d580a870fc75..328471085f959d 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -48,10 +48,6 @@ # define Py_BUILD_CORE #endif -#if defined(Py_LIMITED_API) && defined(Py_BUILD_CORE) -# error "Py_LIMITED_API is not compatible with Py_BUILD_CORE" -#endif - /************************************************************************** Symbols and macros to supply platform-independent interfaces to basic @@ -361,6 +357,15 @@ extern "C" { #include "exports.h" +#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 */ #ifndef INT_MAX @@ -465,6 +470,14 @@ extern "C" { # define WITH_THREAD #endif +/* Some WebAssembly platforms do not provide a working pthread implementation. + * Thread support is stubbed and any attempt to create a new thread fails. + */ +#if (!defined(HAVE_PTHREAD_STUBS) && \ + (!defined(__EMSCRIPTEN__) || defined(__EMSCRIPTEN_PTHREADS__))) +# define Py_CAN_START_THREADS 1 +#endif + #ifdef WITH_THREAD # ifdef Py_BUILD_CORE # ifdef HAVE_THREAD_LOCAL @@ -573,6 +586,14 @@ extern "C" { # define ALIGNOF_MAX_ALIGN_T _Alignof(long double) #endif +#ifndef PY_CXX_CONST +# ifdef __cplusplus +# define PY_CXX_CONST const +# else +# define PY_CXX_CONST +# endif +#endif + #if defined(__sgi) && !defined(_SGI_MP_SOURCE) # define _SGI_MP_SOURCE #endif 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/pythread.h b/Include/pythread.h index 63714437c496b7..a3216c51d66165 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -21,7 +21,8 @@ PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); #if (defined(__APPLE__) || defined(__linux__) || defined(_WIN32) \ - || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ + || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \ + || defined(__OpenBSD__) || defined(__NetBSD__) \ || defined(__DragonFly__) || defined(_AIX)) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); @@ -33,42 +34,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/sysmodule.h b/Include/sysmodule.h index 225e0602d191e1..7b14f72ee2e494 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -1,6 +1,3 @@ - -/* System module interface */ - #ifndef Py_SYSMODULE_H #define Py_SYSMODULE_H #ifdef __cplusplus @@ -21,17 +18,15 @@ Py_DEPRECATED(3.13) PyAPI_FUNC(void) PySys_ResetWarnOptions(void); PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); -#if !defined(Py_LIMITED_API) -typedef struct { - FILE* perf_map; - PyThread_type_lock map_lock; -} PerfMapState; - -PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void); - -PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(const void *code_addr, unsigned int code_size, const char *entry_name); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000 +PyAPI_FUNC(int) PySys_Audit( + const char *event, + const char *argFormat, + ...); -PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void); +PyAPI_FUNC(int) PySys_AuditTuple( + const char *event, + PyObject *args); #endif #ifndef Py_LIMITED_API diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index f00277787122aa..dee00715b3c51d 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -957,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/_pydatetime.py b/Lib/_pydatetime.py index 88275481e7002b..bca2acf1fc88cf 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -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): 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 1f54309c8450d8..f7888d18859ae4 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1270,13 +1270,15 @@ def visit_JoinedStr(self, node): 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) @@ -1299,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..a8870b636d1df5 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -305,7 +305,7 @@ def _wakeup(self): self._waiters = None for waiter in waiters: if not waiter.done(): - waiter.set_result(waiter) + waiter.set_result(None) def _start_serving(self): if self._serving: @@ -377,7 +377,27 @@ async def serve_forever(self): self._serving_forever_fut = None async def wait_closed(self): - if self._waiters is None or self._active_count == 0: + """Wait until server is closed and all connections are dropped. + + - If the server is not closed, wait. + - If it is closed, but there are still active connections, wait. + + Anyone waiting here will be unblocked once both conditions + (server is closed and all connections have been dropped) + have become true, in either order. + + Historical note: In 3.11 and before, this was broken, returning + immediately if the server was already closed, even if there + were still active connections. An attempted fix in 3.12.0 was + still broken, returning immediately if the server was still + open and there were no active connections. Hopefully in 3.12.1 + we have it right. + """ + # Waiters are unblocked by self._wakeup(), which is called + # from two places: self.close() and self._detach(), but only + # when both conditions have become true. To signal that this + # has happened, self._wakeup() sets self._waiters to None. + if self._waiters is None: return waiter = self._loop.create_future() self._waiters.append(waiter) @@ -400,6 +420,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 +623,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) + events._set_running_loop(self) + + def _run_forever_cleanup(self): + """Clean up after an event loop finishes the looping over 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 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. @@ -1451,6 +1496,7 @@ async def create_server( ssl=None, reuse_address=None, reuse_port=None, + keep_alive=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True): @@ -1524,6 +1570,9 @@ async def create_server( socket.SOL_SOCKET, socket.SO_REUSEADDR, True) if reuse_port: _set_reuseport(sock) + if keep_alive: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_KEEPALIVE, True) # Disable IPv4/IPv6 dual stack support (enabled by # default on Linux) which makes a single socket # listen on both address families. @@ -1907,8 +1956,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/events.py b/Lib/asyncio/events.py index 0ccf85105e6673..ebc3836bdc0c4d 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -316,6 +316,7 @@ async def create_server( *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, + keep_alive=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True): @@ -354,6 +355,9 @@ async def create_server( they all set this flag when being created. This option is not supported on Windows. + keep_alive set to True keeps connections active by enabling the + periodic transmission of messages. + ssl_handshake_timeout is the time in seconds that an SSL server will wait for completion of the SSL handshake before aborting the connection. Default is 60s. diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index d521b4e2e255a9..dcd5e0aa345029 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -261,15 +261,11 @@ def _ensure_fd_no_transport(self, fd): except (AttributeError, TypeError, ValueError): # This code matches selectors._fileobj_to_fd function. raise ValueError(f"Invalid file object: {fd!r}") from None - try: - transport = self._transports[fileno] - except KeyError: - pass - else: - if not transport.is_closing(): - raise RuntimeError( - f'File descriptor {fd!r} is used by transport ' - f'{transport!r}') + transport = self._transports.get(fileno) + if transport and not transport.is_closing(): + raise RuntimeError( + f'File descriptor {fd!r} is used by transport ' + f'{transport!r}') def _add_reader(self, fd, callback, *args): self._check_closed() diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index bc84e53b8443cf..ffb48b9cd6cb70 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -245,7 +245,19 @@ def connection_made(self, transport): res = self._client_connected_cb(reader, self._stream_writer) if coroutines.iscoroutine(res): + def callback(task): + exc = task.exception() + if exc is not None: + self._loop.call_exception_handler({ + 'message': 'Unhandled exception in client_connected_cb', + 'exception': exc, + 'transport': transport, + }) + transport.close() + self._task = self._loop.create_task(res) + self._task.add_done_callback(callback) + self._strong_reader = None def connection_lost(self, exc): @@ -394,9 +406,11 @@ async def start_tls(self, sslcontext, *, def __del__(self, warnings=warnings): if not self._transport.is_closing(): - self.close() - warnings.warn(f"unclosed {self!r}", ResourceWarning) - + if self._loop.is_closed(): + warnings.warn("loop is closed", ResourceWarning) + else: + self.close() + warnings.warn(f"unclosed {self!r}", ResourceWarning) class StreamReader: diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 24238c4f5f998d..cb9c1ce4d7d1d2 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -54,16 +54,14 @@ def __repr__(self): async def __aenter__(self): if self._entered: raise RuntimeError( - f"TaskGroup {self!r} has been already entered") - self._entered = True - + f"TaskGroup {self!r} has already been entered") if self._loop is None: self._loop = events.get_running_loop() - self._parent_task = tasks.current_task(self._loop) if self._parent_task is None: raise RuntimeError( f'TaskGroup {self!r} cannot determine the parent task') + self._entered = True return self @@ -160,10 +158,10 @@ def create_task(self, coro, *, name=None, context=None): if self._aborting: raise RuntimeError(f"TaskGroup {self!r} is shutting down") if context is None: - task = self._loop.create_task(coro) + task = self._loop.create_task(coro, name=name) else: - task = self._loop.create_task(coro, context=context) - task.set_name(name) + task = self._loop.create_task(coro, name=name, context=context) + # optimization: Immediately call the done callback if the task is # already done (e.g. if the coro was able to complete eagerly), # and skip scheduling a done callback diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 72f4cc07173f0a..fafee3e738f6aa 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -404,11 +404,10 @@ def create_task(coro, *, name=None, context=None): loop = events.get_running_loop() if context is None: # Use legacy API if context is not needed - task = loop.create_task(coro) + task = loop.create_task(coro, name=name) else: - task = loop.create_task(coro, context=context) + task = loop.create_task(coro, name=name, context=context) - task.set_name(name) return task @@ -424,8 +423,6 @@ async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED): The fs iterable must not be empty. - Coroutines will be wrapped in Tasks. - Returns two sets of Future: (done, pending). Usage: diff --git a/Lib/asyncio/timeouts.py b/Lib/asyncio/timeouts.py index 029c468739bf2d..30042abb3ad804 100644 --- a/Lib/asyncio/timeouts.py +++ b/Lib/asyncio/timeouts.py @@ -49,8 +49,9 @@ def when(self) -> Optional[float]: def reschedule(self, when: Optional[float]) -> None: """Reschedule the timeout.""" - assert self._state is not _State.CREATED if self._state is not _State.ENTERED: + if self._state is _State.CREATED: + raise RuntimeError("Timeout has not been entered") raise RuntimeError( f"Cannot change state of {self._state.value} Timeout", ) @@ -82,11 +83,14 @@ def __repr__(self) -> str: return f"" async def __aenter__(self) -> "Timeout": + if self._state is not _State.CREATED: + raise RuntimeError("Timeout has already been entered") + task = tasks.current_task() + if task is None: + raise RuntimeError("Timeout should be used inside a task") self._state = _State.ENTERED - self._task = tasks.current_task() + self._task = task self._cancelling = self._task.cancelling() - if self._task is None: - raise RuntimeError("Timeout should be used inside a task") self.reschedule(self._when) return self diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 28cef964debd36..41ccf1b78fb93b 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -32,6 +32,7 @@ 'FastChildWatcher', 'PidfdChildWatcher', 'MultiLoopChildWatcher', 'ThreadedChildWatcher', 'DefaultEventLoopPolicy', + 'EventLoop', ) @@ -63,6 +64,7 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): def __init__(self, selector=None): super().__init__(selector) self._signal_handlers = {} + self._unix_server_sockets = {} def close(self): super().close() @@ -283,7 +285,7 @@ async def create_unix_server( sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, - start_serving=True): + start_serving=True, cleanup_socket=True): if isinstance(ssl, bool): raise TypeError('ssl argument must be an SSLContext or None') @@ -339,6 +341,15 @@ async def create_unix_server( raise ValueError( f'A UNIX Domain Stream Socket was expected, got {sock!r}') + if cleanup_socket: + path = sock.getsockname() + # Check for abstract socket. `str` and `bytes` paths are supported. + if path[0] not in (0, '\x00'): + try: + self._unix_server_sockets[sock] = os.stat(path).st_ino + except FileNotFoundError: + pass + sock.setblocking(False) server = base_events.Server(self, [sock], protocol_factory, ssl, backlog, ssl_handshake_timeout, @@ -459,6 +470,27 @@ def cb(fut): self.remove_writer(fd) fut.add_done_callback(cb) + def _stop_serving(self, sock): + # Is this a unix socket that needs cleanup? + if sock in self._unix_server_sockets: + path = sock.getsockname() + else: + path = None + + super()._stop_serving(sock) + + if path is not None: + prev_ino = self._unix_server_sockets[sock] + del self._unix_server_sockets[sock] + try: + if os.stat(path).st_ino == prev_ino: + os.unlink(path) + except FileNotFoundError: + pass + except OSError as err: + logger.error('Unable to clean up listening UNIX socket ' + '%r: %r', path, err) + class _UnixReadPipeTransport(transports.ReadTransport): @@ -1370,14 +1402,7 @@ def is_active(self): return True def close(self): - self._join_threads() - - def _join_threads(self): - """Internal: Join all non-daemon threads""" - threads = [thread for thread in list(self._threads.values()) - if thread.is_alive() and not thread.daemon] - for thread in threads: - thread.join() + pass def __enter__(self): return self @@ -1396,7 +1421,7 @@ def __del__(self, _warn=warnings.warn): def add_child_handler(self, pid, callback, *args): loop = events.get_running_loop() thread = threading.Thread(target=self._do_waitpid, - name=f"waitpid-{next(self._pid_counter)}", + name=f"asyncio-waitpid-{next(self._pid_counter)}", args=(loop, pid, callback, args), daemon=True) self._threads[pid] = thread @@ -1464,8 +1489,6 @@ def _init_watcher(self): self._watcher = PidfdChildWatcher() else: self._watcher = ThreadedChildWatcher() - if threading.current_thread() is threading.main_thread(): - self._watcher.attach_loop(self._local._loop) def set_event_loop(self, loop): """Set the event loop. @@ -1510,3 +1533,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/base64.py b/Lib/base64.py index e233647ee76639..e3e983b3064fe7 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -164,7 +164,6 @@ def urlsafe_b64decode(s): _b32rev = {} def _b32encode(alphabet, s): - global _b32tab2 # Delay the initialization of the table to not waste memory # if the function is never called if alphabet not in _b32tab2: @@ -200,7 +199,6 @@ def _b32encode(alphabet, s): return bytes(encoded) def _b32decode(alphabet, s, casefold=False, map01=None): - global _b32rev # Delay the initialization of the table to not waste memory # if the function is never called if alphabet not in _b32rev: diff --git a/Lib/bdb.py b/Lib/bdb.py index 0f3eec653baaad..1acf7957f0d669 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -32,6 +32,7 @@ def __init__(self, skip=None): self.skip = set(skip) if skip else None self.breaks = {} self.fncache = {} + self.frame_trace_lines = {} self.frame_returning = None self._load_breaks() @@ -331,6 +332,9 @@ def set_trace(self, frame=None): while frame: frame.f_trace = self.trace_dispatch self.botframe = frame + # We need f_trace_liens == True for the debugger to work + self.frame_trace_lines[frame] = frame.f_trace_lines + frame.f_trace_lines = True frame = frame.f_back self.set_step() sys.settrace(self.trace_dispatch) @@ -349,6 +353,9 @@ def set_continue(self): while frame and frame is not self.botframe: del frame.f_trace frame = frame.f_back + for frame, prev_trace_lines in self.frame_trace_lines.items(): + frame.f_trace_lines = prev_trace_lines + self.frame_trace_lines = {} def set_quit(self): """Set quitting attribute to True. diff --git a/Lib/calendar.py b/Lib/calendar.py index 2a4deb70a0111f..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': diff --git a/Lib/cmd.py b/Lib/cmd.py index 88ee7d3ddc4694..2e358d6cd5a02d 100644 --- a/Lib/cmd.py +++ b/Lib/cmd.py @@ -108,7 +108,15 @@ def cmdloop(self, intro=None): import readline self.old_completer = readline.get_completer() readline.set_completer(self.complete) - readline.parse_and_bind(self.completekey+": complete") + if readline.backend == "editline": + if self.completekey == 'tab': + # libedit uses "^I" instead of "tab" + command_string = "bind ^I rl_complete" + else: + command_string = f"bind {self.completekey} rl_complete" + else: + command_string = f"{self.completekey}: complete" + readline.parse_and_bind(command_string) except ImportError: pass try: @@ -210,9 +218,8 @@ def onecmd(self, line): if cmd == '': return self.default(line) else: - try: - func = getattr(self, 'do_' + cmd) - except AttributeError: + func = getattr(self, 'do_' + cmd, None) + if func is None: return self.default(line) return func(arg) diff --git a/Lib/code.py b/Lib/code.py index 2bd5fa3e795a61..f4aecddeca7813 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -5,6 +5,7 @@ # Inspired by similar code by Jeff Epler and Fredrik Lundh. +import builtins import sys import traceback from codeop import CommandCompiler, compile_command @@ -169,7 +170,7 @@ class InteractiveConsole(InteractiveInterpreter): """ - def __init__(self, locals=None, filename=""): + def __init__(self, locals=None, filename="", local_exit=False): """Constructor. The optional locals argument will be passed to the @@ -181,6 +182,7 @@ def __init__(self, locals=None, filename=""): """ InteractiveInterpreter.__init__(self, locals) self.filename = filename + self.local_exit = local_exit self.resetbuffer() def resetbuffer(self): @@ -219,27 +221,64 @@ def interact(self, banner=None, exitmsg=None): elif banner: self.write("%s\n" % str(banner)) more = 0 - while 1: - try: - if more: - prompt = sys.ps2 - else: - prompt = sys.ps1 + + # When the user uses exit() or quit() in their interactive shell + # they probably just want to exit the created shell, not the whole + # process. exit and quit in builtins closes sys.stdin which makes + # it super difficult to restore + # + # When self.local_exit is True, we overwrite the builtins so + # exit() and quit() only raises SystemExit and we can catch that + # to only exit the interactive shell + + _exit = None + _quit = None + + if self.local_exit: + if hasattr(builtins, "exit"): + _exit = builtins.exit + builtins.exit = Quitter("exit") + + if hasattr(builtins, "quit"): + _quit = builtins.quit + builtins.quit = Quitter("quit") + + try: + while True: try: - line = self.raw_input(prompt) - except EOFError: - self.write("\n") - break - else: - more = self.push(line) - except KeyboardInterrupt: - self.write("\nKeyboardInterrupt\n") - self.resetbuffer() - more = 0 - if exitmsg is None: - self.write('now exiting %s...\n' % self.__class__.__name__) - elif exitmsg != '': - self.write('%s\n' % exitmsg) + if more: + prompt = sys.ps2 + else: + prompt = sys.ps1 + try: + line = self.raw_input(prompt) + except EOFError: + self.write("\n") + break + else: + more = self.push(line) + except KeyboardInterrupt: + self.write("\nKeyboardInterrupt\n") + self.resetbuffer() + more = 0 + except SystemExit as e: + if self.local_exit: + self.write("\n") + break + else: + raise e + finally: + # restore exit and quit in builtins if they were modified + if _exit is not None: + builtins.exit = _exit + + if _quit is not None: + builtins.quit = _quit + + if exitmsg is None: + self.write('now exiting %s...\n' % self.__class__.__name__) + elif exitmsg != '': + self.write('%s\n' % exitmsg) def push(self, line): """Push a line to the interpreter. @@ -276,8 +315,22 @@ def raw_input(self, prompt=""): return input(prompt) +class Quitter: + def __init__(self, name): + self.name = name + if sys.platform == "win32": + self.eof = 'Ctrl-Z plus Return' + else: + self.eof = 'Ctrl-D (i.e. EOF)' + + def __repr__(self): + return f'Use {self.name} or {self.eof} to exit' + + def __call__(self, code=None): + raise SystemExit(code) + -def interact(banner=None, readfunc=None, local=None, exitmsg=None): +def interact(banner=None, readfunc=None, local=None, exitmsg=None, local_exit=False): """Closely emulate the interactive Python interpreter. This is a backwards compatible interface to the InteractiveConsole @@ -290,9 +343,10 @@ def interact(banner=None, readfunc=None, local=None, exitmsg=None): readfunc -- if not None, replaces InteractiveConsole.raw_input() local -- passed to InteractiveInterpreter.__init__() exitmsg -- passed to InteractiveConsole.interact() + local_exit -- passed to InteractiveConsole.__init__() """ - console = InteractiveConsole(local) + console = InteractiveConsole(local, local_exit=local_exit) if readfunc is not None: console.raw_input = readfunc else: diff --git a/Lib/codecs.py b/Lib/codecs.py index 82f23983e719c2..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. diff --git a/Lib/codeop.py b/Lib/codeop.py index a574aa4b70f1a8..91146be2c438e2 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -70,10 +70,14 @@ def _maybe_compile(compiler, source, filename, symbol): return None # fallthrough - return compiler(source, filename, symbol) + return compiler(source, filename, symbol, incomplete_input=False) -def _compile(source, filename, symbol): - return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT) +def _compile(source, filename, symbol, incomplete_input=True): + flags = 0 + if incomplete_input: + flags |= PyCF_ALLOW_INCOMPLETE_INPUT + flags |= PyCF_DONT_IMPLY_DEDENT + return compile(source, filename, symbol, flags) def compile_command(source, filename="", symbol="single"): r"""Compile a command and determine whether it is incomplete. @@ -104,8 +108,12 @@ class Compile: def __init__(self): self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT - def __call__(self, source, filename, symbol): - codeob = compile(source, filename, symbol, self.flags, True) + def __call__(self, source, filename, symbol, **kwargs): + flags = self.flags + if kwargs.get('incomplete_input', True) is False: + flags &= ~PyCF_DONT_IMPLY_DEDENT + flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT + codeob = compile(source, filename, symbol, flags, True) for feature in _features: if codeob.co_flags & feature.compiler_flag: self.flags |= feature.compiler_flag diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index a461550ea40da7..2e527dfd810c43 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -457,7 +457,7 @@ def _make(cls, iterable): def _replace(self, /, **kwds): result = self._make(_map(kwds.pop, field_names, self)) if kwds: - raise ValueError(f'Got unexpected field names: {list(kwds)!r}') + raise TypeError(f'Got unexpected field names: {list(kwds)!r}') return result _replace.__doc__ = (f'Return a new {typename} object replacing specified ' diff --git a/Lib/compileall.py b/Lib/compileall.py index d394156cedc4e7..9b53086bf41380 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -172,13 +172,13 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, if stripdir is not None: fullname_parts = fullname.split(os.path.sep) stripdir_parts = stripdir.split(os.path.sep) - ddir_parts = list(fullname_parts) - for spart, opart in zip(stripdir_parts, fullname_parts): - if spart == opart: - ddir_parts.remove(spart) - - dfile = os.path.join(*ddir_parts) + if stripdir_parts != fullname_parts[:len(stripdir_parts)]: + if quiet < 2: + print("The stripdir path {!r} is not a valid prefix for " + "source path {!r}; ignoring".format(stripdir, fullname)) + else: + dfile = os.path.join(*fullname_parts[len(stripdir_parts):]) if prependdir is not None: if dfile is None: diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 73bdcbe8693991..ffaffdb8b3d0aa 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -341,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() @@ -425,8 +432,8 @@ 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 @@ -463,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. @@ -490,7 +497,7 @@ def terminate_broken(self, cause): for work_id, work_item in self.pending_work_items.items(): try: work_item.future.set_exception(bpe) - except _base.InvalidStateError as exc: + 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 @@ -505,17 +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() - - # gh-107219: Close the connection writer which can unblock - # Queue._feed() if it was stuck in send_bytes(). - if sys.platform == 'win32': - self.call_queue._writer.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 @@ -558,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): @@ -653,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) 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 f82e7bca35735b..5b646fabca0225 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): @@ -449,7 +461,7 @@ def __exit__(self, exctype, excinst, exctb): return if issubclass(exctype, self._exceptions): return True - if issubclass(exctype, ExceptionGroup): + if issubclass(exctype, BaseExceptionGroup): match, rest = excinst.split(self._exceptions) if rest is None: return True diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 84f8d68ce092a4..2fba32b5ffbc1e 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -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') @@ -1567,15 +1573,15 @@ def _replace(obj, /, **changes): 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 7e4792e8a8dc62..183091cb0d6098 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -30,6 +30,7 @@ SET_FUNCTION_ATTRIBUTE = opmap['SET_FUNCTION_ATTRIBUTE'] FUNCTION_ATTR_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure') +ENTER_EXECUTOR = opmap['ENTER_EXECUTOR'] LOAD_CONST = opmap['LOAD_CONST'] RETURN_CONST = opmap['RETURN_CONST'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] @@ -72,7 +73,8 @@ def _try_compile(source, name): pass return compile(source, name, 'exec') -def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): +def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False, + show_offsets=False): """Disassemble classes, methods, functions, and other compiled objects. With no argument, disassemble the last traceback. @@ -82,7 +84,8 @@ def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): in a special attribute. """ if x is None: - distb(file=file, show_caches=show_caches, adaptive=adaptive) + distb(file=file, show_caches=show_caches, adaptive=adaptive, + show_offsets=show_offsets) return # Extract functions from methods. if hasattr(x, '__func__'): @@ -103,21 +106,21 @@ def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): if isinstance(x1, _have_code): print("Disassembly of %s:" % name, file=file) try: - dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) + dis(x1, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) except TypeError as msg: print("Sorry:", msg, file=file) print(file=file) elif hasattr(x, 'co_code'): # Code object - _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) + _disassemble_recursive(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) elif isinstance(x, (bytes, bytearray)): # Raw bytecode - _disassemble_bytes(x, file=file, show_caches=show_caches) + _disassemble_bytes(x, file=file, show_caches=show_caches, show_offsets=show_offsets) elif isinstance(x, str): # Source code - _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive) + _disassemble_str(x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__) -def distb(tb=None, *, file=None, show_caches=False, adaptive=False): +def distb(tb=None, *, file=None, show_caches=False, adaptive=False, show_offsets=False): """Disassemble a traceback (default: last traceback).""" if tb is None: try: @@ -128,7 +131,7 @@ def distb(tb=None, *, file=None, show_caches=False, adaptive=False): except AttributeError: raise RuntimeError("no last traceback to disassemble") from None while tb.tb_next: tb = tb.tb_next - disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive) + disassemble(tb.tb_frame.f_code, tb.tb_lasti, file=file, show_caches=show_caches, adaptive=adaptive, show_offsets=show_offsets) # The inspect module interrogates this dictionary to build its # list of CO_* constants. It is also used by pretty_flags to @@ -263,10 +266,11 @@ def show_code(co, *, file=None): 'start_offset', 'starts_line', 'line_number', - 'is_jump_target', - 'positions' + 'label', + 'positions', + 'cache_info', ], - defaults=[None] + defaults=[None, None, None] ) _Instruction.opname.__doc__ = "Human readable name for operation" @@ -281,12 +285,16 @@ def show_code(co, *, file=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.label.__doc__ = "A label (int > 0) if this instruction is a jump target, otherwise None" _Instruction.positions.__doc__ = "dis.Positions object holding the span of source code covered by this instruction" +_Instruction.cache_info.__doc__ = "list of (name, size, data), one for each cache entry of the instruction" -_ExceptionTableEntry = collections.namedtuple("_ExceptionTableEntry", +_ExceptionTableEntryBase = collections.namedtuple("_ExceptionTableEntryBase", "start end target depth lasti") +class _ExceptionTableEntry(_ExceptionTableEntryBase): + pass + _OPNAME_WIDTH = 20 _OPARG_WIDTH = 5 @@ -325,9 +333,11 @@ class Instruction(_Instruction): otherwise equal to Instruction.offset 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 + label - A label if this instruction is a jump target, otherwise None positions - Optional dis.Positions object holding the span of source code covered by this instruction + cache_info - information about the format and content of the instruction's cache + entries (if any) """ @property @@ -369,51 +379,174 @@ def jump_target(self): """ return _get_jump_target(self.opcode, self.arg, self.offset) - def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4): - """Format instruction details for inclusion in disassembly output. + @property + def is_jump_target(self): + """True if other code jumps to here, otherwise False""" + return self.label is not None + + def __str__(self): + output = io.StringIO() + formatter = Formatter(file=output) + formatter.print_instruction(self, False) + return output.getvalue() + + +class Formatter: + def __init__(self, file=None, lineno_width=0, offset_width=0, label_width=0, + line_offset=0): + """Create a Formatter + + *file* where to write the output *lineno_width* sets the width of the line number field (0 omits it) - *mark_as_current* inserts a '-->' marker arrow as part of the line *offset_width* sets the width of the instruction offset field + *label_width* sets the width of the label field + + *line_offset* the line number (within the code unit) """ + self.file = file + self.lineno_width = lineno_width + self.offset_width = offset_width + self.label_width = label_width + + + def print_instruction(self, instr, mark_as_current=False): + """Format instruction details for inclusion in disassembly output.""" + lineno_width = self.lineno_width + offset_width = self.offset_width + label_width = self.label_width + + new_source_line = (lineno_width > 0 and + instr.starts_line and + instr.offset > 0) + if new_source_line: + print(file=self.file) + fields = [] # Column: Source code line number if lineno_width: - if self.starts_line: - lineno_fmt = "%%%dd" if self.line_number is not None else "%%%ds" + if instr.starts_line: + lineno_fmt = "%%%dd" if instr.line_number is not None else "%%%ds" lineno_fmt = lineno_fmt % lineno_width - fields.append(lineno_fmt % self.line_number) + lineno = _NO_LINENO if instr.line_number is None else instr.line_number + fields.append(lineno_fmt % lineno) else: fields.append(' ' * lineno_width) + # Column: Label + if instr.label is not None: + lbl = f"L{instr.label}:" + fields.append(f"{lbl:>{label_width}}") + else: + fields.append(' ' * label_width) + # Column: Instruction offset from start of code sequence + if offset_width > 0: + fields.append(f"{repr(instr.offset):>{offset_width}} ") # Column: Current instruction indicator if mark_as_current: fields.append('-->') else: fields.append(' ') - # Column: Jump target marker - if self.is_jump_target: - fields.append('>>') - else: - fields.append(' ') - # Column: Instruction offset from start of code sequence - fields.append(repr(self.offset).rjust(offset_width)) # Column: Opcode name - fields.append(self.opname.ljust(_OPNAME_WIDTH)) + fields.append(instr.opname.ljust(_OPNAME_WIDTH)) # Column: Opcode argument - if self.arg is not None: - arg = repr(self.arg) + if instr.arg is not None: + arg = repr(instr.arg) # If opname is longer than _OPNAME_WIDTH, we allow it to overflow into # the space reserved for oparg. This results in fewer misaligned opargs # in the disassembly output. - opname_excess = max(0, len(self.opname) - _OPNAME_WIDTH) - fields.append(repr(self.arg).rjust(_OPARG_WIDTH - opname_excess)) + opname_excess = max(0, len(instr.opname) - _OPNAME_WIDTH) + fields.append(repr(instr.arg).rjust(_OPARG_WIDTH - opname_excess)) # Column: Opcode argument details - if self.argrepr: - fields.append('(' + self.argrepr + ')') - return ' '.join(fields).rstrip() + if instr.argrepr: + fields.append('(' + instr.argrepr + ')') + print(' '.join(fields).rstrip(), file=self.file) + + def print_exception_table(self, exception_entries): + file = self.file + if exception_entries: + print("ExceptionTable:", file=file) + for entry in exception_entries: + lasti = " lasti" if entry.lasti else "" + start = entry.start_label + end = entry.end_label + target = entry.target_label + print(f" L{start} to L{end} -> L{target} [{entry.depth}]{lasti}", file=file) + + +class ArgResolver: + def __init__(self, co_consts, names, varname_from_oparg, labels_map): + self.co_consts = co_consts + self.names = names + self.varname_from_oparg = varname_from_oparg + self.labels_map = labels_map + + def get_argval_argrepr(self, op, arg, offset): + get_name = None if self.names is None else self.names.__getitem__ + argval = None + argrepr = '' + deop = _deoptop(op) + if arg is not None: + # Set argval to the dereferenced value of the argument when + # available, and argrepr to the string representation of argval. + # _disassemble_bytes needs the string repr of the + # raw name index for LOAD_GLOBAL, LOAD_CONST, etc. + argval = arg + if deop in hasconst: + argval, argrepr = _get_const_info(deop, arg, self.co_consts) + elif deop in hasname: + if deop == LOAD_GLOBAL: + argval, argrepr = _get_name_info(arg//2, get_name) + if (arg & 1) and argrepr: + argrepr = f"{argrepr} + NULL" + elif deop == LOAD_ATTR: + argval, argrepr = _get_name_info(arg//2, get_name) + if (arg & 1) and 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 = f"{argrepr} + NULL|self" + else: + argval, argrepr = _get_name_info(arg, get_name) + elif deop in hasjabs: + argval = arg*2 + argrepr = f"to L{self.labels_map[argval]}" + elif deop in hasjrel: + signed_arg = -arg if _is_backward_jump(deop) else arg + argval = offset + 2 + signed_arg*2 + caches = _get_cache_size(_all_opname[deop]) + argval += 2 * caches + if deop == ENTER_EXECUTOR: + argval += 2 + argrepr = f"to L{self.labels_map[argval]}" + elif deop in (LOAD_FAST_LOAD_FAST, STORE_FAST_LOAD_FAST, STORE_FAST_STORE_FAST): + arg1 = arg >> 4 + arg2 = arg & 15 + val1, argrepr1 = _get_name_info(arg1, self.varname_from_oparg) + val2, argrepr2 = _get_name_info(arg2, self.varname_from_oparg) + argrepr = argrepr1 + ", " + argrepr2 + argval = val1, val2 + elif deop in haslocal or deop in hasfree: + argval, argrepr = _get_name_info(arg, self.varname_from_oparg) + elif deop in hascompare: + argval = cmp_op[arg >> 5] + argrepr = argval + if arg & 16: + argrepr = f"bool({argrepr})" + elif deop == CONVERT_VALUE: + argval = (None, str, repr, ascii)[arg] + argrepr = ('', 'str', 'repr', 'ascii')[arg] + elif deop == SET_FUNCTION_ATTRIBUTE: + argrepr = ', '.join(s for i, s in enumerate(FUNCTION_ATTR_FLAGS) + if arg & (1<> 4 - arg2 = arg & 15 - val1, argrepr1 = _get_name_info(arg1, varname_from_oparg) - val2, argrepr2 = _get_name_info(arg2, varname_from_oparg) - argrepr = argrepr1 + ", " + argrepr2 - argval = val1, val2 - elif deop in haslocal or deop in hasfree: - argval, argrepr = _get_name_info(arg, varname_from_oparg) - elif deop in hascompare: - argval = cmp_op[arg >> 5] - argrepr = argval - if arg & 16: - argrepr = f"bool({argrepr})" - elif deop == CONVERT_VALUE: - argval = (None, str, repr, ascii)[arg] - argrepr = ('', 'str', 'repr', 'ascii')[arg] - elif deop == SET_FUNCTION_ATTRIBUTE: - argrepr = ', '.join(s for i, s in enumerate(FUNCTION_ATTR_FLAGS) - if arg & (1< 0: if depth is not None: depth = depth - 1 @@ -654,62 +729,97 @@ def _disassemble_recursive(co, *, file=None, depth=None, show_caches=False, adap print(file=file) print("Disassembly of %r:" % (x,), file=file) _disassemble_recursive( - x, file=file, depth=depth, show_caches=show_caches, adaptive=adaptive + x, file=file, depth=depth, show_caches=show_caches, + adaptive=adaptive, show_offsets=show_offsets ) + +def _make_labels_map(original_code, exception_entries=()): + jump_targets = set(findlabels(original_code)) + labels = set(jump_targets) + for start, end, target, _, _ in exception_entries: + labels.add(start) + labels.add(end) + labels.add(target) + labels = sorted(labels) + labels_map = {offset: i+1 for (i, offset) in enumerate(sorted(labels))} + for e in exception_entries: + e.start_label = labels_map[e.start] + e.end_label = labels_map[e.end] + e.target_label = labels_map[e.target] + return labels_map + +_NO_LINENO = ' --' + +def _get_lineno_width(linestarts): + if linestarts is None: + return 0 + maxlineno = max(filter(None, linestarts.values()), default=-1) + if maxlineno == -1: + # Omit the line number column entirely if we have no line number info + return 0 + lineno_width = max(3, len(str(maxlineno))) + if lineno_width < len(_NO_LINENO) and None in linestarts.values(): + lineno_width = len(_NO_LINENO) + return lineno_width + + 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, original_code=None): - # Omit the line number column entirely if we have no line number info - 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 + co_positions=None, show_caches=False, original_code=None, + show_offsets=False): - if show_lineno: - maxlineno = max(linestarts_ints) + line_offset - if maxlineno >= 1000: - lineno_width = len(str(maxlineno)) - else: - lineno_width = 3 + offset_width = len(str(max(len(code) - 2, 9999))) if show_offsets else 0 - if lineno_width < len(str(None)) and None in linestarts.values(): - lineno_width = len(str(None)) - else: - lineno_width = 0 - maxoffset = len(code) - 2 - if maxoffset >= 10000: - offset_width = len(str(maxoffset)) - else: - offset_width = 4 - for instr in _get_instructions_bytes(code, varname_from_oparg, names, - co_consts, linestarts, - line_offset=line_offset, - exception_entries=exception_entries, - co_positions=co_positions, - show_caches=show_caches, - original_code=original_code): - new_source_line = (show_lineno and - instr.starts_line and - instr.offset > 0) - if new_source_line: - print(file=file) + labels_map = _make_labels_map(original_code or code, exception_entries) + label_width = 4 + len(str(len(labels_map))) + + formatter = Formatter(file=file, + lineno_width=_get_lineno_width(linestarts), + offset_width=offset_width, + label_width=label_width, + line_offset=line_offset) + + arg_resolver = ArgResolver(co_consts, names, varname_from_oparg, labels_map) + instrs = _get_instructions_bytes(code, linestarts=linestarts, + line_offset=line_offset, + co_positions=co_positions, + original_code=original_code, + labels_map=labels_map, + arg_resolver=arg_resolver) + + print_instructions(instrs, exception_entries, formatter, + show_caches=show_caches, lasti=lasti) + + +def print_instructions(instrs, exception_entries, formatter, show_caches=False, lasti=-1): + for instr in instrs: if show_caches: is_current_instr = instr.offset == lasti else: # Each CACHE takes 2 bytes is_current_instr = instr.offset <= lasti \ <= 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: - print("ExceptionTable:", file=file) - for entry in exception_entries: - lasti = " lasti" if entry.lasti else "" - end = entry.end-2 - print(f" {entry.start} to {end} -> {entry.target} [{entry.depth}]{lasti}", file=file) + formatter.print_instruction(instr, is_current_instr) + deop = _deoptop(instr.opcode) + if show_caches and instr.cache_info: + offset = instr.offset + for name, size, data in instr.cache_info: + for i in range(size): + offset += 2 + # Only show the fancy argrepr for a CACHE instruction when it's + # the first entry for a particular cache value: + if i == 0: + argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}" + else: + argrepr = "" + formatter.print_instruction( + Instruction("CACHE", CACHE, 0, None, argrepr, offset, offset, + False, None, None, instr.positions), + is_current_instr) + + formatter.print_exception_table(exception_entries) def _disassemble_str(source, **kwargs): """Compile the source string, then disassemble the code object.""" @@ -830,7 +940,7 @@ class Bytecode: Iterating over this yields the bytecode operations as Instruction instances. """ - def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False): + def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False, adaptive=False, show_offsets=False): self.codeobj = co = _get_code_object(x) if first_line is None: self.first_line = co.co_firstlineno @@ -844,18 +954,21 @@ def __init__(self, x, *, first_line=None, current_offset=None, show_caches=False self.exception_entries = _parse_exception_table(co) self.show_caches = show_caches self.adaptive = adaptive + self.show_offsets = show_offsets def __iter__(self): co = self.codeobj + original_code = co.co_code + labels_map = _make_labels_map(original_code, self.exception_entries) + arg_resolver = ArgResolver(co.co_consts, co.co_names, co._varname_from_oparg, + labels_map) return _get_instructions_bytes(_get_code_array(co, self.adaptive), - co._varname_from_oparg, - co.co_names, co.co_consts, - self._linestarts, + linestarts=self._linestarts, line_offset=self._line_offset, - exception_entries=self.exception_entries, co_positions=co.co_positions(), - show_caches=self.show_caches, - original_code=co.co_code) + original_code=original_code, + labels_map=labels_map, + arg_resolver=arg_resolver) def __repr__(self): return "{}({!r})".format(self.__class__.__name__, @@ -892,21 +1005,25 @@ def dis(self): exception_entries=self.exception_entries, co_positions=co.co_positions(), show_caches=self.show_caches, - original_code=co.co_code) + original_code=co.co_code, + show_offsets=self.show_offsets) 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('-O', '--show-offsets', action='store_true', + help='show instruction offsets') 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, show_offsets=args.show_offsets) if __name__ == "__main__": - _test() + main() diff --git a/Lib/doctest.py b/Lib/doctest.py index 46b4dd6769b063..d109b6c9e37343 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -591,9 +591,11 @@ def __hash__(self): def __lt__(self, other): if not isinstance(other, DocTest): return NotImplemented - return ((self.name, self.filename, self.lineno, id(self)) + self_lno = self.lineno if self.lineno is not None else -1 + other_lno = other.lineno if other.lineno is not None else -1 + return ((self.name, self.filename, self_lno, id(self)) < - (other.name, other.filename, other.lineno, id(other))) + (other.name, other.filename, other_lno, id(other))) ###################################################################### ## 3. DocTestParser @@ -1393,7 +1395,24 @@ def __run(self, test, compileflags, out): # The example raised an exception: check if it was expected. else: - exc_msg = traceback.format_exception_only(*exception[:2])[-1] + formatted_ex = traceback.format_exception_only(*exception[:2]) + if issubclass(exception[0], SyntaxError): + # SyntaxError / IndentationError is special: + # we don't care about the carets / suggestions / etc + # We only care about the error message and notes. + # They start with `SyntaxError:` (or any other class name) + exception_line_prefixes = ( + f"{exception[0].__qualname__}:", + f"{exception[0].__module__}.{exception[0].__qualname__}:", + ) + exc_msg_index = next( + index + for index, line in enumerate(formatted_ex) + if line.startswith(exception_line_prefixes) + ) + formatted_ex = formatted_ex[exc_msg_index:] + + exc_msg = "".join(formatted_ex) if not quiet: got += _exception_traceback(exception) diff --git a/Lib/email/message.py b/Lib/email/message.py index 411118c74dabb4..fe769580fed5d0 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -289,25 +289,26 @@ def get_payload(self, i=None, decode=False): # cte might be a Header, so for now stringify it. cte = str(self.get('content-transfer-encoding', '')).lower() # payload may be bytes here. - if isinstance(payload, str): - if utils._has_surrogates(payload): - bpayload = payload.encode('ascii', 'surrogateescape') - if not decode: + if not decode: + if isinstance(payload, str) and utils._has_surrogates(payload): + try: + bpayload = payload.encode('ascii', 'surrogateescape') try: payload = bpayload.decode(self.get_param('charset', 'ascii'), 'replace') except LookupError: payload = bpayload.decode('ascii', 'replace') - elif decode: - try: - bpayload = payload.encode('ascii') - except UnicodeError: - # This won't happen for RFC compliant messages (messages - # containing only ASCII code points in the unicode input). - # If it does happen, turn the string into bytes in a way - # guaranteed not to fail. - bpayload = payload.encode('raw-unicode-escape') - if not decode: + except UnicodeEncodeError: + pass return payload + if isinstance(payload, str): + try: + bpayload = payload.encode('ascii', 'surrogateescape') + except UnicodeEncodeError: + # This won't happen for RFC compliant messages (messages + # containing only ASCII code points in the unicode input). + # If it does happen, turn the string into bytes in a way + # guaranteed not to fail. + bpayload = payload.encode('raw-unicode-escape') if cte == 'quoted-printable': return quopri.decodestring(bpayload) elif cte == 'base64': diff --git a/Lib/email/utils.py b/Lib/email/utils.py index 81da5394ea1695..9175f2fdb6e69e 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 = '' @@ -49,10 +44,10 @@ escapesre = re.compile(r'[\\"]') def _has_surrogates(s): - """Return True if s contains surrogate-escaped binary data.""" + """Return True if s may contain surrogate-escaped binary data.""" # This check is based on the fact that unless there are surrogates, utf8 # (Python's default encoding) can encode any string. This is the fastest - # way to check for surrogates, see issue 11454 for timings. + # way to check for surrogates, see bpo-11454 (moved to gh-55663) for timings. try: s.encode() return False @@ -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) @@ -181,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) diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 1fb1d505cfd0c5..21e4ad99a39628 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('pip',) -_PIP_VERSION = "23.2.1" +_PIP_VERSION = "23.3.1" _PROJECTS = [ ("pip", _PIP_VERSION, "py3"), ] diff --git a/Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl deleted file mode 100644 index ba28ef02e265f0..00000000000000 Binary files a/Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-23.3.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-23.3.1-py3-none-any.whl new file mode 100644 index 00000000000000..a4faf716b663e6 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-23.3.1-py3-none-any.whl differ diff --git a/Lib/enum.py b/Lib/enum.py index f5448a1788e4d2..a8a50a58380375 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -4,7 +4,7 @@ __all__ = [ - 'EnumType', 'EnumMeta', + 'EnumType', 'EnumMeta', 'EnumDict', 'Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag', 'ReprEnum', 'auto', 'unique', 'property', 'verify', 'member', 'nonmember', 'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP', @@ -61,8 +61,8 @@ def _is_sunder(name): return ( len(name) > 2 and name[0] == name[-1] == '_' and - name[1:2] != '_' and - name[-2:-1] != '_' + name[1] != '_' and + name[-2] != '_' ) def _is_internal_class(cls_name, obj): @@ -81,7 +81,6 @@ def _is_private(cls_name, name): if ( len(name) > pat_len and name.startswith(pattern) - and name[pat_len:pat_len+1] != ['_'] and (name[-1] != '_' or name[-2] != '_') ): return True @@ -156,7 +155,6 @@ def _dedent(text): Like textwrap.dedent. Rewritten because we cannot import textwrap. """ lines = text.split('\n') - blanks = 0 for i, ch in enumerate(lines[0]): if ch != ' ': break @@ -315,45 +313,8 @@ def __set_name__(self, enum_class, member_name): ): # no other instances found, record this member in _member_names_ enum_class._member_names_.append(member_name) - # if necessary, get redirect in place and then add it to _member_map_ - found_descriptor = None - descriptor_type = None - class_type = None - for base in enum_class.__mro__[1:]: - attr = base.__dict__.get(member_name) - if attr is not None: - if isinstance(attr, (property, DynamicClassAttribute)): - found_descriptor = attr - class_type = base - descriptor_type = 'enum' - break - elif _is_descriptor(attr): - found_descriptor = attr - descriptor_type = descriptor_type or 'desc' - class_type = class_type or base - continue - else: - descriptor_type = 'attr' - class_type = base - if found_descriptor: - redirect = property() - redirect.member = enum_member - redirect.__set_name__(enum_class, member_name) - if descriptor_type in ('enum','desc'): - # earlier descriptor found; copy fget, fset, fdel to this one. - redirect.fget = getattr(found_descriptor, 'fget', None) - redirect._get = getattr(found_descriptor, '__get__', None) - redirect.fset = getattr(found_descriptor, 'fset', None) - redirect._set = getattr(found_descriptor, '__set__', None) - redirect.fdel = getattr(found_descriptor, 'fdel', None) - redirect._del = getattr(found_descriptor, '__delete__', None) - redirect._attr_type = descriptor_type - redirect._cls_type = class_type - setattr(enum_class, member_name, redirect) - else: - setattr(enum_class, member_name, enum_member) - # now add to _member_map_ (even aliases) - enum_class._member_map_[member_name] = enum_member + + enum_class._add_member_(member_name, enum_member) try: # This may fail if value is not hashable. We can't add the value # to the map, and by-value lookups for this value will be @@ -362,9 +323,10 @@ def __set_name__(self, enum_class, member_name): except TypeError: # keep track of the value in a list so containment checks are quick enum_class._unhashable_values_.append(value) + enum_class._unhashable_values_map_.setdefault(member_name, []).append(value) -class _EnumDict(dict): +class EnumDict(dict): """ Track enum member order and ensure member names are not reused. @@ -373,7 +335,7 @@ class _EnumDict(dict): """ def __init__(self): super().__init__() - self._member_names = {} # use a dict to keep insertion order + self._member_names = {} # use a dict -- faster look-up than a list, and keeps insertion order since 3.7 self._last_values = [] self._ignore = [] self._auto_called = False @@ -395,6 +357,7 @@ def __setitem__(self, key, value): '_order_', '_generate_next_value_', '_numeric_repr_', '_missing_', '_ignore_', '_iter_member_', '_iter_member_by_value_', '_iter_member_by_def_', + '_add_alias_', '_add_value_alias_', ): raise ValueError( '_sunder_ names, such as %r, are reserved for future Enum use' @@ -470,6 +433,10 @@ def __setitem__(self, key, value): self._last_values.append(value) super().__setitem__(key, value) + @property + def member_names(self): + return list(self._member_names) + def update(self, members, **more_members): try: for name in members.keys(): @@ -480,6 +447,8 @@ def update(self, members, **more_members): for name, value in more_members.items(): self[name] = value +_EnumDict = EnumDict # keep private name for backwards compatibility + class EnumType(type): """ @@ -491,7 +460,7 @@ def __prepare__(metacls, cls, bases, **kwds): # check that previous enum members do not exist metacls._check_for_existing_members_(cls, bases) # create the namespace dict - enum_dict = _EnumDict() + enum_dict = EnumDict() enum_dict._cls_name = cls # inherit previous flags and _generate_next_value_ function member_type, first_enum = metacls._get_mixins_(cls, bases) @@ -554,6 +523,7 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k classdict['_member_map_'] = {} classdict['_value2member_map_'] = {} classdict['_unhashable_values_'] = [] + classdict['_unhashable_values_map_'] = {} classdict['_member_type_'] = member_type # now set the __repr__ for the value classdict['_value_repr_'] = metacls._find_data_repr_(cls, bases) @@ -570,12 +540,16 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k try: exc = None enum_class = super().__new__(metacls, cls, bases, classdict, **kwds) - except RuntimeError as e: - # any exceptions raised by member.__new__ will get converted to a - # RuntimeError, so get that original exception back and raise it instead - exc = e.__cause__ or e + except Exception as e: + # since 3.12 the line "Error calling __set_name__ on '_proto_member' instance ..." + # is tacked on to the error instead of raising a RuntimeError + # recreate the exception to discard + exc = type(e)(str(e)) + exc.__cause__ = e.__cause__ + exc.__context__ = e.__context__ + tb = e.__traceback__ if exc is not None: - raise exc + raise exc.with_traceback(tb) # # update classdict with any changes made by __init_subclass__ classdict.update(enum_class.__dict__) @@ -752,7 +726,10 @@ def __contains__(cls, value): """ if isinstance(value, cls): return True - return value in cls._value2member_map_ or value in cls._unhashable_values_ + try: + return value in cls._value2member_map_ + except TypeError: + return value in cls._unhashable_values_ def __delattr__(cls, attr): # nicer error message when someone tries to delete an attribute @@ -1048,7 +1025,57 @@ def _find_new_(mcls, classdict, member_type, first_enum): else: use_args = True return __new__, save_new, use_args -EnumMeta = EnumType + + def _add_member_(cls, name, member): + # _value_ structures are not updated + if name in cls._member_map_: + if cls._member_map_[name] is not member: + raise NameError('%r is already bound: %r' % (name, cls._member_map_[name])) + return + # + # if necessary, get redirect in place and then add it to _member_map_ + found_descriptor = None + descriptor_type = None + class_type = None + for base in cls.__mro__[1:]: + attr = base.__dict__.get(name) + if attr is not None: + if isinstance(attr, (property, DynamicClassAttribute)): + found_descriptor = attr + class_type = base + descriptor_type = 'enum' + break + elif _is_descriptor(attr): + found_descriptor = attr + descriptor_type = descriptor_type or 'desc' + class_type = class_type or base + continue + else: + descriptor_type = 'attr' + class_type = base + if found_descriptor: + redirect = property() + redirect.member = member + redirect.__set_name__(cls, name) + if descriptor_type in ('enum', 'desc'): + # earlier descriptor found; copy fget, fset, fdel to this one. + redirect.fget = getattr(found_descriptor, 'fget', None) + redirect._get = getattr(found_descriptor, '__get__', None) + redirect.fset = getattr(found_descriptor, 'fset', None) + redirect._set = getattr(found_descriptor, '__set__', None) + redirect.fdel = getattr(found_descriptor, 'fdel', None) + redirect._del = getattr(found_descriptor, '__delete__', None) + redirect._attr_type = descriptor_type + redirect._cls_type = class_type + setattr(cls, name, redirect) + else: + setattr(cls, name, member) + # now add to _member_map_ (even aliases) + cls._member_map_[name] = member + # + cls._member_map_[name] = member + +EnumMeta = EnumType # keep EnumMeta name for backwards compatibility class Enum(metaclass=EnumType): @@ -1114,9 +1141,9 @@ def __new__(cls, value): pass except TypeError: # not there, now do long search -- O(n) behavior - for member in cls._member_map_.values(): - if member._value_ == value: - return member + for name, values in cls._unhashable_values_map_.items(): + if value in values: + return cls[name] # 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_: @@ -1157,6 +1184,33 @@ def __new__(cls, value): def __init__(self, *args, **kwds): pass + def _add_alias_(self, name): + self.__class__._add_member_(name, self) + + def _add_value_alias_(self, value): + cls = self.__class__ + try: + if value in cls._value2member_map_: + if cls._value2member_map_[value] is not self: + raise ValueError('%r is already bound: %r' % (value, cls._value2member_map_[value])) + return + except TypeError: + # unhashable value, do long search + for m in cls._member_map_.values(): + if m._value_ == value: + if m is not self: + raise ValueError('%r is already bound: %r' % (value, cls._value2member_map_[value])) + return + try: + # This may fail if value is not hashable. We can't add the value + # to the map, and by-value lookups for this value will be + # linear. + cls._value2member_map_.setdefault(value, self) + except TypeError: + # keep track of the value in a list so containment checks are quick + cls._unhashable_values_.append(value) + cls._unhashable_values_map_.setdefault(self.name, []).append(value) + @staticmethod def _generate_next_value_(name, start, count, last_values): """ @@ -1191,14 +1245,13 @@ def __str__(self): def __dir__(self): """ - Returns all members and all public methods + Returns public methods and other interesting attributes. """ - if self.__class__._member_type_ is object: - interesting = set(['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'value']) - else: + interesting = set() + if self.__class__._member_type_ is not object: interesting = set(object.__dir__(self)) for name in getattr(self, '__dict__', []): - if name[0] != '_': + if name[0] != '_' and name not in self._member_map_: interesting.add(name) for cls in self.__class__.mro(): for name, obj in cls.__dict__.items(): @@ -1211,7 +1264,7 @@ def __dir__(self): else: # in case it was added by `dir(self)` interesting.discard(name) - else: + elif name not in self._member_map_: interesting.add(name) names = sorted( set(['__class__', '__doc__', '__eq__', '__hash__', '__module__']) @@ -1639,7 +1692,7 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): Class decorator that converts a normal class into an :class:`Enum`. No safety checks are done, and some advanced behavior (such as :func:`__init_subclass__`) is not available. Enum creation can be faster - using :func:`simple_enum`. + using :func:`_simple_enum`. >>> from enum import Enum, _simple_enum >>> @_simple_enum(Enum) @@ -1670,7 +1723,8 @@ def convert_class(cls): body['_member_names_'] = member_names = [] body['_member_map_'] = member_map = {} body['_value2member_map_'] = value2member_map = {} - body['_unhashable_values_'] = [] + body['_unhashable_values_'] = unhashable_values = [] + body['_unhashable_values_map_'] = {} body['_member_type_'] = member_type = etype._member_type_ body['_value_repr_'] = etype._value_repr_ if issubclass(etype, Flag): @@ -1717,14 +1771,9 @@ def convert_class(cls): for name, value in attrs.items(): if isinstance(value, auto) and auto.value is _auto_null: value = gnv(name, 1, len(member_names), gnv_last_values) - if value in value2member_map: + if value in value2member_map or value in unhashable_values: # an alias to an existing member - member = value2member_map[value] - redirect = property() - redirect.member = member - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = member + enum_class(value)._add_alias_(name) else: # create the member if use_args: @@ -1739,12 +1788,12 @@ def convert_class(cls): member._name_ = name member.__objclass__ = enum_class member.__init__(value) - redirect = property() - redirect.member = member - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = member member._sort_order_ = len(member_names) + if name not in ('name', 'value'): + setattr(enum_class, name, member) + member_map[name] = member + else: + enum_class._add_member_(name, member) value2member_map[value] = member if _is_single_bit(value): # not a multi-bit alias, record in _member_names_ and _flag_mask_ @@ -1767,14 +1816,13 @@ def convert_class(cls): if value.value is _auto_null: value.value = gnv(name, 1, len(member_names), gnv_last_values) value = value.value - if value in value2member_map: + try: + contained = value in value2member_map + except TypeError: + contained = value in unhashable_values + if contained: # an alias to an existing member - member = value2member_map[value] - redirect = property() - redirect.member = member - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = member + enum_class(value)._add_alias_(name) else: # create the member if use_args: @@ -1790,14 +1838,22 @@ def convert_class(cls): member.__objclass__ = enum_class member.__init__(value) member._sort_order_ = len(member_names) - redirect = property() - redirect.member = member - redirect.__set_name__(enum_class, name) - setattr(enum_class, name, redirect) - member_map[name] = member - value2member_map[value] = member + if name not in ('name', 'value'): + setattr(enum_class, name, member) + member_map[name] = member + else: + enum_class._add_member_(name, member) member_names.append(name) gnv_last_values.append(value) + try: + # This may fail if value is not hashable. We can't add the value + # to the map, and by-value lookups for this value will be + # linear. + enum_class._value2member_map_.setdefault(value, member) + except TypeError: + # keep track of the value in a list so containment checks are quick + enum_class._unhashable_values_.append(value) + enum_class._unhashable_values_map_.setdefault(name, []).append(value) if '__new__' in body: enum_class.__new_member__ = enum_class.__new__ enum_class.__new__ = Enum.__new__ diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py index d5e296f7748c1c..73acb1fe8d4106 100644 --- a/Lib/fnmatch.py +++ b/Lib/fnmatch.py @@ -78,6 +78,11 @@ def translate(pat): """ STAR = object() + parts = _translate(pat, STAR, '.') + return _join_translated_parts(parts, STAR) + + +def _translate(pat, STAR, QUESTION_MARK): res = [] add = res.append i, n = 0, len(pat) @@ -89,7 +94,7 @@ def translate(pat): if (not res) or res[-1] is not STAR: add(STAR) elif c == '?': - add('.') + add(QUESTION_MARK) elif c == '[': j = i if j < n and pat[j] == '!': @@ -146,9 +151,11 @@ def translate(pat): else: add(re.escape(c)) assert i == n + return res + +def _join_translated_parts(inp, STAR): # Deal with STARs. - inp = res res = [] add = res.append i, n = 0, len(inp) diff --git a/Lib/getpass.py b/Lib/getpass.py index 6970d8adfbab36..bd0097ced94c5e 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: @@ -156,7 +156,11 @@ def getuser(): First try various environment variables, then the password database. This works on Windows as long as USERNAME is set. + Any failure to find a username raises OSError. + .. versionchanged:: 3.13 + Previously, various exceptions beyond just :exc:`OSError` + were raised. """ for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): @@ -164,9 +168,12 @@ def getuser(): if user: return user - # If this fails, the exception will "explain" why - import pwd - return pwd.getpwuid(os.getuid())[0] + try: + import pwd + return pwd.getpwuid(os.getuid())[0] + except (ImportError, KeyError) as e: + raise OSError('No username set in the environment') from e + # Bind the name getpass to the appropriate function try: diff --git a/Lib/gettext.py b/Lib/gettext.py index b72b15f82d4355..62cff81b7b3d49 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,28 @@ 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 + return _as_int2(n) + +def _as_int2(n): + try: + return operator.index(n) + except TypeError: + pass + 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 +215,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): @@ -280,6 +295,7 @@ def gettext(self, message): def ngettext(self, msgid1, msgid2, n): if self._fallback: return self._fallback.ngettext(msgid1, msgid2, n) + n = _as_int2(n) if n == 1: return msgid1 else: @@ -293,6 +309,7 @@ def pgettext(self, context, message): def npgettext(self, context, msgid1, msgid2, n): if self._fallback: return self._fallback.npgettext(context, msgid1, msgid2, n) + n = _as_int2(n) if n == 1: return msgid1 else: @@ -579,6 +596,7 @@ def dngettext(domain, msgid1, msgid2, n): try: t = translation(domain, _localedirs.get(domain, None)) except OSError: + n = _as_int2(n) if n == 1: return msgid1 else: @@ -598,6 +616,7 @@ def dnpgettext(domain, context, msgid1, msgid2, n): try: t = translation(domain, _localedirs.get(domain, None)) except OSError: + n = _as_int2(n) if n == 1: return msgid1 else: diff --git a/Lib/glob.py b/Lib/glob.py index a7256422d520fb..4a335a10766cf4 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -249,3 +249,63 @@ def escape(pathname): _dir_open_flags = os.O_RDONLY | getattr(os, 'O_DIRECTORY', 0) + + +def translate(pat, *, recursive=False, include_hidden=False, seps=None): + """Translate a pathname with shell wildcards to a regular expression. + + If `recursive` is true, the pattern segment '**' will match any number of + path segments; if '**' appears outside its own segment, ValueError will be + raised. + + If `include_hidden` is true, wildcards can match path segments beginning + with a dot ('.'). + + If a sequence of separator characters is given to `seps`, they will be + used to split the pattern into segments and match path separators. If not + given, os.path.sep and os.path.altsep (where available) are used. + """ + if not seps: + if os.path.altsep: + seps = (os.path.sep, os.path.altsep) + else: + seps = os.path.sep + escaped_seps = ''.join(map(re.escape, seps)) + any_sep = f'[{escaped_seps}]' if len(seps) > 1 else escaped_seps + not_sep = f'[^{escaped_seps}]' + if include_hidden: + one_last_segment = f'{not_sep}+' + one_segment = f'{one_last_segment}{any_sep}' + any_segments = f'(?:.+{any_sep})?' + any_last_segments = '.*' + else: + one_last_segment = f'[^{escaped_seps}.]{not_sep}*' + one_segment = f'{one_last_segment}{any_sep}' + any_segments = f'(?:{one_segment})*' + any_last_segments = f'{any_segments}(?:{one_last_segment})?' + + results = [] + parts = re.split(any_sep, pat) + last_part_idx = len(parts) - 1 + for idx, part in enumerate(parts): + if part == '*': + results.append(one_segment if idx < last_part_idx else one_last_segment) + continue + if recursive: + if part == '**': + if idx < last_part_idx: + if parts[idx + 1] != '**': + results.append(any_segments) + else: + results.append(any_last_segments) + continue + elif '**' in part: + raise ValueError("Invalid pattern: '**' can only be an entire path component") + if part: + if not include_hidden and part[0] in '*?': + results.append(r'(?!\.)') + results.extend(fnmatch._translate(part, f'{not_sep}*', not_sep)) + if idx < last_part_idx: + results.append(any_sep) + res = ''.join(results) + return fr'(?s:{res})\Z' diff --git a/Lib/hmac.py b/Lib/hmac.py index 8b4f920db954ca..8b4eb2fe741e60 100644 --- a/Lib/hmac.py +++ b/Lib/hmac.py @@ -53,7 +53,7 @@ def __init__(self, key, msg=None, digestmod=''): raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__) if not digestmod: - raise TypeError("Missing required parameter 'digestmod'.") + raise TypeError("Missing required argument 'digestmod'.") if _hashopenssl and isinstance(digestmod, (str, _functype)): try: diff --git a/Lib/http/client.py b/Lib/http/client.py index b35b1d6368aae7..7bb5d824bb6da4 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -172,6 +172,13 @@ def _encode(data, name='data'): "if you want to send it encoded in UTF-8." % (name.title(), data[err.start:err.end], name)) from None +def _strip_ipv6_iface(enc_name: bytes) -> bytes: + """Remove interface scope from IPv6 address.""" + enc_name, percent, _ = enc_name.partition(b"%") + if percent: + assert enc_name.startswith(b'['), enc_name + enc_name += b']' + return enc_name class HTTPMessage(email.message.Message): # XXX The only usage of this method is in @@ -1194,7 +1201,7 @@ def putrequest(self, method, url, skip_host=False, netloc_enc = netloc.encode("ascii") except UnicodeEncodeError: netloc_enc = netloc.encode("idna") - self.putheader('Host', netloc_enc) + self.putheader('Host', _strip_ipv6_iface(netloc_enc)) else: if self._tunnel_host: host = self._tunnel_host @@ -1211,8 +1218,9 @@ def putrequest(self, method, url, skip_host=False, # As per RFC 273, IPv6 address should be wrapped with [] # when used as Host header - if host.find(':') >= 0: + if ":" in host: host_enc = b'[' + host_enc + b']' + host_enc = _strip_ipv6_iface(host_enc) if port == self.default_port: self.putheader('Host', host_enc) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt deleted file mode 100644 index f258797c6e0fb3..00000000000000 --- a/Lib/idlelib/NEWS.txt +++ /dev/null @@ -1,1340 +0,0 @@ -What's New in IDLE 3.12.0 -(since 3.11.0) -Released on 2023-10-02 -========================= - - -gh-104719: Remove IDLE's modification of tokenize.tabsize and test -other uses of tokenize data and methods. - -gh-104499: Fix completions for Tk Aqua 8.7 (currently blank). - -gh-104486: Make About print both tcl and tk versions if different, -as is expected someday. - -gh-88496 Fix IDLE test hang on macOS. - -gh-103314 Support sys.last_exc after exceptions in Shell. -Patch by Irit Katriel. - - -What's New in IDLE 3.11.0 -(since 3.10.0) -Released on 2022-10-24 -========================= - -gh-97527: Fix a bug in the previous bugfix that caused IDLE to not -start when run with 3.10.8, 3.12.0a1, and at least Microsoft Python -3.10.2288.0 installed without the Lib/test package. 3.11.0 was never -affected. - -gh-65802: Document handling of extensions in Save As dialogs. - -gh-95191: Include prompts when saving Shell (interactive input/output). - -gh-95511: Fix the Shell context menu copy-with-prompts bug of copying -an extra line when one selects whole lines. - -gh-95471: Tweak Edit menu. Move 'Select All' above 'Cut' as it is used -with 'Cut' and 'Copy' but not 'Paste'. Add a separator between 'Replace' -and 'Go to Line' to help IDLE issue triagers. - -gh-95411: Enable using IDLE's module browser with .pyw files. - -gh-89610: Add .pyi as a recognized extension for IDLE on macOS. This allows -opening stub files by double clicking on them in the Finder. - -bpo-28950: Apply IDLE syntax highlighting to `.pyi` files. Add util.py -for common components. Patch by Alex Waygood and Terry Jan Reedy. - -bpo-46630: Make query dialogs on Windows start with a cursor in the -entry box. - -bpo-46591: Make the IDLE doc URL on the About IDLE dialog clickable. - -bpo-45296: Clarify close, quit, and exit in IDLE. In the File menu, -'Close' and 'Exit' are now 'Close Window' (the current one) and 'Exit' -is now 'Exit IDLE' (by closing all windows). In Shell, 'quit()' and -'exit()' mean 'close Shell'. If there are no other windows, -this also exits IDLE. - -bpo-45495: Add context keywords 'case' and 'match' to completions list. - -bpo-45296: On Windows, change exit/quit message to suggest Ctrl-D, which -works, instead of , which does not work in IDLE. - - -What's New in IDLE 3.10.0 -(since 3.9.0) -Released on 2021-10-04 -========================= - -bpo-45193: Make completion boxes appear on Ubuntu again. - -bpo-40128: Mostly fix completions on macOS when not using tcl/tk 8.6.11 -(as with 3.9). - -bpo-33962: Move the indent space setting from the Font tab to the new Windows -tab. Patch by Mark Roseman and Terry Jan Reedy. - -bpo-40468: Split the settings dialog General tab into Windows and Shell/Ed -tabs. Move help sources, which extend the Help menu, to the Extensions tab. -Make space for new options and shorten the dialog. The latter makes the -dialog better fit small screens. - -bpo-44010: Highlight the new match statement's soft keywords: match, case, -and _. This highlighting is not perfect and will be incorrect in some rare -cases, especially for some _s in case patterns. - -bpo-44026: Include interpreter's typo fix suggestions in message line -for NameErrors and AttributeErrors. Patch by E. Paine. - -bpo-41611: Avoid occasional uncaught exceptions and freezing when using -completions on macOS. - -bpo-37903: Add mouse actions to the shell sidebar. Left click and -optional drag selects one or more lines of text, as with the -editor line number sidebar. Right click after selecting text lines -displays a context menu with 'copy with prompts'. This zips together -prompts from the sidebar with lines from the selected text. This option -also appears on the context menu for the text. - -bpo-43981: Fix reference leaks in test_sidebar and test_squeezer. -Patches by Terry Jan Reedy and Pablo Galindo - -bpo-37892: Change Shell input indents from tabs to spaces. Shell input -now 'looks right'. Making this feasible motivated the shell sidebar. - -bpo-37903: Move the Shell input prompt to a side bar. - -bpo-43655: Make window managers on macOS and X Window recognize -IDLE dialog windows as dialogs. - -bpo-42225: Document that IDLE can fail on Unix either from misconfigured IP -masquerade rules or failure displaying complex colored (non-ascii) characters. - -bpo-43283: Document why printing to IDLE's Shell is often slower than -printing to a system terminal and that it can be made faster by -pre-formatting a single string before printing. - -bpo-23544: Disable Debug=>Stack Viewer when user code is running or -Debugger is active, to prevent hang or crash. Patch by Zackery Spytz. - -bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal, -2-process mode. User hooks were previously ignored. -Patch by Ken Hilton. - -bpo-33065: Fix problem debugging user classes with __repr__ method. - -bpo-32631: Finish zzdummy example extension module: make menu entries -work; add docstrings and tests with 100% coverage. - -bpo-42508: Keep IDLE running on macOS. Remove obsolete workaround -that prevented running files with shortcuts when using new universal2 -installers built on macOS 11. - -bpo-42426: Fix reporting offset of the RE error in searchengine. - -bpo-42416: Display docstrings in IDLE calltips in more cases, -by using inspect.getdoc. - -bpo-33987: Mostly finish using ttk widgets, mainly for editor, -settings, and searches. Some patches by Mark Roseman. - -bpo-40511: Stop unnecessary "flashing" when typing opening and closing -parentheses inside the parentheses of a function call. - -bpo-38439: Add a 256x256 pixel IDLE icon to the Windows .ico file. Created by -Andrew Clover. Remove the low-color gif variations from the .ico file. - -bpo-41775: Make 'IDLE Shell' the shell title. - -bpo-35764: Rewrite the Calltips doc section. - -bpo-40181: In calltips, stop reminding that '/' marks the end of -positional-only arguments. - - -What's New in IDLE 3.9.0 (since 3.8.0) -Released on 2020-10-05? -====================================== - -bpo-41468: Improve IDLE run crash error message (which users should -never see). - -bpo-41373: Save files loaded with no line ending, as when blank, or -different line endings, by setting its line ending to the system -default. Fix regression in 3.8.4 and 3.9.0b4. - -bpo-41300: Save files with non-ascii chars. Fix regression in -3.9.0b4 and 3.8.4. - -bpo-37765: Add keywords to module name completion list. Rewrite -Completions section of IDLE doc. - -bpo-41152: The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE -is now always UTF-8. - -bpo-41144: Make Open Module open a special module such as os.path. - -bpo-40723: Make test_idle pass when run after import. -Patch by Florian Dahlitz. - -bpo-38689: IDLE will no longer freeze when inspect.signature fails -when fetching a calltip. - -bpo-27115: For 'Go to Line', use a Query entry box subclass with -IDLE standard behavior and improved error checking. - -bpo-39885: When a context menu is invoked by right-clicking outside -of a selection, clear the selection and move the cursor. Cut and -Copy require that the click be within the selection. - -bpo-39852: Edit "Go to line" now clears any selection, preventing -accidental deletion. It also updates Ln and Col on the status bar. - -bpo-39781: Selecting code context lines no longer causes a jump. - -bpo-39663: Add tests for pyparse find_good_parse_start(). - -bpo-39600: Remove duplicate font names from configuration list. - -bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` -or shell restart occurs. Patch by Zackery Spytz. - -bpo-30780: Add remaining configdialog tests for buttons and -highlights and keys tabs. - -bpo-39388: Settings dialog Cancel button cancels pending changes. - -bpo-39050: Settings dialog Help button again displays help text. - -bpo-32989: Add tests for editor newline_and_indent_event method. -Remove unneeded arguments and dead code from pyparse -find_good_parse_start method. - -bpo-38943: Fix autocomplete windows not always appearing on some -systems. Patch by Johnny Najera. - -bpo-38944: Escape key now closes IDLE completion windows. Patch by -Johnny Najera. - -bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra -newlines at the end of non-shell files. - -bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These -functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled -in 3.7.5 and 3.8.0. - -bpo-4630: Add an option to toggle IDLE's cursor blink for shell, -editor, and output windows. See Settings, General, Window Preferences, -Cursor Blink. Patch by Zackery Spytz. - -bpo-26353: Stop adding newline when saving an IDLE shell window. - -bpo-38598: Do not try to compile IDLE shell or output windows. - - -What's New in IDLE 3.8.0 (since 3.7.0) -Released on 2019-10-14 -====================================== - -bpo-36698: IDLE no longer fails when writing non-encodable characters -to stderr. It now escapes them with a backslash, like the regular -Python interpreter. Add an errors field to the standard streams. - -bpo-13153: Improve tkinter's handing of non-BMP (astral) unicode -characters, such as 'rocket \U0001f680'. Whether a proper glyph or -replacement char is displayed depends on the OS and font. For IDLE, -astral chars in code interfere with editing. - -bpo-35379: When exiting IDLE, catch any AttributeError. One happens -when EditorWindow.close is called twice. Printing a traceback, when -IDLE is run from a terminal, is useless and annoying. - -bpo-38183: To avoid test issues, test_idle ignores the user config -directory. It no longer tries to create or access .idlerc or any files -within. Users must run IDLE to discover problems with saving settings. - -bpo-38077: IDLE no longer adds 'argv' to the user namespace when -initializing it. This bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. - -bpo-38401: Shell restart lines now fill the window width, always start -with '=', and avoid wrapping unnecessarily. The line will still wrap -if the included file name is long relative to the width. - -bpo-37092: Add mousewheel scrolling for IDLE module, path, and stack -browsers. Patch by George Zhang. - -bpo-35771: To avoid occasional spurious test_idle failures on slower -machines, increase the ``hover_delay`` in test_tooltip. - -bpo-37824: Properly handle user input warnings in IDLE shell. -Cease turning SyntaxWarnings into SyntaxErrors. - -bpo-37929: IDLE Settings dialog now closes properly when there is no -shell window. - -bpo-37849: Fix completions list appearing too high or low when shown -above the current line. - -bpo-36419: Refactor autocompete and improve testing. - -bpo-37748: Reorder the Run menu. Put the most common choice, -Run Module, at the top. - -bpo-37692: Improve highlight config sample with example shell -interaction and better labels for shell elements. - -bpo-37628: Settings dialog no longer expands with font size. -The font and highlight sample boxes gain scrollbars instead. - -bpo-17535: Add optional line numbers for IDLE editor windows. - -bpo-37627: Initialize the Customize Run dialog with the command line -arguments most recently entered before. The user can optionally edit -before submitting them. - -bpo-33610: Code context always shows the correct context when toggled on. - -bpo-36390: Gather Format menu functions into format.py. Combine -paragraph.py, rstrip.py, and format methods from editor.py. - -bpo-37530: Optimize code context to reduce unneeded background activity. -Font and highlight changes now occur along with text changes instead -of after a random delay. - -bpo-27452: Cleanup config.py by inlining RemoveFile and simplifying -the handling of __file__ in CreateConfigHandlers/ - -bpo-26806: To compensate for stack frames added by IDLE and avoid -possible problems with low recursion limits, add 30 to limits in the -user code execution process. Subtract 30 when reporting recursion -limits to make this addition mostly transparent. - -bpo-37325: Fix tab focus traversal order for help source and custom -run dialogs. - -bpo-37321: Both subprocess connection error messages now refer to -the 'Startup failure' section of the IDLE doc. - -bpo-37177: Properly attach search dialogs to their main window so -that they behave like other dialogs and do not get hidden behind -their main window. - -bpo-37039: Adjust "Zoom Height" to individual screens by momentarily -maximizing the window on first use with a particular screen. Changing -screen settings may invalidate the saved height. While a window is -maximized, "Zoom Height" has no effect. - -bpo-35763: Make calltip reminder about '/' meaning positional-only less -obtrusive by only adding it when there is room on the first line. - -bpo-5680: Add 'Run Customized' to the Run menu to run a module with -customized settings. Any command line arguments entered are added -to sys.argv. One can suppress the normal Shell main module restart. - -bpo-35610: Replace now redundant editor.context_use_ps1 with -.prompt_last_line. This finishes change started in bpo-31858. - -bpo-32411: Stop sorting dict created with desired line order. - -bpo-37038: Make idlelib.run runnable; add test clause. - -bpo-36958: Print any argument other than None or int passed to -SystemExit or sys.exit(). - -bpo-36807: When saving a file, call file.flush() and os.fsync() -so bits are flushed to e.g. a USB drive. - -bpo-36429: Fix starting IDLE with pyshell. -Add idlelib.pyshell alias at top; remove pyshell alias at bottom. -Remove obsolete __name__=='__main__' command. - -bpo-30348: Increase test coverage of idlelib.autocomplete by 30%. -Patch by Louie Lu. - -bpo-23205: Add tests and refactor grep's findfiles. - -bpo-36405: Use dict unpacking in idlelib. - -bpo-36396: Remove fgBg param of idlelib.config.GetHighlight(). -This param was only used twice and changed the return type. - -bpo-23216: IDLE: Add docstrings to search modules. - -bpo-36176: Fix IDLE autocomplete & calltip popup colors. -Prevent conflicts with Linux dark themes -(and slightly darken calltip background). - -bpo-36152: Remove colorizer.ColorDelegator.close_when_done and the -corresponding argument of .close(). In IDLE, both have always been -None or False since 2007. - -bpo-36096: Make colorizer state variables instance-only. - -bpo-32129: Avoid blurry IDLE application icon on macOS with Tk 8.6. -Patch by Kevin Walzer. - -bpo-24310: Document settings dialog font tab sample. - -bpo-35689: Add docstrings and tests for colorizer. - -bpo-35833: Revise IDLE doc for control codes sent to Shell. -Add a code example block. - -bpo-35770: IDLE macosx deletes Options => Configure IDLE. -It previously deleted Window => Zoom Height by mistake. -(Zoom Height is now on the Options menu). On Mac, the settings -dialog is accessed via Preferences on the IDLE menu. - -bpo-35769: Change new file name from 'Untitled' to 'untitled'. - -bpo-35660: Fix imports in window module. - -bpo-35641: Properly format calltip for function without docstring. - -bpo-33987: Use ttk Frame for ttk widgets. - -bpo-34055: Fix erroneous 'smart' indents and newlines in IDLE Shell. - -bpo-28097: Add Previous/Next History entries to Shell menu. - -bpo-35591: Find Selection now works when selection not found. - -bpo-35598: Update config_key: use PEP 8 names and ttk widgets, -make some objects global, and add tests. - -bpo-35196: Speed up squeezer line counting. - -bpo-35208: Squeezer now counts wrapped lines before newlines. - -bpo-35555: Gray out Code Context menu entry when it's not applicable. - -bpo-22703: Improve the Code Context and Zoom Height menu labels. -The Code Context menu label now toggles between Show/Hide Code Context. -The Zoom Height menu now toggles between Zoom/Restore Height. -Zoom Height has moved from the Window menu to the Options menu. - -bpo-35521: Document the editor code context feature. -Add some internal references within the IDLE doc. - -bpo-34864: When starting IDLE on MacOS, warn if the system setting -"Prefer tabs when opening documents" is "Always". As previous -documented for this issue, running IDLE with this setting causes -problems. If the setting is changed while IDLE is running, -there will be no warning until IDLE is restarted. - -bpo-35213: Where appropriate, use 'macOS' in idlelib. - -bpo-34864: Document two IDLE on MacOS issues. The System Preferences -Dock "prefer tabs always" setting disables some IDLE features. -Menus are a bit different than as described for Windows and Linux. - -bpo-35202: Remove unused imports in idlelib. - -bpo-33000: Document that IDLE's shell has no line limit. -A program that runs indefinitely can overfill memory. - -bpo-23220: Explain how IDLE's Shell displays output. -Add new subsection "User output in Shell". - -bpo-35099: Improve the doc about IDLE running user code. -"IDLE -- console differences" is renamed "Running user code". -It mostly covers the implications of using custom sys.stdxxx objects. - -bpo-35097: Add IDLE doc subsection explaining editor windows. -Topics include opening, title and status bars, .py* extension, and running. - -Issue 35093: Document the IDLE document viewer in the IDLE doc. -Add a paragraph in "Help and preferences", "Help sources" subsection. - -bpo-1529353: Explain Shell text squeezing in the IDLE doc. - -bpo-35088: Update idlelib.help.copy_string docstring. -We now use git and backporting instead of hg and forward merging. - -bpo-35087: Update idlelib help files for the current doc build. -The main change is the elimination of chapter-section numbers. - -bpo-1529353: Output over N lines (50 by default) is squeezed down to a button. -N can be changed in the PyShell section of the General page of the -Settings dialog. Fewer, but possibly extra long, lines can be squeezed by -right clicking on the output. Squeezed output can be expanded in place -by double-clicking the button or into the clipboard or a separate window -by right-clicking the button. - -bpo-34548: Use configured color theme for read-only text views. - -bpo-33839: Refactor ToolTip and CallTip classes; add documentation -and tests. - -bpo-34047: Fix mouse wheel scrolling direction on macOS. - -bpo-34275: Make calltips always visible on Mac. -Patch by Kevin Walzer. - -bpo-34120: Fix freezing after closing some dialogs on Mac. -This is one of multiple regressions from using newer tcl/tk. - -bpo-33975: Avoid small type when running htests. -Since part of the purpose of human-viewed tests is to determine that -widgets look right, it is important that they look the same for -testing as when running IDLE. - -bpo-33905: Add test for idlelib.stackview.StackBrowser. - -bpo-33924: Change mainmenu.menudefs key 'windows' to 'window'. -Every other menudef key is the lowercase version of the -corresponding main menu entry (in this case, 'Window'). - -bpo-33906: Rename idlelib.windows as window -Match Window on the main menu and remove last plural module name. -Change imports, test, and attribute references to match new name. - -bpo-33917: Fix and document idlelib/idle_test/template.py. -The revised file compiles, runs, and tests OK. idle_test/README.txt -explains how to use it to create new IDLE test files. - -bpo-33904: In rstrip module, rename class RstripExtension as Rstrip. - -bpo-33907: For consistency and clarity, rename calltip objects. -Module calltips and its class CallTips are now calltip and Calltip. -In module calltip_w, class CallTip is now CalltipWindow. - -bpo-33855: Minimally test all IDLE modules. -Standardize the test file format. Add missing test files that import -the tested module and perform at least one test. Check and record the -coverage of each test. - -bpo-33856: Add 'help' to Shell's initial welcome message. - - -What's New in IDLE 3.7.0 (since 3.6.0) -Released on 2018-06-27 -====================================== - -bpo-33656: On Windows, add API call saying that tk scales for DPI. -On Windows 8.1+ or 10, with DPI compatibility properties of the Python -binary unchanged, and a monitor resolution greater than 96 DPI, this -should make text and lines sharper and some colors brighter. -On other systems, it should have no effect. If you have a custom theme, -you may want to adjust a color or two. If perchance it make text worse -on your monitor, you can disable the ctypes.OleDLL call near the top of -pyshell.py and report the problem on python-list or idle-dev@python.org. - -bpo-33768: Clicking on a context line moves that line to the top -of the editor window. - -bpo-33763: Replace the code context label widget with a text widget. - -bpo-33664: Scroll IDLE editor text by lines. -(Previously, the mouse wheel and scrollbar slider moved text by a fixed -number of pixels, resulting in partial lines at the top of the editor -box.) This change also applies to the shell and grep output windows, -but currently not to read-only text views. - -bpo-33679: Enable theme-specific color configuration for Code Context. -(Previously, there was one code context foreground and background font -color setting, default or custom, on the extensions tab, that applied -to all themes.) For built-in themes, the foreground is the same as -normal text and the background is a contrasting gray. Context colors for -custom themes are set on the Hightlights tab along with other colors. -When one starts IDLE from a console and loads a custom theme without -definitions for 'context', one will see a warning message on the -console. - -bpo-33642: Display up to maxlines non-blank lines for Code Context. -If there is no current context, show a single blank line. (Previously, -the Code Contex had numlines lines, usually with some blank.) The use -of a new option, 'maxlines' (default 15), avoids possible interference -with user settings of the old option, 'numlines' (default 3). - -bpo-33628: Cleanup codecontext.py and its test. - -bpo-32831: Add docstrings and tests for codecontext.py. -Coverage is 100%. Patch by Cheryl Sabella. - -bpo-33564: Code context now recognizes async as a block opener. - -bpo-21474: Update word/identifier definition from ascii to unicode. -In text and entry boxes, this affects selection by double-click, -movement left/right by control-left/right, and deletion left/right -by control-BACKSPACE/DEL. - -bpo-33204: Consistently color invalid string prefixes. -A 'u' string prefix cannot be paired with either 'r' or 'f'. -IDLE now consistently colors as much of the prefix, starting at the -right, as is valid. Revise and extend colorizer test. - -bpo-32984: Set __file__ while running a startup file. -Like Python, IDLE optionally runs 1 startup file in the Shell window -before presenting the first interactive input prompt. For IDLE, -option -s runs a file named in environmental variable IDLESTARTUP or -PYTHONSTARTUP; -r file runs file. Python sets __file__ to the startup -file name before running the file and unsets it before the first -prompt. IDLE now does the same when run normally, without the -n -option. - -bpo-32940: Replace StringTranslatePseudoMapping with faster code. - -bpo-32916: Change 'str' to 'code' in idlelib.pyparse and users. - -bpo-32905: Remove unused code in pyparse module. - -bpo-32874: IDLE - add pyparse tests with 97% coverage. - -bpo-32837: IDLE - require encoding argument for textview.view_file. -Using the system and place-dependent default encoding for open() -is a bad idea for IDLE's system and location-independent files. - -bpo-32826: Add "encoding=utf-8" to open() in IDLE's test_help_about. -GUI test test_file_buttons() only looks at initial ascii-only lines, -but failed on systems where open() defaults to 'ascii' because -readline() internally reads and decodes far enough ahead to encounter -a non-ascii character in CREDITS.txt. - -bpo-32765: Update configdialog General tab create page docstring. -Add new widgets to the widget list. - -bpo-32207: Improve tk event exception tracebacks in IDLE. -When tk event handling is driven by IDLE's run loop, a confusing -and distracting queue.EMPTY traceback context is no longer added -to tk event exception tracebacks. The traceback is now the same -as when event handling is driven by user code. Patch based on -a suggestion by Serhiy Storchaka. - -bpo-32164: Delete unused file idlelib/tabbedpages.py. -Use of TabbedPageSet in configdialog was replaced by ttk.Notebook. - -bpo-32100: Fix old and new bugs in pathbrowser; improve tests. -Patch mostly by Cheryl Sabella. - -bpo-31860: The font sample in the settings dialog is now editable. -Edits persist while IDLE remains open. -Patch by Serhiy Storchake and Terry Jan Reedy. - -bpo-31858: Restrict shell prompt manipulation to the shell. -Editor and output windows only see an empty last prompt line. This -simplifies the code and fixes a minor bug when newline is inserted. -Sys.ps1, if present, is read on Shell start-up, but is not set or changed. -Patch by Terry Jan Reedy. - -bpo-28603: Fix a TypeError that caused a shell restart when printing -a traceback that includes an exception that is unhashable. -Patch by Zane Bitter. - -bpo-13802: Use non-Latin characters in the Font settings sample. -Even if one selects a font that defines a limited subset of the unicode -Basic Multilingual Plane, tcl/tk will use other fonts that define a -character. The expanded example give users of non-Latin characters -a better idea of what they might see in the shell and editors. - -To make room for the expanded sample, frames on the Font tab are -re-arranged. The Font/Tabs help explains a bit about the additions. -Patch by Terry Jan Reedy - -bpo-31460: Simplify the API of IDLE's Module Browser. -Passing a widget instead of an flist with a root widget opens the -option of creating a browser frame that is only part of a window. -Passing a full file name instead of pieces assumed to come from a -.py file opens the possibility of browsing python files that do not -end in .py. - -bpo-31649: Make _htest and _utest parameters keyword-only. -These are used to adjust code for human and unit tests. - -bpo-31459: Rename module browser from Class Browser to Module Browser. -The original module-level class and method browser became a module -browser, with the addition of module-level functions, years ago. -Nested classes and functions were added yesterday. For back- -compatibility, the virtual event <>, which -appears on the Keys tab of the Settings dialog, is not changed. -Patch by Cheryl Sabella. - -bpo-1612262: Module browser now shows nested classes and functions. -Original patches for code and tests by Guilherme Polo and -Cheryl Sabella, respectively. Revisions by Terry Jan Reedy. - -bpo-31500: Tk's default fonts now are scaled on HiDPI displays. -This affects all dialogs. Patch by Serhiy Storchaka. - -bpo-31493: Fix code context update and font update timers. -Canceling timers prevents a warning message when test_idle completes. - -bpo-31488: Update non-key options in former extension classes. -When applying configdialog changes, call .reload for each feature class. -Change ParenMatch so updated options affect existing instances attached -to existing editor windows. - -bpo-31477: Improve rstrip entry in IDLE doc. -Strip Trailing Whitespace strips more than blank spaces. -Multiline string literals are not skipped. - -bpo-31480: fix tests to pass with zzdummy extension disabled. (#3590) -To see the example in action, enable it on options extensions tab. - -bpo-31421: Document how IDLE runs tkinter programs. -IDLE calls tcl/tk update in the background in order to make live -interaction and experimentation with tkinter applications much easier. - -bpo-31414: Fix tk entry box tests by deleting first. -Adding to an int entry is not the same as deleting and inserting -because int('') will fail. Patch by Terry Jan Reedy. - -bpo-27099: Convert IDLE's built-in 'extensions' to regular features. - About 10 IDLE features were implemented as supposedly optional -extensions. Their different behavior could be confusing or worse for -users and not good for maintenance. Hence the conversion. - The main difference for users is that user configurable key bindings -for builtin features are now handled uniformly. Now, editing a binding -in a keyset only affects its value in the keyset. All bindings are -defined together in the system-specific default keysets in config- -extensions.def. All custom keysets are saved as a whole in config- -extension.cfg. All take effect as soon as one clicks Apply or Ok. - The affected events are '<>', -'<>', '<>', '<>', -'<>', '<>', '<>', and -'<>'. Any (global) customizations made before 3.6.3 will -not affect their keyset-specific customization after 3.6.3. and vice -versa. - Initial patch by Charles Wohlganger, revised by Terry Jan Reedy. - -bpo-31051: Rearrange condigdialog General tab. -Sort non-Help options into Window (Shell+Editor) and Editor (only). -Leave room for the addition of new options. -Patch by Terry Jan Reedy. - -bpo-30617: Add docstrings and tests for outwin subclass of editor. -Move some data and functions from the class to module level. -Patch by Cheryl Sabella. - -bpo-31287: Do not modify tkinter.messagebox in test_configdialog. -Instead, mask it with an instance mock that can be deleted. -Patch by Terry Jan Reedy. - -bpo-30781: Use ttk widgets in ConfigDialog pages. -These should especially look better on MacOSX. -Patches by Terry Jan Reedy and Cheryl Sabella. - -bpo-31206: Factor HighPage(Frame) class from ConfigDialog. -Patch by Cheryl Sabella. - -bp0-31001: Add tests for configdialog highlight tab. -Patch by Cheryl Sabella. - -bpo-31205: Factor KeysPage(Frame) class from ConfigDialog. -The slightly modified tests continue to pass. -Patch by Cheryl Sabella. - -bpo-31002: Add tests for configdialog keys tab. -Patch by Cheryl Sabella. - -bpo-19903: Change calltipes to use inspect.signature. -Idlelib.calltips.get_argspec now uses inspect.signature instead of -inspect.getfullargspec, like help() does. This improves the signature -in the call tip in a few different cases, including builtins converted -to provide a signature. A message is added if the object is not -callable, has an invalid signature, or if it has positional-only -parameters. Patch by Louie Lu. - -bop-31083: Add an outline of a TabPage class in configdialog. -Add template as comment. Update existing classes to match outline. -Initial patch by Cheryl Sabella. - -bpo-31050: Factor GenPage(Frame) class from ConfigDialog. -The slightly modified tests for the General tab continue to pass. -Patch by Cheryl Sabella. - -bpo-31004: Factor FontPage(Frame) class from ConfigDialog. -The slightly modified tests continue to pass. The General test -broken by the switch to ttk.Notebook is fixed. -Patch mostly by Cheryl Sabella. - -bpo-30781: IDLE - Use ttk Notebook in ConfigDialog. -This improves navigation by tabbing. -Patch by Terry Jan Reedy. - -bpo-31060: IDLE - Finish rearranging methods of ConfigDialog. -Grouping methods pertaining to each tab and the buttons will aid -writing tests and improving the tabs and will enable splitting the -groups into classes. -Patch by Terry Jan Reedy. - -bpo-30853: IDLE -- Factor a VarTrace class out of ConfigDialog. -Instance tracers manages pairs consisting of a tk variable and a -callback function. When tracing is turned on, setting the variable -calls the function. Test coverage for the new class is 100%. -Patch by Terry Jan Reedy. - -bpo-31003: IDLE: Add more tests for General tab. -Patch by Terry Jan Reedy. - -bpo-30993: IDLE - Improve configdialog font page and tests. -*In configdialog: Document causal pathways in create_font_tab -docstring. Simplify some attribute names. Move set_samples calls to -var_changed_font (idea from Cheryl Sabella). Move related functions to -positions after the create widgets function. -* In test_configdialog: Fix test_font_set so not order dependent. Fix -renamed test_indent_scale so it tests the widget. Adjust tests for -movement of set_samples call. Add tests for load functions. Put all -font tests in one class and tab indent tests in another. Except for -two lines, these tests completely cover the related functions. -Patch by Terry Jan Reedy. - -bpo-30981: IDLE -- Add more configdialog font page tests. - -bpo-28523: IDLE: replace 'colour' with 'color' in configdialog. - -bpo-30917: Add tests for idlelib.config.IdleConf. -Increase coverage from 46% to 96%. -Patch by Louie Lu. - -bpo-30913: Document ConfigDialog tk Vars, methods, and widgets in docstrings -This will facilitate improving the dialog and splitting up the class. -Original patch by Cheryl Sabella. - -bpo-30899: Add tests for ConfigParser subclasses in config. -Coverage is 100% for those classes and ConfigChanges. -Patch by Louie Lu. - -bpo-30881: Add docstrings to browser.py. -Patch by Cheryl Sabella. - -bpo-30851: Remove unused tk variables in configdialog. -One is a duplicate, one is set but cannot be altered by users. -Patch by Cheryl Sabella. - -bpo-30870: Select font option with Up and Down keys, as well as with mouse. -Added test increases configdialog coverage to 60% -Patches mostly by Louie Lu. - -bpo-8231: Call config.IdleConf.GetUserCfgDir only once per process. - -bpo-30779: Factor ConfigChanges class from configdialog, put in config; test. -* In config, put dump test code in a function; run it and unittest in - 'if __name__ == '__main__'. -* Add class config.ConfigChanges based on changes_class_v4.py on bpo issue. -* Add class test_config.ChangesTest, partly using configdialog_tests_v1.py. -* Revise configdialog to use ConfigChanges; see tracker msg297804. -* Revise test_configdialog to match configdialog changes. -* Remove configdialog functions unused or moved to ConfigChanges. -Cheryl Sabella contributed parts of the patch. - -bpo-30777: Configdialog - add docstrings and improve comments. -Patch by Cheryl Sabella. - -bpo-30495: Improve textview with docstrings, PEP8 names, and more tests. -Split TextViewer class into ViewWindow, ViewFrame, and TextFrame classes -so that instances of the latter two can be placed with other widgets -within a multiframe window. -Patches by Cheryl Sabella and Terry Jan Reedy. - -bpo-30723: Make several improvements to parenmatch. -* Add 'parens' style to highlight both opener and closer. -* Make 'default' style, which is not default, a synonym for 'opener'. -* Make time-delay work the same with all styles. -* Add help for config dialog extensions tab, including parenmatch. -* Add new tests. -Original patch by Charles Wohlganger. Revisions by Terry Jan Reedy - -bpo-30674: Grep -- Add docstrings. Patch by Cheryl Sabella. - -bpo-21519: IDLE's basic custom key entry dialog now detects -duplicates properly. Original patch by Saimadhav Heblikar. - -bpo-29910: IDLE no longer deletes a character after commenting out a -region by a key shortcut. Add "return 'break'" for this and other -potential conflicts between IDLE and default key bindings. -Patch by Serhiy Storchaka. - -bpo-30728: Modernize idlelib.configdialog: -* replace import * with specific imports; -* lowercase method and attribute lines. -Patch by Cheryl Sabella. - -bpo-6739: Verify user-entered key sequences by trying to bind them -with to a tk widget. Add tests for all 3 validation functions. -Original patch by G Polo. Tests added by Cheryl Sabella. -Code revised and more tests added by Terry Jan Reedy - -bpo-24813: Add icon to help_about and make other changes. - -bpo-15786: Fix several problems with IDLE's autocompletion box. -The following should now work: clicking on selection box items; -using the scrollbar; selecting an item by hitting Return. -Hangs on MacOSX should no longer happen. Patch by Louie Lu. - -bpo-25514: Add doc subsubsection about IDLE failure to start. -Popup no-connection message directs users to this section. - -bpo-30642: Fix reference leaks in IDLE tests. -Patches by Louie Lu and Terry Jan Reedy. - -bpo-30495: Add docstrings for textview.py and use PEP8 names. -Patches by Cheryl Sabella and Terry Jan Reedy. - -bpo-30290: Help-about: use pep8 names and add tests. -Increase coverage to 100%. -Patches by Louie Lu, Cheryl Sabella, and Terry Jan Reedy. - -bpo-30303: Add _utest option to textview; add new tests. -Increase coverage to 100%. -Patches by Louie Lu and Terry Jan Reedy. - -Issue #29071: IDLE colors f-string prefixes but not invalid ur prefixes. - -Issue #28572: Add 10% to coverage of IDLE's test_configdialog. -Update and augment description of the configuration system. - - -What's New in IDLE 3.6.0 (since 3.5.0) -Released on 2016-12-23 -====================================== - -- Issue #15308: Add 'interrupt execution' (^C) to Shell menu. - Patch by Roger Serwy, updated by Bayard Randel. - -- Issue #27922: Stop IDLE tests from 'flashing' gui widgets on the screen. - -- Issue #27891: Consistently group and sort imports within idlelib modules. - -- Issue #17642: add larger font sizes for classroom projection. - -- Add version to title of IDLE help window. - -- Issue #25564: In section on IDLE -- console differences, mention that - using exec means that __builtins__ is defined for each statement. - -- Issue #27821: Fix 3.6.0a3 regression that prevented custom key sets - from being selected when no custom theme was defined. - -- Issue #27714: text_textview and test_autocomplete now pass when re-run - in the same process. This occurs when test_idle fails when run with the - -w option but without -jn. Fix warning from test_config. - -- Issue #27621: Put query response validation error messages in the query - box itself instead of in a separate messagebox. Redo tests to match. - Add Mac OSX refinements. Original patch by Mark Roseman. - -- Issue #27620: Escape key now closes Query box as cancelled. - -- Issue #27609: IDLE: tab after initial whitespace should tab, not - autocomplete. This fixes problem with writing docstrings at least - twice indented. - -- Issue #27609: Explicitly return None when there are also non-None - returns. In a few cases, reverse a condition and eliminate a return. - -- Issue #25507: IDLE no longer runs buggy code because of its tkinter imports. - Users must include the same imports required to run directly in Python. - -- Issue #27173: Add 'IDLE Modern Unix' to the built-in key sets. - Make the default key set depend on the platform. - Add tests for the changes to the config module. - -- Issue #27452: add line counter and crc to IDLE configHandler test dump. - -- Issue #27477: IDLE search dialogs now use ttk widgets. - -- Issue #27173: Add 'IDLE Modern Unix' to the built-in key sets. - Make the default key set depend on the platform. - Add tests for the changes to the config module. - -- Issue #27452: make command line "idle-test> python test_help.py" work. - __file__ is relative when python is started in the file's directory. - -- Issue #27452: add line counter and crc to IDLE configHandler test dump. - -- Issue #27380: IDLE: add query.py with base Query dialog and ttk widgets. - Module had subclasses SectionName, ModuleName, and HelpSource, which are - used to get information from users by configdialog and file =>Load Module. - Each subclass has itw own validity checks. Using ModuleName allows users - to edit bad module names instead of starting over. - Add tests and delete the two files combined into the new one. - -- Issue #27372: Test_idle no longer changes the locale. - -- Issue #27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names. - -- Issue #27245: IDLE: Cleanly delete custom themes and key bindings. - Previously, when IDLE was started from a console or by import, a cascade - of warnings was emitted. Patch by Serhiy Storchaka. - -- Issue #24137: Run IDLE, test_idle, and htest with tkinter default root disabled. - Fix code and tests that fail with this restriction. - Fix htests to not create a second and redundant root and mainloop. - -- Issue #27310: Fix IDLE.app failure to launch on OS X due to vestigial import. - -- Issue #5124: Paste with text selected now replaces the selection on X11. - This matches how paste works on Windows, Mac, most modern Linux apps, - and ttk widgets. Original patch by Serhiy Storchaka. - -- Issue #24750: Switch all scrollbars in IDLE to ttk versions. - Where needed, minimal tests are added to cover changes. - -- Issue #24759: IDLE requires tk 8.5 and availability ttk widgets. - Delete now unneeded tk version tests and code for older versions. - Add test for IDLE syntax colorizer. - -- Issue #27239: idlelib.macosx.isXyzTk functions initialize as needed. - -- Issue #27262: move Aqua unbinding code, which enable context menus, to macosx. - -- Issue #24759: Make clear in idlelib.idle_test.__init__ that the directory - is a private implementation of test.test_idle and tool for maintainers. - -- Issue #27196: Stop 'ThemeChanged' warnings when running IDLE tests. - These persisted after other warnings were suppressed in #20567. - Apply Serhiy Storchaka's update_idletasks solution to four test files. - Record this additional advice in idle_test/README.txt - -- Issue #20567: Revise idle_test/README.txt with advice about avoiding - tk warning messages from tests. Apply advice to several IDLE tests. - -- Issue # 24225: Update idlelib/README.txt with new file names - and event handlers. - -- Issue #27156: Remove obsolete code not used by IDLE. Replacements: - 1. help.txt, replaced by help.html, is out-of-date and should not be used. - Its dedicated viewer has be replaced by the html viewer in help.py. - 2. 'import idlever; I = idlever.IDLE_VERSION' is the same as - 'import sys; I = version[:version.index(' ')]' - 3. After 'ob = stackviewer.VariablesTreeItem(*args)', - 'ob.keys()' == 'list(ob.object.keys). - 4. In macosc, runningAsOSXAPP == isAquaTk; idCarbonAquaTk == isCarbonTk - -- Issue #27117: Make colorizer htest and turtledemo work with dark themes. - Move code for configuring text widget colors to a new function. - -- Issue #24225: Rename many idlelib/*.py and idle_test/test_*.py files. - Edit files to replace old names with new names when the old name - referred to the module rather than the class it contained. - See the issue and IDLE section in What's New in 3.6 for more. - -- Issue #26673: When tk reports font size as 0, change to size 10. - Such fonts on Linux prevented the configuration dialog from opening. - -- Issue #21939: Add test for IDLE's percolator. - Original patch by Saimadhav Heblikar. - -- Issue #21676: Add test for IDLE's replace dialog. - Original patch by Saimadhav Heblikar. - -- Issue #18410: Add test for IDLE's search dialog. - Original patch by Westley Martínez. - -- Issue #21703: Add test for undo delegator. Patch mostly by - Saimadhav Heblikar . - -- Issue #27044: Add ConfigDialog.remove_var_callbacks to stop memory leaks. - -- Issue #23977: Add more asserts to test_delegator. - -- Issue #20640: Add tests for idlelib.configHelpSourceEdit. - Patch by Saimadhav Heblikar. - -- In the 'IDLE-console differences' section of the IDLE doc, clarify - how running with IDLE affects sys.modules and the standard streams. - -- Issue #25507: fix incorrect change in IOBinding that prevented printing. - Augment IOBinding htest to include all major IOBinding functions. - -- Issue #25905: Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION - MARK in README.txt and open this and NEWS.txt with 'ascii'. - Re-encode CREDITS.txt to utf-8 and open it with 'utf-8'. - -- Issue 15348: Stop the debugger engine (normally in a user process) - before closing the debugger window (running in the IDLE process). - This prevents the RuntimeErrors that were being caught and ignored. - -- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the - debugger is active (15347); b) closing the debugger with the [X] button - (15348); and c) activating the debugger when already active (24455). - The patch by Mark Roseman does this by making two changes. - 1. Suspend and resume the gui.interaction method with the tcl vwait - mechanism intended for this purpose (instead of root.mainloop & .quit). - 2. In gui.run, allow any existing interaction to terminate first. - -- Change 'The program' to 'Your program' in an IDLE 'kill program?' message - to make it clearer that the program referred to is the currently running - user program, not IDLE itself. - -- Issue #24750: Improve the appearance of the IDLE editor window status bar. - Patch by Mark Roseman. - -- Issue #25313: Change the handling of new built-in text color themes to better - address the compatibility problem introduced by the addition of IDLE Dark. - Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. - -- Issue #24782: Extension configuration is now a tab in the IDLE Preferences - dialog rather than a separate dialog. The former tabs are now a sorted - list. Patch by Mark Roseman. - -- Issue #22726: Re-activate the config dialog help button with some content - about the other buttons and the new IDLE Dark theme. - -- Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. - It is more or less IDLE Classic inverted, with a cobalt blue background. - Strings, comments, keywords, ... are still green, red, orange, ... . - To use it with IDLEs released before November 2015, hit the - 'Save as New Custom Theme' button and enter a new name, - such as 'Custom Dark'. The custom theme will work with any IDLE - release, and can be modified. - -- Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc chapter. - 'IDLE' now means 'Integrated Development and Learning Environment'. - -- Issue #24820: Users can now set breakpoint colors in - Settings -> Custom Highlighting. Original patch by Mark Roseman. - -- Issue #24972: Inactive selection background now matches active selection - background, as configured by users, on all systems. Found items are now - always highlighted on Windows. Initial patch by Mark Roseman. - -- Issue #24570: Idle: make calltip and completion boxes appear on Macs - affected by a tk regression. Initial patch by Mark Roseman. - -- Issue #24988: Idle ScrolledList context menus (used in debugger) - now work on Mac Aqua. Patch by Mark Roseman. - -- Issue #24801: Make right-click for context menu work on Mac Aqua. - Patch by Mark Roseman. - -- Issue #25173: Associate tkinter messageboxes with a specific widget. - For Mac OSX, make them a 'sheet'. Patch by Mark Roseman. - -- Issue #25198: Enhance the initial html viewer now used for Idle Help. - * Properly indent fixed-pitch text (patch by Mark Roseman). - * Give code snippet a very Sphinx-like light blueish-gray background. - * Re-use initial width and height set by users for shell and editor. - * When the Table of Contents (TOC) menu is used, put the section header - at the top of the screen. - -- Issue #25225: Condense and rewrite Idle doc section on text colors. - -- Issue #21995: Explain some differences between IDLE and console Python. - -- Issue #22820: Explain need for *print* when running file from Idle editor. - -- Issue #25224: Doc: augment Idle feature list and no-subprocess section. - -- Issue #25219: Update doc for Idle command line options. - Some were missing and notes were not correct. - -- Issue #24861: Most of idlelib is private and subject to change. - Use idleib.idle.* to start Idle. See idlelib.__init__.__doc__. - -- Issue #25199: Idle: add synchronization comments for future maintainers. - -- Issue #16893: Replace help.txt with help.html for Idle doc display. - The new idlelib/help.html is rstripped Doc/build/html/library/idle.html. - It looks better than help.txt and will better document Idle as released. - The tkinter html viewer that works for this file was written by Mark Roseman. - The now unused EditorWindow.HelpDialog class and helt.txt file are deprecated. - -- Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. - -- Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). - - -What's New in IDLE 3.5.0? -========================= -*Release date: 2015-09-13* - -- Issue #23672: Allow Idle to edit and run files with astral chars in name. - Patch by Mohd Sanad Zaki Rizvi. - -- Issue 24745: 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' entries from [Editor Window]. Patch by Mark Roseman. - -- Issue #21192: Idle editor. When a file is run, put its name in the restart bar. - Do not print false prompts. Original patch by Adnan Umer. - -- Issue #13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy. - -- Issue #23184: remove unused names and imports in idlelib. - Initial patch by Al Sweigart. - -- Issue #20577: Configuration of the max line length for the FormatParagraph - extension has been moved from the General tab of the Idle preferences dialog - to the FormatParagraph tab of the Config Extensions dialog. - Patch by Tal Einat. - -- Issue #16893: Update Idle doc chapter to match current Idle and add new - information. - -- Issue #3068: Add Idle extension configuration dialog to Options menu. - Changes are written to HOME/.idlerc/config-extensions.cfg. - Original patch by Tal Einat. - -- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an - editor window with a filename. When Class Browser is requested otherwise, - from a shell, output window, or 'Untitled' editor, Idle no longer displays - an error box. It now pops up an Open Module box (Alt+M). If a valid name - is entered and a module is opened, a corresponding browser is also opened. - -- Issue #4832: Save As to type Python files automatically adds .py to the - name you enter (even if your system does not display it). Some systems - automatically add .txt when type is Text files. - -- Issue #21986: Code objects are not normally pickled by the pickle module. - To match this, they are no longer pickled when running under Idle. - -- Issue #23180: Rename IDLE "Windows" menu item to "Window". - Patch by Al Sweigart. - -- Issue #17390: Adjust Editor window title; remove 'Python', - move version to end. - -- Issue #14105: Idle debugger breakpoints no longer disappear - when inserting or deleting lines. - -- Issue #17172: Turtledemo can now be run from Idle. - Currently, the entry is on the Help menu, but it may move to Run. - Patch by Ramchandra Apt and Lita Cho. - -- Issue #21765: Add support for non-ascii identifiers to HyperParser. - -- Issue #21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav - Heblikar. - -- Issue #18592: Add unittest for SearchDialogBase. Patch by Phil Webster. - -- Issue #21694: Add unittest for ParenMatch. Patch by Saimadhav Heblikar. - -- Issue #21686: add unittest for HyperParser. Original patch by Saimadhav - Heblikar. - -- Issue #12387: Add missing upper(lower)case versions of default Windows key - bindings for Idle so Caps Lock does not disable them. Patch by Roger Serwy. - -- Issue #21695: Closing a Find-in-files output window while the search is - still in progress no longer closes Idle. - -- Issue #18910: Add unittest for textView. Patch by Phil Webster. - -- Issue #18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar. - -- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster. - -- Issue #21477: htest.py - Improve framework, complete set of tests. - Patches by Saimadhav Heblikar - -- Issue #18104: Add idlelib/idle_test/htest.py with a few sample tests to begin - consolidating and improving human-validated tests of Idle. Change other files - as needed to work with htest. Running the module as __main__ runs all tests. - -- Issue #21139: Change default paragraph width to 72, the PEP 8 recommendation. - -- Issue #21284: Paragraph reformat test passes after user changes reformat width. - -- Issue #17654: Ensure IDLE menus are customized properly on OS X for - non-framework builds and for all variants of Tk. - - -What's New in IDLE 3.4.0? -========================= -*Release date: 2014-03-16* - -- Issue #17390: Display Python version on Idle title bar. - Initial patch by Edmond Burnett. - -- Issue #5066: Update IDLE docs. Patch by Todd Rovito. - -- Issue #17625: Close the replace dialog after it is used. - -- Issue #16226: Fix IDLE Path Browser crash. - (Patch by Roger Serwy) - -- Issue #15853: Prevent IDLE crash on OS X when opening Preferences menu - with certain versions of Tk 8.5. Initial patch by Kevin Walzer. - - -What's New in IDLE 3.3.0? -========================= -*Release date: 2012-09-29* - -- Issue #17625: Close the replace dialog after it is used. - -- Issue #7163: Propagate return value of sys.stdout.write. - -- Issue #15318: Prevent writing to sys.stdin. - -- Issue #4832: Modify IDLE to save files with .py extension by - default on Windows and OS X (Tk 8.5) as it already does with X11 Tk. - -- Issue #13532, #15319: Check that arguments to sys.stdout.write are strings. - -- Issue # 12510: Attempt to get certain tool tips no longer crashes IDLE. - Erroneous tool tips have been corrected. Default added for callables. - -- Issue #10365: File open dialog now works instead of crashing even when - parent window is closed while dialog is open. - -- Issue 14876: use user-selected font for highlight configuration. - -- Issue #14937: Perform auto-completion of filenames in strings even for - non-ASCII filenames. Likewise for identifiers. - -- Issue #8515: Set __file__ when run file in IDLE. - Initial patch by Bruce Frederiksen. - -- IDLE can be launched as `python -m idlelib` - -- Issue #14409: IDLE now properly executes commands in the Shell window - when it cannot read the normal config files on startup and - has to use the built-in default key bindings. - There was previously a bug in one of the defaults. - -- Issue #3573: IDLE hangs when passing invalid command line args - (directory(ies) instead of file(s)). - -- Issue #14018: Update checks for unstable system Tcl/Tk versions on OS X - to include versions shipped with OS X 10.7 and 10.8 in addition to 10.6. - - -What's New in IDLE 3.2.1? -========================= -*Release date: 15-May-11* - -- Issue #6378: Further adjust idle.bat to start associated Python - -- Issue #11896: Save on Close failed despite selecting "Yes" in dialog. - -- Issue #1028: Ctrl-space binding to show completions was causing IDLE to exit. - Tk < 8.5 was sending invalid Unicode null; replaced with valid null. - -- Issue #4676: toggle failing on Tk 8.5, causing IDLE exits and strange selection - behavior. Improve selection extension behaviour. - -- Issue #3851: toggle non-functional when NumLock set on Windows. - - -What's New in IDLE 3.1b1? -========================= -*Release date: 06-May-09* - -- Issue #5707: Use of 'filter' in keybindingDialog.py was causing custom key assignment to - fail. Patch by Amaury Forgeot d'Arc. - -- Issue #4815: Offer conversion to UTF-8 if source files have - no encoding declaration and are not encoded in UTF-8. - -- Issue #4008: Fix problems with non-ASCII source files. - -- Issue #4323: Always encode source as UTF-8 without asking - the user (unless a different encoding is declared); remove - user configuration of source encoding; all according to - PEP 3120. - -- Issue #2665: On Windows, an IDLE installation upgraded from an old version - would not start if a custom theme was defined. - ------------------------------------------------------------------------- -Refer to NEWS2x.txt and HISTORY.txt for information on earlier releases. ------------------------------------------------------------------------- diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt new file mode 100644 index 00000000000000..4fba4165fddab5 --- /dev/null +++ b/Lib/idlelib/News3.txt @@ -0,0 +1,1352 @@ +What's New in IDLE 3.13.0 +(since 3.12.0) +Released on 2024-10-xx +========================= + + +gh-112939: Fix processing unsaved files when quitting IDLE on macOS. +Patch by Ronald Oussoren and Christopher Chavez. + +gh-79871: Add docstrings to debugger.py. Fix two bugs in +test_debugger and expand coverage by 47%. Patch by Anthony Shaw. + + +What's New in IDLE 3.12.0 +(since 3.11.0) +Released on 2023-10-02 +========================= + +gh-104719: Remove IDLE's modification of tokenize.tabsize and test +other uses of tokenize data and methods. + +gh-104499: Fix completions for Tk Aqua 8.7 (currently blank). + +gh-104486: Make About print both tcl and tk versions if different, +as is expected someday. + +gh-88496 Fix IDLE test hang on macOS. + +gh-103314 Support sys.last_exc after exceptions in Shell. +Patch by Irit Katriel. + + +What's New in IDLE 3.11.0 +(since 3.10.0) +Released on 2022-10-24 +========================= + +gh-97527: Fix a bug in the previous bugfix that caused IDLE to not +start when run with 3.10.8, 3.12.0a1, and at least Microsoft Python +3.10.2288.0 installed without the Lib/test package. 3.11.0 was never +affected. + +gh-65802: Document handling of extensions in Save As dialogs. + +gh-95191: Include prompts when saving Shell (interactive input/output). + +gh-95511: Fix the Shell context menu copy-with-prompts bug of copying +an extra line when one selects whole lines. + +gh-95471: Tweak Edit menu. Move 'Select All' above 'Cut' as it is used +with 'Cut' and 'Copy' but not 'Paste'. Add a separator between 'Replace' +and 'Go to Line' to help IDLE issue triagers. + +gh-95411: Enable using IDLE's module browser with .pyw files. + +gh-89610: Add .pyi as a recognized extension for IDLE on macOS. This allows +opening stub files by double clicking on them in the Finder. + +bpo-28950: Apply IDLE syntax highlighting to `.pyi` files. Add util.py +for common components. Patch by Alex Waygood and Terry Jan Reedy. + +bpo-46630: Make query dialogs on Windows start with a cursor in the +entry box. + +bpo-46591: Make the IDLE doc URL on the About IDLE dialog clickable. + +bpo-45296: Clarify close, quit, and exit in IDLE. In the File menu, +'Close' and 'Exit' are now 'Close Window' (the current one) and 'Exit' +is now 'Exit IDLE' (by closing all windows). In Shell, 'quit()' and +'exit()' mean 'close Shell'. If there are no other windows, +this also exits IDLE. + +bpo-45495: Add context keywords 'case' and 'match' to completions list. + +bpo-45296: On Windows, change exit/quit message to suggest Ctrl-D, which +works, instead of , which does not work in IDLE. + + +What's New in IDLE 3.10.0 +(since 3.9.0) +Released on 2021-10-04 +========================= + +bpo-45193: Make completion boxes appear on Ubuntu again. + +bpo-40128: Mostly fix completions on macOS when not using tcl/tk 8.6.11 +(as with 3.9). + +bpo-33962: Move the indent space setting from the Font tab to the new Windows +tab. Patch by Mark Roseman and Terry Jan Reedy. + +bpo-40468: Split the settings dialog General tab into Windows and Shell/Ed +tabs. Move help sources, which extend the Help menu, to the Extensions tab. +Make space for new options and shorten the dialog. The latter makes the +dialog better fit small screens. + +bpo-44010: Highlight the new match statement's soft keywords: match, case, +and _. This highlighting is not perfect and will be incorrect in some rare +cases, especially for some _s in case patterns. + +bpo-44026: Include interpreter's typo fix suggestions in message line +for NameErrors and AttributeErrors. Patch by E. Paine. + +bpo-41611: Avoid occasional uncaught exceptions and freezing when using +completions on macOS. + +bpo-37903: Add mouse actions to the shell sidebar. Left click and +optional drag selects one or more lines of text, as with the +editor line number sidebar. Right click after selecting text lines +displays a context menu with 'copy with prompts'. This zips together +prompts from the sidebar with lines from the selected text. This option +also appears on the context menu for the text. + +bpo-43981: Fix reference leaks in test_sidebar and test_squeezer. +Patches by Terry Jan Reedy and Pablo Galindo + +bpo-37892: Change Shell input indents from tabs to spaces. Shell input +now 'looks right'. Making this feasible motivated the shell sidebar. + +bpo-37903: Move the Shell input prompt to a side bar. + +bpo-43655: Make window managers on macOS and X Window recognize +IDLE dialog windows as dialogs. + +bpo-42225: Document that IDLE can fail on Unix either from misconfigured IP +masquerade rules or failure displaying complex colored (non-ascii) characters. + +bpo-43283: Document why printing to IDLE's Shell is often slower than +printing to a system terminal and that it can be made faster by +pre-formatting a single string before printing. + +bpo-23544: Disable Debug=>Stack Viewer when user code is running or +Debugger is active, to prevent hang or crash. Patch by Zackery Spytz. + +bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal, +2-process mode. User hooks were previously ignored. +Patch by Ken Hilton. + +bpo-33065: Fix problem debugging user classes with __repr__ method. + +bpo-32631: Finish zzdummy example extension module: make menu entries +work; add docstrings and tests with 100% coverage. + +bpo-42508: Keep IDLE running on macOS. Remove obsolete workaround +that prevented running files with shortcuts when using new universal2 +installers built on macOS 11. + +bpo-42426: Fix reporting offset of the RE error in searchengine. + +bpo-42416: Display docstrings in IDLE calltips in more cases, +by using inspect.getdoc. + +bpo-33987: Mostly finish using ttk widgets, mainly for editor, +settings, and searches. Some patches by Mark Roseman. + +bpo-40511: Stop unnecessary "flashing" when typing opening and closing +parentheses inside the parentheses of a function call. + +bpo-38439: Add a 256x256 pixel IDLE icon to the Windows .ico file. Created by +Andrew Clover. Remove the low-color gif variations from the .ico file. + +bpo-41775: Make 'IDLE Shell' the shell title. + +bpo-35764: Rewrite the Calltips doc section. + +bpo-40181: In calltips, stop reminding that '/' marks the end of +positional-only arguments. + + +What's New in IDLE 3.9.0 (since 3.8.0) +Released on 2020-10-05? +====================================== + +bpo-41468: Improve IDLE run crash error message (which users should +never see). + +bpo-41373: Save files loaded with no line ending, as when blank, or +different line endings, by setting its line ending to the system +default. Fix regression in 3.8.4 and 3.9.0b4. + +bpo-41300: Save files with non-ascii chars. Fix regression in +3.9.0b4 and 3.8.4. + +bpo-37765: Add keywords to module name completion list. Rewrite +Completions section of IDLE doc. + +bpo-41152: The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE +is now always UTF-8. + +bpo-41144: Make Open Module open a special module such as os.path. + +bpo-40723: Make test_idle pass when run after import. +Patch by Florian Dahlitz. + +bpo-38689: IDLE will no longer freeze when inspect.signature fails +when fetching a calltip. + +bpo-27115: For 'Go to Line', use a Query entry box subclass with +IDLE standard behavior and improved error checking. + +bpo-39885: When a context menu is invoked by right-clicking outside +of a selection, clear the selection and move the cursor. Cut and +Copy require that the click be within the selection. + +bpo-39852: Edit "Go to line" now clears any selection, preventing +accidental deletion. It also updates Ln and Col on the status bar. + +bpo-39781: Selecting code context lines no longer causes a jump. + +bpo-39663: Add tests for pyparse find_good_parse_start(). + +bpo-39600: Remove duplicate font names from configuration list. + +bpo-38792: Close a shell calltip if a :exc:`KeyboardInterrupt` +or shell restart occurs. Patch by Zackery Spytz. + +bpo-30780: Add remaining configdialog tests for buttons and +highlights and keys tabs. + +bpo-39388: Settings dialog Cancel button cancels pending changes. + +bpo-39050: Settings dialog Help button again displays help text. + +bpo-32989: Add tests for editor newline_and_indent_event method. +Remove unneeded arguments and dead code from pyparse +find_good_parse_start method. + +bpo-38943: Fix autocomplete windows not always appearing on some +systems. Patch by Johnny Najera. + +bpo-38944: Escape key now closes IDLE completion windows. Patch by +Johnny Najera. + +bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra +newlines at the end of non-shell files. + +bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These +functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled +in 3.7.5 and 3.8.0. + +bpo-4630: Add an option to toggle IDLE's cursor blink for shell, +editor, and output windows. See Settings, General, Window Preferences, +Cursor Blink. Patch by Zackery Spytz. + +bpo-26353: Stop adding newline when saving an IDLE shell window. + +bpo-38598: Do not try to compile IDLE shell or output windows. + + +What's New in IDLE 3.8.0 (since 3.7.0) +Released on 2019-10-14 +====================================== + +bpo-36698: IDLE no longer fails when writing non-encodable characters +to stderr. It now escapes them with a backslash, like the regular +Python interpreter. Add an errors field to the standard streams. + +bpo-13153: Improve tkinter's handing of non-BMP (astral) unicode +characters, such as 'rocket \U0001f680'. Whether a proper glyph or +replacement char is displayed depends on the OS and font. For IDLE, +astral chars in code interfere with editing. + +bpo-35379: When exiting IDLE, catch any AttributeError. One happens +when EditorWindow.close is called twice. Printing a traceback, when +IDLE is run from a terminal, is useless and annoying. + +bpo-38183: To avoid test issues, test_idle ignores the user config +directory. It no longer tries to create or access .idlerc or any files +within. Users must run IDLE to discover problems with saving settings. + +bpo-38077: IDLE no longer adds 'argv' to the user namespace when +initializing it. This bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. + +bpo-38401: Shell restart lines now fill the window width, always start +with '=', and avoid wrapping unnecessarily. The line will still wrap +if the included file name is long relative to the width. + +bpo-37092: Add mousewheel scrolling for IDLE module, path, and stack +browsers. Patch by George Zhang. + +bpo-35771: To avoid occasional spurious test_idle failures on slower +machines, increase the ``hover_delay`` in test_tooltip. + +bpo-37824: Properly handle user input warnings in IDLE shell. +Cease turning SyntaxWarnings into SyntaxErrors. + +bpo-37929: IDLE Settings dialog now closes properly when there is no +shell window. + +bpo-37849: Fix completions list appearing too high or low when shown +above the current line. + +bpo-36419: Refactor autocompete and improve testing. + +bpo-37748: Reorder the Run menu. Put the most common choice, +Run Module, at the top. + +bpo-37692: Improve highlight config sample with example shell +interaction and better labels for shell elements. + +bpo-37628: Settings dialog no longer expands with font size. +The font and highlight sample boxes gain scrollbars instead. + +bpo-17535: Add optional line numbers for IDLE editor windows. + +bpo-37627: Initialize the Customize Run dialog with the command line +arguments most recently entered before. The user can optionally edit +before submitting them. + +bpo-33610: Code context always shows the correct context when toggled on. + +bpo-36390: Gather Format menu functions into format.py. Combine +paragraph.py, rstrip.py, and format methods from editor.py. + +bpo-37530: Optimize code context to reduce unneeded background activity. +Font and highlight changes now occur along with text changes instead +of after a random delay. + +bpo-27452: Cleanup config.py by inlining RemoveFile and simplifying +the handling of __file__ in CreateConfigHandlers/ + +bpo-26806: To compensate for stack frames added by IDLE and avoid +possible problems with low recursion limits, add 30 to limits in the +user code execution process. Subtract 30 when reporting recursion +limits to make this addition mostly transparent. + +bpo-37325: Fix tab focus traversal order for help source and custom +run dialogs. + +bpo-37321: Both subprocess connection error messages now refer to +the 'Startup failure' section of the IDLE doc. + +bpo-37177: Properly attach search dialogs to their main window so +that they behave like other dialogs and do not get hidden behind +their main window. + +bpo-37039: Adjust "Zoom Height" to individual screens by momentarily +maximizing the window on first use with a particular screen. Changing +screen settings may invalidate the saved height. While a window is +maximized, "Zoom Height" has no effect. + +bpo-35763: Make calltip reminder about '/' meaning positional-only less +obtrusive by only adding it when there is room on the first line. + +bpo-5680: Add 'Run Customized' to the Run menu to run a module with +customized settings. Any command line arguments entered are added +to sys.argv. One can suppress the normal Shell main module restart. + +bpo-35610: Replace now redundant editor.context_use_ps1 with +.prompt_last_line. This finishes change started in bpo-31858. + +bpo-32411: Stop sorting dict created with desired line order. + +bpo-37038: Make idlelib.run runnable; add test clause. + +bpo-36958: Print any argument other than None or int passed to +SystemExit or sys.exit(). + +bpo-36807: When saving a file, call file.flush() and os.fsync() +so bits are flushed to e.g. a USB drive. + +bpo-36429: Fix starting IDLE with pyshell. +Add idlelib.pyshell alias at top; remove pyshell alias at bottom. +Remove obsolete __name__=='__main__' command. + +bpo-30348: Increase test coverage of idlelib.autocomplete by 30%. +Patch by Louie Lu. + +bpo-23205: Add tests and refactor grep's findfiles. + +bpo-36405: Use dict unpacking in idlelib. + +bpo-36396: Remove fgBg param of idlelib.config.GetHighlight(). +This param was only used twice and changed the return type. + +bpo-23216: IDLE: Add docstrings to search modules. + +bpo-36176: Fix IDLE autocomplete & calltip popup colors. +Prevent conflicts with Linux dark themes +(and slightly darken calltip background). + +bpo-36152: Remove colorizer.ColorDelegator.close_when_done and the +corresponding argument of .close(). In IDLE, both have always been +None or False since 2007. + +bpo-36096: Make colorizer state variables instance-only. + +bpo-32129: Avoid blurry IDLE application icon on macOS with Tk 8.6. +Patch by Kevin Walzer. + +bpo-24310: Document settings dialog font tab sample. + +bpo-35689: Add docstrings and tests for colorizer. + +bpo-35833: Revise IDLE doc for control codes sent to Shell. +Add a code example block. + +bpo-35770: IDLE macosx deletes Options => Configure IDLE. +It previously deleted Window => Zoom Height by mistake. +(Zoom Height is now on the Options menu). On Mac, the settings +dialog is accessed via Preferences on the IDLE menu. + +bpo-35769: Change new file name from 'Untitled' to 'untitled'. + +bpo-35660: Fix imports in window module. + +bpo-35641: Properly format calltip for function without docstring. + +bpo-33987: Use ttk Frame for ttk widgets. + +bpo-34055: Fix erroneous 'smart' indents and newlines in IDLE Shell. + +bpo-28097: Add Previous/Next History entries to Shell menu. + +bpo-35591: Find Selection now works when selection not found. + +bpo-35598: Update config_key: use PEP 8 names and ttk widgets, +make some objects global, and add tests. + +bpo-35196: Speed up squeezer line counting. + +bpo-35208: Squeezer now counts wrapped lines before newlines. + +bpo-35555: Gray out Code Context menu entry when it's not applicable. + +bpo-22703: Improve the Code Context and Zoom Height menu labels. +The Code Context menu label now toggles between Show/Hide Code Context. +The Zoom Height menu now toggles between Zoom/Restore Height. +Zoom Height has moved from the Window menu to the Options menu. + +bpo-35521: Document the editor code context feature. +Add some internal references within the IDLE doc. + +bpo-34864: When starting IDLE on MacOS, warn if the system setting +"Prefer tabs when opening documents" is "Always". As previous +documented for this issue, running IDLE with this setting causes +problems. If the setting is changed while IDLE is running, +there will be no warning until IDLE is restarted. + +bpo-35213: Where appropriate, use 'macOS' in idlelib. + +bpo-34864: Document two IDLE on MacOS issues. The System Preferences +Dock "prefer tabs always" setting disables some IDLE features. +Menus are a bit different than as described for Windows and Linux. + +bpo-35202: Remove unused imports in idlelib. + +bpo-33000: Document that IDLE's shell has no line limit. +A program that runs indefinitely can overfill memory. + +bpo-23220: Explain how IDLE's Shell displays output. +Add new subsection "User output in Shell". + +bpo-35099: Improve the doc about IDLE running user code. +"IDLE -- console differences" is renamed "Running user code". +It mostly covers the implications of using custom sys.stdxxx objects. + +bpo-35097: Add IDLE doc subsection explaining editor windows. +Topics include opening, title and status bars, .py* extension, and running. + +Issue 35093: Document the IDLE document viewer in the IDLE doc. +Add a paragraph in "Help and preferences", "Help sources" subsection. + +bpo-1529353: Explain Shell text squeezing in the IDLE doc. + +bpo-35088: Update idlelib.help.copy_string docstring. +We now use git and backporting instead of hg and forward merging. + +bpo-35087: Update idlelib help files for the current doc build. +The main change is the elimination of chapter-section numbers. + +bpo-1529353: Output over N lines (50 by default) is squeezed down to a button. +N can be changed in the PyShell section of the General page of the +Settings dialog. Fewer, but possibly extra long, lines can be squeezed by +right clicking on the output. Squeezed output can be expanded in place +by double-clicking the button or into the clipboard or a separate window +by right-clicking the button. + +bpo-34548: Use configured color theme for read-only text views. + +bpo-33839: Refactor ToolTip and CallTip classes; add documentation +and tests. + +bpo-34047: Fix mouse wheel scrolling direction on macOS. + +bpo-34275: Make calltips always visible on Mac. +Patch by Kevin Walzer. + +bpo-34120: Fix freezing after closing some dialogs on Mac. +This is one of multiple regressions from using newer tcl/tk. + +bpo-33975: Avoid small type when running htests. +Since part of the purpose of human-viewed tests is to determine that +widgets look right, it is important that they look the same for +testing as when running IDLE. + +bpo-33905: Add test for idlelib.stackview.StackBrowser. + +bpo-33924: Change mainmenu.menudefs key 'windows' to 'window'. +Every other menudef key is the lowercase version of the +corresponding main menu entry (in this case, 'Window'). + +bpo-33906: Rename idlelib.windows as window +Match Window on the main menu and remove last plural module name. +Change imports, test, and attribute references to match new name. + +bpo-33917: Fix and document idlelib/idle_test/template.py. +The revised file compiles, runs, and tests OK. idle_test/README.txt +explains how to use it to create new IDLE test files. + +bpo-33904: In rstrip module, rename class RstripExtension as Rstrip. + +bpo-33907: For consistency and clarity, rename calltip objects. +Module calltips and its class CallTips are now calltip and Calltip. +In module calltip_w, class CallTip is now CalltipWindow. + +bpo-33855: Minimally test all IDLE modules. +Standardize the test file format. Add missing test files that import +the tested module and perform at least one test. Check and record the +coverage of each test. + +bpo-33856: Add 'help' to Shell's initial welcome message. + + +What's New in IDLE 3.7.0 (since 3.6.0) +Released on 2018-06-27 +====================================== + +bpo-33656: On Windows, add API call saying that tk scales for DPI. +On Windows 8.1+ or 10, with DPI compatibility properties of the Python +binary unchanged, and a monitor resolution greater than 96 DPI, this +should make text and lines sharper and some colors brighter. +On other systems, it should have no effect. If you have a custom theme, +you may want to adjust a color or two. If perchance it make text worse +on your monitor, you can disable the ctypes.OleDLL call near the top of +pyshell.py and report the problem on python-list or idle-dev@python.org. + +bpo-33768: Clicking on a context line moves that line to the top +of the editor window. + +bpo-33763: Replace the code context label widget with a text widget. + +bpo-33664: Scroll IDLE editor text by lines. +(Previously, the mouse wheel and scrollbar slider moved text by a fixed +number of pixels, resulting in partial lines at the top of the editor +box.) This change also applies to the shell and grep output windows, +but currently not to read-only text views. + +bpo-33679: Enable theme-specific color configuration for Code Context. +(Previously, there was one code context foreground and background font +color setting, default or custom, on the extensions tab, that applied +to all themes.) For built-in themes, the foreground is the same as +normal text and the background is a contrasting gray. Context colors for +custom themes are set on the Hightlights tab along with other colors. +When one starts IDLE from a console and loads a custom theme without +definitions for 'context', one will see a warning message on the +console. + +bpo-33642: Display up to maxlines non-blank lines for Code Context. +If there is no current context, show a single blank line. (Previously, +the Code Contex had numlines lines, usually with some blank.) The use +of a new option, 'maxlines' (default 15), avoids possible interference +with user settings of the old option, 'numlines' (default 3). + +bpo-33628: Cleanup codecontext.py and its test. + +bpo-32831: Add docstrings and tests for codecontext.py. +Coverage is 100%. Patch by Cheryl Sabella. + +bpo-33564: Code context now recognizes async as a block opener. + +bpo-21474: Update word/identifier definition from ascii to unicode. +In text and entry boxes, this affects selection by double-click, +movement left/right by control-left/right, and deletion left/right +by control-BACKSPACE/DEL. + +bpo-33204: Consistently color invalid string prefixes. +A 'u' string prefix cannot be paired with either 'r' or 'f'. +IDLE now consistently colors as much of the prefix, starting at the +right, as is valid. Revise and extend colorizer test. + +bpo-32984: Set __file__ while running a startup file. +Like Python, IDLE optionally runs 1 startup file in the Shell window +before presenting the first interactive input prompt. For IDLE, +option -s runs a file named in environmental variable IDLESTARTUP or +PYTHONSTARTUP; -r file runs file. Python sets __file__ to the startup +file name before running the file and unsets it before the first +prompt. IDLE now does the same when run normally, without the -n +option. + +bpo-32940: Replace StringTranslatePseudoMapping with faster code. + +bpo-32916: Change 'str' to 'code' in idlelib.pyparse and users. + +bpo-32905: Remove unused code in pyparse module. + +bpo-32874: IDLE - add pyparse tests with 97% coverage. + +bpo-32837: IDLE - require encoding argument for textview.view_file. +Using the system and place-dependent default encoding for open() +is a bad idea for IDLE's system and location-independent files. + +bpo-32826: Add "encoding=utf-8" to open() in IDLE's test_help_about. +GUI test test_file_buttons() only looks at initial ascii-only lines, +but failed on systems where open() defaults to 'ascii' because +readline() internally reads and decodes far enough ahead to encounter +a non-ascii character in CREDITS.txt. + +bpo-32765: Update configdialog General tab create page docstring. +Add new widgets to the widget list. + +bpo-32207: Improve tk event exception tracebacks in IDLE. +When tk event handling is driven by IDLE's run loop, a confusing +and distracting queue.EMPTY traceback context is no longer added +to tk event exception tracebacks. The traceback is now the same +as when event handling is driven by user code. Patch based on +a suggestion by Serhiy Storchaka. + +bpo-32164: Delete unused file idlelib/tabbedpages.py. +Use of TabbedPageSet in configdialog was replaced by ttk.Notebook. + +bpo-32100: Fix old and new bugs in pathbrowser; improve tests. +Patch mostly by Cheryl Sabella. + +bpo-31860: The font sample in the settings dialog is now editable. +Edits persist while IDLE remains open. +Patch by Serhiy Storchake and Terry Jan Reedy. + +bpo-31858: Restrict shell prompt manipulation to the shell. +Editor and output windows only see an empty last prompt line. This +simplifies the code and fixes a minor bug when newline is inserted. +Sys.ps1, if present, is read on Shell start-up, but is not set or changed. +Patch by Terry Jan Reedy. + +bpo-28603: Fix a TypeError that caused a shell restart when printing +a traceback that includes an exception that is unhashable. +Patch by Zane Bitter. + +bpo-13802: Use non-Latin characters in the Font settings sample. +Even if one selects a font that defines a limited subset of the unicode +Basic Multilingual Plane, tcl/tk will use other fonts that define a +character. The expanded example give users of non-Latin characters +a better idea of what they might see in the shell and editors. + +To make room for the expanded sample, frames on the Font tab are +re-arranged. The Font/Tabs help explains a bit about the additions. +Patch by Terry Jan Reedy + +bpo-31460: Simplify the API of IDLE's Module Browser. +Passing a widget instead of an flist with a root widget opens the +option of creating a browser frame that is only part of a window. +Passing a full file name instead of pieces assumed to come from a +.py file opens the possibility of browsing python files that do not +end in .py. + +bpo-31649: Make _htest and _utest parameters keyword-only. +These are used to adjust code for human and unit tests. + +bpo-31459: Rename module browser from Class Browser to Module Browser. +The original module-level class and method browser became a module +browser, with the addition of module-level functions, years ago. +Nested classes and functions were added yesterday. For back- +compatibility, the virtual event <>, which +appears on the Keys tab of the Settings dialog, is not changed. +Patch by Cheryl Sabella. + +bpo-1612262: Module browser now shows nested classes and functions. +Original patches for code and tests by Guilherme Polo and +Cheryl Sabella, respectively. Revisions by Terry Jan Reedy. + +bpo-31500: Tk's default fonts now are scaled on HiDPI displays. +This affects all dialogs. Patch by Serhiy Storchaka. + +bpo-31493: Fix code context update and font update timers. +Canceling timers prevents a warning message when test_idle completes. + +bpo-31488: Update non-key options in former extension classes. +When applying configdialog changes, call .reload for each feature class. +Change ParenMatch so updated options affect existing instances attached +to existing editor windows. + +bpo-31477: Improve rstrip entry in IDLE doc. +Strip Trailing Whitespace strips more than blank spaces. +Multiline string literals are not skipped. + +bpo-31480: fix tests to pass with zzdummy extension disabled. (#3590) +To see the example in action, enable it on options extensions tab. + +bpo-31421: Document how IDLE runs tkinter programs. +IDLE calls tcl/tk update in the background in order to make live +interaction and experimentation with tkinter applications much easier. + +bpo-31414: Fix tk entry box tests by deleting first. +Adding to an int entry is not the same as deleting and inserting +because int('') will fail. Patch by Terry Jan Reedy. + +bpo-27099: Convert IDLE's built-in 'extensions' to regular features. + About 10 IDLE features were implemented as supposedly optional +extensions. Their different behavior could be confusing or worse for +users and not good for maintenance. Hence the conversion. + The main difference for users is that user configurable key bindings +for builtin features are now handled uniformly. Now, editing a binding +in a keyset only affects its value in the keyset. All bindings are +defined together in the system-specific default keysets in config- +extensions.def. All custom keysets are saved as a whole in config- +extension.cfg. All take effect as soon as one clicks Apply or Ok. + The affected events are '<>', +'<>', '<>', '<>', +'<>', '<>', '<>', and +'<>'. Any (global) customizations made before 3.6.3 will +not affect their keyset-specific customization after 3.6.3. and vice +versa. + Initial patch by Charles Wohlganger, revised by Terry Jan Reedy. + +bpo-31051: Rearrange condigdialog General tab. +Sort non-Help options into Window (Shell+Editor) and Editor (only). +Leave room for the addition of new options. +Patch by Terry Jan Reedy. + +bpo-30617: Add docstrings and tests for outwin subclass of editor. +Move some data and functions from the class to module level. +Patch by Cheryl Sabella. + +bpo-31287: Do not modify tkinter.messagebox in test_configdialog. +Instead, mask it with an instance mock that can be deleted. +Patch by Terry Jan Reedy. + +bpo-30781: Use ttk widgets in ConfigDialog pages. +These should especially look better on MacOSX. +Patches by Terry Jan Reedy and Cheryl Sabella. + +bpo-31206: Factor HighPage(Frame) class from ConfigDialog. +Patch by Cheryl Sabella. + +bp0-31001: Add tests for configdialog highlight tab. +Patch by Cheryl Sabella. + +bpo-31205: Factor KeysPage(Frame) class from ConfigDialog. +The slightly modified tests continue to pass. +Patch by Cheryl Sabella. + +bpo-31002: Add tests for configdialog keys tab. +Patch by Cheryl Sabella. + +bpo-19903: Change calltipes to use inspect.signature. +Idlelib.calltips.get_argspec now uses inspect.signature instead of +inspect.getfullargspec, like help() does. This improves the signature +in the call tip in a few different cases, including builtins converted +to provide a signature. A message is added if the object is not +callable, has an invalid signature, or if it has positional-only +parameters. Patch by Louie Lu. + +bop-31083: Add an outline of a TabPage class in configdialog. +Add template as comment. Update existing classes to match outline. +Initial patch by Cheryl Sabella. + +bpo-31050: Factor GenPage(Frame) class from ConfigDialog. +The slightly modified tests for the General tab continue to pass. +Patch by Cheryl Sabella. + +bpo-31004: Factor FontPage(Frame) class from ConfigDialog. +The slightly modified tests continue to pass. The General test +broken by the switch to ttk.Notebook is fixed. +Patch mostly by Cheryl Sabella. + +bpo-30781: IDLE - Use ttk Notebook in ConfigDialog. +This improves navigation by tabbing. +Patch by Terry Jan Reedy. + +bpo-31060: IDLE - Finish rearranging methods of ConfigDialog. +Grouping methods pertaining to each tab and the buttons will aid +writing tests and improving the tabs and will enable splitting the +groups into classes. +Patch by Terry Jan Reedy. + +bpo-30853: IDLE -- Factor a VarTrace class out of ConfigDialog. +Instance tracers manages pairs consisting of a tk variable and a +callback function. When tracing is turned on, setting the variable +calls the function. Test coverage for the new class is 100%. +Patch by Terry Jan Reedy. + +bpo-31003: IDLE: Add more tests for General tab. +Patch by Terry Jan Reedy. + +bpo-30993: IDLE - Improve configdialog font page and tests. +*In configdialog: Document causal pathways in create_font_tab +docstring. Simplify some attribute names. Move set_samples calls to +var_changed_font (idea from Cheryl Sabella). Move related functions to +positions after the create widgets function. +* In test_configdialog: Fix test_font_set so not order dependent. Fix +renamed test_indent_scale so it tests the widget. Adjust tests for +movement of set_samples call. Add tests for load functions. Put all +font tests in one class and tab indent tests in another. Except for +two lines, these tests completely cover the related functions. +Patch by Terry Jan Reedy. + +bpo-30981: IDLE -- Add more configdialog font page tests. + +bpo-28523: IDLE: replace 'colour' with 'color' in configdialog. + +bpo-30917: Add tests for idlelib.config.IdleConf. +Increase coverage from 46% to 96%. +Patch by Louie Lu. + +bpo-30913: Document ConfigDialog tk Vars, methods, and widgets in docstrings +This will facilitate improving the dialog and splitting up the class. +Original patch by Cheryl Sabella. + +bpo-30899: Add tests for ConfigParser subclasses in config. +Coverage is 100% for those classes and ConfigChanges. +Patch by Louie Lu. + +bpo-30881: Add docstrings to browser.py. +Patch by Cheryl Sabella. + +bpo-30851: Remove unused tk variables in configdialog. +One is a duplicate, one is set but cannot be altered by users. +Patch by Cheryl Sabella. + +bpo-30870: Select font option with Up and Down keys, as well as with mouse. +Added test increases configdialog coverage to 60% +Patches mostly by Louie Lu. + +bpo-8231: Call config.IdleConf.GetUserCfgDir only once per process. + +bpo-30779: Factor ConfigChanges class from configdialog, put in config; test. +* In config, put dump test code in a function; run it and unittest in + 'if __name__ == '__main__'. +* Add class config.ConfigChanges based on changes_class_v4.py on bpo issue. +* Add class test_config.ChangesTest, partly using configdialog_tests_v1.py. +* Revise configdialog to use ConfigChanges; see tracker msg297804. +* Revise test_configdialog to match configdialog changes. +* Remove configdialog functions unused or moved to ConfigChanges. +Cheryl Sabella contributed parts of the patch. + +bpo-30777: Configdialog - add docstrings and improve comments. +Patch by Cheryl Sabella. + +bpo-30495: Improve textview with docstrings, PEP8 names, and more tests. +Split TextViewer class into ViewWindow, ViewFrame, and TextFrame classes +so that instances of the latter two can be placed with other widgets +within a multiframe window. +Patches by Cheryl Sabella and Terry Jan Reedy. + +bpo-30723: Make several improvements to parenmatch. +* Add 'parens' style to highlight both opener and closer. +* Make 'default' style, which is not default, a synonym for 'opener'. +* Make time-delay work the same with all styles. +* Add help for config dialog extensions tab, including parenmatch. +* Add new tests. +Original patch by Charles Wohlganger. Revisions by Terry Jan Reedy + +bpo-30674: Grep -- Add docstrings. Patch by Cheryl Sabella. + +bpo-21519: IDLE's basic custom key entry dialog now detects +duplicates properly. Original patch by Saimadhav Heblikar. + +bpo-29910: IDLE no longer deletes a character after commenting out a +region by a key shortcut. Add "return 'break'" for this and other +potential conflicts between IDLE and default key bindings. +Patch by Serhiy Storchaka. + +bpo-30728: Modernize idlelib.configdialog: +* replace import * with specific imports; +* lowercase method and attribute lines. +Patch by Cheryl Sabella. + +bpo-6739: Verify user-entered key sequences by trying to bind them +with to a tk widget. Add tests for all 3 validation functions. +Original patch by G Polo. Tests added by Cheryl Sabella. +Code revised and more tests added by Terry Jan Reedy + +bpo-24813: Add icon to help_about and make other changes. + +bpo-15786: Fix several problems with IDLE's autocompletion box. +The following should now work: clicking on selection box items; +using the scrollbar; selecting an item by hitting Return. +Hangs on MacOSX should no longer happen. Patch by Louie Lu. + +bpo-25514: Add doc subsubsection about IDLE failure to start. +Popup no-connection message directs users to this section. + +bpo-30642: Fix reference leaks in IDLE tests. +Patches by Louie Lu and Terry Jan Reedy. + +bpo-30495: Add docstrings for textview.py and use PEP8 names. +Patches by Cheryl Sabella and Terry Jan Reedy. + +bpo-30290: Help-about: use pep8 names and add tests. +Increase coverage to 100%. +Patches by Louie Lu, Cheryl Sabella, and Terry Jan Reedy. + +bpo-30303: Add _utest option to textview; add new tests. +Increase coverage to 100%. +Patches by Louie Lu and Terry Jan Reedy. + +Issue #29071: IDLE colors f-string prefixes but not invalid ur prefixes. + +Issue #28572: Add 10% to coverage of IDLE's test_configdialog. +Update and augment description of the configuration system. + + +What's New in IDLE 3.6.0 (since 3.5.0) +Released on 2016-12-23 +====================================== + +- Issue #15308: Add 'interrupt execution' (^C) to Shell menu. + Patch by Roger Serwy, updated by Bayard Randel. + +- Issue #27922: Stop IDLE tests from 'flashing' gui widgets on the screen. + +- Issue #27891: Consistently group and sort imports within idlelib modules. + +- Issue #17642: add larger font sizes for classroom projection. + +- Add version to title of IDLE help window. + +- Issue #25564: In section on IDLE -- console differences, mention that + using exec means that __builtins__ is defined for each statement. + +- Issue #27821: Fix 3.6.0a3 regression that prevented custom key sets + from being selected when no custom theme was defined. + +- Issue #27714: text_textview and test_autocomplete now pass when re-run + in the same process. This occurs when test_idle fails when run with the + -w option but without -jn. Fix warning from test_config. + +- Issue #27621: Put query response validation error messages in the query + box itself instead of in a separate messagebox. Redo tests to match. + Add Mac OSX refinements. Original patch by Mark Roseman. + +- Issue #27620: Escape key now closes Query box as cancelled. + +- Issue #27609: IDLE: tab after initial whitespace should tab, not + autocomplete. This fixes problem with writing docstrings at least + twice indented. + +- Issue #27609: Explicitly return None when there are also non-None + returns. In a few cases, reverse a condition and eliminate a return. + +- Issue #25507: IDLE no longer runs buggy code because of its tkinter imports. + Users must include the same imports required to run directly in Python. + +- Issue #27173: Add 'IDLE Modern Unix' to the built-in key sets. + Make the default key set depend on the platform. + Add tests for the changes to the config module. + +- Issue #27452: add line counter and crc to IDLE configHandler test dump. + +- Issue #27477: IDLE search dialogs now use ttk widgets. + +- Issue #27173: Add 'IDLE Modern Unix' to the built-in key sets. + Make the default key set depend on the platform. + Add tests for the changes to the config module. + +- Issue #27452: make command line "idle-test> python test_help.py" work. + __file__ is relative when python is started in the file's directory. + +- Issue #27452: add line counter and crc to IDLE configHandler test dump. + +- Issue #27380: IDLE: add query.py with base Query dialog and ttk widgets. + Module had subclasses SectionName, ModuleName, and HelpSource, which are + used to get information from users by configdialog and file =>Load Module. + Each subclass has itw own validity checks. Using ModuleName allows users + to edit bad module names instead of starting over. + Add tests and delete the two files combined into the new one. + +- Issue #27372: Test_idle no longer changes the locale. + +- Issue #27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names. + +- Issue #27245: IDLE: Cleanly delete custom themes and key bindings. + Previously, when IDLE was started from a console or by import, a cascade + of warnings was emitted. Patch by Serhiy Storchaka. + +- Issue #24137: Run IDLE, test_idle, and htest with tkinter default root disabled. + Fix code and tests that fail with this restriction. + Fix htests to not create a second and redundant root and mainloop. + +- Issue #27310: Fix IDLE.app failure to launch on OS X due to vestigial import. + +- Issue #5124: Paste with text selected now replaces the selection on X11. + This matches how paste works on Windows, Mac, most modern Linux apps, + and ttk widgets. Original patch by Serhiy Storchaka. + +- Issue #24750: Switch all scrollbars in IDLE to ttk versions. + Where needed, minimal tests are added to cover changes. + +- Issue #24759: IDLE requires tk 8.5 and availability ttk widgets. + Delete now unneeded tk version tests and code for older versions. + Add test for IDLE syntax colorizer. + +- Issue #27239: idlelib.macosx.isXyzTk functions initialize as needed. + +- Issue #27262: move Aqua unbinding code, which enable context menus, to macosx. + +- Issue #24759: Make clear in idlelib.idle_test.__init__ that the directory + is a private implementation of test.test_idle and tool for maintainers. + +- Issue #27196: Stop 'ThemeChanged' warnings when running IDLE tests. + These persisted after other warnings were suppressed in #20567. + Apply Serhiy Storchaka's update_idletasks solution to four test files. + Record this additional advice in idle_test/README.txt + +- Issue #20567: Revise idle_test/README.txt with advice about avoiding + tk warning messages from tests. Apply advice to several IDLE tests. + +- Issue # 24225: Update idlelib/README.txt with new file names + and event handlers. + +- Issue #27156: Remove obsolete code not used by IDLE. Replacements: + 1. help.txt, replaced by help.html, is out-of-date and should not be used. + Its dedicated viewer has be replaced by the html viewer in help.py. + 2. 'import idlever; I = idlever.IDLE_VERSION' is the same as + 'import sys; I = version[:version.index(' ')]' + 3. After 'ob = stackviewer.VariablesTreeItem(*args)', + 'ob.keys()' == 'list(ob.object.keys). + 4. In macosc, runningAsOSXAPP == isAquaTk; idCarbonAquaTk == isCarbonTk + +- Issue #27117: Make colorizer htest and turtledemo work with dark themes. + Move code for configuring text widget colors to a new function. + +- Issue #24225: Rename many idlelib/*.py and idle_test/test_*.py files. + Edit files to replace old names with new names when the old name + referred to the module rather than the class it contained. + See the issue and IDLE section in What's New in 3.6 for more. + +- Issue #26673: When tk reports font size as 0, change to size 10. + Such fonts on Linux prevented the configuration dialog from opening. + +- Issue #21939: Add test for IDLE's percolator. + Original patch by Saimadhav Heblikar. + +- Issue #21676: Add test for IDLE's replace dialog. + Original patch by Saimadhav Heblikar. + +- Issue #18410: Add test for IDLE's search dialog. + Original patch by Westley Martínez. + +- Issue #21703: Add test for undo delegator. Patch mostly by + Saimadhav Heblikar . + +- Issue #27044: Add ConfigDialog.remove_var_callbacks to stop memory leaks. + +- Issue #23977: Add more asserts to test_delegator. + +- Issue #20640: Add tests for idlelib.configHelpSourceEdit. + Patch by Saimadhav Heblikar. + +- In the 'IDLE-console differences' section of the IDLE doc, clarify + how running with IDLE affects sys.modules and the standard streams. + +- Issue #25507: fix incorrect change in IOBinding that prevented printing. + Augment IOBinding htest to include all major IOBinding functions. + +- Issue #25905: Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION + MARK in README.txt and open this and NEWS.txt with 'ascii'. + Re-encode CREDITS.txt to utf-8 and open it with 'utf-8'. + +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + +- Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. + It is more or less IDLE Classic inverted, with a cobalt blue background. + Strings, comments, keywords, ... are still green, red, orange, ... . + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. + +- Issue #25224: README.txt is now an idlelib index for IDLE developers and + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. + +- Issue #24820: Users can now set breakpoint colors in + Settings -> Custom Highlighting. Original patch by Mark Roseman. + +- Issue #24972: Inactive selection background now matches active selection + background, as configured by users, on all systems. Found items are now + always highlighted on Windows. Initial patch by Mark Roseman. + +- Issue #24570: Idle: make calltip and completion boxes appear on Macs + affected by a tk regression. Initial patch by Mark Roseman. + +- Issue #24988: Idle ScrolledList context menus (used in debugger) + now work on Mac Aqua. Patch by Mark Roseman. + +- Issue #24801: Make right-click for context menu work on Mac Aqua. + Patch by Mark Roseman. + +- Issue #25173: Associate tkinter messageboxes with a specific widget. + For Mac OSX, make them a 'sheet'. Patch by Mark Roseman. + +- Issue #25198: Enhance the initial html viewer now used for Idle Help. + * Properly indent fixed-pitch text (patch by Mark Roseman). + * Give code snippet a very Sphinx-like light blueish-gray background. + * Re-use initial width and height set by users for shell and editor. + * When the Table of Contents (TOC) menu is used, put the section header + at the top of the screen. + +- Issue #25225: Condense and rewrite Idle doc section on text colors. + +- Issue #21995: Explain some differences between IDLE and console Python. + +- Issue #22820: Explain need for *print* when running file from Idle editor. + +- Issue #25224: Doc: augment Idle feature list and no-subprocess section. + +- Issue #25219: Update doc for Idle command line options. + Some were missing and notes were not correct. + +- Issue #24861: Most of idlelib is private and subject to change. + Use idleib.idle.* to start Idle. See idlelib.__init__.__doc__. + +- Issue #25199: Idle: add synchronization comments for future maintainers. + +- Issue #16893: Replace help.txt with help.html for Idle doc display. + The new idlelib/help.html is rstripped Doc/build/html/library/idle.html. + It looks better than help.txt and will better document Idle as released. + The tkinter html viewer that works for this file was written by Mark Roseman. + The now unused EditorWindow.HelpDialog class and helt.txt file are deprecated. + +- Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. + +- Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). + + +What's New in IDLE 3.5.0? +========================= +*Release date: 2015-09-13* + +- Issue #23672: Allow Idle to edit and run files with astral chars in name. + Patch by Mohd Sanad Zaki Rizvi. + +- Issue 24745: 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' entries from [Editor Window]. Patch by Mark Roseman. + +- Issue #21192: Idle editor. When a file is run, put its name in the restart bar. + Do not print false prompts. Original patch by Adnan Umer. + +- Issue #13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy. + +- Issue #23184: remove unused names and imports in idlelib. + Initial patch by Al Sweigart. + +- Issue #20577: Configuration of the max line length for the FormatParagraph + extension has been moved from the General tab of the Idle preferences dialog + to the FormatParagraph tab of the Config Extensions dialog. + Patch by Tal Einat. + +- Issue #16893: Update Idle doc chapter to match current Idle and add new + information. + +- Issue #3068: Add Idle extension configuration dialog to Options menu. + Changes are written to HOME/.idlerc/config-extensions.cfg. + Original patch by Tal Einat. + +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an + editor window with a filename. When Class Browser is requested otherwise, + from a shell, output window, or 'Untitled' editor, Idle no longer displays + an error box. It now pops up an Open Module box (Alt+M). If a valid name + is entered and a module is opened, a corresponding browser is also opened. + +- Issue #4832: Save As to type Python files automatically adds .py to the + name you enter (even if your system does not display it). Some systems + automatically add .txt when type is Text files. + +- Issue #21986: Code objects are not normally pickled by the pickle module. + To match this, they are no longer pickled when running under Idle. + +- Issue #23180: Rename IDLE "Windows" menu item to "Window". + Patch by Al Sweigart. + +- Issue #17390: Adjust Editor window title; remove 'Python', + move version to end. + +- Issue #14105: Idle debugger breakpoints no longer disappear + when inserting or deleting lines. + +- Issue #17172: Turtledemo can now be run from Idle. + Currently, the entry is on the Help menu, but it may move to Run. + Patch by Ramchandra Apt and Lita Cho. + +- Issue #21765: Add support for non-ascii identifiers to HyperParser. + +- Issue #21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav + Heblikar. + +- Issue #18592: Add unittest for SearchDialogBase. Patch by Phil Webster. + +- Issue #21694: Add unittest for ParenMatch. Patch by Saimadhav Heblikar. + +- Issue #21686: add unittest for HyperParser. Original patch by Saimadhav + Heblikar. + +- Issue #12387: Add missing upper(lower)case versions of default Windows key + bindings for Idle so Caps Lock does not disable them. Patch by Roger Serwy. + +- Issue #21695: Closing a Find-in-files output window while the search is + still in progress no longer closes Idle. + +- Issue #18910: Add unittest for textView. Patch by Phil Webster. + +- Issue #18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar. + +- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster. + +- Issue #21477: htest.py - Improve framework, complete set of tests. + Patches by Saimadhav Heblikar + +- Issue #18104: Add idlelib/idle_test/htest.py with a few sample tests to begin + consolidating and improving human-validated tests of Idle. Change other files + as needed to work with htest. Running the module as __main__ runs all tests. + +- Issue #21139: Change default paragraph width to 72, the PEP 8 recommendation. + +- Issue #21284: Paragraph reformat test passes after user changes reformat width. + +- Issue #17654: Ensure IDLE menus are customized properly on OS X for + non-framework builds and for all variants of Tk. + + +What's New in IDLE 3.4.0? +========================= +*Release date: 2014-03-16* + +- Issue #17390: Display Python version on Idle title bar. + Initial patch by Edmond Burnett. + +- Issue #5066: Update IDLE docs. Patch by Todd Rovito. + +- Issue #17625: Close the replace dialog after it is used. + +- Issue #16226: Fix IDLE Path Browser crash. + (Patch by Roger Serwy) + +- Issue #15853: Prevent IDLE crash on OS X when opening Preferences menu + with certain versions of Tk 8.5. Initial patch by Kevin Walzer. + + +What's New in IDLE 3.3.0? +========================= +*Release date: 2012-09-29* + +- Issue #17625: Close the replace dialog after it is used. + +- Issue #7163: Propagate return value of sys.stdout.write. + +- Issue #15318: Prevent writing to sys.stdin. + +- Issue #4832: Modify IDLE to save files with .py extension by + default on Windows and OS X (Tk 8.5) as it already does with X11 Tk. + +- Issue #13532, #15319: Check that arguments to sys.stdout.write are strings. + +- Issue # 12510: Attempt to get certain tool tips no longer crashes IDLE. + Erroneous tool tips have been corrected. Default added for callables. + +- Issue #10365: File open dialog now works instead of crashing even when + parent window is closed while dialog is open. + +- Issue 14876: use user-selected font for highlight configuration. + +- Issue #14937: Perform auto-completion of filenames in strings even for + non-ASCII filenames. Likewise for identifiers. + +- Issue #8515: Set __file__ when run file in IDLE. + Initial patch by Bruce Frederiksen. + +- IDLE can be launched as `python -m idlelib` + +- Issue #14409: IDLE now properly executes commands in the Shell window + when it cannot read the normal config files on startup and + has to use the built-in default key bindings. + There was previously a bug in one of the defaults. + +- Issue #3573: IDLE hangs when passing invalid command line args + (directory(ies) instead of file(s)). + +- Issue #14018: Update checks for unstable system Tcl/Tk versions on OS X + to include versions shipped with OS X 10.7 and 10.8 in addition to 10.6. + + +What's New in IDLE 3.2.1? +========================= +*Release date: 15-May-11* + +- Issue #6378: Further adjust idle.bat to start associated Python + +- Issue #11896: Save on Close failed despite selecting "Yes" in dialog. + +- Issue #1028: Ctrl-space binding to show completions was causing IDLE to exit. + Tk < 8.5 was sending invalid Unicode null; replaced with valid null. + +- Issue #4676: toggle failing on Tk 8.5, causing IDLE exits and strange selection + behavior. Improve selection extension behaviour. + +- Issue #3851: toggle non-functional when NumLock set on Windows. + + +What's New in IDLE 3.1b1? +========================= +*Release date: 06-May-09* + +- Issue #5707: Use of 'filter' in keybindingDialog.py was causing custom key assignment to + fail. Patch by Amaury Forgeot d'Arc. + +- Issue #4815: Offer conversion to UTF-8 if source files have + no encoding declaration and are not encoded in UTF-8. + +- Issue #4008: Fix problems with non-ASCII source files. + +- Issue #4323: Always encode source as UTF-8 without asking + the user (unless a different encoding is declared); remove + user configuration of source encoding; all according to + PEP 3120. + +- Issue #2665: On Windows, an IDLE installation upgraded from an old version + would not start if a custom theme was defined. + +------------------------------------------------------------------------ +Refer to NEWS2x.txt and HISTORY.txt for information on earlier releases. +------------------------------------------------------------------------ diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py index 4fe64dced60aca..8b9060e57072ea 100644 --- a/Lib/idlelib/browser.py +++ b/Lib/idlelib/browser.py @@ -250,9 +250,11 @@ def closure(): class Nested_in_closure: pass ModuleBrowser(parent, file, _htest=True) + if __name__ == "__main__": if len(sys.argv) == 1: # If pass file on command line, unittest fails. from unittest import main main('idlelib.idle_test.test_browser', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_module_browser) diff --git a/Lib/idlelib/calltip_w.py b/Lib/idlelib/calltip_w.py index 278546064adde2..9386376058c791 100644 --- a/Lib/idlelib/calltip_w.py +++ b/Lib/idlelib/calltip_w.py @@ -193,6 +193,7 @@ def calltip_hide(event): text.focus_set() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_calltip_w', verbosity=2, exit=False) diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 2b09d79470b47c..92992fd9cce9cd 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -597,7 +597,9 @@ def GetCoreKeys(self, keySetName=None): problem getting any core binding there will be an 'ultimate last resort fallback' to the CUA-ish bindings defined here. """ + # TODO: = dict(sorted([(v-event, keys), ...]))? keyBindings={ + # vitual-event: list of key events. '<>': ['', ''], '<>': ['', ''], '<>': ['', ''], @@ -880,7 +882,7 @@ def _dump(): # htest # (not really, but ignore in coverage) line, crc = 0, 0 def sprint(obj): - global line, crc + nonlocal line, crc txt = str(obj) line += 1 crc = crc32(txt.encode(encoding='utf-8'), crc) @@ -889,7 +891,7 @@ def sprint(obj): def dumpCfg(cfg): print('\n', cfg, '\n') # Cfg has variable '0xnnnnnnnn' address. - for key in sorted(cfg.keys()): + for key in sorted(cfg): sections = cfg[key].sections() sprint(key) sprint(sections) @@ -904,8 +906,11 @@ def dumpCfg(cfg): dumpCfg(idleConf.userCfg) print('\nlines = ', line, ', crc = ', crc, sep='') + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_config', verbosity=2, exit=False) - # Run revised _dump() as htest? + _dump() + # Run revised _dump() (700+ lines) as htest? More sorting. + # Perhaps as window with tabs for textviews, making it config viewer. diff --git a/Lib/idlelib/config_key.py b/Lib/idlelib/config_key.py index bb07231cd590b6..e5f67e8d4069ee 100644 --- a/Lib/idlelib/config_key.py +++ b/Lib/idlelib/config_key.py @@ -351,4 +351,4 @@ def cancel(self, event=None): main('idlelib.idle_test.test_config_key', verbosity=2, exit=False) from idlelib.idle_test.htest import run - run(GetKeysDialog) + run(GetKeysWindow) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index cda7966d558a51..eedf97bf74fe6a 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -211,14 +211,8 @@ def help(self): contents=help_common+help_pages.get(page, '')) def deactivate_current_config(self): - """Remove current key bindings. - Iterate over window instances defined in parent and remove - the keybindings. - """ - # Before a config is saved, some cleanup of current - # config must be done - remove the previous keybindings. - win_instances = self.parent.instance_dict.keys() - for instance in win_instances: + """Remove current key bindings in current windows.""" + for instance in self.parent.instance_dict: instance.RemoveKeybindings() def activate_config_changes(self): @@ -227,8 +221,7 @@ def activate_config_changes(self): Dynamically update the current parent window instances with some of the configuration changes. """ - win_instances = self.parent.instance_dict.keys() - for instance in win_instances: + for instance in self.parent.instance_dict: instance.ResetColorizer() instance.ResetFont() instance.set_notabs_indentwidth() @@ -583,22 +576,23 @@ def create_page_highlight(self): (*)theme_message: Label """ self.theme_elements = { - 'Normal Code or Text': ('normal', '00'), - 'Code Context': ('context', '01'), - 'Python Keywords': ('keyword', '02'), - 'Python Definitions': ('definition', '03'), - 'Python Builtins': ('builtin', '04'), - 'Python Comments': ('comment', '05'), - 'Python Strings': ('string', '06'), - 'Selected Text': ('hilite', '07'), - 'Found Text': ('hit', '08'), - 'Cursor': ('cursor', '09'), - 'Editor Breakpoint': ('break', '10'), - 'Shell Prompt': ('console', '11'), - 'Error Text': ('error', '12'), - 'Shell User Output': ('stdout', '13'), - 'Shell User Exception': ('stderr', '14'), - 'Line Number': ('linenumber', '16'), + # Display-name: internal-config-tag-name. + 'Normal Code or Text': 'normal', + 'Code Context': 'context', + 'Python Keywords': 'keyword', + 'Python Definitions': 'definition', + 'Python Builtins': 'builtin', + 'Python Comments': 'comment', + 'Python Strings': 'string', + 'Selected Text': 'hilite', + 'Found Text': 'hit', + 'Cursor': 'cursor', + 'Editor Breakpoint': 'break', + 'Shell Prompt': 'console', + 'Error Text': 'error', + 'Shell User Output': 'stdout', + 'Shell User Exception': 'stderr', + 'Line Number': 'linenumber', } self.builtin_name = tracers.add( StringVar(self), self.var_changed_builtin_name) @@ -658,7 +652,7 @@ def tem(event, elem=element): # event.widget.winfo_top_level().highlight_target.set(elem) self.highlight_target.set(elem) text.tag_bind( - self.theme_elements[element][0], '', tem) + self.theme_elements[element], '', tem) text['state'] = 'disabled' self.style.configure('frame_color_set.TFrame', borderwidth=1, relief='solid') @@ -765,8 +759,7 @@ def load_theme_cfg(self): self.builtinlist.SetMenu(item_list, item_list[0]) self.set_theme_type() # Load theme element option menu. - theme_names = list(self.theme_elements.keys()) - theme_names.sort(key=lambda x: self.theme_elements[x][1]) + theme_names = list(self.theme_elements) self.targetlist.SetMenu(theme_names, theme_names[0]) self.paint_theme_sample() self.set_highlight_target() @@ -893,7 +886,7 @@ def on_new_color_set(self): new_color = self.color.get() self.style.configure('frame_color_set.TFrame', background=new_color) plane = 'foreground' if self.fg_bg_toggle.get() else 'background' - sample_element = self.theme_elements[self.highlight_target.get()][0] + sample_element = self.theme_elements[self.highlight_target.get()] self.highlight_sample.tag_config(sample_element, **{plane: new_color}) theme = self.custom_name.get() theme_element = sample_element + '-' + plane @@ -1007,7 +1000,7 @@ def set_color_sample(self): frame_color_set """ # Set the color sample area. - tag = self.theme_elements[self.highlight_target.get()][0] + tag = self.theme_elements[self.highlight_target.get()] plane = 'foreground' if self.fg_bg_toggle.get() else 'background' color = self.highlight_sample.tag_cget(tag, plane) self.style.configure('frame_color_set.TFrame', background=color) @@ -1037,7 +1030,7 @@ def paint_theme_sample(self): else: # User theme theme = self.custom_name.get() for element_title in self.theme_elements: - element = self.theme_elements[element_title][0] + element = self.theme_elements[element_title] colors = idleConf.GetHighlight(theme, element) if element == 'cursor': # Cursor sample needs special painting. colors['background'] = idleConf.GetHighlight( @@ -1477,12 +1470,13 @@ def load_keys_list(self, keyset_name): reselect = True list_index = self.bindingslist.index(ANCHOR) keyset = idleConf.GetKeySet(keyset_name) - bind_names = list(keyset.keys()) + # 'set' is dict mapping virtual event to list of key events. + bind_names = list(keyset) bind_names.sort() self.bindingslist.delete(0, END) for bind_name in bind_names: key = ' '.join(keyset[bind_name]) - bind_name = bind_name[2:-2] # Trim off the angle brackets. + bind_name = bind_name[2:-2] # Trim double angle brackets. if keyset_name in changes['keys']: # Handle any unsaved changes to this key set. if bind_name in changes['keys'][keyset_name]: diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py index 452c62b42655b3..f487b4c4b16a60 100644 --- a/Lib/idlelib/debugger.py +++ b/Lib/idlelib/debugger.py @@ -1,3 +1,20 @@ +"""Debug user code with a GUI interface to a subclass of bdb.Bdb. + +The Idb idb and Debugger gui instances each need a reference to each +other or to an rpc proxy for each other. + +If IDLE is started with '-n', so that user code and idb both run in the +IDLE process, Debugger is called without an idb. Debugger.__init__ +calls Idb with its incomplete self. Idb.__init__ stores gui and gui +then stores idb. + +If IDLE is started normally, so that user code executes in a separate +process, debugger_r.start_remote_debugger is called, executing in the +IDLE process. It calls 'start the debugger' in the remote process, +which calls Idb with a gui proxy. Then Debugger is called in the IDLE +for more. +""" + import bdb import os @@ -10,66 +27,95 @@ class Idb(bdb.Bdb): + "Supply user_line and user_exception functions for Bdb." def __init__(self, gui): - self.gui = gui # An instance of Debugger or proxy of remote. - bdb.Bdb.__init__(self) + self.gui = gui # An instance of Debugger or proxy thereof. + super().__init__() def user_line(self, frame): - if self.in_rpc_code(frame): + """Handle a user stopping or breaking at a line. + + Convert frame to a string and send it to gui. + """ + if _in_rpc_code(frame): self.set_step() return - message = self.__frame2message(frame) + message = _frame2message(frame) try: self.gui.interaction(message, frame) except TclError: # When closing debugger window with [x] in 3.x pass - def user_exception(self, frame, info): - if self.in_rpc_code(frame): + def user_exception(self, frame, exc_info): + """Handle an the occurrence of an exception.""" + if _in_rpc_code(frame): self.set_step() return - message = self.__frame2message(frame) - self.gui.interaction(message, frame, info) - - def in_rpc_code(self, frame): - if frame.f_code.co_filename.count('rpc.py'): - return True - else: - prev_frame = frame.f_back - prev_name = prev_frame.f_code.co_filename - if 'idlelib' in prev_name and 'debugger' in prev_name: - # catch both idlelib/debugger.py and idlelib/debugger_r.py - # on both Posix and Windows - return False - return self.in_rpc_code(prev_frame) - - def __frame2message(self, frame): - code = frame.f_code - filename = code.co_filename - lineno = frame.f_lineno - basename = os.path.basename(filename) - message = f"{basename}:{lineno}" - if code.co_name != "?": - message = f"{message}: {code.co_name}()" - return message + message = _frame2message(frame) + self.gui.interaction(message, frame, exc_info) + +def _in_rpc_code(frame): + "Determine if debugger is within RPC code." + if frame.f_code.co_filename.count('rpc.py'): + return True # Skip this frame. + else: + prev_frame = frame.f_back + if prev_frame is None: + return False + prev_name = prev_frame.f_code.co_filename + if 'idlelib' in prev_name and 'debugger' in prev_name: + # catch both idlelib/debugger.py and idlelib/debugger_r.py + # on both Posix and Windows + return False + return _in_rpc_code(prev_frame) + +def _frame2message(frame): + """Return a message string for frame.""" + code = frame.f_code + filename = code.co_filename + lineno = frame.f_lineno + basename = os.path.basename(filename) + message = f"{basename}:{lineno}" + if code.co_name != "?": + message = f"{message}: {code.co_name}()" + return message class Debugger: - - vstack = vsource = vlocals = vglobals = None + """The debugger interface. + + This class handles the drawing of the debugger window and + the interactions with the underlying debugger session. + """ + vstack = None + vsource = None + vlocals = None + vglobals = None + stackviewer = None + localsviewer = None + globalsviewer = None def __init__(self, pyshell, idb=None): + """Instantiate and draw a debugger window. + + :param pyshell: An instance of the PyShell Window + :type pyshell: :class:`idlelib.pyshell.PyShell` + + :param idb: An instance of the IDLE debugger (optional) + :type idb: :class:`idlelib.debugger.Idb` + """ if idb is None: idb = Idb(self) self.pyshell = pyshell self.idb = idb # If passed, a proxy of remote instance. self.frame = None self.make_gui() - self.interacting = 0 + self.interacting = False self.nesting_level = 0 def run(self, *args): + """Run the debugger.""" # Deal with the scenario where we've already got a program running # in the debugger and we want to start another. If that is the case, # our second 'run' was invoked from an event dispatched not from @@ -104,12 +150,13 @@ def run(self, *args): self.root.after(100, lambda: self.run(*args)) return try: - self.interacting = 1 + self.interacting = True return self.idb.run(*args) finally: - self.interacting = 0 + self.interacting = False def close(self, event=None): + """Close the debugger and window.""" try: self.quit() except Exception: @@ -127,6 +174,7 @@ def close(self, event=None): self.top.destroy() def make_gui(self): + """Draw the debugger gui on the screen.""" pyshell = self.pyshell self.flist = pyshell.flist self.root = root = pyshell.root @@ -135,11 +183,11 @@ def make_gui(self): self.top.wm_iconname("Debug") top.wm_protocol("WM_DELETE_WINDOW", self.close) self.top.bind("", self.close) - # + self.bframe = bframe = Frame(top) self.bframe.pack(anchor="w") self.buttons = bl = [] - # + self.bcont = b = Button(bframe, text="Go", command=self.cont) bl.append(b) self.bstep = b = Button(bframe, text="Step", command=self.step) @@ -150,14 +198,14 @@ def make_gui(self): bl.append(b) self.bret = b = Button(bframe, text="Quit", command=self.quit) bl.append(b) - # + for b in bl: b.configure(state="disabled") b.pack(side="left") - # + self.cframe = cframe = Frame(bframe) self.cframe.pack(side="left") - # + if not self.vstack: self.__class__.vstack = BooleanVar(top) self.vstack.set(1) @@ -180,20 +228,20 @@ def make_gui(self): self.bglobals = Checkbutton(cframe, text="Globals", command=self.show_globals, variable=self.vglobals) self.bglobals.grid(row=1, column=1) - # + self.status = Label(top, anchor="w") self.status.pack(anchor="w") self.error = Label(top, anchor="w") self.error.pack(anchor="w", fill="x") self.errorbg = self.error.cget("background") - # + self.fstack = Frame(top, height=1) self.fstack.pack(expand=1, fill="both") self.flocals = Frame(top) self.flocals.pack(expand=1, fill="both") self.fglobals = Frame(top, height=1) self.fglobals.pack(expand=1, fill="both") - # + if self.vstack.get(): self.show_stack() if self.vlocals.get(): @@ -204,7 +252,7 @@ def make_gui(self): def interaction(self, message, frame, info=None): self.frame = frame self.status.configure(text=message) - # + if info: type, value, tb = info try: @@ -223,28 +271,28 @@ def interaction(self, message, frame, info=None): tb = None bg = self.errorbg self.error.configure(text=m1, background=bg) - # + sv = self.stackviewer if sv: stack, i = self.idb.get_stack(self.frame, tb) sv.load_stack(stack, i) - # + self.show_variables(1) - # + if self.vsource.get(): self.sync_source_line() - # + for b in self.buttons: b.configure(state="normal") - # + self.top.wakeup() # Nested main loop: Tkinter's main loop is not reentrant, so use # Tcl's vwait facility, which reenters the event loop until an - # event handler sets the variable we're waiting on + # event handler sets the variable we're waiting on. self.nesting_level += 1 self.root.tk.call('vwait', '::idledebugwait') self.nesting_level -= 1 - # + for b in self.buttons: b.configure(state="disabled") self.status.configure(text="") @@ -288,8 +336,6 @@ def quit(self): def abort_loop(self): self.root.tk.call('set', '::idledebugwait', '1') - stackviewer = None - def show_stack(self): if not self.stackviewer and self.vstack.get(): self.stackviewer = sv = StackViewer(self.fstack, self.flist, self) @@ -311,9 +357,6 @@ def show_frame(self, stackitem): self.frame = stackitem[0] # lineno is stackitem[1] self.show_variables() - localsviewer = None - globalsviewer = None - def show_locals(self): lv = self.localsviewer if self.vlocals.get(): @@ -354,26 +397,32 @@ def show_variables(self, force=0): if gv: gv.load_dict(gdict, force, self.pyshell.interp.rpcclt) - def set_breakpoint_here(self, filename, lineno): + def set_breakpoint(self, filename, lineno): + """Set a filename-lineno breakpoint in the debugger. + + Called from self.load_breakpoints and EW.setbreakpoint + """ self.idb.set_break(filename, lineno) - def clear_breakpoint_here(self, filename, lineno): + def clear_breakpoint(self, filename, lineno): self.idb.clear_break(filename, lineno) def clear_file_breaks(self, filename): self.idb.clear_all_file_breaks(filename) def load_breakpoints(self): - "Load PyShellEditorWindow breakpoints into subprocess debugger" + """Load PyShellEditorWindow breakpoints into subprocess debugger.""" for editwin in self.pyshell.flist.inversedict: filename = editwin.io.filename try: for lineno in editwin.breakpoints: - self.set_breakpoint_here(filename, lineno) + self.set_breakpoint(filename, lineno) except AttributeError: continue + class StackViewer(ScrolledList): + "Code stack viewer for debugger GUI." def __init__(self, master, flist, gui): if macosx.isAquaTk(): @@ -414,12 +463,12 @@ def load_stack(self, stack, index=None): self.select(index) def popup_event(self, event): - "override base method" + "Override base method." if self.stack: return ScrolledList.popup_event(self, event) def fill_menu(self): - "override base method" + "Override base method." menu = self.menu menu.add_command(label="Go to source line", command=self.goto_source_line) @@ -427,12 +476,12 @@ def fill_menu(self): command=self.show_stack_frame) def on_select(self, index): - "override base method" + "Override base method." if 0 <= index < len(self.stack): self.gui.show_frame(self.stack[index]) def on_double(self, index): - "override base method" + "Override base method." self.show_source(index) def goto_source_line(self): @@ -457,6 +506,7 @@ def show_source(self, index): class NamespaceViewer: + "Global/local namespace viewer for debugger GUI." def __init__(self, master, title, dict=None): width = 0 @@ -509,7 +559,7 @@ def load_dict(self, dict, force=0, rpc_client=None): # There is also an obscure bug in sorted(dict) where the # interpreter gets into a loop requesting non-existing dict[0], # dict[1], dict[2], etc from the debugger_r.DictProxy. - ### + # TODO recheck above; see debugger_r 159ff, debugobj 60. keys_list = dict.keys() names = sorted(keys_list) ### @@ -544,6 +594,7 @@ def load_dict(self, dict, force=0, rpc_client=None): def close(self): self.frame.destroy() + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_debugger', verbosity=2, exit=False) diff --git a/Lib/idlelib/debugobj.py b/Lib/idlelib/debugobj.py index 71d01c7070df54..156377f8ed26ac 100644 --- a/Lib/idlelib/debugobj.py +++ b/Lib/idlelib/debugobj.py @@ -93,7 +93,8 @@ def setfunction(value, key=key, object=self.object): class DictTreeItem(SequenceTreeItem): def keys(self): - keys = list(self.object.keys()) + # TODO return sorted(self.object) + keys = list(self.object) try: keys.sort() except: @@ -119,7 +120,7 @@ def make_objecttreeitem(labeltext, object, setfunction=None): return c(labeltext, object, setfunction) -def _object_browser(parent): # htest # +def _debug_object_browser(parent): # htest # import sys from tkinter import Toplevel top = Toplevel(parent) @@ -134,9 +135,10 @@ def _object_browser(parent): # htest # node = TreeNode(sc.canvas, None, item) node.update() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False) from idlelib.idle_test.htest import run - run(_object_browser) + run(_debug_object_browser) diff --git a/Lib/idlelib/delegator.py b/Lib/idlelib/delegator.py index 55c95da8532f47..93ae8bbd43ff44 100644 --- a/Lib/idlelib/delegator.py +++ b/Lib/idlelib/delegator.py @@ -28,6 +28,7 @@ def setdelegate(self, delegate): self.resetcache() self.delegate = delegate + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_delegator', verbosity=2) diff --git a/Lib/idlelib/dynoption.py b/Lib/idlelib/dynoption.py index d5dfc3eda13f60..b8937f7106ca75 100644 --- a/Lib/idlelib/dynoption.py +++ b/Lib/idlelib/dynoption.py @@ -29,6 +29,7 @@ def SetMenu(self,valueList,value=None): if value: self.variable.set(value) + def _dyn_option_menu(parent): # htest # from tkinter import Toplevel # + StringVar, Button @@ -49,6 +50,7 @@ def update(): button = Button(top, text="Change option set", command=update) button.pack() + if __name__ == '__main__': # Only module without unittests because of intention to replace. from idlelib.idle_test.htest import run diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 69b27d0683a104..6ad383f460c7ee 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -1748,6 +1748,7 @@ def _editor_window(parent): # htest # # Does not stop error, neither does following # edit.text.bind("<>", edit.close_event) + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_editor', verbosity=2, exit=False) diff --git a/Lib/idlelib/filelist.py b/Lib/idlelib/filelist.py index f87781d2570fe0..e27e5d32a0ff63 100644 --- a/Lib/idlelib/filelist.py +++ b/Lib/idlelib/filelist.py @@ -124,6 +124,7 @@ def _test(): # TODO check and convert to htest if flist.inversedict: root.mainloop() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_filelist', verbosity=2) diff --git a/Lib/idlelib/grep.py b/Lib/idlelib/grep.py index 12513594b76f8f..ef14349960bfa2 100644 --- a/Lib/idlelib/grep.py +++ b/Lib/idlelib/grep.py @@ -204,15 +204,17 @@ def _grep_dialog(parent): # htest # frame.pack() text = Text(frame, height=5) text.pack() + text.insert('1.0', 'import grep') def show_grep_dialog(): - text.tag_add(SEL, "1.0", END) + text.tag_add(SEL, "1.0", '1.end') grep(text, flist=flist) - text.tag_remove(SEL, "1.0", END) + text.tag_remove(SEL, "1.0", '1.end') button = Button(frame, text="Show GrepDialog", command=show_grep_dialog) button.pack() + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_grep', verbosity=2, exit=False) diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py index cc027b9cef4f5b..3cc7e36e35555b 100644 --- a/Lib/idlelib/help.py +++ b/Lib/idlelib/help.py @@ -278,7 +278,8 @@ def copy_strip(): out.write(line.rstrip() + b'\n') print(f'{src} copied to {dst}') -def show_idlehelp(parent): + +def _helpwindow(parent): "Create HelpWindow; called from Idle Help event handler." filename = join(abspath(dirname(__file__)), 'help.html') if not isfile(filename): @@ -286,9 +287,10 @@ def show_idlehelp(parent): return HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version()) + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_help', verbosity=2, exit=False) from idlelib.idle_test.htest import run - run(show_idlehelp) + run(_helpwindow) diff --git a/Lib/idlelib/help_about.py b/Lib/idlelib/help_about.py index cfa4ca781f087d..aa1c352897f9e7 100644 --- a/Lib/idlelib/help_about.py +++ b/Lib/idlelib/help_about.py @@ -129,11 +129,11 @@ def create_widgets(self): idle.grid(row=12, column=0, sticky=W, padx=10, pady=0) idle_buttons = Frame(frame_background, bg=self.bg) idle_buttons.grid(row=13, column=0, columnspan=3, sticky=NSEW) - self.readme = Button(idle_buttons, text='README', width=8, + self.readme = Button(idle_buttons, text='Readme', width=8, highlightbackground=self.bg, command=self.show_readme) self.readme.pack(side=LEFT, padx=10, pady=10) - self.idle_news = Button(idle_buttons, text='NEWS', width=8, + self.idle_news = Button(idle_buttons, text='News', width=8, highlightbackground=self.bg, command=self.show_idle_news) self.idle_news.pack(side=LEFT, padx=10, pady=10) @@ -167,7 +167,7 @@ def show_readme(self): def show_idle_news(self): "Handle News button event." - self.display_file_text('About - NEWS', 'NEWS.txt', 'utf-8') + self.display_file_text('About - News', 'News3.txt', 'utf-8') def display_printer_text(self, title, printer): """Create textview for built-in constants. diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py index d297f8aa0094ee..997f85ff5a78b2 100644 --- a/Lib/idlelib/idle_test/htest.py +++ b/Lib/idlelib/idle_test/htest.py @@ -1,38 +1,36 @@ -'''Run human tests of Idle's window, dialog, and popup widgets. - -run(*tests) -Create a master Tk window. Within that, run each callable in tests -after finding the matching test spec in this file. If tests is empty, -run an htest for each spec dict in this file after finding the matching -callable in the module named in the spec. Close the window to skip or -end the test. - -In a tested module, let X be a global name bound to a callable (class -or function) whose .__name__ attribute is also X (the usual situation). -The first parameter of X must be 'parent'. When called, the parent -argument will be the root window. X must create a child Toplevel -window (or subclass thereof). The Toplevel may be a test widget or -dialog, in which case the callable is the corresponding class. Or the -Toplevel may contain the widget to be tested or set up a context in -which a test widget is invoked. In this latter case, the callable is a -wrapper function that sets up the Toplevel and other objects. Wrapper -function names, such as _editor_window', should start with '_'. +"""Run human tests of Idle's window, dialog, and popup widgets. + +run(*tests) Create a master Tk() htest window. Within that, run each +callable in tests after finding the matching test spec in this file. If +tests is empty, run an htest for each spec dict in this file after +finding the matching callable in the module named in the spec. Close +the master window to end testing. + +In a tested module, let X be a global name bound to a callable (class or +function) whose .__name__ attribute is also X (the usual situation). The +first parameter of X must be 'parent' or 'master'. When called, the +first argument will be the root window. X must create a child +Toplevel(parent/master) (or subclass thereof). The Toplevel may be a +test widget or dialog, in which case the callable is the corresponding +class. Or the Toplevel may contain the widget to be tested or set up a +context in which a test widget is invoked. In this latter case, the +callable is a wrapper function that sets up the Toplevel and other +objects. Wrapper function names, such as _editor_window', should start +with '_' and be lowercase. End the module with if __name__ == '__main__': - + from idlelib.idle_test.htest import run - run(X) + run(callable) # There could be multiple comma-separated callables. -To have wrapper functions and test invocation code ignored by coveragepy -reports, put '# htest #' on the def statement header line. - -def _wrapper(parent): # htest # - -Also make sure that the 'if __name__' line matches the above. Then have -make sure that .coveragerc includes the following. +To have wrapper functions ignored by coverage reports, tag the def +header like so: "def _wrapper(parent): # htest #". Use the same tag +for htest lines in widget code. Make sure that the 'if __name__' line +matches the above. Then have make sure that .coveragerc includes the +following: [report] exclude_lines = @@ -46,7 +44,7 @@ def _wrapper(parent): # htest # following template, with X.__name__ prepended to '_spec'. When all tests are run, the prefix is use to get X. -_spec = { +callable_spec = { 'file': '', 'kwds': {'title': ''}, 'msg': "" @@ -54,16 +52,16 @@ def _wrapper(parent): # htest # file (no .py): run() imports file.py. kwds: augmented with {'parent':root} and passed to X as **kwds. -title: an example kwd; some widgets need this, delete if not. +title: an example kwd; some widgets need this, delete line if not. msg: master window hints about testing the widget. -Modules and classes not being tested at the moment: -pyshell.PyShellEditorWindow -debugger.Debugger -autocomplete_w.AutoCompleteWindow -outwin.OutputWindow (indirectly being tested with grep test) -''' +TODO test these modules and classes: + autocomplete_w.AutoCompleteWindow + debugger.Debugger + outwin.OutputWindow (indirectly being tested with grep test) + pyshell.PyShellEditorWindow +""" import idlelib.pyshell # Set Windows DPI awareness before Tk(). from importlib import import_module @@ -91,15 +89,6 @@ def _wrapper(parent): # htest # "Force-open-calltip does not work here.\n" } -_module_browser_spec = { - 'file': 'browser', - 'kwds': {}, - 'msg': "Inspect names of module, class(with superclass if " - "applicable), methods and functions.\nToggle nested items.\n" - "Double clicking on items prints a traceback for an exception " - "that is ignored." - } - _color_delegator_spec = { 'file': 'colorizer', 'kwds': {}, @@ -109,16 +98,6 @@ def _wrapper(parent): # htest # "The default color scheme is in idlelib/config-highlight.def" } -CustomRun_spec = { - 'file': 'query', - 'kwds': {'title': 'Customize query.py Run', - '_htest': True}, - 'msg': "Enter with or [Run]. Print valid entry to Shell\n" - "Arguments are parsed into a list\n" - "Mode is currently restart True or False\n" - "Close dialog with valid entry, , [Cancel], [X]" - } - ConfigDialog_spec = { 'file': 'configdialog', 'kwds': {'title': 'ConfigDialogTest', @@ -135,6 +114,24 @@ def _wrapper(parent): # htest # "changes made have persisted." } +CustomRun_spec = { + 'file': 'query', + 'kwds': {'title': 'Customize query.py Run', + '_htest': True}, + 'msg': "Enter with or [OK]. Print valid entry to Shell\n" + "Arguments are parsed into a list\n" + "Mode is currently restart True or False\n" + "Close dialog with valid entry, , [Cancel], [X]" + } + +_debug_object_browser_spec = { + 'file': 'debugobj', + 'kwds': {}, + 'msg': "Double click on items up to the lowest level.\n" + "Attributes of the objects and related information " + "will be displayed side-by-side at each level." + } + # TODO Improve message _dyn_option_menu_spec = { 'file': 'dynoption', @@ -152,7 +149,7 @@ def _wrapper(parent): # htest # "Best to close editor first." } -GetKeysDialog_spec = { +GetKeysWindow_spec = { 'file': 'config_key', 'kwds': {'title': 'Test keybindings', 'action': 'find-again', @@ -173,8 +170,8 @@ def _wrapper(parent): # htest # 'msg': "Click the 'Show GrepDialog' button.\n" "Test the various 'Find-in-files' functions.\n" "The results should be displayed in a new '*Output*' window.\n" - "'Right-click'->'Go to file/line' anywhere in the search results " - "should open that file \nin a new EditorWindow." + "'Right-click'->'Go to file/line' in the search results\n " + "should open that file in a new EditorWindow." } HelpSource_spec = { @@ -190,7 +187,14 @@ def _wrapper(parent): # htest # "Any url ('www...', 'http...') is accepted.\n" "Test Browse with and without path, as cannot unittest.\n" "[Ok] or prints valid entry to shell\n" - "[Cancel] or prints None to shell" + ", [Cancel], or [X] prints None to shell" + } + +_helpwindow_spec = { + 'file': 'help', + 'kwds': {}, + 'msg': "If the help text displays, this works.\n" + "Text is selectable. Window is scrollable." } _io_binding_spec = { @@ -206,56 +210,36 @@ def _wrapper(parent): # htest # "Check that changes were saved by opening the file elsewhere." } -_linenumbers_drag_scrolling_spec = { - 'file': 'sidebar', +_multi_call_spec = { + 'file': 'multicall', 'kwds': {}, - 'msg': textwrap.dedent("""\ - 1. Click on the line numbers and drag down below the edge of the - window, moving the mouse a bit and then leaving it there for a while. - The text and line numbers should gradually scroll down, with the - selection updated continuously. - - 2. With the lines still selected, click on a line number above the - selected lines. Only the line whose number was clicked should be - selected. - - 3. Repeat step #1, dragging to above the window. The text and line - numbers should gradually scroll up, with the selection updated - continuously. - - 4. Repeat step #2, clicking a line number below the selection."""), + 'msg': "The following should trigger a print to console or IDLE Shell.\n" + "Entering and leaving the text area, key entry, ,\n" + ", , , \n" + ", and focusing elsewhere." } -_multi_call_spec = { - 'file': 'multicall', +_module_browser_spec = { + 'file': 'browser', 'kwds': {}, - 'msg': "The following actions should trigger a print to console or IDLE" - " Shell.\nEntering and leaving the text area, key entry, " - ",\n, , " - ", \n, and " - "focusing out of the window\nare sequences to be tested." + 'msg': textwrap.dedent(""" + "Inspect names of module, class(with superclass if applicable), + "methods and functions. Toggle nested items. Double clicking + "on items prints a traceback for an exception that is ignored.""") } _multistatus_bar_spec = { 'file': 'statusbar', 'kwds': {}, 'msg': "Ensure presence of multi-status bar below text area.\n" - "Click 'Update Status' to change the multi-status text" - } - -_object_browser_spec = { - 'file': 'debugobj', - 'kwds': {}, - 'msg': "Double click on items up to the lowest level.\n" - "Attributes of the objects and related information " - "will be displayed side-by-side at each level." + "Click 'Update Status' to change the status text" } -_path_browser_spec = { +PathBrowser_spec = { 'file': 'pathbrowser', - 'kwds': {}, + 'kwds': {'_htest': True}, 'msg': "Test for correct display of all paths in sys.path.\n" - "Toggle nested items up to the lowest level.\n" + "Toggle nested items out to the lowest level.\n" "Double clicking on an item prints a traceback\n" "for an exception that is ignored." } @@ -291,6 +275,15 @@ def _wrapper(parent): # htest # "Click [Close] or [X] to close the 'Replace Dialog'." } +_scrolled_list_spec = { + 'file': 'scrolledlist', + 'kwds': {}, + 'msg': "You should see a scrollable list of items\n" + "Selecting (clicking) or double clicking an item " + "prints the name to the console or Idle shell.\n" + "Right clicking an item will display a popup." + } + _search_dialog_spec = { 'file': 'search', 'kwds': {}, @@ -306,28 +299,31 @@ def _wrapper(parent): # htest # "Its only action is to close." } -_scrolled_list_spec = { - 'file': 'scrolledlist', +_sidebar_number_scrolling_spec = { + 'file': 'sidebar', 'kwds': {}, - 'msg': "You should see a scrollable list of items\n" - "Selecting (clicking) or double clicking an item " - "prints the name to the console or Idle shell.\n" - "Right clicking an item will display a popup." - } + 'msg': textwrap.dedent("""\ + 1. Click on the line numbers and drag down below the edge of the + window, moving the mouse a bit and then leaving it there for a + while. The text and line numbers should gradually scroll down, + with the selection updated continuously. -show_idlehelp_spec = { - 'file': 'help', - 'kwds': {}, - 'msg': "If the help text displays, this works.\n" - "Text is selectable. Window is scrollable." + 2. With the lines still selected, click on a line number above + or below the selected lines. Only the line whose number was + clicked should be selected. + + 3. Repeat step #1, dragging to above the window. The text and + line numbers should gradually scroll up, with the selection + updated continuously. + + 4. Repeat step #2, clicking a line number below the selection."""), } -_stack_viewer_spec = { +_stackbrowser_spec = { 'file': 'stackviewer', 'kwds': {}, 'msg': "A stacktrace for a NameError exception.\n" - "Expand 'idlelib ...' and ''.\n" - "Check that exc_value, exc_tb, and exc_type are correct.\n" + "Should have NameError and 1 traceback line." } _tooltip_spec = { @@ -370,11 +366,12 @@ def _wrapper(parent): # htest # } def run(*tests): + "Run callables in tests." root = tk.Tk() root.title('IDLE htest') root.resizable(0, 0) - # a scrollable Label like constant width text widget. + # A scrollable Label-like constant width text widget. frameLabel = tk.Frame(root, padx=10) frameLabel.pack() text = tk.Text(frameLabel, wrap='word') @@ -384,45 +381,44 @@ def run(*tests): scrollbar.pack(side='right', fill='y', expand=False) text.pack(side='left', fill='both', expand=True) - test_list = [] # List of tuples of the form (spec, callable widget) + test_list = [] # Make list of (spec, callable) tuples. if tests: for test in tests: test_spec = globals()[test.__name__ + '_spec'] test_spec['name'] = test.__name__ test_list.append((test_spec, test)) else: - for k, d in globals().items(): - if k.endswith('_spec'): - test_name = k[:-5] - test_spec = d + for key, dic in globals().items(): + if key.endswith('_spec'): + test_name = key[:-5] + test_spec = dic test_spec['name'] = test_name mod = import_module('idlelib.' + test_spec['file']) test = getattr(mod, test_name) test_list.append((test_spec, test)) + test_list.reverse() # So can pop in proper order in next_test. test_name = tk.StringVar(root) callable_object = None test_kwds = None def next_test(): - nonlocal test_name, callable_object, test_kwds if len(test_list) == 1: next_button.pack_forget() test_spec, callable_object = test_list.pop() test_kwds = test_spec['kwds'] - test_kwds['parent'] = root test_name.set('Test ' + test_spec['name']) - text.configure(state='normal') # enable text editing - text.delete('1.0','end') - text.insert("1.0",test_spec['msg']) - text.configure(state='disabled') # preserve read-only property + text['state'] = 'normal' # Enable text replacement. + text.delete('1.0', 'end') + text.insert("1.0", test_spec['msg']) + text['state'] = 'disabled' # Restore read-only property. def run_test(_=None): - widget = callable_object(**test_kwds) + widget = callable_object(root, **test_kwds) try: - print(widget.result) + print(widget.result) # Only true for query classes(?). except AttributeError: pass @@ -441,5 +437,6 @@ def close(_=None): next_test() root.mainloop() + if __name__ == '__main__': run() diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py index 08ed76fe288294..6d75cf7aa67dcc 100644 --- a/Lib/idlelib/idle_test/test_config.py +++ b/Lib/idlelib/idle_test/test_config.py @@ -85,8 +85,8 @@ def test_load_nothing(self): self.assertEqual(parser.sections(), []) def test_load_file(self): - # Borrow test/cfgparser.1 from test_configparser. - config_path = findfile('cfgparser.1') + # Borrow test/configdata/cfgparser.1 from test_configparser. + config_path = findfile('cfgparser.1', subdir='configdata') parser = config.IdleConfParser(config_path) parser.Load() @@ -274,8 +274,8 @@ def test_create_config_handlers(self): conf.CreateConfigHandlers() # Check keys are equal - self.assertCountEqual(conf.defaultCfg.keys(), conf.config_types) - self.assertCountEqual(conf.userCfg.keys(), conf.config_types) + self.assertCountEqual(conf.defaultCfg, conf.config_types) + self.assertCountEqual(conf.userCfg, conf.config_types) # Check conf parser are correct type for default_parser in conf.defaultCfg.values(): @@ -294,8 +294,8 @@ def test_create_config_handlers(self): def test_load_cfg_files(self): conf = self.new_config(_utest=True) - # Borrow test/cfgparser.1 from test_configparser. - config_path = findfile('cfgparser.1') + # Borrow test/configdata/cfgparser.1 from test_configparser. + config_path = findfile('cfgparser.1', subdir='configdata') conf.defaultCfg['foo'] = config.IdleConfParser(config_path) conf.userCfg['foo'] = config.IdleUserConfParser(config_path) diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index e5d5b4013fca57..6f8518a9bb19d0 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -430,7 +430,7 @@ def test_highlight_target_text_mouse(self): def tag_to_element(elem): for element, tag in d.theme_elements.items(): - elem[tag[0]] = element + elem[tag] = element def click_it(start): x, y, dx, dy = hs.bbox(start) diff --git a/Lib/idlelib/idle_test/test_debugger.py b/Lib/idlelib/idle_test/test_debugger.py index 35efb3411c73b5..d1c9638dd5d711 100644 --- a/Lib/idlelib/idle_test/test_debugger.py +++ b/Lib/idlelib/idle_test/test_debugger.py @@ -1,16 +1,286 @@ -"Test debugger, coverage 19%" +"""Test debugger, coverage 66% + +Try to make tests pass with draft bdbx, which may replace bdb in 3.13+. +""" from idlelib import debugger -import unittest -from test.support import requires -requires('gui') +from collections import namedtuple +from textwrap import dedent from tkinter import Tk +from test.support import requires +import unittest +from unittest import mock +from unittest.mock import Mock, patch + +"""A test python script for the debug tests.""" +TEST_CODE = dedent(""" + i = 1 + i += 2 + if i == 3: + print(i) + """) + + +class MockFrame: + "Minimal mock frame." + + def __init__(self, code, lineno): + self.f_code = code + self.f_lineno = lineno + + +class IdbTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.gui = Mock() + cls.idb = debugger.Idb(cls.gui) + + # Create test and code objects to simulate a debug session. + code_obj = compile(TEST_CODE, 'idlelib/file.py', mode='exec') + frame1 = MockFrame(code_obj, 1) + frame1.f_back = None + frame2 = MockFrame(code_obj, 2) + frame2.f_back = frame1 + cls.frame = frame2 + cls.msg = 'file.py:2: ()' + + def test_init(self): + self.assertIs(self.idb.gui, self.gui) + # Won't test super call since two Bdbs are very different. + + def test_user_line(self): + # Test that .user_line() creates a string message for a frame. + self.gui.interaction = Mock() + self.idb.user_line(self.frame) + self.gui.interaction.assert_called_once_with(self.msg, self.frame) + + def test_user_exception(self): + # Test that .user_exception() creates a string message for a frame. + exc_info = (type(ValueError), ValueError(), None) + self.gui.interaction = Mock() + self.idb.user_exception(self.frame, exc_info) + self.gui.interaction.assert_called_once_with( + self.msg, self.frame, exc_info) + + +class FunctionTest(unittest.TestCase): + # Test module functions together. + + def test_functions(self): + rpc_obj = compile(TEST_CODE,'rpc.py', mode='exec') + rpc_frame = MockFrame(rpc_obj, 2) + rpc_frame.f_back = rpc_frame + self.assertTrue(debugger._in_rpc_code(rpc_frame)) + self.assertEqual(debugger._frame2message(rpc_frame), + 'rpc.py:2: ()') + + code_obj = compile(TEST_CODE, 'idlelib/debugger.py', mode='exec') + code_frame = MockFrame(code_obj, 1) + code_frame.f_back = None + self.assertFalse(debugger._in_rpc_code(code_frame)) + self.assertEqual(debugger._frame2message(code_frame), + 'debugger.py:1: ()') + + code_frame.f_back = code_frame + self.assertFalse(debugger._in_rpc_code(code_frame)) + code_frame.f_back = rpc_frame + self.assertTrue(debugger._in_rpc_code(code_frame)) + + +class DebuggerTest(unittest.TestCase): + "Tests for Debugger that do not need a real root." + + @classmethod + def setUpClass(cls): + cls.pyshell = Mock() + cls.pyshell.root = Mock() + cls.idb = Mock() + with patch.object(debugger.Debugger, 'make_gui'): + cls.debugger = debugger.Debugger(cls.pyshell, cls.idb) + cls.debugger.root = Mock() + + def test_cont(self): + self.debugger.cont() + self.idb.set_continue.assert_called_once() + + def test_step(self): + self.debugger.step() + self.idb.set_step.assert_called_once() + + def test_quit(self): + self.debugger.quit() + self.idb.set_quit.assert_called_once() + + def test_next(self): + with patch.object(self.debugger, 'frame') as frame: + self.debugger.next() + self.idb.set_next.assert_called_once_with(frame) + + def test_ret(self): + with patch.object(self.debugger, 'frame') as frame: + self.debugger.ret() + self.idb.set_return.assert_called_once_with(frame) + + def test_clear_breakpoint(self): + self.debugger.clear_breakpoint('test.py', 4) + self.idb.clear_break.assert_called_once_with('test.py', 4) + + def test_clear_file_breaks(self): + self.debugger.clear_file_breaks('test.py') + self.idb.clear_all_file_breaks.assert_called_once_with('test.py') + + def test_set_load_breakpoints(self): + # Test the .load_breakpoints() method calls idb. + FileIO = namedtuple('FileIO', 'filename') + + class MockEditWindow(object): + def __init__(self, fn, breakpoints): + self.io = FileIO(fn) + self.breakpoints = breakpoints + + self.pyshell.flist = Mock() + self.pyshell.flist.inversedict = ( + MockEditWindow('test1.py', [4, 4]), + MockEditWindow('test2.py', [13, 44, 45]), + ) + self.debugger.set_breakpoint('test0.py', 1) + self.idb.set_break.assert_called_once_with('test0.py', 1) + self.debugger.load_breakpoints() # Call set_breakpoint 5 times. + self.idb.set_break.assert_has_calls( + [mock.call('test0.py', 1), + mock.call('test1.py', 4), + mock.call('test1.py', 4), + mock.call('test2.py', 13), + mock.call('test2.py', 44), + mock.call('test2.py', 45)]) + + def test_sync_source_line(self): + # Test that .sync_source_line() will set the flist.gotofileline with fixed frame. + test_code = compile(TEST_CODE, 'test_sync.py', 'exec') + test_frame = MockFrame(test_code, 1) + self.debugger.frame = test_frame + + self.debugger.flist = Mock() + with patch('idlelib.debugger.os.path.exists', return_value=True): + self.debugger.sync_source_line() + self.debugger.flist.gotofileline.assert_called_once_with('test_sync.py', 1) + + +class DebuggerGuiTest(unittest.TestCase): + """Tests for debugger.Debugger that need tk root. + + close needs debugger.top set in make_gui. + """ + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = root = Tk() + root.withdraw() + cls.pyshell = Mock() + cls.pyshell.root = root + cls.idb = Mock() +# stack tests fail with debugger here. +## cls.debugger = debugger.Debugger(cls.pyshell, cls.idb) +## cls.debugger.root = root +## # real root needed for real make_gui +## # run, interacting, abort_loop + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def setUp(self): + self.debugger = debugger.Debugger(self.pyshell, self.idb) + self.debugger.root = self.root + # real root needed for real make_gui + # run, interacting, abort_loop + + def test_run_debugger(self): + self.debugger.run(1, 'two') + self.idb.run.assert_called_once_with(1, 'two') + self.assertEqual(self.debugger.interacting, 0) + + def test_close(self): + # Test closing the window in an idle state. + self.debugger.close() + self.pyshell.close_debugger.assert_called_once() + + def test_show_stack(self): + self.debugger.show_stack() + self.assertEqual(self.debugger.stackviewer.gui, self.debugger) + + def test_show_stack_with_frame(self): + test_frame = MockFrame(None, None) + self.debugger.frame = test_frame + + # Reset the stackviewer to force it to be recreated. + self.debugger.stackviewer = None + self.idb.get_stack.return_value = ([], 0) + self.debugger.show_stack() + + # Check that the newly created stackviewer has the test gui as a field. + self.assertEqual(self.debugger.stackviewer.gui, self.debugger) + self.idb.get_stack.assert_called_once_with(test_frame, None) + + +class StackViewerTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def setUp(self): + self.code = compile(TEST_CODE, 'test_stackviewer.py', 'exec') + self.stack = [ + (MockFrame(self.code, 1), 1), + (MockFrame(self.code, 2), 2) + ] + # Create a stackviewer and load the test stack. + self.sv = debugger.StackViewer(self.root, None, None) + self.sv.load_stack(self.stack) + + def test_init(self): + # Test creation of StackViewer. + gui = None + flist = None + master_window = self.root + sv = debugger.StackViewer(master_window, flist, gui) + self.assertTrue(hasattr(sv, 'stack')) + + def test_load_stack(self): + # Test the .load_stack() method against a fixed test stack. + # Check the test stack is assigned and the list contains the repr of them. + self.assertEqual(self.sv.stack, self.stack) + self.assertTrue('?.(), line 1:' in self.sv.get(0)) + self.assertEqual(self.sv.get(1), '?.(), line 2: ') + + def test_show_source(self): + # Test the .show_source() method against a fixed test stack. + # Patch out the file list to monitor it + self.sv.flist = Mock() + # Patch out isfile to pretend file exists. + with patch('idlelib.debugger.os.path.isfile', return_value=True) as isfile: + self.sv.show_source(1) + isfile.assert_called_once_with('test_stackviewer.py') + self.sv.flist.open.assert_called_once_with('test_stackviewer.py') + class NameSpaceTest(unittest.TestCase): @classmethod def setUpClass(cls): + requires('gui') cls.root = Tk() cls.root.withdraw() @@ -23,7 +293,5 @@ def test_init(self): debugger.NamespaceViewer(self.root, 'Test') -# Other classes are Idb, Debugger, and StackViewer. - if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_debugobj.py b/Lib/idlelib/idle_test/test_debugobj.py index 131ce22b8bb69b..90ace4e1bc4f9e 100644 --- a/Lib/idlelib/idle_test/test_debugobj.py +++ b/Lib/idlelib/idle_test/test_debugobj.py @@ -37,7 +37,7 @@ def test_isexpandable(self): def test_keys(self): ti = debugobj.SequenceTreeItem('label', 'abc') - self.assertEqual(list(ti.keys()), [0, 1, 2]) + self.assertEqual(list(ti.keys()), [0, 1, 2]) # keys() is a range. class DictTreeItemTest(unittest.TestCase): @@ -50,7 +50,7 @@ def test_isexpandable(self): def test_keys(self): ti = debugobj.DictTreeItem('label', {1:1, 0:0, 2:2}) - self.assertEqual(ti.keys(), [0, 1, 2]) + self.assertEqual(ti.keys(), [0, 1, 2]) # keys() is a sorted list. if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_help_about.py b/Lib/idlelib/idle_test/test_help_about.py index 8b79487b15d4cd..7e16abdb7c9f96 100644 --- a/Lib/idlelib/idle_test/test_help_about.py +++ b/Lib/idlelib/idle_test/test_help_about.py @@ -71,7 +71,7 @@ def test_file_buttons(self): """Test buttons that display files.""" dialog = self.dialog button_sources = [(self.dialog.readme, 'README.txt', 'readme'), - (self.dialog.idle_news, 'NEWS.txt', 'news'), + (self.dialog.idle_news, 'News3.txt', 'news'), (self.dialog.idle_credits, 'CREDITS.txt', 'credits')] for button, filename, name in button_sources: diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index af8159c2b33f51..464126e2df0668 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -7,7 +7,7 @@ from tkinter import filedialog from tkinter import messagebox -from tkinter.simpledialog import askstring +from tkinter.simpledialog import askstring # loadfile encoding. from idlelib.config import idleConf from idlelib.util import py_extensions @@ -180,24 +180,25 @@ def loadfile(self, filename): return True def maybesave(self): + """Return 'yes', 'no', 'cancel' as appropriate. + + Tkinter messagebox.askyesnocancel converts these tk responses + to True, False, None. Convert back, as now expected elsewhere. + """ if self.get_saved(): return "yes" - message = "Do you want to save %s before closing?" % ( - self.filename or "this untitled document") + message = ("Do you want to save " + f"{self.filename or 'this untitled document'}" + " before closing?") confirm = messagebox.askyesnocancel( title="Save On Close", message=message, default=messagebox.YES, parent=self.text) if confirm: - reply = "yes" self.save(None) - if not self.get_saved(): - reply = "cancel" - elif confirm is None: - reply = "cancel" - else: - reply = "no" + reply = "yes" if self.get_saved() else "cancel" + else: reply = "cancel" if confirm is None else "no" self.text.focus_set() return reply @@ -393,13 +394,15 @@ def updaterecentfileslist(self,filename): if self.editwin.flist: self.editwin.update_recent_files_list(filename) + def _io_binding(parent): # htest # from tkinter import Toplevel, Text - root = Toplevel(parent) - root.title("Test IOBinding") + top = Toplevel(parent) + top.title("Test IOBinding") x, y = map(int, parent.geometry().split('+')[1:]) - root.geometry("+%d+%d" % (x, y + 175)) + top.geometry("+%d+%d" % (x, y + 175)) + class MyEditWin: def __init__(self, text): self.text = text @@ -423,12 +426,13 @@ def saveas(self, event): def savecopy(self, event): self.text.event_generate("<>") - text = Text(root) + text = Text(top) text.pack() text.focus_set() editwin = MyEditWin(text) IOBinding(editwin) + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False) diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py index 2ea02ec04d661a..332952f4572cbd 100644 --- a/Lib/idlelib/macosx.py +++ b/Lib/idlelib/macosx.py @@ -221,7 +221,7 @@ def help_dialog(event=None): # The binding above doesn't reliably work on all versions of Tk # on macOS. Adding command definition below does seem to do the # right thing for now. - root.createcommand('exit', flist.close_all_callback) + root.createcommand('::tk::mac::Quit', flist.close_all_callback) if isCarbonTk(): # for Carbon AquaTk, replace the default Tk apple menu diff --git a/Lib/idlelib/multicall.py b/Lib/idlelib/multicall.py index 0200f445cc9340..41f81813113062 100644 --- a/Lib/idlelib/multicall.py +++ b/Lib/idlelib/multicall.py @@ -421,6 +421,8 @@ def _multi_call(parent): # htest # top.geometry("+%d+%d" % (x, y + 175)) text = MultiCallCreator(tkinter.Text)(top) text.pack() + text.focus_set() + def bindseq(seq, n=[0]): def handler(event): print(seq) @@ -440,6 +442,7 @@ def handler(event): bindseq("") bindseq("") + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_mainmenu', verbosity=2, exit=False) diff --git a/Lib/idlelib/outwin.py b/Lib/idlelib/outwin.py index 610031e26f1dff..5ed3f35a7af655 100644 --- a/Lib/idlelib/outwin.py +++ b/Lib/idlelib/outwin.py @@ -182,6 +182,7 @@ def setup(self): text.tag_raise('sel') self.write = self.owin.write + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_outwin', verbosity=2, exit=False) diff --git a/Lib/idlelib/pathbrowser.py b/Lib/idlelib/pathbrowser.py index 6de242d0000bed..48a77875ba5801 100644 --- a/Lib/idlelib/pathbrowser.py +++ b/Lib/idlelib/pathbrowser.py @@ -99,13 +99,9 @@ def listmodules(self, allnames): return sorted -def _path_browser(parent): # htest # - PathBrowser(parent, _htest=True) - parent.mainloop() - if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_pathbrowser', verbosity=2, exit=False) from idlelib.idle_test.htest import run - run(_path_browser) + run(PathBrowser) diff --git a/Lib/idlelib/percolator.py b/Lib/idlelib/percolator.py index 1fe34d29f54eb2..aa73427c4915c8 100644 --- a/Lib/idlelib/percolator.py +++ b/Lib/idlelib/percolator.py @@ -86,11 +86,11 @@ def delete(self, *args): print(self.name, ": delete", args) self.delegate.delete(*args) - box = tk.Toplevel(parent) - box.title("Test Percolator") + top = tk.Toplevel(parent) + top.title("Test Percolator") x, y = map(int, parent.geometry().split('+')[1:]) - box.geometry("+%d+%d" % (x, y + 175)) - text = tk.Text(box) + top.geometry("+%d+%d" % (x, y + 175)) + text = tk.Text(top) p = Percolator(text) pin = p.insertfilter pout = p.removefilter @@ -103,13 +103,15 @@ def toggle2(): (pin if var2.get() else pout)(t2) text.pack() + text.focus_set() var1 = tk.IntVar(parent) - cb1 = tk.Checkbutton(box, text="Tracer1", command=toggle1, variable=var1) + cb1 = tk.Checkbutton(top, text="Tracer1", command=toggle1, variable=var1) cb1.pack() var2 = tk.IntVar(parent) - cb2 = tk.Checkbutton(box, text="Tracer2", command=toggle2, variable=var2) + cb2 = tk.Checkbutton(top, text="Tracer2", command=toggle2, variable=var2) cb2.pack() + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_percolator', verbosity=2, exit=False) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 6028700356b171..1524fccd5d20f8 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -133,8 +133,8 @@ class PyShellEditorWindow(EditorWindow): def __init__(self, *args): self.breakpoints = [] EditorWindow.__init__(self, *args) - self.text.bind("<>", self.set_breakpoint_here) - self.text.bind("<>", self.clear_breakpoint_here) + self.text.bind("<>", self.set_breakpoint_event) + self.text.bind("<>", self.clear_breakpoint_event) self.text.bind("<>", self.flist.open_shell) #TODO: don't read/write this from/to .idlerc when testing @@ -155,8 +155,8 @@ def filename_changed_hook(old_hook=self.io.filename_change_hook, ("Copy", "<>", "rmenu_check_copy"), ("Paste", "<>", "rmenu_check_paste"), (None, None, None), - ("Set Breakpoint", "<>", None), - ("Clear Breakpoint", "<>", None) + ("Set Breakpoint", "<>", None), + ("Clear Breakpoint", "<>", None) ] def color_breakpoint_text(self, color=True): @@ -181,11 +181,11 @@ def set_breakpoint(self, lineno): self.breakpoints.append(lineno) try: # update the subprocess debugger debug = self.flist.pyshell.interp.debugger - debug.set_breakpoint_here(filename, lineno) + debug.set_breakpoint(filename, lineno) except: # but debugger may not be active right now.... pass - def set_breakpoint_here(self, event=None): + def set_breakpoint_event(self, event=None): text = self.text filename = self.io.filename if not filename: @@ -194,7 +194,7 @@ def set_breakpoint_here(self, event=None): lineno = int(float(text.index("insert"))) self.set_breakpoint(lineno) - def clear_breakpoint_here(self, event=None): + def clear_breakpoint_event(self, event=None): text = self.text filename = self.io.filename if not filename: @@ -209,7 +209,7 @@ def clear_breakpoint_here(self, event=None): "insert lineend +1char") try: debug = self.flist.pyshell.interp.debugger - debug.clear_breakpoint_here(filename, lineno) + debug.clear_breakpoint(filename, lineno) except: pass @@ -747,10 +747,11 @@ def showtraceback(self): self.tkconsole.open_stack_viewer() def checklinecache(self): - c = linecache.cache - for key in list(c.keys()): + "Remove keys other than ''." + cache = linecache.cache + for key in list(cache): # Iterate list because mutate cache. if key[:1] + key[-1:] != "<>": - del c[key] + del cache[key] def runcommand(self, code): "Run the code without invoking the debugger" @@ -1693,6 +1694,7 @@ def main(): root.destroy() capture_warnings(False) + if __name__ == "__main__": main() diff --git a/Lib/idlelib/query.py b/Lib/idlelib/query.py index df02f2123ab02f..57230e2aaca66d 100644 --- a/Lib/idlelib/query.py +++ b/Lib/idlelib/query.py @@ -368,7 +368,7 @@ def create_extra(self): sticky='we') def cli_args_ok(self): - "Validity check and parsing for command line arguments." + "Return command line arg list or None if error." cli_string = self.entry.get().strip() try: cli_args = shlex.split(cli_string, posix=True) diff --git a/Lib/idlelib/redirector.py b/Lib/idlelib/redirector.py index 4928340e98df68..08728956abd900 100644 --- a/Lib/idlelib/redirector.py +++ b/Lib/idlelib/redirector.py @@ -164,6 +164,7 @@ def my_insert(*args): original_insert(*args) original_insert = redir.register("insert", my_insert) + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_redirector', verbosity=2, exit=False) diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py index ca83173877ad1d..7997f24f1b0fa6 100644 --- a/Lib/idlelib/replace.py +++ b/Lib/idlelib/replace.py @@ -120,7 +120,7 @@ def _replace_expand(self, m, repl): if self.engine.isre(): try: new = m.expand(repl) - except re.error: + except re.PatternError: self.engine.report_error(repl, 'Invalid Replace Expression') new = None else: @@ -299,6 +299,7 @@ def show_replace(): button = Button(frame, text="Replace", command=show_replace) button.pack() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_replace', verbosity=2, exit=False) diff --git a/Lib/idlelib/scrolledlist.py b/Lib/idlelib/scrolledlist.py index 71fd18ab19ec8a..4fb418db326255 100644 --- a/Lib/idlelib/scrolledlist.py +++ b/Lib/idlelib/scrolledlist.py @@ -132,6 +132,7 @@ def _scrolled_list(parent): # htest # top = Toplevel(parent) x, y = map(int, parent.geometry().split('+')[1:]) top.geometry("+%d+%d" % (x+200, y + 175)) + class MyScrolledList(ScrolledList): def fill_menu(self): self.menu.add_command(label="right click") def on_select(self, index): print("select", self.get(index)) @@ -141,9 +142,10 @@ def on_double(self, index): print("double", self.get(index)) for i in range(30): scrolled_list.append("Item %02d" % i) + if __name__ == '__main__': from unittest import main - main('idlelib.idle_test.test_scrolledlist', verbosity=2,) + main('idlelib.idle_test.test_scrolledlist', verbosity=2, exit=False) from idlelib.idle_test.htest import run run(_scrolled_list) diff --git a/Lib/idlelib/search.py b/Lib/idlelib/search.py index b35f3b59c3d2e8..935a4832257fa4 100644 --- a/Lib/idlelib/search.py +++ b/Lib/idlelib/search.py @@ -156,6 +156,7 @@ def show_find(): button = Button(frame, text="Search (selection ignored)", command=show_find) button.pack() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_search', verbosity=2, exit=False) diff --git a/Lib/idlelib/searchengine.py b/Lib/idlelib/searchengine.py index 0684142f43644a..ceb38cfaef900b 100644 --- a/Lib/idlelib/searchengine.py +++ b/Lib/idlelib/searchengine.py @@ -84,7 +84,7 @@ def getprog(self): flags = flags | re.IGNORECASE try: prog = re.compile(pat, flags) - except re.error as e: + except re.PatternError as e: self.report_error(pat, e.msg, e.pos) return None return prog diff --git a/Lib/idlelib/sidebar.py b/Lib/idlelib/sidebar.py index fb1084dbf3f18b..ff77b568a786e0 100644 --- a/Lib/idlelib/sidebar.py +++ b/Lib/idlelib/sidebar.py @@ -25,10 +25,9 @@ def get_end_linenumber(text): def get_displaylines(text, index): """Display height, in lines, of a logical line in a Tk text widget.""" - res = text.count(f"{index} linestart", - f"{index} lineend", - "displaylines") - return res[0] if res else 0 + return text.count(f"{index} linestart", + f"{index} lineend", + "displaylines") def get_widget_padding(widget): """Get the total padding of a Tk widget, including its border.""" @@ -514,16 +513,16 @@ def update_colors(self): self.change_callback() -def _linenumbers_drag_scrolling(parent): # htest # +def _sidebar_number_scrolling(parent): # htest # from idlelib.idle_test.test_sidebar import Dummy_editwin - toplevel = tk.Toplevel(parent) - text_frame = tk.Frame(toplevel) + top = tk.Toplevel(parent) + text_frame = tk.Frame(top) text_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) text_frame.rowconfigure(1, weight=1) text_frame.columnconfigure(1, weight=1) - font = idleConf.GetFont(toplevel, 'main', 'EditorWindow') + font = idleConf.GetFont(top, 'main', 'EditorWindow') text = tk.Text(text_frame, width=80, height=24, wrap=tk.NONE, font=font) text.grid(row=1, column=1, sticky=tk.NSEW) @@ -541,4 +540,4 @@ def _linenumbers_drag_scrolling(parent): # htest # main('idlelib.idle_test.test_sidebar', verbosity=2, exit=False) from idlelib.idle_test.htest import run - run(_linenumbers_drag_scrolling) + run(_sidebar_number_scrolling) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 7b00c4cdb7d033..977c56ef15f2ae 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -1,3 +1,5 @@ +# Rename to stackbrowser or possibly consolidate with browser. + import linecache import os @@ -99,7 +101,7 @@ def IsExpandable(self): def GetSubList(self): sublist = [] - for key in self.object.keys(): + for key in self.object.keys(): # self.object not necessarily dict. try: value = self.object[key] except KeyError: @@ -111,7 +113,7 @@ def setfunction(value, key=key, object=self.object): return sublist -def _stack_viewer(parent): # htest # +def _stackbrowser(parent): # htest # from idlelib.pyshell import PyShellFileList top = tk.Toplevel(parent) top.title("Test StackViewer") @@ -129,4 +131,4 @@ def _stack_viewer(parent): # htest # main('idlelib.idle_test.test_stackviewer', verbosity=2, exit=False) from idlelib.idle_test.htest import run - run(_stack_viewer) + run(_stackbrowser) diff --git a/Lib/idlelib/statusbar.py b/Lib/idlelib/statusbar.py index 755fafb0ac6438..8445d4cc8dfdb9 100644 --- a/Lib/idlelib/statusbar.py +++ b/Lib/idlelib/statusbar.py @@ -26,6 +26,7 @@ def _multistatus_bar(parent): # htest # x, y = map(int, parent.geometry().split('+')[1:]) top.geometry("+%d+%d" %(x, y + 175)) top.title("Test multistatus bar") + frame = Frame(top) text = Text(frame, height=5, width=40) text.pack() @@ -42,6 +43,7 @@ def change(): button.pack(side='bottom') frame.pack() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_statusbar', verbosity=2, exit=False) diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index 5f30f0f6092bfa..9c2eb47b24aec9 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -492,6 +492,7 @@ def _tree_widget(parent): # htest # node = TreeNode(sc.canvas, None, item) node.expand() + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_tree', verbosity=2, exit=False) diff --git a/Lib/idlelib/undo.py b/Lib/idlelib/undo.py index 5f10c0f05c1acb..f52446d5fcdcf8 100644 --- a/Lib/idlelib/undo.py +++ b/Lib/idlelib/undo.py @@ -339,25 +339,26 @@ def bump_depth(self, incr=1): def _undo_delegator(parent): # htest # from tkinter import Toplevel, Text, Button from idlelib.percolator import Percolator - undowin = Toplevel(parent) - undowin.title("Test UndoDelegator") + top = Toplevel(parent) + top.title("Test UndoDelegator") x, y = map(int, parent.geometry().split('+')[1:]) - undowin.geometry("+%d+%d" % (x, y + 175)) + top.geometry("+%d+%d" % (x, y + 175)) - text = Text(undowin, height=10) + text = Text(top, height=10) text.pack() text.focus_set() p = Percolator(text) d = UndoDelegator() p.insertfilter(d) - undo = Button(undowin, text="Undo", command=lambda:d.undo_event(None)) + undo = Button(top, text="Undo", command=lambda:d.undo_event(None)) undo.pack(side='left') - redo = Button(undowin, text="Redo", command=lambda:d.redo_event(None)) + redo = Button(top, text="Redo", command=lambda:d.redo_event(None)) redo.pack(side='left') - dump = Button(undowin, text="Dump", command=lambda:d.dump_event(None)) + dump = Button(top, text="Dump", command=lambda:d.dump_event(None)) dump.pack(side='left') + if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_undo', verbosity=2, exit=False) diff --git a/Lib/idlelib/util.py b/Lib/idlelib/util.py index ede670a4db5536..5ac69a7b94cb56 100644 --- a/Lib/idlelib/util.py +++ b/Lib/idlelib/util.py @@ -16,6 +16,7 @@ # .pyw is for Windows; .pyi is for stub files. py_extensions = ('.py', '.pyw', '.pyi') # Order needed for open/save dialogs. + if __name__ == '__main__': from unittest import main main('idlelib.idle_test.test_util', verbosity=2) diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index ec2e56f6ea9ca1..d942045f3de666 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -824,10 +824,16 @@ def _module_repr_from_spec(spec): """Return the repr to use for the module.""" name = '?' if spec.name is None else spec.name if spec.origin is None: - if spec.loader is None: + loader = spec.loader + if loader is None: return f'' + elif ( + _bootstrap_external is not None + and isinstance(loader, _bootstrap_external.NamespaceLoader) + ): + return f'' else: - return f'' + return f'' else: if spec.has_location: return f'' diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 0019897c943e14..d537598ac16433 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -413,6 +413,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a7 3492 (make POP_JUMP_IF_NONE/NOT_NONE/TRUE/FALSE relative) # Python 3.11a7 3493 (Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative) # Python 3.11a7 3494 (New location info table) +# Python 3.11b4 3495 (Set line number of module's RESUME instr to 0 per PEP 626) # Python 3.12a1 3500 (Remove PRECALL opcode) # Python 3.12a1 3501 (YIELD_VALUE oparg == stack_depth) # Python 3.12a1 3502 (LOAD_FAST_CHECK, no NULL-check in LOAD_FAST) @@ -459,6 +460,8 @@ def _write_atomic(path, data, mode=0o666): # 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.13a1 3564 (Removed oparg from YIELD_VALUE, changed oparg values of RESUME) +# Python 3.13a1 3565 (Oparg of YIELD_VALUE indicates whether it is in a yield-from) # Python 3.14 will start with 3600 @@ -475,7 +478,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 = (3563).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3565).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index f4d6e82331516f..3ad71d31c2f438 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -135,7 +135,7 @@ class _incompatible_extension_module_restrictions: may not be imported in a subinterpreter. That implies modules that do not implement multi-phase init or that explicitly of out. - Likewise for modules import in a subinterpeter with its own GIL + Likewise for modules import in a subinterpreter with its own GIL when the extension does not support a per-interpreter GIL. This implies the module does not have a Py_mod_multiple_interpreters slot set to Py_MOD_PER_INTERPRETER_GIL_SUPPORTED. diff --git a/Lib/inspect.py b/Lib/inspect.py index aaa22bef896602..f0b72662a9a0b2 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -3316,6 +3316,16 @@ def __repr__(self): return '<{} {}>'.format(self.__class__.__name__, self) def __str__(self): + return self.format() + + def format(self, *, max_width=None): + """Create a string representation of the Signature object. + + If *max_width* integer is passed, + signature will try to fit into the *max_width*. + If signature is longer than *max_width*, + all parameters will be on separate lines. + """ result = [] render_pos_only_separator = False render_kw_only_separator = True @@ -3353,6 +3363,8 @@ def __str__(self): result.append('/') rendered = '({})'.format(', '.join(result)) + if max_width is not None and len(rendered) > max_width: + rendered = '(\n {}\n)'.format(',\n '.join(result)) if self.return_annotation is not _empty: anno = formatannotation(self.return_annotation) diff --git a/Lib/io.py b/Lib/io.py index 50ce97436ac1d1..f0e2fa15d5abcf 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -45,7 +45,8 @@ "FileIO", "BytesIO", "StringIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", "BufferedRWPair", "BufferedRandom", "TextIOBase", "TextIOWrapper", - "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] + "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END", + "DEFAULT_BUFFER_SIZE", "text_encoding", "IncrementalNewlineDecoder"] import _io diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index f5aba434fd4253..e398cc138308d9 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1389,6 +1389,16 @@ def is_link_local(self): """ return self in self._constants._linklocal_network + @property + def ipv6_mapped(self): + """Return the IPv4-mapped IPv6 address. + + Returns: + The IPv4-mapped IPv6 address per RFC 4291. + + """ + return IPv6Address(f'::ffff:{self}') + class IPv4Interface(IPv4Address): @@ -1970,6 +1980,9 @@ def __eq__(self, other): return False return self._scope_id == getattr(other, '_scope_id', None) + def __reduce__(self): + return (self.__class__, (str(self),)) + @property def scope_id(self): """Identifier of a particular zone of the address's scope. diff --git a/Lib/linecache.py b/Lib/linecache.py index 97644a8e3794e1..329a14053458b7 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -5,10 +5,8 @@ that name. """ -import functools import sys import os -import tokenize __all__ = ["getline", "clearcache", "checkcache", "lazycache"] @@ -82,6 +80,8 @@ def updatecache(filename, module_globals=None): If something's wrong, print a message, discard the cache entry, and return an empty list.""" + import tokenize + if filename in cache: if len(cache[filename]) != 1: cache.pop(filename, None) @@ -176,7 +176,16 @@ def lazycache(filename, module_globals): get_source = getattr(loader, 'get_source', None) if name and get_source: - get_lines = functools.partial(get_source, name) + def get_lines(name=name, *args, **kwargs): + return get_source(name, *args, **kwargs) 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/locale.py b/Lib/locale.py index 55c819ca80a160..e0cb4c5449d556 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -541,12 +541,14 @@ def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): """ import warnings - warnings.warn( - "Use setlocale(), getencoding() and getlocale() instead", - DeprecationWarning, stacklevel=2 - ) + warnings._deprecated( + "locale.getdefaultlocale", + "{name!r} is deprecated and slated for removal in Python {remove}. " + "Use setlocale(), getencoding() and getlocale() instead.", + remove=(3, 15)) return _getdefaultlocale(envvars) + def _getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): try: # check if it's supported by the _locale module diff --git a/Lib/logging/config.py b/Lib/logging/config.py index 951bba73913cb3..4b520e3b1e0da6 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -482,10 +482,10 @@ def configure_custom(self, config): c = config.pop('()') if not callable(c): c = self.resolve(c) - props = config.pop('.', None) # Check for valid identifiers - kwargs = {k: config[k] for k in config if valid_ident(k)} + kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))} result = c(**kwargs) + props = config.pop('.', None) if props: for name, value in props.items(): setattr(result, name, value) @@ -835,8 +835,7 @@ def configure_handler(self, config): factory = functools.partial(self._configure_queue_handler, klass) else: factory = klass - props = config.pop('.', None) - kwargs = {k: config[k] for k in config if valid_ident(k)} + kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))} try: result = factory(**kwargs) except TypeError as te: @@ -854,6 +853,7 @@ def configure_handler(self, config): result.setLevel(logging._checkLevel(level)) if filters: self.add_filters(result, filters) + props = config.pop('.', None) if props: for name, value in props.items(): setattr(result, name, value) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index e75da9b7b1de64..9840b7b0aeba88 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -830,10 +830,8 @@ class SysLogHandler(logging.Handler): "local7": LOG_LOCAL7, } - #The map below appears to be trivially lowercasing the key. However, - #there's more to it than meets the eye - in some locales, lowercasing - #gives unexpected results. See SF #1524081: in the Turkish locale, - #"INFO".lower() != "info" + # Originally added to work around GH-43683. Unnecessary since GH-50043 but kept + # for backwards compatibility. priority_map = { "DEBUG" : "debug", "INFO" : "info", diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 59834a2b3b5243..36afaded705d0a 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -395,6 +395,56 @@ def get_file(self, key): f = open(os.path.join(self._path, self._lookup(key)), 'rb') return _ProxyFile(f) + def get_info(self, key): + """Get the keyed message's "info" as a string.""" + subpath = self._lookup(key) + if self.colon in subpath: + return subpath.split(self.colon)[-1] + return '' + + def set_info(self, key, info: str): + """Set the keyed message's "info" string.""" + if not isinstance(info, str): + raise TypeError(f'info must be a string: {type(info)}') + old_subpath = self._lookup(key) + new_subpath = old_subpath.split(self.colon)[0] + if info: + new_subpath += self.colon + info + if new_subpath == old_subpath: + return + old_path = os.path.join(self._path, old_subpath) + new_path = os.path.join(self._path, new_subpath) + os.rename(old_path, new_path) + self._toc[key] = new_subpath + + def get_flags(self, key): + """Return as a string the standard flags that are set on the keyed message.""" + info = self.get_info(key) + if info.startswith('2,'): + return info[2:] + return '' + + def set_flags(self, key, flags: str): + """Set the given flags and unset all others on the keyed message.""" + if not isinstance(flags, str): + raise TypeError(f'flags must be a string: {type(flags)}') + # TODO: check if flags are valid standard flag characters? + self.set_info(key, '2,' + ''.join(sorted(set(flags)))) + + def add_flag(self, key, flag: str): + """Set the given flag(s) without changing others on the keyed message.""" + if not isinstance(flag, str): + raise TypeError(f'flag must be a string: {type(flag)}') + # TODO: check that flag is a valid standard flag character? + self.set_flags(key, ''.join(set(self.get_flags(key)) | set(flag))) + + def remove_flag(self, key, flag: str): + """Unset the given string flag(s) without changing others on the keyed message.""" + if not isinstance(flag, str): + raise TypeError(f'flag must be a string: {type(flag)}') + if self.get_flags(key): + self.set_flags(key, ''.join(set(self.get_flags(key)) - set(flag))) + def iterkeys(self): """Return an iterator over keys.""" self._refresh() diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 273c22a7654f05..96cebc6eabec89 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -1165,15 +1165,19 @@ def __imul__(self, value): self._callmethod('__imul__', (value,)) return self + __class_getitem__ = classmethod(types.GenericAlias) + -DictProxy = MakeProxyType('DictProxy', ( +_BaseDictProxy = MakeProxyType('DictProxy', ( '__contains__', '__delitem__', '__getitem__', '__iter__', '__len__', '__setitem__', 'clear', 'copy', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values' )) -DictProxy._method_to_typeid_ = { +_BaseDictProxy._method_to_typeid_ = { '__iter__': 'Iterator', } +class DictProxy(_BaseDictProxy): + __class_getitem__ = classmethod(types.GenericAlias) ArrayProxy = MakeProxyType('ArrayProxy', ( 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/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/shared_memory.py b/Lib/multiprocessing/shared_memory.py index 9a1e5aa17b87a2..67e70fdc27cf31 100644 --- a/Lib/multiprocessing/shared_memory.py +++ b/Lib/multiprocessing/shared_memory.py @@ -71,8 +71,9 @@ class SharedMemory: _flags = os.O_RDWR _mode = 0o600 _prepend_leading_slash = True if _USE_POSIX else False + _track = True - def __init__(self, name=None, create=False, size=0): + def __init__(self, name=None, create=False, size=0, *, track=True): if not size >= 0: raise ValueError("'size' must be a positive integer") if create: @@ -82,6 +83,7 @@ def __init__(self, name=None, create=False, size=0): if name is None and not self._flags & os.O_EXCL: raise ValueError("'name' can only be None if create=True") + self._track = track if _USE_POSIX: # POSIX Shared Memory @@ -116,8 +118,8 @@ def __init__(self, name=None, create=False, size=0): except OSError: self.unlink() raise - - resource_tracker.register(self._name, "shared_memory") + if self._track: + resource_tracker.register(self._name, "shared_memory") else: @@ -236,12 +238,20 @@ def close(self): def unlink(self): """Requests that the underlying shared memory block be destroyed. - In order to ensure proper cleanup of resources, unlink should be - called once (and only once) across all processes which have access - to the shared memory block.""" + Unlink should be called once (and only once) across all handles + which have access to the shared memory block, even if these + handles belong to different processes. Closing and unlinking may + happen in any order, but trying to access data inside a shared + memory block after unlinking may result in memory errors, + depending on platform. + + This method has no effect on Windows, where the only way to + delete a shared memory block is to close all handles.""" + if _USE_POSIX and self._name: _posixshmem.shm_unlink(self._name) - resource_tracker.unregister(self._name, "shared_memory") + if self._track: + resource_tracker.unregister(self._name, "shared_memory") _encoding = "utf8" diff --git a/Lib/ntpath.py b/Lib/ntpath.py index df3402d46c9cc6..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 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 deleted file mode 100644 index bd5f61b0b7c878..00000000000000 --- a/Lib/pathlib.py +++ /dev/null @@ -1,1415 +0,0 @@ -"""Object-oriented filesystem paths. - -This module provides classes to represent abstract paths and concrete -paths with operations that have semantics appropriate for different -operating systems. -""" - -import fnmatch -import functools -import io -import ntpath -import os -import posixpath -import re -import sys -import warnings -from _collections_abc import Sequence -from errno import ENOENT, ENOTDIR, EBADF, ELOOP -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 - - -__all__ = [ - "UnsupportedOperation", - "PurePath", "PurePosixPath", "PureWindowsPath", - "Path", "PosixPath", "WindowsPath", - ] - -# -# Internals -# - -# Reference for Windows paths can be found at -# https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file . -_WIN_RESERVED_NAMES = frozenset( - {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | - {f'COM{c}' for c in '123456789\xb9\xb2\xb3'} | - {f'LPT{c}' for c in '123456789\xb9\xb2\xb3'} -) - -_WINERROR_NOT_READY = 21 # drive exists but is not accessible -_WINERROR_INVALID_NAME = 123 # fix for bpo-35306 -_WINERROR_CANT_RESOLVE_FILENAME = 1921 # broken symlink pointing to itself - -# EBADF - guard against macOS `stat` throwing EBADF -_IGNORED_ERRNOS = (ENOENT, ENOTDIR, EBADF, ELOOP) - -_IGNORED_WINERRORS = ( - _WINERROR_NOT_READY, - _WINERROR_INVALID_NAME, - _WINERROR_CANT_RESOLVE_FILENAME) - -def _ignore_error(exception): - return (getattr(exception, 'errno', None) in _IGNORED_ERRNOS or - getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) - - -@functools.cache -def _is_case_sensitive(pathmod): - return pathmod.normcase('Aa') == 'Aa' - -# -# Globbing helpers -# - - -# fnmatch.translate() returns a regular expression that includes a prefix and -# a suffix, which enable matching newlines and ensure the end of the string is -# matched, respectively. These features are undesirable for our implementation -# of PurePatch.match(), which represents path separators as newlines and joins -# pattern segments together. As a workaround, we define a slice object that -# can remove the prefix and suffix from any translate() result. See the -# _compile_pattern_lines() function for more details. -_FNMATCH_PREFIX, _FNMATCH_SUFFIX = fnmatch.translate('_').split('_') -_FNMATCH_SLICE = slice(len(_FNMATCH_PREFIX), -len(_FNMATCH_SUFFIX)) -_SWAP_SEP_AND_NEWLINE = { - '/': str.maketrans({'/': '\n', '\n': '/'}), - '\\': str.maketrans({'\\': '\n', '\n': '\\'}), -} - - -@functools.lru_cache(maxsize=256) -def _compile_pattern(pat, case_sensitive): - """Compile given glob pattern to a re.Pattern object (observing case - sensitivity), or None if the pattern should match everything.""" - if pat == '*': - return None - flags = re.NOFLAG if case_sensitive else re.IGNORECASE - return re.compile(fnmatch.translate(pat), flags).match - - -@functools.lru_cache() -def _compile_pattern_lines(pattern_lines, case_sensitive): - """Compile the given pattern lines to an `re.Pattern` object. - - The *pattern_lines* argument is a glob-style pattern (e.g. '**/*.py') with - its path separators and newlines swapped (e.g. '**\n*.py`). By using - newlines to separate path components, and not setting `re.DOTALL`, we - ensure that the `*` wildcard cannot match path separators. - - The returned `re.Pattern` object may have its `match()` method called to - match a complete pattern, or `search()` to match from the right. The - argument supplied to these methods must also have its path separators and - newlines swapped. - """ - - # Match the start of the path, or just after a path separator - parts = ['^'] - for part in pattern_lines.splitlines(keepends=True): - if part == '*\n': - part = r'.+\n' - elif part == '*': - part = r'.+' - elif part == '**\n': - # '**/' component: we use '[\s\S]' rather than '.' so that path - # separators (i.e. newlines) are matched. The trailing '^' ensures - # we terminate after a path separator (i.e. on a new line). - part = r'[\s\S]*^' - elif part == '**': - # '**' component. - part = r'[\s\S]*' - elif '**' in part: - raise ValueError("Invalid pattern: '**' can only be an entire path component") - else: - # Any other component: pass to fnmatch.translate(). We slice off - # the common prefix and suffix added by translate() to ensure that - # re.DOTALL is not set, and the end of the string not matched, - # respectively. With DOTALL not set, '*' wildcards will not match - # path separators, because the '.' characters in the pattern will - # not match newlines. - part = fnmatch.translate(part)[_FNMATCH_SLICE] - parts.append(part) - # Match the end of the path, always. - parts.append(r'\Z') - flags = re.MULTILINE - if not case_sensitive: - flags |= re.IGNORECASE - return re.compile(''.join(parts), flags=flags) - - -def _select_children(parent_paths, dir_only, follow_symlinks, match): - """Yield direct children of given paths, filtering by name and type.""" - if follow_symlinks is None: - follow_symlinks = True - for parent_path in parent_paths: - try: - # We must close the scandir() object before proceeding to - # avoid exhausting file descriptors when globbing deep trees. - with parent_path._scandir() as scandir_it: - entries = list(scandir_it) - except OSError: - pass - else: - for entry in entries: - if dir_only: - try: - if not entry.is_dir(follow_symlinks=follow_symlinks): - continue - except OSError: - continue - name = entry.name - if match is None or match(name): - yield parent_path._make_child_relpath(name) - - -def _select_recursive(parent_paths, dir_only, follow_symlinks): - """Yield given paths and all their subdirectories, recursively.""" - if follow_symlinks is None: - follow_symlinks = False - for parent_path in parent_paths: - paths = [parent_path] - while paths: - path = paths.pop() - yield path - try: - # We must close the scandir() object before proceeding to - # avoid exhausting file descriptors when globbing deep trees. - with path._scandir() as scandir_it: - entries = list(scandir_it) - except OSError: - pass - else: - for entry in entries: - try: - if entry.is_dir(follow_symlinks=follow_symlinks): - paths.append(path._make_child_relpath(entry.name)) - continue - except OSError: - pass - if not dir_only: - yield path._make_child_relpath(entry.name) - - -def _select_unique(paths): - """Yields the given paths, filtering out duplicates.""" - yielded = set() - try: - for path in paths: - path_str = str(path) - if path_str not in yielded: - yield path - yielded.add(path_str) - finally: - yielded.clear() - - -# -# Public API -# - -class UnsupportedOperation(NotImplementedError): - """An exception that is raised when an unsupported operation is called on - a path object. - """ - pass - - -class _PathParents(Sequence): - """This object provides sequence-like access to the logical ancestors - of a path. Don't try to construct it yourself.""" - __slots__ = ('_path', '_drv', '_root', '_tail') - - def __init__(self, path): - self._path = path - self._drv = path.drive - self._root = path.root - self._tail = path._tail - - def __len__(self): - return len(self._tail) - - def __getitem__(self, idx): - if isinstance(idx, slice): - return tuple(self[i] for i in range(*idx.indices(len(self)))) - - if idx >= len(self) or idx < -len(self): - raise IndexError(idx) - if idx < 0: - idx += len(self) - return self._path._from_parsed_parts(self._drv, self._root, - self._tail[:-idx - 1]) - - def __repr__(self): - return "<{}.parents>".format(type(self._path).__name__) - - -class PurePath: - """Base class for manipulating paths without I/O. - - PurePath represents a filesystem path and offers operations which - don't imply any actual filesystem I/O. Depending on your system, - instantiating a PurePath will return either a PurePosixPath or a - PureWindowsPath object. You can also instantiate either of these classes - directly, regardless of your system. - """ - - __slots__ = ( - # The `_raw_paths` slot stores unnormalized string paths. This is set - # in the `__init__()` method. - '_raw_paths', - - # The `_drv`, `_root` and `_tail_cached` slots store parsed and - # normalized parts of the path. They are set when any of the `drive`, - # `root` or `_tail` properties are accessed for the first time. The - # three-part division corresponds to the result of - # `os.path.splitroot()`, except that the tail is further split on path - # separators (i.e. it is a list of strings), and that the root and - # tail are normalized. - '_drv', '_root', '_tail_cached', - - # The `_str` slot stores the string representation of the path, - # computed from the drive, root and tail when `__str__()` is called - # for the first time. It's used to implement `_str_normcase` - '_str', - - # The `_str_normcase_cached` slot stores the string path with - # normalized case. It is set when the `_str_normcase` property is - # accessed for the first time. It's used to implement `__eq__()` - # `__hash__()`, and `_parts_normcase` - '_str_normcase_cached', - - # The `_parts_normcase_cached` slot stores the case-normalized - # string path after splitting on path separators. It's set when the - # `_parts_normcase` property is accessed for the first time. It's used - # to implement comparison methods like `__lt__()`. - '_parts_normcase_cached', - - # The `_lines_cached` slot stores the string path with path separators - # and newlines swapped. This is used to implement `match()`. - '_lines_cached', - - # The `_hash` slot stores the hash of the case-normalized string - # path. It's set when `__hash__()` is called for the first time. - '_hash', - ) - pathmod = os.path - - def __new__(cls, *args, **kwargs): - """Construct a PurePath from one or several strings and or existing - PurePath objects. The strings and path objects are combined so as - to yield a canonicalized path, which is incorporated into the - new PurePath object. - """ - if cls is PurePath: - cls = PureWindowsPath if os.name == 'nt' else PurePosixPath - return object.__new__(cls) - - def __reduce__(self): - # Using the parts tuple helps share interned path parts - # when pickling related paths. - return (self.__class__, self.parts) - - def __init__(self, *args): - paths = [] - for arg in args: - if isinstance(arg, PurePath): - if arg.pathmod is ntpath and self.pathmod is posixpath: - # GH-103631: Convert separators for backwards compatibility. - paths.extend(path.replace('\\', '/') for path in arg._raw_paths) - else: - paths.extend(arg._raw_paths) - else: - try: - path = os.fspath(arg) - except TypeError: - path = arg - if not isinstance(path, str): - raise TypeError( - "argument should be a str or an os.PathLike " - "object where __fspath__ returns a str, " - f"not {type(path).__name__!r}") - paths.append(path) - self._raw_paths = paths - - def with_segments(self, *pathsegments): - """Construct a new path object from any number of path-like objects. - Subclasses may override this method to customize how new path objects - are created from methods like `iterdir()`. - """ - return type(self)(*pathsegments) - - @classmethod - def _parse_path(cls, path): - if not path: - return '', '', [] - sep = cls.pathmod.sep - altsep = cls.pathmod.altsep - if altsep: - path = path.replace(altsep, sep) - drv, root, rel = cls.pathmod.splitroot(path) - if not root and drv.startswith(sep) and not drv.endswith(sep): - drv_parts = drv.split(sep) - if len(drv_parts) == 4 and drv_parts[2] not in '?.': - # e.g. //server/share - root = sep - elif len(drv_parts) == 6: - # e.g. //?/unc/server/share - root = sep - parsed = [sys.intern(str(x)) for x in rel.split(sep) if x and x != '.'] - return drv, root, parsed - - def _load_parts(self): - paths = self._raw_paths - if len(paths) == 0: - path = '' - elif len(paths) == 1: - path = paths[0] - else: - path = self.pathmod.join(*paths) - drv, root, tail = self._parse_path(path) - self._drv = drv - self._root = root - self._tail_cached = tail - - def _from_parsed_parts(self, drv, root, tail): - path_str = self._format_parsed_parts(drv, root, tail) - path = self.with_segments(path_str) - path._str = path_str or '.' - path._drv = drv - path._root = root - path._tail_cached = tail - return path - - @classmethod - def _format_parsed_parts(cls, drv, root, tail): - if drv or root: - return drv + root + cls.pathmod.sep.join(tail) - elif tail and cls.pathmod.splitdrive(tail[0])[0]: - tail = ['.'] + tail - return cls.pathmod.sep.join(tail) - - def __str__(self): - """Return the string representation of the path, suitable for - passing to system calls.""" - try: - return self._str - except AttributeError: - self._str = self._format_parsed_parts(self.drive, self.root, - self._tail) or '.' - return self._str - - def __fspath__(self): - return str(self) - - def as_posix(self): - """Return the string representation of the path with forward (/) - slashes.""" - return str(self).replace(self.pathmod.sep, '/') - - def __bytes__(self): - """Return the bytes representation of the path. This is only - recommended to use under Unix.""" - return os.fsencode(self) - - def __repr__(self): - return "{}({!r})".format(self.__class__.__name__, self.as_posix()) - - def as_uri(self): - """Return the path as a 'file' URI.""" - if not self.is_absolute(): - raise ValueError("relative path can't be expressed as a file URI") - - drive = self.drive - if len(drive) == 2 and drive[1] == ':': - # It's a path on a local drive => 'file:///c:/a/b' - prefix = 'file:///' + drive - path = self.as_posix()[2:] - elif drive: - # It's a path on a network drive => 'file://host/share/a/b' - prefix = 'file:' - path = self.as_posix() - else: - # It's a posix path => 'file:///etc/hosts' - prefix = 'file://' - path = str(self) - return prefix + urlquote_from_bytes(os.fsencode(path)) - - @property - def _str_normcase(self): - # String with normalized case, for hashing and equality checks - try: - return self._str_normcase_cached - except AttributeError: - if _is_case_sensitive(self.pathmod): - self._str_normcase_cached = str(self) - else: - self._str_normcase_cached = str(self).lower() - return self._str_normcase_cached - - @property - def _parts_normcase(self): - # Cached parts with normalized case, for comparisons. - try: - return self._parts_normcase_cached - except AttributeError: - self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep) - return self._parts_normcase_cached - - @property - def _lines(self): - # Path with separators and newlines swapped, for pattern matching. - try: - return self._lines_cached - except AttributeError: - path_str = str(self) - if path_str == '.': - self._lines_cached = '' - else: - trans = _SWAP_SEP_AND_NEWLINE[self.pathmod.sep] - self._lines_cached = path_str.translate(trans) - return self._lines_cached - - def __eq__(self, other): - if not isinstance(other, PurePath): - return NotImplemented - return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod - - def __hash__(self): - try: - return self._hash - except AttributeError: - self._hash = hash(self._str_normcase) - return self._hash - - def __lt__(self, other): - if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: - return NotImplemented - return self._parts_normcase < other._parts_normcase - - def __le__(self, other): - if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: - return NotImplemented - return self._parts_normcase <= other._parts_normcase - - def __gt__(self, other): - if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: - return NotImplemented - return self._parts_normcase > other._parts_normcase - - def __ge__(self, other): - if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: - return NotImplemented - return self._parts_normcase >= other._parts_normcase - - @property - def drive(self): - """The drive prefix (letter or UNC path), if any.""" - try: - return self._drv - except AttributeError: - self._load_parts() - return self._drv - - @property - def root(self): - """The root of the path, if any.""" - try: - return self._root - except AttributeError: - self._load_parts() - return self._root - - @property - def _tail(self): - try: - return self._tail_cached - except AttributeError: - self._load_parts() - return self._tail_cached - - @property - def anchor(self): - """The concatenation of the drive and root, or ''.""" - anchor = self.drive + self.root - return anchor - - @property - def name(self): - """The final path component, if any.""" - tail = self._tail - if not tail: - return '' - return tail[-1] - - @property - def suffix(self): - """ - The final component's last suffix, if any. - - This includes the leading period. For example: '.txt' - """ - name = self.name - i = name.rfind('.') - if 0 < i < len(name) - 1: - return name[i:] - else: - return '' - - @property - def suffixes(self): - """ - A list of the final component's suffixes, if any. - - These include the leading periods. For example: ['.tar', '.gz'] - """ - name = self.name - if name.endswith('.'): - return [] - name = name.lstrip('.') - return ['.' + suffix for suffix in name.split('.')[1:]] - - @property - def stem(self): - """The final path component, minus its last suffix.""" - name = self.name - i = name.rfind('.') - if 0 < i < len(name) - 1: - return name[:i] - else: - return name - - def with_name(self, name): - """Return a new path with the file name changed.""" - 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): - raise ValueError("Invalid name %r" % (name)) - return self._from_parsed_parts(self.drive, self.root, - self._tail[:-1] + [name]) - - def with_stem(self, stem): - """Return a new path with the stem changed.""" - return self.with_name(stem + self.suffix) - - def with_suffix(self, suffix): - """Return a new path with the file suffix changed. If the path - has no suffix, add given suffix. If the given suffix is an empty - string, remove the suffix from the path. - """ - m = self.pathmod - if m.sep in suffix or m.altsep and m.altsep in suffix: - raise ValueError("Invalid suffix %r" % (suffix,)) - if suffix and not suffix.startswith('.') or suffix == '.': - raise ValueError("Invalid suffix %r" % (suffix)) - name = self.name - if not name: - raise ValueError("%r has an empty name" % (self,)) - old_suffix = self.suffix - if not old_suffix: - name = name + suffix - else: - name = name[:-len(old_suffix)] + suffix - return self._from_parsed_parts(self.drive, self.root, - self._tail[:-1] + [name]) - - def relative_to(self, other, /, *_deprecated, walk_up=False): - """Return the relative path to another path identified by the passed - arguments. If the operation is not possible (because this is not - related to the other path), raise ValueError. - - The *walk_up* parameter controls whether `..` may be used to resolve - the path. - """ - if _deprecated: - msg = ("support for supplying more than one positional argument " - "to pathlib.PurePath.relative_to() is deprecated and " - "scheduled for removal in Python {remove}") - warnings._deprecated("pathlib.PurePath.relative_to(*args)", msg, - remove=(3, 14)) - other = self.with_segments(other, *_deprecated) - 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") - parts = ['..'] * step + self._tail[len(path._tail):] - return self.with_segments(*parts) - - def is_relative_to(self, other, /, *_deprecated): - """Return True if the path is relative to another path or False. - """ - if _deprecated: - msg = ("support for supplying more than one argument to " - "pathlib.PurePath.is_relative_to() is deprecated and " - "scheduled for removal in Python {remove}") - warnings._deprecated("pathlib.PurePath.is_relative_to(*args)", - msg, remove=(3, 14)) - other = self.with_segments(other, *_deprecated) - return other == self or other in self.parents - - @property - def parts(self): - """An object providing sequence-like access to the - components in the filesystem path.""" - if self.drive or self.root: - return (self.drive + self.root,) + tuple(self._tail) - else: - return tuple(self._tail) - - def joinpath(self, *pathsegments): - """Combine this path with one or several arguments, and return a - new path representing either a subpath (if all arguments are relative - paths) or a totally different path (if one of the arguments is - anchored). - """ - return self.with_segments(self, *pathsegments) - - def __truediv__(self, key): - try: - return self.joinpath(key) - except TypeError: - return NotImplemented - - def __rtruediv__(self, key): - try: - return self.with_segments(key, self) - except TypeError: - return NotImplemented - - @property - def parent(self): - """The logical parent of the path.""" - drv = self.drive - root = self.root - tail = self._tail - if not tail: - return self - return self._from_parsed_parts(drv, root, tail[:-1]) - - @property - def parents(self): - """A sequence of this path's logical parents.""" - # The value of this property should not be cached on the path object, - # as doing so would introduce a reference cycle. - return _PathParents(self) - - def is_absolute(self): - """True if the path is absolute (has both a root and, if applicable, - a drive).""" - if self.pathmod is ntpath: - # ntpath.isabs() is defective - see GH-44626. - return bool(self.drive and self.root) - elif self.pathmod is posixpath: - # Optimization: work with raw paths on POSIX. - for path in self._raw_paths: - if path.startswith('/'): - return True - return False - else: - return self.pathmod.isabs(str(self)) - - def is_reserved(self): - """Return True if the path contains one of the special names reserved - by the system, if any.""" - if self.pathmod is posixpath or not self._tail: - return False - - # NOTE: the rules for reserved names seem somewhat complicated - # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not - # exist). We err on the side of caution and return True for paths - # which are not considered reserved by Windows. - if self.drive.startswith('\\\\'): - # UNC paths are never reserved. - return False - name = self._tail[-1].partition('.')[0].partition(':')[0].rstrip(' ') - return name.upper() in _WIN_RESERVED_NAMES - - def match(self, path_pattern, *, case_sensitive=None): - """ - Return True if this path matches the given pattern. - """ - if not isinstance(path_pattern, PurePath): - path_pattern = self.with_segments(path_pattern) - if case_sensitive is None: - case_sensitive = _is_case_sensitive(self.pathmod) - pattern = _compile_pattern_lines(path_pattern._lines, case_sensitive) - if path_pattern.drive or path_pattern.root: - return pattern.match(self._lines) is not None - elif path_pattern._tail: - return pattern.search(self._lines) is not None - else: - raise ValueError("empty pattern") - - -# Subclassing os.PathLike makes isinstance() checks slower, -# which in turn makes Path construction slower. Register instead! -os.PathLike.register(PurePath) - - -class PurePosixPath(PurePath): - """PurePath subclass for non-Windows systems. - - On a POSIX system, instantiating a PurePath should return this object. - However, you can also instantiate it directly on any system. - """ - pathmod = posixpath - __slots__ = () - - -class PureWindowsPath(PurePath): - """PurePath subclass for Windows systems. - - On a Windows system, instantiating a PurePath should return this object. - However, you can also instantiate it directly on any system. - """ - pathmod = ntpath - __slots__ = () - - -# Filesystem-accessing classes - - -class Path(PurePath): - """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__ = () - - 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 lstat(self): - """ - Like stat(), except if the path points to a symlink, the symlink's - status information is returned, rather than its target's. - """ - return self.stat(follow_symlinks=False) - - - # Convenience functions for querying the stat results - - def exists(self, *, follow_symlinks=True): - """ - Whether this path exists. - - This method normally follows symlinks; to check whether a symlink exists, - add the argument follow_symlinks=False. - """ - try: - self.stat(follow_symlinks=follow_symlinks) - except OSError as e: - if not _ignore_error(e): - raise - return False - except ValueError: - # Non-encodable path - return False - return True - - def is_dir(self, *, follow_symlinks=True): - """ - Whether this path is a directory. - """ - try: - return S_ISDIR(self.stat(follow_symlinks=follow_symlinks).st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_file(self, *, follow_symlinks=True): - """ - Whether this path is a regular file (also True for symlinks pointing - to regular files). - """ - try: - return S_ISREG(self.stat(follow_symlinks=follow_symlinks).st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_mount(self): - """ - Check if this path is a mount point - """ - return os.path.ismount(self) - - def is_symlink(self): - """ - Whether this path is a symbolic link. - """ - try: - return S_ISLNK(self.lstat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist - return False - except ValueError: - # Non-encodable path - return False - - def is_junction(self): - """ - Whether this path is a junction. - """ - return os.path.isjunction(self) - - def is_block_device(self): - """ - Whether this path is a block device. - """ - try: - return S_ISBLK(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_char_device(self): - """ - Whether this path is a character device. - """ - try: - return S_ISCHR(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_fifo(self): - """ - Whether this path is a FIFO. - """ - try: - return S_ISFIFO(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_socket(self): - """ - Whether this path is a socket. - """ - try: - return S_ISSOCK(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def samefile(self, other_path): - """Return whether other_path is the same or not as this file - (as returned by os.path.samefile()). - """ - st = self.stat() - try: - other_st = other_path.stat() - except AttributeError: - other_st = self.with_segments(other_path).stat() - return (st.st_ino == other_st.st_ino and - st.st_dev == other_st.st_dev) - - 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 read_bytes(self): - """ - Open the file in bytes mode, read it, and close the file. - """ - with self.open(mode='rb') as f: - return f.read() - - def read_text(self, encoding=None, errors=None): - """ - Open the file in text mode, read it, and close the file. - """ - encoding = io.text_encoding(encoding) - with self.open(mode='r', encoding=encoding, errors=errors) as f: - return f.read() - - def write_bytes(self, data): - """ - Open the file in bytes mode, write to it, and close the file. - """ - # type-check for the buffer interface before truncating the file - view = memoryview(data) - with self.open(mode='wb') as f: - return f.write(view) - - def write_text(self, data, encoding=None, errors=None, newline=None): - """ - Open the file in text mode, write to it, and close the file. - """ - if not isinstance(data, str): - raise TypeError('data must be str, not %s' % - data.__class__.__name__) - encoding = io.text_encoding(encoding) - with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f: - return f.write(data) - - 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): - # bpo-24132: a future version of pathlib will support subclassing of - # pathlib.Path to customize how the filesystem is accessed. This - # includes scandir(), which is used to implement glob(). - return os.scandir(self) - - def _make_child_relpath(self, name): - sep = self.pathmod.sep - lines_name = name.replace('\n', sep) - lines_str = self._lines - path_str = str(self) - tail = self._tail - if tail: - path_str = f'{path_str}{sep}{name}' - lines_str = f'{lines_str}\n{lines_name}' - elif path_str != '.': - path_str = f'{path_str}{name}' - lines_str = f'{lines_str}{lines_name}' - else: - path_str = name - lines_str = lines_name - path = self.with_segments(path_str) - path._str = path_str - path._drv = self.drive - path._root = self.root - path._tail_cached = tail + [name] - path._lines_cached = lines_str - return path - - def glob(self, pattern, *, case_sensitive=None, follow_symlinks=None): - """Iterate over this subtree and yield all existing files (of any - kind, including directories) matching the given relative pattern. - """ - sys.audit("pathlib.Path.glob", self, pattern) - return self._glob(pattern, case_sensitive, follow_symlinks) - - def rglob(self, pattern, *, case_sensitive=None, follow_symlinks=None): - """Recursively yield all existing files (of any kind, including - directories) matching the given relative pattern, anywhere in - this subtree. - """ - sys.audit("pathlib.Path.rglob", self, pattern) - return self._glob(f'**/{pattern}', case_sensitive, follow_symlinks) - - def _glob(self, pattern, case_sensitive, follow_symlinks): - path_pattern = self.with_segments(pattern) - if path_pattern.drive or path_pattern.root: - raise NotImplementedError("Non-relative patterns are unsupported") - elif not path_pattern._tail: - raise ValueError("Unacceptable pattern: {!r}".format(pattern)) - - pattern_parts = list(path_pattern._tail) - if pattern[-1] in (self.pathmod.sep, self.pathmod.altsep): - # GH-65238: pathlib doesn't preserve trailing slash. Add it back. - 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: - # TODO: evaluate case-sensitivity of each directory in _select_children(). - case_sensitive = _is_case_sensitive(self.pathmod) - - # If symlinks are handled consistently, and the pattern does not - # contain '..' components, then we can use a 'walk-and-match' strategy - # when expanding '**' wildcards. When a '**' wildcard is encountered, - # all following pattern parts are immediately consumed and used to - # build a `re.Pattern` object. This pattern is used to filter the - # recursive walk. As a result, pattern parts following a '**' wildcard - # do not perform any filesystem access, which can be much faster! - filter_paths = follow_symlinks is not None and '..' not in pattern_parts - deduplicate_paths = False - paths = iter([self] if self.is_dir() else []) - part_idx = 0 - while part_idx < len(pattern_parts): - part = pattern_parts[part_idx] - part_idx += 1 - if part == '': - # Trailing slash. - pass - elif part == '..': - paths = (path._make_child_relpath('..') for path in paths) - elif part == '**': - # Consume adjacent '**' components. - while part_idx < len(pattern_parts) and pattern_parts[part_idx] == '**': - part_idx += 1 - - if filter_paths and part_idx < len(pattern_parts) and pattern_parts[part_idx] != '': - dir_only = pattern_parts[-1] == '' - paths = _select_recursive(paths, dir_only, follow_symlinks) - - # Filter out paths that don't match pattern. - prefix_len = len(self._make_child_relpath('_')._lines) - 1 - match = _compile_pattern_lines(path_pattern._lines, case_sensitive).match - paths = (path for path in paths if match(path._lines[prefix_len:])) - return paths - - dir_only = part_idx < len(pattern_parts) - paths = _select_recursive(paths, dir_only, follow_symlinks) - if deduplicate_paths: - # De-duplicate if we've already seen a '**' component. - paths = _select_unique(paths) - deduplicate_paths = True - elif '**' in part: - raise ValueError("Invalid pattern: '**' can only be an entire path component") - else: - dir_only = part_idx < len(pattern_parts) - match = _compile_pattern(part, case_sensitive) - paths = _select_children(paths, dir_only, follow_symlinks, match) - return paths - - def walk(self, top_down=True, on_error=None, follow_symlinks=False): - """Walk the directory tree from this directory, similar to os.walk().""" - sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks) - paths = [self] - - while paths: - path = paths.pop() - if isinstance(path, tuple): - yield path - continue - - # We may not have read permission for self, in which case we can't - # get a list of the files the directory contains. os.walk() - # always suppressed the exception in that instance, rather than - # blow up for a minor reason when (say) a thousand readable - # directories are still left to visit. That logic is copied here. - try: - scandir_it = path._scandir() - except OSError as error: - if on_error is not None: - on_error(error) - continue - - with scandir_it: - dirnames = [] - filenames = [] - for entry in scandir_it: - try: - is_dir = entry.is_dir(follow_symlinks=follow_symlinks) - except OSError: - # Carried over from os.path.isdir(). - is_dir = False - - if is_dir: - dirnames.append(entry.name) - else: - filenames.append(entry.name) - - if top_down: - yield path, dirnames, filenames - else: - paths.append((path, dirnames, filenames)) - - 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 __new__(cls, *args, **kwargs): - if cls is Path: - cls = WindowsPath if os.name == 'nt' else PosixPath - return object.__new__(cls) - - @classmethod - def cwd(cls): - """Return a new path pointing to the current working directory.""" - # We call 'absolute()' rather than using 'os.getcwd()' directly to - # enable users to replace the implementation of 'absolute()' in a - # subclass and benefit from the new behaviour here. This works because - # os.path.abspath('.') == os.getcwd(). - return cls().absolute() - - @classmethod - def home(cls): - """Return a new path pointing to the user's home directory (as - returned by os.path.expanduser('~')). - """ - return cls("~").expanduser() - - def absolute(self): - """Return an absolute version of this path by prepending the current - working directory. No normalization or symlink resolution is performed. - - Use resolve() to get the canonical path to a file. - """ - if self.is_absolute(): - return self - elif self.drive: - # There is a CWD on each drive-letter drive. - cwd = os.path.abspath(self.drive) - else: - cwd = os.getcwd() - # Fast path for "empty" paths, e.g. Path("."), Path("") or Path(). - # We pass only one argument to with_segments() to avoid the cost - # of joining, and we exploit the fact that getcwd() returns a - # fully-normalized string by storing it in _str. This is used to - # implement Path.cwd(). - if not self.root and not self._tail: - result = self.with_segments(cwd) - result._str = cwd - return result - return self.with_segments(cwd, self) - - def resolve(self, strict=False): - """ - Make the path absolute, resolving all symlinks on the way and also - normalizing it. - """ - - return self.with_segments(os.path.realpath(self, strict=strict)) - - def owner(self): - """ - Return the login name of the file owner. - """ - try: - import pwd - 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 - 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)) - - def touch(self, mode=0o666, exist_ok=True): - """ - Create this file with the given access mode, if it doesn't exist. - """ - - if exist_ok: - # First try to bump modification time - # Implementation note: GNU touch uses the UTIME_NOW option of - # the utimensat() / futimens() functions. - try: - os.utime(self, None) - except OSError: - # Avoid exception chaining - pass - else: - return - flags = os.O_CREAT | os.O_WRONLY - if not exist_ok: - flags |= os.O_EXCL - fd = os.open(self, flags, mode) - os.close(fd) - - def mkdir(self, mode=0o777, parents=False, exist_ok=False): - """ - Create a new directory at this given path. - """ - try: - os.mkdir(self, mode) - except FileNotFoundError: - if not parents or self.parent == self: - raise - self.parent.mkdir(parents=True, exist_ok=True) - self.mkdir(mode, parents=False, exist_ok=exist_ok) - except OSError: - # Cannot rely on checking for EEXIST, since the operating system - # could give priority to other errors like EACCES or EROFS - if not exist_ok or not self.is_dir(): - raise - - def chmod(self, mode, *, follow_symlinks=True): - """ - Change the permissions of the path, like os.chmod(). - """ - 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. - If the path is a directory, use rmdir() instead. - """ - try: - os.unlink(self) - except FileNotFoundError: - if not missing_ok: - raise - - def rmdir(self): - """ - Remove this directory. The directory must be empty. - """ - os.rmdir(self) - - 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. - """ - os.rename(self, target) - return self.with_segments(target) - - 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. - """ - 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) - - 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) - - def expanduser(self): - """ Return a new path with expanded ~ and ~user constructs - (as returned by os.path.expanduser) - """ - if (not (self.drive or self.root) and - self._tail and self._tail[0][:1] == '~'): - homedir = os.path.expanduser(self._tail[0]) - if homedir[:1] == "~": - raise RuntimeError("Could not determine home directory.") - drv, root, tail = self._parse_path(homedir) - return self._from_parsed_parts(drv, root, tail + self._tail[1:]) - - return self - - -class PosixPath(Path, PurePosixPath): - """Path subclass for non-Windows systems. - - On a POSIX system, instantiating a Path should return this object. - """ - __slots__ = () - - if os.name == 'nt': - def __new__(cls, *args, **kwargs): - raise UnsupportedOperation( - f"cannot instantiate {cls.__name__!r} on your system") - -class WindowsPath(Path, PureWindowsPath): - """Path subclass for Windows systems. - - On a Windows system, instantiating a Path should return this object. - """ - __slots__ = () - - if os.name != 'nt': - def __new__(cls, *args, **kwargs): - raise UnsupportedOperation( - f"cannot instantiate {cls.__name__!r} on your system") diff --git a/Lib/pathlib/__init__.py b/Lib/pathlib/__init__.py new file mode 100644 index 00000000000000..b020d2db350da8 --- /dev/null +++ b/Lib/pathlib/__init__.py @@ -0,0 +1,509 @@ +"""Object-oriented filesystem paths. + +This module provides classes to represent abstract paths and concrete +paths with operations that have semantics appropriate for different +operating systems. +""" + +import io +import ntpath +import os +import posixpath + +try: + import pwd +except ImportError: + pwd = None +try: + import grp +except ImportError: + grp = None + +from . import _abc + + +__all__ = [ + "UnsupportedOperation", + "PurePath", "PurePosixPath", "PureWindowsPath", + "Path", "PosixPath", "WindowsPath", + ] + + +UnsupportedOperation = _abc.UnsupportedOperation + + +class PurePath(_abc.PurePathBase): + """Base class for manipulating paths without I/O. + + PurePath represents a filesystem path and offers operations which + don't imply any actual filesystem I/O. Depending on your system, + instantiating a PurePath will return either a PurePosixPath or a + PureWindowsPath object. You can also instantiate either of these classes + directly, regardless of your system. + """ + + __slots__ = ( + # The `_str_normcase_cached` slot stores the string path with + # normalized case. It is set when the `_str_normcase` property is + # accessed for the first time. It's used to implement `__eq__()` + # `__hash__()`, and `_parts_normcase` + '_str_normcase_cached', + + # The `_parts_normcase_cached` slot stores the case-normalized + # string path after splitting on path separators. It's set when the + # `_parts_normcase` property is accessed for the first time. It's used + # to implement comparison methods like `__lt__()`. + '_parts_normcase_cached', + + # The `_hash` slot stores the hash of the case-normalized string + # path. It's set when `__hash__()` is called for the first time. + '_hash', + ) + + def __new__(cls, *args, **kwargs): + """Construct a PurePath from one or several strings and or existing + PurePath objects. The strings and path objects are combined so as + to yield a canonicalized path, which is incorporated into the + new PurePath object. + """ + if cls is PurePath: + cls = PureWindowsPath if os.name == 'nt' else PurePosixPath + return object.__new__(cls) + + def __init__(self, *args): + paths = [] + for arg in args: + if isinstance(arg, PurePath): + if arg.pathmod is ntpath and self.pathmod is posixpath: + # GH-103631: Convert separators for backwards compatibility. + paths.extend(path.replace('\\', '/') for path in arg._raw_paths) + else: + paths.extend(arg._raw_paths) + else: + try: + path = os.fspath(arg) + except TypeError: + path = arg + if not isinstance(path, str): + raise TypeError( + "argument should be a str or an os.PathLike " + "object where __fspath__ returns a str, " + f"not {type(path).__name__!r}") + paths.append(path) + # Avoid calling super().__init__, as an optimisation + self._raw_paths = paths + self._resolving = False + + def __reduce__(self): + # Using the parts tuple helps share interned path parts + # when pickling related paths. + return (self.__class__, self.parts) + + def __fspath__(self): + return str(self) + + def __bytes__(self): + """Return the bytes representation of the path. This is only + recommended to use under Unix.""" + return os.fsencode(self) + + @property + def _str_normcase(self): + # String with normalized case, for hashing and equality checks + try: + return self._str_normcase_cached + except AttributeError: + if _abc._is_case_sensitive(self.pathmod): + self._str_normcase_cached = str(self) + else: + self._str_normcase_cached = str(self).lower() + return self._str_normcase_cached + + def __hash__(self): + try: + return self._hash + except AttributeError: + self._hash = hash(self._str_normcase) + return self._hash + + def __eq__(self, other): + if not isinstance(other, PurePath): + return NotImplemented + return self._str_normcase == other._str_normcase and self.pathmod is other.pathmod + + @property + def _parts_normcase(self): + # Cached parts with normalized case, for comparisons. + try: + return self._parts_normcase_cached + except AttributeError: + self._parts_normcase_cached = self._str_normcase.split(self.pathmod.sep) + return self._parts_normcase_cached + + def __lt__(self, other): + if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: + return NotImplemented + return self._parts_normcase < other._parts_normcase + + def __le__(self, other): + if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: + return NotImplemented + return self._parts_normcase <= other._parts_normcase + + def __gt__(self, other): + if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: + return NotImplemented + return self._parts_normcase > other._parts_normcase + + def __ge__(self, other): + if not isinstance(other, PurePath) or self.pathmod is not other.pathmod: + return NotImplemented + return self._parts_normcase >= other._parts_normcase + + def as_uri(self): + """Return the path as a URI.""" + if not self.is_absolute(): + raise ValueError("relative path can't be expressed as a file URI") + + drive = self.drive + if len(drive) == 2 and drive[1] == ':': + # It's a path on a local drive => 'file:///c:/a/b' + prefix = 'file:///' + drive + path = self.as_posix()[2:] + elif drive: + # It's a path on a network drive => 'file://host/share/a/b' + prefix = 'file:' + path = self.as_posix() + else: + # It's a posix path => 'file:///etc/hosts' + prefix = 'file://' + path = str(self) + from urllib.parse import quote_from_bytes + return prefix + quote_from_bytes(os.fsencode(path)) + + +# Subclassing os.PathLike makes isinstance() checks slower, +# which in turn makes Path construction slower. Register instead! +os.PathLike.register(PurePath) + + +class PurePosixPath(PurePath): + """PurePath subclass for non-Windows systems. + + On a POSIX system, instantiating a PurePath should return this object. + However, you can also instantiate it directly on any system. + """ + pathmod = posixpath + __slots__ = () + + +class PureWindowsPath(PurePath): + """PurePath subclass for Windows systems. + + On a Windows system, instantiating a PurePath should return this object. + However, you can also instantiate it directly on any system. + """ + pathmod = ntpath + __slots__ = () + + +class Path(_abc.PathBase, PurePath): + """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__ = () + as_uri = PurePath.as_uri + + @classmethod + def _unsupported(cls, method_name): + msg = f"{cls.__name__}.{method_name}() is unsupported on this system" + raise UnsupportedOperation(msg) + + def __init__(self, *args, **kwargs): + if kwargs: + import warnings + 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 + No normalization or symlink resolution is performed. + + Use resolve() to resolve symlinks and remove '..' segments. + """ + if self.is_absolute(): + return self + if self.root: + drive = os.path.splitroot(os.getcwd())[0] + return self._from_parsed_parts(drive, self.root, self._tail) + if self.drive: + # There is a CWD on each drive-letter drive. + cwd = os.path.abspath(self.drive) + else: + cwd = os.getcwd() + if not self._tail: + # Fast path for "empty" paths, e.g. Path("."), Path("") or Path(). + # We pass only one argument to with_segments() to avoid the cost + # of joining, and we exploit the fact that getcwd() returns a + # fully-normalized string by storing it in _str. This is used to + # implement Path.cwd(). + result = self.with_segments(cwd) + result._str = cwd + return result + drive, root, rel = os.path.splitroot(cwd) + if not rel: + return self._from_parsed_parts(drive, root, self._tail) + tail = rel.split(self.pathmod.sep) + tail.extend(self._tail) + return self._from_parsed_parts(drive, root, tail) + + def resolve(self, strict=False): + """ + Make the path absolute, resolving all symlinks on the way and also + normalizing it. + """ + + return self.with_segments(os.path.realpath(self, strict=strict)) + + if pwd: + def owner(self, *, follow_symlinks=True): + """ + Return the login name of the file owner. + """ + uid = self.stat(follow_symlinks=follow_symlinks).st_uid + return pwd.getpwuid(uid).pw_name + + if grp: + def group(self, *, follow_symlinks=True): + """ + Return the group name of the file gid. + """ + gid = self.stat(follow_symlinks=follow_symlinks).st_gid + return grp.getgrgid(gid).gr_name + + 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): + """ + Create this file with the given access mode, if it doesn't exist. + """ + + if exist_ok: + # First try to bump modification time + # Implementation note: GNU touch uses the UTIME_NOW option of + # the utimensat() / futimens() functions. + try: + os.utime(self, None) + except OSError: + # Avoid exception chaining + pass + else: + return + flags = os.O_CREAT | os.O_WRONLY + if not exist_ok: + flags |= os.O_EXCL + fd = os.open(self, flags, mode) + os.close(fd) + + def mkdir(self, mode=0o777, parents=False, exist_ok=False): + """ + Create a new directory at this given path. + """ + try: + os.mkdir(self, mode) + except FileNotFoundError: + if not parents or self.parent == self: + raise + self.parent.mkdir(parents=True, exist_ok=True) + self.mkdir(mode, parents=False, exist_ok=exist_ok) + except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS + if not exist_ok or not self.is_dir(): + raise + + def chmod(self, mode, *, follow_symlinks=True): + """ + Change the permissions of the path, like os.chmod(). + """ + os.chmod(self, mode, follow_symlinks=follow_symlinks) + + def unlink(self, missing_ok=False): + """ + Remove this file or link. + If the path is a directory, use rmdir() instead. + """ + try: + os.unlink(self) + except FileNotFoundError: + if not missing_ok: + raise + + def rmdir(self): + """ + Remove this directory. The directory must be empty. + """ + os.rmdir(self) + + 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. + """ + os.rename(self, target) + return self.with_segments(target) + + 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. + """ + os.replace(self, target) + return self.with_segments(target) + + 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) + + 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. + """ + os.link(target, self) + + def expanduser(self): + """ Return a new path with expanded ~ and ~user constructs + (as returned by os.path.expanduser) + """ + if (not (self.drive or self.root) and + self._tail and self._tail[0][:1] == '~'): + homedir = os.path.expanduser(self._tail[0]) + if homedir[:1] == "~": + raise RuntimeError("Could not determine home directory.") + drv, root, tail = self._parse_path(homedir) + return self._from_parsed_parts(drv, root, tail + self._tail[1:]) + + 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. + + On a POSIX system, instantiating a Path should return this object. + """ + __slots__ = () + + if os.name == 'nt': + def __new__(cls, *args, **kwargs): + raise UnsupportedOperation( + f"cannot instantiate {cls.__name__!r} on your system") + +class WindowsPath(Path, PureWindowsPath): + """Path subclass for Windows systems. + + On a Windows system, instantiating a Path should return this object. + """ + __slots__ = () + + if os.name != 'nt': + def __new__(cls, *args, **kwargs): + raise UnsupportedOperation( + f"cannot instantiate {cls.__name__!r} on your system") diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py new file mode 100644 index 00000000000000..4808d0e61f7038 --- /dev/null +++ b/Lib/pathlib/_abc.py @@ -0,0 +1,1150 @@ +import functools +import io +import ntpath +import os +import posixpath +import sys +import warnings +from _collections_abc import Sequence +from errno import ENOENT, ENOTDIR, EBADF, ELOOP, EINVAL +from itertools import chain +from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO + +# +# 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( + {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | + {f'COM{c}' for c in '123456789\xb9\xb2\xb3'} | + {f'LPT{c}' for c in '123456789\xb9\xb2\xb3'} +) + +_WINERROR_NOT_READY = 21 # drive exists but is not accessible +_WINERROR_INVALID_NAME = 123 # fix for bpo-35306 +_WINERROR_CANT_RESOLVE_FILENAME = 1921 # broken symlink pointing to itself + +# EBADF - guard against macOS `stat` throwing EBADF +_IGNORED_ERRNOS = (ENOENT, ENOTDIR, EBADF, ELOOP) + +_IGNORED_WINERRORS = ( + _WINERROR_NOT_READY, + _WINERROR_INVALID_NAME, + _WINERROR_CANT_RESOLVE_FILENAME) + +def _ignore_error(exception): + return (getattr(exception, 'errno', None) in _IGNORED_ERRNOS or + getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) + + +@functools.cache +def _is_case_sensitive(pathmod): + return pathmod.normcase('Aa') == 'Aa' + +# +# Globbing helpers +# + +re = glob = None + + +@functools.lru_cache(maxsize=256) +def _compile_pattern(pat, sep, case_sensitive): + """Compile given glob pattern to a re.Pattern object (observing case + sensitivity).""" + global re, glob + if re is None: + import re, glob + + flags = re.NOFLAG if case_sensitive else re.IGNORECASE + regex = glob.translate(pat, recursive=True, include_hidden=True, seps=sep) + # The string representation of an empty path is a single dot ('.'). Empty + # paths shouldn't match wildcards, so we consume it with an atomic group. + regex = r'(\.\Z)?+' + regex + return re.compile(regex, flags=flags).match + + +def _select_children(parent_paths, dir_only, follow_symlinks, match): + """Yield direct children of given paths, filtering by name and type.""" + if follow_symlinks is None: + follow_symlinks = True + for parent_path in parent_paths: + try: + # We must close the scandir() object before proceeding to + # avoid exhausting file descriptors when globbing deep trees. + with parent_path._scandir() as scandir_it: + entries = list(scandir_it) + except OSError: + pass + else: + for entry in entries: + if dir_only: + try: + if not entry.is_dir(follow_symlinks=follow_symlinks): + continue + except OSError: + continue + name = entry.name + if match(name): + yield parent_path._make_child_relpath(name) + + +def _select_recursive(parent_paths, dir_only, follow_symlinks): + """Yield given paths and all their subdirectories, recursively.""" + if follow_symlinks is None: + follow_symlinks = False + for parent_path in parent_paths: + paths = [parent_path] + while paths: + path = paths.pop() + yield path + try: + # We must close the scandir() object before proceeding to + # avoid exhausting file descriptors when globbing deep trees. + with path._scandir() as scandir_it: + entries = list(scandir_it) + except OSError: + pass + else: + for entry in entries: + try: + if entry.is_dir(follow_symlinks=follow_symlinks): + paths.append(path._make_child_relpath(entry.name)) + continue + except OSError: + pass + if not dir_only: + yield path._make_child_relpath(entry.name) + + +def _select_unique(paths): + """Yields the given paths, filtering out duplicates.""" + yielded = set() + try: + for path in paths: + path_str = str(path) + if path_str not in yielded: + yield path + yielded.add(path_str) + finally: + yielded.clear() + + +class UnsupportedOperation(NotImplementedError): + """An exception that is raised when an unsupported operation is called on + a path object. + """ + pass + + +class _PathParents(Sequence): + """This object provides sequence-like access to the logical ancestors + of a path. Don't try to construct it yourself.""" + __slots__ = ('_path', '_drv', '_root', '_tail') + + def __init__(self, path): + self._path = path + self._drv = path.drive + self._root = path.root + self._tail = path._tail + + def __len__(self): + return len(self._tail) + + def __getitem__(self, idx): + if isinstance(idx, slice): + return tuple(self[i] for i in range(*idx.indices(len(self)))) + + if idx >= len(self) or idx < -len(self): + raise IndexError(idx) + if idx < 0: + idx += len(self) + return self._path._from_parsed_parts(self._drv, self._root, + self._tail[:-idx - 1]) + + def __repr__(self): + return "<{}.parents>".format(type(self._path).__name__) + + +class PurePathBase: + """Base class for pure path objects. + + This class *does not* provide several magic methods that are defined in + its subclass PurePath. They are: __fspath__, __bytes__, __reduce__, + __hash__, __eq__, __lt__, __le__, __gt__, __ge__. Its initializer and path + joining methods accept only strings, not os.PathLike objects more broadly. + """ + + __slots__ = ( + # The `_raw_paths` slot stores unnormalized string paths. This is set + # in the `__init__()` method. + '_raw_paths', + + # The `_drv`, `_root` and `_tail_cached` slots store parsed and + # normalized parts of the path. They are set when any of the `drive`, + # `root` or `_tail` properties are accessed for the first time. The + # three-part division corresponds to the result of + # `os.path.splitroot()`, except that the tail is further split on path + # separators (i.e. it is a list of strings), and that the root and + # tail are normalized. + '_drv', '_root', '_tail_cached', + + # The `_str` slot stores the string representation of the path, + # computed from the drive, root and tail when `__str__()` is called + # for the first time. It's used to implement `_str_normcase` + '_str', + + # 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 + + def __init__(self, *paths): + self._raw_paths = paths + self._resolving = False + + def with_segments(self, *pathsegments): + """Construct a new path object from any number of path-like objects. + Subclasses may override this method to customize how new path objects + are created from methods like `iterdir()`. + """ + return type(self)(*pathsegments) + + @classmethod + def _parse_path(cls, path): + if not path: + return '', '', [] + sep = cls.pathmod.sep + altsep = cls.pathmod.altsep + if altsep: + path = path.replace(altsep, sep) + drv, root, rel = cls.pathmod.splitroot(path) + if not root and drv.startswith(sep) and not drv.endswith(sep): + drv_parts = drv.split(sep) + if len(drv_parts) == 4 and drv_parts[2] not in '?.': + # e.g. //server/share + root = sep + elif len(drv_parts) == 6: + # e.g. //?/unc/server/share + root = sep + parsed = [sys.intern(str(x)) for x in rel.split(sep) if x and x != '.'] + return drv, root, parsed + + def _load_parts(self): + paths = self._raw_paths + if len(paths) == 0: + path = '' + elif len(paths) == 1: + path = paths[0] + else: + path = self.pathmod.join(*paths) + drv, root, tail = self._parse_path(path) + self._drv = drv + self._root = root + self._tail_cached = tail + + def _from_parsed_parts(self, drv, root, tail): + path_str = self._format_parsed_parts(drv, root, tail) + path = self.with_segments(path_str) + path._str = path_str or '.' + path._drv = drv + path._root = root + path._tail_cached = tail + return path + + @classmethod + def _format_parsed_parts(cls, drv, root, tail): + if drv or root: + return drv + root + cls.pathmod.sep.join(tail) + elif tail and cls.pathmod.splitdrive(tail[0])[0]: + tail = ['.'] + tail + return cls.pathmod.sep.join(tail) + + def __str__(self): + """Return the string representation of the path, suitable for + passing to system calls.""" + try: + return self._str + except AttributeError: + self._str = self._format_parsed_parts(self.drive, self.root, + self._tail) or '.' + return self._str + + def as_posix(self): + """Return the string representation of the path with forward (/) + slashes.""" + return str(self).replace(self.pathmod.sep, '/') + + def __repr__(self): + return "{}({!r})".format(self.__class__.__name__, self.as_posix()) + + @property + def drive(self): + """The drive prefix (letter or UNC path), if any.""" + try: + return self._drv + except AttributeError: + self._load_parts() + return self._drv + + @property + def root(self): + """The root of the path, if any.""" + try: + return self._root + except AttributeError: + self._load_parts() + return self._root + + @property + def _tail(self): + try: + return self._tail_cached + except AttributeError: + self._load_parts() + return self._tail_cached + + @property + def anchor(self): + """The concatenation of the drive and root, or ''.""" + anchor = self.drive + self.root + return anchor + + @property + def name(self): + """The final path component, if any.""" + tail = self._tail + if not tail: + return '' + return tail[-1] + + @property + def suffix(self): + """ + The final component's last suffix, if any. + + This includes the leading period. For example: '.txt' + """ + name = self.name + i = name.rfind('.') + if 0 < i < len(name) - 1: + return name[i:] + else: + return '' + + @property + def suffixes(self): + """ + A list of the final component's suffixes, if any. + + These include the leading periods. For example: ['.tar', '.gz'] + """ + name = self.name + if name.endswith('.'): + return [] + name = name.lstrip('.') + return ['.' + suffix for suffix in name.split('.')[1:]] + + @property + def stem(self): + """The final path component, minus its last suffix.""" + name = self.name + i = name.rfind('.') + if 0 < i < len(name) - 1: + return name[:i] + else: + return name + + def with_name(self, name): + """Return a new path with the file name changed.""" + m = self.pathmod + if not name or m.sep in name or (m.altsep and m.altsep in name) or name == '.': + raise ValueError(f"Invalid name {name!r}") + tail = self._tail.copy() + if not tail: + raise ValueError(f"{self!r} has an empty name") + tail[-1] = name + return self._from_parsed_parts(self.drive, self.root, tail) + + def with_stem(self, stem): + """Return a new path with the stem changed.""" + return self.with_name(stem + self.suffix) + + def with_suffix(self, suffix): + """Return a new path with the file suffix changed. If the path + has no suffix, add given suffix. If the given suffix is an empty + string, remove the suffix from the path. + """ + if not suffix: + return self.with_name(self.stem) + elif suffix.startswith('.') and len(suffix) > 1: + return self.with_name(self.stem + suffix) + else: + raise ValueError(f"Invalid suffix {suffix!r}") + + def relative_to(self, other, /, *_deprecated, walk_up=False): + """Return the relative path to another path identified by the passed + arguments. If the operation is not possible (because this is not + related to the other path), raise ValueError. + + The *walk_up* parameter controls whether `..` may be used to resolve + the path. + """ + if _deprecated: + msg = ("support for supplying more than one positional argument " + "to pathlib.PurePath.relative_to() is deprecated and " + "scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath.relative_to(*args)", msg, + remove=(3, 14)) + other = self.with_segments(other, *_deprecated) + elif not isinstance(other, PurePathBase): + other = self.with_segments(other) + for step, path in enumerate(chain([other], other.parents)): + if path == self or path in self.parents: + 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") + parts = ['..'] * step + self._tail[len(path._tail):] + return self._from_parsed_parts('', '', parts) + + def is_relative_to(self, other, /, *_deprecated): + """Return True if the path is relative to another path or False. + """ + if _deprecated: + msg = ("support for supplying more than one argument to " + "pathlib.PurePath.is_relative_to() is deprecated and " + "scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath.is_relative_to(*args)", + msg, remove=(3, 14)) + other = self.with_segments(other, *_deprecated) + elif not isinstance(other, PurePathBase): + other = self.with_segments(other) + return other == self or other in self.parents + + @property + def parts(self): + """An object providing sequence-like access to the + components in the filesystem path.""" + if self.drive or self.root: + return (self.drive + self.root,) + tuple(self._tail) + else: + return tuple(self._tail) + + def joinpath(self, *pathsegments): + """Combine this path with one or several arguments, and return a + new path representing either a subpath (if all arguments are relative + paths) or a totally different path (if one of the arguments is + anchored). + """ + return self.with_segments(*self._raw_paths, *pathsegments) + + def __truediv__(self, key): + try: + return self.joinpath(key) + except TypeError: + return NotImplemented + + def __rtruediv__(self, key): + try: + return self.with_segments(key, *self._raw_paths) + except TypeError: + return NotImplemented + + @property + def parent(self): + """The logical parent of the path.""" + drv = self.drive + root = self.root + tail = self._tail + if not tail: + return self + path = self._from_parsed_parts(drv, root, tail[:-1]) + path._resolving = self._resolving + return path + + @property + def parents(self): + """A sequence of this path's logical parents.""" + # The value of this property should not be cached on the path object, + # as doing so would introduce a reference cycle. + return _PathParents(self) + + def is_absolute(self): + """True if the path is absolute (has both a root and, if applicable, + a drive).""" + if self.pathmod is ntpath: + # ntpath.isabs() is defective - see GH-44626. + return bool(self.drive and self.root) + elif self.pathmod is posixpath: + # Optimization: work with raw paths on POSIX. + for path in self._raw_paths: + if path.startswith('/'): + return True + return False + else: + return self.pathmod.isabs(str(self)) + + def is_reserved(self): + """Return True if the path contains one of the special names reserved + by the system, if any.""" + if self.pathmod is posixpath or not self._tail: + return False + + # NOTE: the rules for reserved names seem somewhat complicated + # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not + # exist). We err on the side of caution and return True for paths + # which are not considered reserved by Windows. + if self.drive.startswith('\\\\'): + # UNC paths are never reserved. + return False + name = self._tail[-1].partition('.')[0].partition(':')[0].rstrip(' ') + return name.upper() in _WIN_RESERVED_NAMES + + def match(self, path_pattern, *, case_sensitive=None): + """ + Return True if this path matches the given pattern. + """ + if not isinstance(path_pattern, PurePathBase): + path_pattern = self.with_segments(path_pattern) + if case_sensitive is None: + case_sensitive = _is_case_sensitive(self.pathmod) + sep = path_pattern.pathmod.sep + pattern_str = str(path_pattern) + if path_pattern.drive or path_pattern.root: + pass + elif path_pattern._tail: + pattern_str = f'**{sep}{pattern_str}' + else: + raise ValueError("empty pattern") + match = _compile_pattern(pattern_str, sep, case_sensitive) + return match(str(self)) is not None + + + +class PathBase(PurePathBase): + """Base class for concrete path objects. + + 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__ = () + + @classmethod + def _unsupported(cls, method_name): + msg = f"{cls.__name__}.{method_name}() is unsupported" + raise UnsupportedOperation(msg) + + def stat(self, *, follow_symlinks=True): + """ + Return the result of the stat() system call on this path, like + os.stat() does. + """ + self._unsupported("stat") + + def lstat(self): + """ + Like stat(), except if the path points to a symlink, the symlink's + status information is returned, rather than its target's. + """ + return self.stat(follow_symlinks=False) + + + # Convenience functions for querying the stat results + + def exists(self, *, follow_symlinks=True): + """ + Whether this path exists. + + This method normally follows symlinks; to check whether a symlink exists, + add the argument follow_symlinks=False. + """ + try: + self.stat(follow_symlinks=follow_symlinks) + except OSError as e: + if not _ignore_error(e): + raise + return False + except ValueError: + # Non-encodable path + return False + return True + + def is_dir(self, *, follow_symlinks=True): + """ + Whether this path is a directory. + """ + try: + return S_ISDIR(self.stat(follow_symlinks=follow_symlinks).st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_file(self, *, follow_symlinks=True): + """ + Whether this path is a regular file (also True for symlinks pointing + to regular files). + """ + try: + return S_ISREG(self.stat(follow_symlinks=follow_symlinks).st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_mount(self): + """ + Check if this path is a mount point + """ + # Need to exist and be a dir + if not self.exists() or not self.is_dir(): + return False + + try: + parent_dev = self.parent.stat().st_dev + except OSError: + return False + + dev = self.stat().st_dev + if dev != parent_dev: + return True + ino = self.stat().st_ino + parent_ino = self.parent.stat().st_ino + return ino == parent_ino + + def is_symlink(self): + """ + Whether this path is a symbolic link. + """ + try: + return S_ISLNK(self.lstat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist + return False + except ValueError: + # Non-encodable path + return False + + def is_junction(self): + """ + Whether this path is a junction. + """ + # 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): + """ + Whether this path is a block device. + """ + try: + return S_ISBLK(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_char_device(self): + """ + Whether this path is a character device. + """ + try: + return S_ISCHR(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_fifo(self): + """ + Whether this path is a FIFO. + """ + try: + return S_ISFIFO(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_socket(self): + """ + Whether this path is a socket. + """ + try: + return S_ISSOCK(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def samefile(self, other_path): + """Return whether other_path is the same or not as this file + (as returned by os.path.samefile()). + """ + st = self.stat() + try: + other_st = other_path.stat() + except AttributeError: + other_st = self.with_segments(other_path).stat() + return (st.st_ino == other_st.st_ino and + st.st_dev == other_st.st_dev) + + 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. + """ + self._unsupported("open") + + def read_bytes(self): + """ + Open the file in bytes mode, read it, and close the file. + """ + with self.open(mode='rb') as f: + return f.read() + + def read_text(self, encoding=None, errors=None, newline=None): + """ + Open the file in text mode, read it, and close the file. + """ + encoding = io.text_encoding(encoding) + with self.open(mode='r', encoding=encoding, errors=errors, newline=newline) as f: + return f.read() + + def write_bytes(self, data): + """ + Open the file in bytes mode, write to it, and close the file. + """ + # type-check for the buffer interface before truncating the file + view = memoryview(data) + with self.open(mode='wb') as f: + return f.write(view) + + def write_text(self, data, encoding=None, errors=None, newline=None): + """ + Open the file in text mode, write to it, and close the file. + """ + if not isinstance(data, str): + raise TypeError('data must be str, not %s' % + data.__class__.__name__) + encoding = io.text_encoding(encoding) + with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f: + return f.write(data) + + 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. + """ + self._unsupported("iterdir") + + def _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(). + from contextlib import nullcontext + return nullcontext(self.iterdir()) + + def _make_child_relpath(self, name): + path_str = str(self) + tail = self._tail + if tail: + path_str = f'{path_str}{self.pathmod.sep}{name}' + elif path_str != '.': + path_str = f'{path_str}{name}' + else: + path_str = name + path = self.with_segments(path_str) + path._str = path_str + path._drv = self.drive + path._root = self.root + path._tail_cached = tail + [name] + return path + + def glob(self, pattern, *, case_sensitive=None, follow_symlinks=None): + """Iterate over this subtree and yield all existing files (of any + kind, including directories) matching the given relative pattern. + """ + sys.audit("pathlib.Path.glob", self, pattern) + return self._glob(pattern, case_sensitive, follow_symlinks) + + def rglob(self, pattern, *, case_sensitive=None, follow_symlinks=None): + """Recursively yield all existing files (of any kind, including + directories) matching the given relative pattern, anywhere in + this subtree. + """ + sys.audit("pathlib.Path.rglob", self, pattern) + return self._glob(f'**/{pattern}', case_sensitive, follow_symlinks) + + def _glob(self, pattern, case_sensitive, follow_symlinks): + path_pattern = self.with_segments(pattern) + if path_pattern.drive or path_pattern.root: + raise NotImplementedError("Non-relative patterns are unsupported") + elif not path_pattern._tail: + raise ValueError("Unacceptable pattern: {!r}".format(pattern)) + + pattern_parts = path_pattern._tail.copy() + if pattern[-1] in (self.pathmod.sep, self.pathmod.altsep): + # GH-65238: pathlib doesn't preserve trailing slash. Add it back. + 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: + # TODO: evaluate case-sensitivity of each directory in _select_children(). + case_sensitive = _is_case_sensitive(self.pathmod) + + # If symlinks are handled consistently, and the pattern does not + # contain '..' components, then we can use a 'walk-and-match' strategy + # when expanding '**' wildcards. When a '**' wildcard is encountered, + # all following pattern parts are immediately consumed and used to + # build a `re.Pattern` object. This pattern is used to filter the + # recursive walk. As a result, pattern parts following a '**' wildcard + # do not perform any filesystem access, which can be much faster! + filter_paths = follow_symlinks is not None and '..' not in pattern_parts + deduplicate_paths = False + sep = self.pathmod.sep + paths = iter([self] if self.is_dir() else []) + part_idx = 0 + while part_idx < len(pattern_parts): + part = pattern_parts[part_idx] + part_idx += 1 + if part == '': + # Trailing slash. + pass + elif part == '..': + paths = (path._make_child_relpath('..') for path in paths) + elif part == '**': + # Consume adjacent '**' components. + while part_idx < len(pattern_parts) and pattern_parts[part_idx] == '**': + part_idx += 1 + + if filter_paths and part_idx < len(pattern_parts) and pattern_parts[part_idx] != '': + dir_only = pattern_parts[-1] == '' + paths = _select_recursive(paths, dir_only, follow_symlinks) + + # Filter out paths that don't match pattern. + prefix_len = len(str(self._make_child_relpath('_'))) - 1 + match = _compile_pattern(str(path_pattern), sep, case_sensitive) + paths = (path for path in paths if match(str(path), prefix_len)) + return paths + + dir_only = part_idx < len(pattern_parts) + paths = _select_recursive(paths, dir_only, follow_symlinks) + if deduplicate_paths: + # De-duplicate if we've already seen a '**' component. + paths = _select_unique(paths) + deduplicate_paths = True + elif '**' in part: + raise ValueError("Invalid pattern: '**' can only be an entire path component") + else: + dir_only = part_idx < len(pattern_parts) + match = _compile_pattern(part, sep, case_sensitive) + paths = _select_children(paths, dir_only, follow_symlinks, match) + return paths + + def walk(self, top_down=True, on_error=None, follow_symlinks=False): + """Walk the directory tree from this directory, similar to os.walk().""" + sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks) + paths = [self] + + while paths: + path = paths.pop() + if isinstance(path, tuple): + yield path + continue + + # We may not have read permission for self, in which case we can't + # get a list of the files the directory contains. os.walk() + # always suppressed the exception in that instance, rather than + # blow up for a minor reason when (say) a thousand readable + # directories are still left to visit. That logic is copied here. + try: + scandir_obj = path._scandir() + except OSError as error: + if on_error is not None: + on_error(error) + continue + + with scandir_obj as scandir_it: + dirnames = [] + filenames = [] + for entry in scandir_it: + try: + is_dir = entry.is_dir(follow_symlinks=follow_symlinks) + except OSError: + # Carried over from os.path.isdir(). + is_dir = False + + if is_dir: + dirnames.append(entry.name) + else: + filenames.append(entry.name) + + if top_down: + yield path, dirnames, filenames + else: + paths.append((path, dirnames, filenames)) + + paths += [path._make_child_relpath(d) for d in reversed(dirnames)] + + def absolute(self): + """Return an absolute version of this path + No normalization or symlink resolution is performed. + + Use resolve() to resolve symlinks and remove '..' segments. + """ + self._unsupported("absolute") + + @classmethod + def cwd(cls): + """Return a new path pointing to the current working directory.""" + # We call 'absolute()' rather than using 'os.getcwd()' directly to + # enable users to replace the implementation of 'absolute()' in a + # subclass and benefit from the new behaviour here. This works because + # os.path.abspath('.') == os.getcwd(). + return cls().absolute() + + 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 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. + """ + if not self._tail: + return self, [] + 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 + path, parts = self._split_stack() + try: + path = path.absolute() + except UnsupportedOperation: + pass + + # 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 + 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 + next_path = path._make_child_relpath(part) + if querying and part != '..': + next_path._resolving = True + try: + st = next_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(self)) + target, target_parts = next_path.readlink()._split_stack() + # If the symlink target is absolute (like '/etc/hosts'), set the current + # path to its uppermost parent (like '/'). + if target.root: + path = target + # Add the symlink target's reversed tail parts (like ['hosts', 'etc']) to + # the stack of unresolved path parts. + parts.extend(target_parts) + continue + elif parts and not S_ISDIR(st.st_mode): + raise NotADirectoryError(ENOTDIR, "Not a directory", str(self)) + except OSError: + if strict: + raise + else: + querying = False + next_path._resolving = False + path = next_path + 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, *, follow_symlinks=True): + """ + Return the login name of the file owner. + """ + self._unsupported("owner") + + def group(self, *, follow_symlinks=True): + """ + 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") diff --git a/Lib/pdb.py b/Lib/pdb.py index fd62d246f124ab..83b7fefec63636 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -138,9 +138,14 @@ def check(self): if not os.path.exists(self): print('Error:', self.orig, 'does not exist') sys.exit(1) + if os.path.isdir(self): + print('Error:', self.orig, 'is a directory') + sys.exit(1) - # Replace pdb's dir with script's dir in front of module search path. - sys.path[0] = os.path.dirname(self) + # If safe_path(-P) is not set, sys.path[0] is the directory + # of pdb, and we should replace it with the directory of the script + if not sys.flags.safe_path: + sys.path[0] = os.path.dirname(self) @property def filename(self): @@ -164,6 +169,9 @@ class _ModuleTarget(str): def check(self): try: self._details + except ImportError as e: + print(f"ImportError: {e}") + sys.exit(1) except Exception: traceback.print_exc() sys.exit(1) @@ -199,6 +207,15 @@ def namespace(self): ) +class _PdbInteractiveConsole(code.InteractiveConsole): + def __init__(self, ns, message): + self._message = message + super().__init__(locals=ns, local_exit=True) + + def write(self, data): + self._message(data, end='') + + # Interaction prompt line will separate file and call info from code # text using value of line_prefix string. A newline and arrow may # be to your liking. You can set it once pdb is imported using the @@ -232,7 +249,7 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, try: import readline # remove some common file name delimiters - readline.set_completer_delims(' \t\n`@#$%^&*()=+[{]}\\|;:\'",<>?') + readline.set_completer_delims(' \t\n`@#%^&*()=+[{]}\\|;:\'",<>?') except ImportError: pass self.allow_kbdint = False @@ -304,6 +321,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 @@ -423,8 +448,9 @@ 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): """ @@ -582,11 +608,20 @@ def precmd(self, line): args = line.split() while args[0] in self.aliases: line = self.aliases[args[0]] - ii = 1 - for tmpArg in args[1:]: - line = line.replace("%" + str(ii), - tmpArg) - ii += 1 + for idx in range(1, 10): + if f'%{idx}' in line: + if idx >= len(args): + self.error(f"Not enough arguments for alias '{args[0]}'") + # This is a no-op + return "!" + line = line.replace(f'%{idx}', args[idx]) + elif '%*' not in line: + if idx < len(args): + self.error(f"Too many arguments for alias '{args[0]}'") + # This is a no-op + return "!" + break + line = line.replace("%*", ' '.join(args[1:])) args = line.split() # split into ';;' separated commands @@ -601,6 +636,7 @@ def precmd(self, line): # Replace all the convenience variables line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', r'__pdb_convenience_variables["\1"]', line) + return line def onecmd(self, line): @@ -645,8 +681,8 @@ def handle_command_def(self, line): # interface abstraction functions - def message(self, msg): - print(msg, file=self.stdout) + def message(self, msg, end='\n'): + print(msg, end=end, file=self.stdout) def error(self, msg): print('***', msg, file=self.stdout) @@ -661,6 +697,18 @@ def set_convenience_variable(self, frame, name, value): # Generic completion functions. Individual complete_foo methods can be # assigned below to one of these functions. + def completenames(self, text, line, begidx, endidx): + # Overwrite completenames() of cmd so for the command completion, + # if no current command matches, check for expressions as well + commands = super().completenames(text, line, begidx, endidx) + for alias in self.aliases: + if alias.startswith(text): + commands.append(alias) + if commands: + return commands + else: + return self._complete_expression(text, line, begidx, endidx) + def _complete_location(self, text, line, begidx, endidx): # Complete a file/module/function location for break/tbreak/clear. if line.strip().endswith((':', ',')): @@ -695,6 +743,10 @@ def _complete_expression(self, text, line, begidx, endidx): # complete builtins, and they clutter the namespace quite heavily, so we # leave them out. ns = {**self.curframe.f_globals, **self.curframe_locals} + if text.startswith("$"): + # Complete convenience variables + conv_vars = self.curframe.f_globals.get('__pdb_convenience_variables', {}) + return [f"${name}" for name in conv_vars if name.startswith(text[1:])] if '.' in text: # Walk an attribute chain up to the last part, similar to what # rlcompleter does. This will bail if any of the parts are not @@ -872,7 +924,7 @@ def do_break(self, arg, temporary = 0): #use co_name to identify the bkpt (function names #could be aliased, but co_name is invariant) funcname = code.co_name - lineno = code.co_firstlineno + lineno = self._find_first_executable_line(code) filename = code.co_filename except: # last thing to try @@ -975,6 +1027,23 @@ def checkline(self, filename, lineno): return 0 return lineno + def _find_first_executable_line(self, code): + """ Try to find the first executable line of the code object. + + Equivalently, find the line number of the instruction that's + after RESUME + + Return code.co_firstlineno if no executable line is found. + """ + prev = None + for instr in dis.get_instructions(code): + if prev is not None and prev.opname == 'RESUME': + if instr.positions.lineno is not None: + return instr.positions.lineno + return code.co_firstlineno + prev = instr + return code.co_firstlineno + def do_enable(self, arg): """enable bpnumber [bpnumber ...] @@ -1452,7 +1521,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 @@ -1466,7 +1535,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 @@ -1501,6 +1570,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 @@ -1680,8 +1755,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: @@ -1690,7 +1765,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 @@ -1720,7 +1795,9 @@ def do_interact(self, arg): contains all the (global and local) names found in the current scope. """ ns = {**self.curframe.f_globals, **self.curframe_locals} - code.interact("*interactive*", local=ns) + console = _PdbInteractiveConsole(ns, message=self.message) + console.interact(banner="*pdb interact start*", + exitmsg="*exit from pdb interact command*") def do_alias(self, arg): """alias [name [command]] @@ -1759,7 +1836,18 @@ def do_alias(self, arg): else: self.error(f"Unknown alias '{args[0]}'") else: - self.aliases[args[0]] = ' '.join(args[1:]) + # Do a validation check to make sure no replaceable parameters + # are skipped if %* is not used. + alias = ' '.join(args[1:]) + if '%*' not in alias: + consecutive = True + for idx in range(1, 10): + if f'%{idx}' not in alias: + consecutive = False + if f'%{idx}' in alias and not consecutive: + self.error("Replaceable parameters must be consecutive") + return + self.aliases[args[0]] = alias def do_unalias(self, arg): """unalias name @@ -2136,9 +2224,6 @@ def main(): while True: try: pdb._run(target) - if pdb._user_requested_quit: - break - print("The program finished and will be restarted") except Restart: print("Restarting", target, "with arguments:") print("\t" + " ".join(sys.argv[1:])) @@ -2146,9 +2231,6 @@ def main(): # In most cases SystemExit does not warrant a post-mortem session. print("The program exited via sys.exit(). Exit status:", end=' ') print(e) - except SyntaxError: - traceback.print_exc() - sys.exit(1) except BaseException as e: traceback.print_exc() print("Uncaught exception. Entering post mortem debugging") @@ -2156,6 +2238,9 @@ def main(): pdb.interaction(None, e) print("Post mortem debugger finished. The " + target + " will be restarted") + if pdb._user_requested_quit: + break + print("The program finished and will be restarted") # When invoked as main program, invoke the debugger on a script diff --git a/Lib/platform.py b/Lib/platform.py index 7bb222088d5061..75aa55510858fd 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -118,6 +118,10 @@ import sys import functools import itertools +try: + import _wmi +except ImportError: + _wmi = None ### Globals & Constants @@ -312,24 +316,26 @@ def _syscmd_ver(system='', release='', version='', version = _norm_version(version) return system, release, version -try: - import _wmi -except ImportError: - def _wmi_query(*keys): + +def _wmi_query(table, *keys): + global _wmi + if not _wmi: raise OSError("not supported") -else: - def _wmi_query(table, *keys): - table = { - "OS": "Win32_OperatingSystem", - "CPU": "Win32_Processor", - }[table] + table = { + "OS": "Win32_OperatingSystem", + "CPU": "Win32_Processor", + }[table] + try: data = _wmi.exec_query("SELECT {} FROM {}".format( ",".join(keys), table, )).split("\0") - split_data = (i.partition("=") for i in data) - dict_data = {i[0]: i[2] for i in split_data} - return (dict_data[k] for k in keys) + except OSError: + _wmi = None + raise OSError("not supported") + split_data = (i.partition("=") for i in data) + dict_data = {i[0]: i[2] for i in split_data} + return (dict_data[k] for k in keys) _WIN32_CLIENT_RELEASES = [ diff --git a/Lib/pprint.py b/Lib/pprint.py index 34ed12637e2288..9314701db340c7 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -128,6 +128,9 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *, sort_dicts If true, dict keys are sorted. + underscore_numbers + If true, digit groups are separated with underscores. + """ indent = int(indent) width = int(width) diff --git a/Lib/pstats.py b/Lib/pstats.py index 51bcca84188740..2f054bb4011e7f 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -329,7 +329,7 @@ def eval_print_amount(self, sel, list, msg): if isinstance(sel, str): try: rex = re.compile(sel) - except re.error: + except re.PatternError: msg += " \n" % sel return new_list, msg new_list = [] diff --git a/Lib/pydoc.py b/Lib/pydoc.py index c9a55799b39f0c..83c74a75cd1c00 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -201,7 +201,10 @@ def _getargspec(object): try: signature = inspect.signature(object) if signature: - return str(signature) + name = getattr(object, '__name__', '') + # function are always single-line and should not be formatted + max_width = (80 - len(name)) if name != '' else None + return signature.format(max_width=max_width) except (ValueError, TypeError): argspec = getattr(object, '__text_signature__', None) if argspec: @@ -2073,20 +2076,22 @@ def help(self, request, is_cli=False): self.output.write('\n') def intro(self): - self.output.write(''' -Welcome to Python {0}'s help utility! - -If this is your first time using Python, you should definitely check out -the tutorial on the internet at https://docs.python.org/{0}/tutorial/. + self.output.write('''\ +Welcome to Python {0}'s help utility! If this is your first time using +Python, you should definitely check out the tutorial at +https://docs.python.org/{0}/tutorial/. Enter the name of any module, keyword, or topic to get help on writing -Python programs and using Python modules. To quit this help utility and -return to the interpreter, just type "quit". +Python programs and using Python modules. To get a list of available +modules, keywords, symbols, or topics, enter "modules", "keywords", +"symbols", or "topics". + +Each module also comes with a one-line summary of what it does; to list +the modules whose name or summary contain a given string such as "spam", +enter "modules spam". -To get a list of available modules, keywords, symbols, or topics, type -"modules", "keywords", "symbols", or "topics". Each module also comes -with a one-line summary of what it does; to list the modules whose name -or summary contain a given string such as "spam", type "modules spam". +To quit this help utility and return to the interpreter, +enter "q" or "quit". '''.format('%d.%d' % sys.version_info[:2])) def list(self, items, columns=4, width=80): diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index cb742992a48e8f..7c1bdc4dff2ec4 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 Wed Nov 22 11:44:32 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' @@ -5334,7 +5574,7 @@ ' Create an alias called *name* that executes *command*. The\n' ' *command* must *not* be enclosed in quotes. Replaceable ' 'parameters\n' - ' can be indicated by "%1", "%2", and so on, while "%*" is ' + ' can be indicated by "%1", "%2", … and "%9", while "%*" is ' 'replaced\n' ' by all the parameters. If *command* is omitted, the current ' 'alias\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,1191 @@ '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' - ' Special attributes:\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' + '\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, ' '| |\n' - ' | | dict are the parameter names, ' + '| | and "\'return\'" for the return ' '| |\n' - ' | | and "\'return\'" for the ' - 'return | |\n' - ' | | annotation, if provided. For ' + '| | annotation, if provided. For ' '| |\n' - ' | | more information on working ' + '| | more information on working ' '| |\n' - ' | | with this attribute, see ' + '| | with this attribute, see ' '| |\n' - ' | | Annotations Best Practices. ' + '| | Annotations Best Practices. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__kwdefaults__" | A dict containing defaults for ' - '| Writable |\n' - ' | | keyword-only parameters. ' + '| "__kwdefaults__" | A dict containing defaults for | ' + 'Writable |\n' + '| | keyword-only parameters. ' + '| |\n' + '+---------------------------+---------------------------------+-------------+\n' + '| "__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' - ' When an instance method object is derived from a class ' + 'An instance method object combines a class, a class instance and ' + 'any\n' + 'callable object (normally a user-defined function).\n' + '\n' + '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' + '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' - ' Calling the asynchronous iterator’s "aiterator.__anext__" ' + '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 ' + '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' '\n' - ' Class attribute assignments update the class’s dictionary, ' - 'never\n' - ' the dictionary of a base class.\n' + 'Special attributes:\n' '\n' - ' A class object can be called (see above) to yield a class ' - 'instance\n' - ' (see below).\n' + ' "__name__"\n' + ' The class name.\n' '\n' - ' Special attributes:\n' + ' "__module__"\n' + ' The name of the module in which the class was defined.\n' '\n' - ' "__name__"\n' - ' The class name.\n' + ' "__dict__"\n' + ' The dictionary containing the class’s namespace.\n' '\n' - ' "__module__"\n' - ' The name of the module in which the class was defined.\n' + ' "__bases__"\n' + ' A tuple containing the base classes, in the order of their\n' + ' occurrence in the base class list.\n' '\n' - ' "__dict__"\n' - ' The dictionary containing the class’s namespace.\n' + ' "__doc__"\n' + ' The class’s documentation string, or "None" if undefined.\n' '\n' - ' "__bases__"\n' - ' A tuple containing the base classes, in the order of ' - 'their\n' - ' occurrence in the base class list.\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' - ' "__doc__"\n' - ' The class’s documentation string, or "None" if undefined.\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' + '\n' + 'Code objects\n' + '------------\n' '\n' - ' Future feature declarations ("from __future__ import ' - 'division")\n' - ' also use bits in "co_flags" to indicate whether a code ' + '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' - ' 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 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' + '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' + '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' - ' Other bits in "co_flags" are reserved for internal use.\n' + 'Other bits in "co_flags" are reserved for internal use.\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' + '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' - ' codeobject.co_positions()\n' + 'codeobject.co_positions()\n' '\n' - ' Returns an iterable over the source code positions of ' - 'each\n' - ' bytecode instruction in the code object.\n' + ' Returns an iterable over the source code positions of each ' + 'bytecode\n' + ' instruction in the code object.\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' + ' 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' - ' This positional information can be missing. A ' - 'non-exhaustive\n' - ' lists of cases where this may happen:\n' + ' This positional information can be missing. A non-exhaustive ' + 'lists\n' + ' of cases where this may happen:\n' '\n' - ' * Running the interpreter with "-X" "no_debug_ranges".\n' + ' * Running the interpreter with "-X" "no_debug_ranges".\n' '\n' - ' * Loading a pyc file compiled while using "-X"\n' - ' "no_debug_ranges".\n' + ' * Loading a pyc file compiled while using "-X" ' + '"no_debug_ranges".\n' '\n' - ' * Position tuples corresponding to artificial ' - 'instructions.\n' + ' * Position tuples corresponding to artificial instructions.\n' '\n' - ' * Line and column numbers that can’t be represented due ' - 'to\n' - ' implementation specific limitations.\n' + ' * Line and column numbers that can’t be represented due to\n' + ' implementation specific limitations.\n' '\n' - ' When this occurs, some or all of the tuple elements can ' - 'be\n' - ' "None".\n' + ' When this occurs, some or all of the tuple elements can be ' + '"None".\n' '\n' - ' New in version 3.11.\n' + ' New in version 3.11.\n' '\n' - ' Note:\n' + ' Note:\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' + ' 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' - ' 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' + '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' - ' 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 ' + '"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.clear()\n' + '\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' - ' Frame objects support one method:\n' + ' "RuntimeError" is raised if the frame is currently executing or\n' + ' suspended.\n' '\n' - ' frame.clear()\n' + ' New in version 3.4.\n' '\n' - ' This method clears all references to local variables held ' - 'by\n' - ' the frame. Also, if the frame belonged to a generator, ' + ' Changed in version 3.13: Attempting to clear a suspended frame\n' + ' raises "RuntimeError" (as has always been the case for ' + 'executing\n' + ' frames).\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' @@ -14564,21 +15222,23 @@ '\n' 'Keys views are set-like since their entries are unique and ' '*hashable*.\n' - 'If all values are hashable, so that "(key, value)" pairs are ' - 'unique\n' - 'and hashable, then the items view is also set-like. (Values ' - 'views are\n' - 'not treated as set-like since the entries are generally not ' - 'unique.)\n' - 'For set-like views, all of the operations defined for the ' - 'abstract\n' - 'base class "collections.abc.Set" are available (for example, ' - '"==",\n' - '"<", or "^"). While using set operators, set-like views ' - 'accept any\n' - 'iterable as the other operand, unlike sets which only accept ' - 'sets as\n' - 'the input.\n' + 'Items views also have set-like operations since the (key, ' + 'value) pairs\n' + 'are unique and the keys are hashable. If all values in an ' + 'items view\n' + 'are hashable as well, then the items view can interoperate ' + 'with other\n' + 'sets. (Values views are not treated as set-like since the ' + 'entries are\n' + 'generally not unique.) For set-like views, all of the ' + 'operations\n' + 'defined for the abstract base class "collections.abc.Set" ' + 'are\n' + 'available (for example, "==", "<", or "^"). While using ' + 'set\n' + 'operators, set-like views accept any iterable as the other ' + 'operand,\n' + 'unlike sets which only accept sets as the input.\n' '\n' 'An example of dictionary view usage:\n' '\n' @@ -14611,10 +15271,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 1d789b107904fb..875beb2f8cf41c 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -50,7 +50,6 @@ # Adrian Baddeley. Adapted by Raymond Hettinger for use with # the Mersenne Twister and os.urandom() core generators. -from warnings import warn as _warn from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from math import tau as TWOPI, floor as _floor, isfinite as _isfinite @@ -63,13 +62,6 @@ import os as _os import _random -try: - # hashlib is pretty heavy to load, try lean internal module first - from _sha512 import sha512 as _sha512 -except ImportError: - # fallback to official implementation - from hashlib import sha512 as _sha512 - __all__ = [ "Random", "SystemRandom", @@ -105,6 +97,7 @@ BPF = 53 # Number of bits in a float RECIP_BPF = 2 ** -BPF _ONE = 1 +_sha512 = None class Random(_random.Random): @@ -159,13 +152,23 @@ def seed(self, a=None, version=2): a = -2 if x == -1 else x elif version == 2 and isinstance(a, (str, bytes, bytearray)): + global _sha512 + if _sha512 is None: + try: + # hashlib is pretty heavy to load, try lean internal + # module first + from _sha2 import sha512 as _sha512 + except ImportError: + # fallback to official implementation + from hashlib import sha512 as _sha512 + if isinstance(a, str): a = a.encode() 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 @@ -257,9 +260,10 @@ def _randbelow_without_getrandbits(self, n, maxsize=1<= maxsize: - _warn("Underlying random() generator does not supply \n" - "enough bits to choose from a population range this large.\n" - "To remove the range limitation, add a getrandbits() method.") + from warnings import warn + warn("Underlying random() generator does not supply \n" + "enough bits to choose from a population range this large.\n" + "To remove the range limitation, add a getrandbits() method.") return _floor(random() * n) rem = maxsize % n limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0 diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index 428d1b0d5fbd87..7e8abbf6ffe155 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -117,7 +117,8 @@ U UNICODE For compatibility only. Ignored for string patterns (it is the default), and forbidden for bytes patterns. -This module also defines an exception 'error'. +This module also defines exception 'PatternError', aliased to 'error' for +backward compatibility. """ @@ -133,7 +134,7 @@ "findall", "finditer", "compile", "purge", "escape", "error", "Pattern", "Match", "A", "I", "L", "M", "S", "X", "U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", - "UNICODE", "NOFLAG", "RegexFlag", + "UNICODE", "NOFLAG", "RegexFlag", "PatternError" ] __version__ = "2.2.1" @@ -155,7 +156,7 @@ class RegexFlag: _numeric_repr_ = hex # sre exception -error = _compiler.error +PatternError = error = _compiler.PatternError # -------------------------------------------------------------------- # public interface diff --git a/Lib/re/_compiler.py b/Lib/re/_compiler.py index d0a4c55caf6e41..7b888f877eb3dc 100644 --- a/Lib/re/_compiler.py +++ b/Lib/re/_compiler.py @@ -147,8 +147,10 @@ def _compile(code, pattern, flags): emit(0) # look ahead else: lo, hi = av[1].getwidth() + if lo > MAXCODE: + raise error("looks too much behind") if lo != hi: - raise error("look-behind requires fixed-width pattern") + raise PatternError("look-behind requires fixed-width pattern") emit(lo) # look behind _compile(code, av[1], flags) emit(SUCCESS) @@ -207,7 +209,7 @@ def _compile(code, pattern, flags): else: code[skipyes] = _len(code) - skipyes + 1 else: - raise error("internal: unsupported operand type %r" % (op,)) + raise PatternError(f"internal: unsupported operand type {op!r}") def _compile_charset(charset, flags, code): # compile charset subprogram @@ -233,7 +235,7 @@ def _compile_charset(charset, flags, code): else: emit(av) else: - raise error("internal: unsupported set operator %r" % (op,)) + raise PatternError(f"internal: unsupported set operator {op!r}") emit(FAILURE) def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): @@ -547,7 +549,7 @@ def _compile_info(code, pattern, flags): else: emit(MAXCODE) prefix = prefix[:MAXCODE] - emit(min(hi, MAXCODE)) + emit(hi) # add literal prefix if prefix: emit(len(prefix)) # length diff --git a/Lib/re/_constants.py b/Lib/re/_constants.py index d8e483ac4f23b4..9c3c294ba448b4 100644 --- a/Lib/re/_constants.py +++ b/Lib/re/_constants.py @@ -20,7 +20,7 @@ # SRE standard exception (access as sre.error) # should this really be here? -class error(Exception): +class PatternError(Exception): """Exception raised for invalid regular expressions. Attributes: @@ -53,6 +53,9 @@ def __init__(self, msg, pattern=None, pos=None): super().__init__(msg) +# Backward compatibility after renaming in 3.13 +error = PatternError + class _NamedIntConstant(int): def __new__(cls, value, name): self = super(_NamedIntConstant, cls).__new__(cls, value) diff --git a/Lib/re/_parser.py b/Lib/re/_parser.py index d00b7e67d55958..f3c779340fe230 100644 --- a/Lib/re/_parser.py +++ b/Lib/re/_parser.py @@ -67,6 +67,10 @@ TYPE_FLAGS = SRE_FLAG_ASCII | SRE_FLAG_LOCALE | SRE_FLAG_UNICODE GLOBAL_FLAGS = SRE_FLAG_DEBUG +# Maximal value returned by SubPattern.getwidth(). +# Must be larger than MAXREPEAT, MAXCODE and sys.maxsize. +MAXWIDTH = 1 << 64 + class State: # keeps track of state for parsing def __init__(self): @@ -177,7 +181,7 @@ def getwidth(self): lo = hi = 0 for op, av in self.data: if op is BRANCH: - i = MAXREPEAT - 1 + i = MAXWIDTH j = 0 for av in av[1]: l, h = av.getwidth() @@ -196,7 +200,10 @@ def getwidth(self): elif op in _REPEATCODES: i, j = av[2].getwidth() lo = lo + i * av[0] - hi = hi + j * av[1] + if av[1] == MAXREPEAT and j: + hi = MAXWIDTH + else: + hi = hi + j * av[1] elif op in _UNITCODES: lo = lo + 1 hi = hi + 1 @@ -216,7 +223,7 @@ def getwidth(self): hi = hi + j elif op is SUCCESS: break - self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT) + self.width = min(lo, MAXWIDTH), min(hi, MAXWIDTH) return self.width class Tokenizer: diff --git a/Lib/shutil.py b/Lib/shutil.py index b37bd082eee0c6..dc3aac3e07f910 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 = [] @@ -591,23 +590,21 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, dirs_exist_ok=dirs_exist_ok) if hasattr(os.stat_result, 'st_file_attributes'): - def _rmtree_islink(path): - try: - st = os.lstat(path) - return (stat.S_ISLNK(st.st_mode) or - (st.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT - and st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)) - except OSError: - return False + def _rmtree_islink(st): + return (stat.S_ISLNK(st.st_mode) or + (st.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT + and st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)) else: - def _rmtree_islink(path): - return os.path.islink(path) + def _rmtree_islink(st): + return stat.S_ISLNK(st.st_mode) # version vulnerable to race conditions def _rmtree_unsafe(path, onexc): try: with os.scandir(path) as scandir_it: entries = list(scandir_it) + except FileNotFoundError: + return except OSError as err: onexc(os.scandir, path, err) entries = [] @@ -615,6 +612,8 @@ def _rmtree_unsafe(path, onexc): fullname = entry.path try: is_dir = entry.is_dir(follow_symlinks=False) + except FileNotFoundError: + continue except OSError: is_dir = False @@ -625,6 +624,8 @@ def _rmtree_unsafe(path, onexc): # a directory with a symlink after the call to # os.scandir or entry.is_dir above. raise OSError("Cannot call rmtree on a symbolic link") + except FileNotFoundError: + continue except OSError as err: onexc(os.path.islink, fullname, err) continue @@ -632,10 +633,14 @@ def _rmtree_unsafe(path, onexc): else: try: os.unlink(fullname) + except FileNotFoundError: + continue except OSError as err: onexc(os.unlink, fullname, err) try: os.rmdir(path) + except FileNotFoundError: + pass except OSError as err: onexc(os.rmdir, path, err) @@ -644,6 +649,8 @@ def _rmtree_safe_fd(topfd, path, onexc): try: with os.scandir(topfd) as scandir_it: entries = list(scandir_it) + except FileNotFoundError: + return except OSError as err: err.filename = path onexc(os.scandir, path, err) @@ -652,6 +659,8 @@ def _rmtree_safe_fd(topfd, path, onexc): fullname = os.path.join(path, entry.name) try: is_dir = entry.is_dir(follow_symlinks=False) + except FileNotFoundError: + continue except OSError: is_dir = False else: @@ -659,6 +668,8 @@ def _rmtree_safe_fd(topfd, path, onexc): try: orig_st = entry.stat(follow_symlinks=False) is_dir = stat.S_ISDIR(orig_st.st_mode) + except FileNotFoundError: + continue except OSError as err: onexc(os.lstat, fullname, err) continue @@ -666,6 +677,8 @@ def _rmtree_safe_fd(topfd, path, onexc): try: dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd) dirfd_closed = False + except FileNotFoundError: + continue except OSError as err: onexc(os.open, fullname, err) else: @@ -674,8 +687,15 @@ def _rmtree_safe_fd(topfd, path, onexc): _rmtree_safe_fd(dirfd, fullname, onexc) try: os.close(dirfd) + except OSError as err: + # close() should not be retried after an error. dirfd_closed = True + onexc(os.close, fullname, err) + dirfd_closed = True + try: os.rmdir(entry.name, dir_fd=topfd) + except FileNotFoundError: + continue except OSError as err: onexc(os.rmdir, fullname, err) else: @@ -689,10 +709,15 @@ def _rmtree_safe_fd(topfd, path, onexc): onexc(os.path.islink, fullname, err) finally: if not dirfd_closed: - os.close(dirfd) + try: + os.close(dirfd) + except OSError as err: + onexc(os.close, fullname, err) else: try: os.unlink(entry.name, dir_fd=topfd) + except FileNotFoundError: + continue except OSError as err: onexc(os.unlink, fullname, err) @@ -722,10 +747,6 @@ def rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None): If both onerror and onexc are set, onerror is ignored and onexc is used. """ - if onerror is not None: - warnings.warn("onerror argument is deprecated, use onexc instead", - DeprecationWarning, stacklevel=2) - sys.audit("shutil.rmtree", path, dir_fd) if ignore_errors: def onexc(*args): @@ -755,13 +776,13 @@ def onexc(*args): # lstat()/open()/fstat() trick. try: orig_st = os.lstat(path, dir_fd=dir_fd) - except Exception as err: + except OSError as err: onexc(os.lstat, path, err) return try: fd = os.open(path, os.O_RDONLY, dir_fd=dir_fd) fd_closed = False - except Exception as err: + except OSError as err: onexc(os.open, path, err) return try: @@ -769,7 +790,12 @@ def onexc(*args): _rmtree_safe_fd(fd, path, onexc) try: os.close(fd) + except OSError as err: + # close() should not be retried after an error. fd_closed = True + onexc(os.close, path, err) + fd_closed = True + try: os.rmdir(path, dir_fd=dir_fd) except OSError as err: onexc(os.rmdir, path, err) @@ -781,12 +807,20 @@ def onexc(*args): onexc(os.path.islink, path, err) finally: if not fd_closed: - os.close(fd) + try: + os.close(fd) + except OSError as err: + onexc(os.close, path, err) else: if dir_fd is not None: raise NotImplementedError("dir_fd unavailable on this platform") try: - if _rmtree_islink(path): + st = os.lstat(path) + except OSError as err: + onexc(os.lstat, path, err) + return + try: + if _rmtree_islink(st): # symlinks to directories are forbidden, see bug #1669 raise OSError("Cannot call rmtree on a symbolic link") except OSError as err: @@ -1554,8 +1588,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/site.py b/Lib/site.py index 672fa7b000ad02..2517b7e5f1d22a 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -444,8 +444,7 @@ def register_readline(): # Reading the initialization (config) file may not be enough to set a # completion key, so we set one first and then read the file. - readline_doc = getattr(readline, '__doc__', '') - if readline_doc is not None and 'libedit' in readline_doc: + if readline.backend == 'editline': readline.parse_and_bind('bind ^I rl_complete') else: readline.parse_and_bind('tab: complete') diff --git a/Lib/socket.py b/Lib/socket.py index 321fcda51505c1..5f0a1f40e25b94 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -702,16 +702,15 @@ def readinto(self, b): self._checkReadable() if self._timeout_occurred: raise OSError("cannot read from timed out object") - while True: - try: - return self._sock.recv_into(b) - except timeout: - self._timeout_occurred = True - raise - except error as e: - if e.errno in _blocking_errnos: - return None - raise + try: + return self._sock.recv_into(b) + except timeout: + self._timeout_occurred = True + raise + except error as e: + if e.errno in _blocking_errnos: + return None + raise def write(self, b): """Write the given bytes or bytearray object *b* to the socket diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py index 3b59763375c147..b93b84384a0925 100644 --- a/Lib/sqlite3/__main__.py +++ b/Lib/sqlite3/__main__.py @@ -116,6 +116,10 @@ def main(*args): else: # No SQL provided; start the REPL. console = SqliteInteractiveConsole(con) + try: + import readline + except ImportError: + pass console.interact(banner, exitmsg="") finally: con.close() diff --git a/Lib/ssl.py b/Lib/ssl.py index 62e55857141dfc..d01484964b6895 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -116,7 +116,7 @@ from _ssl import ( HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1, - HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3 + HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3, HAS_PSK ) from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION @@ -1270,10 +1270,14 @@ def recv(self, buflen=1024, flags=0): def recv_into(self, buffer, nbytes=None, flags=0): self._checkClosed() - if buffer and (nbytes is None): - nbytes = len(buffer) - elif nbytes is None: - nbytes = 1024 + if nbytes is None: + if buffer is not None: + with memoryview(buffer) as view: + nbytes = view.nbytes + if not nbytes: + nbytes = 1024 + else: + nbytes = 1024 if self._sslobj is not None: if flags != 0: raise ValueError( diff --git a/Lib/statistics.py b/Lib/statistics.py index 96c803483057e7..83aaedb04515e0 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -527,8 +527,10 @@ def count(iterable): def geometric_mean(data): """Convert data to floats and compute the geometric mean. - Raises a StatisticsError if the input dataset is empty, - if it contains a zero, or if it contains a negative value. + Raises a StatisticsError if the input dataset is empty + or if it contains a negative value. + + Returns zero if the product of inputs is zero. No special efforts are made to achieve exact results. (However, this may change in the future.) @@ -536,11 +538,25 @@ def geometric_mean(data): >>> round(geometric_mean([54, 24, 36]), 9) 36.0 """ - try: - return exp(fmean(map(log, data))) - except ValueError: - raise StatisticsError('geometric mean requires a non-empty dataset ' - 'containing positive numbers') from None + n = 0 + found_zero = False + def count_positive(iterable): + nonlocal n, found_zero + for n, x in enumerate(iterable, start=1): + if x > 0.0 or math.isnan(x): + yield x + elif x == 0.0: + found_zero = True + else: + raise StatisticsError('No negative inputs allowed', x) + total = fsum(map(log, count_positive(data))) + if not n: + raise StatisticsError('Must have a non-empty dataset') + if math.isnan(total): + return math.nan + if found_zero: + return math.nan if total == math.inf else 0.0 + return exp(total / n) def harmonic_mean(data, weights=None): @@ -844,7 +860,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 = [] diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 6df5dd551ea67e..d6edd1a9807d1b 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -74,8 +74,8 @@ else: _mswindows = True -# wasm32-emscripten and wasm32-wasi do not support processes -_can_fork_exec = sys.platform not in {"emscripten", "wasi"} +# some platforms do not support subprocesses +_can_fork_exec = sys.platform not in {"emscripten", "wasi", "ios", "tvos", "watchos"} if _mswindows: import _winapi @@ -103,18 +103,22 @@ if _can_fork_exec: from _posixsubprocess import fork_exec as _fork_exec # used in methods that are called by __del__ - _waitpid = os.waitpid - _waitstatus_to_exitcode = os.waitstatus_to_exitcode - _WIFSTOPPED = os.WIFSTOPPED - _WSTOPSIG = os.WSTOPSIG - _WNOHANG = os.WNOHANG + class _del_safe: + waitpid = os.waitpid + waitstatus_to_exitcode = os.waitstatus_to_exitcode + WIFSTOPPED = os.WIFSTOPPED + WSTOPSIG = os.WSTOPSIG + WNOHANG = os.WNOHANG + ECHILD = errno.ECHILD else: - _fork_exec = None - _waitpid = None - _waitstatus_to_exitcode = None - _WIFSTOPPED = None - _WSTOPSIG = None - _WNOHANG = None + class _del_safe: + waitpid = None + waitstatus_to_exitcode = None + WIFSTOPPED = None + WSTOPSIG = None + WNOHANG = None + ECHILD = errno.ECHILD + import select import selectors @@ -1951,20 +1955,16 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, raise child_exception_type(err_msg) - def _handle_exitstatus(self, sts, - _waitstatus_to_exitcode=_waitstatus_to_exitcode, - _WIFSTOPPED=_WIFSTOPPED, - _WSTOPSIG=_WSTOPSIG): + def _handle_exitstatus(self, sts, _del_safe=_del_safe): """All callers to this function MUST hold self._waitpid_lock.""" # This method is called (indirectly) by __del__, so it cannot # refer to anything outside of its local scope. - if _WIFSTOPPED(sts): - self.returncode = -_WSTOPSIG(sts) + if _del_safe.WIFSTOPPED(sts): + self.returncode = -_del_safe.WSTOPSIG(sts) else: - self.returncode = _waitstatus_to_exitcode(sts) + self.returncode = _del_safe.waitstatus_to_exitcode(sts) - def _internal_poll(self, _deadstate=None, _waitpid=_waitpid, - _WNOHANG=_WNOHANG, _ECHILD=errno.ECHILD): + def _internal_poll(self, _deadstate=None, _del_safe=_del_safe): """Check if child process has terminated. Returns returncode attribute. @@ -1980,13 +1980,13 @@ def _internal_poll(self, _deadstate=None, _waitpid=_waitpid, try: if self.returncode is not None: return self.returncode # Another thread waited. - pid, sts = _waitpid(self.pid, _WNOHANG) + pid, sts = _del_safe.waitpid(self.pid, _del_safe.WNOHANG) if pid == self.pid: self._handle_exitstatus(sts) except OSError as e: if _deadstate is not None: self.returncode = _deadstate - elif e.errno == _ECHILD: + elif e.errno == _del_safe.ECHILD: # This happens if SIGCLD is set to be ignored or # waiting for child processes has otherwise been # disabled for our process. This child is dead, we diff --git a/Lib/symtable.py b/Lib/symtable.py index 4b0bc6f497a553..17f820abd56660 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -233,7 +233,16 @@ def __init__(self, name, flags, namespaces=None, *, module_scope=False): self.__module_scope = module_scope def __repr__(self): - return "".format(self.__name) + flags_str = '|'.join(self._flags_str()) + return f'' + + def _scope_str(self): + return _scopes_value_to_name.get(self.__scope) or str(self.__scope) + + def _flags_str(self): + for flagname, flagvalue in _flags: + if self.__flags & flagvalue == flagvalue: + yield flagname def get_name(self): """Return a name of a symbol. @@ -323,11 +332,43 @@ def get_namespace(self): else: return self.__namespaces[0] + +_flags = [('USE', USE)] +_flags.extend(kv for kv in globals().items() if kv[0].startswith('DEF_')) +_scopes_names = ('FREE', 'LOCAL', 'GLOBAL_IMPLICIT', 'GLOBAL_EXPLICIT', 'CELL') +_scopes_value_to_name = {globals()[n]: n for n in _scopes_names} + + +def main(args): + import sys + def print_symbols(table, level=0): + indent = ' ' * level + nested = "nested " if table.is_nested() else "" + if table.get_type() == 'module': + what = f'from file {table._filename!r}' + else: + what = f'{table.get_name()!r}' + print(f'{indent}symbol table for {nested}{table.get_type()} {what}:') + for ident in table.get_identifiers(): + symbol = table.lookup(ident) + flags = ', '.join(symbol._flags_str()).lower() + print(f' {indent}{symbol._scope_str().lower()} symbol {symbol.get_name()!r}: {flags}') + print() + + for table2 in table.get_children(): + print_symbols(table2, level + 1) + + for filename in args or ['-']: + if filename == '-': + src = sys.stdin.read() + filename = '' + else: + with open(filename, 'rb') as f: + src = f.read() + mod = symtable(src, filename, 'exec') + print_symbols(mod) + + if __name__ == "__main__": - import os, sys - with open(sys.argv[0]) as f: - src = f.read() - mod = symtable(src, os.path.split(sys.argv[0])[1], "exec") - for ident in mod.get_identifiers(): - info = mod.lookup(ident) - print(info, info.is_local(), info.is_namespace()) + import sys + main(sys.argv[1:]) diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py deleted file mode 100644 index a8b5c5f7dfba5b..00000000000000 --- a/Lib/sysconfig.py +++ /dev/null @@ -1,880 +0,0 @@ -"""Access to Python's configuration information.""" - -import os -import sys -import threading -from os.path import realpath - -__all__ = [ - 'get_config_h_filename', - 'get_config_var', - 'get_config_vars', - 'get_makefile_filename', - 'get_path', - 'get_path_names', - 'get_paths', - 'get_platform', - 'get_python_version', - 'get_scheme_names', - 'parse_config_h', -] - -# Keys for get_config_var() that are never converted to Python integers. -_ALWAYS_STR = { - 'MACOSX_DEPLOYMENT_TARGET', -} - -_INSTALL_SCHEMES = { - 'posix_prefix': { - 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', - 'platinclude': - '{installed_platbase}/include/python{py_version_short}{abiflags}', - 'scripts': '{base}/bin', - 'data': '{base}', - }, - 'posix_home': { - 'stdlib': '{installed_base}/lib/python', - 'platstdlib': '{base}/lib/python', - 'purelib': '{base}/lib/python', - 'platlib': '{base}/lib/python', - 'include': '{installed_base}/include/python', - 'platinclude': '{installed_base}/include/python', - 'scripts': '{base}/bin', - 'data': '{base}', - }, - 'nt': { - 'stdlib': '{installed_base}/Lib', - 'platstdlib': '{base}/Lib', - 'purelib': '{base}/Lib/site-packages', - 'platlib': '{base}/Lib/site-packages', - 'include': '{installed_base}/Include', - 'platinclude': '{installed_base}/Include', - 'scripts': '{base}/Scripts', - 'data': '{base}', - }, - # Downstream distributors can overwrite the default install scheme. - # This is done to support downstream modifications where distributors change - # the installation layout (eg. different site-packages directory). - # So, distributors will change the default scheme to one that correctly - # represents their layout. - # This presents an issue for projects/people that need to bootstrap virtual - # environments, like virtualenv. As distributors might now be customizing - # the default install scheme, there is no guarantee that the information - # returned by sysconfig.get_default_scheme/get_paths is correct for - # a virtual environment, the only guarantee we have is that it is correct - # for the *current* environment. When bootstrapping a virtual environment, - # we need to know its layout, so that we can place the files in the - # correct locations. - # The "*_venv" install scheme is a scheme to bootstrap virtual environments, - # essentially identical to the default posix_prefix/nt schemes. - # Downstream distributors who patch posix_prefix/nt scheme are encouraged to - # leave the following schemes unchanged - 'posix_venv': { - 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/python{py_version_short}{abiflags}', - 'platinclude': - '{installed_platbase}/include/python{py_version_short}{abiflags}', - 'scripts': '{base}/bin', - 'data': '{base}', - }, - 'nt_venv': { - 'stdlib': '{installed_base}/Lib', - 'platstdlib': '{base}/Lib', - 'purelib': '{base}/Lib/site-packages', - 'platlib': '{base}/Lib/site-packages', - 'include': '{installed_base}/Include', - 'platinclude': '{installed_base}/Include', - 'scripts': '{base}/Scripts', - 'data': '{base}', - }, - } - -# For the OS-native venv scheme, we essentially provide an alias: -if os.name == 'nt': - _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] -else: - _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] - - -# NOTE: site.py has copy of this function. -# Sync it when modify this function. -def _getuserbase(): - env_base = os.environ.get("PYTHONUSERBASE", None) - if env_base: - return env_base - - # Emscripten, VxWorks, and WASI have no home directories - if sys.platform in {"emscripten", "vxworks", "wasi"}: - return None - - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - return joinuser(base, "Python") - - if sys.platform == "darwin" and sys._framework: - return joinuser("~", "Library", sys._framework, - f"{sys.version_info[0]}.{sys.version_info[1]}") - - return joinuser("~", ".local") - -_HAS_USER_BASE = (_getuserbase() is not None) - -if _HAS_USER_BASE: - _INSTALL_SCHEMES |= { - # NOTE: When modifying "purelib" scheme, update site._get_path() too. - 'nt_user': { - 'stdlib': '{userbase}/Python{py_version_nodot_plat}', - 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', - 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', - 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', - 'include': '{userbase}/Python{py_version_nodot_plat}/Include', - 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', - 'data': '{userbase}', - }, - 'posix_user': { - 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', - 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', - 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', - }, - 'osx_framework_user': { - 'stdlib': '{userbase}/lib/python', - 'platstdlib': '{userbase}/lib/python', - 'purelib': '{userbase}/lib/python/site-packages', - 'platlib': '{userbase}/lib/python/site-packages', - 'include': '{userbase}/include/python{py_version_short}', - 'scripts': '{userbase}/bin', - 'data': '{userbase}', - }, - } - -_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', - 'scripts', 'data') - -_PY_VERSION = sys.version.split()[0] -_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}' -_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}' -_PREFIX = os.path.normpath(sys.prefix) -_BASE_PREFIX = os.path.normpath(sys.base_prefix) -_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) -_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) -# Mutex guarding initialization of _CONFIG_VARS. -_CONFIG_VARS_LOCK = threading.RLock() -_CONFIG_VARS = None -# True iff _CONFIG_VARS has been fully initialized. -_CONFIG_VARS_INITIALIZED = False -_USER_BASE = None - -# Regexes needed for parsing Makefile (and similar syntaxes, -# 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: - return realpath(path) - except OSError: - return path - -if sys.executable: - _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) -else: - # sys.executable can be empty if argv[0] has been changed and Python is - # unable to retrieve the real program name - _PROJECT_BASE = _safe_realpath(os.getcwd()) - -# In a virtual environment, `sys._home` gives us the target directory -# `_PROJECT_BASE` for the executable that created it when the virtual -# python is an actual executable ('venv --copies' or Windows). -_sys_home = getattr(sys, '_home', None) -if _sys_home: - _PROJECT_BASE = _sys_home - -if os.name == 'nt': - # In a source build, the executable is in a subdirectory of the root - # that we want (\PCbuild\). - # `_BASE_PREFIX` is used as the base installation is where the source - # will be. The realpath is needed to prevent mount point confusion - # that can occur with just string comparisons. - if _safe_realpath(_PROJECT_BASE).startswith( - _safe_realpath(f'{_BASE_PREFIX}\\PCbuild')): - _PROJECT_BASE = _BASE_PREFIX - -# set for cross builds -if "_PYTHON_PROJECT_BASE" in os.environ: - _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) - -def is_python_build(check_home=None): - if check_home is not None: - import warnings - warnings.warn("check_home argument is deprecated and ignored.", - DeprecationWarning, stacklevel=2) - for fn in ("Setup", "Setup.local"): - if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): - return True - return False - -_PYTHON_BUILD = is_python_build() - -if _PYTHON_BUILD: - for scheme in ('posix_prefix', 'posix_home'): - # On POSIX-y platforms, Python will: - # - Build from .h files in 'headers' (which is only added to the - # scheme when building CPython) - # - Install .h files to 'include' - scheme = _INSTALL_SCHEMES[scheme] - scheme['headers'] = scheme['include'] - scheme['include'] = '{srcdir}/Include' - scheme['platinclude'] = '{projectbase}/.' - del scheme - - -def _subst_vars(s, local_vars): - try: - return s.format(**local_vars) - except KeyError as var: - try: - return s.format(**os.environ) - except KeyError: - raise AttributeError(f'{var}') from None - -def _extend_dict(target_dict, other_dict): - target_keys = target_dict.keys() - for key, value in other_dict.items(): - if key in target_keys: - continue - target_dict[key] = value - - -def _expand_vars(scheme, vars): - res = {} - if vars is None: - vars = {} - _extend_dict(vars, get_config_vars()) - if os.name == 'nt': - # On Windows we want to substitute 'lib' for schemes rather - # than the native value (without modifying vars, in case it - # was passed in) - vars = vars | {'platlibdir': 'lib'} - - for key, value in _INSTALL_SCHEMES[scheme].items(): - if os.name in ('posix', 'nt'): - value = os.path.expanduser(value) - res[key] = os.path.normpath(_subst_vars(value, vars)) - return res - - -def _get_preferred_schemes(): - if os.name == 'nt': - return { - 'prefix': 'nt', - 'home': 'posix_home', - 'user': 'nt_user', - } - if sys.platform == 'darwin' and sys._framework: - return { - 'prefix': 'posix_prefix', - 'home': 'posix_home', - 'user': 'osx_framework_user', - } - return { - 'prefix': 'posix_prefix', - 'home': 'posix_home', - 'user': 'posix_user', - } - - -def get_preferred_scheme(key): - if key == 'prefix' and sys.prefix != sys.base_prefix: - return 'venv' - scheme = _get_preferred_schemes()[key] - if scheme not in _INSTALL_SCHEMES: - raise ValueError( - f"{key!r} returned {scheme!r}, which is not a valid scheme " - f"on this platform" - ) - return scheme - - -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: - return os.path.join(_PROJECT_BASE, "Makefile") - if hasattr(sys, 'abiflags'): - config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' - else: - config_dir_name = 'config' - if hasattr(sys.implementation, '_multiarch'): - config_dir_name += f'-{sys.implementation._multiarch}' - return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') - - -def _get_sysconfigdata_name(): - multiarch = getattr(sys.implementation, '_multiarch', '') - return os.environ.get( - '_PYTHON_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() - name = _get_sysconfigdata_name() - _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) - build_time_vars = _temp.build_time_vars - vars.update(build_time_vars) - -def _init_non_posix(vars): - """Initialize the module as appropriate for NT""" - # set basic install directories - import _imp - 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 - vars['EXE'] = '.exe' - vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT - vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) - vars['TZPATH'] = '' - -# -# public APIs -# - - -def parse_config_h(fp, vars=None): - """Parse a config.h-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. - """ - if vars is None: - vars = {} - import re - define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") - - while True: - line = fp.readline() - if not line: - break - m = define_rx.match(line) - if m: - n, v = m.group(1, 2) - try: - if n in _ALWAYS_STR: - raise ValueError - v = int(v) - except ValueError: - pass - vars[n] = v - else: - m = undef_rx.match(line) - if m: - vars[m.group(1)] = 0 - return vars - - -def get_config_h_filename(): - """Return the path of pyconfig.h.""" - if _PYTHON_BUILD: - if os.name == "nt": - inc_dir = os.path.join(_PROJECT_BASE, "PC") - else: - inc_dir = _PROJECT_BASE - else: - inc_dir = get_path('platinclude') - return os.path.join(inc_dir, 'pyconfig.h') - - -def get_scheme_names(): - """Return a tuple containing the schemes names.""" - return tuple(sorted(_INSTALL_SCHEMES)) - - -def get_path_names(): - """Return a tuple containing the paths names.""" - return _SCHEME_KEYS - - -def get_paths(scheme=get_default_scheme(), vars=None, expand=True): - """Return a mapping containing an install scheme. - - ``scheme`` is the install scheme name. If not provided, it will - return the default scheme for the current platform. - """ - if expand: - return _expand_vars(scheme, vars) - else: - return _INSTALL_SCHEMES[scheme] - - -def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): - """Return a path corresponding to the scheme. - - ``scheme`` is the install scheme name. - """ - return get_paths(scheme, vars, expand)[name] - - -def _init_config_vars(): - global _CONFIG_VARS - _CONFIG_VARS = {} - # Normalized versions of prefix and exec_prefix are handy to have; - # in fact, these are the standard versions used most places in the - # Distutils. - _CONFIG_VARS['prefix'] = _PREFIX - _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX - _CONFIG_VARS['py_version'] = _PY_VERSION - _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT - _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT - _CONFIG_VARS['installed_base'] = _BASE_PREFIX - _CONFIG_VARS['base'] = _PREFIX - _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX - _CONFIG_VARS['platbase'] = _EXEC_PREFIX - _CONFIG_VARS['projectbase'] = _PROJECT_BASE - _CONFIG_VARS['platlibdir'] = sys.platlibdir - try: - _CONFIG_VARS['abiflags'] = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - _CONFIG_VARS['abiflags'] = '' - try: - _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') - except AttributeError: - _CONFIG_VARS['py_version_nodot_plat'] = '' - - if os.name == 'nt': - _init_non_posix(_CONFIG_VARS) - _CONFIG_VARS['VPATH'] = sys._vpath - if os.name == 'posix': - _init_posix(_CONFIG_VARS) - if _HAS_USER_BASE: - # Setting 'userbase' is done below the call to the - # init function to enable using 'get_config_var' in - # the init-function. - _CONFIG_VARS['userbase'] = _getuserbase() - - # Always convert srcdir to an absolute path - srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) - if os.name == 'posix': - if _PYTHON_BUILD: - # If srcdir is a relative path (typically '.' or '..') - # then it should be interpreted relative to the directory - # containing Makefile. - base = os.path.dirname(get_makefile_filename()) - srcdir = os.path.join(base, srcdir) - else: - # srcdir is not meaningful since the installation is - # spread about the filesystem. We choose the - # directory containing the Makefile since we know it - # exists. - srcdir = os.path.dirname(get_makefile_filename()) - _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) - - # OS X platforms require special customization to handle - # multi-architecture, multi-os-version installers - if sys.platform == 'darwin': - import _osx_support - _osx_support.customize_config_vars(_CONFIG_VARS) - - global _CONFIG_VARS_INITIALIZED - _CONFIG_VARS_INITIALIZED = True - - -def get_config_vars(*args): - """With no arguments, return a dictionary of all configuration - variables relevant for the current platform. - - On Unix, this means every variable defined in Python's installed Makefile; - On Windows it's a much smaller set. - - With arguments, return a list of values that result from looking up - each argument in the configuration variable dictionary. - """ - - # Avoid claiming the lock once initialization is complete. - if not _CONFIG_VARS_INITIALIZED: - with _CONFIG_VARS_LOCK: - # Test again with the lock held to avoid races. Note that - # we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED, - # to ensure that recursive calls to get_config_vars() - # don't re-enter init_config_vars(). - if _CONFIG_VARS is None: - _init_config_vars() - - if args: - vals = [] - for name in args: - vals.append(_CONFIG_VARS.get(name)) - return vals - else: - return _CONFIG_VARS - - -def get_config_var(name): - """Return the value of a single variable using the dictionary returned by - 'get_config_vars()'. - - Equivalent to get_config_vars().get(name) - """ - return get_config_vars().get(name) - - -def get_platform(): - """Return a string that identifies the current platform. - - This is used mainly to distinguish platform-specific build directories and - platform-specific built distributions. Typically includes the OS name and - version and the architecture (as supplied by 'os.uname()'), although the - exact information included depends on the OS; on Linux, the kernel version - isn't particularly important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - - """ - if os.name == 'nt': - if 'amd64' in sys.version.lower(): - return 'win-amd64' - if '(arm)' in sys.version.lower(): - return 'win-arm32' - if '(arm64)' in sys.version.lower(): - return 'win-arm64' - return sys.platform - - if os.name != "posix" or not hasattr(os, 'uname'): - # XXX what about the architecture? NT is Intel or Alpha - return sys.platform - - # Set for cross builds explicitly - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_PLATFORM"] - - # Try to distinguish various flavours of Unix - osname, host, release, version, machine = os.uname() - - # Convert the OS name to lowercase, remove '/' characters, and translate - # spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_') - machine = machine.replace('/', '-') - - if osname[:5] == "linux": - # At least on Linux/Intel, 'machine' is the processor -- - # i386, etc. - # XXX what about Alpha, SPARC, etc? - return f"{osname}-{machine}" - elif osname[:5] == "sunos": - if release[0] >= "5": # SunOS 5 == Solaris 2 - osname = "solaris" - release = f"{int(release[0]) - 3}.{release[2:]}" - # We can't use "platform.architecture()[0]" because a - # bootstrap problem. We use a dict to get an error - # if some suspicious happens. - bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} - machine += f".{bitness[sys.maxsize]}" - # fall through to standard osname-release-machine representation - elif osname[:3] == "aix": - from _aix_support import aix_platform - return aix_platform() - elif osname[:6] == "cygwin": - osname = "cygwin" - import re - rel_re = re.compile(r'[\d.]+') - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == "darwin": - import _osx_support - osname, release, machine = _osx_support.get_platform_osx( - get_config_vars(), - osname, release, machine) - - return f"{osname}-{release}-{machine}" - - -def get_python_version(): - return _PY_VERSION_SHORT - - -def expand_makefile_vars(s, vars): - """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in - 'string' according to 'vars' (a dictionary mapping variable names to - values). Variables not present in 'vars' are silently expanded to the - empty string. The variable values in 'vars' should not contain further - variable expansions; if 'vars' is the output of 'parse_makefile()', - you're fine. Returns a variable-expanded version of 's'. - """ - import re - - # This algorithm does multiple expansion, so if vars['foo'] contains - # "${bar}", it will expand ${foo} to ${bar}, and then expand - # ${bar}... and so forth. This is fine as long as 'vars' comes from - # 'parse_makefile()', which takes care of such expansions eagerly, - # according to make's variable expansion semantics. - - while True: - m = re.search(_findvar1_rx, s) or re.search(_findvar2_rx, s) - if m: - (beg, end) = m.span() - s = s[0:beg] + vars.get(m.group(1)) + s[end:] - 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/__init__.py b/Lib/sysconfig/__init__.py new file mode 100644 index 00000000000000..c60c9f3440615b --- /dev/null +++ b/Lib/sysconfig/__init__.py @@ -0,0 +1,666 @@ +"""Access to Python's configuration information.""" + +import os +import sys +import threading +from os.path import realpath + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + +# Keys for get_config_var() that are never converted to Python integers. +_ALWAYS_STR = { + 'MACOSX_DEPLOYMENT_TARGET', +} + +_INSTALL_SCHEMES = { + 'posix_prefix': { + 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', + 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': + '{installed_platbase}/include/python{py_version_short}{abiflags}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'posix_home': { + 'stdlib': '{installed_base}/lib/python', + 'platstdlib': '{base}/lib/python', + 'purelib': '{base}/lib/python', + 'platlib': '{base}/lib/python', + 'include': '{installed_base}/include/python', + 'platinclude': '{installed_base}/include/python', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'nt': { + 'stdlib': '{installed_base}/Lib', + 'platstdlib': '{base}/Lib', + 'purelib': '{base}/Lib/site-packages', + 'platlib': '{base}/Lib/site-packages', + 'include': '{installed_base}/Include', + 'platinclude': '{installed_base}/Include', + 'scripts': '{base}/Scripts', + 'data': '{base}', + }, + # Downstream distributors can overwrite the default install scheme. + # This is done to support downstream modifications where distributors change + # the installation layout (eg. different site-packages directory). + # So, distributors will change the default scheme to one that correctly + # represents their layout. + # This presents an issue for projects/people that need to bootstrap virtual + # environments, like virtualenv. As distributors might now be customizing + # the default install scheme, there is no guarantee that the information + # returned by sysconfig.get_default_scheme/get_paths is correct for + # a virtual environment, the only guarantee we have is that it is correct + # for the *current* environment. When bootstrapping a virtual environment, + # we need to know its layout, so that we can place the files in the + # correct locations. + # The "*_venv" install scheme is a scheme to bootstrap virtual environments, + # essentially identical to the default posix_prefix/nt schemes. + # Downstream distributors who patch posix_prefix/nt scheme are encouraged to + # leave the following schemes unchanged + 'posix_venv': { + 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', + 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': + '{installed_platbase}/include/python{py_version_short}{abiflags}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'nt_venv': { + 'stdlib': '{installed_base}/Lib', + 'platstdlib': '{base}/Lib', + 'purelib': '{base}/Lib/site-packages', + 'platlib': '{base}/Lib/site-packages', + 'include': '{installed_base}/Include', + 'platinclude': '{installed_base}/Include', + 'scripts': '{base}/Scripts', + 'data': '{base}', + }, + } + +# For the OS-native venv scheme, we essentially provide an alias: +if os.name == 'nt': + _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] +else: + _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] + + +# NOTE: site.py has copy of this function. +# Sync it when modify this function. +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + if env_base: + return env_base + + # Emscripten, VxWorks, and WASI have no home directories + if sys.platform in {"emscripten", "vxworks", "wasi"}: + return None + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + return joinuser(base, "Python") + + if sys.platform == "darwin" and sys._framework: + return joinuser("~", "Library", sys._framework, + f"{sys.version_info[0]}.{sys.version_info[1]}") + + return joinuser("~", ".local") + +_HAS_USER_BASE = (_getuserbase() is not None) + +if _HAS_USER_BASE: + _INSTALL_SCHEMES |= { + # NOTE: When modifying "purelib" scheme, update site._get_path() too. + 'nt_user': { + 'stdlib': '{userbase}/Python{py_version_nodot_plat}', + 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', + 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', + 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', + 'include': '{userbase}/Python{py_version_nodot_plat}/Include', + 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', + 'data': '{userbase}', + }, + 'posix_user': { + 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', + }, + 'osx_framework_user': { + 'stdlib': '{userbase}/lib/python', + 'platstdlib': '{userbase}/lib/python', + 'purelib': '{userbase}/lib/python/site-packages', + 'platlib': '{userbase}/lib/python/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data': '{userbase}', + }, + } + +_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', + 'scripts', 'data') + +_PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}' +_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}' +_PREFIX = os.path.normpath(sys.prefix) +_BASE_PREFIX = os.path.normpath(sys.base_prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) +# Mutex guarding initialization of _CONFIG_VARS. +_CONFIG_VARS_LOCK = threading.RLock() +_CONFIG_VARS = None +# True iff _CONFIG_VARS has been fully initialized. +_CONFIG_VARS_INITIALIZED = False +_USER_BASE = None + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +# In a virtual environment, `sys._home` gives us the target directory +# `_PROJECT_BASE` for the executable that created it when the virtual +# python is an actual executable ('venv --copies' or Windows). +_sys_home = getattr(sys, '_home', None) +if _sys_home: + _PROJECT_BASE = _sys_home + +if os.name == 'nt': + # In a source build, the executable is in a subdirectory of the root + # that we want (\PCbuild\). + # `_BASE_PREFIX` is used as the base installation is where the source + # will be. The realpath is needed to prevent mount point confusion + # that can occur with just string comparisons. + if _safe_realpath(_PROJECT_BASE).startswith( + _safe_realpath(f'{_BASE_PREFIX}\\PCbuild')): + _PROJECT_BASE = _BASE_PREFIX + +# set for cross builds +if "_PYTHON_PROJECT_BASE" in os.environ: + _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) + +def is_python_build(check_home=None): + if check_home is not None: + import warnings + warnings.warn("check_home argument is deprecated and ignored.", + DeprecationWarning, stacklevel=2) + for fn in ("Setup", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + # On POSIX-y platforms, Python will: + # - Build from .h files in 'headers' (which is only added to the + # scheme when building CPython) + # - Install .h files to 'include' + scheme = _INSTALL_SCHEMES[scheme] + scheme['headers'] = scheme['include'] + scheme['include'] = '{srcdir}/Include' + scheme['platinclude'] = '{projectbase}/.' + del scheme + + +def _subst_vars(s, local_vars): + try: + return s.format(**local_vars) + except KeyError as var: + try: + return s.format(**os.environ) + except KeyError: + raise AttributeError(f'{var}') from None + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + if os.name == 'nt': + # On Windows we want to substitute 'lib' for schemes rather + # than the native value (without modifying vars, in case it + # was passed in) + vars = vars | {'platlibdir': 'lib'} + + for key, value in _INSTALL_SCHEMES[scheme].items(): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def _get_preferred_schemes(): + if os.name == 'nt': + return { + 'prefix': 'nt', + 'home': 'posix_home', + 'user': 'nt_user', + } + if sys.platform == 'darwin' and sys._framework: + return { + 'prefix': 'posix_prefix', + 'home': 'posix_home', + 'user': 'osx_framework_user', + } + return { + 'prefix': 'posix_prefix', + 'home': 'posix_home', + 'user': 'posix_user', + } + + +def get_preferred_scheme(key): + if key == 'prefix' and sys.prefix != sys.base_prefix: + return 'venv' + scheme = _get_preferred_schemes()[key] + if scheme not in _INSTALL_SCHEMES: + raise ValueError( + f"{key!r} returned {scheme!r}, which is not a valid scheme " + f"on this platform" + ) + return scheme + + +def get_default_scheme(): + return get_preferred_scheme('prefix') + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' + else: + config_dir_name = 'config' + if hasattr(sys.implementation, '_multiarch'): + config_dir_name += f'-{sys.implementation._multiarch}' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _get_sysconfigdata_name(): + multiarch = getattr(sys.implementation, '_multiarch', '') + return os.environ.get( + '_PYTHON_SYSCONFIGDATA_NAME', + f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}', + ) + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # _sysconfigdata is generated at build time, see _generate_posix_vars() + name = _get_sysconfigdata_name() + _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) + build_time_vars = _temp.build_time_vars + vars.update(build_time_vars) + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + import _winapi + import _sysconfig + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + + # Add EXT_SUFFIX, SOABI, and Py_GIL_DISABLED + 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)) + vars['TZPATH'] = '' + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-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. + """ + if vars is None: + vars = {} + import re + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + if n in _ALWAYS_STR: + raise ValueError + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + # This ought to be as simple as dirname(sys._base_executable), but + # if a venv uses symlinks to a build in the source tree, then this + # fails. So instead we guess the subdirectory name from sys.winver + if sys.winver.endswith('-32'): + arch = 'win32' + elif sys.winver.endswith('-arm64'): + arch = 'arm64' + else: + arch = 'amd64' + inc_dir = os.path.join(_PROJECT_BASE, 'PCbuild', arch) + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_INSTALL_SCHEMES)) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + return _SCHEME_KEYS + + +def get_paths(scheme=get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + if expand: + return _expand_vars(scheme, vars) + else: + return _INSTALL_SCHEMES[scheme] + + +def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def _init_config_vars(): + global _CONFIG_VARS + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT + _CONFIG_VARS['installed_base'] = _BASE_PREFIX + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + _CONFIG_VARS['platlibdir'] = sys.platlibdir + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + try: + _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') + except AttributeError: + _CONFIG_VARS['py_version_nodot_plat'] = '' + + if os.name == 'nt': + _init_non_posix(_CONFIG_VARS) + _CONFIG_VARS['VPATH'] = sys._vpath + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + if _HAS_USER_BASE: + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + _CONFIG_VARS['userbase'] = _getuserbase() + + # Always convert srcdir to an absolute path + srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) + if os.name == 'posix': + if _PYTHON_BUILD: + # If srcdir is a relative path (typically '.' or '..') + # then it should be interpreted relative to the directory + # containing Makefile. + base = os.path.dirname(get_makefile_filename()) + srcdir = os.path.join(base, srcdir) + else: + # srcdir is not meaningful since the installation is + # spread about the filesystem. We choose the + # directory containing the Makefile since we know it + # exists. + srcdir = os.path.dirname(get_makefile_filename()) + _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) + + # OS X platforms require special customization to handle + # multi-architecture, multi-os-version installers + if sys.platform == 'darwin': + import _osx_support + _osx_support.customize_config_vars(_CONFIG_VARS) + + global _CONFIG_VARS_INITIALIZED + _CONFIG_VARS_INITIALIZED = True + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + + # Avoid claiming the lock once initialization is complete. + if not _CONFIG_VARS_INITIALIZED: + with _CONFIG_VARS_LOCK: + # Test again with the lock held to avoid races. Note that + # we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED, + # to ensure that recursive calls to get_config_vars() + # don't re-enter init_config_vars(). + if _CONFIG_VARS is None: + _init_config_vars() + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name and + version and the architecture (as supplied by 'os.uname()'), although the + exact information included depends on the OS; on Linux, the kernel version + isn't particularly important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + + """ + if os.name == 'nt': + if 'amd64' in sys.version.lower(): + return 'win-amd64' + if '(arm)' in sys.version.lower(): + return 'win-arm32' + if '(arm64)' in sys.version.lower(): + return 'win-arm64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha + return sys.platform + + # Set for cross builds explicitly + if "_PYTHON_HOST_PLATFORM" in os.environ: + return os.environ["_PYTHON_HOST_PLATFORM"] + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters, and translate + # spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return f"{osname}-{machine}" + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = f"{int(release[0]) - 3}.{release[2:]}" + # We can't use "platform.architecture()[0]" because a + # bootstrap problem. We use a dict to get an error + # if some suspicious happens. + bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} + machine += f".{bitness[sys.maxsize]}" + # fall through to standard osname-release-machine representation + elif osname[:3] == "aix": + from _aix_support import aix_platform + return aix_platform() + elif osname[:6] == "cygwin": + osname = "cygwin" + import re + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + import _osx_support + osname, release, machine = _osx_support.get_platform_osx( + get_config_vars(), + osname, release, machine) + + return f"{osname}-{release}-{machine}" + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def expand_makefile_vars(s, vars): + """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + 'string' according to 'vars' (a dictionary mapping variable names to + values). Variables not present in 'vars' are silently expanded to the + empty string. The variable values in 'vars' should not contain further + variable expansions; if 'vars' is the output of 'parse_makefile()', + you're fine. Returns a variable-expanded version of 's'. + """ + import re + + # This algorithm does multiple expansion, so if vars['foo'] contains + # "${bar}", it will expand ${foo} to ${bar}, and then expand + # ${bar}... and so forth. This is fine as long as 'vars' comes from + # 'parse_makefile()', which takes care of such expansions eagerly, + # according to make's variable expansion semantics. + + while True: + m = re.search(_findvar1_rx, s) or re.search(_findvar2_rx, s) + if m: + (beg, end) = m.span() + s = s[0:beg] + vars.get(m.group(1)) + s[end:] + else: + break + return s 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 726f9f50ba2e72..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 @@ -2219,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. ' diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 2b4f4313247128..cbfc172a789b25 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -269,6 +269,22 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type): raise FileExistsError(_errno.EEXIST, "No usable temporary file name found") +def _dont_follow_symlinks(func, path, *args): + # Pass follow_symlinks=False, unless not supported on this platform. + if func in _os.supports_follow_symlinks: + func(path, *args, follow_symlinks=False) + elif _os.name == 'nt' or not _os.path.islink(path): + func(path, *args) + +def _resetperms(path): + try: + chflags = _os.chflags + except AttributeError: + pass + else: + _dont_follow_symlinks(chflags, path, 0) + _dont_follow_symlinks(_os.chmod, path, 0o700) + # User visible interfaces. @@ -872,26 +888,37 @@ def __init__(self, suffix=None, prefix=None, dir=None, ignore_errors=self._ignore_cleanup_errors, delete=self._delete) @classmethod - def _rmtree(cls, name, ignore_errors=False): + def _rmtree(cls, name, ignore_errors=False, repeated=False): def onexc(func, path, exc): if isinstance(exc, PermissionError): - def resetperms(path): - try: - _os.chflags(path, 0) - except AttributeError: - pass - _os.chmod(path, 0o700) + if repeated and path == name: + if ignore_errors: + return + raise try: if path != name: - resetperms(_os.path.dirname(path)) - resetperms(path) + _resetperms(_os.path.dirname(path)) + _resetperms(path) try: _os.unlink(path) - # PermissionError is raised on FreeBSD for directories - except (IsADirectoryError, PermissionError): + except IsADirectoryError: cls._rmtree(path, ignore_errors=ignore_errors) + except PermissionError: + # The PermissionError handler was originally added for + # FreeBSD in directories, but it seems that it is raised + # on Windows too. + # bpo-43153: Calling _rmtree again may + # raise NotADirectoryError and mask the PermissionError. + # So we must re-raise the current PermissionError if + # path is not a directory. + if not _os.path.isdir(path) or _os.path.isjunction(path): + if ignore_errors: + return + raise + cls._rmtree(path, ignore_errors=ignore_errors, + repeated=(path == name)) except FileNotFoundError: pass elif isinstance(exc, FileNotFoundError): diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml index e202766b147e6d..74ab215ee8ee28 100644 --- a/Lib/test/.ruff.toml +++ b/Lib/test/.ruff.toml @@ -3,33 +3,22 @@ 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", - # Failed to parse - "support/socket_helper.py", - "test_fstring.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_typing.py", - "test_unittest/testmock/testpatch.py", "test_yield_from.py", "time_hashlib.py", - # Pending /~https://github.com/python/cpython/pull/109139 - "test_monitoring.py", ] diff --git a/Lib/test/_test_atexit.py b/Lib/test/_test_atexit.py index 55d28083349175..f618c1fcbca52b 100644 --- a/Lib/test/_test_atexit.py +++ b/Lib/test/_test_atexit.py @@ -19,7 +19,9 @@ def assert_raises_unraisable(self, exc_type, func, *args): atexit.register(func, *args) atexit._run_exitfuncs() - self.assertEqual(cm.unraisable.object, func) + self.assertIsNone(cm.unraisable.object) + self.assertEqual(cm.unraisable.err_msg, + f'Exception ignored in atexit callback {func!r}') self.assertEqual(cm.unraisable.exc_type, exc_type) self.assertEqual(type(cm.unraisable.exc_value), exc_type) @@ -125,7 +127,9 @@ def func(): try: with support.catch_unraisable_exception() as cm: atexit._run_exitfuncs() - self.assertEqual(cm.unraisable.object, func) + self.assertIsNone(cm.unraisable.object) + self.assertEqual(cm.unraisable.err_msg, + f'Exception ignored in atexit callback {func!r}') self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError) self.assertEqual(type(cm.unraisable.exc_value), ZeroDivisionError) finally: 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 279380fa7ea8e3..b8aff921a0c901 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): +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): @@ -1651,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') @@ -1675,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() @@ -2434,8 +2438,11 @@ def test_namespace(self): # # -def sqr(x, wait=0.0): - time.sleep(wait) +def sqr(x, wait=0.0, event=None): + if event is None: + time.sleep(wait) + else: + event.wait(wait) return x*x def mul(x, y): @@ -2574,10 +2581,18 @@ def test_async(self): self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) def test_async_timeout(self): - res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 1.0)) - get = TimingWrapper(res.get) - self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2) - self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2) + p = self.Pool(3) + try: + event = threading.Event() if self.TYPE == 'threads' else None + res = p.apply_async(sqr, (6, TIMEOUT2 + support.SHORT_TIMEOUT, event)) + get = TimingWrapper(res.get) + self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2) + self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2) + finally: + if event is not None: + event.set() + p.terminate() + p.join() def test_imap(self): it = self.pool.imap(sqr, list(range(10))) @@ -2678,14 +2693,15 @@ 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 - ) - 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) + if self.TYPE == 'threads': + self.skipTest("Threads cannot be terminated") + + # Simulate slow tasks which take "forever" to complete + p = self.Pool(3) + args = [support.LONG_TIMEOUT for i in range(10_000)] + result = p.map_async(time.sleep, args, chunksize=1) + p.terminate() + p.join() def test_empty_iterable(self): # See Issue 12157 @@ -4439,6 +4455,59 @@ def test_shared_memory_cleaned_after_process_termination(self): "resource_tracker: There appear to be 1 leaked " "shared_memory objects to clean up at shutdown", err) + @unittest.skipIf(os.name != "posix", "resource_tracker is posix only") + def test_shared_memory_untracking(self): + # gh-82300: When a separate Python process accesses shared memory + # with track=False, it must not cause the memory to be deleted + # when terminating. + cmd = '''if 1: + import sys + from multiprocessing.shared_memory import SharedMemory + mem = SharedMemory(create=False, name=sys.argv[1], track=False) + mem.close() + ''' + mem = shared_memory.SharedMemory(create=True, size=10) + # The resource tracker shares pipes with the subprocess, and so + # err existing means that the tracker process has terminated now. + try: + rc, out, err = script_helper.assert_python_ok("-c", cmd, mem.name) + self.assertNotIn(b"resource_tracker", err) + self.assertEqual(rc, 0) + mem2 = shared_memory.SharedMemory(create=False, name=mem.name) + mem2.close() + finally: + try: + mem.unlink() + except OSError: + pass + mem.close() + + @unittest.skipIf(os.name != "posix", "resource_tracker is posix only") + def test_shared_memory_tracking(self): + # gh-82300: When a separate Python process accesses shared memory + # with track=True, it must cause the memory to be deleted when + # terminating. + cmd = '''if 1: + import sys + from multiprocessing.shared_memory import SharedMemory + mem = SharedMemory(create=False, name=sys.argv[1], track=True) + mem.close() + ''' + mem = shared_memory.SharedMemory(create=True, size=10) + try: + rc, out, err = script_helper.assert_python_ok("-c", cmd, mem.name) + self.assertEqual(rc, 0) + self.assertIn( + b"resource_tracker: There appear to be 1 leaked " + b"shared_memory objects to clean up at shutdown", err) + finally: + try: + mem.unlink() + except OSError: + pass + resource_tracker.unregister(mem._name, "shared_memory") + mem.close() + # # Test to verify that `Finalize` works. # @@ -4908,7 +4977,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() @@ -4948,7 +5017,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() @@ -4997,25 +5066,19 @@ def test_wait_socket_slow(self): 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): diff --git a/Lib/test/archivetestdata/README.md b/Lib/test/archivetestdata/README.md new file mode 100644 index 00000000000000..7b555fa32765bf --- /dev/null +++ b/Lib/test/archivetestdata/README.md @@ -0,0 +1,36 @@ +# Test data for `test_zipfile`, `test_tarfile` (and even some others) + +## `test_zipfile` + +The test executables in this directory are created manually from `header.sh` and +the `testdata_module_inside_zip.py` file. You must have Info-ZIP's zip utility +installed (`apt install zip` on Debian). + +### Purpose of `exe_with_zip` and `exe_with_z64` + +These are used to test executable files with an appended zipfile, in a scenario +where the executable is _not_ a Python interpreter itself so our automatic +zipimport machinery (that'd look for `__main__.py`) is not being used. + +### Updating the test executables + +If you update header.sh or the testdata_module_inside_zip.py file, rerun the +commands below. These are expected to be rarely changed, if ever. + +#### Standard old format (2.0) zip file + +``` +zip -0 zip2.zip testdata_module_inside_zip.py +cat header.sh zip2.zip >exe_with_zip +rm zip2.zip +``` + +#### Modern format (4.5) zip64 file + +Redirecting from stdin forces Info-ZIP's zip tool to create a zip64. + +``` +zip -0 zip64.zip +cat header.sh zip64.zip >exe_with_z64 +rm zip64.zip +``` diff --git a/Lib/test/ziptestdata/exe_with_z64 b/Lib/test/archivetestdata/exe_with_z64 similarity index 100% rename from Lib/test/ziptestdata/exe_with_z64 rename to Lib/test/archivetestdata/exe_with_z64 diff --git a/Lib/test/ziptestdata/exe_with_zip b/Lib/test/archivetestdata/exe_with_zip similarity index 100% rename from Lib/test/ziptestdata/exe_with_zip rename to Lib/test/archivetestdata/exe_with_zip diff --git a/Lib/test/ziptestdata/header.sh b/Lib/test/archivetestdata/header.sh similarity index 100% rename from Lib/test/ziptestdata/header.sh rename to Lib/test/archivetestdata/header.sh diff --git a/Lib/test/recursion.tar b/Lib/test/archivetestdata/recursion.tar similarity index 100% rename from Lib/test/recursion.tar rename to Lib/test/archivetestdata/recursion.tar diff --git a/Lib/test/ziptestdata/testdata_module_inside_zip.py b/Lib/test/archivetestdata/testdata_module_inside_zip.py similarity index 100% rename from Lib/test/ziptestdata/testdata_module_inside_zip.py rename to Lib/test/archivetestdata/testdata_module_inside_zip.py diff --git a/Lib/test/testtar.tar b/Lib/test/archivetestdata/testtar.tar similarity index 100% rename from Lib/test/testtar.tar rename to Lib/test/archivetestdata/testtar.tar diff --git a/Lib/test/testtar.tar.xz b/Lib/test/archivetestdata/testtar.tar.xz similarity index 100% rename from Lib/test/testtar.tar.xz rename to Lib/test/archivetestdata/testtar.tar.xz diff --git a/Lib/test/zip_cp437_header.zip b/Lib/test/archivetestdata/zip_cp437_header.zip similarity index 100% rename from Lib/test/zip_cp437_header.zip rename to Lib/test/archivetestdata/zip_cp437_header.zip diff --git a/Lib/test/zipdir.zip b/Lib/test/archivetestdata/zipdir.zip similarity index 100% rename from Lib/test/zipdir.zip rename to Lib/test/archivetestdata/zipdir.zip diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index f0cedde308d53b..ce4a11b119c900 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -289,7 +289,7 @@ def hook(event, args): def test_unraisablehook(): - from _testinternalcapi import write_unraisable_exc + from _testcapi import err_formatunraisable def unraisablehook(hookargs): pass @@ -302,7 +302,8 @@ def hook(event, args): sys.addaudithook(hook) sys.unraisablehook = unraisablehook - write_unraisable_exc(RuntimeError("nonfatal-error"), "for audit hook test", None) + err_formatunraisable(RuntimeError("nonfatal-error"), + "Exception ignored for audit hook test") def test_winreg(): @@ -454,6 +455,9 @@ def __call__(self): i = _thread.start_new_thread(test_func(), ()) lock.acquire() + handle = _thread.start_joinable_thread(test_func()) + handle.join() + def test_threading_abort(): # Ensures that aborting PyThreadState_New raises the correct exception diff --git a/Lib/test/clinic.test.c b/Lib/test/clinic.test.c index 2ef7a6e8eb2795..a6a21664bb82a1 100644 --- a/Lib/test/clinic.test.c +++ b/Lib/test/clinic.test.c @@ -4951,6 +4951,55 @@ static PyObject * Test_meth_coexist_impl(TestObj *self) /*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/ +/*[clinic input] +@getter +Test.property +[clinic start generated code]*/ + +#if defined(TEST_PROPERTY_GETSETDEF) +# undef TEST_PROPERTY_GETSETDEF +# define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, (setter)Test_property_set, NULL}, +#else +# define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, NULL, NULL}, +#endif + +static PyObject * +Test_property_get_impl(TestObj *self); + +static PyObject * +Test_property_get(TestObj *self, void *Py_UNUSED(context)) +{ + return Test_property_get_impl(self); +} + +static PyObject * +Test_property_get_impl(TestObj *self) +/*[clinic end generated code: output=af8140b692e0e2f1 input=2d92b3449fbc7d2b]*/ + +/*[clinic input] +@setter +Test.property +[clinic start generated code]*/ + +#if defined(TEST_PROPERTY_GETSETDEF) +# undef TEST_PROPERTY_GETSETDEF +# define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, (setter)Test_property_set, NULL}, +#else +# define TEST_PROPERTY_GETSETDEF {"property", NULL, (setter)Test_property_set, NULL}, +#endif + +static int +Test_property_set_impl(TestObj *self, PyObject *value); + +static int +Test_property_set(TestObj *self, PyObject *value, void *Py_UNUSED(context)) +{ + return Test_property_set_impl(self, value); +} + +static int +Test_property_set_impl(TestObj *self, PyObject *value) +/*[clinic end generated code: output=f3eba6487d7550e2 input=3bc3f46a23c83a88]*/ /*[clinic input] output push @@ -5467,3 +5516,248 @@ docstr_fallback_to_converter_default(PyObject *module, PyObject *const *args, Py static PyObject * docstr_fallback_to_converter_default_impl(PyObject *module, str a) /*[clinic end generated code: output=ae24a9c6f60ee8a6 input=0cbe6a4d24bc2274]*/ + + +/*[clinic input] +@critical_section +test_critical_section +[clinic start generated code]*/ + +PyDoc_STRVAR(test_critical_section__doc__, +"test_critical_section($module, /)\n" +"--\n" +"\n"); + +#define TEST_CRITICAL_SECTION_METHODDEF \ + {"test_critical_section", (PyCFunction)test_critical_section, METH_NOARGS, test_critical_section__doc__}, + +static PyObject * +test_critical_section_impl(PyObject *module); + +static PyObject * +test_critical_section(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(module); + return_value = test_critical_section_impl(module); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +static PyObject * +test_critical_section_impl(PyObject *module) +/*[clinic end generated code: output=9d5a87bb28aa3f0c input=8c58956d6ff00f80]*/ + + +/*[clinic input] +@critical_section +test_critical_section_meth_o + a: object(subclass_of="&PyUnicode_Type") + / +[clinic start generated code]*/ + +PyDoc_STRVAR(test_critical_section_meth_o__doc__, +"test_critical_section_meth_o($module, a, /)\n" +"--\n" +"\n"); + +#define TEST_CRITICAL_SECTION_METH_O_METHODDEF \ + {"test_critical_section_meth_o", (PyCFunction)test_critical_section_meth_o, METH_O, test_critical_section_meth_o__doc__}, + +static PyObject * +test_critical_section_meth_o_impl(PyObject *module, PyObject *a); + +static PyObject * +test_critical_section_meth_o(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *a; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("test_critical_section_meth_o", "argument", "str", arg); + goto exit; + } + a = arg; + Py_BEGIN_CRITICAL_SECTION(module); + return_value = test_critical_section_meth_o_impl(module, a); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + +static PyObject * +test_critical_section_meth_o_impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=7a9d7420802d1202 input=376533f51eceb6c3]*/ + +/*[clinic input] +@critical_section a +test_critical_section_object + a: object(subclass_of="&PyUnicode_Type") + / +test_critical_section_object +[clinic start generated code]*/ + +PyDoc_STRVAR(test_critical_section_object__doc__, +"test_critical_section_object($module, a, /)\n" +"--\n" +"\n" +"test_critical_section_object"); + +#define TEST_CRITICAL_SECTION_OBJECT_METHODDEF \ + {"test_critical_section_object", (PyCFunction)test_critical_section_object, METH_O, test_critical_section_object__doc__}, + +static PyObject * +test_critical_section_object_impl(PyObject *module, PyObject *a); + +static PyObject * +test_critical_section_object(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *a; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("test_critical_section_object", "argument", "str", arg); + goto exit; + } + a = arg; + Py_BEGIN_CRITICAL_SECTION(a); + return_value = test_critical_section_object_impl(module, a); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + +static PyObject * +test_critical_section_object_impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=ec06df92232b0fb5 input=6f67f91b523c875f]*/ + +PyDoc_STRVAR(test_critical_section_object__doc__, +"test_critical_section_object($module, a, /)\n" +"--\n" +"\n" +"test_critical_section_object"); + +#define TEST_CRITICAL_SECTION_OBJECT_METHODDEF \ + {"test_critical_section_object", (PyCFunction)test_critical_section_object, METH_O, test_critical_section_object__doc__}, + +static PyObject * +test_critical_section_object_impl(PyObject *module, PyObject *a); + +static PyObject * +test_critical_section_object(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *a; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("test_critical_section_object", "argument", "str", arg); + goto exit; + } + a = arg; + Py_BEGIN_CRITICAL_SECTION(a); + return_value = test_critical_section_object_impl(module, a); + Py_END_CRITICAL_SECTION(); + +exit: + return return_value; +} + +/*[clinic input] +@critical_section a b +test_critical_section_object2 + a: object(subclass_of="&PyUnicode_Type") + b: object(subclass_of="&PyUnicode_Type") + / +test_critical_section_object2 +[clinic start generated code]*/ + +PyDoc_STRVAR(test_critical_section_object2__doc__, +"test_critical_section_object2($module, a, b, /)\n" +"--\n" +"\n" +"test_critical_section_object2"); + +#define TEST_CRITICAL_SECTION_OBJECT2_METHODDEF \ + {"test_critical_section_object2", _PyCFunction_CAST(test_critical_section_object2), METH_FASTCALL, test_critical_section_object2__doc__}, + +static PyObject * +test_critical_section_object2_impl(PyObject *module, PyObject *a, + PyObject *b); + +static PyObject * +test_critical_section_object2(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + + if (!_PyArg_CheckPositional("test_critical_section_object2", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("test_critical_section_object2", "argument 1", "str", args[0]); + goto exit; + } + a = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("test_critical_section_object2", "argument 2", "str", args[1]); + goto exit; + } + b = args[1]; + Py_BEGIN_CRITICAL_SECTION2(a, b); + return_value = test_critical_section_object2_impl(module, a, b); + Py_END_CRITICAL_SECTION2(); + +exit: + return return_value; +} + +static PyObject * +test_critical_section_object2_impl(PyObject *module, PyObject *a, + PyObject *b) +/*[clinic end generated code: output=d73a1657c18df17a input=638824e41419a466]*/ + +PyDoc_STRVAR(test_critical_section_object2__doc__, +"test_critical_section_object2($module, a, b, /)\n" +"--\n" +"\n" +"test_critical_section_object2"); + +#define TEST_CRITICAL_SECTION_OBJECT2_METHODDEF \ + {"test_critical_section_object2", _PyCFunction_CAST(test_critical_section_object2), METH_FASTCALL, test_critical_section_object2__doc__}, + +static PyObject * +test_critical_section_object2_impl(PyObject *module, PyObject *a, + PyObject *b); + +static PyObject * +test_critical_section_object2(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + + if (!_PyArg_CheckPositional("test_critical_section_object2", nargs, 2, 2)) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("test_critical_section_object2", "argument 1", "str", args[0]); + goto exit; + } + a = args[0]; + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("test_critical_section_object2", "argument 2", "str", args[1]); + goto exit; + } + b = args[1]; + Py_BEGIN_CRITICAL_SECTION2(a, b); + return_value = test_critical_section_object2_impl(module, a, b); + Py_END_CRITICAL_SECTION2(); + +exit: + return return_value; +} diff --git a/Lib/test/cfgparser.1 b/Lib/test/configdata/cfgparser.1 similarity index 100% rename from Lib/test/cfgparser.1 rename to Lib/test/configdata/cfgparser.1 diff --git a/Lib/test/cfgparser.2 b/Lib/test/configdata/cfgparser.2 similarity index 100% rename from Lib/test/cfgparser.2 rename to Lib/test/configdata/cfgparser.2 diff --git a/Lib/test/cfgparser.3 b/Lib/test/configdata/cfgparser.3 similarity index 100% rename from Lib/test/cfgparser.3 rename to Lib/test/configdata/cfgparser.3 diff --git a/Lib/test/cov.py b/Lib/test/cov.py new file mode 100644 index 00000000000000..e4699c7afe174a --- /dev/null +++ b/Lib/test/cov.py @@ -0,0 +1,48 @@ +"""A minimal hook for gathering line coverage of the standard library. + +Designed to be used with -Xpresite= which means: +* it installs itself on import +* it's not imported as `__main__` so can't use the ifmain idiom +* it can't import anything besides `sys` to avoid tainting gathered coverage +* filenames are not normalized + +To get gathered coverage back, look for 'test.cov' in `sys.modules` +instead of importing directly. That way you can determine if the module +was already in use. + +If you need to disable the hook, call the `disable()` function. +""" + +import sys + +mon = sys.monitoring + +FileName = str +LineNo = int +Location = tuple[FileName, LineNo] + +coverage: set[Location] = set() + + +# `types` and `typing` aren't imported to avoid invalid coverage +def add_line( + code: "types.CodeType", + lineno: int, +) -> "typing.Literal[sys.monitoring.DISABLE]": + coverage.add((code.co_filename, lineno)) + return mon.DISABLE + + +def enable(): + mon.use_tool_id(mon.COVERAGE_ID, "regrtest coverage") + mon.register_callback(mon.COVERAGE_ID, mon.events.LINE, add_line) + mon.set_events(mon.COVERAGE_ID, mon.events.LINE) + + +def disable(): + mon.set_events(mon.COVERAGE_ID, 0) + mon.register_callback(mon.COVERAGE_ID, mon.events.LINE, None) + mon.free_tool_id(mon.COVERAGE_ID) + + +enable() diff --git a/Lib/test/imp_dummy.py b/Lib/test/imp_dummy.py deleted file mode 100644 index 2a4deb49547cf4..00000000000000 --- a/Lib/test/imp_dummy.py +++ /dev/null @@ -1,3 +0,0 @@ -# Fodder for test of issue24748 in test_imp - -dummy_name = True diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index 0a863561d5273d..0053bce4292f64 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -2,9 +2,8 @@ import os.path import shlex import sys -from test.support import os_helper - -from .utils import MS_WINDOWS +from test.support import os_helper, Py_DEBUG +from .utils import ALL_RESOURCES, RESOURCE_NAMES, TestFilter USAGE = """\ @@ -29,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 @@ -132,19 +133,6 @@ """ -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') - - class Namespace(argparse.Namespace): def __init__(self, **kwargs) -> None: self.ci = False @@ -173,8 +161,7 @@ def __init__(self, **kwargs) -> None: self.forever = False self.header = False self.failfast = False - self.match_tests = None - self.ignore_tests = None + self.match_tests: TestFilter = [] self.pgo = False self.pgo_extended = False self.worker_json = None @@ -195,6 +182,20 @@ def error(self, message): super().error(message + "\nPass -h or --help for complete help.") +class FilterAction(argparse.Action): + def __call__(self, parser, namespace, value, option_string=None): + items = getattr(namespace, self.dest) + items.append((value, self.const)) + + +class FromFileFilterAction(argparse.Action): + def __call__(self, parser, namespace, value, option_string=None): + items = getattr(namespace, self.dest) + with open(value, encoding='utf-8') as fp: + for line in fp: + items.append((line.strip(), self.const)) + + def _create_parser(): # Set prog to prevent the uninformative "__main__.py" from displaying in # error messages when using "python -m test ...". @@ -204,6 +205,7 @@ def _create_parser(): epilog=EPILOG, add_help=False, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.set_defaults(match_tests=[]) # Arguments with this clause added to its help are described further in # the epilog's "Additional option details" section. @@ -231,6 +233,9 @@ def _create_parser(): 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', @@ -251,10 +256,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) @@ -264,17 +265,19 @@ def _create_parser(): help='single step through a set of tests.' + more_details) group.add_argument('-m', '--match', metavar='PAT', - dest='match_tests', action='append', + dest='match_tests', action=FilterAction, const=True, help='match test cases and methods with glob pattern PAT') group.add_argument('-i', '--ignore', metavar='PAT', - dest='ignore_tests', action='append', + dest='match_tests', action=FilterAction, const=False, help='ignore test cases and methods with glob pattern PAT') group.add_argument('--matchfile', metavar='FILENAME', - dest='match_filename', + dest='match_tests', + action=FromFileFilterAction, const=True, help='similar to --match but get patterns from a ' 'text file, one pattern per line') group.add_argument('--ignorefile', metavar='FILENAME', - dest='ignore_filename', + dest='match_tests', + action=FromFileFilterAction, const=False, help='similar to --matchfile but it receives patterns ' 'from text file to ignore') group.add_argument('-G', '--failfast', action='store_true', @@ -414,18 +417,15 @@ def _parse_args(args, **kwargs): # Similar to options: # # -j0 --randomize --fail-env-changed --fail-rerun --rerun - # --slowest --verbose3 --nowindows + # --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 - if MS_WINDOWS: - ns.nowindows = True # Silence alerts under Windows else: ns._add_python_opts = False @@ -433,21 +433,31 @@ def _parse_args(args, **kwargs): # --slow-ci has the priority if ns.slow_ci: # Similar to: -u "all" --timeout=1200 - if not ns.use: - ns.use = [['all']] + if ns.use is None: + ns.use = [] + ns.use.insert(0, ['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.use is None: + ns.use = [] + ns.use.insert(0, ['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!") - if ns.use_mp is not None and ns.trace: - parser.error("-T and -j don't go together!") + if ns.trace: + if ns.use_mp is not None: + if not Py_DEBUG: + parser.error("need --with-pydebug to use -T and -j together") + else: + print( + "Warning: collecting coverage without -j is imprecise. Configure" + " --with-pydebug and run -m test -T -j for best results.", + file=sys.stderr + ) if ns.python is not None: if ns.use_mp is None: parser.error("-p requires -j!") @@ -491,23 +501,17 @@ def _parse_args(args, **kwargs): ns.randomize = True if ns.verbose: ns.header = True - if ns.huntrleaks and ns.verbose3: + # When -jN option is used, a worker process does not use --verbose3 + # and so -R 3:3 -jN --verbose3 just works as expected: there is no false + # alarm about memory leak. + if ns.huntrleaks and ns.verbose3 and ns.use_mp is None: ns.verbose3 = False + # run_single_test() replaces sys.stdout with io.StringIO if verbose3 + # is true. In this case, huntrleaks sees an write into StringIO as + # a memory leak, whereas it is not (gh-71290). print("WARNING: Disable --verbose3 because it's incompatible with " - "--huntrleaks: see http://bugs.python.org/issue27103", + "--huntrleaks without -jN option", file=sys.stderr) - if ns.match_filename: - if ns.match_tests is None: - ns.match_tests = [] - with open(ns.match_filename) as fp: - for line in fp: - ns.match_tests.append(line.strip()) - if ns.ignore_filename: - if ns.ignore_tests is None: - ns.ignore_tests = [] - with open(ns.ignore_filename) as fp: - for line in fp: - ns.ignore_tests.append(line.strip()) if ns.forever: # --forever implies --failfast ns.failfast = True diff --git a/Lib/test/libregrtest/filter.py b/Lib/test/libregrtest/filter.py new file mode 100644 index 00000000000000..817624d79e9263 --- /dev/null +++ b/Lib/test/libregrtest/filter.py @@ -0,0 +1,72 @@ +import itertools +import operator +import re + + +# By default, don't filter tests +_test_matchers = () +_test_patterns = () + + +def match_test(test): + # Function used by support.run_unittest() and regrtest --list-cases + result = False + for matcher, result in reversed(_test_matchers): + if matcher(test.id()): + return result + return not result + + +def _is_full_match_test(pattern): + # If a pattern contains at least one dot, it's considered + # as a full test identifier. + # Example: 'test.test_os.FileTests.test_access'. + # + # ignore patterns which contain fnmatch patterns: '*', '?', '[...]' + # or '[!...]'. For example, ignore 'test_access*'. + return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern)) + + +def set_match_tests(patterns): + global _test_matchers, _test_patterns + + if not patterns: + _test_matchers = () + _test_patterns = () + else: + itemgetter = operator.itemgetter + patterns = tuple(patterns) + if patterns != _test_patterns: + _test_matchers = [ + (_compile_match_function(map(itemgetter(0), it)), result) + for result, it in itertools.groupby(patterns, itemgetter(1)) + ] + _test_patterns = patterns + + +def _compile_match_function(patterns): + patterns = list(patterns) + + if all(map(_is_full_match_test, patterns)): + # Simple case: all patterns are full test identifier. + # The test.bisect_cmd utility only uses such full test identifiers. + return set(patterns).__contains__ + else: + import fnmatch + regex = '|'.join(map(fnmatch.translate, patterns)) + # The search *is* case sensitive on purpose: + # don't use flags=re.IGNORECASE + regex_match = re.compile(regex).match + + def match_test_regex(test_id, regex_match=regex_match): + if regex_match(test_id): + # The regex matches the whole identifier, for example + # 'test.test_os.FileTests.test_access'. + return True + else: + # Try to match parts of the test identifier. + # For example, split 'test.test_os.FileTests.test_access' + # into: 'test', 'test_os', 'FileTests' and 'test_access'. + return any(map(regex_match, test_id.split("."))) + + return match_test_regex diff --git a/Lib/test/libregrtest/findtests.py b/Lib/test/libregrtest/findtests.py index 96cc3e0d021184..78343775bc5b99 100644 --- a/Lib/test/libregrtest/findtests.py +++ b/Lib/test/libregrtest/findtests.py @@ -4,8 +4,9 @@ from test import support +from .filter import match_test, set_match_tests from .utils import ( - StrPath, TestName, TestTuple, TestList, FilterTuple, + StrPath, TestName, TestTuple, TestList, TestFilter, abs_module_name, count, printlist) @@ -20,6 +21,7 @@ "test_concurrent_futures", "test_future_stmt", "test_gdb", + "test_inspect", "test_multiprocessing_fork", "test_multiprocessing_forkserver", "test_multiprocessing_spawn", @@ -78,15 +80,14 @@ def _list_cases(suite): if isinstance(test, unittest.TestSuite): _list_cases(test) elif isinstance(test, unittest.TestCase): - if support.match_test(test): + if match_test(test): print(test.id()) def list_cases(tests: TestTuple, *, - match_tests: FilterTuple | None = None, - ignore_tests: FilterTuple | None = None, + match_tests: TestFilter | None = None, test_dir: StrPath | None = None): support.verbose = False - support.set_match_tests(match_tests, ignore_tests) + set_match_tests(match_tests) skipped = [] for test_name in tests: diff --git a/Lib/test/libregrtest/logger.py b/Lib/test/libregrtest/logger.py index 2f0c4bf1c84b5c..a125706927393c 100644 --- a/Lib/test/libregrtest/logger.py +++ b/Lib/test/libregrtest/logger.py @@ -1,9 +1,10 @@ import os import time +from test.support import MS_WINDOWS from .results import TestResults from .runtests import RunTests -from .utils import print_warning, MS_WINDOWS +from .utils import print_warning if MS_WINDOWS: from .win_utils import WindowsLoadTracker diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index dcb2c5870de176..7ca1b1cb65ae40 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -3,26 +3,29 @@ import re import shlex import sys +import sysconfig import time +import trace from test import support -from test.support import os_helper +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 .result import State, TestResult 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, + StrPath, StrJSON, TestName, TestList, TestTuple, TestFilter, strip_py_suffix, count, format_duration, printlist, get_temp_dir, get_work_dir, exit_timeout, display_header, cleanup_temp_dir, print_warning, - MS_WINDOWS, EXIT_TIMEOUT) + is_cross_compiled, get_host_runner, + EXIT_TIMEOUT) class Regrtest: @@ -71,20 +74,12 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False): self.want_rerun: bool = ns.rerun self.want_run_leaks: bool = ns.runleaks - ci_mode = (ns.fast_ci or ns.slow_ci) + 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 - and ci_mode) + 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.match_tests: TestFilter = ns.match_tests self.exclude: bool = ns.exclude self.fromfile: StrPath | None = ns.fromfile self.starting_test: TestName | None = ns.start @@ -105,8 +100,6 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False): self.fail_env_changed: bool = ns.fail_env_changed self.fail_rerun: bool = ns.fail_rerun self.forever: bool = ns.forever - self.randomize: bool = ns.randomize - self.random_seed: int | None = ns.random_seed self.output_on_failure: bool = ns.verbose3 self.timeout: float | None = ns.timeout if ns.huntrleaks: @@ -128,6 +121,22 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False): self.coverage_dir: StrPath | None = ns.coverdir self.tmp_dir: StrPath | None = ns.tempdir + # Randomize + self.randomize: bool = ns.randomize + if ('SOURCE_DATE_EPOCH' in os.environ + # don't use the variable if empty + and os.environ['SOURCE_DATE_EPOCH'] + ): + self.randomize = False + # SOURCE_DATE_EPOCH should be an integer, but use a string to not + # fail if it's not integer. random.seed() accepts a string. + # https://reproducible-builds.org/docs/source-date-epoch/ + self.random_seed: int | str = os.environ['SOURCE_DATE_EPOCH'] + elif ns.random_seed is None: + self.random_seed = random.getrandbits(32) + else: + self.random_seed = ns.random_seed + # tests self.first_runtests: RunTests | None = None @@ -208,10 +217,8 @@ def find_tests(self, tests: TestList | None = None) -> tuple[TestTuple, TestList print(f"Cannot find starting test: {self.starting_test}") sys.exit(1) + random.seed(self.random_seed) if self.randomize: - if self.random_seed is None: - self.random_seed = random.randrange(100_000_000) - random.seed(self.random_seed) random.shuffle(selected) return (tuple(selected), tests) @@ -278,7 +285,9 @@ def display_result(self, runtests): self.results.display_result(runtests.tests, self.quiet, self.print_slowest) - def run_test(self, test_name: TestName, runtests: RunTests, tracer): + def run_test( + self, test_name: TestName, runtests: RunTests, tracer: trace.Trace | None + ) -> TestResult: 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. @@ -286,6 +295,9 @@ def run_test(self, test_name: TestName, runtests: RunTests, tracer): namespace = dict(locals()) tracer.runctx(cmd, globals=globals(), locals=namespace) result = namespace['result'] + # Mypy doesn't know about this attribute yet, + # but it will do soon: /~https://github.com/python/typeshed/pull/11091 + result.covered_lines = list(tracer.counts) # type: ignore[attr-defined] else: result = run_single_test(test_name, runtests) @@ -293,14 +305,13 @@ def run_test(self, test_name: TestName, runtests: RunTests, tracer): return result - def run_tests_sequentially(self, runtests): + def run_tests_sequentially(self, runtests) -> None: if self.coverage: - import trace tracer = trace.Trace(trace=False, count=True) else: tracer = None - save_modules = sys.modules.keys() + save_modules = set(sys.modules) jobs = runtests.get_jobs() if jobs is not None: @@ -324,10 +335,18 @@ def run_tests_sequentially(self, runtests): 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) + # Unload the newly imported test modules (best effort finalization) + new_modules = [module for module in sys.modules + if module not in save_modules and + module.startswith(("test.", "test_"))] + for module in new_modules: + sys.modules.pop(module, None) + # Remove the attribute of the parent module. + parent, _, name = module.rpartition('.') + try: + delattr(sys.modules[parent], name) + except (KeyError, AttributeError): + pass if result.must_stop(self.fail_fast, self.fail_env_changed): break @@ -343,8 +362,6 @@ def run_tests_sequentially(self, runtests): if previous_test: print(previous_test) - return tracer - def get_state(self): state = self.results.get_state(self.fail_env_changed) if self.first_state: @@ -355,7 +372,7 @@ 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_tests(self, tracer): + def finalize_tests(self, coverage: trace.CoverageResults | None) -> None: if self.next_single_filename: if self.next_single_test: with open(self.next_single_filename, 'w') as fp: @@ -363,10 +380,11 @@ def finalize_tests(self, tracer): else: os.unlink(self.next_single_filename) - if tracer is not None: - results = tracer.results() - results.write_results(show_missing=True, summary=True, - coverdir=self.coverage_dir) + if coverage is not None: + # uses a new-in-Python 3.13 keyword argument that mypy doesn't know about yet: + coverage.write_results(show_missing=True, summary=True, # type: ignore[call-arg] + coverdir=self.coverage_dir, + ignore_missing_files=True) if self.want_run_leaks: os.system("leaks %d" % os.getpid()) @@ -376,7 +394,7 @@ def finalize_tests(self, tracer): def display_summary(self): duration = time.perf_counter() - self.logger.start_time - filtered = bool(self.match_tests) or bool(self.ignore_tests) + filtered = bool(self.match_tests) # Total duration print() @@ -394,7 +412,6 @@ def create_run_tests(self, tests: TestTuple): 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, @@ -407,13 +424,13 @@ def create_run_tests(self, tests: TestTuple): hunt_refleak=self.hunt_refleak, test_dir=self.test_dir, use_junit=(self.junit_filename is not None), + coverage=self.coverage, 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: @@ -425,16 +442,18 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int: if self.num_workers < 0: # Use all CPUs + 2 extra worker processes for tests # that like to sleep - self.num_workers = (os.cpu_count() or 1) + 2 + # + # os.process.cpu_count() is new in Python 3.13; + # mypy doesn't know about it yet + self.num_workers = (os.process_cpu_count() or 1) + 2 # type: ignore[attr-defined] # 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) + display_header(self.use_resources, self.python_cmd) - if self.randomize: - print("Using random seed", self.random_seed) + print("Using random seed:", self.random_seed) runtests = self.create_run_tests(selected) self.first_runtests = runtests @@ -454,10 +473,10 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int: try: if self.num_workers: self._run_tests_mp(runtests, self.num_workers) - tracer = None else: - tracer = self.run_tests_sequentially(runtests) + self.run_tests_sequentially(runtests) + coverage = self.results.get_coverage_results() self.display_result(runtests) if self.want_rerun and self.results.need_rerun(): @@ -467,7 +486,7 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int: self.logger.stop_load_tracker() self.display_summary() - self.finalize_tests(tracer) + self.finalize_tests(coverage) return self.results.get_exitcode(self.fail_env_changed, self.fail_rerun) @@ -489,8 +508,56 @@ def run_tests(self, selected: TestTuple, tests: TestList | None) -> int: # processes. return self._run_tests(selected, tests) - def _add_python_opts(self): - python_opts = [] + 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: @@ -504,32 +571,27 @@ def _add_python_opts(self): if sys.flags.bytes_warning < 2: python_opts.append('-bb') - # WASM/WASI buildbot builders pass multiple PYTHON environment - # variables such as PYTHONPATH and _PYTHON_HOSTRUNNER. - if not self.python_cmd: + if not keep_environ: # Ignore PYTHON* environment variables if not sys.flags.ignore_environment: python_opts.append('-E') - if not python_opts: - return - - cmd = [*sys.orig_argv, "--dont-add-python-opts"] - cmd[1:1] = python_opts - + 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) + 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) as proc: + with subprocess.Popen(cmd, env=environ) as proc: try: proc.wait() except KeyboardInterrupt: @@ -548,6 +610,28 @@ def _add_python_opts(self): 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 + + # 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") + + self._execute_python(cmd, environ) + def _init(self): # Set sys.stdout encoder error handler to backslashreplace, # similar to sys.stderr error handler, to avoid UnicodeEncodeError @@ -583,7 +667,6 @@ def main(self, tests: TestList | None = None): 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) diff --git a/Lib/test/libregrtest/mypy.ini b/Lib/test/libregrtest/mypy.ini index fefc347728a701..22c7c7a9acef14 100644 --- a/Lib/test/libregrtest/mypy.ini +++ b/Lib/test/libregrtest/mypy.ini @@ -5,7 +5,7 @@ [mypy] files = Lib/test/libregrtest explicit_package_bases = True -python_version = 3.11 +python_version = 3.12 platform = linux pretty = True @@ -25,7 +25,7 @@ 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.*] +[mypy-Lib.test.libregrtest.main.*,Lib.test.libregrtest.run_workers.*] strict_optional = False # Various internal modules that typeshed deliberately doesn't have stubs for: diff --git a/Lib/test/libregrtest/pgo.py b/Lib/test/libregrtest/pgo.py index cabbba73d5eff5..e3a6927be5db1d 100644 --- a/Lib/test/libregrtest/pgo.py +++ b/Lib/test/libregrtest/pgo.py @@ -42,10 +42,10 @@ 'test_set', 'test_sqlite3', 'test_statistics', + 'test_str', 'test_struct', 'test_tabnanny', 'test_time', - 'test_unicode', 'test_xml_etree', 'test_xml_etree_c', ] diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index ada1a65b867ee6..5836a8421cb42d 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -52,7 +52,8 @@ def runtest_refleak(test_name, test_func, except ImportError: zdc = None # Run unmodified on platforms without zipimport support else: - zdc = zipimport._zip_directory_cache.copy() + # private attribute that mypy doesn't know about: + zdc = zipimport._zip_directory_cache.copy() # type: ignore[attr-defined] abcs = {} for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: if not isabstract(abc): diff --git a/Lib/test/libregrtest/result.py b/Lib/test/libregrtest/result.py index bf885264657d5c..74eae40440435d 100644 --- a/Lib/test/libregrtest/result.py +++ b/Lib/test/libregrtest/result.py @@ -2,13 +2,35 @@ import json from typing import Any -from test.support import TestStats - from .utils import ( StrJSON, TestName, FilterTuple, format_duration, normalize_test_name, print_warning) +@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 + + # Avoid enum.Enum to reduce the number of imports when tests are run class State: PASSED = "PASSED" @@ -19,7 +41,8 @@ class State: ENV_CHANGED = "ENV_CHANGED" RESOURCE_DENIED = "RESOURCE_DENIED" INTERRUPTED = "INTERRUPTED" - MULTIPROCESSING_ERROR = "MULTIPROCESSING_ERROR" + 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" @@ -29,7 +52,8 @@ def is_failed(state): State.FAILED, State.UNCAUGHT_EXC, State.REFLEAK, - State.MULTIPROCESSING_ERROR, + State.WORKER_FAILED, + State.WORKER_BUG, State.TIMEOUT} @staticmethod @@ -42,14 +66,21 @@ def has_meaningful_duration(state): State.SKIPPED, State.RESOURCE_DENIED, State.INTERRUPTED, - State.MULTIPROCESSING_ERROR, + State.WORKER_FAILED, + State.WORKER_BUG, State.DID_NOT_RUN} @staticmethod def must_stop(state): return state in { State.INTERRUPTED, - State.MULTIPROCESSING_ERROR} + State.WORKER_BUG, + } + + +FileName = str +LineNo = int +Location = tuple[FileName, LineNo] @dataclasses.dataclass(slots=True) @@ -65,6 +96,9 @@ class TestResult: errors: list[tuple[str, str]] | None = None failures: list[tuple[str, str]] | None = None + # partial coverage in a worker run; not used by sequential in-process runs + covered_lines: list[Location] | None = None + def is_failed(self, fail_env_changed: bool) -> bool: if self.state == State.ENV_CHANGED: return fail_env_changed @@ -108,8 +142,10 @@ def __str__(self) -> str: return f"{self.test_name} skipped (resource denied)" case State.INTERRUPTED: return f"{self.test_name} interrupted" - case State.MULTIPROCESSING_ERROR: - return f"{self.test_name} process crashed" + 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: @@ -179,6 +215,10 @@ def _decode_test_result(data: dict[str, Any]) -> TestResult | dict[str, Any]: data.pop('__test_result__') if data['stats'] is not None: data['stats'] = TestStats(**data['stats']) + if data['covered_lines'] is not None: + data['covered_lines'] = [ + tuple(loc) for loc in data['covered_lines'] + ] return TestResult(**data) else: return data diff --git a/Lib/test/libregrtest/results.py b/Lib/test/libregrtest/results.py index 35df50d581ff6a..a41ea8aba028c3 100644 --- a/Lib/test/libregrtest/results.py +++ b/Lib/test/libregrtest/results.py @@ -1,14 +1,14 @@ import sys -from test.support import TestStats +import trace from .runtests import RunTests -from .result import State, TestResult +from .result import State, TestResult, TestStats, Location from .utils import ( StrPath, TestName, TestTuple, TestList, FilterDict, printlist, count, format_duration) -# Python uses exit code 1 when an exception is not catched +# Python uses exit code 1 when an exception is not caught # argparse.ArgumentParser.error() uses exit code 2 EXITCODE_BAD_TEST = 2 EXITCODE_ENV_CHANGED = 3 @@ -30,15 +30,19 @@ def __init__(self): 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] = [] + self.testsuite_xml: list = [] + # used by -T with -j + self.covered_lines: set[Location] = set() def is_all_good(self): return (not self.bad and not self.skipped - and not self.interrupted) + and not self.interrupted + and not self.worker_bug) def get_executed(self): return (set(self.good) | set(self.bad) | set(self.skipped) @@ -60,6 +64,8 @@ def get_state(self, fail_env_changed): if self.interrupted: state.append("INTERRUPTED") + if self.worker_bug: + state.append("WORKER BUG") if not state: state.append("SUCCESS") @@ -77,6 +83,8 @@ def get_exitcode(self, fail_env_changed, fail_rerun): 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): @@ -105,17 +113,28 @@ def accumulate_result(self, result: TestResult, runtests: RunTests): 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: + if result.duration is None: + raise ValueError("result.duration is None") 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) - + if result.covered_lines: + # we don't care about trace counts so we don't have to sum them up + self.covered_lines.update(result.covered_lines) xml_data = result.xml_data if xml_data: self.add_junit(xml_data) + def get_coverage_results(self) -> trace.CoverageResults: + counts = {loc: 1 for loc in self.covered_lines} + return trace.CoverageResults(counts=counts) + def need_rerun(self): return bool(self.rerun_results) @@ -173,12 +192,6 @@ def write_junit(self, filename: StrPath): f.write(s) def display_result(self, tests: TestTuple, quiet: bool, print_slowest: bool): - omitted = set(tests) - self.get_executed() - if omitted: - print() - print(count(len(omitted), "test"), "omitted:") - printlist(omitted) - if print_slowest: self.test_times.sort(reverse=True) print() @@ -186,16 +199,21 @@ def display_result(self, tests: TestTuple, quiet: bool, print_slowest: bool): for test_time, test in self.test_times[:10]: print("- %s: %s" % (test, format_duration(test_time))) - all_tests = [ - (self.bad, "test", "{} failed:"), - (self.env_changed, "test", "{} altered the execution environment (env changed):"), - ] + 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.rerun, "re-run test", "{}:")) 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() diff --git a/Lib/test/libregrtest/run_workers.py b/Lib/test/libregrtest/run_workers.py index 41ed7b0bac01ad..18a0342f0611cf 100644 --- a/Lib/test/libregrtest/run_workers.py +++ b/Lib/test/libregrtest/run_workers.py @@ -10,19 +10,19 @@ import threading import time import traceback -from typing import Literal, TextIO +from typing import Any, Literal, TextIO from test import support -from test.support import os_helper +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 .runtests import RunTests, WorkerRunTests, JsonFile, JsonFileType from .single import PROGRESS_MIN_TIME from .utils import ( - StrPath, TestName, MS_WINDOWS, - format_duration, print_warning, count, plural) + StrPath, TestName, + format_duration, print_warning, count, plural, get_signal_name) from .worker import create_worker_process, USE_PROCESS_GROUP if MS_WINDOWS: @@ -92,7 +92,7 @@ def __init__(self, test_name: TestName, err_msg: str | None, stdout: str | None, - state: str = State.MULTIPROCESSING_ERROR): + state: str): result = TestResult(test_name, state=state) self.mp_result = MultiprocessResult(result, stdout, err_msg) super().__init__() @@ -162,7 +162,7 @@ def stop(self) -> None: self._stopped = True self._kill() - def _run_process(self, runtests: RunTests, output_fd: int, + def _run_process(self, runtests: WorkerRunTests, output_fd: int, tmp_dir: StrPath | None = None) -> int | None: popen = create_worker_process(runtests, output_fd, tmp_dir) self._popen = popen @@ -243,38 +243,41 @@ def create_json_file(self, stack: contextlib.ExitStack) -> tuple[JsonFile, TextI json_fd = json_tmpfile.fileno() if MS_WINDOWS: - json_handle = msvcrt.get_osfhandle(json_fd) + # The msvcrt module is only available on Windows; + # we run mypy with `--platform=linux` in CI + json_handle: int = msvcrt.get_osfhandle(json_fd) # type: ignore[attr-defined] 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.""" - + def create_worker_runtests(self, test_name: TestName, json_file: JsonFile) -> WorkerRunTests: tests = (test_name,) if self.runtests.rerun: match_tests = self.runtests.get_match_tests(test_name) else: match_tests = None - kwargs = {} + kwargs: dict[str, Any] = {} if match_tests: - kwargs['match_tests'] = match_tests - return self.runtests.copy( + kwargs['match_tests'] = [(test, True) for test in match_tests] + if self.runtests.output_on_failure: + kwargs['verbose'] = True + kwargs['output_on_failure'] = False + return self.runtests.create_worker_runtests( tests=tests, json_file=json_file, **kwargs) - def run_tmp_files(self, worker_runtests: RunTests, + def run_tmp_files(self, worker_runtests: WorkerRunTests, 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 + # run on WASI. WASI doesn't pass environment variables like TMPDIR to # worker processes. tmp_dir = tempfile.mkdtemp(prefix="test_python_") tmp_dir = os.path.abspath(tmp_dir) @@ -298,7 +301,9 @@ def read_stdout(self, stdout_file: TextIO) -> str: # gh-101634: Catch UnicodeDecodeError if stdout cannot be # decoded from encoding raise WorkerError(self.test_name, - f"Cannot read process stdout: {exc}", None) + 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]: @@ -317,10 +322,11 @@ def read_json(self, json_file: JsonFile, json_tmpfile: TextIO | None, # decoded from encoding err_msg = f"Failed to read worker process JSON: {exc}" raise WorkerError(self.test_name, err_msg, stdout, - state=State.MULTIPROCESSING_ERROR) + state=State.WORKER_BUG) if not worker_json: - raise WorkerError(self.test_name, "empty JSON", stdout) + raise WorkerError(self.test_name, "empty JSON", stdout, + state=State.WORKER_BUG) try: result = TestResult.from_json(worker_json) @@ -329,7 +335,7 @@ def read_json(self, json_file: JsonFile, json_tmpfile: TextIO | None, # decoded from encoding err_msg = f"Failed to parse worker process JSON: {exc}" raise WorkerError(self.test_name, err_msg, stdout, - state=State.MULTIPROCESSING_ERROR) + state=State.WORKER_BUG) return (result, stdout) @@ -339,15 +345,22 @@ def _runtest(self, test_name: TestName) -> MultiprocessResult: json_file, json_tmpfile = self.create_json_file(stack) worker_runtests = self.create_worker_runtests(test_name, json_file) + retcode: str | int | None 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, None, stdout, state=State.TIMEOUT) + raise WorkerError(self.test_name, stdout=stdout, + err_msg=None, + state=State.TIMEOUT) if retcode != 0: - raise WorkerError(self.test_name, f"Exit code {retcode}", stdout) + 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) @@ -527,7 +540,7 @@ def display_result(self, mp_result: MultiprocessResult) -> None: text = str(result) if mp_result.err_msg: - # MULTIPROCESSING_ERROR + # WORKER_BUG text += ' (%s)' % mp_result.err_msg elif (result.duration >= PROGRESS_MIN_TIME and not pgo): text += ' (%s)' % format_duration(result.duration) @@ -543,7 +556,7 @@ def _process_result(self, item: QueueOutput) -> TestResult: # Thread got an exception format_exc = item[1] print_warning(f"regrtest worker thread failed: {format_exc}") - result = TestResult("", state=State.MULTIPROCESSING_ERROR) + result = TestResult("", state=State.WORKER_BUG) self.results.accumulate_result(result, self.runtests) return result @@ -553,8 +566,16 @@ def _process_result(self, item: QueueOutput) -> TestResult: self.results.accumulate_result(result, self.runtests) self.display_result(mp_result) - if mp_result.worker_stdout: - print(mp_result.worker_stdout, flush=True) + # 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 diff --git a/Lib/test/libregrtest/runtests.py b/Lib/test/libregrtest/runtests.py index 4da312db4cb02e..edd72276320e41 100644 --- a/Lib/test/libregrtest/runtests.py +++ b/Lib/test/libregrtest/runtests.py @@ -8,7 +8,7 @@ from test import support from .utils import ( - StrPath, StrJSON, TestTuple, FilterTuple, FilterDict) + StrPath, StrJSON, TestTuple, TestFilter, FilterTuple, FilterDict) class JsonFileType: @@ -33,7 +33,8 @@ def configure_subprocess(self, popen_kwargs: dict) -> None: popen_kwargs['pass_fds'] = [self.file] case JsonFileType.WINDOWS_HANDLE: # Windows handle - startupinfo = subprocess.STARTUPINFO() + # We run mypy with `--platform=linux` so it complains about this: + startupinfo = subprocess.STARTUPINFO() # type: ignore[attr-defined] startupinfo.lpAttributeList = {"handle_list": [self.file]} popen_kwargs['startupinfo'] = startupinfo @@ -72,8 +73,7 @@ class RunTests: tests: TestTuple fail_fast: bool fail_env_changed: bool - match_tests: FilterTuple | None - ignore_tests: FilterTuple | None + match_tests: TestFilter match_tests_dict: FilterDict | None rerun: bool forever: bool @@ -86,19 +86,24 @@ class RunTests: hunt_refleak: HuntRefleak | None test_dir: StrPath | None use_junit: bool + coverage: 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 + random_seed: int | str - def copy(self, **override): + def copy(self, **override) -> 'RunTests': state = dataclasses.asdict(self) state.update(override) return RunTests(**state) + def create_worker_runtests(self, **override): + state = dataclasses.asdict(self) + state.update(override) + return WorkerRunTests(**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) @@ -119,13 +124,6 @@ def iter_tests(self): 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: # @@ -140,9 +138,21 @@ def json_file_use_stdout(self) -> bool: ) +@dataclasses.dataclass(slots=True, frozen=True) +class WorkerRunTests(RunTests): + json_file: JsonFile + + def as_json(self) -> StrJSON: + return json.dumps(self, cls=_EncodeRunTests) + + @staticmethod + def from_json(worker_json: StrJSON) -> 'WorkerRunTests': + return json.loads(worker_json, object_hook=_decode_runtests) + + class _EncodeRunTests(json.JSONEncoder): def default(self, o: Any) -> dict[str, Any]: - if isinstance(o, RunTests): + if isinstance(o, WorkerRunTests): result = dataclasses.asdict(o) result["__runtests__"] = True return result @@ -157,6 +167,6 @@ def _decode_runtests(data: dict[str, Any]) -> RunTests | dict[str, Any]: data['hunt_refleak'] = HuntRefleak(**data['hunt_refleak']) if data['json_file']: data['json_file'] = JsonFile(**data['json_file']) - return RunTests(**data) + return WorkerRunTests(**data) else: return data diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index f0d8d7ebaa2fdb..9e9741493e9a5b 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -8,6 +8,7 @@ from test import support from test.support.os_helper import TESTFN_UNDECODABLE, FS_NONASCII +from .filter import set_match_tests from .runtests import RunTests from .utils import ( setup_unraisable_hook, setup_threading_excepthook, fix_umask, @@ -92,11 +93,11 @@ def setup_tests(runtests: RunTests): support.PGO = runtests.pgo support.PGO_EXTENDED = runtests.pgo_extended - support.set_match_tests(runtests.match_tests, runtests.ignore_tests) + set_match_tests(runtests.match_tests) if runtests.use_junit: support.junit_xml_list = [] - from test.support.testresult import RegressionTestResult + from .testresult import RegressionTestResult RegressionTestResult.USE_XML = True else: support.junit_xml_list = None @@ -111,6 +112,8 @@ def setup_tests(runtests: RunTests): 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) @@ -121,10 +124,10 @@ def setup_tests(runtests: RunTests): support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, timeout) if runtests.hunt_refleak: - unittest.BaseTestSuite._cleanup = False + # private attribute that mypy doesn't know about: + unittest.BaseTestSuite._cleanup = False # type: ignore[attr-defined] if runtests.gc_threshold is not None: gc.set_threshold(runtests.gc_threshold) - if runtests.randomize: - random.seed(runtests.random_seed) + random.seed(runtests.random_seed) diff --git a/Lib/test/libregrtest/single.py b/Lib/test/libregrtest/single.py index 0304f858edf42c..235029d8620ff5 100644 --- a/Lib/test/libregrtest/single.py +++ b/Lib/test/libregrtest/single.py @@ -1,4 +1,3 @@ -import doctest import faulthandler import gc import importlib @@ -9,13 +8,14 @@ import unittest from test import support -from test.support import TestStats from test.support import threading_helper -from .result import State, TestResult +from .filter import match_test +from .result import State, TestResult, TestStats from .runtests import RunTests from .save_env import saved_test_environment from .setup import setup_tests +from .testresult import get_test_runner from .utils import ( TestName, clear_caches, remove_testfn, abs_module_name, print_warning) @@ -33,7 +33,47 @@ def run_unittest(test_mod): print(error, file=sys.stderr) if loader.errors: raise Exception("errors while loading tests") - return support.run_unittest(tests) + _filter_suite(tests, match_test) + return _run_suite(tests) + +def _filter_suite(suite, pred): + """Recursively filter test cases in a suite based on a predicate.""" + newtests = [] + for test in suite._tests: + if isinstance(test, unittest.TestSuite): + _filter_suite(test, pred) + newtests.append(test) + else: + if pred(test): + newtests.append(test) + suite._tests = newtests + +def _run_suite(suite): + """Run tests from a unittest.TestSuite-derived class.""" + runner = get_test_runner(sys.stdout, + verbosity=support.verbose, + capture_output=(support.junit_xml_list is not None)) + + result = runner.run(suite) + + if support.junit_xml_list is not None: + support.junit_xml_list.append(result.get_xml_element()) + + if not result.testsRun and not result.skipped and not result.errors: + raise support.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: + err = result.failures[0][1] + else: + err = "multiple errors occurred" + if not support.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 support.TestFailedWithDetails(err, errors, failures, stats=stats) + return result def regrtest_runner(result: TestResult, test_func, runtests: RunTests) -> None: @@ -58,14 +98,18 @@ def regrtest_runner(result: TestResult, test_func, runtests: RunTests) -> None: 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 + # Don't import doctest at top level since only few tests return + # a doctest.TestResult instance. + import doctest + if isinstance(test_result, doctest.TestResults): + stats = TestStats.from_doctest(test_result) + else: + print_warning(f"Unknown test result type: {type(test_result)}") + stats = None result.stats = stats @@ -78,10 +122,6 @@ 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"): @@ -193,11 +233,11 @@ def _runtest(result: TestResult, runtests: RunTests) -> None: 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: + if timeout is not None and threading_helper.can_start_thread: + use_timeout = True faulthandler.dump_traceback_later(timeout, exit=True) + else: + use_timeout = False try: setup_tests(runtests) diff --git a/Lib/test/support/testresult.py b/Lib/test/libregrtest/testresult.py similarity index 100% rename from Lib/test/support/testresult.py rename to Lib/test/libregrtest/testresult.py diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 46451152b8859f..26481e71221ade 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -5,19 +5,20 @@ 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 collections.abc import Callable, Iterable from test import support from test.support import os_helper from test.support import threading_helper -MS_WINDOWS = (sys.platform == 'win32') - # 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_' @@ -30,6 +31,19 @@ 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 @@ -38,6 +52,7 @@ TestList = list[TestName] # --match and --ignore options: list of patterns # ('*' joker character can be used) +TestFilter = list[tuple[TestName, bool]] FilterTuple = tuple[TestName, ...] FilterDict = dict[TestName, FilterTuple] @@ -275,8 +290,8 @@ def get_build_info(): build = [] # --disable-gil - if sysconfig.get_config_var('Py_NOGIL'): - build.append("nogil") + if sysconfig.get_config_var('Py_GIL_DISABLED'): + build.append("free_threading") if hasattr(sys, 'gettotalrefcount'): # --with-pydebug @@ -362,10 +377,19 @@ def get_temp_dir(tmp_dir: StrPath | None = None) -> StrPath: # Python out of the source tree, especially when the # source tree is read only. tmp_dir = sysconfig.get_config_var('srcdir') + if not tmp_dir: + raise RuntimeError( + "Could not determine the correct value for tmp_dir" + ) tmp_dir = os.path.join(tmp_dir, 'build') else: # WASI platform tmp_dir = sysconfig.get_config_var('projectbase') + if not tmp_dir: + raise RuntimeError( + "sysconfig.get_config_var('projectbase') " + f"unexpectedly returned {tmp_dir!r} on WASI" + ) tmp_dir = os.path.join(tmp_dir, 'build') # When get_temp_dir() is called in a worker process, @@ -522,7 +546,42 @@ def adjust_rlimit_nofile(): f"{new_fd_limit}: {err}.") -def display_header(use_resources: tuple[str, ...]): +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: Iterable[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), @@ -530,18 +589,45 @@ def display_header(use_resources: tuple[str, ...]): print("== Python build:", ' '.join(get_build_info())) print("== cwd:", os.getcwd()) - cpu_count = os.cpu_count() + cpu_count: object = os.cpu_count() if cpu_count: + # The function is new in Python 3.13; mypy doesn't know about it yet: + process_cpu_count = os.process_cpu_count() # type: ignore[attr-defined] + 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" + print("== encodings: locale=%s FS=%s" % (locale.getencoding(), sys.getfilesystemencoding())) - if use_resources: - print(f"== resources ({len(use_resources)}): " - f"{', '.join(sorted(use_resources))}") + text = format_resources(use_resources) + print(f"== {text}") else: - print("== resources: (all disabled, use -u option)") + 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. @@ -581,3 +667,24 @@ def cleanup_temp_dir(tmp_dir: StrPath): 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 index a9c8be0bb65d08..7a6d33d4499943 100644 --- a/Lib/test/libregrtest/worker.py +++ b/Lib/test/libregrtest/worker.py @@ -4,20 +4,20 @@ from typing import Any, NoReturn from test import support -from test.support import os_helper +from test.support import os_helper, Py_DEBUG from .setup import setup_process, setup_test_dir -from .runtests import RunTests, JsonFile, JsonFileType +from .runtests import WorkerRunTests, JsonFile, JsonFileType from .single import run_single_test from .utils import ( - StrPath, StrJSON, FilterTuple, + StrPath, StrJSON, TestFilter, 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, +def create_worker_process(runtests: WorkerRunTests, output_fd: int, tmp_dir: StrPath | None = None) -> subprocess.Popen: python_cmd = runtests.python_cmd worker_json = runtests.as_json() @@ -30,6 +30,8 @@ def create_worker_process(runtests: RunTests, output_fd: int, python_opts = [opt for opt in python_opts if opt != "-E"] else: executable = (sys.executable,) + if runtests.coverage: + python_opts.append("-Xpresite=test.cov") cmd = [*executable, *python_opts, '-u', # Unbuffered stdout and stderr '-m', 'test.libregrtest.worker', @@ -71,9 +73,9 @@ def create_worker_process(runtests: RunTests, output_fd: int, def worker_process(worker_json: StrJSON) -> NoReturn: - runtests = RunTests.from_json(worker_json) + runtests = WorkerRunTests.from_json(worker_json) test_name = runtests.tests[0] - match_tests: FilterTuple | None = runtests.match_tests + match_tests: TestFilter = runtests.match_tests json_file: JsonFile = runtests.json_file setup_test_dir(runtests.test_dir) @@ -81,12 +83,24 @@ def worker_process(worker_json: StrJSON) -> NoReturn: if runtests.rerun: if match_tests: - matching = "matching: " + ", ".join(match_tests) + matching = "matching: " + ", ".join(pattern for pattern, result in match_tests if result) 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 runtests.coverage: + if "test.cov" in sys.modules: # imported by -Xpresite= + result.covered_lines = list(sys.modules["test.cov"].coverage) + elif not Py_DEBUG: + print( + "Gathering coverage in worker processes requires --with-pydebug", + flush=True, + ) + else: + raise LookupError( + "`test.cov` not found in sys.modules but coverage wanted" + ) if json_file.file_type == JsonFileType.STDOUT: print() diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index ddb180ef5ef825..fd446c8145850c 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -3514,6 +3514,84 @@ def __init__(self): pass self.assertRaises(pickle.PicklingError, BadPickler().dump, 0) self.assertRaises(pickle.UnpicklingError, BadUnpickler().load) + def test_unpickler_bad_file(self): + # bpo-38384: Crash in _pickle if the read attribute raises an error. + def raises_oserror(self, *args, **kwargs): + raise OSError + @property + def bad_property(self): + 1/0 + + # File without read and readline + class F: + pass + self.assertRaises((AttributeError, TypeError), self.Unpickler, F()) + + # File without read + class F: + readline = raises_oserror + self.assertRaises((AttributeError, TypeError), self.Unpickler, F()) + + # File without readline + class F: + read = raises_oserror + self.assertRaises((AttributeError, TypeError), self.Unpickler, F()) + + # File with bad read + class F: + read = bad_property + readline = raises_oserror + self.assertRaises(ZeroDivisionError, self.Unpickler, F()) + + # File with bad readline + class F: + readline = bad_property + read = raises_oserror + self.assertRaises(ZeroDivisionError, self.Unpickler, F()) + + # File with bad readline, no read + class F: + readline = bad_property + self.assertRaises(ZeroDivisionError, self.Unpickler, F()) + + # File with bad read, no readline + class F: + read = bad_property + self.assertRaises((AttributeError, ZeroDivisionError), self.Unpickler, F()) + + # File with bad peek + class F: + peek = bad_property + read = raises_oserror + readline = raises_oserror + try: + self.Unpickler(F()) + except ZeroDivisionError: + pass + + # File with bad readinto + class F: + readinto = bad_property + read = raises_oserror + readline = raises_oserror + try: + self.Unpickler(F()) + except ZeroDivisionError: + pass + + def test_pickler_bad_file(self): + # File without write + class F: + pass + self.assertRaises(TypeError, self.Pickler, F()) + + # File with bad write + class F: + @property + def write(self): + 1/0 + self.assertRaises(ZeroDivisionError, self.Pickler, F()) + def check_dumps_loads_oob_buffers(self, dumps, loads): # No need to do the full gamut of tests here, just enough to # check that dumps() and loads() redirect their arguments diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 0e7528ef97c5f6..49e41ca6cdaf98 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -239,6 +239,7 @@ def format_attr(attr, value): 'getresgid', 'getresuid', 'getuid', + 'process_cpu_count', 'uname', ): call_func(info_add, 'os.%s' % func, os, func) @@ -516,7 +517,7 @@ def collect_sysconfig(info_add): 'PY_STDMODULE_CFLAGS', 'Py_DEBUG', 'Py_ENABLE_SHARED', - 'Py_NOGIL', + 'Py_GIL_DISABLED', 'SHELL', 'SOABI', 'abs_builddir', @@ -543,6 +544,7 @@ def collect_sysconfig(info_add): 'WITH_DOC_STRINGS', 'WITH_DTRACE', 'WITH_FREELISTS', + 'WITH_MIMALLOC', 'WITH_PYMALLOC', 'WITH_VALGRIND', ): @@ -729,6 +731,7 @@ def collect_support(info_add): return attributes = ( + 'MS_WINDOWS', 'has_fork_support', 'has_socket_support', 'has_strftime_extensions', diff --git a/Lib/test/regrtestdata/import_from_tests/test_regrtest_a.py b/Lib/test/regrtestdata/import_from_tests/test_regrtest_a.py new file mode 100644 index 00000000000000..9c3d0c7cf4bfaa --- /dev/null +++ b/Lib/test/regrtestdata/import_from_tests/test_regrtest_a.py @@ -0,0 +1,11 @@ +import sys +import unittest +import test_regrtest_b.util + +class Test(unittest.TestCase): + def test(self): + test_regrtest_b.util # does not fail + self.assertIn('test_regrtest_a', sys.modules) + self.assertIs(sys.modules['test_regrtest_b'], test_regrtest_b) + self.assertIs(sys.modules['test_regrtest_b.util'], test_regrtest_b.util) + self.assertNotIn('test_regrtest_c', sys.modules) diff --git a/Lib/test/regrtestdata/import_from_tests/test_regrtest_b/__init__.py b/Lib/test/regrtestdata/import_from_tests/test_regrtest_b/__init__.py new file mode 100644 index 00000000000000..3dfba253455ad2 --- /dev/null +++ b/Lib/test/regrtestdata/import_from_tests/test_regrtest_b/__init__.py @@ -0,0 +1,9 @@ +import sys +import unittest + +class Test(unittest.TestCase): + def test(self): + self.assertNotIn('test_regrtest_a', sys.modules) + self.assertIn('test_regrtest_b', sys.modules) + self.assertNotIn('test_regrtest_b.util', sys.modules) + self.assertNotIn('test_regrtest_c', sys.modules) diff --git a/Lib/test/regrtestdata/import_from_tests/test_regrtest_b/util.py b/Lib/test/regrtestdata/import_from_tests/test_regrtest_b/util.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/Lib/test/regrtestdata/import_from_tests/test_regrtest_c.py b/Lib/test/regrtestdata/import_from_tests/test_regrtest_c.py new file mode 100644 index 00000000000000..de80769118d709 --- /dev/null +++ b/Lib/test/regrtestdata/import_from_tests/test_regrtest_c.py @@ -0,0 +1,11 @@ +import sys +import unittest +import test_regrtest_b.util + +class Test(unittest.TestCase): + def test(self): + test_regrtest_b.util # does not fail + self.assertNotIn('test_regrtest_a', sys.modules) + self.assertIs(sys.modules['test_regrtest_b'], test_regrtest_b) + self.assertIs(sys.modules['test_regrtest_b.util'], test_regrtest_b.util) + self.assertIn('test_regrtest_c', sys.modules) 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 38d5012ba46c08..b605951320dc8b 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -6,7 +6,6 @@ import contextlib import dataclasses import functools -import getpass import _opcode import os import re @@ -19,8 +18,6 @@ import unittest import warnings -from .testresult import get_test_runner - __all__ = [ # globals @@ -34,7 +31,6 @@ "is_resource_enabled", "requires", "requires_freebsd_version", "requires_linux_version", "requires_mac_ver", "check_syntax_error", - "run_unittest", "run_doctest", "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "requires_zlib", @@ -46,7 +42,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", @@ -75,13 +71,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 @@ -392,6 +382,7 @@ def wrapper(*args, **kw): def skip_if_buildbot(reason=None): """Decorator raising SkipTest if running on a buildbot.""" + import getpass if not reason: reason = 'not suitable for buildbots' try: @@ -435,6 +426,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.""" @@ -507,6 +510,8 @@ def has_no_debug_ranges(): def requires_debug_ranges(reason='requires co_positions / debug_ranges'): return unittest.skipIf(has_no_debug_ranges(), reason) +MS_WINDOWS = (sys.platform == 'win32') + # Is not actually used in tests, but is kept for compatibility. is_jython = sys.platform.startswith('java') @@ -791,7 +796,11 @@ def check_cflags_pgo(): return any(option in cflags_nodist for option in pgo_options) -_header = 'nP' +Py_GIL_DISABLED = bool(sysconfig.get_config_var('Py_GIL_DISABLED')) +if Py_GIL_DISABLED: + _header = 'PHBBInP' +else: + _header = 'nP' _align = '0n' _vheader = _header + 'n' @@ -1074,18 +1083,30 @@ def check_impl_detail(**guards): def no_tracing(func): """Decorator to temporarily turn off tracing for the duration of a test.""" - if not hasattr(sys, 'gettrace'): - return func - else: + trace_wrapper = func + if hasattr(sys, 'gettrace'): @functools.wraps(func) - def wrapper(*args, **kwargs): + def trace_wrapper(*args, **kwargs): original_trace = sys.gettrace() try: sys.settrace(None) return func(*args, **kwargs) finally: sys.settrace(original_trace) - return wrapper + + coverage_wrapper = trace_wrapper + if 'test.cov' in sys.modules: # -Xpresite=test.cov used + cov = sys.monitoring.COVERAGE_ID + @functools.wraps(func) + def coverage_wrapper(*args, **kwargs): + original_events = sys.monitoring.get_events(cov) + try: + sys.monitoring.set_events(cov, 0) + return trace_wrapper(*args, **kwargs) + finally: + sys.monitoring.set_events(cov, original_events) + + return coverage_wrapper def refcount_test(test): @@ -1110,176 +1131,6 @@ def requires_specialization(test): return unittest.skipUnless( _opcode.ENABLE_SPECIALIZATION, "requires specialization")(test) -def _filter_suite(suite, pred): - """Recursively filter test cases in a suite based on a predicate.""" - newtests = [] - for test in suite._tests: - if isinstance(test, unittest.TestSuite): - _filter_suite(test, pred) - newtests.append(test) - else: - if pred(test): - 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, - verbosity=verbose, - capture_output=(junit_xml_list is not None)) - - result = runner.run(suite) - - if junit_xml_list is not None: - junit_xml_list.append(result.get_xml_element()) - - 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: - err = result.failures[0][1] - else: - err = "multiple errors occurred" - 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, stats=stats) - return result - - -# By default, don't filter tests -_match_test_func = None - -_accept_test_patterns = None -_ignore_test_patterns = None - - -def match_test(test): - # Function used by support.run_unittest() and regrtest --list-cases - if _match_test_func is None: - return True - else: - return _match_test_func(test.id()) - - -def _is_full_match_test(pattern): - # If a pattern contains at least one dot, it's considered - # as a full test identifier. - # Example: 'test.test_os.FileTests.test_access'. - # - # ignore patterns which contain fnmatch patterns: '*', '?', '[...]' - # or '[!...]'. For example, ignore 'test_access*'. - return ('.' in pattern) and (not re.search(r'[?*\[\]]', 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: - ignore_patterns = () - - accept_func = ignore_func = None - - if accept_patterns != _accept_test_patterns: - accept_patterns, accept_func = _compile_match_function(accept_patterns) - if ignore_patterns != _ignore_test_patterns: - ignore_patterns, ignore_func = _compile_match_function(ignore_patterns) - - # Create a copy since patterns can be mutable and so modified later - _accept_test_patterns = tuple(accept_patterns) - _ignore_test_patterns = tuple(ignore_patterns) - - if accept_func is not None or ignore_func is not None: - def match_function(test_id): - accept = True - ignore = False - if accept_func: - accept = accept_func(test_id) - if ignore_func: - ignore = ignore_func(test_id) - return accept and not ignore - - _match_test_func = match_function - - -def _compile_match_function(patterns): - if not patterns: - func = None - # set_match_tests(None) behaves as set_match_tests(()) - patterns = () - elif all(map(_is_full_match_test, patterns)): - # Simple case: all patterns are full test identifier. - # The test.bisect_cmd utility only uses such full test identifiers. - func = set(patterns).__contains__ - else: - import fnmatch - regex = '|'.join(map(fnmatch.translate, patterns)) - # The search *is* case sensitive on purpose: - # don't use flags=re.IGNORECASE - regex_match = re.compile(regex).match - - def match_test_regex(test_id): - if regex_match(test_id): - # The regex matches the whole identifier, for example - # 'test.test_os.FileTests.test_access'. - return True - else: - # Try to match parts of the test identifier. - # For example, split 'test.test_os.FileTests.test_access' - # into: 'test', 'test_os', 'FileTests' and 'test_access'. - return any(map(regex_match, test_id.split("."))) - - func = match_test_regex - - return patterns, func - - -def run_unittest(*classes): - """Run tests from unittest.TestCase-derived classes.""" - valid_types = (unittest.TestSuite, unittest.TestCase) - loader = unittest.TestLoader() - suite = unittest.TestSuite() - for cls in classes: - if isinstance(cls, str): - if cls in sys.modules: - suite.addTest(loader.loadTestsFromModule(sys.modules[cls])) - else: - raise ValueError("str arguments must be keys in sys.modules") - elif isinstance(cls, valid_types): - suite.addTest(cls) - else: - suite.addTest(loader.loadTestsFromTestCase(cls)) - _filter_suite(suite, match_test) - return _run_suite(suite) #======================================================================= # Check for the presence of docstrings. @@ -1301,38 +1152,6 @@ def _check_docstrings(): "test requires docstrings") -#======================================================================= -# doctest driver. - -def run_doctest(module, verbosity=None, optionflags=0): - """Run doctest on the given module. Return (#failures, #tests). - - If optional argument verbosity is not specified (or is None), pass - support's belief about verbosity on to doctest. Else doctest's - usual behavior is used (it searches sys.argv for -v). - """ - - import doctest - - if verbosity is None: - verbosity = verbose - else: - verbosity = None - - 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__, results.attempted)) - return results - - #======================================================================= # Support for saving and restoring the imported modules. @@ -2025,7 +1844,12 @@ def restore(self): def with_pymalloc(): import _testcapi - return _testcapi.WITH_PYMALLOC + return _testcapi.WITH_PYMALLOC and not Py_GIL_DISABLED + + +def with_mimalloc(): + import _testcapi + return _testcapi.WITH_MIMALLOC class _ALWAYS_EQ: @@ -2297,13 +2121,21 @@ def set_recursion_limit(limit): finally: sys.setrecursionlimit(original_limit) -def infinite_recursion(max_depth=100): +def infinite_recursion(max_depth=None): """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.""" - if max_depth < 3: + if max_depth is None: + if not python_is_optimized() or Py_DEBUG: + # Python built without compiler optimizations or in debug mode + # usually consumes more stack memory per function call. + # Unoptimized number based on what works under a WASI debug build. + max_depth = 50 + else: + max_depth = 100 + elif 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. @@ -2544,8 +2376,16 @@ 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 +def _get_c_recursion_limit(): + try: + import _testcapi + return _testcapi.Py_C_RECURSION_LIMIT + except (ImportError, AttributeError): + # Originally taken from Include/cpython/pystate.h . + return 1500 + +# The default C recursion limit. +Py_C_RECURSION_LIMIT = _get_c_recursion_limit() #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', diff --git a/Lib/test/support/bytecode_helper.py b/Lib/test/support/bytecode_helper.py index 388d1266773c8a..a4845065a5322e 100644 --- a/Lib/test/support/bytecode_helper.py +++ b/Lib/test/support/bytecode_helper.py @@ -7,6 +7,18 @@ _UNSPECIFIED = object() +def instructions_with_positions(instrs, co_positions): + # Return (instr, positions) pairs from the instrs list and co_positions + # iterator. The latter contains items for cache lines and the former + # doesn't, so those need to be skipped. + + co_positions = co_positions or iter(()) + for instr in instrs: + yield instr, next(co_positions, ()) + for _, size, _ in (instr.cache_info or ()): + for i in range(size): + next(co_positions, ()) + class BytecodeTestCase(unittest.TestCase): """Custom assertion methods for inspecting bytecode.""" diff --git a/Lib/test/support/interpreters.py b/Lib/test/support/interpreters.py deleted file mode 100644 index eeff3abe0324e5..00000000000000 --- a/Lib/test/support/interpreters.py +++ /dev/null @@ -1,198 +0,0 @@ -"""Subinterpreters High Level Module.""" - -import time -import _xxsubinterpreters as _interpreters -import _xxinterpchannels as _channels - -# aliases: -from _xxsubinterpreters import is_shareable -from _xxinterpchannels import ( - ChannelError, ChannelNotFoundError, ChannelEmptyError, -) - - -__all__ = [ - 'Interpreter', 'get_current', 'get_main', 'create', 'list_all', - 'SendChannel', 'RecvChannel', - 'create_channel', 'list_all_channels', 'is_shareable', - 'ChannelError', 'ChannelNotFoundError', - 'ChannelEmptyError', - ] - - -def create(*, isolated=True): - """Return a new (idle) Python interpreter.""" - id = _interpreters.create(isolated=isolated) - return Interpreter(id, isolated=isolated) - - -def list_all(): - """Return all existing interpreters.""" - return [Interpreter(id) for id in _interpreters.list_all()] - - -def get_current(): - """Return the currently running interpreter.""" - id = _interpreters.get_current() - return Interpreter(id) - - -def get_main(): - """Return the main interpreter.""" - id = _interpreters.get_main() - return Interpreter(id) - - -class Interpreter: - """A single Python interpreter.""" - - def __init__(self, id, *, isolated=None): - if not isinstance(id, (int, _interpreters.InterpreterID)): - raise TypeError(f'id must be an int, got {id!r}') - self._id = id - self._isolated = isolated - - def __repr__(self): - data = dict(id=int(self._id), isolated=self._isolated) - kwargs = (f'{k}={v!r}' for k, v in data.items()) - return f'{type(self).__name__}({", ".join(kwargs)})' - - def __hash__(self): - return hash(self._id) - - def __eq__(self, other): - if not isinstance(other, Interpreter): - return NotImplemented - else: - return other._id == self._id - - @property - def id(self): - return self._id - - @property - def isolated(self): - if self._isolated is None: - # XXX The low-level function has not been added yet. - # See bpo-.... - self._isolated = _interpreters.is_isolated(self._id) - return self._isolated - - def is_running(self): - """Return whether or not the identified interpreter is running.""" - return _interpreters.is_running(self._id) - - def close(self): - """Finalize and destroy the interpreter. - - Attempting to destroy the current interpreter results - in a RuntimeError. - """ - return _interpreters.destroy(self._id) - - def run(self, src_str, /, *, channels=None): - """Run the given source code in the interpreter. - - This blocks the current Python thread until done. - """ - _interpreters.run_string(self._id, src_str, channels) - - -def create_channel(): - """Return (recv, send) for a new cross-interpreter channel. - - The channel may be used to pass data safely between interpreters. - """ - cid = _channels.create() - recv, send = RecvChannel(cid), SendChannel(cid) - return recv, send - - -def list_all_channels(): - """Return a list of (recv, send) for all open channels.""" - return [(RecvChannel(cid), SendChannel(cid)) - for cid in _channels.list_all()] - - -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 - - def __repr__(self): - return f'{type(self).__name__}(id={int(self._id)})' - - def __hash__(self): - return hash(self._id) - - def __eq__(self, other): - if isinstance(self, RecvChannel): - if not isinstance(other, RecvChannel): - return NotImplemented - elif not isinstance(other, SendChannel): - return NotImplemented - return other._id == self._id - - @property - def id(self): - return self._id - - -_NOT_SET = object() - - -class RecvChannel(_ChannelEnd): - """The receiving end of a cross-interpreter channel.""" - - def recv(self, *, _sentinel=object(), _delay=10 / 1000): # 10 milliseconds - """Return the next object from the channel. - - This blocks until an object has been sent, if none have been - sent already. - """ - obj = _channels.recv(self._id, _sentinel) - while obj is _sentinel: - time.sleep(_delay) - obj = _channels.recv(self._id, _sentinel) - return obj - - def recv_nowait(self, default=_NOT_SET): - """Return the next object from the channel. - - If none have been sent then return the default if one - is provided or fail with ChannelEmptyError. Otherwise this - is the same as recv(). - """ - if default is _NOT_SET: - return _channels.recv(self._id) - else: - return _channels.recv(self._id, default) - - -class SendChannel(_ChannelEnd): - """The sending end of a cross-interpreter channel.""" - - 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) - - def send_nowait(self, obj): - """Send the object to the channel's receiving end. - - If the object is immediately received then return True - (else False). Otherwise this is the same as send(). - """ - # 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) diff --git a/Lib/test/support/interpreters/__init__.py b/Lib/test/support/interpreters/__init__.py new file mode 100644 index 00000000000000..15a908e9663593 --- /dev/null +++ b/Lib/test/support/interpreters/__init__.py @@ -0,0 +1,187 @@ +"""Subinterpreters High Level Module.""" + +import threading +import weakref +import _xxsubinterpreters as _interpreters + +# aliases: +from _xxsubinterpreters import ( + InterpreterError, InterpreterNotFoundError, + is_shareable, +) + + +__all__ = [ + 'get_current', 'get_main', 'create', 'list_all', 'is_shareable', + 'Interpreter', + 'InterpreterError', 'InterpreterNotFoundError', 'ExecFailure', + 'create_queue', 'Queue', 'QueueEmpty', 'QueueFull', +] + + +_queuemod = None + +def __getattr__(name): + if name in ('Queue', 'QueueEmpty', 'QueueFull', 'create_queue'): + global create_queue, Queue, QueueEmpty, QueueFull + ns = globals() + from .queues import ( + create as create_queue, + Queue, QueueEmpty, QueueFull, + ) + return ns[name] + else: + raise AttributeError(name) + + +_EXEC_FAILURE_STR = """ +{superstr} + +Uncaught in the interpreter: + +{formatted} +""".strip() + +class ExecFailure(RuntimeError): + + def __init__(self, excinfo): + msg = excinfo.formatted + if not msg: + if excinfo.type and excinfo.msg: + msg = f'{excinfo.type.__name__}: {excinfo.msg}' + else: + msg = excinfo.type.__name__ or excinfo.msg + super().__init__(msg) + self.excinfo = excinfo + + def __str__(self): + try: + formatted = self.excinfo.errdisplay + except Exception: + return super().__str__() + else: + return _EXEC_FAILURE_STR.format( + superstr=super().__str__(), + formatted=formatted, + ) + + +def create(): + """Return a new (idle) Python interpreter.""" + id = _interpreters.create(isolated=True) + return Interpreter(id) + + +def list_all(): + """Return all existing interpreters.""" + return [Interpreter(id) for id in _interpreters.list_all()] + + +def get_current(): + """Return the currently running interpreter.""" + id = _interpreters.get_current() + return Interpreter(id) + + +def get_main(): + """Return the main interpreter.""" + id = _interpreters.get_main() + return Interpreter(id) + + +_known = weakref.WeakValueDictionary() + +class Interpreter: + """A single Python interpreter.""" + + def __new__(cls, id, /): + # There is only one instance for any given ID. + if not isinstance(id, int): + raise TypeError(f'id must be an int, got {id!r}') + id = int(id) + try: + self = _known[id] + assert hasattr(self, '_ownsref') + except KeyError: + # This may raise InterpreterNotFoundError: + _interpreters._incref(id) + try: + self = super().__new__(cls) + self._id = id + self._ownsref = True + except BaseException: + _interpreters._deccref(id) + raise + _known[id] = self + return self + + def __repr__(self): + return f'{type(self).__name__}({self.id})' + + def __hash__(self): + return hash(self._id) + + def __del__(self): + self._decref() + + def _decref(self): + if not self._ownsref: + return + self._ownsref = False + try: + _interpreters._decref(self.id) + except InterpreterNotFoundError: + pass + + @property + def id(self): + return self._id + + def is_running(self): + """Return whether or not the identified interpreter is running.""" + return _interpreters.is_running(self._id) + + def close(self): + """Finalize and destroy the interpreter. + + Attempting to destroy the current interpreter results + in a RuntimeError. + """ + return _interpreters.destroy(self._id) + + def prepare_main(self, ns=None, /, **kwargs): + """Bind the given values into the interpreter's __main__. + + The values must be shareable. + """ + ns = dict(ns, **kwargs) if ns is not None else kwargs + _interpreters.set___main___attrs(self._id, ns) + + def exec_sync(self, code, /): + """Run the given source code in the interpreter. + + 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 an ExecFailure + 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. + """ + excinfo = _interpreters.exec(self._id, code) + if excinfo is not None: + raise ExecFailure(excinfo) + + def run(self, code, /): + def task(): + self.exec_sync(code) + t = threading.Thread(target=task) + t.start() + return t diff --git a/Lib/test/support/interpreters/channels.py b/Lib/test/support/interpreters/channels.py new file mode 100644 index 00000000000000..75a5a60f54f926 --- /dev/null +++ b/Lib/test/support/interpreters/channels.py @@ -0,0 +1,171 @@ +"""Cross-interpreter Channels High Level Module.""" + +import time +import _xxinterpchannels as _channels + +# aliases: +from _xxinterpchannels import ( + ChannelError, ChannelNotFoundError, ChannelClosedError, + ChannelEmptyError, ChannelNotEmptyError, +) + + +__all__ = [ + 'create', 'list_all', + 'SendChannel', 'RecvChannel', + 'ChannelError', 'ChannelNotFoundError', 'ChannelEmptyError', +] + + +def create(): + """Return (recv, send) for a new cross-interpreter channel. + + The channel may be used to pass data safely between interpreters. + """ + cid = _channels.create() + recv, send = RecvChannel(cid), SendChannel(cid) + return recv, send + + +def list_all(): + """Return a list of (recv, send) for all open channels.""" + return [(RecvChannel(cid), SendChannel(cid)) + for cid in _channels.list_all()] + + +class _ChannelEnd: + """The base class for RecvChannel and SendChannel.""" + + _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)})' + + def __hash__(self): + return hash(self._id) + + def __eq__(self, other): + if isinstance(self, RecvChannel): + if not isinstance(other, RecvChannel): + return NotImplemented + elif not isinstance(other, SendChannel): + return NotImplemented + return other._id == self._id + + @property + def id(self): + return self._id + + @property + def _info(self): + return _channels.get_info(self._id) + + @property + def is_closed(self): + return self._info.closed + + +_NOT_SET = object() + + +class RecvChannel(_ChannelEnd): + """The receiving end of a cross-interpreter channel.""" + + _end = 'recv' + + def recv(self, timeout=None, *, + _sentinel=object(), + _delay=10 / 1000, # 10 milliseconds + ): + """Return the next object from the channel. + + This blocks until an object has been sent, if none have been + sent already. + """ + if timeout is not None: + timeout = int(timeout) + if timeout < 0: + raise ValueError(f'timeout value must be non-negative') + end = time.time() + timeout + obj = _channels.recv(self._id, _sentinel) + while obj is _sentinel: + time.sleep(_delay) + if timeout is not None and time.time() >= end: + raise TimeoutError + obj = _channels.recv(self._id, _sentinel) + return obj + + def recv_nowait(self, default=_NOT_SET): + """Return the next object from the channel. + + If none have been sent then return the default if one + is provided or fail with ChannelEmptyError. Otherwise this + is the same as recv(). + """ + if default is _NOT_SET: + return _channels.recv(self._id) + 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' + + @property + def is_closed(self): + info = self._info + return info.closed or info.closing + + def send(self, obj, timeout=None): + """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, timeout=timeout, blocking=True) + + def send_nowait(self, obj): + """Send the object to the channel's receiving end. + + If the object is immediately received then return True + (else False). Otherwise this is the same as send(). + """ + # 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, blocking=False) + + def send_buffer(self, obj, timeout=None): + """Send the object's buffer to the channel's receiving end. + + This blocks until the object is received. + """ + _channels.send_buffer(self._id, obj, timeout=timeout, 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/interpreters/queues.py b/Lib/test/support/interpreters/queues.py new file mode 100644 index 00000000000000..aead0c40ca9667 --- /dev/null +++ b/Lib/test/support/interpreters/queues.py @@ -0,0 +1,172 @@ +"""Cross-interpreter Queues High Level Module.""" + +import queue +import time +import weakref +import _xxinterpqueues as _queues + +# aliases: +from _xxinterpqueues import ( + QueueError, QueueNotFoundError, +) + +__all__ = [ + 'create', 'list_all', + 'Queue', + 'QueueError', 'QueueNotFoundError', 'QueueEmpty', 'QueueFull', +] + + +class QueueEmpty(_queues.QueueEmpty, queue.Empty): + """Raised from get_nowait() when the queue is empty. + + It is also raised from get() if it times out. + """ + + +class QueueFull(_queues.QueueFull, queue.Full): + """Raised from put_nowait() when the queue is full. + + It is also raised from put() if it times out. + """ + + +def create(maxsize=0): + """Return a new cross-interpreter queue. + + The queue may be used to pass data safely between interpreters. + """ + qid = _queues.create(maxsize) + return Queue(qid) + + +def list_all(): + """Return a list of all open queues.""" + return [Queue(qid) + for qid in _queues.list_all()] + + + +_known_queues = weakref.WeakValueDictionary() + +class Queue: + """A cross-interpreter queue.""" + + def __new__(cls, id, /): + # There is only one instance for any given ID. + if isinstance(id, int): + id = int(id) + else: + raise TypeError(f'id must be an int, got {id!r}') + try: + self = _known_queues[id] + except KeyError: + self = super().__new__(cls) + self._id = id + _known_queues[id] = self + _queues.bind(id) + return self + + def __del__(self): + try: + _queues.release(self._id) + except QueueNotFoundError: + pass + try: + del _known_queues[self._id] + except KeyError: + pass + + def __repr__(self): + return f'{type(self).__name__}({self.id})' + + def __hash__(self): + return hash(self._id) + + @property + def id(self): + return self._id + + @property + def maxsize(self): + try: + return self._maxsize + except AttributeError: + self._maxsize = _queues.get_maxsize(self._id) + return self._maxsize + + def empty(self): + return self.qsize() == 0 + + def full(self): + return _queues.is_full(self._id) + + def qsize(self): + return _queues.get_count(self._id) + + def put(self, obj, timeout=None, *, + _delay=10 / 1000, # 10 milliseconds + ): + """Add the object to the queue. + + This blocks while the queue is full. + """ + if timeout is not None: + timeout = int(timeout) + if timeout < 0: + raise ValueError(f'timeout value must be non-negative') + end = time.time() + timeout + while True: + try: + _queues.put(self._id, obj) + except _queues.QueueFull as exc: + if timeout is not None and time.time() >= end: + exc.__class__ = QueueFull + raise # re-raise + time.sleep(_delay) + else: + break + + def put_nowait(self, obj): + try: + return _queues.put(self._id, obj) + except _queues.QueueFull as exc: + exc.__class__ = QueueFull + raise # re-raise + + def get(self, timeout=None, *, + _delay=10 / 1000, # 10 milliseconds + ): + """Return the next object from the queue. + + This blocks while the queue is empty. + """ + if timeout is not None: + timeout = int(timeout) + if timeout < 0: + raise ValueError(f'timeout value must be non-negative') + end = time.time() + timeout + while True: + try: + return _queues.get(self._id) + except _queues.QueueEmpty as exc: + if timeout is not None and time.time() >= end: + exc.__class__ = QueueEmpty + raise # re-raise + time.sleep(_delay) + return obj + + def get_nowait(self): + """Return the next object from the channel. + + If the queue is empty then raise QueueEmpty. Otherwise this + is the same as get(). + """ + try: + return _queues.get(self._id) + except _queues.QueueEmpty as exc: + exc.__class__ = QueueEmpty + raise # re-raise + + +_queues._register_queue_type(Queue) diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py index 821a4b1ffd5077..7a67d87fb9e846 100644 --- a/Lib/test/support/os_helper.py +++ b/Lib/test/support/os_helper.py @@ -10,6 +10,8 @@ import unittest import warnings +from test import support + # Filename used for testing TESTFN_ASCII = '@test' @@ -590,10 +592,17 @@ def fd_count(): """Count the number of open file descriptors. """ if sys.platform.startswith(('linux', 'freebsd', 'emscripten')): + fd_path = "/proc/self/fd" + elif sys.platform == "darwin": + fd_path = "/dev/fd" + else: + fd_path = None + + if fd_path is not None: try: - names = os.listdir("/proc/self/fd") + names = os.listdir(fd_path) # Subtract one because listdir() internally opens a file - # descriptor to list the content of the /proc/self/fd/ directory. + # descriptor to list the content of the directory. return len(names) - 1 except FileNotFoundError: pass @@ -720,13 +729,16 @@ def __exit__(self, *ignore_exc): try: - import ctypes - kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) - - ERROR_FILE_NOT_FOUND = 2 - DDD_REMOVE_DEFINITION = 2 - DDD_EXACT_MATCH_ON_REMOVE = 4 - DDD_NO_BROADCAST_SYSTEM = 8 + if support.MS_WINDOWS: + import ctypes + kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) + + ERROR_FILE_NOT_FOUND = 2 + DDD_REMOVE_DEFINITION = 2 + DDD_EXACT_MATCH_ON_REMOVE = 4 + DDD_NO_BROADCAST_SYSTEM = 8 + else: + raise AttributeError except (ImportError, AttributeError): def subst_drive(path): raise unittest.SkipTest('ctypes or kernel32 is not available') diff --git a/Lib/test/support/pty_helper.py b/Lib/test/support/pty_helper.py new file mode 100644 index 00000000000000..11037d22516448 --- /dev/null +++ b/Lib/test/support/pty_helper.py @@ -0,0 +1,60 @@ +""" +Helper to run a script in a pseudo-terminal. +""" +import os +import selectors +import subprocess +import sys +from contextlib import ExitStack +from errno import EIO + +from test.support.import_helper import import_module + +def run_pty(script, input=b"dummy input\r", env=None): + pty = import_module('pty') + output = bytearray() + [master, slave] = pty.openpty() + args = (sys.executable, '-c', script) + proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env) + os.close(slave) + with ExitStack() as cleanup: + cleanup.enter_context(proc) + def terminate(proc): + try: + proc.terminate() + except ProcessLookupError: + # Workaround for Open/Net BSD bug (Issue 16762) + pass + cleanup.callback(terminate, proc) + cleanup.callback(os.close, master) + # Avoid using DefaultSelector and PollSelector. Kqueue() does not + # work with pseudo-terminals on OS X < 10.9 (Issue 20365) and Open + # BSD (Issue 20667). Poll() does not work with OS X 10.6 or 10.4 + # either (Issue 20472). Hopefully the file descriptor is low enough + # to use with select(). + sel = cleanup.enter_context(selectors.SelectSelector()) + sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE) + os.set_blocking(master, False) + while True: + for [_, events] in sel.select(): + if events & selectors.EVENT_READ: + try: + chunk = os.read(master, 0x10000) + except OSError as err: + # Linux raises EIO when slave is closed (Issue 5380) + if err.errno != EIO: + raise + chunk = b"" + if not chunk: + return output + output.extend(chunk) + if events & selectors.EVENT_WRITE: + try: + input = input[os.write(master, input):] + except OSError as err: + # Apparently EIO means the slave was closed + if err.errno != EIO: + raise + input = b"" # Stop writing + if not input: + sel.modify(master, selectors.EVENT_READ) diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py index c2b43f4060eb55..759020c33aa700 100644 --- a/Lib/test/support/script_helper.py +++ b/Lib/test/support/script_helper.py @@ -8,7 +8,6 @@ import os.path import subprocess import py_compile -import zipfile from importlib.util import source_from_cache from test import support @@ -93,13 +92,28 @@ def fail(self, cmd_line): # Executing the interpreter in a subprocess @support.requires_subprocess() def run_python_until_end(*args, **env_vars): + """Used to implement assert_python_*. + + *args are the command line flags to pass to the python interpreter. + **env_vars keyword arguments are environment variables to set on the process. + + If __run_using_command= is supplied, it must be a list of + command line arguments to prepend to the command line used. + Useful when you want to run another command that should launch the + python interpreter via its own arguments. ["/bin/echo", "--"] for + example could print the unquoted python command line instead of + run it. + """ env_required = interpreter_requires_environment() + run_using_command = env_vars.pop('__run_using_command', None) cwd = env_vars.pop('__cwd', None) if '__isolated' in env_vars: isolated = env_vars.pop('__isolated') else: isolated = not env_vars and not env_required cmd_line = [sys.executable, '-X', 'faulthandler'] + if run_using_command: + cmd_line = run_using_command + cmd_line if isolated: # isolated mode: ignore Python environment variables, ignore user # site-packages, and don't add the current directory to sys.path @@ -226,6 +240,7 @@ def make_script(script_dir, script_basename, source, omit_suffix=False): def make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None): + import zipfile zip_filename = zip_basename+os.extsep+'zip' zip_name = os.path.join(zip_dir, zip_filename) with zipfile.ZipFile(zip_name, 'w') as zip_file: @@ -252,6 +267,7 @@ def make_pkg(pkg_dir, init_source=''): def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source, depth=1, compiled=False): + import zipfile unlink = [] init_name = make_script(zip_dir, '__init__', '') unlink.append(init_name) diff --git a/Lib/test/support/threading_helper.py b/Lib/test/support/threading_helper.py index 7f16050f32b9d1..afa25a76f63829 100644 --- a/Lib/test/support/threading_helper.py +++ b/Lib/test/support/threading_helper.py @@ -22,34 +22,37 @@ def threading_setup(): - return _thread._count(), threading._dangling.copy() + return _thread._count(), len(threading._dangling) def threading_cleanup(*original_values): - _MAX_COUNT = 100 - - for count in range(_MAX_COUNT): - values = _thread._count(), threading._dangling - if values == original_values: - break - - if not count: - # Display a warning at the first iteration - support.environment_altered = True - dangling_threads = values[1] - support.print_warning(f"threading_cleanup() failed to cleanup " - f"{values[0] - original_values[0]} threads " - f"(count: {values[0]}, " - f"dangling: {len(dangling_threads)})") - for thread in dangling_threads: - support.print_warning(f"Dangling thread: {thread!r}") - - # Don't hold references to threads - dangling_threads = None - values = None - - time.sleep(0.01) - support.gc_collect() + orig_count, orig_ndangling = original_values + + timeout = 1.0 + for _ in support.sleeping_retry(timeout, error=False): + # Copy the thread list to get a consistent output. threading._dangling + # is a WeakSet, its value changes when it's read. + dangling_threads = list(threading._dangling) + count = _thread._count() + + if count <= orig_count: + return + + # Timeout! + support.environment_altered = True + support.print_warning( + f"threading_cleanup() failed to clean up threads " + f"in {timeout:.1f} seconds\n" + f" before: thread count={orig_count}, dangling={orig_ndangling}\n" + f" after: thread count={count}, dangling={len(dangling_threads)}") + for thread in dangling_threads: + support.print_warning(f"Dangling thread: {thread!r}") + + # The warning happens when a test spawns threads and some of these threads + # are still running after the test completes. To fix this warning, join + # threads explicitly to wait until they complete. + # + # To make the warning more likely, reduce the timeout. def reap_threads(func): diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index c1f612dc4a63cb..10f04b64dda40e 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -8,6 +8,14 @@ class OpListTests(unittest.TestCase): + def check_bool_function_result(self, func, ops, expected): + for op in ops: + if isinstance(op, str): + op = dis.opmap[op] + with self.subTest(opcode=op, func=func): + self.assertIsInstance(func(op), bool) + self.assertEqual(func(op), expected) + def test_invalid_opcodes(self): invalid = [-100, -1, 255, 512, 513, 1000] self.check_bool_function_result(_opcode.is_valid, invalid, False) @@ -47,7 +55,7 @@ def check_function(self, func, expected): check_function(self, _opcode.has_exc, dis.hasexc) -class OpListTests(unittest.TestCase): +class StackEffectTests(unittest.TestCase): def test_stack_effect(self): self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1) self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 0), -1) diff --git a/Lib/test/test__xxinterpchannels.py b/Lib/test/test__xxinterpchannels.py index 750cd99b85e7a6..cc2ed7849b0c0f 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(): @@ -72,8 +79,7 @@ def __new__(cls, name=None, id=None): name = 'interp' elif name == 'main': raise ValueError('name mismatch (unexpected "main")') - if not isinstance(id, interpreters.InterpreterID): - id = interpreters.InterpreterID(id) + assert isinstance(id, int), repr(id) elif not name or name == 'main': name = 'main' id = main @@ -189,7 +195,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 +338,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 +396,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 +422,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 +445,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 +471,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 +512,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 +534,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) @@ -557,12 +563,67 @@ def test_channel_list_interpreters_closed_send_end(self): with self.assertRaises(channels.ChannelClosedError): channels.list_interpreters(cid, send=False) - #################### + def test_allowed_types(self): + cid = channels.create() + objects = [ + None, + 'spam', + b'spam', + 42, + ] + for obj in objects: + with self.subTest(obj): + channels.send(cid, obj, blocking=False) + got = channels.recv(cid) + + self.assertEqual(got, obj) + self.assertIs(type(got), type(obj)) + # XXX Check the following? + #self.assertIsNot(got, obj) + # XXX What about between interpreters? + + def test_run_string_arg_unresolved(self): + cid = channels.create() + interp = interpreters.create() + + interpreters.set___main___attrs(interp, dict(cid=cid.send)) + out = _run_output(interp, dedent(""" + import _xxinterpchannels as _channels + print(cid.end) + _channels.send(cid, b'spam', blocking=False) + """)) + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + self.assertEqual(out.strip(), 'send') + + # XXX For now there is no high-level channel into which the + # sent channel ID can be converted... + # Note: this test caused crashes on some buildbots (bpo-33615). + @unittest.skip('disabled until high-level channels exist') + def test_run_string_arg_resolved(self): + cid = channels.create() + cid = channels._channel_id(cid, _resolve=True) + interp = interpreters.create() + + out = _run_output(interp, dedent(""" + import _xxinterpchannels as _channels + print(chan.id.end) + _channels.send(chan.id, b'spam', blocking=False) + """), + dict(chan=cid.send)) + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + self.assertEqual(out.strip(), 'send') + + #------------------- + # send/recv 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 +635,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 +646,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 +656,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 +690,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 +712,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 +735,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 +748,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,65 +759,242 @@ def test_recv_sending_interp_destroyed(self): channels.recv(cid2) del cid2 - def test_allowed_types(self): + #------------------- + # send_buffer + + def test_send_buffer(self): + buf = bytearray(b'spamspamspam') cid = channels.create() - objects = [ - None, - 'spam', - b'spam', - 42, - ] - for obj in objects: - with self.subTest(obj): - channels.send(cid, obj) - got = channels.recv(cid) + channels.send_buffer(cid, buf, blocking=False) + obj = channels.recv(cid) - self.assertEqual(got, obj) - self.assertIs(type(got), type(obj)) - # XXX Check the following? - #self.assertIsNot(got, obj) - # XXX What about between interpreters? + 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) + + #------------------- + # send with waiting + + def build_send_waiter(self, obj, *, buffer=False): + # We want a long enough sleep that send() actually has to wait. + + if buffer: + send = channels.send_buffer + else: + send = channels.send - def test_run_string_arg_unresolved(self): cid = channels.create() - interp = interpreters.create() + try: + started = time.monotonic() + send(cid, obj, blocking=False) + stopped = time.monotonic() + channels.recv(cid) + finally: + channels.destroy(cid) + delay = stopped - started # seconds + delay *= 3 - out = _run_output(interp, dedent(""" - import _xxinterpchannels as _channels - print(cid.end) - _channels.send(cid, b'spam') - """), - dict(cid=cid.send)) - obj = channels.recv(cid) + def wait(): + time.sleep(delay) + return wait - self.assertEqual(obj, b'spam') - self.assertEqual(out.strip(), 'send') + def test_send_blocking_waiting(self): + received = None + obj = b'spam' + wait = self.build_send_waiter(obj) + cid = channels.create() + def f(): + nonlocal received + wait() + received = recv_wait(cid) + t = threading.Thread(target=f) + t.start() + channels.send(cid, obj, blocking=True) + t.join() - # XXX For now there is no high-level channel into which the - # sent channel ID can be converted... - # Note: this test caused crashes on some buildbots (bpo-33615). - @unittest.skip('disabled until high-level channels exist') - def test_run_string_arg_resolved(self): + self.assertEqual(received, obj) + + def test_send_buffer_blocking_waiting(self): + received = None + obj = bytearray(b'spam') + wait = self.build_send_waiter(obj, buffer=True) cid = channels.create() - cid = channels._channel_id(cid, _resolve=True) - interp = interpreters.create() + def f(): + nonlocal received + wait() + received = recv_wait(cid) + t = threading.Thread(target=f) + t.start() + channels.send_buffer(cid, obj, blocking=True) + t.join() - out = _run_output(interp, dedent(""" - import _xxinterpchannels as _channels - print(chan.id.end) - _channels.send(chan.id, b'spam') - """), - dict(chan=cid.send)) - obj = channels.recv(cid) + self.assertEqual(received, obj) - self.assertEqual(obj, b'spam') - self.assertEqual(out.strip(), 'send') + def test_send_blocking_no_wait(self): + received = None + obj = b'spam' + cid = channels.create() + def f(): + nonlocal received + received = recv_wait(cid) + t = threading.Thread(target=f) + t.start() + channels.send(cid, obj, blocking=True) + t.join() + + self.assertEqual(received, obj) + + def test_send_buffer_blocking_no_wait(self): + received = None + obj = bytearray(b'spam') + cid = channels.create() + def f(): + nonlocal received + received = recv_wait(cid) + t = threading.Thread(target=f) + t.start() + channels.send_buffer(cid, obj, blocking=True) + t.join() + + self.assertEqual(received, obj) + + def test_send_timeout(self): + obj = b'spam' + + with self.subTest('non-blocking with timeout'): + cid = channels.create() + with self.assertRaises(ValueError): + channels.send(cid, obj, blocking=False, timeout=0.1) + + with self.subTest('timeout hit'): + cid = channels.create() + with self.assertRaises(TimeoutError): + channels.send(cid, obj, blocking=True, timeout=0.1) + with self.assertRaises(channels.ChannelEmptyError): + received = channels.recv(cid) + print(repr(received)) + + with self.subTest('timeout not hit'): + cid = channels.create() + def f(): + recv_wait(cid) + t = threading.Thread(target=f) + t.start() + channels.send(cid, obj, blocking=True, timeout=10) + t.join() + + def test_send_buffer_timeout(self): + try: + self._has_run_once_timeout + except AttributeError: + # At the moment, this test leaks a few references. + # It looks like the leak originates with the addition + # of _channels.send_buffer() (gh-110246), whereas the + # tests were added afterward. We want this test even + # if the refleak isn't fixed yet, so we skip here. + raise unittest.SkipTest('temporarily skipped due to refleaks') + else: + self._has_run_once_timeout = True + + obj = bytearray(b'spam') + + with self.subTest('non-blocking with timeout'): + cid = channels.create() + with self.assertRaises(ValueError): + channels.send_buffer(cid, obj, blocking=False, timeout=0.1) + + with self.subTest('timeout hit'): + cid = channels.create() + with self.assertRaises(TimeoutError): + channels.send_buffer(cid, obj, blocking=True, timeout=0.1) + with self.assertRaises(channels.ChannelEmptyError): + received = channels.recv(cid) + print(repr(received)) + + with self.subTest('timeout not hit'): + cid = channels.create() + def f(): + recv_wait(cid) + t = threading.Thread(target=f) + t.start() + channels.send_buffer(cid, obj, blocking=True, timeout=10) + t.join() + + def test_send_closed_while_waiting(self): + obj = b'spam' + wait = self.build_send_waiter(obj) + + with self.subTest('without timeout'): + cid = channels.create() + def f(): + wait() + channels.close(cid, force=True) + t = threading.Thread(target=f) + t.start() + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, obj, blocking=True) + t.join() + + with self.subTest('with timeout'): + cid = channels.create() + def f(): + wait() + channels.close(cid, force=True) + t = threading.Thread(target=f) + t.start() + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, obj, blocking=True, timeout=30) + t.join() + def test_send_buffer_closed_while_waiting(self): + try: + self._has_run_once_closed + except AttributeError: + # At the moment, this test leaks a few references. + # It looks like the leak originates with the addition + # of _channels.send_buffer() (gh-110246), whereas the + # tests were added afterward. We want this test even + # if the refleak isn't fixed yet, so we skip here. + raise unittest.SkipTest('temporarily skipped due to refleaks') + else: + self._has_run_once_closed = True + + obj = bytearray(b'spam') + wait = self.build_send_waiter(obj, buffer=True) + + with self.subTest('without timeout'): + cid = channels.create() + def f(): + wait() + channels.close(cid, force=True) + t = threading.Thread(target=f) + t.start() + with self.assertRaises(channels.ChannelClosedError): + channels.send_buffer(cid, obj, blocking=True) + t.join() + + with self.subTest('with timeout'): + cid = channels.create() + def f(): + wait() + channels.close(cid, force=True) + t = threading.Thread(target=f) + t.start() + with self.assertRaises(channels.ChannelClosedError): + channels.send_buffer(cid, obj, blocking=True, timeout=30) + t.join() + + #------------------- # close 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,27 +1009,27 @@ 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 _channels.recv({cid}) """)) channels.close(cid) - with self.assertRaises(interpreters.RunFailedError) as cm: - interpreters.run_string(id1, dedent(f""" + + excsnap = interpreters.run_string(id1, dedent(f""" _channels.send({cid}, b'spam') """)) - self.assertIn('ChannelClosedError', str(cm.exception)) - with self.assertRaises(interpreters.RunFailedError) as cm: - interpreters.run_string(id2, dedent(f""" + self.assertEqual(excsnap.type.__name__, 'ChannelClosedError') + + excsnap = interpreters.run_string(id2, dedent(f""" _channels.send({cid}, b'spam') """)) - self.assertIn('ChannelClosedError', str(cm.exception)) + self.assertEqual(excsnap.type.__name__, 'ChannelClosedError') 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 +1046,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 +1057,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 +1093,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 +1117,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 +1128,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 +1148,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 +1161,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 +1235,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 +1250,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 +1266,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 +1277,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 +1286,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 +1304,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 +1323,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 +1333,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 +1343,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 +1430,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 +1660,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 +1708,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..a76e4d0ade5b8a 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -7,13 +7,15 @@ import threading import unittest -import _testcapi +import _testinternalcapi from test import support from test.support import import_helper +from test.support import os_helper from test.support import script_helper interpreters = import_helper.import_module('_xxsubinterpreters') +from _xxsubinterpreters import InterpreterNotFoundError ################################## @@ -31,10 +33,10 @@ def _captured_script(script): return wrapped, open(r, encoding="utf-8") -def _run_output(interp, request, shared=None): +def _run_output(interp, request): script, rpipe = _captured_script(request) with rpipe: - interpreters.run_string(interp, script, shared) + interpreters.run_string(interp, script) return rpipe.read() @@ -102,6 +104,10 @@ def test_default_shareables(self): 'spam', 10, -10, + True, + False, + 100.0, + (1, ('spam', 'eggs')), ] for obj in shareables: with self.subTest(obj): @@ -120,8 +126,6 @@ class SubBytes(bytes): not_shareables = [ # singletons - True, - False, NotImplemented, ..., # builtin types and objects @@ -129,7 +133,6 @@ class SubBytes(bytes): object, object(), Exception(), - 100.0, # user-defined types and objects Cheese, Cheese('Wensleydale'), @@ -146,8 +149,8 @@ class ShareableTypeTests(unittest.TestCase): def _assert_values(self, values): for obj in values: with self.subTest(obj): - xid = _testcapi.get_crossinterp_data(obj) - got = _testcapi.restore_crossinterp_data(xid) + xid = _testinternalcapi.get_crossinterp_data(obj) + got = _testinternalcapi.restore_crossinterp_data(xid) self.assertEqual(got, obj) self.assertIs(type(got), type(obj)) @@ -155,8 +158,8 @@ def _assert_values(self, values): def test_singletons(self): for obj in [None]: with self.subTest(obj): - xid = _testcapi.get_crossinterp_data(obj) - got = _testcapi.restore_crossinterp_data(xid) + xid = _testinternalcapi.get_crossinterp_data(obj) + got = _testinternalcapi.restore_crossinterp_data(xid) # XXX What about between interpreters? self.assertIs(got, obj) @@ -187,7 +190,40 @@ def test_non_shareable_int(self): for i in ints: with self.subTest(i): with self.assertRaises(OverflowError): - _testcapi.get_crossinterp_data(i) + _testinternalcapi.get_crossinterp_data(i) + + def test_bool(self): + self._assert_values([True, False]) + + def test_float(self): + self._assert_values([0.0, 1.1, -1.0, 0.12345678, -0.12345678]) + + def test_tuple(self): + self._assert_values([(), (1,), ("hello", "world", ), (1, True, "hello")]) + # Test nesting + self._assert_values([ + ((1,),), + ((1, 2), (3, 4)), + ((1, 2), (3, 4), (5, 6)), + ]) + + def test_tuples_containing_non_shareable_types(self): + non_shareables = [ + Exception(), + object(), + ] + for s in non_shareables: + value = tuple([0, 1.0, s]) + with self.subTest(repr(value)): + # XXX Assert the NotShareableError when it is exported + with self.assertRaises(ValueError): + _testinternalcapi.get_crossinterp_data(value) + # Check nested as well + value = tuple([0, 1., (s,)]) + with self.subTest("nested " + repr(value)): + # XXX Assert the NotShareableError when it is exported + with self.assertRaises(ValueError): + _testinternalcapi.get_crossinterp_data(value) class ModuleTests(TestBase): @@ -231,7 +267,7 @@ def test_main(self): main = interpreters.get_main() cur = interpreters.get_current() self.assertEqual(cur, main) - self.assertIsInstance(cur, interpreters.InterpreterID) + self.assertIsInstance(cur, int) def test_subinterpreter(self): main = interpreters.get_main() @@ -240,7 +276,7 @@ def test_subinterpreter(self): import _xxsubinterpreters as _interpreters cur = _interpreters.get_current() print(cur) - assert isinstance(cur, _interpreters.InterpreterID) + assert isinstance(cur, int) """)) cur = int(out.strip()) _, expected = interpreters.list_all() @@ -254,7 +290,7 @@ def test_from_main(self): [expected] = interpreters.list_all() main = interpreters.get_main() self.assertEqual(main, expected) - self.assertIsInstance(main, interpreters.InterpreterID) + self.assertIsInstance(main, int) def test_from_subinterpreter(self): [expected] = interpreters.list_all() @@ -263,7 +299,7 @@ def test_from_subinterpreter(self): import _xxsubinterpreters as _interpreters main = _interpreters.get_main() print(main) - assert isinstance(main, _interpreters.InterpreterID) + assert isinstance(main, int) """)) main = int(out.strip()) self.assertEqual(main, expected) @@ -298,11 +334,11 @@ def test_from_subinterpreter(self): def test_already_destroyed(self): interp = interpreters.create() interpreters.destroy(interp) - with self.assertRaises(RuntimeError): + with self.assertRaises(InterpreterNotFoundError): interpreters.is_running(interp) def test_does_not_exist(self): - with self.assertRaises(RuntimeError): + with self.assertRaises(InterpreterNotFoundError): interpreters.is_running(1_000_000) def test_bad_id(self): @@ -310,70 +346,11 @@ def test_bad_id(self): interpreters.is_running(-1) -class InterpreterIDTests(TestBase): - - def test_with_int(self): - id = interpreters.InterpreterID(10, force=True) - - self.assertEqual(int(id), 10) - - def test_coerce_id(self): - class Int(str): - def __index__(self): - return 10 - - id = interpreters.InterpreterID(Int(), force=True) - self.assertEqual(int(id), 10) - - def test_bad_id(self): - self.assertRaises(TypeError, interpreters.InterpreterID, object()) - self.assertRaises(TypeError, interpreters.InterpreterID, 10.0) - self.assertRaises(TypeError, interpreters.InterpreterID, '10') - self.assertRaises(TypeError, interpreters.InterpreterID, b'10') - self.assertRaises(ValueError, interpreters.InterpreterID, -1) - self.assertRaises(OverflowError, interpreters.InterpreterID, 2**64) - - def test_does_not_exist(self): - id = interpreters.create() - with self.assertRaises(RuntimeError): - interpreters.InterpreterID(int(id) + 1) # unforced - - def test_str(self): - id = interpreters.InterpreterID(10, force=True) - self.assertEqual(str(id), '10') - - def test_repr(self): - id = interpreters.InterpreterID(10, force=True) - self.assertEqual(repr(id), 'InterpreterID(10)') - - def test_equality(self): - id1 = interpreters.create() - id2 = interpreters.InterpreterID(int(id1)) - id3 = interpreters.create() - - self.assertTrue(id1 == id1) - self.assertTrue(id1 == id2) - self.assertTrue(id1 == int(id1)) - self.assertTrue(int(id1) == id1) - self.assertTrue(id1 == float(int(id1))) - self.assertTrue(float(int(id1)) == id1) - self.assertFalse(id1 == float(int(id1)) + 0.1) - self.assertFalse(id1 == str(int(id1))) - self.assertFalse(id1 == 2**1000) - self.assertFalse(id1 == float('inf')) - self.assertFalse(id1 == 'spam') - self.assertFalse(id1 == id3) - - self.assertFalse(id1 != id1) - self.assertFalse(id1 != id2) - self.assertTrue(id1 != id3) - - class CreateTests(TestBase): def test_in_main(self): id = interpreters.create() - self.assertIsInstance(id, interpreters.InterpreterID) + self.assertIsInstance(id, int) self.assertIn(id, interpreters.list_all()) @@ -409,7 +386,7 @@ def test_in_subinterpreter(self): import _xxsubinterpreters as _interpreters id = _interpreters.create() print(id) - assert isinstance(id, _interpreters.InterpreterID) + assert isinstance(id, int) """)) id2 = int(out.strip()) @@ -501,11 +478,11 @@ def f(): def test_already_destroyed(self): id = interpreters.create() interpreters.destroy(id) - with self.assertRaises(RuntimeError): + with self.assertRaises(InterpreterNotFoundError): interpreters.destroy(id) def test_does_not_exist(self): - with self.assertRaises(RuntimeError): + with self.assertRaises(InterpreterNotFoundError): interpreters.destroy(1_000_000) def test_bad_id(self): @@ -653,10 +630,10 @@ def test_shareable_types(self): ] for obj in objects: with self.subTest(obj): + interpreters.set___main___attrs(interp, dict(obj=obj)) interpreters.run_string( interp, f'assert(obj == {obj!r})', - shared=dict(obj=obj), ) def test_os_exec(self): @@ -706,7 +683,7 @@ def test_does_not_exist(self): id = 0 while id in interpreters.list_all(): id += 1 - with self.assertRaises(RuntimeError): + with self.assertRaises(InterpreterNotFoundError): interpreters.run_string(id, 'print("spam")') def test_error_id(self): @@ -725,43 +702,6 @@ def test_bytes_for_script(self): with self.assertRaises(TypeError): interpreters.run_string(self.id, b'print("spam")') - @contextlib.contextmanager - def assert_run_failed(self, exctype, msg=None): - with self.assertRaises(interpreters.RunFailedError) as caught: - yield - if msg is None: - self.assertEqual(str(caught.exception).split(':')[0], - exctype.__name__) - else: - self.assertEqual(str(caught.exception), - "{}: {}".format(exctype.__name__, msg)) - - def test_invalid_syntax(self): - with self.assert_run_failed(SyntaxError): - # missing close paren - interpreters.run_string(self.id, 'print("spam"') - - def test_failure(self): - with self.assert_run_failed(Exception, 'spam'): - interpreters.run_string(self.id, 'raise Exception("spam")') - - def test_SystemExit(self): - with self.assert_run_failed(SystemExit, '42'): - interpreters.run_string(self.id, 'raise SystemExit(42)') - - def test_sys_exit(self): - with self.assert_run_failed(SystemExit): - interpreters.run_string(self.id, dedent(""" - import sys - sys.exit() - """)) - - with self.assert_run_failed(SystemExit, '42'): - interpreters.run_string(self.id, dedent(""" - import sys - sys.exit(42) - """)) - def test_with_shared(self): r, w = os.pipe() @@ -781,7 +721,8 @@ def test_with_shared(self): with open({w}, 'wb') as chan: pickle.dump(ns, chan) """) - interpreters.run_string(self.id, script, shared) + interpreters.set___main___attrs(self.id, shared) + interpreters.run_string(self.id, script) with open(r, 'rb') as chan: ns = pickle.load(chan) @@ -802,7 +743,8 @@ def test_shared_overwrites(self): ns2 = dict(vars()) del ns2['__builtins__'] """) - interpreters.run_string(self.id, script, shared) + interpreters.set___main___attrs(self.id, shared) + interpreters.run_string(self.id, script) r, w = os.pipe() script = dedent(f""" @@ -833,7 +775,8 @@ def test_shared_overwrites_default_vars(self): with open({w}, 'wb') as chan: pickle.dump(ns, chan) """) - interpreters.run_string(self.id, script, shared) + interpreters.set___main___attrs(self.id, shared) + interpreters.run_string(self.id, script) with open(r, 'rb') as chan: ns = pickle.load(chan) @@ -925,5 +868,270 @@ def f(): self.assertEqual(retcode, 0) +class RunFailedTests(TestBase): + + def setUp(self): + super().setUp() + self.id = interpreters.create() + + def add_module(self, modname, text): + import tempfile + tempdir = tempfile.mkdtemp() + self.addCleanup(lambda: os_helper.rmtree(tempdir)) + interpreters.run_string(self.id, dedent(f""" + import sys + sys.path.insert(0, {tempdir!r}) + """)) + return script_helper.make_script(tempdir, modname, text) + + def run_script(self, text, *, fails=False): + r, w = os.pipe() + try: + script = dedent(f""" + import os, sys + os.write({w}, b'0') + + # This raises an exception: + {{}} + + # Nothing from here down should ever run. + os.write({w}, b'1') + class NeverError(Exception): pass + raise NeverError # never raised + """).format(dedent(text)) + if fails: + err = interpreters.run_string(self.id, script) + self.assertIsNot(err, None) + return err + else: + err = interpreters.run_string(self.id, script) + self.assertIs(err, None) + return None + except: + raise # re-raise + else: + msg = os.read(r, 100) + self.assertEqual(msg, b'0') + finally: + os.close(r) + os.close(w) + + def _assert_run_failed(self, exctype, msg, script): + if isinstance(exctype, str): + exctype_name = exctype + exctype = None + else: + exctype_name = exctype.__name__ + + # Run the script. + excinfo = self.run_script(script, fails=True) + + # Check the wrapper exception. + self.assertEqual(excinfo.type.__name__, exctype_name) + if msg is None: + self.assertEqual(excinfo.formatted.split(':')[0], + exctype_name) + else: + self.assertEqual(excinfo.formatted, + '{}: {}'.format(exctype_name, msg)) + + return excinfo + + def assert_run_failed(self, exctype, script): + self._assert_run_failed(exctype, None, script) + + def assert_run_failed_msg(self, exctype, msg, script): + self._assert_run_failed(exctype, msg, script) + + def test_exit(self): + with self.subTest('sys.exit(0)'): + # XXX Should an unhandled SystemExit(0) be handled as not-an-error? + self.assert_run_failed(SystemExit, """ + sys.exit(0) + """) + + with self.subTest('sys.exit()'): + self.assert_run_failed(SystemExit, """ + import sys + sys.exit() + """) + + with self.subTest('sys.exit(42)'): + self.assert_run_failed_msg(SystemExit, '42', """ + import sys + sys.exit(42) + """) + + with self.subTest('SystemExit'): + self.assert_run_failed_msg(SystemExit, '42', """ + raise SystemExit(42) + """) + + # XXX Also check os._exit() (via a subprocess)? + + def test_plain_exception(self): + self.assert_run_failed_msg(Exception, 'spam', """ + raise Exception("spam") + """) + + def test_invalid_syntax(self): + script = dedent(""" + x = 1 + 2 + y = 2 + 4 + z = 4 + 8 + + # missing close paren + print("spam" + + if x + y + z < 20: + ... + """) + + with self.subTest('script'): + self.assert_run_failed(SyntaxError, script) + + with self.subTest('module'): + modname = 'spam_spam_spam' + filename = self.add_module(modname, script) + self.assert_run_failed(SyntaxError, f""" + import {modname} + """) + + def test_NameError(self): + self.assert_run_failed(NameError, """ + res = spam + eggs + """) + # XXX check preserved suggestions + + def test_AttributeError(self): + self.assert_run_failed(AttributeError, """ + object().spam + """) + # XXX check preserved suggestions + + def test_ExceptionGroup(self): + self.assert_run_failed(ExceptionGroup, """ + raise ExceptionGroup('exceptions', [ + Exception('spam'), + ImportError('eggs'), + ]) + """) + + def test_user_defined_exception(self): + self.assert_run_failed_msg('MyError', 'spam', """ + class MyError(Exception): + pass + raise MyError('spam') + """) + + +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.set___main___attrs(self.id, dict(w=w)) + interpreters.run_func(self.id, script) + + 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.set___main___attrs(self.id, dict(w=w)) + interpreters.run_func(self.id, script) + 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.set___main___attrs(self.id, dict(w=w)) + interpreters.run_func(self.id, code) + + 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 fa96e259b8c978..64fcb02309de77 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -12,6 +12,10 @@ import weakref from functools import partial from textwrap import dedent +try: + import _testinternalcapi +except ImportError: + _testinternalcapi = None from test import support from test.support.import_helper import import_fresh_module @@ -100,6 +104,8 @@ def to_tuple(t): # With "with x as y: pass", "with x as y, z as q: pass", + "with (x as y): pass", + "with (x, y): pass", # Raise "raise Exception('string')", # TryExcept @@ -1116,12 +1122,14 @@ 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 crash_depth = 100_000 success_depth = 1200 + if _testinternalcapi is not None: + remaining = _testinternalcapi.get_c_recursion_remaining() + success_depth = min(success_depth, remaining) def check_limit(prefix, repeated): expect_ok = prefix + repeated * success_depth @@ -3015,6 +3023,8 @@ def main(): ('Module', [('If', (1, 0, 6, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 6, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [('Pass', (6, 2, 6, 6))])])], []), ('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',)))], [('Pass', (1, 13, 1, 17))], None)], []), ('Module', [('With', (1, 0, 1, 25), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',))), ('withitem', ('Name', (1, 13, 1, 14), 'z', ('Load',)), ('Name', (1, 18, 1, 19), 'q', ('Store',)))], [('Pass', (1, 21, 1, 25))], None)], []), +('Module', [('With', (1, 0, 1, 19), [('withitem', ('Name', (1, 6, 1, 7), 'x', ('Load',)), ('Name', (1, 11, 1, 12), 'y', ('Store',)))], [('Pass', (1, 15, 1, 19))], None)], []), +('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 6, 1, 7), 'x', ('Load',)), None), ('withitem', ('Name', (1, 9, 1, 10), 'y', ('Load',)), None)], [('Pass', (1, 13, 1, 17))], None)], []), ('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []), ('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []), ('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []), diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index abcb6f55c4b04e..c2080977e9d587 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -922,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_events.py b/Lib/test/test_asyncio/test_events.py index 3ee6565b2b65ad..b25c0975736e20 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1693,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: diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 1eb5641914f2a4..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 @@ -272,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_sendfile.py b/Lib/test/test_asyncio/test_sendfile.py index 0198da21d77028..d33ff197bbfa1d 100644 --- a/Lib/test/test_asyncio/test_sendfile.py +++ b/Lib/test/test_asyncio/test_sendfile.py @@ -470,8 +470,11 @@ def test_sendfile_close_peer_in_the_middle_of_receiving(self): self.assertTrue(1024 <= srv_proto.nbytes < len(self.DATA), srv_proto.nbytes) - self.assertTrue(1024 <= self.file.tell() < len(self.DATA), - self.file.tell()) + if not (sys.platform == 'win32' + and isinstance(self.loop, asyncio.ProactorEventLoop)): + # On Windows, Proactor uses transmitFile, which does not update tell() + self.assertTrue(1024 <= self.file.tell() < len(self.DATA), + self.file.tell()) self.assertTrue(cli_proto.transport.is_closing()) def test_sendfile_fallback_close_peer_in_the_middle_of_receiving(self): diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index 06d8b60f219f1a..f22cf3026e244b 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -1,4 +1,6 @@ import asyncio +import os +import socket import time import threading import unittest @@ -122,29 +124,133 @@ async def main(srv): class TestServer2(unittest.IsolatedAsyncioTestCase): - async def test_wait_closed(self): + async def test_wait_closed_basic(self): async def serve(*args): pass srv = await asyncio.start_server(serve, socket_helper.HOSTv4, 0) + self.addCleanup(srv.close) - # active count = 0 + # active count = 0, not closed: should block task1 = asyncio.create_task(srv.wait_closed()) await asyncio.sleep(0) - self.assertTrue(task1.done()) + self.assertFalse(task1.done()) - # active count != 0 + # active count != 0, not closed: should block srv._attach() task2 = asyncio.create_task(srv.wait_closed()) await asyncio.sleep(0) + self.assertFalse(task1.done()) self.assertFalse(task2.done()) srv.close() await asyncio.sleep(0) + # active count != 0, closed: should block + task3 = asyncio.create_task(srv.wait_closed()) + await asyncio.sleep(0) + self.assertFalse(task1.done()) self.assertFalse(task2.done()) + self.assertFalse(task3.done()) srv._detach() + # active count == 0, closed: should unblock + await task1 await task2 + await task3 + await srv.wait_closed() # Return immediately + + async def test_wait_closed_race(self): + # Test a regression in 3.12.0, should be fixed in 3.12.1 + async def serve(*args): + pass + + srv = await asyncio.start_server(serve, socket_helper.HOSTv4, 0) + self.addCleanup(srv.close) + + task = asyncio.create_task(srv.wait_closed()) + await asyncio.sleep(0) + self.assertFalse(task.done()) + srv._attach() + loop = asyncio.get_running_loop() + loop.call_soon(srv.close) + loop.call_soon(srv._detach) + await srv.wait_closed() + + + + +# Test the various corner cases of Unix server socket removal +class UnixServerCleanupTests(unittest.IsolatedAsyncioTestCase): + @socket_helper.skip_unless_bind_unix_socket + async def test_unix_server_addr_cleanup(self): + # Default scenario + with test_utils.unix_socket_path() as addr: + async def serve(*args): + pass + + srv = await asyncio.start_unix_server(serve, addr) + + srv.close() + self.assertFalse(os.path.exists(addr)) + + @socket_helper.skip_unless_bind_unix_socket + async def test_unix_server_sock_cleanup(self): + # Using already bound socket + with test_utils.unix_socket_path() as addr: + async def serve(*args): + pass + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.bind(addr) + + srv = await asyncio.start_unix_server(serve, sock=sock) + + srv.close() + self.assertFalse(os.path.exists(addr)) + + @socket_helper.skip_unless_bind_unix_socket + async def test_unix_server_cleanup_gone(self): + # Someone else has already cleaned up the socket + with test_utils.unix_socket_path() as addr: + async def serve(*args): + pass + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.bind(addr) + + srv = await asyncio.start_unix_server(serve, sock=sock) + + os.unlink(addr) + + srv.close() + + @socket_helper.skip_unless_bind_unix_socket + async def test_unix_server_cleanup_replaced(self): + # Someone else has replaced the socket with their own + with test_utils.unix_socket_path() as addr: + async def serve(*args): + pass + + srv = await asyncio.start_unix_server(serve, addr) + + os.unlink(addr) + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.bind(addr) + + srv.close() + self.assertTrue(os.path.exists(addr)) + + @socket_helper.skip_unless_bind_unix_socket + async def test_unix_server_cleanup_prevented(self): + # Automatic cleanup explicitly disabled + with test_utils.unix_socket_path() as addr: + async def serve(*args): + pass + + srv = await asyncio.start_unix_server(serve, addr, cleanup_socket=False) + + srv.close() + self.assertTrue(os.path.exists(addr)) @unittest.skipUnless(hasattr(asyncio, 'ProactorEventLoop'), 'Windows only') diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 9c92e75886c593..b408cd1f7da205 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -37,8 +37,7 @@ def tearDown(self): # just in case if we have transport close callbacks test_utils.run_briefly(self.loop) - self.loop.close() - gc.collect() + # set_event_loop() takes care of closing self.loop in a safe way super().tearDown() def _basetest_open_connection(self, open_connection_fut): @@ -1083,10 +1082,11 @@ async def inner(httpd): 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): + with self.assertWarns(ResourceWarning) as cm: del wr gc.collect() - + self.assertEqual(len(cm.warnings), 1) + self.assertTrue(str(cm.warnings[0].message).startswith("unclosed None: + port = socket_helper.find_unused_port() + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + + async def client(): + rd, wr = await asyncio.open_connection('localhost', port) + wr.write(b'test msg') + await wr.drain() + wr.close() + await wr.wait_closed() + + async def main(): + async def handle_echo(reader, writer): + raise Exception('test') + + server = await asyncio.start_server( + handle_echo, 'localhost', port) + await server.start_serving() + await client() + server.close() + await server.wait_closed() + + self.loop.run_until_complete(main()) + + self.assertEqual(messages[0]['message'], + 'Unhandled exception in client_connected_cb') + # Break explicitly reference cycle + messages = None if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index dc5a48d500e8d5..179c8cb8cc17cf 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -14,8 +14,7 @@ from test.support import os_helper -MS_WINDOWS = (sys.platform == 'win32') -if MS_WINDOWS: +if support.MS_WINDOWS: import msvcrt else: from asyncio import unix_events @@ -283,7 +282,7 @@ def test_stdin_broken_pipe(self): rfd, wfd = os.pipe() self.addCleanup(os.close, rfd) self.addCleanup(os.close, wfd) - if MS_WINDOWS: + if support.MS_WINDOWS: handle = msvcrt.get_osfhandle(rfd) os.set_handle_inheritable(handle, True) code = textwrap.dedent(f''' diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index 6a0231f2859a62..7a18362b54e469 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -8,6 +8,8 @@ from asyncio import taskgroups import unittest +from test.test_asyncio.utils import await_without_task + # To prevent a warning "test altered the execution environment" def tearDownModule(): @@ -779,6 +781,49 @@ async def main(): await asyncio.create_task(main()) + async def test_taskgroup_already_entered(self): + tg = taskgroups.TaskGroup() + async with tg: + with self.assertRaisesRegex(RuntimeError, "has already been entered"): + async with tg: + pass + + async def test_taskgroup_double_enter(self): + tg = taskgroups.TaskGroup() + async with tg: + pass + with self.assertRaisesRegex(RuntimeError, "has already been entered"): + async with tg: + pass + + async def test_taskgroup_finished(self): + tg = taskgroups.TaskGroup() + async with tg: + pass + coro = asyncio.sleep(0) + with self.assertRaisesRegex(RuntimeError, "is finished"): + tg.create_task(coro) + # We still have to await coro to avoid a warning + await coro + + async def test_taskgroup_not_entered(self): + tg = taskgroups.TaskGroup() + coro = asyncio.sleep(0) + with self.assertRaisesRegex(RuntimeError, "has not been entered"): + tg.create_task(coro) + # We still have to await coro to avoid a warning + await coro + + async def test_taskgroup_without_parent_task(self): + tg = taskgroups.TaskGroup() + with self.assertRaisesRegex(RuntimeError, "parent task"): + await await_without_task(tg.__aenter__()) + coro = asyncio.sleep(0) + with self.assertRaisesRegex(RuntimeError, "has not been entered"): + tg.create_task(coro) + # We still have to await coro to avoid a warning + await coro + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_asyncio/test_timeouts.py b/Lib/test/test_asyncio/test_timeouts.py index e9b59b953518b3..f54e79e4d8e600 100644 --- a/Lib/test/test_asyncio/test_timeouts.py +++ b/Lib/test/test_asyncio/test_timeouts.py @@ -5,11 +5,12 @@ import asyncio +from test.test_asyncio.utils import await_without_task + def tearDownModule(): asyncio.set_event_loop_policy(None) - class TimeoutTests(unittest.IsolatedAsyncioTestCase): async def test_timeout_basic(self): @@ -257,6 +258,51 @@ async def test_timeout_exception_cause (self): cause = exc.exception.__cause__ assert isinstance(cause, asyncio.CancelledError) + async def test_timeout_already_entered(self): + async with asyncio.timeout(0.01) as cm: + with self.assertRaisesRegex(RuntimeError, "has already been entered"): + async with cm: + pass + + async def test_timeout_double_enter(self): + async with asyncio.timeout(0.01) as cm: + pass + with self.assertRaisesRegex(RuntimeError, "has already been entered"): + async with cm: + pass + + async def test_timeout_finished(self): + async with asyncio.timeout(0.01) as cm: + pass + with self.assertRaisesRegex(RuntimeError, "finished"): + cm.reschedule(0.02) + + async def test_timeout_expired(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01) as cm: + await asyncio.sleep(1) + with self.assertRaisesRegex(RuntimeError, "expired"): + cm.reschedule(0.02) + + async def test_timeout_expiring(self): + async with asyncio.timeout(0.01) as cm: + with self.assertRaises(asyncio.CancelledError): + await asyncio.sleep(1) + with self.assertRaisesRegex(RuntimeError, "expiring"): + cm.reschedule(0.02) + + async def test_timeout_not_entered(self): + cm = asyncio.timeout(0.01) + with self.assertRaisesRegex(RuntimeError, "has not been entered"): + cm.reschedule(0.02) + + async def test_timeout_without_task(self): + cm = asyncio.timeout(0.01) + with self.assertRaisesRegex(RuntimeError, "task"): + await await_without_task(cm.__aenter__()) + with self.assertRaisesRegex(RuntimeError, "has not been entered"): + cm.reschedule(0.02) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 7322be597ae2d2..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 @@ -15,6 +16,7 @@ import unittest from unittest import mock import warnings + from test import support from test.support import os_helper from test.support import socket_helper @@ -1903,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') @@ -1947,6 +1951,8 @@ async def func(): @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) @@ -1964,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/utils.py b/Lib/test/test_asyncio/utils.py index e1101bf42eb24e..44943e1fa7bc4e 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -37,9 +37,9 @@ # 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 +# GetTickCount64() has a resolution of 15.6 ms. Use 50 ms to tolerate rounding # issues. -CLOCK_RES = 0.020 +CLOCK_RES = 0.050 def data_file(*filename): @@ -546,6 +546,7 @@ def close_loop(loop): else: loop._default_executor.shutdown(wait=True) loop.close() + policy = support.maybe_get_event_loop_policy() if policy is not None: try: @@ -557,9 +558,13 @@ def close_loop(loop): pass else: if isinstance(watcher, asyncio.ThreadedChildWatcher): - threads = list(watcher._threads.values()) - for thread in threads: - thread.join() + # Wait for subprocess to finish, but not forever + for thread in list(watcher._threads.values()): + thread.join(timeout=support.SHORT_TIMEOUT) + if thread.is_alive(): + raise RuntimeError(f"thread {thread} still alive: " + "subprocess still running") + def set_event_loop(self, loop, *, cleanup=True): if loop is None: @@ -612,3 +617,18 @@ def mock_nonblocking_socket(proto=socket.IPPROTO_TCP, type=socket.SOCK_STREAM, sock.family = family sock.gettimeout.return_value = 0.0 return sock + + +async def await_without_task(coro): + exc = None + def func(): + try: + for _ in coro.__await__(): + pass + except BaseException as err: + nonlocal exc + exc = err + asyncio.get_running_loop().call_soon(func) + await asyncio.sleep(0) + if exc is not None: + raise exc diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 47e5832d311bd1..cd0a4e2264865d 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -209,6 +209,8 @@ def test_threading(self): expected = [ ("_thread.start_new_thread", "(, (), None)"), ("test.test_func", "()"), + ("_thread.start_joinable_thread", "(,)"), + ("test.test_func", "()"), ] self.assertEqual(actual, expected) diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index ef744f6b97259c..82dea8a6d731ea 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -474,6 +474,12 @@ def test_base64_roundtrip(self, binary, newline): restored = binascii.a2b_base64(self.type2test(converted)) self.assertConversion(binary, converted, restored, newline=newline) + def test_c_contiguity(self): + m = memoryview(bytearray(b'noncontig')) + noncontig_writable = m[::-2] + with self.assertRaises(BufferError): + binascii.b2a_hex(noncontig_writable) + class ArrayBinASCIITest(BinASCIITest): def type2test(self, s): diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 33cb248ff6e82b..5e66d58fd2cb18 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -627,6 +627,11 @@ def __dir__(self): # test that object has a __dir__() self.assertEqual(sorted([].__dir__()), dir([])) + def test___ne__(self): + self.assertFalse(None.__ne__(None)) + self.assertTrue(None.__ne__(0)) + self.assertTrue(None.__ne__("abc")) + def test_divmod(self): self.assertEqual(divmod(12, 7), (1, 5)) self.assertEqual(divmod(-12, 7), (-2, 2)) @@ -2039,6 +2044,23 @@ def test_bytearray_extend_error(self): bad_iter = map(int, "X") self.assertRaises(ValueError, array.extend, bad_iter) + def test_bytearray_join_with_misbehaving_iterator(self): + # Issue #112625 + array = bytearray(b',') + def iterator(): + array.clear() + yield b'A' + yield b'B' + self.assertRaises(BufferError, array.join, iterator()) + + def test_bytearray_join_with_custom_iterator(self): + # Issue #112625 + array = bytearray(b',') + def iterator(): + yield b'A' + yield b'B' + self.assertEqual(bytearray(b'A,B'), array.join(iterator())) + def test_construct_singletons(self): for const in None, Ellipsis, NotImplemented: tp = type(const) @@ -2203,8 +2225,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) @@ -2254,7 +2274,10 @@ def _run_child(self, child, terminal_input): return lines - def check_input_tty(self, prompt, terminal_input, stdio_encoding=None): + def check_input_tty(self, prompt, terminal_input, stdio_encoding=None, *, + expected=None, + stdin_errors='surrogateescape', + stdout_errors='replace'): if not sys.stdin.isatty() or not sys.stdout.isatty(): self.skipTest("stdin and stdout must be ttys") def child(wpipe): @@ -2262,22 +2285,26 @@ def child(wpipe): if stdio_encoding: sys.stdin = io.TextIOWrapper(sys.stdin.detach(), encoding=stdio_encoding, - errors='surrogateescape') + errors=stdin_errors) sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding=stdio_encoding, - errors='replace') + errors=stdout_errors) print("tty =", sys.stdin.isatty() and sys.stdout.isatty(), file=wpipe) - print(ascii(input(prompt)), file=wpipe) + try: + print(ascii(input(prompt)), file=wpipe) + except BaseException as e: + print(ascii(f'{e.__class__.__name__}: {e!s}'), file=wpipe) lines = self.run_child(child, terminal_input + b"\r\n") # Check we did exercise the GNU readline path self.assertIn(lines[0], {'tty = True', 'tty = False'}) if lines[0] != 'tty = True': self.skipTest("standard IO in should have been a tty") input_result = eval(lines[1]) # ascii() -> eval() roundtrip - if stdio_encoding: - expected = terminal_input.decode(stdio_encoding, 'surrogateescape') - else: - expected = terminal_input.decode(sys.stdin.encoding) # what else? + if expected is None: + if stdio_encoding: + expected = terminal_input.decode(stdio_encoding, 'surrogateescape') + else: + expected = terminal_input.decode(sys.stdin.encoding) # what else? self.assertEqual(input_result, expected) def test_input_tty(self): @@ -2298,13 +2325,32 @@ def skip_if_readline(self): def test_input_tty_non_ascii(self): self.skip_if_readline() # Check stdin/stdout encoding is used when invoking PyOS_Readline() - self.check_input_tty("prompté", b"quux\xe9", "utf-8") + self.check_input_tty("prompté", b"quux\xc3\xa9", "utf-8") def test_input_tty_non_ascii_unicode_errors(self): self.skip_if_readline() # Check stdin/stdout error handler is used when invoking PyOS_Readline() self.check_input_tty("prompté", b"quux\xe9", "ascii") + def test_input_tty_null_in_prompt(self): + self.check_input_tty("prompt\0", b"", + expected='ValueError: input: prompt string cannot contain ' + 'null characters') + + def test_input_tty_nonencodable_prompt(self): + self.skip_if_readline() + self.check_input_tty("prompté", b"quux", "ascii", stdout_errors='strict', + expected="UnicodeEncodeError: 'ascii' codec can't encode " + "character '\\xe9' in position 6: ordinal not in " + "range(128)") + + def test_input_tty_nondecodable_input(self): + self.skip_if_readline() + self.check_input_tty("prompt", b"quux\xe9", "ascii", stdin_errors='strict', + expected="UnicodeDecodeError: 'ascii' codec can't decode " + "byte 0xe9 in position 4: ordinal not in " + "range(128)") + def test_input_no_stdout_fileno(self): # Issue #24402: If stdin is the original terminal but stdout.fileno() # fails, do not use the original stdout file descriptor diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index afd506f07520d8..a3804a945f2e3a 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -46,6 +46,10 @@ def __index__(self): class BaseBytesTest: + def assertTypedEqual(self, actual, expected): + self.assertIs(type(actual), type(expected)) + self.assertEqual(actual, expected) + def test_basics(self): b = self.type2test() self.assertEqual(type(b), self.type2test) @@ -1023,36 +1027,63 @@ def test_buffer_is_readonly(self): self.assertRaises(TypeError, f.readinto, b"") def test_custom(self): - class A: - def __bytes__(self): - return b'abc' - self.assertEqual(bytes(A()), b'abc') - class A: pass - self.assertRaises(TypeError, bytes, A()) - class A: - def __bytes__(self): - return None - self.assertRaises(TypeError, bytes, A()) - class A: + self.assertEqual(bytes(BytesSubclass(b'abc')), b'abc') + self.assertEqual(BytesSubclass(OtherBytesSubclass(b'abc')), + BytesSubclass(b'abc')) + self.assertEqual(bytes(WithBytes(b'abc')), b'abc') + self.assertEqual(BytesSubclass(WithBytes(b'abc')), BytesSubclass(b'abc')) + + class NoBytes: pass + self.assertRaises(TypeError, bytes, NoBytes()) + self.assertRaises(TypeError, bytes, WithBytes('abc')) + self.assertRaises(TypeError, bytes, WithBytes(None)) + class IndexWithBytes: def __bytes__(self): return b'a' def __index__(self): return 42 - self.assertEqual(bytes(A()), b'a') + self.assertEqual(bytes(IndexWithBytes()), b'a') # Issue #25766 - class A(str): + class StrWithBytes(str): + def __new__(cls, value): + self = str.__new__(cls, '\u20ac') + self.value = value + return self def __bytes__(self): - return b'abc' - self.assertEqual(bytes(A('\u20ac')), b'abc') - self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4') + return self.value + self.assertEqual(bytes(StrWithBytes(b'abc')), b'abc') + self.assertEqual(bytes(StrWithBytes(b'abc'), 'iso8859-15'), b'\xa4') + self.assertEqual(bytes(StrWithBytes(BytesSubclass(b'abc'))), b'abc') + self.assertEqual(BytesSubclass(StrWithBytes(b'abc')), BytesSubclass(b'abc')) + self.assertEqual(BytesSubclass(StrWithBytes(b'abc'), 'iso8859-15'), + BytesSubclass(b'\xa4')) + self.assertEqual(BytesSubclass(StrWithBytes(BytesSubclass(b'abc'))), + BytesSubclass(b'abc')) + self.assertEqual(BytesSubclass(StrWithBytes(OtherBytesSubclass(b'abc'))), + BytesSubclass(b'abc')) # Issue #24731 - class A: + self.assertTypedEqual(bytes(WithBytes(BytesSubclass(b'abc'))), BytesSubclass(b'abc')) + self.assertTypedEqual(BytesSubclass(WithBytes(BytesSubclass(b'abc'))), + BytesSubclass(b'abc')) + self.assertTypedEqual(BytesSubclass(WithBytes(OtherBytesSubclass(b'abc'))), + BytesSubclass(b'abc')) + + class BytesWithBytes(bytes): + def __new__(cls, value): + self = bytes.__new__(cls, b'\xa4') + self.value = value + return self def __bytes__(self): - return OtherBytesSubclass(b'abc') - self.assertEqual(bytes(A()), b'abc') - self.assertIs(type(bytes(A())), OtherBytesSubclass) - self.assertEqual(BytesSubclass(A()), b'abc') - self.assertIs(type(BytesSubclass(A())), BytesSubclass) + return self.value + self.assertTypedEqual(bytes(BytesWithBytes(b'abc')), b'abc') + self.assertTypedEqual(BytesSubclass(BytesWithBytes(b'abc')), + BytesSubclass(b'abc')) + self.assertTypedEqual(bytes(BytesWithBytes(BytesSubclass(b'abc'))), + BytesSubclass(b'abc')) + self.assertTypedEqual(BytesSubclass(BytesWithBytes(BytesSubclass(b'abc'))), + BytesSubclass(b'abc')) + self.assertTypedEqual(BytesSubclass(BytesWithBytes(OtherBytesSubclass(b'abc'))), + BytesSubclass(b'abc')) # Test PyBytes_FromFormat() def test_from_format(self): @@ -2069,6 +2100,12 @@ class BytesSubclass(bytes): class OtherBytesSubclass(bytes): pass +class WithBytes: + def __init__(self, value): + self.value = value + def __bytes__(self): + return self.value + class ByteArraySubclassTest(SubclassTest, unittest.TestCase): basetype = bytearray type2test = ByteArraySubclass diff --git a/Lib/test/test_capi/test_abstract.py b/Lib/test/test_capi/test_abstract.py index eeaef60a8b47b5..97ed939928c360 100644 --- a/Lib/test/test_capi/test_abstract.py +++ b/Lib/test/test_capi/test_abstract.py @@ -1,10 +1,37 @@ import unittest from collections import OrderedDict -import _testcapi +from test import support +from test.support import import_helper +_testcapi = import_helper.import_module('_testcapi') +from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX NULL = None +class StrSubclass(str): + pass + +class BytesSubclass(bytes): + pass + +class WithStr: + def __init__(self, value): + self.value = value + def __str__(self): + return self.value + +class WithRepr: + def __init__(self, value): + self.value = value + def __repr__(self): + return self.value + +class WithBytes: + def __init__(self, value): + self.value = value + def __bytes__(self): + return self.value + class TestObject: @property def evil(self): @@ -41,6 +68,68 @@ def gen(): class CAPITest(unittest.TestCase): + def assertTypedEqual(self, actual, expected): + self.assertIs(type(actual), type(expected)) + self.assertEqual(actual, expected) + + def test_object_str(self): + # Test PyObject_Str() + object_str = _testcapi.object_str + self.assertTypedEqual(object_str(''), '') + self.assertTypedEqual(object_str('abc'), 'abc') + self.assertTypedEqual(object_str('\U0001f40d'), '\U0001f40d') + self.assertTypedEqual(object_str(StrSubclass('abc')), 'abc') + self.assertTypedEqual(object_str(WithStr('abc')), 'abc') + self.assertTypedEqual(object_str(WithStr(StrSubclass('abc'))), StrSubclass('abc')) + self.assertTypedEqual(object_str(WithRepr('')), '') + self.assertTypedEqual(object_str(WithRepr(StrSubclass(''))), StrSubclass('')) + self.assertTypedEqual(object_str(NULL), '') + + def test_object_repr(self): + # Test PyObject_Repr() + object_repr = _testcapi.object_repr + self.assertTypedEqual(object_repr(''), "''") + self.assertTypedEqual(object_repr('abc'), "'abc'") + self.assertTypedEqual(object_repr('\U0001f40d'), "'\U0001f40d'") + self.assertTypedEqual(object_repr(StrSubclass('abc')), "'abc'") + self.assertTypedEqual(object_repr(WithRepr('')), '') + self.assertTypedEqual(object_repr(WithRepr(StrSubclass(''))), StrSubclass('')) + self.assertTypedEqual(object_repr(WithRepr('<\U0001f40d>')), '<\U0001f40d>') + self.assertTypedEqual(object_repr(WithRepr(StrSubclass('<\U0001f40d>'))), StrSubclass('<\U0001f40d>')) + self.assertTypedEqual(object_repr(NULL), '') + + def test_object_ascii(self): + # Test PyObject_ASCII() + object_ascii = _testcapi.object_ascii + self.assertTypedEqual(object_ascii(''), "''") + self.assertTypedEqual(object_ascii('abc'), "'abc'") + self.assertTypedEqual(object_ascii('\U0001f40d'), r"'\U0001f40d'") + self.assertTypedEqual(object_ascii(StrSubclass('abc')), "'abc'") + self.assertTypedEqual(object_ascii(WithRepr('')), '') + self.assertTypedEqual(object_ascii(WithRepr(StrSubclass(''))), StrSubclass('')) + self.assertTypedEqual(object_ascii(WithRepr('<\U0001f40d>')), r'<\U0001f40d>') + self.assertTypedEqual(object_ascii(WithRepr(StrSubclass('<\U0001f40d>'))), r'<\U0001f40d>') + self.assertTypedEqual(object_ascii(NULL), '') + + def test_object_bytes(self): + # Test PyObject_Bytes() + object_bytes = _testcapi.object_bytes + self.assertTypedEqual(object_bytes(b''), b'') + self.assertTypedEqual(object_bytes(b'abc'), b'abc') + self.assertTypedEqual(object_bytes(BytesSubclass(b'abc')), b'abc') + self.assertTypedEqual(object_bytes(WithBytes(b'abc')), b'abc') + self.assertTypedEqual(object_bytes(WithBytes(BytesSubclass(b'abc'))), BytesSubclass(b'abc')) + self.assertTypedEqual(object_bytes(bytearray(b'abc')), b'abc') + self.assertTypedEqual(object_bytes(memoryview(b'abc')), b'abc') + self.assertTypedEqual(object_bytes([97, 98, 99]), b'abc') + self.assertTypedEqual(object_bytes((97, 98, 99)), b'abc') + self.assertTypedEqual(object_bytes(iter([97, 98, 99])), b'abc') + self.assertRaises(TypeError, object_bytes, WithBytes(bytearray(b'abc'))) + self.assertRaises(TypeError, object_bytes, WithBytes([97, 98, 99])) + self.assertRaises(TypeError, object_bytes, 3) + self.assertRaises(TypeError, object_bytes, 'abc') + self.assertRaises(TypeError, object_bytes, object()) + self.assertTypedEqual(object_bytes(NULL), b'') def test_object_getattr(self): xgetattr = _testcapi.object_getattr @@ -107,8 +196,18 @@ def test_object_hasattr(self): self.assertFalse(xhasattr(obj, 'b')) self.assertTrue(xhasattr(obj, '\U0001f40d')) - self.assertFalse(xhasattr(obj, 'evil')) - self.assertFalse(xhasattr(obj, 1)) + with support.catch_unraisable_exception() as cm: + self.assertFalse(xhasattr(obj, 'evil')) + self.assertEqual(cm.unraisable.exc_type, RuntimeError) + self.assertEqual(str(cm.unraisable.exc_value), + 'do not get evil') + + with support.catch_unraisable_exception() as cm: + self.assertFalse(xhasattr(obj, 1)) + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + "attribute name must be string, not 'int'") + # CRASHES xhasattr(obj, NULL) # CRASHES xhasattr(NULL, 'a') @@ -121,8 +220,18 @@ def test_object_hasattrstring(self): self.assertFalse(hasattrstring(obj, b'b')) self.assertTrue(hasattrstring(obj, '\U0001f40d'.encode())) - self.assertFalse(hasattrstring(obj, b'evil')) - self.assertFalse(hasattrstring(obj, b'\xff')) + with support.catch_unraisable_exception() as cm: + self.assertFalse(hasattrstring(obj, b'evil')) + self.assertEqual(cm.unraisable.exc_type, RuntimeError) + self.assertEqual(str(cm.unraisable.exc_value), + 'do not get evil') + + with support.catch_unraisable_exception() as cm: + self.assertFalse(hasattrstring(obj, b'\xff')) + self.assertEqual(cm.unraisable.exc_type, UnicodeDecodeError) + self.assertRegex(str(cm.unraisable.exc_value), + "'utf-8' codec can't decode") + # CRASHES hasattrstring(obj, NULL) # CRASHES hasattrstring(NULL, b'a') @@ -340,12 +449,41 @@ def test_mapping_haskey(self): 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')) + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskey(42, 'a')) + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + "'int' object is not subscriptable") + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskey({}, [])) + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + "unhashable type: 'list'") + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskey([], 1)) + self.assertEqual(cm.unraisable.exc_type, IndexError) + self.assertEqual(str(cm.unraisable.exc_value), + 'list index out of range') + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskey([], 'a')) + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + 'list indices must be integers or slices, not str') + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskey({}, NULL)) + self.assertEqual(cm.unraisable.exc_type, SystemError) + self.assertEqual(str(cm.unraisable.exc_value), + 'null argument to internal routine') + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskey(NULL, 'a')) + self.assertEqual(cm.unraisable.exc_type, SystemError) + self.assertEqual(str(cm.unraisable.exc_value), + 'null argument to internal routine') def test_mapping_haskeystring(self): haskeystring = _testcapi.mapping_haskeystring @@ -358,11 +496,35 @@ def test_mapping_haskeystring(self): 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')) + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskeystring(42, b'a')) + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + "'int' object is not subscriptable") + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskeystring({}, b'\xff')) + self.assertEqual(cm.unraisable.exc_type, UnicodeDecodeError) + self.assertRegex(str(cm.unraisable.exc_value), + "'utf-8' codec can't decode") + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskeystring({}, NULL)) + self.assertEqual(cm.unraisable.exc_type, SystemError) + self.assertEqual(str(cm.unraisable.exc_value), + "null argument to internal routine") + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskeystring([], b'a')) + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + 'list indices must be integers or slices, not str') + + with support.catch_unraisable_exception() as cm: + self.assertFalse(haskeystring(NULL, b'a')) + self.assertEqual(cm.unraisable.exc_type, SystemError) + self.assertEqual(str(cm.unraisable.exc_value), + "null argument to internal routine") def test_mapping_haskeywitherror(self): haskey = _testcapi.mapping_haskeywitherror @@ -574,6 +736,8 @@ def test_sequence_getitem(self): self.assertEqual(getitem(lst, 1), 'b') self.assertEqual(getitem(lst, -1), 'c') self.assertRaises(IndexError, getitem, lst, 3) + self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MAX) + self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MIN) self.assertRaises(TypeError, getitem, 42, 1) self.assertRaises(TypeError, getitem, {}, 1) @@ -598,6 +762,9 @@ def test_sequence_repeat(self): self.assertEqual(repeat(('a', 'b'), 2), ('a', 'b', 'a', 'b')) self.assertEqual(repeat(['a', 'b'], 0), []) self.assertEqual(repeat(['a', 'b'], -1), []) + self.assertEqual(repeat(['a', 'b'], PY_SSIZE_T_MIN), []) + self.assertEqual(repeat([], PY_SSIZE_T_MAX), []) + self.assertRaises(MemoryError, repeat, ['a', 'b'], PY_SSIZE_T_MAX) self.assertRaises(TypeError, repeat, set(), 2) self.assertRaises(TypeError, repeat, 42, 2) @@ -631,6 +798,9 @@ def test_sequence_inplacerepeat(self): self.assertEqual(inplacerepeat(('a', 'b'), 2), ('a', 'b', 'a', 'b')) self.assertEqual(inplacerepeat(['a', 'b'], 0), []) self.assertEqual(inplacerepeat(['a', 'b'], -1), []) + self.assertEqual(inplacerepeat(['a', 'b'], PY_SSIZE_T_MIN), []) + self.assertEqual(inplacerepeat([], PY_SSIZE_T_MAX), []) + self.assertRaises(MemoryError, inplacerepeat, ['a', 'b'], PY_SSIZE_T_MAX) self.assertRaises(TypeError, inplacerepeat, set(), 2) self.assertRaises(TypeError, inplacerepeat, 42, 2) @@ -647,6 +817,8 @@ def test_sequence_setitem(self): setitem(lst, 0, NULL) self.assertEqual(lst, ['x', 'y']) self.assertRaises(IndexError, setitem, lst, 3, 'x') + self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MAX, 'x') + self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MIN, 'x') self.assertRaises(TypeError, setitem, 42, 1, 'x') self.assertRaises(TypeError, setitem, {}, 1, 'x') @@ -660,6 +832,8 @@ def test_sequence_delitem(self): delitem(lst, -1) self.assertEqual(lst, ['a']) self.assertRaises(IndexError, delitem, lst, 3) + self.assertRaises(IndexError, delitem, lst, PY_SSIZE_T_MAX) + self.assertRaises(IndexError, delitem, lst, PY_SSIZE_T_MIN) self.assertRaises(TypeError, delitem, 42, 1) self.assertRaises(TypeError, delitem, {}, 1) @@ -669,13 +843,19 @@ 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]) + for start in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]: + for stop in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]: + data = [1, 2, 3, 4, 5] + data_copy = [1, 2, 3, 4, 5] + setslice(data, start, stop, [8, 9]) + data_copy[start:stop] = [8, 9] + self.assertEqual(data, data_copy) + + data = [1, 2, 3, 4, 5] + data_copy = [1, 2, 3, 4, 5] + setslice(data, start, stop, NULL) + del data_copy[start:stop] + self.assertEqual(data, data_copy) # Custom class: class Custom: @@ -701,21 +881,17 @@ def __setitem__(self, index, value): 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]) + for start in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]: + for stop in [*range(-6, 7), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]: + data = [1, 2, 3, 4, 5] + data_copy = [1, 2, 3, 4, 5] + delslice(data, start, stop) + del data_copy[start:stop] + self.assertEqual(data, data_copy) # Custom class: class Custom: @@ -817,6 +993,13 @@ def test_sequence_tuple(self): self.assertRaises(TypeError, xtuple, 42) self.assertRaises(SystemError, xtuple, NULL) + def test_number_check(self): + number_check = _testcapi.number_check + self.assertTrue(number_check(1 + 1j)) + self.assertTrue(number_check(1)) + self.assertTrue(number_check(0.5)) + self.assertFalse(number_check("1 + 1j")) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_bytearray.py b/Lib/test/test_capi/test_bytearray.py new file mode 100644 index 00000000000000..833122c4e319d8 --- /dev/null +++ b/Lib/test/test_capi/test_bytearray.py @@ -0,0 +1,164 @@ +import unittest +from test.support import import_helper + +_testcapi = import_helper.import_module('_testcapi') +from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + +NULL = None + +class ByteArraySubclass(bytearray): + pass + +class BytesLike: + def __init__(self, value): + self.value = value + def __bytes__(self): + return self.value + + +class CAPITest(unittest.TestCase): + def test_check(self): + # Test PyByteArray_Check() + check = _testcapi.bytearray_check + self.assertTrue(check(bytearray(b'abc'))) + self.assertFalse(check(b'abc')) + self.assertTrue(check(ByteArraySubclass(b'abc'))) + self.assertFalse(check(BytesLike(b'abc'))) + self.assertFalse(check(3)) + self.assertFalse(check([])) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_checkexact(self): + # Test PyByteArray_CheckExact() + check = _testcapi.bytearray_checkexact + self.assertTrue(check(bytearray(b'abc'))) + self.assertFalse(check(b'abc')) + self.assertFalse(check(ByteArraySubclass(b'abc'))) + self.assertFalse(check(BytesLike(b'abc'))) + self.assertFalse(check(3)) + self.assertFalse(check([])) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_fromstringandsize(self): + # Test PyByteArray_FromStringAndSize() + fromstringandsize = _testcapi.bytearray_fromstringandsize + + self.assertEqual(fromstringandsize(b'abc'), bytearray(b'abc')) + self.assertEqual(fromstringandsize(b'abc', 2), bytearray(b'ab')) + self.assertEqual(fromstringandsize(b'abc\0def'), bytearray(b'abc\0def')) + self.assertEqual(fromstringandsize(b'', 0), bytearray()) + self.assertEqual(fromstringandsize(NULL, 0), bytearray()) + self.assertEqual(len(fromstringandsize(NULL, 3)), 3) + self.assertRaises(MemoryError, fromstringandsize, NULL, PY_SSIZE_T_MAX) + + self.assertRaises(SystemError, fromstringandsize, b'abc', -1) + self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN) + self.assertRaises(SystemError, fromstringandsize, NULL, -1) + self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN) + + def test_fromobject(self): + # Test PyByteArray_FromObject() + fromobject = _testcapi.bytearray_fromobject + + self.assertEqual(fromobject(b'abc'), bytearray(b'abc')) + self.assertEqual(fromobject(bytearray(b'abc')), bytearray(b'abc')) + self.assertEqual(fromobject(ByteArraySubclass(b'abc')), bytearray(b'abc')) + self.assertEqual(fromobject([97, 98, 99]), bytearray(b'abc')) + self.assertEqual(fromobject(3), bytearray(b'\0\0\0')) + self.assertRaises(TypeError, fromobject, BytesLike(b'abc')) + self.assertRaises(TypeError, fromobject, 'abc') + self.assertRaises(TypeError, fromobject, object()) + + # CRASHES fromobject(NULL) + + def test_size(self): + # Test PyByteArray_Size() + size = _testcapi.bytearray_size + + self.assertEqual(size(bytearray(b'abc')), 3) + self.assertEqual(size(ByteArraySubclass(b'abc')), 3) + + # CRASHES size(b'abc') + # CRASHES size(object()) + # CRASHES size(NULL) + + def test_asstring(self): + """Test PyByteArray_AsString()""" + asstring = _testcapi.bytearray_asstring + + self.assertEqual(asstring(bytearray(b'abc'), 4), b'abc\0') + self.assertEqual(asstring(ByteArraySubclass(b'abc'), 4), b'abc\0') + self.assertEqual(asstring(bytearray(b'abc\0def'), 8), b'abc\0def\0') + + # CRASHES asstring(b'abc', 0) + # CRASHES asstring(object()', 0) + # CRASHES asstring(NULL, 0) + + def test_concat(self): + """Test PyByteArray_Concat()""" + concat = _testcapi.bytearray_concat + + ba = bytearray(b'abc') + self.assertEqual(concat(ba, b'def'), bytearray(b'abcdef')) + self.assertEqual(ba, b'abc') + + self.assertEqual(concat(b'abc', b'def'), bytearray(b'abcdef')) + self.assertEqual(concat(b'a\0b', b'c\0d'), bytearray(b'a\0bc\0d')) + self.assertEqual(concat(bytearray(b'abc'), b'def'), bytearray(b'abcdef')) + self.assertEqual(concat(b'abc', bytearray(b'def')), bytearray(b'abcdef')) + self.assertEqual(concat(bytearray(b'abc'), b''), bytearray(b'abc')) + self.assertEqual(concat(b'', bytearray(b'def')), bytearray(b'def')) + self.assertEqual(concat(memoryview(b'xabcy')[1:4], b'def'), + bytearray(b'abcdef')) + self.assertEqual(concat(b'abc', memoryview(b'xdefy')[1:4]), + bytearray(b'abcdef')) + + self.assertRaises(TypeError, concat, memoryview(b'axbycz')[::2], b'def') + self.assertRaises(TypeError, concat, b'abc', memoryview(b'dxeyfz')[::2]) + self.assertRaises(TypeError, concat, b'abc', 'def') + self.assertRaises(TypeError, concat, 'abc', b'def') + self.assertRaises(TypeError, concat, 'abc', 'def') + self.assertRaises(TypeError, concat, [], b'def') + self.assertRaises(TypeError, concat, b'abc', []) + self.assertRaises(TypeError, concat, [], []) + + # CRASHES concat(NULL, bytearray(b'def')) + # CRASHES concat(bytearray(b'abc'), NULL) + # CRASHES concat(NULL, object()) + # CRASHES concat(object(), NULL) + + def test_resize(self): + """Test PyByteArray_Resize()""" + resize = _testcapi.bytearray_resize + + ba = bytearray(b'abcdef') + self.assertEqual(resize(ba, 3), 0) + self.assertEqual(ba, bytearray(b'abc')) + self.assertEqual(resize(ba, 10), 0) + self.assertEqual(len(ba), 10) + self.assertEqual(ba[:3], bytearray(b'abc')) + self.assertEqual(resize(ba, 2**20), 0) + self.assertEqual(len(ba), 2**20) + self.assertEqual(ba[:3], bytearray(b'abc')) + self.assertEqual(resize(ba, 0), 0) + self.assertEqual(ba, bytearray()) + + ba = ByteArraySubclass(b'abcdef') + self.assertEqual(resize(ba, 3), 0) + self.assertEqual(ba, bytearray(b'abc')) + + self.assertRaises(MemoryError, resize, bytearray(), PY_SSIZE_T_MAX) + self.assertRaises(MemoryError, resize, bytearray(1000), PY_SSIZE_T_MAX) + + # CRASHES resize(bytearray(b'abc'), -1) + # CRASHES resize(b'abc', 0) + # CRASHES resize(object(), 0) + # CRASHES resize(NULL, 0) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_bytes.py b/Lib/test/test_capi/test_bytes.py new file mode 100644 index 00000000000000..bb5d724ff187d4 --- /dev/null +++ b/Lib/test/test_capi/test_bytes.py @@ -0,0 +1,222 @@ +import unittest +from test.support import import_helper + +_testcapi = import_helper.import_module('_testcapi') +from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + +NULL = None + +class BytesSubclass(bytes): + pass + +class BytesLike: + def __init__(self, value): + self.value = value + def __bytes__(self): + return self.value + + +class CAPITest(unittest.TestCase): + def test_check(self): + # Test PyBytes_Check() + check = _testcapi.bytes_check + self.assertTrue(check(b'abc')) + self.assertFalse(check('abc')) + self.assertFalse(check(bytearray(b'abc'))) + self.assertTrue(check(BytesSubclass(b'abc'))) + self.assertFalse(check(BytesLike(b'abc'))) + self.assertFalse(check(3)) + self.assertFalse(check([])) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_checkexact(self): + # Test PyBytes_CheckExact() + check = _testcapi.bytes_checkexact + self.assertTrue(check(b'abc')) + self.assertFalse(check('abc')) + self.assertFalse(check(bytearray(b'abc'))) + self.assertFalse(check(BytesSubclass(b'abc'))) + self.assertFalse(check(BytesLike(b'abc'))) + self.assertFalse(check(3)) + self.assertFalse(check([])) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_fromstringandsize(self): + # Test PyBytes_FromStringAndSize() + fromstringandsize = _testcapi.bytes_fromstringandsize + + self.assertEqual(fromstringandsize(b'abc'), b'abc') + self.assertEqual(fromstringandsize(b'abc', 2), b'ab') + self.assertEqual(fromstringandsize(b'abc\0def'), b'abc\0def') + self.assertEqual(fromstringandsize(b'', 0), b'') + self.assertEqual(fromstringandsize(NULL, 0), b'') + self.assertEqual(len(fromstringandsize(NULL, 3)), 3) + self.assertRaises((MemoryError, OverflowError), + fromstringandsize, NULL, PY_SSIZE_T_MAX) + + self.assertRaises(SystemError, fromstringandsize, b'abc', -1) + self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN) + self.assertRaises(SystemError, fromstringandsize, NULL, -1) + self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN) + + def test_fromstring(self): + # Test PyBytes_FromString() + fromstring = _testcapi.bytes_fromstring + + self.assertEqual(fromstring(b'abc\0def'), b'abc') + self.assertEqual(fromstring(b''), b'') + + # CRASHES fromstring(NULL) + + def test_fromobject(self): + # Test PyBytes_FromObject() + fromobject = _testcapi.bytes_fromobject + + self.assertEqual(fromobject(b'abc'), b'abc') + self.assertEqual(fromobject(bytearray(b'abc')), b'abc') + self.assertEqual(fromobject(BytesSubclass(b'abc')), b'abc') + self.assertEqual(fromobject([97, 98, 99]), b'abc') + self.assertRaises(TypeError, fromobject, 3) + self.assertRaises(TypeError, fromobject, BytesLike(b'abc')) + self.assertRaises(TypeError, fromobject, 'abc') + self.assertRaises(TypeError, fromobject, object()) + self.assertRaises(SystemError, fromobject, NULL) + + def test_size(self): + # Test PyBytes_Size() + size = _testcapi.bytes_size + + self.assertEqual(size(b'abc'), 3) + self.assertEqual(size(BytesSubclass(b'abc')), 3) + self.assertRaises(TypeError, size, bytearray(b'abc')) + self.assertRaises(TypeError, size, 'abc') + self.assertRaises(TypeError, size, object()) + + # CRASHES size(NULL) + + def test_asstring(self): + """Test PyBytes_AsString()""" + asstring = _testcapi.bytes_asstring + + self.assertEqual(asstring(b'abc', 4), b'abc\0') + self.assertEqual(asstring(b'abc\0def', 8), b'abc\0def\0') + self.assertRaises(TypeError, asstring, 'abc', 0) + self.assertRaises(TypeError, asstring, object(), 0) + + # CRASHES asstring(NULL, 0) + + def test_asstringandsize(self): + """Test PyBytes_AsStringAndSize()""" + asstringandsize = _testcapi.bytes_asstringandsize + asstringandsize_null = _testcapi.bytes_asstringandsize_null + + self.assertEqual(asstringandsize(b'abc', 4), (b'abc\0', 3)) + self.assertEqual(asstringandsize(b'abc\0def', 8), (b'abc\0def\0', 7)) + self.assertEqual(asstringandsize_null(b'abc', 4), b'abc\0') + self.assertRaises(ValueError, asstringandsize_null, b'abc\0def', 8) + self.assertRaises(TypeError, asstringandsize, 'abc', 0) + self.assertRaises(TypeError, asstringandsize_null, 'abc', 0) + self.assertRaises(TypeError, asstringandsize, object(), 0) + self.assertRaises(TypeError, asstringandsize_null, object(), 0) + + # CRASHES asstringandsize(NULL, 0) + # CRASHES asstringandsize_null(NULL, 0) + + def test_repr(self): + # Test PyBytes_Repr() + bytes_repr = _testcapi.bytes_repr + + self.assertEqual(bytes_repr(b'''abc''', 0), r"""b'abc'""") + self.assertEqual(bytes_repr(b'''abc''', 1), r"""b'abc'""") + self.assertEqual(bytes_repr(b'''a'b"c"d''', 0), r"""b'a\'b"c"d'""") + self.assertEqual(bytes_repr(b'''a'b"c"d''', 1), r"""b'a\'b"c"d'""") + self.assertEqual(bytes_repr(b'''a'b"c''', 0), r"""b'a\'b"c'""") + self.assertEqual(bytes_repr(b'''a'b"c''', 1), r"""b'a\'b"c'""") + self.assertEqual(bytes_repr(b'''a'b'c"d''', 0), r"""b'a\'b\'c"d'""") + self.assertEqual(bytes_repr(b'''a'b'c"d''', 1), r"""b'a\'b\'c"d'""") + self.assertEqual(bytes_repr(b'''a'b'c'd''', 0), r"""b'a\'b\'c\'d'""") + self.assertEqual(bytes_repr(b'''a'b'c'd''', 1), r'''b"a'b'c'd"''') + + self.assertEqual(bytes_repr(BytesSubclass(b'abc'), 0), r"""b'abc'""") + + # UDEFINED bytes_repr(object(), 0) + # CRASHES bytes_repr(NULL, 0) + + def test_concat(self, concat=None): + """Test PyBytes_Concat()""" + if concat is None: + concat = _testcapi.bytes_concat + + self.assertEqual(concat(b'abc', b'def'), b'abcdef') + self.assertEqual(concat(b'a\0b', b'c\0d'), b'a\0bc\0d') + self.assertEqual(concat(bytearray(b'abc'), b'def'), b'abcdef') + self.assertEqual(concat(b'abc', bytearray(b'def')), b'abcdef') + self.assertEqual(concat(bytearray(b'abc'), b''), b'abc') + self.assertEqual(concat(b'', bytearray(b'def')), b'def') + self.assertEqual(concat(memoryview(b'xabcy')[1:4], b'def'), b'abcdef') + self.assertEqual(concat(b'abc', memoryview(b'xdefy')[1:4]), b'abcdef') + + self.assertEqual(concat(b'abc', b'def', True), b'abcdef') + self.assertEqual(concat(b'abc', bytearray(b'def'), True), b'abcdef') + # Check that it does not change the singleton + self.assertEqual(concat(bytes(), b'def', True), b'def') + self.assertEqual(len(bytes()), 0) + + self.assertRaises(TypeError, concat, memoryview(b'axbycz')[::2], b'def') + self.assertRaises(TypeError, concat, b'abc', memoryview(b'dxeyfz')[::2]) + self.assertRaises(TypeError, concat, b'abc', 'def') + self.assertRaises(TypeError, concat, 'abc', b'def') + self.assertRaises(TypeError, concat, 'abc', 'def') + self.assertRaises(TypeError, concat, [], b'def') + self.assertRaises(TypeError, concat, b'abc', []) + self.assertRaises(TypeError, concat, [], []) + + self.assertEqual(concat(NULL, b'def'), NULL) + self.assertEqual(concat(b'abc', NULL), NULL) + self.assertEqual(concat(NULL, object()), NULL) + self.assertEqual(concat(object(), NULL), NULL) + + def test_concatanddel(self): + """Test PyBytes_ConcatAndDel()""" + self.test_concat(_testcapi.bytes_concatanddel) + + def test_decodeescape(self): + """Test PyBytes_DecodeEscape()""" + decodeescape = _testcapi.bytes_decodeescape + + self.assertEqual(decodeescape(b'abc'), b'abc') + self.assertEqual(decodeescape(br'\t\n\r\x0b\x0c\x00\\\'\"'), + b'''\t\n\r\v\f\0\\'"''') + self.assertEqual(decodeescape(b'\t\n\r\x0b\x0c\x00'), b'\t\n\r\v\f\0') + self.assertEqual(decodeescape(br'\xa1\xa2'), b'\xa1\xa2') + self.assertEqual(decodeescape(br'\2\24\241'), b'\x02\x14\xa1') + self.assertEqual(decodeescape(b'\xa1\xa2'), b'\xa1\xa2') + with self.assertWarns(DeprecationWarning): + self.assertEqual(decodeescape(br'\u4f60'), br'\u4f60') + with self.assertWarns(DeprecationWarning): + self.assertEqual(decodeescape(br'\z'), br'\z') + with self.assertWarns(DeprecationWarning): + self.assertEqual(decodeescape(br'\541'), b'a') + + for b in b'\\', br'\x', br'\xa', br'\xz', br'\xaz': + self.assertRaises(ValueError, decodeescape, b) + self.assertRaises(ValueError, decodeescape, b, 'strict') + self.assertEqual(decodeescape(br'x\xa', 'replace'), b'x?') + self.assertEqual(decodeescape(br'x\xay', 'replace'), b'x?y') + self.assertEqual(decodeescape(br'x\xa\xy', 'replace'), b'x??y') + self.assertEqual(decodeescape(br'x\xa\xy', 'ignore'), b'xy') + self.assertRaises(ValueError, decodeescape, b'\\', 'spam') + self.assertEqual(decodeescape(NULL), b'') + self.assertRaises(OverflowError, decodeescape, b'abc', NULL, PY_SSIZE_T_MAX) + self.assertRaises(OverflowError, decodeescape, NULL, NULL, PY_SSIZE_T_MAX) + + # CRASHES decodeescape(b'abc', NULL, -1) + # CRASHES decodeescape(NULL, NULL, 1) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_complex.py b/Lib/test/test_capi/test_complex.py new file mode 100644 index 00000000000000..d6fc1f077c40aa --- /dev/null +++ b/Lib/test/test_capi/test_complex.py @@ -0,0 +1,233 @@ +from math import isnan +import errno +import unittest +import warnings + +from test.test_capi.test_getargs import (BadComplex, BadComplex2, Complex, + FloatSubclass, Float, BadFloat, + BadFloat2, ComplexSubclass) +from test.support import import_helper + + +_testcapi = import_helper.import_module('_testcapi') + +NULL = None +INF = float("inf") +NAN = float("nan") +DBL_MAX = _testcapi.DBL_MAX + + +class BadComplex3: + def __complex__(self): + raise RuntimeError + + +class CAPIComplexTest(unittest.TestCase): + def test_check(self): + # Test PyComplex_Check() + check = _testcapi.complex_check + + self.assertTrue(check(1+2j)) + self.assertTrue(check(ComplexSubclass(1+2j))) + self.assertFalse(check(Complex())) + self.assertFalse(check(3)) + self.assertFalse(check(3.0)) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_checkexact(self): + # PyComplex_CheckExact() + checkexact = _testcapi.complex_checkexact + + self.assertTrue(checkexact(1+2j)) + self.assertFalse(checkexact(ComplexSubclass(1+2j))) + self.assertFalse(checkexact(Complex())) + self.assertFalse(checkexact(3)) + self.assertFalse(checkexact(3.0)) + self.assertFalse(checkexact(object())) + + # CRASHES checkexact(NULL) + + def test_fromccomplex(self): + # Test PyComplex_FromCComplex() + fromccomplex = _testcapi.complex_fromccomplex + + self.assertEqual(fromccomplex(1+2j), 1.0+2.0j) + + def test_fromdoubles(self): + # Test PyComplex_FromDoubles() + fromdoubles = _testcapi.complex_fromdoubles + + self.assertEqual(fromdoubles(1.0, 2.0), 1.0+2.0j) + + def test_realasdouble(self): + # Test PyComplex_RealAsDouble() + realasdouble = _testcapi.complex_realasdouble + + self.assertEqual(realasdouble(1+2j), 1.0) + self.assertEqual(realasdouble(-1+0j), -1.0) + self.assertEqual(realasdouble(4.25), 4.25) + self.assertEqual(realasdouble(-1.0), -1.0) + self.assertEqual(realasdouble(42), 42.) + self.assertEqual(realasdouble(-1), -1.0) + + # Test subclasses of complex/float + self.assertEqual(realasdouble(ComplexSubclass(1+2j)), 1.0) + self.assertEqual(realasdouble(FloatSubclass(4.25)), 4.25) + + # Test types with __complex__ dunder method + # Function doesn't support classes with __complex__ dunder, see #109598 + self.assertRaises(TypeError, realasdouble, Complex()) + + # Test types with __float__ dunder method + self.assertEqual(realasdouble(Float()), 4.25) + self.assertRaises(TypeError, realasdouble, BadFloat()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(realasdouble(BadFloat2()), 4.25) + + self.assertRaises(TypeError, realasdouble, object()) + + # CRASHES realasdouble(NULL) + + def test_imagasdouble(self): + # Test PyComplex_ImagAsDouble() + imagasdouble = _testcapi.complex_imagasdouble + + self.assertEqual(imagasdouble(1+2j), 2.0) + self.assertEqual(imagasdouble(1-1j), -1.0) + self.assertEqual(imagasdouble(4.25), 0.0) + self.assertEqual(imagasdouble(42), 0.0) + + # Test subclasses of complex/float + self.assertEqual(imagasdouble(ComplexSubclass(1+2j)), 2.0) + self.assertEqual(imagasdouble(FloatSubclass(4.25)), 0.0) + + # Test types with __complex__ dunder method + # Function doesn't support classes with __complex__ dunder, see #109598 + self.assertEqual(imagasdouble(Complex()), 0.0) + + # Function returns 0.0 anyway, see #109598 + self.assertEqual(imagasdouble(object()), 0.0) + + # CRASHES imagasdouble(NULL) + + def test_asccomplex(self): + # Test PyComplex_AsCComplex() + asccomplex = _testcapi.complex_asccomplex + + self.assertEqual(asccomplex(1+2j), 1.0+2.0j) + self.assertEqual(asccomplex(-1+2j), -1.0+2.0j) + self.assertEqual(asccomplex(4.25), 4.25+0.0j) + self.assertEqual(asccomplex(-1.0), -1.0+0.0j) + self.assertEqual(asccomplex(42), 42+0j) + self.assertEqual(asccomplex(-1), -1.0+0.0j) + + # Test subclasses of complex/float + self.assertEqual(asccomplex(ComplexSubclass(1+2j)), 1.0+2.0j) + self.assertEqual(asccomplex(FloatSubclass(4.25)), 4.25+0.0j) + + # Test types with __complex__ dunder method + self.assertEqual(asccomplex(Complex()), 4.25+0.5j) + self.assertRaises(TypeError, asccomplex, BadComplex()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(asccomplex(BadComplex2()), 4.25+0.5j) + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + self.assertRaises(DeprecationWarning, asccomplex, BadComplex2()) + self.assertRaises(RuntimeError, asccomplex, BadComplex3()) + + # Test types with __float__ dunder method + self.assertEqual(asccomplex(Float()), 4.25+0.0j) + self.assertRaises(TypeError, asccomplex, BadFloat()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(asccomplex(BadFloat2()), 4.25+0.0j) + + self.assertRaises(TypeError, asccomplex, object()) + + # CRASHES asccomplex(NULL) + + def test_py_c_sum(self): + # Test _Py_c_sum() + _py_c_sum = _testcapi._py_c_sum + + self.assertEqual(_py_c_sum(1, 1j), (1+1j, 0)) + + def test_py_c_diff(self): + # Test _Py_c_diff() + _py_c_diff = _testcapi._py_c_diff + + self.assertEqual(_py_c_diff(1, 1j), (1-1j, 0)) + + def test_py_c_neg(self): + # Test _Py_c_neg() + _py_c_neg = _testcapi._py_c_neg + + self.assertEqual(_py_c_neg(1+1j), -1-1j) + + def test_py_c_prod(self): + # Test _Py_c_prod() + _py_c_prod = _testcapi._py_c_prod + + self.assertEqual(_py_c_prod(2, 1j), (2j, 0)) + + def test_py_c_quot(self): + # Test _Py_c_quot() + _py_c_quot = _testcapi._py_c_quot + + self.assertEqual(_py_c_quot(1, 1j), (-1j, 0)) + self.assertEqual(_py_c_quot(1, -1j), (1j, 0)) + self.assertEqual(_py_c_quot(1j, 2), (0.5j, 0)) + self.assertEqual(_py_c_quot(1j, -2), (-0.5j, 0)) + self.assertEqual(_py_c_quot(1, 2j), (-0.5j, 0)) + + z, e = _py_c_quot(NAN, 1j) + self.assertTrue(isnan(z.real)) + self.assertTrue(isnan(z.imag)) + self.assertEqual(e, 0) + + z, e = _py_c_quot(1j, NAN) + self.assertTrue(isnan(z.real)) + self.assertTrue(isnan(z.imag)) + self.assertEqual(e, 0) + + self.assertEqual(_py_c_quot(1, 0j)[1], errno.EDOM) + + def test_py_c_pow(self): + # Test _Py_c_pow() + _py_c_pow = _testcapi._py_c_pow + + self.assertEqual(_py_c_pow(1j, 0j), (1+0j, 0)) + self.assertEqual(_py_c_pow(1, 1j), (1+0j, 0)) + self.assertEqual(_py_c_pow(0j, 1), (0j, 0)) + self.assertAlmostEqual(_py_c_pow(1j, 2)[0], -1.0+0j) + + r, e = _py_c_pow(1+1j, -1) + self.assertAlmostEqual(r, 0.5-0.5j) + self.assertEqual(e, 0) + + self.assertEqual(_py_c_pow(0j, -1)[1], errno.EDOM) + self.assertEqual(_py_c_pow(0j, 1j)[1], errno.EDOM) + self.assertEqual(_py_c_pow(*[DBL_MAX+1j]*2)[0], complex(*[INF]*2)) + + + def test_py_c_abs(self): + # Test _Py_c_abs() + _py_c_abs = _testcapi._py_c_abs + + self.assertEqual(_py_c_abs(-1), (1.0, 0)) + self.assertEqual(_py_c_abs(1j), (1.0, 0)) + + self.assertEqual(_py_c_abs(complex('+inf+1j')), (INF, 0)) + self.assertEqual(_py_c_abs(complex('-inf+1j')), (INF, 0)) + self.assertEqual(_py_c_abs(complex('1.25+infj')), (INF, 0)) + self.assertEqual(_py_c_abs(complex('1.25-infj')), (INF, 0)) + + self.assertTrue(isnan(_py_c_abs(complex('1.25+nanj'))[0])) + self.assertTrue(isnan(_py_c_abs(complex('nan-1j'))[0])) + + self.assertEqual(_py_c_abs(complex(*[DBL_MAX]*2))[1], errno.ERANGE) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py index 11b2ca910707df..57a7238588eae0 100644 --- a/Lib/test/test_capi/test_dict.py +++ b/Lib/test/test_capi/test_dict.py @@ -1,6 +1,7 @@ import unittest from collections import OrderedDict, UserDict from types import MappingProxyType +from test import support import _testcapi @@ -30,7 +31,7 @@ def test_dict_check(self): self.assertFalse(check(UserDict({1: 2}))) self.assertFalse(check([1, 2])) self.assertFalse(check(object())) - #self.assertFalse(check(NULL)) + # CRASHES check(NULL) def test_dict_checkexact(self): check = _testcapi.dict_checkexact @@ -39,7 +40,7 @@ def test_dict_checkexact(self): self.assertFalse(check(UserDict({1: 2}))) self.assertFalse(check([1, 2])) self.assertFalse(check(object())) - #self.assertFalse(check(NULL)) + # CRASHES check(NULL) def test_dict_new(self): dict_new = _testcapi.dict_new @@ -118,7 +119,12 @@ def test_dict_getitem(self): self.assertEqual(getitem(dct2, 'a'), 1) self.assertIs(getitem(dct2, 'b'), KeyError) - self.assertIs(getitem({}, []), KeyError) # unhashable + with support.catch_unraisable_exception() as cm: + self.assertIs(getitem({}, []), KeyError) # unhashable + self.assertEqual(cm.unraisable.exc_type, TypeError) + self.assertEqual(str(cm.unraisable.exc_value), + "unhashable type: 'list'") + self.assertIs(getitem(42, 'a'), KeyError) self.assertIs(getitem([1], 0), KeyError) # CRASHES getitem({}, NULL) @@ -135,7 +141,12 @@ def test_dict_getitemstring(self): self.assertEqual(getitemstring(dct2, b'a'), 1) self.assertIs(getitemstring(dct2, b'b'), KeyError) - self.assertIs(getitemstring({}, INVALID_UTF8), KeyError) + with support.catch_unraisable_exception() as cm: + self.assertIs(getitemstring({}, INVALID_UTF8), KeyError) + self.assertEqual(cm.unraisable.exc_type, UnicodeDecodeError) + self.assertRegex(str(cm.unraisable.exc_value), + "'utf-8' codec can't decode") + self.assertIs(getitemstring(42, b'a'), KeyError) self.assertIs(getitemstring([], b'a'), KeyError) # CRASHES getitemstring({}, NULL) @@ -421,6 +432,93 @@ def test_dict_mergefromseq2(self): # CRASHES mergefromseq2({}, NULL, 0) # CRASHES mergefromseq2(NULL, {}, 0) + def test_dict_pop(self): + # Test PyDict_Pop() + dict_pop = _testcapi.dict_pop + dict_pop_null = _testcapi.dict_pop_null + + # key present, get removed value + mydict = {"key": "value", "key2": "value2"} + self.assertEqual(dict_pop(mydict, "key"), (1, "value")) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_pop(mydict, "key2"), (1, "value2")) + self.assertEqual(mydict, {}) + + # key present, ignore removed value + mydict = {"key": "value", "key2": "value2"} + self.assertEqual(dict_pop_null(mydict, "key"), 1) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_pop_null(mydict, "key2"), 1) + self.assertEqual(mydict, {}) + + # key missing, expect removed value; empty dict has a fast path + self.assertEqual(dict_pop({}, "key"), (0, NULL)) + self.assertEqual(dict_pop({"a": 1}, "key"), (0, NULL)) + + # key missing, ignored removed value; empty dict has a fast path + self.assertEqual(dict_pop_null({}, "key"), 0) + self.assertEqual(dict_pop_null({"a": 1}, "key"), 0) + + # dict error + not_dict = UserDict({1: 2}) + self.assertRaises(SystemError, dict_pop, not_dict, "key") + self.assertRaises(SystemError, dict_pop_null, not_dict, "key") + + # key error; don't hash key if dict is empty + not_hashable_key = ["list"] + self.assertEqual(dict_pop({}, not_hashable_key), (0, NULL)) + with self.assertRaises(TypeError): + dict_pop({'key': 1}, not_hashable_key) + dict_pop({}, NULL) # key is not checked if dict is empty + + # CRASHES dict_pop(NULL, "key") + # CRASHES dict_pop({"a": 1}, NULL) + + def test_dict_popstring(self): + # Test PyDict_PopString() + dict_popstring = _testcapi.dict_popstring + dict_popstring_null = _testcapi.dict_popstring_null + + # key present, get removed value + mydict = {"key": "value", "key2": "value2"} + self.assertEqual(dict_popstring(mydict, "key"), (1, "value")) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_popstring(mydict, "key2"), (1, "value2")) + self.assertEqual(mydict, {}) + + # key present, ignore removed value + mydict = {"key": "value", "key2": "value2"} + self.assertEqual(dict_popstring_null(mydict, "key"), 1) + self.assertEqual(mydict, {"key2": "value2"}) + self.assertEqual(dict_popstring_null(mydict, "key2"), 1) + self.assertEqual(mydict, {}) + + # key missing; empty dict has a fast path + self.assertEqual(dict_popstring({}, "key"), (0, NULL)) + self.assertEqual(dict_popstring_null({}, "key"), 0) + self.assertEqual(dict_popstring({"a": 1}, "key"), (0, NULL)) + self.assertEqual(dict_popstring_null({"a": 1}, "key"), 0) + + # non-ASCII key + non_ascii = '\U0001f40d' + dct = {'\U0001f40d': 123} + self.assertEqual(dict_popstring(dct, '\U0001f40d'.encode()), (1, 123)) + dct = {'\U0001f40d': 123} + self.assertEqual(dict_popstring_null(dct, '\U0001f40d'.encode()), 1) + + # dict error + not_dict = UserDict({1: 2}) + self.assertRaises(SystemError, dict_popstring, not_dict, "key") + self.assertRaises(SystemError, dict_popstring_null, not_dict, "key") + + # key error + self.assertRaises(UnicodeDecodeError, dict_popstring, {1: 2}, INVALID_UTF8) + self.assertRaises(UnicodeDecodeError, dict_popstring_null, {1: 2}, INVALID_UTF8) + + # CRASHES dict_popstring(NULL, "key") + # CRASHES dict_popstring({}, NULL) + # CRASHES dict_popstring({"a": 1}, NULL) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_exceptions.py b/Lib/test/test_capi/test_exceptions.py index b96cc7922a0ee7..1d158e3586e98d 100644 --- a/Lib/test/test_capi/test_exceptions.py +++ b/Lib/test/test_capi/test_exceptions.py @@ -17,6 +17,10 @@ NULL = None +class CustomError(Exception): + pass + + class Test_Exceptions(unittest.TestCase): def test_exception(self): @@ -270,6 +274,104 @@ def test_setfromerrnowithfilename(self): (ENOENT, 'No such file or directory', 'file')) # CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error') + def test_err_writeunraisable(self): + # Test PyErr_WriteUnraisable() + writeunraisable = _testcapi.err_writeunraisable + firstline = self.test_err_writeunraisable.__code__.co_firstlineno + + with support.catch_unraisable_exception() as cm: + writeunraisable(CustomError('oops!'), hex) + self.assertEqual(cm.unraisable.exc_type, CustomError) + self.assertEqual(str(cm.unraisable.exc_value), 'oops!') + self.assertEqual(cm.unraisable.exc_traceback.tb_lineno, + firstline + 6) + self.assertIsNone(cm.unraisable.err_msg) + self.assertEqual(cm.unraisable.object, hex) + + with support.catch_unraisable_exception() as cm: + writeunraisable(CustomError('oops!'), NULL) + self.assertEqual(cm.unraisable.exc_type, CustomError) + self.assertEqual(str(cm.unraisable.exc_value), 'oops!') + self.assertEqual(cm.unraisable.exc_traceback.tb_lineno, + firstline + 15) + self.assertIsNone(cm.unraisable.err_msg) + self.assertIsNone(cm.unraisable.object) + + with (support.swap_attr(sys, 'unraisablehook', None), + support.captured_stderr() as stderr): + writeunraisable(CustomError('oops!'), hex) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], f'Exception ignored in: {hex!r}') + self.assertEqual(lines[1], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!') + + with (support.swap_attr(sys, 'unraisablehook', None), + support.captured_stderr() as stderr): + writeunraisable(CustomError('oops!'), NULL) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!') + + # CRASHES writeunraisable(NULL, hex) + # CRASHES writeunraisable(NULL, NULL) + + def test_err_formatunraisable(self): + # Test PyErr_FormatUnraisable() + formatunraisable = _testcapi.err_formatunraisable + firstline = self.test_err_formatunraisable.__code__.co_firstlineno + + with support.catch_unraisable_exception() as cm: + formatunraisable(CustomError('oops!'), b'Error in %R', []) + self.assertEqual(cm.unraisable.exc_type, CustomError) + self.assertEqual(str(cm.unraisable.exc_value), 'oops!') + self.assertEqual(cm.unraisable.exc_traceback.tb_lineno, + firstline + 6) + self.assertEqual(cm.unraisable.err_msg, 'Error in []') + self.assertIsNone(cm.unraisable.object) + + with support.catch_unraisable_exception() as cm: + formatunraisable(CustomError('oops!'), b'undecodable \xff') + self.assertEqual(cm.unraisable.exc_type, CustomError) + self.assertEqual(str(cm.unraisable.exc_value), 'oops!') + self.assertEqual(cm.unraisable.exc_traceback.tb_lineno, + firstline + 15) + self.assertIsNone(cm.unraisable.err_msg) + self.assertIsNone(cm.unraisable.object) + + with support.catch_unraisable_exception() as cm: + formatunraisable(CustomError('oops!'), NULL) + self.assertEqual(cm.unraisable.exc_type, CustomError) + self.assertEqual(str(cm.unraisable.exc_value), 'oops!') + self.assertEqual(cm.unraisable.exc_traceback.tb_lineno, + firstline + 24) + self.assertIsNone(cm.unraisable.err_msg) + self.assertIsNone(cm.unraisable.object) + + with (support.swap_attr(sys, 'unraisablehook', None), + support.captured_stderr() as stderr): + formatunraisable(CustomError('oops!'), b'Error in %R', []) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], f'Error in []:') + self.assertEqual(lines[1], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!') + + with (support.swap_attr(sys, 'unraisablehook', None), + support.captured_stderr() as stderr): + formatunraisable(CustomError('oops!'), b'undecodable \xff') + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!') + + with (support.swap_attr(sys, 'unraisablehook', None), + support.captured_stderr() as stderr): + formatunraisable(CustomError('oops!'), NULL) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!') + + # CRASHES formatunraisable(NULL, b'Error in %R', []) + # CRASHES formatunraisable(NULL, NULL) + class Test_PyUnstable_Exc_PrepReraiseStar(ExceptionIsLikeMixin, unittest.TestCase): diff --git a/Lib/test/test_capi/test_float.py b/Lib/test/test_capi/test_float.py new file mode 100644 index 00000000000000..cb94d562645916 --- /dev/null +++ b/Lib/test/test_capi/test_float.py @@ -0,0 +1,182 @@ +import math +import sys +import unittest +import warnings + +from test.test_capi.test_getargs import (Float, FloatSubclass, FloatSubclass2, + BadIndex2, BadFloat2, Index, BadIndex, + BadFloat) +from test.support import import_helper + +_testcapi = import_helper.import_module('_testcapi') + +NULL = None + +# For PyFloat_Pack/Unpack* +BIG_ENDIAN = 0 +LITTLE_ENDIAN = 1 +EPSILON = { + 2: 2.0 ** -11, # binary16 + 4: 2.0 ** -24, # binary32 + 8: 2.0 ** -53, # binary64 +} + +HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE") +INF = float("inf") +NAN = float("nan") + + +class CAPIFloatTest(unittest.TestCase): + def test_check(self): + # Test PyFloat_Check() + check = _testcapi.float_check + + self.assertTrue(check(4.25)) + self.assertTrue(check(FloatSubclass(4.25))) + self.assertFalse(check(Float())) + self.assertFalse(check(3)) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_checkexact(self): + # Test PyFloat_CheckExact() + checkexact = _testcapi.float_checkexact + + self.assertTrue(checkexact(4.25)) + self.assertFalse(checkexact(FloatSubclass(4.25))) + self.assertFalse(checkexact(Float())) + self.assertFalse(checkexact(3)) + self.assertFalse(checkexact(object())) + + # CRASHES checkexact(NULL) + + def test_fromstring(self): + # Test PyFloat_FromString() + fromstring = _testcapi.float_fromstring + + self.assertEqual(fromstring("4.25"), 4.25) + self.assertEqual(fromstring(b"4.25"), 4.25) + self.assertRaises(ValueError, fromstring, "4.25\0") + self.assertRaises(ValueError, fromstring, b"4.25\0") + + self.assertEqual(fromstring(bytearray(b"4.25")), 4.25) + + self.assertEqual(fromstring(memoryview(b"4.25")), 4.25) + self.assertEqual(fromstring(memoryview(b"4.255")[:-1]), 4.25) + self.assertRaises(TypeError, fromstring, memoryview(b"4.25")[::2]) + + self.assertRaises(TypeError, fromstring, 4.25) + + # CRASHES fromstring(NULL) + + def test_fromdouble(self): + # Test PyFloat_FromDouble() + fromdouble = _testcapi.float_fromdouble + + self.assertEqual(fromdouble(4.25), 4.25) + + def test_asdouble(self): + # Test PyFloat_AsDouble() + asdouble = _testcapi.float_asdouble + + class BadFloat3: + def __float__(self): + raise RuntimeError + + self.assertEqual(asdouble(4.25), 4.25) + self.assertEqual(asdouble(-1.0), -1.0) + self.assertEqual(asdouble(42), 42.0) + self.assertEqual(asdouble(-1), -1.0) + self.assertEqual(asdouble(2**1000), float(2**1000)) + + self.assertEqual(asdouble(FloatSubclass(4.25)), 4.25) + self.assertEqual(asdouble(FloatSubclass2(4.25)), 4.25) + self.assertEqual(asdouble(Index()), 99.) + + self.assertRaises(TypeError, asdouble, BadIndex()) + self.assertRaises(TypeError, asdouble, BadFloat()) + self.assertRaises(RuntimeError, asdouble, BadFloat3()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(asdouble(BadIndex2()), 1.) + with self.assertWarns(DeprecationWarning): + self.assertEqual(asdouble(BadFloat2()), 4.25) + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + self.assertRaises(DeprecationWarning, asdouble, BadFloat2()) + self.assertRaises(TypeError, asdouble, object()) + self.assertRaises(TypeError, asdouble, NULL) + + def test_getinfo(self): + # Test PyFloat_GetInfo() + getinfo = _testcapi.float_getinfo + + self.assertEqual(getinfo(), sys.float_info) + + def test_getmax(self): + # Test PyFloat_GetMax() + getmax = _testcapi.float_getmax + + self.assertEqual(getmax(), sys.float_info.max) + + def test_getmin(self): + # Test PyFloat_GetMax() + getmin = _testcapi.float_getmin + + self.assertEqual(getmin(), sys.float_info.min) + + def test_pack(self): + # Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() + pack = _testcapi.float_pack + + self.assertEqual(pack(2, 1.5, BIG_ENDIAN), b'>\x00') + self.assertEqual(pack(4, 1.5, BIG_ENDIAN), b'?\xc0\x00\x00') + self.assertEqual(pack(8, 1.5, BIG_ENDIAN), + b'?\xf8\x00\x00\x00\x00\x00\x00') + self.assertEqual(pack(2, 1.5, LITTLE_ENDIAN), b'\x00>') + self.assertEqual(pack(4, 1.5, LITTLE_ENDIAN), b'\x00\x00\xc0?') + self.assertEqual(pack(8, 1.5, LITTLE_ENDIAN), + b'\x00\x00\x00\x00\x00\x00\xf8?') + + def test_unpack(self): + # Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() + unpack = _testcapi.float_unpack + + self.assertEqual(unpack(b'>\x00', BIG_ENDIAN), 1.5) + self.assertEqual(unpack(b'?\xc0\x00\x00', BIG_ENDIAN), 1.5) + self.assertEqual(unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(unpack(b'\x00>', LITTLE_ENDIAN), 1.5) + self.assertEqual(unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN), 1.5) + self.assertEqual(unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN), + 1.5) + + def test_pack_unpack_roundtrip(self): + pack = _testcapi.float_pack + unpack = _testcapi.float_unpack + + large = 2.0 ** 100 + values = [1.0, 1.5, large, 1.0/7, math.pi] + if HAVE_IEEE_754: + values.extend((INF, NAN)) + for value in values: + for size in (2, 4, 8,): + if size == 2 and value == large: + # too large for 16-bit float + continue + rel_tol = EPSILON[size] + for endian in (BIG_ENDIAN, LITTLE_ENDIAN): + with self.subTest(value=value, size=size, endian=endian): + data = pack(size, value, endian) + value2 = unpack(data, endian) + if math.isnan(value): + self.assertTrue(math.isnan(value2), (value, value2)) + elif size < 8: + self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol), + (value, value2)) + else: + self.assertEqual(value2, value) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_getargs.py b/Lib/test/test_capi/test_getargs.py index e10f679eeb71c8..9b6aef27625ad0 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 @@ -151,6 +153,8 @@ class TupleSubclass(tuple): class DictSubclass(dict): pass +NONCONTIG_WRITABLE = memoryview(bytearray(b'noncontig'))[::-2] +NONCONTIG_READONLY = memoryview(b'noncontig')[::-2] class Unsigned_TestCase(unittest.TestCase): def test_b(self): @@ -835,6 +839,8 @@ def test_y_star(self): self.assertEqual(getargs_y_star(bytearray(b'bytearray')), b'bytearray') self.assertEqual(getargs_y_star(memoryview(b'memoryview')), b'memoryview') self.assertRaises(TypeError, getargs_y_star, None) + self.assertRaises(BufferError, getargs_y_star, NONCONTIG_WRITABLE) + self.assertRaises(BufferError, getargs_y_star, NONCONTIG_READONLY) def test_y_hash(self): from _testcapi import getargs_y_hash @@ -844,6 +850,9 @@ def test_y_hash(self): self.assertRaises(TypeError, getargs_y_hash, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_y_hash, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_y_hash, None) + # TypeError: must be read-only bytes-like object, not memoryview + self.assertRaises(TypeError, getargs_y_hash, NONCONTIG_WRITABLE) + self.assertRaises(TypeError, getargs_y_hash, NONCONTIG_READONLY) def test_w_star(self): # getargs_w_star() modifies first and last byte @@ -859,6 +868,17 @@ def test_w_star(self): self.assertEqual(getargs_w_star(memoryview(buf)), b'[emoryvie]') self.assertEqual(buf, bytearray(b'[emoryvie]')) self.assertRaises(TypeError, getargs_w_star, None) + self.assertRaises(TypeError, getargs_w_star, NONCONTIG_WRITABLE) + self.assertRaises(TypeError, getargs_w_star, NONCONTIG_READONLY) + + def test_getargs_empty(self): + from _testcapi import getargs_empty + self.assertTrue(getargs_empty()) + self.assertRaises(TypeError, getargs_empty, 1) + self.assertRaises(TypeError, getargs_empty, 1, 2, 3) + self.assertRaises(TypeError, getargs_empty, a=1) + self.assertRaises(TypeError, getargs_empty, a=1, b=2) + self.assertRaises(TypeError, getargs_empty, 'x', 'y', 'z', a=1, b=2) class String_TestCase(unittest.TestCase): @@ -891,6 +911,8 @@ def test_s_star(self): self.assertEqual(getargs_s_star(bytearray(b'bytearray')), b'bytearray') self.assertEqual(getargs_s_star(memoryview(b'memoryview')), b'memoryview') self.assertRaises(TypeError, getargs_s_star, None) + self.assertRaises(BufferError, getargs_s_star, NONCONTIG_WRITABLE) + self.assertRaises(BufferError, getargs_s_star, NONCONTIG_READONLY) def test_s_hash(self): from _testcapi import getargs_s_hash @@ -900,6 +922,9 @@ def test_s_hash(self): self.assertRaises(TypeError, getargs_s_hash, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_s_hash, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_s_hash, None) + # TypeError: must be read-only bytes-like object, not memoryview + self.assertRaises(TypeError, getargs_s_hash, NONCONTIG_WRITABLE) + self.assertRaises(TypeError, getargs_s_hash, NONCONTIG_READONLY) def test_z(self): from _testcapi import getargs_z @@ -918,6 +943,8 @@ def test_z_star(self): self.assertEqual(getargs_z_star(bytearray(b'bytearray')), b'bytearray') self.assertEqual(getargs_z_star(memoryview(b'memoryview')), b'memoryview') self.assertIsNone(getargs_z_star(None)) + self.assertRaises(BufferError, getargs_z_star, NONCONTIG_WRITABLE) + self.assertRaises(BufferError, getargs_z_star, NONCONTIG_READONLY) def test_z_hash(self): from _testcapi import getargs_z_hash @@ -927,6 +954,9 @@ def test_z_hash(self): self.assertRaises(TypeError, getargs_z_hash, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_z_hash, memoryview(b'memoryview')) self.assertIsNone(getargs_z_hash(None)) + # TypeError: must be read-only bytes-like object, not memoryview + self.assertRaises(TypeError, getargs_z_hash, NONCONTIG_WRITABLE) + self.assertRaises(TypeError, getargs_z_hash, NONCONTIG_READONLY) def test_es(self): from _testcapi import getargs_es @@ -1160,6 +1190,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() @@ -1187,20 +1238,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']) @@ -1209,11 +1263,84 @@ def test_positional_only(self): with self.assertRaisesRegex(SystemError, 'Empty keyword'): parse((1,), {}, 'O|OO', ['', 'a', '']) + def test_nonascii_keywords(self): + parse = _testcapi.parse_tuple_and_keywords + + for name in ('a', 'ä', 'ŷ', '㷷', '𐀀'): + with self.subTest(name=name): + self.assertEqual(parse((), {name: 1}, 'O', [name]), (1,)) + self.assertEqual(parse((), {}, '|O', [name]), (NULL,)) + with self.assertRaisesRegex(TypeError, + f"function missing required argument '{name}'"): + parse((), {}, 'O', [name]) + with self.assertRaisesRegex(TypeError, + fr"argument for function given by name \('{name}'\) " + fr"and position \(1\)"): + parse((1,), {name: 2}, 'O|O', [name, 'b']) + with self.assertRaisesRegex(TypeError, + f"'{name}' is an invalid keyword argument"): + parse((), {name: 1}, '|O', ['b']) + with self.assertRaisesRegex(TypeError, + "'b' is an invalid keyword argument"): + parse((), {'b': 1}, '|O', [name]) + + invalid = name.encode() + (name.encode()[:-1] or b'\x80') + self.assertEqual(parse((), {}, '|O', [invalid]), (NULL,)) + self.assertEqual(parse((1,), {'b': 2}, 'O|O', [invalid, 'b']), + (1, 2)) + with self.assertRaisesRegex(TypeError, + f"function missing required argument '{name}\ufffd'"): + parse((), {}, 'O', [invalid]) + with self.assertRaisesRegex(UnicodeDecodeError, + f"'utf-8' codec can't decode bytes? "): + parse((), {'b': 1}, '|OO', [invalid, 'b']) + with self.assertRaisesRegex(UnicodeDecodeError, + f"'utf-8' codec can't decode bytes? "): + parse((), {'b': 1}, '|O', [invalid]) + + for name2 in ('b', 'ë', 'ĉ', 'Ɐ', '𐀁'): + with self.subTest(name2=name2): + with self.assertRaisesRegex(TypeError, + f"'{name2}' is an invalid keyword argument"): + parse((), {name2: 1}, '|O', [name]) + + name2 = name.encode().decode('latin1') + if name2 != name: + with self.assertRaisesRegex(TypeError, + f"'{name2}' is an invalid keyword argument"): + parse((), {name2: 1}, '|O', [name]) + name3 = name + '3' + with self.assertRaisesRegex(TypeError, + f"'{name2}' is an invalid keyword argument"): + parse((), {name2: 1, name3: 2}, '|OO', [name, name3]) + + def test_nested_tuple(self): + parse = _testcapi.parse_tuple_and_keywords + + self.assertEqual(parse(((1, 2, 3),), {}, '(OOO)', ['a']), (1, 2, 3)) + self.assertEqual(parse((1, (2, 3), 4), {}, 'O(OO)O', ['a', 'b', 'c']), + (1, 2, 3, 4)) + parse(((1, 2, 3),), {}, '(iii)', ['a']) -class Test_testcapi(unittest.TestCase): - locals().update((name, getattr(_testcapi, name)) - for name in dir(_testcapi) - if name.startswith('test_') and name.endswith('_code')) + with self.assertRaisesRegex(TypeError, + "argument 1 must be sequence of length 2, not 3"): + parse(((1, 2, 3),), {}, '(ii)', ['a']) + with self.assertRaisesRegex(TypeError, + "argument 1 must be sequence of length 2, not 1"): + parse(((1,),), {}, '(ii)', ['a']) + with self.assertRaisesRegex(TypeError, + "argument 1 must be 2-item sequence, not int"): + parse((1,), {}, '(ii)', ['a']) + with self.assertRaisesRegex(TypeError, + "argument 1 must be 2-item sequence, not bytes"): + parse((b'ab',), {}, '(ii)', ['a']) + + for f in 'es', 'et', 'es#', 'et#': + with self.assertRaises(LookupError): # empty encoding "" + parse((('a',),), {}, '(' + f + ')', ['a']) + with self.assertRaisesRegex(TypeError, + "argument 1 must be sequence of length 1, not 0"): + parse(((),), {}, '(' + f + ')', ['a']) if __name__ == "__main__": diff --git a/Lib/test/test_capi/test_hash.py b/Lib/test/test_capi/test_hash.py new file mode 100644 index 00000000000000..8436da7c32df10 --- /dev/null +++ b/Lib/test/test_capi/test_hash.py @@ -0,0 +1,79 @@ +import sys +import unittest +from test.support import import_helper +_testcapi = import_helper.import_module('_testcapi') + + +SIZEOF_VOID_P = _testcapi.SIZEOF_VOID_P +SIZEOF_PY_HASH_T = SIZEOF_VOID_P + + +class CAPITest(unittest.TestCase): + def test_hash_getfuncdef(self): + # Test PyHash_GetFuncDef() + hash_getfuncdef = _testcapi.hash_getfuncdef + func_def = hash_getfuncdef() + + match func_def.name: + case "fnv": + self.assertEqual(func_def.hash_bits, 8 * SIZEOF_PY_HASH_T) + self.assertEqual(func_def.seed_bits, 16 * SIZEOF_PY_HASH_T) + case "siphash13": + self.assertEqual(func_def.hash_bits, 64) + self.assertEqual(func_def.seed_bits, 128) + case "siphash24": + self.assertEqual(func_def.hash_bits, 64) + self.assertEqual(func_def.seed_bits, 128) + case _: + self.fail(f"unknown function name: {func_def.name!r}") + + # compare with sys.hash_info + hash_info = sys.hash_info + self.assertEqual(func_def.name, hash_info.algorithm) + self.assertEqual(func_def.hash_bits, hash_info.hash_bits) + self.assertEqual(func_def.seed_bits, hash_info.seed_bits) + + def test_hash_pointer(self): + # Test Py_HashPointer() + hash_pointer = _testcapi.hash_pointer + + UHASH_T_MASK = ((2 ** (8 * SIZEOF_PY_HASH_T)) - 1) + HASH_T_MAX = (2 ** (8 * SIZEOF_PY_HASH_T - 1) - 1) + + def python_hash_pointer(x): + # Py_HashPointer() rotates the pointer bits by 4 bits to the right + x = (x >> 4) | ((x & 15) << (8 * SIZEOF_VOID_P - 4)) + + # Convert unsigned uintptr_t (Py_uhash_t) to signed Py_hash_t + if HASH_T_MAX < x: + x = (~x) + 1 + x &= UHASH_T_MASK + x = (~x) + 1 + return x + + if SIZEOF_VOID_P == 8: + values = ( + 0xABCDEF1234567890, + 0x1234567890ABCDEF, + 0xFEE4ABEDD1CECA5E, + ) + else: + values = ( + 0x12345678, + 0x1234ABCD, + 0xDEADCAFE, + ) + + for value in values: + expected = python_hash_pointer(value) + with self.subTest(value=value): + self.assertEqual(hash_pointer(value), expected, + f"hash_pointer({value:x}) = " + f"{hash_pointer(value):x} != {expected:x}") + + # Py_HashPointer(NULL) returns 0 + self.assertEqual(hash_pointer(0), 0) + + # Py_HashPointer((void*)(uintptr_t)-1) doesn't return -1 but -2 + VOID_P_MAX = -1 & (2 ** (8 * SIZEOF_VOID_P) - 1) + self.assertEqual(hash_pointer(VOID_P_MAX), -2) diff --git a/Lib/test/test_capi/test_list.py b/Lib/test/test_capi/test_list.py new file mode 100644 index 00000000000000..eb03d51d3def37 --- /dev/null +++ b/Lib/test/test_capi/test_list.py @@ -0,0 +1,344 @@ +import gc +import weakref +import unittest +from test.support import import_helper +from collections import UserList +_testcapi = import_helper.import_module('_testcapi') + +NULL = None +PY_SSIZE_T_MIN = _testcapi.PY_SSIZE_T_MIN +PY_SSIZE_T_MAX = _testcapi.PY_SSIZE_T_MAX + +class ListSubclass(list): + pass + + +class DelAppend: + def __init__(self, lst, item): + self.lst = lst + self.item = item + + def __del__(self): + self.lst.append(self.item) + + +class CAPITest(unittest.TestCase): + def test_check(self): + # Test PyList_Check() + check = _testcapi.list_check + self.assertTrue(check([1, 2])) + self.assertTrue(check([])) + self.assertTrue(check(ListSubclass([1, 2]))) + self.assertFalse(check({1: 2})) + self.assertFalse(check((1, 2))) + self.assertFalse(check(42)) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + + def test_list_check_exact(self): + # Test PyList_CheckExact() + check = _testcapi.list_check_exact + self.assertTrue(check([1])) + self.assertTrue(check([])) + self.assertFalse(check(ListSubclass([1]))) + self.assertFalse(check(UserList([1, 2]))) + self.assertFalse(check({1: 2})) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_list_new(self): + # Test PyList_New() + list_new = _testcapi.list_new + lst = list_new(0) + self.assertEqual(lst, []) + self.assertIs(type(lst), list) + lst2 = list_new(0) + self.assertIsNot(lst2, lst) + self.assertRaises(SystemError, list_new, NULL) + self.assertRaises(SystemError, list_new, -1) + + def test_list_size(self): + # Test PyList_Size() + size = _testcapi.list_size + self.assertEqual(size([1, 2]), 2) + self.assertEqual(size(ListSubclass([1, 2])), 2) + self.assertRaises(SystemError, size, UserList()) + self.assertRaises(SystemError, size, {}) + self.assertRaises(SystemError, size, 23) + self.assertRaises(SystemError, size, object()) + # CRASHES size(NULL) + + def test_list_get_size(self): + # Test PyList_GET_SIZE() + size = _testcapi.list_get_size + self.assertEqual(size([1, 2]), 2) + self.assertEqual(size(ListSubclass([1, 2])), 2) + # CRASHES size(object()) + # CRASHES size(23) + # CRASHES size({}) + # CRASHES size(UserList()) + # CRASHES size(NULL) + + + def test_list_getitem(self): + # Test PyList_GetItem() + getitem = _testcapi.list_getitem + lst = [1, 2, 3] + self.assertEqual(getitem(lst, 0), 1) + self.assertEqual(getitem(lst, 2), 3) + self.assertRaises(IndexError, getitem, lst, 3) + self.assertRaises(IndexError, getitem, lst, -1) + self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MIN) + self.assertRaises(IndexError, getitem, lst, PY_SSIZE_T_MAX) + self.assertRaises(SystemError, getitem, 42, 1) + self.assertRaises(SystemError, getitem, (1, 2, 3), 1) + self.assertRaises(SystemError, getitem, {1: 2}, 1) + + # CRASHES getitem(NULL, 1) + + def test_list_get_item(self): + # Test PyList_GET_ITEM() + get_item = _testcapi.list_get_item + lst = [1, 2, [1, 2, 3]] + self.assertEqual(get_item(lst, 0), 1) + self.assertEqual(get_item(lst, 2), [1, 2, 3]) + + # CRASHES for out of index: get_item(lst, 3) + # CRASHES for get_item(lst, PY_SSIZE_T_MIN) + # CRASHES for get_item(lst, PY_SSIZE_T_MAX) + # CRASHES get_item(21, 2) + # CRASHES get_item(NULL, 1) + + + def test_list_setitem(self): + # Test PyList_SetItem() + setitem = _testcapi.list_setitem + lst = [1, 2, 3] + setitem(lst, 0, 10) + self.assertEqual(lst, [10, 2, 3]) + setitem(lst, 2, 12) + self.assertEqual(lst, [10, 2, 12]) + self.assertRaises(IndexError, setitem, lst, 3 , 5) + self.assertRaises(IndexError, setitem, lst, -1, 5) + self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MIN, 5) + self.assertRaises(IndexError, setitem, lst, PY_SSIZE_T_MAX, 5) + self.assertRaises(SystemError, setitem, (1, 2, 3), 1, 5) + self.assertRaises(SystemError, setitem, {1: 2}, 1, 5) + + # CRASHES setitem(NULL, 'a', 5) + + def test_list_set_item(self): + # Test PyList_SET_ITEM() + set_item = _testcapi.list_set_item + lst = [1, 2, 3] + set_item(lst, 1, 10) + set_item(lst, 2, [1, 2, 3]) + self.assertEqual(lst, [1, 10, [1, 2, 3]]) + + # CRASHES for set_item([1], -1, 5) + # CRASHES for set_item([1], PY_SSIZE_T_MIN, 5) + # CRASHES for set_item([1], PY_SSIZE_T_MAX, 5) + # CRASHES for set_item([], 0, 1) + # CRASHES for set_item(NULL, 0, 1) + + + def test_list_insert(self): + # Test PyList_Insert() + insert = _testcapi.list_insert + lst = [1, 2, 3] + insert(lst, 0, 23) + self.assertEqual(lst, [23, 1, 2, 3]) + insert(lst, -1, 22) + self.assertEqual(lst, [23, 1, 2, 22, 3]) + insert(lst, PY_SSIZE_T_MIN, 1) + self.assertEqual(lst[0], 1) + insert(lst, len(lst), 123) + self.assertEqual(lst[-1], 123) + insert(lst, len(lst)-1, 124) + self.assertEqual(lst[-2], 124) + insert(lst, PY_SSIZE_T_MAX, 223) + self.assertEqual(lst[-1], 223) + + self.assertRaises(SystemError, insert, (1, 2, 3), 1, 5) + self.assertRaises(SystemError, insert, {1: 2}, 1, 5) + + # CRASHES insert(NULL, 1, 5) + + def test_list_append(self): + # Test PyList_Append() + append = _testcapi.list_append + lst = [1, 2, 3] + append(lst, 10) + self.assertEqual(lst, [1, 2, 3, 10]) + append(lst, [4, 5]) + self.assertEqual(lst, [1, 2, 3, 10, [4, 5]]) + self.assertRaises(SystemError, append, lst, NULL) + self.assertRaises(SystemError, append, (), 0) + self.assertRaises(SystemError, append, 42, 0) + # CRASHES append(NULL, 0) + + def test_list_getslice(self): + # Test PyList_GetSlice() + getslice = _testcapi.list_getslice + lst = [1, 2, 3] + + # empty + self.assertEqual(getslice(lst, PY_SSIZE_T_MIN, 0), []) + self.assertEqual(getslice(lst, -1, 0), []) + self.assertEqual(getslice(lst, 3, PY_SSIZE_T_MAX), []) + + # slice + self.assertEqual(getslice(lst, 1, 3), [2, 3]) + + # whole + self.assertEqual(getslice(lst, 0, len(lst)), lst) + self.assertEqual(getslice(lst, 0, 100), lst) + self.assertEqual(getslice(lst, -100, 100), lst) + + self.assertRaises(SystemError, getslice, (1, 2, 3), 0, 0) + self.assertRaises(SystemError, getslice, 'abc', 0, 0) + self.assertRaises(SystemError, getslice, 42, 0, 0) + + # CRASHES getslice(NULL, 0, 0) + + def test_list_setslice(self): + # Test PyList_SetSlice() + list_setslice = _testcapi.list_setslice + def set_slice(lst, low, high, value): + lst = lst.copy() + self.assertEqual(list_setslice(lst, low, high, value), 0) + return lst + + # insert items + self.assertEqual(set_slice([], 0, 0, list("abc")), list("abc")) + self.assertEqual(set_slice([], PY_SSIZE_T_MIN, PY_SSIZE_T_MIN, list("abc")), list("abc")) + self.assertEqual(set_slice([], PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, list("abc")), list("abc")) + lst = list("abc") + self.assertEqual(set_slice(lst, 0, 0, ["X"]), list("Xabc")) + self.assertEqual(set_slice(lst, 1, 1, list("XY")), list("aXYbc")) + self.assertEqual(set_slice(lst, len(lst), len(lst), ["X"]), list("abcX")) + # self.assertEqual(set_slice(lst, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, ["X"]), list("abcX")) + + # replace items + lst = list("abc") + self.assertEqual(set_slice(lst, -100, 1, list("X")), list("Xbc")) + self.assertEqual(set_slice(lst, 1, 2, list("X")), list("aXc")) + self.assertEqual(set_slice(lst, 1, 3, list("XY")), list("aXY")) + self.assertEqual(set_slice(lst, 0, 3, list("XYZ")), list("XYZ")) + + # delete items + lst = list("abcdef") + self.assertEqual(set_slice(lst, 0, len(lst), []), []) + self.assertEqual(set_slice(lst, -100, 100, []), []) + self.assertEqual(set_slice(lst, 1, 5, []), list("af")) + self.assertEqual(set_slice(lst, 3, len(lst), []), list("abc")) + + # delete items with NULL + lst = list("abcdef") + self.assertEqual(set_slice(lst, 0, len(lst), NULL), []) + self.assertEqual(set_slice(lst, 3, len(lst), NULL), list("abc")) + + self.assertRaises(SystemError, list_setslice, (), 0, 0, []) + self.assertRaises(SystemError, list_setslice, 42, 0, 0, []) + + # Item finalizer modify the list (clear the list) + lst = [] + lst.append(DelAppend(lst, 'zombie')) + self.assertEqual(list_setslice(lst, 0, len(lst), NULL), 0) + self.assertEqual(lst, ['zombie']) + + # Item finalizer modify the list (remove an list item) + lst = [] + lst.append(DelAppend(lst, 'zombie')) + lst.extend("abc") + self.assertEqual(list_setslice(lst, 0, 1, NULL), 0) + self.assertEqual(lst, ['a', 'b', 'c', 'zombie']) + + # CRASHES setslice(NULL, 0, 0, []) + + def test_list_sort(self): + # Test PyList_Sort() + sort = _testcapi.list_sort + lst = [4, 6, 7, 3, 1, 5, 9, 2, 0, 8] + sort(lst) + self.assertEqual(lst, list(range(10))) + + lst2 = ListSubclass([4, 6, 7, 3, 1, 5, 9, 2, 0, 8]) + sort(lst2) + self.assertEqual(lst2, list(range(10))) + + self.assertRaises(SystemError, sort, ()) + self.assertRaises(SystemError, sort, object()) + self.assertRaises(SystemError, sort, NULL) + + + def test_list_reverse(self): + # Test PyList_Reverse() + reverse = _testcapi.list_reverse + def list_reverse(lst): + self.assertEqual(reverse(lst), 0) + return lst + + self.assertEqual(list_reverse([]), []) + self.assertEqual(list_reverse([2, 5, 10]), [10, 5, 2]) + + self.assertRaises(SystemError, reverse, ()) + self.assertRaises(SystemError, reverse, object()) + self.assertRaises(SystemError, reverse, NULL) + + def test_list_astuple(self): + # Test PyList_AsTuple() + astuple = _testcapi.list_astuple + self.assertEqual(astuple([]), ()) + self.assertEqual(astuple([2, 5, 10]), (2, 5, 10)) + + self.assertRaises(SystemError, astuple, ()) + self.assertRaises(SystemError, astuple, object()) + self.assertRaises(SystemError, astuple, NULL) + + def test_list_clear(self): + # Test PyList_Clear() + list_clear = _testcapi.list_clear + + lst = [1, 2, 3] + self.assertEqual(list_clear(lst), 0) + self.assertEqual(lst, []) + + lst = [] + self.assertEqual(list_clear(lst), 0) + self.assertEqual(lst, []) + + self.assertRaises(SystemError, list_clear, ()) + self.assertRaises(SystemError, list_clear, object()) + + # Item finalizer modify the list + lst = [] + lst.append(DelAppend(lst, 'zombie')) + list_clear(lst) + self.assertEqual(lst, ['zombie']) + + # CRASHES list_clear(NULL) + + def test_list_extend(self): + # Test PyList_Extend() + list_extend = _testcapi.list_extend + + for other_type in (list, tuple, str, iter): + lst = list("ab") + arg = other_type("def") + self.assertEqual(list_extend(lst, arg), 0) + self.assertEqual(lst, list("abdef")) + + # PyList_Extend(lst, lst) + lst = list("abc") + self.assertEqual(list_extend(lst, lst), 0) + self.assertEqual(lst, list("abcabc")) + + self.assertRaises(TypeError, list_extend, [], object()) + self.assertRaises(SystemError, list_extend, (), list("abc")) + + # CRASHES list_extend(NULL, []) + # CRASHES list_extend([], NULL) diff --git a/Lib/test/test_capi/test_long.py b/Lib/test/test_capi/test_long.py index 101fe1f0de77f1..8e3ef25d1ff86f 100644 --- a/Lib/test/test_capi/test_long.py +++ b/Lib/test/test_capi/test_long.py @@ -6,6 +6,25 @@ # Skip this test if the _testcapi module isn't available. _testcapi = import_helper.import_module('_testcapi') +NULL = None + +class IntSubclass(int): + pass + +class Index: + def __init__(self, value): + self.value = value + + def __index__(self): + return self.value + +# use __index__(), not __int__() +class MyIndexAndInt: + def __index__(self): + return 10 + def __int__(self): + return 22 + class LongTests(unittest.TestCase): @@ -34,35 +53,375 @@ def test_compact_known(self): self.assertEqual(_testcapi.call_long_compact_api(sys.maxsize), (False, -1)) + def test_long_check(self): + # Test PyLong_Check() + check = _testcapi.pylong_check + self.assertTrue(check(1)) + self.assertTrue(check(123456789012345678901234567890)) + self.assertTrue(check(-1)) + self.assertTrue(check(True)) + self.assertTrue(check(IntSubclass(1))) + self.assertFalse(check(1.0)) + self.assertFalse(check(object())) + # CRASHES check(NULL) + + def test_long_checkexact(self): + # Test PyLong_CheckExact() + check = _testcapi.pylong_checkexact + self.assertTrue(check(1)) + self.assertTrue(check(123456789012345678901234567890)) + self.assertTrue(check(-1)) + self.assertFalse(check(True)) + self.assertFalse(check(IntSubclass(1))) + self.assertFalse(check(1.0)) + self.assertFalse(check(object())) + # CRASHES check(NULL) + + def test_long_fromdouble(self): + # Test PyLong_FromDouble() + fromdouble = _testcapi.pylong_fromdouble + float_max = sys.float_info.max + for value in (5.0, 5.1, 5.9, -5.1, -5.9, 0.0, -0.0, float_max, -float_max): + with self.subTest(value=value): + self.assertEqual(fromdouble(value), int(value)) + self.assertRaises(OverflowError, fromdouble, float('inf')) + self.assertRaises(OverflowError, fromdouble, float('-inf')) + self.assertRaises(ValueError, fromdouble, float('nan')) + + def test_long_fromvoidptr(self): + # Test PyLong_FromVoidPtr() + fromvoidptr = _testcapi.pylong_fromvoidptr + obj = object() + x = fromvoidptr(obj) + y = fromvoidptr(NULL) + self.assertIsInstance(x, int) + self.assertGreaterEqual(x, 0) + self.assertIsInstance(y, int) + self.assertEqual(y, 0) + self.assertNotEqual(x, y) + + def test_long_fromstring(self): + # Test PyLong_FromString() + fromstring = _testcapi.pylong_fromstring + self.assertEqual(fromstring(b'123', 10), (123, 3)) + self.assertEqual(fromstring(b'cafe', 16), (0xcafe, 4)) + self.assertEqual(fromstring(b'xyz', 36), (44027, 3)) + self.assertEqual(fromstring(b'123', 0), (123, 3)) + self.assertEqual(fromstring(b'0xcafe', 0), (0xcafe, 6)) + self.assertRaises(ValueError, fromstring, b'cafe', 0) + self.assertEqual(fromstring(b'-123', 10), (-123, 4)) + self.assertEqual(fromstring(b' -123 ', 10), (-123, 6)) + self.assertEqual(fromstring(b'1_23', 10), (123, 4)) + self.assertRaises(ValueError, fromstring, b'- 123', 10) + self.assertRaises(ValueError, fromstring, b'', 10) + + self.assertRaises(ValueError, fromstring, b'123', 1) + self.assertRaises(ValueError, fromstring, b'123', -1) + self.assertRaises(ValueError, fromstring, b'123', 37) + + self.assertRaises(ValueError, fromstring, '١٢٣٤٥٦٧٨٩٠'.encode(), 0) + self.assertRaises(ValueError, fromstring, '١٢٣٤٥٦٧٨٩٠'.encode(), 16) + + self.assertEqual(fromstring(b'123\x00', 0), (123, 3)) + self.assertEqual(fromstring(b'123\x00456', 0), (123, 3)) + self.assertEqual(fromstring(b'123\x00', 16), (0x123, 3)) + self.assertEqual(fromstring(b'123\x00456', 16), (0x123, 3)) + + # CRASHES fromstring(NULL, 0) + # CRASHES fromstring(NULL, 16) + + def test_long_fromunicodeobject(self): + # Test PyLong_FromUnicodeObject() + fromunicodeobject = _testcapi.pylong_fromunicodeobject + self.assertEqual(fromunicodeobject('123', 10), 123) + self.assertEqual(fromunicodeobject('cafe', 16), 0xcafe) + self.assertEqual(fromunicodeobject('xyz', 36), 44027) + self.assertEqual(fromunicodeobject('123', 0), 123) + self.assertEqual(fromunicodeobject('0xcafe', 0), 0xcafe) + self.assertRaises(ValueError, fromunicodeobject, 'cafe', 0) + self.assertEqual(fromunicodeobject('-123', 10), -123) + self.assertEqual(fromunicodeobject(' -123 ', 10), -123) + self.assertEqual(fromunicodeobject('1_23', 10), 123) + self.assertRaises(ValueError, fromunicodeobject, '- 123', 10) + self.assertRaises(ValueError, fromunicodeobject, '', 10) + + self.assertRaises(ValueError, fromunicodeobject, '123', 1) + self.assertRaises(ValueError, fromunicodeobject, '123', -1) + self.assertRaises(ValueError, fromunicodeobject, '123', 37) + + self.assertEqual(fromunicodeobject('١٢٣٤٥٦٧٨٩٠', 0), 1234567890) + self.assertEqual(fromunicodeobject('١٢٣٤٥٦٧٨٩٠', 16), 0x1234567890) + + self.assertRaises(ValueError, fromunicodeobject, '123\x00', 0) + self.assertRaises(ValueError, fromunicodeobject, '123\x00456', 0) + self.assertRaises(ValueError, fromunicodeobject, '123\x00', 16) + self.assertRaises(ValueError, fromunicodeobject, '123\x00456', 16) + + # CRASHES fromunicodeobject(NULL, 0) + # CRASHES fromunicodeobject(NULL, 16) + def test_long_asint(self): + # Test PyLong_AsInt() PyLong_AsInt = _testcapi.PyLong_AsInt - INT_MIN = _testcapi.INT_MIN - INT_MAX = _testcapi.INT_MAX + from _testcapi import INT_MIN, 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) + self.assertEqual(PyLong_AsInt(IntSubclass(42)), 42) + self.assertEqual(PyLong_AsInt(Index(42)), 42) + self.assertEqual(PyLong_AsInt(MyIndexAndInt()), 10) # bound checking - with self.assertRaises(OverflowError): - PyLong_AsInt(INT_MIN - 1) - with self.assertRaises(OverflowError): - PyLong_AsInt(INT_MAX + 1) + self.assertRaises(OverflowError, PyLong_AsInt, INT_MIN - 1) + self.assertRaises(OverflowError, PyLong_AsInt, INT_MAX + 1) # invalid type - for value in (1.0, b'2', '3'): + self.assertRaises(TypeError, PyLong_AsInt, 1.0) + self.assertRaises(TypeError, PyLong_AsInt, b'2') + self.assertRaises(TypeError, PyLong_AsInt, '3') + self.assertRaises(SystemError, PyLong_AsInt, NULL) + + def test_long_aslong(self): + # Test PyLong_AsLong() and PyLong_FromLong() + aslong = _testcapi.pylong_aslong + from _testcapi import LONG_MIN, LONG_MAX + # round trip (object -> long -> object) + for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(aslong(value), value) + + self.assertEqual(aslong(IntSubclass(42)), 42) + self.assertEqual(aslong(Index(42)), 42) + self.assertEqual(aslong(MyIndexAndInt()), 10) + + self.assertRaises(OverflowError, aslong, LONG_MIN - 1) + self.assertRaises(OverflowError, aslong, LONG_MAX + 1) + self.assertRaises(TypeError, aslong, 1.0) + self.assertRaises(TypeError, aslong, b'2') + self.assertRaises(TypeError, aslong, '3') + self.assertRaises(SystemError, aslong, NULL) + + def test_long_aslongandoverflow(self): + # Test PyLong_AsLongAndOverflow() + aslongandoverflow = _testcapi.pylong_aslongandoverflow + from _testcapi import LONG_MIN, LONG_MAX + # round trip (object -> long -> object) + for value in (LONG_MIN, LONG_MAX, -1, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(aslongandoverflow(value), (value, 0)) + + self.assertEqual(aslongandoverflow(IntSubclass(42)), (42, 0)) + self.assertEqual(aslongandoverflow(Index(42)), (42, 0)) + self.assertEqual(aslongandoverflow(MyIndexAndInt()), (10, 0)) + + self.assertEqual(aslongandoverflow(LONG_MIN - 1), (-1, -1)) + self.assertEqual(aslongandoverflow(LONG_MAX + 1), (-1, 1)) + # CRASHES aslongandoverflow(1.0) + # CRASHES aslongandoverflow(NULL) + + def test_long_asunsignedlong(self): + # Test PyLong_AsUnsignedLong() and PyLong_FromUnsignedLong() + asunsignedlong = _testcapi.pylong_asunsignedlong + from _testcapi import ULONG_MAX + # round trip (object -> unsigned long -> object) + for value in (ULONG_MAX, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(asunsignedlong(value), value) + + self.assertEqual(asunsignedlong(IntSubclass(42)), 42) + self.assertRaises(TypeError, asunsignedlong, Index(42)) + self.assertRaises(TypeError, asunsignedlong, MyIndexAndInt()) + + self.assertRaises(OverflowError, asunsignedlong, -1) + self.assertRaises(OverflowError, asunsignedlong, ULONG_MAX + 1) + self.assertRaises(TypeError, asunsignedlong, 1.0) + self.assertRaises(TypeError, asunsignedlong, b'2') + self.assertRaises(TypeError, asunsignedlong, '3') + self.assertRaises(SystemError, asunsignedlong, NULL) + + def test_long_asunsignedlongmask(self): + # Test PyLong_AsUnsignedLongMask() + asunsignedlongmask = _testcapi.pylong_asunsignedlongmask + from _testcapi import ULONG_MAX + # round trip (object -> unsigned long -> object) + for value in (ULONG_MAX, 0, 1, 1234): with self.subTest(value=value): - with self.assertRaises(TypeError): - PyLong_AsInt(value) + self.assertEqual(asunsignedlongmask(value), value) + + self.assertEqual(asunsignedlongmask(IntSubclass(42)), 42) + self.assertEqual(asunsignedlongmask(Index(42)), 42) + self.assertEqual(asunsignedlongmask(MyIndexAndInt()), 10) + + self.assertEqual(asunsignedlongmask(-1), ULONG_MAX) + self.assertEqual(asunsignedlongmask(ULONG_MAX + 1), 0) + self.assertRaises(TypeError, asunsignedlongmask, 1.0) + self.assertRaises(TypeError, asunsignedlongmask, b'2') + self.assertRaises(TypeError, asunsignedlongmask, '3') + self.assertRaises(SystemError, asunsignedlongmask, NULL) + + def test_long_aslonglong(self): + # Test PyLong_AsLongLong() and PyLong_FromLongLong() + aslonglong = _testcapi.pylong_aslonglong + from _testcapi import LLONG_MIN, LLONG_MAX + # round trip (object -> long long -> object) + for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(aslonglong(value), value) + + self.assertEqual(aslonglong(IntSubclass(42)), 42) + self.assertEqual(aslonglong(Index(42)), 42) + self.assertEqual(aslonglong(MyIndexAndInt()), 10) + + self.assertRaises(OverflowError, aslonglong, LLONG_MIN - 1) + self.assertRaises(OverflowError, aslonglong, LLONG_MAX + 1) + self.assertRaises(TypeError, aslonglong, 1.0) + self.assertRaises(TypeError, aslonglong, b'2') + self.assertRaises(TypeError, aslonglong, '3') + self.assertRaises(SystemError, aslonglong, NULL) + + def test_long_aslonglongandoverflow(self): + # Test PyLong_AsLongLongAndOverflow() + aslonglongandoverflow = _testcapi.pylong_aslonglongandoverflow + from _testcapi import LLONG_MIN, LLONG_MAX + # round trip (object -> long long -> object) + for value in (LLONG_MIN, LLONG_MAX, -1, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(aslonglongandoverflow(value), (value, 0)) + + self.assertEqual(aslonglongandoverflow(IntSubclass(42)), (42, 0)) + self.assertEqual(aslonglongandoverflow(Index(42)), (42, 0)) + self.assertEqual(aslonglongandoverflow(MyIndexAndInt()), (10, 0)) + + self.assertEqual(aslonglongandoverflow(LLONG_MIN - 1), (-1, -1)) + self.assertEqual(aslonglongandoverflow(LLONG_MAX + 1), (-1, 1)) + # CRASHES aslonglongandoverflow(1.0) + # CRASHES aslonglongandoverflow(NULL) + + def test_long_asunsignedlonglong(self): + # Test PyLong_AsUnsignedLongLong() and PyLong_FromUnsignedLongLong() + asunsignedlonglong = _testcapi.pylong_asunsignedlonglong + from _testcapi import ULLONG_MAX + # round trip (object -> unsigned long long -> object) + for value in (ULLONG_MAX, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(asunsignedlonglong(value), value) + + self.assertEqual(asunsignedlonglong(IntSubclass(42)), 42) + self.assertRaises(TypeError, asunsignedlonglong, Index(42)) + self.assertRaises(TypeError, asunsignedlonglong, MyIndexAndInt()) + + self.assertRaises(OverflowError, asunsignedlonglong, -1) + self.assertRaises(OverflowError, asunsignedlonglong, ULLONG_MAX + 1) + self.assertRaises(TypeError, asunsignedlonglong, 1.0) + self.assertRaises(TypeError, asunsignedlonglong, b'2') + self.assertRaises(TypeError, asunsignedlonglong, '3') + self.assertRaises(SystemError, asunsignedlonglong, NULL) + + def test_long_asunsignedlonglongmask(self): + # Test PyLong_AsUnsignedLongLongMask() + asunsignedlonglongmask = _testcapi.pylong_asunsignedlonglongmask + from _testcapi import ULLONG_MAX + # round trip (object -> unsigned long long -> object) + for value in (ULLONG_MAX, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(asunsignedlonglongmask(value), value) + + self.assertEqual(asunsignedlonglongmask(IntSubclass(42)), 42) + self.assertEqual(asunsignedlonglongmask(Index(42)), 42) + self.assertEqual(asunsignedlonglongmask(MyIndexAndInt()), 10) + + self.assertEqual(asunsignedlonglongmask(-1), ULLONG_MAX) + self.assertEqual(asunsignedlonglongmask(ULLONG_MAX + 1), 0) + self.assertRaises(TypeError, asunsignedlonglongmask, 1.0) + self.assertRaises(TypeError, asunsignedlonglongmask, b'2') + self.assertRaises(TypeError, asunsignedlonglongmask, '3') + self.assertRaises(SystemError, asunsignedlonglongmask, NULL) + + def test_long_as_ssize_t(self): + # Test PyLong_AsSsize_t() and PyLong_FromSsize_t() + as_ssize_t = _testcapi.pylong_as_ssize_t + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + # round trip (object -> Py_ssize_t -> object) + for value in (PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(as_ssize_t(value), value) + + self.assertEqual(as_ssize_t(IntSubclass(42)), 42) + self.assertRaises(TypeError, as_ssize_t, Index(42)) + self.assertRaises(TypeError, as_ssize_t, MyIndexAndInt()) + + self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MIN - 1) + self.assertRaises(OverflowError, as_ssize_t, PY_SSIZE_T_MAX + 1) + self.assertRaises(TypeError, as_ssize_t, 1.0) + self.assertRaises(TypeError, as_ssize_t, b'2') + self.assertRaises(TypeError, as_ssize_t, '3') + self.assertRaises(SystemError, as_ssize_t, NULL) + + def test_long_as_size_t(self): + # Test PyLong_AsSize_t() and PyLong_FromSize_t() + as_size_t = _testcapi.pylong_as_size_t + from _testcapi import SIZE_MAX + # round trip (object -> size_t -> object) + for value in (SIZE_MAX, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(as_size_t(value), value) + + self.assertEqual(as_size_t(IntSubclass(42)), 42) + self.assertRaises(TypeError, as_size_t, Index(42)) + self.assertRaises(TypeError, as_size_t, MyIndexAndInt()) + + self.assertRaises(OverflowError, as_size_t, -1) + self.assertRaises(OverflowError, as_size_t, SIZE_MAX + 1) + self.assertRaises(TypeError, as_size_t, 1.0) + self.assertRaises(TypeError, as_size_t, b'2') + self.assertRaises(TypeError, as_size_t, '3') + self.assertRaises(SystemError, as_size_t, NULL) + + def test_long_asdouble(self): + # Test PyLong_AsDouble() + asdouble = _testcapi.pylong_asdouble + MAX = int(sys.float_info.max) + for value in (-MAX, MAX, -1, 0, 1, 1234): + with self.subTest(value=value): + self.assertEqual(asdouble(value), float(value)) + self.assertIsInstance(asdouble(value), float) + + self.assertEqual(asdouble(IntSubclass(42)), 42.0) + self.assertRaises(TypeError, asdouble, Index(42)) + self.assertRaises(TypeError, asdouble, MyIndexAndInt()) + + self.assertRaises(OverflowError, asdouble, 2 * MAX) + self.assertRaises(OverflowError, asdouble, -2 * MAX) + self.assertRaises(TypeError, asdouble, 1.0) + self.assertRaises(TypeError, asdouble, b'2') + self.assertRaises(TypeError, asdouble, '3') + self.assertRaises(SystemError, asdouble, NULL) + + def test_long_asvoidptr(self): + # Test PyLong_AsVoidPtr() + fromvoidptr = _testcapi.pylong_fromvoidptr + asvoidptr = _testcapi.pylong_asvoidptr + obj = object() + x = fromvoidptr(obj) + y = fromvoidptr(NULL) + self.assertIs(asvoidptr(x), obj) + self.assertIs(asvoidptr(y), NULL) + self.assertIs(asvoidptr(IntSubclass(x)), obj) + + # negative values + M = (1 << _testcapi.SIZEOF_VOID_P * 8) + if x >= M//2: + self.assertIs(asvoidptr(x - M), obj) + if y >= M//2: + self.assertIs(asvoidptr(y - M), NULL) + + self.assertRaises(TypeError, asvoidptr, Index(x)) + self.assertRaises(TypeError, asvoidptr, object()) + self.assertRaises(OverflowError, asvoidptr, 2**1000) + self.assertRaises(OverflowError, asvoidptr, -2**1000) + # CRASHES asvoidptr(NULL) if __name__ == "__main__": diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py index 72f23b1a34080e..04f17a9ec9e72a 100644 --- a/Lib/test/test_capi/test_mem.py +++ b/Lib/test/test_capi/test_mem.py @@ -152,6 +152,8 @@ class C(): pass self.assertGreaterEqual(count, i*5-2) +# Py_GIL_DISABLED requires mimalloc (not malloc) +@unittest.skipIf(support.Py_GIL_DISABLED, 'need malloc') class PyMemMallocDebugTests(PyMemDebugTests): PYTHONMALLOC = 'malloc_debug' @@ -161,6 +163,11 @@ class PyMemPymallocDebugTests(PyMemDebugTests): PYTHONMALLOC = 'pymalloc_debug' +@unittest.skipUnless(support.with_mimalloc(), 'need mimaloc') +class PyMemMimallocDebugTests(PyMemDebugTests): + PYTHONMALLOC = 'mimalloc_debug' + + @unittest.skipUnless(support.Py_DEBUG, 'need Py_DEBUG') class PyMemDefaultTests(PyMemDebugTests): # test default allocator of Python compiled in debug mode diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 5ece213e7b2363..123813b949fb7d 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -7,7 +7,6 @@ import importlib.machinery import importlib.util import json -import opcode import os import pickle import queue @@ -298,6 +297,94 @@ 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() @@ -1010,46 +1097,21 @@ 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) + def test_get_type_module_name(self): + from collections import OrderedDict + ht = _testcapi.get_heaptype_for_name() + for cls, expected in { + int: 'builtins', + OrderedDict: 'collections', + ht: '_testcapi', + }.items(): + with self.subTest(repr(cls)): + modname = _testinternalcapi.get_type_module_name(cls) + self.assertEqual(modname, expected) + ht.__module__ = 'test_module' + modname = _testinternalcapi.get_type_module_name(ht) + self.assertEqual(modname, 'test_module') @requires_limited_api class TestHeapTypeRelative(unittest.TestCase): @@ -1464,6 +1526,7 @@ def test_isolated_subinterpreter(self): maxtext = 250 main_interpid = 0 interpid = _interpreters.create() + self.addCleanup(lambda: _interpreters.destroy(interpid)) _interpreters.run_string(interpid, f"""if True: import json import os @@ -1957,6 +2020,137 @@ def test_module_state_shared_in_global(self): self.assertEqual(main_attr_id, subinterp_attr_id) +@requires_subinterpreters +class InterpreterIDTests(unittest.TestCase): + + InterpreterID = _testcapi.get_interpreterid_type() + + def new_interpreter(self): + def ensure_destroyed(interpid): + try: + _interpreters.destroy(interpid) + except _interpreters.InterpreterNotFoundError: + pass + id = _interpreters.create() + self.addCleanup(lambda: ensure_destroyed(id)) + return id + + def test_with_int(self): + id = self.InterpreterID(10, force=True) + + self.assertEqual(int(id), 10) + + def test_coerce_id(self): + class Int(str): + def __index__(self): + return 10 + + id = self.InterpreterID(Int(), force=True) + self.assertEqual(int(id), 10) + + def test_bad_id(self): + for badid in [ + object(), + 10.0, + '10', + b'10', + ]: + with self.subTest(badid): + with self.assertRaises(TypeError): + self.InterpreterID(badid) + + badid = -1 + with self.subTest(badid): + with self.assertRaises(ValueError): + self.InterpreterID(badid) + + badid = 2**64 + with self.subTest(badid): + with self.assertRaises(OverflowError): + self.InterpreterID(badid) + + def test_exists(self): + id = self.new_interpreter() + with self.assertRaises(_interpreters.InterpreterNotFoundError): + self.InterpreterID(int(id) + 1) # unforced + + def test_does_not_exist(self): + id = self.new_interpreter() + with self.assertRaises(_interpreters.InterpreterNotFoundError): + self.InterpreterID(int(id) + 1) # unforced + + def test_destroyed(self): + id = _interpreters.create() + _interpreters.destroy(id) + with self.assertRaises(_interpreters.InterpreterNotFoundError): + self.InterpreterID(id) # unforced + + def test_str(self): + id = self.InterpreterID(10, force=True) + self.assertEqual(str(id), '10') + + def test_repr(self): + id = self.InterpreterID(10, force=True) + self.assertEqual(repr(id), 'InterpreterID(10)') + + def test_equality(self): + id1 = self.new_interpreter() + id2 = self.InterpreterID(id1) + id3 = self.InterpreterID( + self.new_interpreter()) + + self.assertTrue(id2 == id2) # identity + self.assertTrue(id2 == id1) # int-equivalent + self.assertTrue(id1 == id2) # reversed + self.assertTrue(id2 == int(id2)) + self.assertTrue(id2 == float(int(id2))) + self.assertTrue(float(int(id2)) == id2) + self.assertFalse(id2 == float(int(id2)) + 0.1) + self.assertFalse(id2 == str(int(id2))) + self.assertFalse(id2 == 2**1000) + self.assertFalse(id2 == float('inf')) + self.assertFalse(id2 == 'spam') + self.assertFalse(id2 == id3) + + self.assertFalse(id2 != id2) + self.assertFalse(id2 != id1) + self.assertFalse(id1 != id2) + self.assertTrue(id2 != id3) + + def test_linked_lifecycle(self): + id1 = _interpreters.create() + _testcapi.unlink_interpreter_refcount(id1) + self.assertEqual( + _testinternalcapi.get_interpreter_refcount(id1), + 0) + + id2 = self.InterpreterID(id1) + self.assertEqual( + _testinternalcapi.get_interpreter_refcount(id1), + 1) + + # The interpreter isn't linked to ID objects, so it isn't destroyed. + del id2 + self.assertEqual( + _testinternalcapi.get_interpreter_refcount(id1), + 0) + + _testcapi.link_interpreter_refcount(id1) + self.assertEqual( + _testinternalcapi.get_interpreter_refcount(id1), + 0) + + id3 = self.InterpreterID(id1) + self.assertEqual( + _testinternalcapi.get_interpreter_refcount(id1), + 1) + + # The interpreter is linked now so is destroyed. + del id3 + with self.assertRaises(_interpreters.InterpreterNotFoundError): + _testinternalcapi.get_interpreter_refcount(id1) + + class BuiltinStaticTypesTests(unittest.TestCase): TYPES = [ @@ -2071,7 +2265,7 @@ def test_gilstate_matches_current(self): class Test_testcapi(unittest.TestCase): locals().update((name, getattr(_testcapi, name)) for name in dir(_testcapi) - if name.startswith('test_') and not name.endswith('_code')) + if name.startswith('test_')) # Suppress warning from PyUnicode_FromUnicode(). @warnings_helper.ignore_warnings(category=DeprecationWarning) @@ -2288,416 +2482,59 @@ def func(): self.do_test(func, names) -@contextlib.contextmanager -def temporary_optimizer(opt): - old_opt = _testinternalcapi.get_optimizer() - _testinternalcapi.set_optimizer(opt) - try: - yield - finally: - _testinternalcapi.set_optimizer(old_opt) - - -@contextlib.contextmanager -def clear_executors(func): - # Clear executors in func before and after running a block - func.__code__ = func.__code__.replace() - try: - yield - finally: - func.__code__ = func.__code__.replace() - - -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): - old = _testinternalcapi.get_optimizer() - opt = _testinternalcapi.get_counter_optimizer() - 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 - ns = {} - exec(textwrap.dedent(""" - def loop(): - for _ in range(1000): - pass - """), ns, ns) - loop = ns['loop'] - - for repeat in range(5): - opt = _testinternalcapi.get_counter_optimizer() - with temporary_optimizer(opt): - self.assertEqual(opt.get_count(), 0) - with clear_executors(loop): - loop() - self.assertEqual(opt.get_count(), 1000) - - def test_long_loop(self): - "Check that we aren't confused by EXTENDED_ARG" - - # Generate a new function at each call - ns = {} - exec(textwrap.dedent(""" - def nop(): - pass +@unittest.skipUnless(support.Py_GIL_DISABLED, 'need Py_GIL_DISABLED') +class TestPyThreadId(unittest.TestCase): + def test_py_thread_id(self): + # gh-112535: Test _Py_ThreadId(): make sure that thread identifiers + # in a few threads are unique + py_thread_id = _testinternalcapi.py_thread_id + short_sleep = 0.010 - def long_loop(): - for _ in range(10): - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - """), ns, ns) - long_loop = ns['long_loop'] - - opt = _testinternalcapi.get_counter_optimizer() - with temporary_optimizer(opt): - self.assertEqual(opt.get_count(), 0) - 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: - try: - return _testinternalcapi.get_executor(code, i) - except ValueError: - pass - return None - - -class TestUops(unittest.TestCase): - - def test_basic_loop(self): - def testfunc(x): - i = 0 - while i < x: - i += 1 - - opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): - testfunc(1000) - - ex = get_first_executor(testfunc) - self.assertIsNotNone(ex) - uops = {opname for opname, _, _ in ex} - self.assertIn("_SET_IP", uops) - self.assertIn("LOAD_FAST", uops) - - def test_extended_arg(self): - "Check EXTENDED_ARG handling in superblock creation" - 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): - ex = get_first_executor(many_vars) - self.assertIsNone(ex) - many_vars() - - ex = get_first_executor(many_vars) - self.assertIsNotNone(ex) - self.assertIn(("LOAD_FAST", 259, 0), list(ex)) - - def test_unspecialized_unpack(self): - # An example of an unspecialized opcode - def testfunc(x): - i = 0 - while i < x: - i += 1 - a, b = {1: 2, 3: 3} - assert a == 1 and b == 3 - i = 0 - while i < x: - 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("UNPACK_SEQUENCE", uops) - - def test_pop_jump_if_false(self): - def testfunc(n): - i = 0 - while i < n: - 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_FALSE", uops) - - def test_pop_jump_if_none(self): - def testfunc(a): - for x in a: - if x is None: - x = 0 - - opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): - testfunc(range(20)) - - ex = get_first_executor(testfunc) - self.assertIsNotNone(ex) - uops = {opname for opname, _, _ in ex} - self.assertIn("_POP_JUMP_IF_TRUE", uops) - - 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(range(20)) - - ex = get_first_executor(testfunc) - self.assertIsNotNone(ex) - uops = {opname for opname, _, _ in ex} - self.assertIn("_POP_JUMP_IF_FALSE", uops) - - def test_pop_jump_if_true(self): - def testfunc(n): - i = 0 - while not i >= n: - 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) - - def test_jump_backward(self): - def testfunc(n): - i = 0 - while i < n: - 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("_JUMP_TO_TOP", uops) - - def test_jump_forward(self): - def testfunc(n): - a = 0 - while a < n: - if a < 0: - a = -a - else: - a = +a - a += 1 - return a - - 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} - # Since there is no JUMP_FORWARD instruction, - # look for indirect evidence: the += operator - self.assertIn("_BINARY_OP_ADD_INT", uops) - - def test_for_iter_range(self): - def testfunc(n): - total = 0 - for i in range(n): - total += i - return total - - opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): - total = testfunc(20) - self.assertEqual(total, 190) - - ex = get_first_executor(testfunc) - self.assertIsNotNone(ex) - # for i, (opname, oparg) in enumerate(ex): - # print(f"{i:4d}: {opname:<20s} {oparg:3d}") - uops = {opname for opname, _, _ in ex} - self.assertIn("_IS_ITER_EXHAUSTED_RANGE", uops) - # Verification that the jump goes past END_FOR - # is done by manual inspection of the output - - def test_for_iter_list(self): - def testfunc(a): - total = 0 - for i in a: - total += i - return total - - opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): - a = list(range(20)) - total = testfunc(a) - self.assertEqual(total, 190) - - ex = get_first_executor(testfunc) - self.assertIsNotNone(ex) - # for i, (opname, oparg) in enumerate(ex): - # print(f"{i:4d}: {opname:<20s} {oparg:3d}") - uops = {opname for opname, _, _ in ex} - self.assertIn("_IS_ITER_EXHAUSTED_LIST", uops) - # Verification that the jump goes past END_FOR - # is done by manual inspection of the output - - def test_for_iter_tuple(self): - def testfunc(a): - total = 0 - for i in a: - total += i - return total - - opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): - a = tuple(range(20)) - total = testfunc(a) - self.assertEqual(total, 190) - - ex = get_first_executor(testfunc) - self.assertIsNotNone(ex) - # for i, (opname, oparg) in enumerate(ex): - # print(f"{i:4d}: {opname:<20s} {oparg:3d}") - uops = {opname for opname, _, _ in ex} - self.assertIn("_IS_ITER_EXHAUSTED_TUPLE", uops) - # Verification that the jump goes past END_FOR - # is done by manual inspection of the output - - def test_list_edge_case(self): - def testfunc(it): - for x in it: - pass - - opt = _testinternalcapi.get_uop_optimizer() - with temporary_optimizer(opt): - a = [1, 2, 3] - it = iter(a) - testfunc(it) - a.append(4) - 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) + class GetThreadId(threading.Thread): + def __init__(self): + super().__init__() + self.get_lock = threading.Lock() + self.get_lock.acquire() + self.started_lock = threading.Event() + self.py_tid = None + + def run(self): + self.started_lock.set() + self.get_lock.acquire() + self.py_tid = py_thread_id() + time.sleep(short_sleep) + self.py_tid2 = py_thread_id() + + nthread = 5 + threads = [GetThreadId() for _ in range(nthread)] + + # first make run sure that all threads are running + for thread in threads: + thread.start() + for thread in threads: + thread.started_lock.wait() + + # call _Py_ThreadId() in the main thread + py_thread_ids = [py_thread_id()] + + # now call _Py_ThreadId() in each thread + for thread in threads: + thread.get_lock.release() + + # call _Py_ThreadId() in each thread and wait until threads complete + for thread in threads: + thread.join() + py_thread_ids.append(thread.py_tid) + # _PyThread_Id() should not change for a given thread. + # For example, it should remain the same after a short sleep. + self.assertEqual(thread.py_tid2, thread.py_tid) + + # make sure that all _Py_ThreadId() are unique + for tid in py_thread_ids: + self.assertIsInstance(tid, int) + self.assertGreater(tid, 0) + self.assertEqual(len(set(py_thread_ids)), len(py_thread_ids), + py_thread_ids) if __name__ == "__main__": diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py new file mode 100644 index 00000000000000..9f4731103c9413 --- /dev/null +++ b/Lib/test/test_capi/test_opt.py @@ -0,0 +1,544 @@ +import contextlib +import opcode +import textwrap +import unittest + +import _testinternalcapi + + +@contextlib.contextmanager +def temporary_optimizer(opt): + old_opt = _testinternalcapi.get_optimizer() + _testinternalcapi.set_optimizer(opt) + try: + yield + finally: + _testinternalcapi.set_optimizer(old_opt) + + +@contextlib.contextmanager +def clear_executors(func): + # Clear executors in func before and after running a block + func.__code__ = func.__code__.replace() + try: + yield + finally: + func.__code__ = func.__code__.replace() + + +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): + old = _testinternalcapi.get_optimizer() + opt = _testinternalcapi.get_counter_optimizer() + 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 + ns = {} + exec(textwrap.dedent(""" + def loop(): + for _ in range(1000): + pass + """), ns, ns) + loop = ns['loop'] + + for repeat in range(5): + opt = _testinternalcapi.get_counter_optimizer() + with temporary_optimizer(opt): + self.assertEqual(opt.get_count(), 0) + with clear_executors(loop): + loop() + self.assertEqual(opt.get_count(), 1000) + + def test_long_loop(self): + "Check that we aren't confused by EXTENDED_ARG" + + # Generate a new function at each call + ns = {} + exec(textwrap.dedent(""" + def nop(): + pass + + def long_loop(): + for _ in range(10): + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); + """), ns, ns) + long_loop = ns['long_loop'] + + opt = _testinternalcapi.get_counter_optimizer() + with temporary_optimizer(opt): + self.assertEqual(opt.get_count(), 0) + 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: + try: + return _testinternalcapi.get_executor(code, i) + except ValueError: + pass + return None + + +class TestExecutorInvalidation(unittest.TestCase): + + def setUp(self): + self.old = _testinternalcapi.get_optimizer() + self.opt = _testinternalcapi.get_counter_optimizer() + _testinternalcapi.set_optimizer(self.opt) + + def tearDown(self): + _testinternalcapi.set_optimizer(self.old) + + def test_invalidate_object(self): + # Generate a new set of functions at each call + ns = {} + func_src = "\n".join( + f""" + def f{n}(): + for _ in range(1000): + pass + """ for n in range(5) + ) + exec(textwrap.dedent(func_src), ns, ns) + funcs = [ ns[f'f{n}'] for n in range(5)] + objects = [object() for _ in range(5)] + + for f in funcs: + f() + executors = [get_first_executor(f) for f in funcs] + # Set things up so each executor depends on the objects + # with an equal or lower index. + for i, exe in enumerate(executors): + self.assertTrue(exe.is_valid()) + for obj in objects[:i+1]: + _testinternalcapi.add_executor_dependency(exe, obj) + self.assertTrue(exe.is_valid()) + # Assert that the correct executors are invalidated + # and check that nothing crashes when we invalidate + # an executor mutliple times. + for i in (4,3,2,1,0): + _testinternalcapi.invalidate_executors(objects[i]) + for exe in executors[i:]: + self.assertFalse(exe.is_valid()) + for exe in executors[:i]: + self.assertTrue(exe.is_valid()) + + def test_uop_optimizer_invalidation(self): + # Generate a new function at each call + ns = {} + exec(textwrap.dedent(""" + def f(): + for i in range(1000): + pass + """), ns, ns) + f = ns['f'] + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + f() + exe = get_first_executor(f) + self.assertTrue(exe.is_valid()) + _testinternalcapi.invalidate_executors(f.__code__) + self.assertFalse(exe.is_valid()) + +class TestUops(unittest.TestCase): + + def test_basic_loop(self): + def testfunc(x): + i = 0 + while i < x: + i += 1 + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + testfunc(1000) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _, _ in ex} + self.assertIn("_SET_IP", uops) + self.assertIn("LOAD_FAST", uops) + + def test_extended_arg(self): + "Check EXTENDED_ARG handling in superblock creation" + 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): + ex = get_first_executor(many_vars) + self.assertIsNone(ex) + many_vars() + + ex = get_first_executor(many_vars) + self.assertIsNotNone(ex) + self.assertIn(("LOAD_FAST", 259, 0), list(ex)) + + def test_unspecialized_unpack(self): + # An example of an unspecialized opcode + def testfunc(x): + i = 0 + while i < x: + i += 1 + a, b = {1: 2, 3: 3} + assert a == 1 and b == 3 + i = 0 + while i < x: + 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("_UNPACK_SEQUENCE", uops) + + def test_pop_jump_if_false(self): + def testfunc(n): + i = 0 + while i < n: + 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("_GUARD_IS_TRUE_POP", uops) + + def test_pop_jump_if_none(self): + def testfunc(a): + for x in a: + if x is None: + x = 0 + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + testfunc(range(20)) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _, _ in ex} + self.assertIn("_GUARD_IS_NOT_NONE_POP", uops) + + 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(range(20)) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _, _ in ex} + self.assertIn("_GUARD_IS_NONE_POP", uops) + + def test_pop_jump_if_true(self): + def testfunc(n): + i = 0 + while not i >= n: + 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("_GUARD_IS_FALSE_POP", uops) + + def test_jump_backward(self): + def testfunc(n): + i = 0 + while i < n: + 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("_JUMP_TO_TOP", uops) + + def test_jump_forward(self): + def testfunc(n): + a = 0 + while a < n: + if a < 0: + a = -a + else: + a = +a + a += 1 + return a + + 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} + # Since there is no JUMP_FORWARD instruction, + # look for indirect evidence: the += operator + self.assertIn("_BINARY_OP_ADD_INT", uops) + + def test_for_iter_range(self): + def testfunc(n): + total = 0 + for i in range(n): + total += i + return total + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + total = testfunc(20) + self.assertEqual(total, 190) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + # for i, (opname, oparg) in enumerate(ex): + # print(f"{i:4d}: {opname:<20s} {oparg:3d}") + uops = {opname for opname, _, _ in ex} + self.assertIn("_GUARD_NOT_EXHAUSTED_RANGE", uops) + # Verification that the jump goes past END_FOR + # is done by manual inspection of the output + + def test_for_iter_list(self): + def testfunc(a): + total = 0 + for i in a: + total += i + return total + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + a = list(range(20)) + total = testfunc(a) + self.assertEqual(total, 190) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + # for i, (opname, oparg) in enumerate(ex): + # print(f"{i:4d}: {opname:<20s} {oparg:3d}") + uops = {opname for opname, _, _ in ex} + self.assertIn("_GUARD_NOT_EXHAUSTED_LIST", uops) + # Verification that the jump goes past END_FOR + # is done by manual inspection of the output + + def test_for_iter_tuple(self): + def testfunc(a): + total = 0 + for i in a: + total += i + return total + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + a = tuple(range(20)) + total = testfunc(a) + self.assertEqual(total, 190) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + # for i, (opname, oparg) in enumerate(ex): + # print(f"{i:4d}: {opname:<20s} {oparg:3d}") + uops = {opname for opname, _, _ in ex} + self.assertIn("_GUARD_NOT_EXHAUSTED_TUPLE", uops) + # Verification that the jump goes past END_FOR + # is done by manual inspection of the output + + def test_list_edge_case(self): + def testfunc(it): + for x in it: + pass + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + a = [1, 2, 3] + it = iter(a) + testfunc(it) + a.append(4) + 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("_GUARD_IS_FALSE_POP", uops) + + def test_for_iter_tier_two(self): + class MyIter: + def __init__(self, n): + self.n = n + def __iter__(self): + return self + def __next__(self): + self.n -= 1 + if self.n < 0: + raise StopIteration + return self.n + + def testfunc(n, m): + x = 0 + for i in range(m): + for j in MyIter(n): + x += 1000*i + j + return x + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + x = testfunc(10, 10) + + self.assertEqual(x, sum(range(10)) * 10010) + + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + uops = {opname for opname, _, _ in ex} + self.assertIn("_FOR_ITER_TIER_TWO", uops) + + def test_confidence_score(self): + def testfunc(n): + bits = 0 + for i in range(n): + if i & 0x01: + bits += 1 + if i & 0x02: + bits += 1 + if i&0x04: + bits += 1 + if i&0x08: + bits += 1 + if i&0x10: + bits += 1 + if i&0x20: + bits += 1 + return bits + + opt = _testinternalcapi.get_uop_optimizer() + with temporary_optimizer(opt): + x = testfunc(20) + + self.assertEqual(x, 40) + ex = get_first_executor(testfunc) + self.assertIsNotNone(ex) + ops = [opname for opname, _, _ in ex] + count = ops.count("_GUARD_IS_TRUE_POP") + # Because Each 'if' halves the score, the second branch is + # too much already. + self.assertEqual(count, 1) + + +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_sys.py b/Lib/test/test_capi/test_sys.py new file mode 100644 index 00000000000000..08bf0370fc59b5 --- /dev/null +++ b/Lib/test/test_capi/test_sys.py @@ -0,0 +1,154 @@ +import unittest +import contextlib +import sys +from test import support +from test.support import import_helper + +try: + import _testcapi +except ImportError: + _testcapi = None + +NULL = None + +class CAPITest(unittest.TestCase): + # TODO: Test the following functions: + # + # PySys_Audit() + # PySys_AuditTuple() + + maxDiff = None + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_sys_getobject(self): + # Test PySys_GetObject() + 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) + with support.catch_unraisable_exception() as cm: + self.assertIs(getobject(b'\xff'), AttributeError) + self.assertEqual(cm.unraisable.exc_type, UnicodeDecodeError) + self.assertRegex(str(cm.unraisable.exc_value), + "'utf-8' codec can't decode") + # CRASHES getobject(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_sys_setobject(self): + # Test PySys_SetObject() + 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) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_sys_getxoptions(self): + # Test PySys_GetXOptions() + getxoptions = _testcapi.sys_getxoptions + + self.assertIs(getxoptions(), sys._xoptions) + + xoptions = sys._xoptions + try: + sys._xoptions = 'non-dict' + self.assertEqual(getxoptions(), {}) + self.assertIs(getxoptions(), sys._xoptions) + + del sys._xoptions + self.assertEqual(getxoptions(), {}) + self.assertIs(getxoptions(), sys._xoptions) + finally: + sys._xoptions = xoptions + self.assertIs(getxoptions(), sys._xoptions) + + def _test_sys_formatstream(self, funname, streamname): + import_helper.import_module('ctypes') + from ctypes import pythonapi, c_char_p, py_object + func = getattr(pythonapi, funname) + func.argtypes = (c_char_p,) + + # Supports plain C types. + with support.captured_output(streamname) as stream: + func(b'Hello, %s!', c_char_p(b'world')) + self.assertEqual(stream.getvalue(), 'Hello, world!') + + # Supports Python objects. + with support.captured_output(streamname) as stream: + func(b'Hello, %R!', py_object('world')) + self.assertEqual(stream.getvalue(), "Hello, 'world'!") + + # The total length is not limited. + with support.captured_output(streamname) as stream: + func(b'Hello, %s!', c_char_p(b'world'*200)) + self.assertEqual(stream.getvalue(), 'Hello, ' + 'world'*200 + '!') + + def test_sys_formatstdout(self): + # Test PySys_FormatStdout() + self._test_sys_formatstream('PySys_FormatStdout', 'stdout') + + def test_sys_formatstderr(self): + # Test PySys_FormatStderr() + self._test_sys_formatstream('PySys_FormatStderr', 'stderr') + + def _test_sys_writestream(self, funname, streamname): + import_helper.import_module('ctypes') + from ctypes import pythonapi, c_char_p + func = getattr(pythonapi, funname) + func.argtypes = (c_char_p,) + + # Supports plain C types. + with support.captured_output(streamname) as stream: + func(b'Hello, %s!', c_char_p(b'world')) + self.assertEqual(stream.getvalue(), 'Hello, world!') + + # There is a limit on the total length. + with support.captured_output(streamname) as stream: + func(b'Hello, %s!', c_char_p(b'world'*100)) + self.assertEqual(stream.getvalue(), 'Hello, ' + 'world'*100 + '!') + with support.captured_output(streamname) as stream: + func(b'Hello, %s!', c_char_p(b'world'*200)) + out = stream.getvalue() + self.assertEqual(out[:20], 'Hello, worldworldwor') + self.assertEqual(out[-13:], '... truncated') + self.assertGreater(len(out), 1000) + + def test_sys_writestdout(self): + # Test PySys_WriteStdout() + self._test_sys_writestream('PySys_WriteStdout', 'stdout') + + def test_sys_writestderr(self): + # Test PySys_WriteStderr() + self._test_sys_writestream('PySys_WriteStderr', 'stderr') + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py index 622ee8993907fa..bb6161abf4da81 100644 --- a/Lib/test/test_capi/test_unicode.py +++ b/Lib/test/test_capi/test_unicode.py @@ -5,6 +5,7 @@ try: import _testcapi + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX except ImportError: _testcapi = None try: @@ -30,9 +31,17 @@ def test_new(self): for maxchar in 0, 0x61, 0xa1, 0x4f60, 0x1f600, 0x10ffff: self.assertEqual(new(0, maxchar), '') self.assertEqual(new(5, maxchar), chr(maxchar)*5) + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX, maxchar) self.assertEqual(new(0, 0x110000), '') + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2, 0x4f60) + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2+1, 0x4f60) + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2, 0x1f600) + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//2+1, 0x1f600) + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//4, 0x1f600) + self.assertRaises(MemoryError, new, PY_SSIZE_T_MAX//4+1, 0x1f600) self.assertRaises(SystemError, new, 5, 0x110000) self.assertRaises(SystemError, new, -1, 0) + self.assertRaises(SystemError, new, PY_SSIZE_T_MIN, 0) @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') @@ -53,8 +62,8 @@ def test_fill(self): for to in strings[:idx]: self.assertRaises(ValueError, fill, to, 0, 0, fill_char) for to in strings[idx:]: - for start in range(7): - for length in range(-1, 7 - start): + for start in [*range(7), PY_SSIZE_T_MAX]: + for length in [*range(-1, 7 - start), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]: filled = max(min(length, 5 - start), 0) if filled == 5 and to != strings[idx]: # narrow -> wide @@ -66,6 +75,7 @@ def test_fill(self): s = strings[0] self.assertRaises(IndexError, fill, s, -1, 0, 0x78) + self.assertRaises(IndexError, fill, s, PY_SSIZE_T_MIN, 0, 0x78) self.assertRaises(ValueError, fill, s, 0, 0, 0x110000) self.assertRaises(SystemError, fill, b'abc', 0, 0, 0x78) self.assertRaises(SystemError, fill, [], 0, 0, 0x78) @@ -76,7 +86,7 @@ def test_fill(self): @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_writechar(self): - """Test PyUnicode_ReadChar()""" + """Test PyUnicode_WriteChar()""" from _testcapi import unicode_writechar as writechar strings = [ @@ -96,10 +106,12 @@ def test_writechar(self): self.assertRaises(IndexError, writechar, 'abc', 3, 0x78) self.assertRaises(IndexError, writechar, 'abc', -1, 0x78) + self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MAX, 0x78) + self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MIN, 0x78) self.assertRaises(TypeError, writechar, b'abc', 0, 0x78) self.assertRaises(TypeError, writechar, [], 0, 0x78) # CRASHES writechar(NULL, 0, 0x78) - # TODO: Test PyUnicode_CopyCharacters() with non-modifiable and legacy + # TODO: Test PyUnicode_WriteChar() with non-modifiable and legacy # unicode. @support.cpython_only @@ -117,7 +129,11 @@ def test_resize(self): self.assertEqual(resize(s, 3), (s, 0)) self.assertEqual(resize(s, 2), (s[:2], 0)) self.assertEqual(resize(s, 4), (s + '\0', 0)) + self.assertEqual(resize(s, 10), (s + '\0'*7, 0)) self.assertEqual(resize(s, 0), ('', 0)) + self.assertRaises(MemoryError, resize, s, PY_SSIZE_T_MAX) + self.assertRaises(SystemError, resize, s, -1) + self.assertRaises(SystemError, resize, s, PY_SSIZE_T_MIN) self.assertRaises(SystemError, resize, b'abc', 0) self.assertRaises(SystemError, resize, [], 0) self.assertRaises(SystemError, resize, NULL, 0) @@ -196,8 +212,13 @@ def test_fromstringandsize(self): self.assertEqual(fromstringandsize(b'', 0), '') self.assertEqual(fromstringandsize(NULL, 0), '') + self.assertRaises(MemoryError, fromstringandsize, b'abc', PY_SSIZE_T_MAX) self.assertRaises(SystemError, fromstringandsize, b'abc', -1) - # TODO: Test PyUnicode_FromStringAndSize(NULL, size) for size != 0 + self.assertRaises(SystemError, fromstringandsize, b'abc', PY_SSIZE_T_MIN) + self.assertRaises(SystemError, fromstringandsize, NULL, -1) + self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MIN) + self.assertRaises(SystemError, fromstringandsize, NULL, 3) + self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MAX) @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') @@ -245,7 +266,9 @@ def test_fromkindanddata(self): for kind in -1, 0, 3, 5, 8: self.assertRaises(SystemError, fromkindanddata, kind, b'') self.assertRaises(ValueError, fromkindanddata, 1, b'abc', -1) + self.assertRaises(ValueError, fromkindanddata, 1, b'abc', PY_SSIZE_T_MIN) self.assertRaises(ValueError, fromkindanddata, 1, NULL, -1) + self.assertRaises(ValueError, fromkindanddata, 1, NULL, PY_SSIZE_T_MIN) # CRASHES fromkindanddata(1, NULL, 1) # CRASHES fromkindanddata(4, b'\xff\xff\xff\xff') @@ -261,12 +284,14 @@ def test_substring(self): 'ab\xa1\xa2\u4f60\u597d\U0001f600\U0001f601' ] for s in strings: - for start in range(0, len(s) + 2): - for end in range(max(start-1, 0), len(s) + 2): + for start in [*range(0, len(s) + 2), PY_SSIZE_T_MAX]: + for end in [*range(max(start-1, 0), len(s) + 2), PY_SSIZE_T_MAX]: self.assertEqual(substring(s, start, end), s[start:end]) self.assertRaises(IndexError, substring, 'abc', -1, 0) + self.assertRaises(IndexError, substring, 'abc', PY_SSIZE_T_MIN, 0) self.assertRaises(IndexError, substring, 'abc', 0, -1) + self.assertRaises(IndexError, substring, 'abc', 0, PY_SSIZE_T_MIN) # CRASHES substring(b'abc', 0, 0) # CRASHES substring([], 0, 0) # CRASHES substring(NULL, 0, 0) @@ -296,7 +321,9 @@ def test_readchar(self): for i, c in enumerate(s): self.assertEqual(readchar(s, i), ord(c)) self.assertRaises(IndexError, readchar, s, len(s)) + self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MAX) self.assertRaises(IndexError, readchar, s, -1) + self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MIN) self.assertRaises(TypeError, readchar, b'abc', 0) self.assertRaises(TypeError, readchar, [], 0) @@ -731,10 +758,15 @@ def test_fromwidechar(self): if SIZEOF_WCHAR_T == 2: self.assertEqual(fromwidechar('a\U0001f600'.encode(encoding), 2), 'a\ud83d') + self.assertRaises(MemoryError, fromwidechar, b'', PY_SSIZE_T_MAX) self.assertRaises(SystemError, fromwidechar, b'\0'*SIZEOF_WCHAR_T, -2) + self.assertRaises(SystemError, fromwidechar, b'\0'*SIZEOF_WCHAR_T, PY_SSIZE_T_MIN) self.assertEqual(fromwidechar(NULL, 0), '') self.assertRaises(SystemError, fromwidechar, NULL, 1) + self.assertRaises(SystemError, fromwidechar, NULL, PY_SSIZE_T_MAX) self.assertRaises(SystemError, fromwidechar, NULL, -1) + self.assertRaises(SystemError, fromwidechar, NULL, -2) + self.assertRaises(SystemError, fromwidechar, NULL, PY_SSIZE_T_MIN) @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') @@ -906,7 +938,11 @@ def test_asutf8andsize(self): self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, '\ud8ff', 0) self.assertRaises(TypeError, unicode_asutf8andsize, b'abc', 0) self.assertRaises(TypeError, unicode_asutf8andsize, [], 0) + self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize_null, '\ud8ff', 0) + self.assertRaises(TypeError, unicode_asutf8andsize_null, b'abc', 0) + self.assertRaises(TypeError, unicode_asutf8andsize_null, [], 0) # CRASHES unicode_asutf8andsize(NULL, 0) + # CRASHES unicode_asutf8andsize_null(NULL, 0) @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') @@ -965,6 +1001,11 @@ def test_split(self): self.assertEqual(split('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) self.assertEqual(split('a|b|c|d', '|', 2), ['a', 'b', 'c|d']) + self.assertEqual(split('a|b|c|d', '|', PY_SSIZE_T_MAX), + ['a', 'b', 'c', 'd']) + self.assertEqual(split('a|b|c|d', '|', -1), ['a', 'b', 'c', 'd']) + self.assertEqual(split('a|b|c|d', '|', PY_SSIZE_T_MIN), + ['a', 'b', 'c', 'd']) self.assertEqual(split('a|b|c|d', '\u20ac'), ['a|b|c|d']) self.assertEqual(split('a||b|c||d', '||'), ['a', 'b|c', 'd']) self.assertEqual(split('а|б|в|г', '|'), ['а', 'б', 'в', 'г']) @@ -988,6 +1029,11 @@ def test_rsplit(self): self.assertEqual(rsplit('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) self.assertEqual(rsplit('a|b|c|d', '|', 2), ['a|b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '|', PY_SSIZE_T_MAX), + ['a', 'b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '|', -1), ['a', 'b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '|', PY_SSIZE_T_MIN), + ['a', 'b', 'c', 'd']) self.assertEqual(rsplit('a|b|c|d', '\u20ac'), ['a|b|c|d']) self.assertEqual(rsplit('a||b|c||d', '||'), ['a', 'b|c', 'd']) self.assertEqual(rsplit('а|б|в|г', '|'), ['а', 'б', 'в', 'г']) @@ -1120,11 +1166,14 @@ def test_count(self): self.assertEqual(unicode_count(str, '', 0, len(str)), len(str)+1) # start < end self.assertEqual(unicode_count(str, '!', 1, len(str)+1), 1) + self.assertEqual(unicode_count(str, '!', 1, PY_SSIZE_T_MAX), 1) # start >= end self.assertEqual(unicode_count(str, '!', 0, 0), 0) self.assertEqual(unicode_count(str, '!', len(str), 0), 0) # negative self.assertEqual(unicode_count(str, '!', -len(str), -1), 1) + self.assertEqual(unicode_count(str, '!', -len(str)-1, -1), 1) + self.assertEqual(unicode_count(str, '!', PY_SSIZE_T_MIN, -1), 1) # bad arguments self.assertRaises(TypeError, unicode_count, str, b'!', 0, len(str)) self.assertRaises(TypeError, unicode_count, b"!>_= end self.assertEqual(find(str, '!', 0, 0, 1), -1) + self.assertEqual(find(str, '!', 0, 0, -1), -1) self.assertEqual(find(str, '!', len(str), 0, 1), -1) + self.assertEqual(find(str, '!', len(str), 0, -1), -1) # negative self.assertEqual(find(str, '!', -len(str), -1, 1), 0) self.assertEqual(find(str, '!', -len(str), -1, -1), 0) + self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, -1, 1), 0) + self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, -1, -1), 0) + self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, 1), 0) + self.assertEqual(find(str, '!', PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1), 4) # bad arguments self.assertRaises(TypeError, find, str, b'!', 0, len(str), 1) self.assertRaises(TypeError, find, b"!>_= end self.assertEqual(unicode_findchar(str, ord('!'), 0, 0, 1), -1) + self.assertEqual(unicode_findchar(str, ord('!'), 0, 0, -1), -1) self.assertEqual(unicode_findchar(str, ord('!'), len(str), 0, 1), -1) + self.assertEqual(unicode_findchar(str, ord('!'), len(str), 0, -1), -1) # negative self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, 1), 0) self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, -1), 0) + self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, -1, 1), 0) + self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, -1, -1), 0) + self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, 1), 0) + self.assertEqual(unicode_findchar(str, ord('!'), PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, -1), 4) # bad arguments # CRASHES unicode_findchar(b"!>_ int + """ + expected_error = f"{annotation} method cannot define a return type" + self.expect_failure(block, expected_error, lineno=3) + + block = f""" + module foo + class Foo "" "" + {annotation} + Foo.property + obj: int + / + """ + expected_error = f"{annotation} method cannot define parameters" + self.expect_failure(block, expected_error) + + def test_duplicate_getset(self): + annotations = ["@getter", "@setter"] + for annotation in annotations: + with self.subTest(annotation=annotation): + block = f""" + module foo + class Foo "" "" + {annotation} + {annotation} + Foo.property -> int + """ + expected_error = f"Cannot apply {annotation} twice to the same function!" + self.expect_failure(block, expected_error, lineno=3) + + def test_getter_and_setter_disallowed_on_same_function(self): + dup_annotations = [("@getter", "@setter"), ("@setter", "@getter")] + for dup in dup_annotations: + with self.subTest(dup=dup): + block = f""" + module foo + class Foo "" "" + {dup[0]} + {dup[1]} + Foo.property -> int + """ + expected_error = "Cannot apply both @getter and @setter to the same function!" + self.expect_failure(block, expected_error, lineno=3) def test_duplicate_coexist(self): err = "Called @coexist twice" @@ -2398,7 +2472,7 @@ def expect_failure(self, *args): def test_external(self): CLINIC_TEST = 'clinic.test.c' 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() # Run clinic CLI and verify that it does not complain. @@ -2406,7 +2480,7 @@ def test_external(self): out = self.expect_success("-f", "-o", TESTFN, source) self.assertEqual(out, "") - with open(TESTFN, 'r', encoding='utf-8') as f: + with open(TESTFN, encoding='utf-8') as f: new_contents = f.read() self.assertEqual(new_contents, orig_contents) @@ -2466,7 +2540,7 @@ def test_cli_force(self): "/*[clinic end generated code: " "output=c16447c01510dfb3 input=9543a8d2da235301]*/\n" ) - with open(fn, 'r', encoding='utf-8') as f: + with open(fn, encoding='utf-8') as f: generated = f.read() self.assertTrue(generated.endswith(checksum), (generated, checksum)) @@ -3154,6 +3228,10 @@ def test_posonly_vararg(self): self.assertEqual(ac_tester.posonly_vararg(1, 2), (1, 2, ())) self.assertEqual(ac_tester.posonly_vararg(1, b=2), (1, 2, ())) self.assertEqual(ac_tester.posonly_vararg(1, 2, 3, 4), (1, 2, (3, 4))) + with self.assertRaises(TypeError): + ac_tester.posonly_vararg(b=4) + with self.assertRaises(TypeError): + ac_tester.posonly_vararg(1, 2, 3, b=4) def test_vararg_and_posonly(self): with self.assertRaises(TypeError): @@ -3204,6 +3282,37 @@ def test_gh_99240_double_free(self): with self.assertRaisesRegex(TypeError, err): ac_tester.gh_99240_double_free('a', '\0b') + def test_null_or_tuple_for_varargs(self): + # All of these should not crash: + valid_args_for_test = [ + (('a',), {}, + ('a', (), False)), + (('a', 1, 2, 3), {'covariant': True}, + ('a', (1, 2, 3), True)), + ((), {'name': 'a'}, + ('a', (), False)), + ((), {'name': 'a', 'covariant': True}, + ('a', (), True)), + ((), {'covariant': True, 'name': 'a'}, + ('a', (), True)), + ] + for args, kwargs, expected in valid_args_for_test: + with self.subTest(args=args, kwargs=kwargs): + self.assertEqual( + ac_tester.null_or_tuple_for_varargs(*args, **kwargs), + expected, + ) + + def test_null_or_tuple_for_varargs_error(self): + with self.assertRaises(TypeError): + ac_tester.null_or_tuple_for_varargs(covariant=True) + with self.assertRaises(TypeError): + ac_tester.null_or_tuple_for_varargs(1, name='a') + with self.assertRaises(TypeError): + ac_tester.null_or_tuple_for_varargs(1, 2, 3, name='a', covariant=True) + with self.assertRaises(TypeError): + ac_tester.null_or_tuple_for_varargs(1, 2, 3, covariant=True, name='a') + def test_cloned_func_exception_message(self): incorrect_arg = -1 # f1() and f2() accept a single str with self.assertRaisesRegex(TypeError, "clone_f1"): diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index 319801c71f776b..46ec82b704963d 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -9,7 +9,10 @@ import doctest import unittest import io +import textwrap from test import support +from test.support.import_helper import import_module +from test.support.pty_helper import run_pty class samplecmdclass(cmd.Cmd): """ @@ -244,23 +247,55 @@ def test_input_reset_at_EOF(self): "(Cmd) *** Unknown syntax: EOF\n")) +class CmdPrintExceptionClass(cmd.Cmd): + """ + GH-80731 + cmd.Cmd should print the correct exception in default() + >>> mycmd = CmdPrintExceptionClass() + >>> try: + ... raise ValueError("test") + ... except ValueError: + ... mycmd.onecmd("not important") + (, ValueError('test')) + """ + + def default(self, line): + print(sys.exc_info()[:2]) + + +@support.requires_subprocess() +class CmdTestReadline(unittest.TestCase): + def setUpClass(): + # Ensure that the readline module is loaded + # If this fails, the test is skipped because SkipTest will be raised + readline = import_module('readline') + + def test_basic_completion(self): + script = textwrap.dedent(""" + import cmd + class simplecmd(cmd.Cmd): + def do_tab_completion_test(self, args): + print('tab completion success') + return True + + simplecmd().cmdloop() + """) + + # 't' and complete 'ab_completion_test' to 'tab_completion_test' + input = b"t\t\n" + + output = run_pty(script, input) + + self.assertIn(b'ab_completion_test', output) + self.assertIn(b'tab completion success', output) + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) return tests -def test_coverage(coverdir): - trace = support.import_module('trace') - tracer=trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], - trace=0, count=1) - tracer.run('import importlib; importlib.reload(cmd); test_main()') - r=tracer.results() - print("Writing coverage results...") - r.write_results(show_missing=True, summary=True, coverdir=coverdir) if __name__ == "__main__": - if "-c" in sys.argv: - test_coverage('/tmp/cmd.cover') - elif "-i" in sys.argv: + if "-i" in sys.argv: samplecmdclass().cmdloop() else: unittest.main() diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index f4754dbf735a1d..1fe3b2fe53c0b6 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -153,6 +153,17 @@ def test_xoption_frozen_modules(self): res = assert_python_ok(*cmd) self.assertRegex(res.out.decode('utf-8'), expected) + def test_env_var_frozen_modules(self): + tests = { + ('on', 'FrozenImporter'), + ('off', 'SourceFileLoader'), + } + for raw, expected in tests: + cmd = ['-c', 'import os; print(os.__spec__.loader, end="")'] + with self.subTest(raw): + res = assert_python_ok(*cmd, PYTHON_FROZEN_MODULES=raw) + self.assertRegex(res.out.decode('utf-8'), expected) + def test_run_module(self): # Test expected operation of the '-m' switch # Switch needs an argument @@ -468,8 +479,9 @@ def test_stdout_flush_at_shutdown(self): rc, out, err = assert_python_failure('-c', code) self.assertEqual(b'', out) self.assertEqual(120, rc) - self.assertRegex(err.decode('ascii', 'ignore'), - 'Exception ignored in.*\nOSError: .*') + self.assertIn(b'Exception ignored on flushing sys.stdout:\n' + b'OSError: '.replace(b'\n', os.linesep.encode()), + err) def test_closed_stdout(self): # Issue #13444: if stdout has been explicitly closed, we should @@ -726,6 +738,8 @@ def test_xdev(self): out = self.run_xdev("-c", code, check_exitcode=False) if support.with_pymalloc(): alloc_name = "pymalloc_debug" + elif support.Py_GIL_DISABLED: + alloc_name = "mimalloc_debug" else: alloc_name = "malloc_debug" self.assertEqual(out, alloc_name) @@ -802,8 +816,13 @@ def check_pythonmalloc(self, env_var, name): @support.cpython_only def test_pythonmalloc(self): # Test the PYTHONMALLOC environment variable + malloc = not support.Py_GIL_DISABLED pymalloc = support.with_pymalloc() - if pymalloc: + mimalloc = support.with_mimalloc() + if support.Py_GIL_DISABLED: + default_name = 'mimalloc_debug' if support.Py_DEBUG else 'mimalloc' + default_name_debug = 'mimalloc_debug' + elif pymalloc: default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc' default_name_debug = 'pymalloc_debug' else: @@ -813,14 +832,22 @@ def test_pythonmalloc(self): tests = [ (None, default_name), ('debug', default_name_debug), - ('malloc', 'malloc'), - ('malloc_debug', 'malloc_debug'), ] + if malloc: + tests.extend([ + ('malloc', 'malloc'), + ('malloc_debug', 'malloc_debug'), + ]) if pymalloc: tests.extend(( ('pymalloc', 'pymalloc'), ('pymalloc_debug', 'pymalloc_debug'), )) + if mimalloc: + tests.extend(( + ('mimalloc', 'mimalloc'), + ('mimalloc_debug', 'mimalloc_debug'), + )) for env_var, name in tests: with self.subTest(env_var=env_var, name=name): @@ -878,11 +905,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) @@ -902,6 +926,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..48754d5a63da3b 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): @@ -682,6 +684,27 @@ def test_syntaxerror_null_bytes_in_multiline_string(self): ] ) + def test_source_lines_are_shown_when_running_source(self): + _, _, stderr = assert_python_failure("-c", "1/0") + expected_lines = [ + b'Traceback (most recent call last):', + b' File "", line 1, in ', + b' 1/0', + b' ~^~', + b'ZeroDivisionError: division by zero'] + self.assertEqual(stderr.splitlines(), expected_lines) + + def test_syntaxerror_does_not_crash(self): + script = "nonlocal x\n" + with os_helper.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() + # It used to crash in /~https://github.com/python/cpython/issues/111132 + self.assertTrue(text.endswith( + 'SyntaxError: nonlocal declaration not allowed at module level\n', + ), text) + def test_consistent_sys_path_for_direct_execution(self): # This test case ensures that the following all give the same # sys.path configuration: diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index a961ddbe17a3d3..d8fb826edeb681 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -144,6 +144,8 @@ gc_collect) from test.support.script_helper import assert_python_ok from test.support import threading_helper +from test.support.bytecode_helper import (BytecodeTestCase, + instructions_with_positions) from opcode import opmap, opname COPY_FREE_VARS = opmap['COPY_FREE_VARS'] @@ -384,10 +386,8 @@ def test_co_positions_artificial_instructions(self): code = traceback.tb_frame.f_code artificial_instructions = [] - for instr, positions in zip( - dis.get_instructions(code, show_caches=True), - code.co_positions(), - strict=True + for instr, positions in instructions_with_positions( + dis.get_instructions(code), code.co_positions() ): # If any of the positions is None, then all have to # be None as well for the case above. There are still diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 226bc3a853b7b9..747c0f9683c19c 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -10,11 +10,7 @@ code = import_helper.import_module('code') -class TestInteractiveConsole(unittest.TestCase): - - def setUp(self): - self.console = code.InteractiveConsole() - self.mock_sys() +class MockSys: def mock_sys(self): "Mock system environment for InteractiveConsole" @@ -32,6 +28,13 @@ def mock_sys(self): del self.sysmod.ps1 del self.sysmod.ps2 + +class TestInteractiveConsole(unittest.TestCase, MockSys): + + def setUp(self): + self.console = code.InteractiveConsole() + self.mock_sys() + def test_ps1(self): self.infunc.side_effect = EOFError('Finished') self.console.interact() @@ -151,5 +154,21 @@ def test_context_tb(self): self.assertIn(expected, output) +class TestInteractiveConsoleLocalExit(unittest.TestCase, MockSys): + + def setUp(self): + self.console = code.InteractiveConsole(local_exit=True) + self.mock_sys() + + def test_exit(self): + # default exit message + self.infunc.side_effect = ["exit()"] + self.console.interact(banner='') + self.assertEqual(len(self.stderr.method_calls), 2) + err_msg = self.stderr.method_calls[1] + expected = 'now exiting InteractiveConsole...\n' + self.assertEqual(err_msg, ['write', (expected,), {}]) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_codecencodings_iso2022.py b/Lib/test/test_codecencodings_iso2022.py index 00ea1c39dd6fb6..027dbecc6134df 100644 --- a/Lib/test/test_codecencodings_iso2022.py +++ b/Lib/test/test_codecencodings_iso2022.py @@ -24,6 +24,52 @@ class Test_ISO2022_JP2(multibytecodec_support.TestBase, unittest.TestCase): (b'ab\x1BNdef', 'replace', 'abdef'), ) +class Test_ISO2022_JP3(multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_jp_3' + tstring = multibytecodec_support.load_teststring('iso2022_jp') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + (b'\x1B$(O\x2E\x23\x1B(B', 'strict', '\u3402' ), + (b'\x1B$(O\x2E\x22\x1B(B', 'strict', '\U0002000B' ), + (b'\x1B$(O\x24\x77\x1B(B', 'strict', '\u304B\u309A'), + (b'\x1B$(P\x21\x22\x1B(B', 'strict', '\u4E02' ), + (b'\x1B$(P\x7E\x76\x1B(B', 'strict', '\U0002A6B2' ), + ('\u3402', 'strict', b'\x1B$(O\x2E\x23\x1B(B'), + ('\U0002000B', 'strict', b'\x1B$(O\x2E\x22\x1B(B'), + ('\u304B\u309A', 'strict', b'\x1B$(O\x24\x77\x1B(B'), + ('\u4E02', 'strict', b'\x1B$(P\x21\x22\x1B(B'), + ('\U0002A6B2', 'strict', b'\x1B$(P\x7E\x76\x1B(B'), + (b'ab\x1B$(O\x2E\x21\x1B(Bdef', 'replace', 'ab\uFFFDdef'), + ('ab\u4FF1def', 'replace', b'ab?def'), + ) + xmlcharnametest = ( + '\xAB\u211C\xBB = \u2329\u1234\u232A', + b'\x1B$(O\x29\x28\x1B(Bℜ\x1B$(O\x29\x32\x1B(B = ⟨ሴ⟩' + ) + +class Test_ISO2022_JP2004(multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_jp_2004' + tstring = multibytecodec_support.load_teststring('iso2022_jp') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + (b'\x1B$(Q\x2E\x23\x1B(B', 'strict', '\u3402' ), + (b'\x1B$(Q\x2E\x22\x1B(B', 'strict', '\U0002000B' ), + (b'\x1B$(Q\x24\x77\x1B(B', 'strict', '\u304B\u309A'), + (b'\x1B$(P\x21\x22\x1B(B', 'strict', '\u4E02' ), + (b'\x1B$(P\x7E\x76\x1B(B', 'strict', '\U0002A6B2' ), + ('\u3402', 'strict', b'\x1B$(Q\x2E\x23\x1B(B'), + ('\U0002000B', 'strict', b'\x1B$(Q\x2E\x22\x1B(B'), + ('\u304B\u309A', 'strict', b'\x1B$(Q\x24\x77\x1B(B'), + ('\u4E02', 'strict', b'\x1B$(P\x21\x22\x1B(B'), + ('\U0002A6B2', 'strict', b'\x1B$(P\x7E\x76\x1B(B'), + (b'ab\x1B$(Q\x2E\x21\x1B(Bdef', 'replace', 'ab\u4FF1def'), + ('ab\u4FF1def', 'replace', b'ab\x1B$(Q\x2E\x21\x1B(Bdef'), + ) + xmlcharnametest = ( + '\xAB\u211C\xBB = \u2329\u1234\u232A', + b'\x1B$(Q\x29\x28\x1B(Bℜ\x1B$(Q\x29\x32\x1B(B = ⟨ሴ⟩' + ) + class Test_ISO2022_KR(multibytecodec_support.TestBase, unittest.TestCase): encoding = 'iso2022_kr' tstring = multibytecodec_support.load_teststring('iso2022_kr') diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index b5e9271ac0c3cd..ff511a625a0194 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1762,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): @@ -3567,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_codeop.py b/Lib/test/test_codeop.py index e3c382266fa058..2abb6c6d935b7e 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -5,6 +5,7 @@ import unittest import warnings from test.support import warnings_helper +from textwrap import dedent from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT @@ -308,6 +309,19 @@ def test_invalid_warning(self): self.assertRegex(str(w[0].message), 'invalid escape sequence') self.assertEqual(w[0].filename, '') + def assertSyntaxErrorMatches(self, code, message): + with self.subTest(code): + with self.assertRaisesRegex(SyntaxError, message): + compile_command(code, symbol='exec') + + def test_syntax_errors(self): + self.assertSyntaxErrorMatches( + dedent("""\ + def foo(x,x): + pass + """), "duplicate argument 'x' in function definition") + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index bb8b352518ef3e..7e6f811e17cfa2 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -488,12 +488,8 @@ def test_instance(self): self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - try: + with self.assertRaises(TypeError): p._replace(x=1, error=2) - except ValueError: - pass - else: - self._fail('Did not detect an incorrect fieldname') # verify that field string can have commas Point = namedtuple('Point', 'x, y') diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index c4452e38934cf8..f681d125db7d7a 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -12,6 +12,7 @@ from test import support from test.support import (script_helper, requires_debug_ranges, requires_specialization, Py_C_RECURSION_LIMIT) +from test.support.bytecode_helper import instructions_with_positions from test.support.os_helper import FakePath class TestSpecifics(unittest.TestCase): @@ -1283,6 +1284,23 @@ def test_remove_redundant_nop_edge_case(self): def f(): a if (1 if b else c) else d + def test_global_declaration_in_except_used_in_else(self): + # See gh-111123 + code = textwrap.dedent("""\ + def f(): + try: + pass + %s Exception: + global a + else: + print(a) + """) + + g, l = {'a': 5}, {} + for kw in ("except", "except*"): + exec(code % kw, g, l); + + @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): # Ensure that compiled code snippets have correct line and column numbers @@ -1329,8 +1347,8 @@ def generic_visit(self, node): def assertOpcodeSourcePositionIs(self, code, opcode, line, end_line, column, end_column, occurrence=1): - for instr, position in zip( - dis.Bytecode(code, show_caches=True), code.co_positions(), strict=True + for instr, position in instructions_with_positions( + dis.Bytecode(code), code.co_positions() ): if instr.opname == opcode: occurrence -= 1 diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 9cd92ad365c5a9..83a9532aecfac8 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -362,6 +362,29 @@ def test_strip_only(self): str(err, encoding=sys.getdefaultencoding()) ) + def test_strip_only_invalid(self): + fullpath = ["test", "build", "real", "path"] + path = os.path.join(self.directory, *fullpath) + os.makedirs(path) + script = script_helper.make_script(path, "test", "1 / 0") + bc = importlib.util.cache_from_source(script) + stripdir = os.path.join(self.directory, *(fullpath[:2] + ['fake'])) + compileall.compile_dir(path, quiet=True, stripdir=stripdir) + rc, out, err = script_helper.assert_python_failure(bc) + expected_not_in = os.path.join(self.directory, *fullpath[2:]) + self.assertIn( + path, + str(err, encoding=sys.getdefaultencoding()) + ) + self.assertNotIn( + expected_not_in, + str(err, encoding=sys.getdefaultencoding()) + ) + self.assertNotIn( + stripdir, + str(err, encoding=sys.getdefaultencoding()) + ) + def test_prepend_only(self): fullpath = ["test", "build", "real", "path"] path = os.path.join(self.directory, *fullpath) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 9180cca62b28b8..b057121f285dc7 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -109,6 +109,8 @@ def test_truediv(self): complex(random(), random())) self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) + self.assertRaises(TypeError, operator.truediv, 1j, None) + self.assertRaises(TypeError, operator.truediv, None, 1j) for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: z = complex(0, 0) / complex(denom_real, denom_imag) @@ -140,6 +142,7 @@ def test_floordiv_zero_division(self): def test_richcompare(self): self.assertIs(complex.__eq__(1+1j, 1<<10000), False) self.assertIs(complex.__lt__(1+1j, None), NotImplemented) + self.assertIs(complex.__eq__(1+1j, None), NotImplemented) self.assertIs(complex.__eq__(1+1j, 1+1j), True) self.assertIs(complex.__eq__(1+1j, 2+2j), False) self.assertIs(complex.__ne__(1+1j, 1+1j), False) @@ -162,6 +165,7 @@ def test_richcompare(self): self.assertIs(operator.eq(1+1j, 2+2j), False) self.assertIs(operator.ne(1+1j, 1+1j), False) self.assertIs(operator.ne(1+1j, 2+2j), True) + self.assertIs(operator.eq(1+1j, 2.0), False) def test_richcompare_boundaries(self): def check(n, deltas, is_equal, imag = 0.0): @@ -180,6 +184,27 @@ def check(n, deltas, is_equal, imag = 0.0): check(2 ** pow, range(1, 101), lambda delta: False, float(i)) check(2 ** 53, range(-100, 0), lambda delta: True) + def test_add(self): + self.assertEqual(1j + int(+1), complex(+1, 1)) + self.assertEqual(1j + int(-1), complex(-1, 1)) + self.assertRaises(OverflowError, operator.add, 1j, 10**1000) + self.assertRaises(TypeError, operator.add, 1j, None) + self.assertRaises(TypeError, operator.add, None, 1j) + + def test_sub(self): + self.assertEqual(1j - int(+1), complex(-1, 1)) + self.assertEqual(1j - int(-1), complex(1, 1)) + self.assertRaises(OverflowError, operator.sub, 1j, 10**1000) + self.assertRaises(TypeError, operator.sub, 1j, None) + self.assertRaises(TypeError, operator.sub, None, 1j) + + def test_mul(self): + self.assertEqual(1j * int(20), complex(0, 20)) + self.assertEqual(1j * int(-1), complex(0, -1)) + self.assertRaises(OverflowError, operator.mul, 1j, 10**1000) + self.assertRaises(TypeError, operator.mul, 1j, None) + self.assertRaises(TypeError, operator.mul, None, 1j) + def test_mod(self): # % is no longer supported on complex numbers with self.assertRaises(TypeError): @@ -212,11 +237,18 @@ def test_divmod_zero_division(self): def test_pow(self): self.assertAlmostEqual(pow(1+1j, 0+0j), 1.0) self.assertAlmostEqual(pow(0+0j, 2+0j), 0.0) + self.assertEqual(pow(0+0j, 2000+0j), 0.0) + self.assertEqual(pow(0, 0+0j), 1.0) + self.assertEqual(pow(-1, 0+0j), 1.0) self.assertRaises(ZeroDivisionError, pow, 0+0j, 1j) + self.assertRaises(ZeroDivisionError, pow, 0+0j, -1000) self.assertAlmostEqual(pow(1j, -1), 1/1j) self.assertAlmostEqual(pow(1j, 200), 1) self.assertRaises(ValueError, pow, 1+1j, 1+1j, 1+1j) self.assertRaises(OverflowError, pow, 1e200+1j, 1e200+1j) + self.assertRaises(TypeError, pow, 1j, None) + self.assertRaises(TypeError, pow, None, 1j) + self.assertAlmostEqual(pow(1j, 0.5), 0.7071067811865476+0.7071067811865475j) a = 3.33+4.43j self.assertEqual(a ** 0j, 1) @@ -301,6 +333,7 @@ def test_boolcontext(self): for i in range(100): self.assertTrue(complex(random() + 1e-6, random() + 1e-6)) self.assertTrue(not complex(0.0, 0.0)) + self.assertTrue(1j) def test_conjugate(self): self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) @@ -314,6 +347,8 @@ def __complex__(self): return self.value self.assertRaises(TypeError, complex, {}) self.assertRaises(TypeError, complex, NS(1.5)) self.assertRaises(TypeError, complex, NS(1)) + self.assertRaises(TypeError, complex, object()) + self.assertRaises(TypeError, complex, NS(4.25+0.5j), object()) self.assertAlmostEqual(complex("1+10j"), 1+10j) self.assertAlmostEqual(complex(10), 10+0j) @@ -359,6 +394,8 @@ def __complex__(self): return self.value self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) + self.assertEqual(complex('1-1j'), 1.0 - 1j) + self.assertEqual(complex('1J'), 1j) class complex2(complex): pass self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) @@ -553,6 +590,8 @@ def test_hash(self): x /= 3.0 # now check against floating point self.assertEqual(hash(x), hash(complex(x, 0.))) + self.assertNotEqual(hash(2000005 - 1j), -1) + def test_abs(self): nums = [complex(x/3., y/7.) for x in range(-9,9) for y in range(-9,9)] for num in nums: @@ -602,6 +641,14 @@ def test(v, expected, test_fn=self.assertEqual): test(complex(-0., 0.), "(-0+0j)") test(complex(-0., -0.), "(-0-0j)") + def test_pos(self): + class ComplexSubclass(complex): + pass + + self.assertEqual(+(1+6j), 1+6j) + self.assertEqual(+ComplexSubclass(1, 6), 1+6j) + self.assertIs(type(+ComplexSubclass(1, 6)), complex) + def test_neg(self): self.assertEqual(-(1+6j), -1-6j) diff --git a/Lib/test/test_concurrent_futures/test_deadlock.py b/Lib/test/test_concurrent_futures/test_deadlock.py index af702542081ad9..3c30c4558c0b3e 100644 --- a/Lib/test/test_concurrent_futures/test_deadlock.py +++ b/Lib/test/test_concurrent_futures/test_deadlock.py @@ -286,11 +286,12 @@ def wakeup(self): super().wakeup() def clear(self): + super().clear() try: while True: self._dummy_queue.get_nowait() except queue.Empty: - super().clear() + pass with (unittest.mock.patch.object(futures.process._ExecutorManagerThread, 'run', mock_run), diff --git a/Lib/test/test_concurrent_futures/test_process_pool.py b/Lib/test/test_concurrent_futures/test_process_pool.py index 7763a4946f110c..3e61b0c9387c6f 100644 --- a/Lib/test/test_concurrent_futures/test_process_pool.py +++ b/Lib/test/test_concurrent_futures/test_process_pool.py @@ -1,5 +1,6 @@ import os import sys +import threading import time import unittest from concurrent import futures @@ -187,6 +188,34 @@ def test_max_tasks_early_shutdown(self): 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_joinable_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_joinable_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_joinable_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, diff --git a/Lib/test/test_concurrent_futures/test_thread_pool.py b/Lib/test/test_concurrent_futures/test_thread_pool.py index 812f989d8f3ad2..5926a632aa4bec 100644 --- a/Lib/test/test_concurrent_futures/test_thread_pool.py +++ b/Lib/test/test_concurrent_futures/test_thread_pool.py @@ -25,7 +25,7 @@ def record_finished(n): def test_default_workers(self): executor = self.executor_type() - expected = min(32, (os.cpu_count() or 1) + 4) + expected = min(32, (os.process_cpu_count() or 1) + 4) self.assertEqual(executor._max_workers, expected) def test_saturation(self): diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 53163d7528b64a..2d7dfbde7082ee 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -543,7 +543,7 @@ def test_parse_errors(self): "[Foo]\n wrong-indent\n") self.assertEqual(e.args, ('',)) # read_file on a real file - tricky = support.findfile("cfgparser.3") + tricky = support.findfile("cfgparser.3", subdir="configdata") if self.delimiters[0] == '=': error = configparser.ParsingError expected = (tricky,) @@ -717,7 +717,7 @@ class mystr(str): def test_read_returns_file_list(self): if self.delimiters[0] != '=': self.skipTest('incompatible format') - file1 = support.findfile("cfgparser.1") + file1 = support.findfile("cfgparser.1", subdir="configdata") # check when we pass a mix of readable and non-readable files: cf = self.newconfig() parsed_files = cf.read([file1, "nonexistent-file"], encoding="utf-8") @@ -750,7 +750,7 @@ def test_read_returns_file_list(self): def test_read_returns_file_list_with_bytestring_path(self): if self.delimiters[0] != '=': self.skipTest('incompatible format') - file1_bytestring = support.findfile("cfgparser.1").encode() + file1_bytestring = support.findfile("cfgparser.1", subdir="configdata").encode() # check when passing an existing bytestring path cf = self.newconfig() parsed_files = cf.read(file1_bytestring, encoding="utf-8") @@ -1126,7 +1126,7 @@ class RawConfigParserTestSambaConf(CfgParserTestCaseClass, unittest.TestCase): empty_lines_in_values = False def test_reading(self): - smbconf = support.findfile("cfgparser.2") + smbconf = support.findfile("cfgparser.2", subdir="configdata") # check when we pass a mix of readable and non-readable files: cf = self.newconfig() parsed_files = cf.read([smbconf, "nonexistent-file"], encoding='utf-8') @@ -1321,7 +1321,7 @@ class ConfigParserTestCaseTrickyFile(CfgParserTestCaseClass, unittest.TestCase): allow_no_value = True def test_cfgparser_dot_3(self): - tricky = support.findfile("cfgparser.3") + tricky = support.findfile("cfgparser.3", subdir="configdata") cf = self.newconfig() self.assertEqual(len(cf.read(tricky, encoding='utf-8')), 1) self.assertEqual(cf.sections(), ['strange', @@ -1353,7 +1353,7 @@ def test_cfgparser_dot_3(self): self.assertEqual(cf.get('more interpolation', 'lets'), 'go shopping') def test_unicode_failure(self): - tricky = support.findfile("cfgparser.3") + tricky = support.findfile("cfgparser.3", subdir="configdata") cf = self.newconfig() with self.assertRaises(UnicodeDecodeError): cf.read(tricky, encoding='ascii') @@ -1454,7 +1454,7 @@ def fromstring(self, string, defaults=None): class FakeFile: def __init__(self): - file_path = support.findfile("cfgparser.1") + file_path = support.findfile("cfgparser.1", subdir="configdata") with open(file_path, encoding="utf-8") as f: self.lines = f.readlines() self.lines.reverse() @@ -1475,7 +1475,7 @@ def readline_generator(f): class ReadFileTestCase(unittest.TestCase): def test_file(self): - file_paths = [support.findfile("cfgparser.1")] + file_paths = [support.findfile("cfgparser.1", subdir="configdata")] try: file_paths.append(file_paths[0].encode('utf8')) except UnicodeEncodeError: diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index dbc7dfcc24bf07..36c3abca80f894 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -167,9 +167,46 @@ 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_no_yield(self): + @contextmanager + def whoo(): + if False: + yield + ctx = whoo() + with self.assertRaises(RuntimeError): + ctx.__enter__() + + 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_non_normalised(self): + @contextmanager + def whoo(): + try: + yield + except RuntimeError: + raise SyntaxError + + ctx = whoo() + ctx.__enter__() + with self.assertRaises(SyntaxError): + ctx.__exit__(RuntimeError, None, None) def test_contextmanager_except(self): state = [] @@ -250,6 +287,25 @@ def test_issue29692(): self.assertEqual(ex.args[0], 'issue29692:Unchained') self.assertIsNone(ex.__cause__) + def test_contextmanager_wrap_runtimeerror(self): + @contextmanager + def woohoo(): + try: + yield + except Exception as exc: + raise RuntimeError(f'caught {exc}') from exc + + with self.assertRaises(RuntimeError): + with woohoo(): + 1 / 0 + + # If the context manager wrapped StopIteration in a RuntimeError, + # we also unwrap it, because we can't tell whether the wrapping was + # done by the generator machinery or by the generator itself. + with self.assertRaises(StopIteration): + with woohoo(): + raise StopIteration + def _create_contextmanager_attribs(self): def attribs(**kw): def decorate(func): @@ -261,6 +317,7 @@ def decorate(func): @attribs(foo='bar') def baz(spam): """Whee!""" + yield return baz def test_contextmanager_attribs(self): @@ -317,8 +374,11 @@ def woohoo(a, *, b): def test_recursive(self): depth = 0 + ncols = 0 @contextmanager def woohoo(): + nonlocal ncols + ncols += 1 nonlocal depth before = depth depth += 1 @@ -332,6 +392,7 @@ def recursive(): recursive() recursive() + self.assertEqual(ncols, 10) self.assertEqual(depth, 0) @@ -1236,6 +1297,24 @@ def test_exception_groups(self): [KeyError("ke1"), KeyError("ke2")], ), ) + # Check handling of BaseExceptionGroup, using GeneratorExit so that + # we don't accidentally discard a ctrl-c with KeyboardInterrupt. + with suppress(GeneratorExit): + raise BaseExceptionGroup("message", [GeneratorExit()]) + # If we raise a BaseException group, we can still suppress parts + with self.assertRaises(BaseExceptionGroup) as eg1: + with suppress(KeyError): + raise BaseExceptionGroup("message", [GeneratorExit("g"), KeyError("k")]) + self.assertExceptionIsLike( + eg1.exception, BaseExceptionGroup("message", [GeneratorExit("g")]), + ) + # If we suppress all the leaf BaseExceptions, we get a non-base ExceptionGroup + with self.assertRaises(ExceptionGroup) as eg1: + with suppress(GeneratorExit): + raise BaseExceptionGroup("message", [GeneratorExit("g"), KeyError("k")]) + self.assertExceptionIsLike( + eg1.exception, ExceptionGroup("message", [KeyError("k")]), + ) class TestChdir(unittest.TestCase): @@ -1257,7 +1336,7 @@ def test_simple(self): def test_reentrant(self): old_cwd = os.getcwd() target1 = self.make_relative_path('data') - target2 = self.make_relative_path('ziptestdata') + target2 = self.make_relative_path('archivetestdata') self.assertNotIn(old_cwd, (target1, target2)) chdir1, chdir2 = chdir(target1), chdir(target2) diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index fa89c23f8edd91..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): @@ -561,13 +531,6 @@ def __exit__(self, *exc_details): ('__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 c66c6eeb00811e..89102373759ca0 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -936,14 +936,24 @@ def __replace__(self, **changes): def test_namedtuple(self): from collections import namedtuple - Point = namedtuple('Point', 'x y', defaults=(0,)) - p = Point(11, 22) - self.assertEqual(copy.replace(p), (11, 22)) - 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) + 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(TypeError, 'unexpected field name'): + copy.replace(p, x=1, error=2) def test_dataclass(self): from dataclasses import dataclass diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 47145782c0f04f..25c981d1511bc1 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2216,6 +2216,14 @@ async def f(): gen.cr_frame.clear() gen.close() + def test_cr_frame_after_close(self): + async def f(): + pass + gen = f() + self.assertIsNotNone(gen.cr_frame) + gen.close() + self.assertIsNone(gen.cr_frame) + def test_stack_in_coroutine_throw(self): # Regression test for /~https://github.com/python/cpython/issues/93592 async def a(): diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py index 74bf420900367e..c6039bd17b0662 100644 --- a/Lib/test/test_cppext/__init__.py +++ b/Lib/test/test_cppext/__init__.py @@ -2,18 +2,20 @@ # compatible with C++ and does not emit C++ compiler warnings. import os.path import shutil -import sys import unittest import subprocess import sysconfig from test import support -MS_WINDOWS = (sys.platform == 'win32') 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(support.Py_GIL_DISABLED, + 'test does not work with --disable-gil') @support.requires_subprocess() class TestCPPExt(unittest.TestCase): @support.requires_resource('cpu') @@ -26,7 +28,7 @@ def test_build_cpp03(self): # 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( diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py index 976633bc33889c..c7ba1efb4dd05a 100644 --- a/Lib/test/test_cppext/setup.py +++ b/Lib/test/test_cppext/setup.py @@ -4,15 +4,13 @@ import shlex import sys import sysconfig +from test import support from setuptools import setup, Extension -MS_WINDOWS = (sys.platform == 'win32') - - SOURCE = 'extension.cpp' -if not MS_WINDOWS: +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 diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 3056fe84dac5dd..27e8a767903777 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -83,8 +83,8 @@ def test_throw(self): for func, (cc, nc, _, _, _) in pr.stats.items(): if func[2] == "": - self.assertEqual(cc, 2) - self.assertEqual(nc, 2) + self.assertEqual(cc, 1) + self.assertEqual(nc, 1) class TestCommandLine(unittest.TestCase): diff --git a/Lib/test/test_ctypes/test_arrays.py b/Lib/test/test_ctypes/test_arrays.py index f7a4b5df514e5b..6b6cebd3e20285 100644 --- a/Lib/test/test_ctypes/test_arrays.py +++ b/Lib/test/test_ctypes/test_arrays.py @@ -189,10 +189,10 @@ def test_bad_subclass(self): class T(Array): pass with self.assertRaises(AttributeError): - class T(Array): + class T2(Array): _type_ = c_int with self.assertRaises(AttributeError): - class T(Array): + class T3(Array): _length_ = 13 def test_bad_length(self): @@ -201,15 +201,15 @@ class T(Array): _type_ = c_int _length_ = - sys.maxsize * 2 with self.assertRaises(ValueError): - class T(Array): + class T2(Array): _type_ = c_int _length_ = -1 with self.assertRaises(TypeError): - class T(Array): + class T3(Array): _type_ = c_int _length_ = 1.87 with self.assertRaises(OverflowError): - class T(Array): + class T4(Array): _type_ = c_int _length_ = sys.maxsize * 2 diff --git a/Lib/test/test_ctypes/test_callbacks.py b/Lib/test/test_ctypes/test_callbacks.py index 6fe3e119672409..19f4158c0ac846 100644 --- a/Lib/test/test_ctypes/test_callbacks.py +++ b/Lib/test/test_ctypes/test_callbacks.py @@ -322,9 +322,9 @@ def func(): self.assertIsInstance(cm.unraisable.exc_value, TypeError) self.assertEqual(cm.unraisable.err_msg, - "Exception ignored on converting result " - "of ctypes callback function") - self.assertIs(cm.unraisable.object, func) + f"Exception ignored on converting result " + f"of ctypes callback function {func!r}") + self.assertIsNone(cm.unraisable.object) if __name__ == '__main__': diff --git a/Lib/test/test_ctypes/test_functions.py b/Lib/test/test_ctypes/test_functions.py index 08eecbc9ea4442..04e8582ff1e427 100644 --- a/Lib/test/test_ctypes/test_functions.py +++ b/Lib/test/test_ctypes/test_functions.py @@ -46,15 +46,15 @@ class X(object, Array): _type_ = "i" with self.assertRaises(TypeError): - class X(object, _Pointer): + class X2(object, _Pointer): pass with self.assertRaises(TypeError): - class X(object, _SimpleCData): + class X3(object, _SimpleCData): _type_ = "i" with self.assertRaises(TypeError): - class X(object, Structure): + class X4(object, Structure): _fields_ = [] def test_c_char_parm(self): diff --git a/Lib/test/test_ctypes/test_random_things.py b/Lib/test/test_ctypes/test_random_things.py index 65eb53f86475d3..630f6ed9489eba 100644 --- a/Lib/test/test_ctypes/test_random_things.py +++ b/Lib/test/test_ctypes/test_random_things.py @@ -51,9 +51,9 @@ def expect_unraisable(self, exc_type, exc_msg=None): if exc_msg is not None: self.assertEqual(str(cm.unraisable.exc_value), exc_msg) self.assertEqual(cm.unraisable.err_msg, - "Exception ignored on calling ctypes " - "callback function") - self.assertIs(cm.unraisable.object, callback_func) + f"Exception ignored on calling ctypes " + f"callback function {callback_func!r}") + self.assertIsNone(cm.unraisable.object) def test_ValueError(self): cb = CFUNCTYPE(c_int, c_int)(callback_func) diff --git a/Lib/test/test_ctypes/test_structures.py b/Lib/test/test_ctypes/test_structures.py index f05ee5e491a41e..21039f04947507 100644 --- a/Lib/test/test_ctypes/test_structures.py +++ b/Lib/test/test_ctypes/test_structures.py @@ -1,13 +1,15 @@ import _ctypes_test +import platform import struct import sys import unittest -from ctypes import (CDLL, Structure, Union, POINTER, sizeof, byref, alignment, +from ctypes import (CDLL, Array, Structure, Union, POINTER, sizeof, byref, alignment, c_void_p, c_char, c_wchar, c_byte, c_ubyte, c_uint8, c_uint16, c_uint32, c_short, c_ushort, c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong, c_float, c_double) from struct import calcsize +from collections import namedtuple from test import support @@ -473,34 +475,53 @@ class X(Structure): def test_array_in_struct(self): # See bpo-22273 + # Load the shared library + dll = CDLL(_ctypes_test.__file__) + # These should mirror the structures in Modules/_ctypes/_ctypes_test.c class Test2(Structure): _fields_ = [ ('data', c_ubyte * 16), ] - class Test3(Structure): + class Test3AParent(Structure): + _fields_ = [ + ('data', c_float * 2), + ] + + class Test3A(Test3AParent): + _fields_ = [ + ('more_data', c_float * 2), + ] + + class Test3B(Structure): _fields_ = [ ('data', c_double * 2), ] - class Test3A(Structure): + class Test3C(Structure): _fields_ = [ - ('data', c_float * 2), + ("data", c_double * 4) ] - class Test3B(Test3A): + class Test3D(Structure): _fields_ = [ - ('more_data', c_float * 2), + ("data", c_double * 8) + ] + + class Test3E(Structure): + _fields_ = [ + ("data", c_double * 9) ] + + # Tests for struct Test2 s = Test2() expected = 0 for i in range(16): s.data[i] = i expected += i - dll = CDLL(_ctypes_test.__file__) - func = dll._testfunc_array_in_struct1 + func = dll._testfunc_array_in_struct2 func.restype = c_int func.argtypes = (Test2,) result = func(s) @@ -509,29 +530,16 @@ class Test3B(Test3A): for i in range(16): self.assertEqual(s.data[i], i) - s = Test3() - s.data[0] = 3.14159 - s.data[1] = 2.71828 - expected = 3.14159 + 2.71828 - func = dll._testfunc_array_in_struct2 - func.restype = c_double - func.argtypes = (Test3,) - result = func(s) - self.assertEqual(result, expected) - # check the passed-in struct hasn't changed - self.assertEqual(s.data[0], 3.14159) - self.assertEqual(s.data[1], 2.71828) - - s = Test3B() + # Tests for struct Test3A + s = Test3A() s.data[0] = 3.14159 s.data[1] = 2.71828 s.more_data[0] = -3.0 s.more_data[1] = -2.0 - - expected = 3.14159 + 2.71828 - 5.0 - func = dll._testfunc_array_in_struct2a + expected = 3.14159 + 2.71828 - 3.0 - 2.0 + func = dll._testfunc_array_in_struct3A func.restype = c_double - func.argtypes = (Test3B,) + func.argtypes = (Test3A,) result = func(s) self.assertAlmostEqual(result, expected, places=6) # check the passed-in struct hasn't changed @@ -540,6 +548,61 @@ class Test3B(Test3A): self.assertAlmostEqual(s.more_data[0], -3.0, places=6) self.assertAlmostEqual(s.more_data[1], -2.0, places=6) + # Test3B, Test3C, Test3D, Test3E have the same logic with different + # sizes hence putting them in a loop. + StructCtype = namedtuple( + "StructCtype", + ["cls", "cfunc1", "cfunc2", "items"] + ) + structs_to_test = [ + StructCtype( + Test3B, + dll._testfunc_array_in_struct3B, + dll._testfunc_array_in_struct3B_set_defaults, + 2), + StructCtype( + Test3C, + dll._testfunc_array_in_struct3C, + dll._testfunc_array_in_struct3C_set_defaults, + 4), + StructCtype( + Test3D, + dll._testfunc_array_in_struct3D, + dll._testfunc_array_in_struct3D_set_defaults, + 8), + StructCtype( + Test3E, + dll._testfunc_array_in_struct3E, + dll._testfunc_array_in_struct3E_set_defaults, + 9), + ] + + for sut in structs_to_test: + s = sut.cls() + + # Test for cfunc1 + expected = 0 + for i in range(sut.items): + float_i = float(i) + s.data[i] = float_i + expected += float_i + func = sut.cfunc1 + func.restype = c_double + func.argtypes = (sut.cls,) + result = func(s) + self.assertEqual(result, expected) + # check the passed-in struct hasn't changed + for i in range(sut.items): + self.assertEqual(s.data[i], float(i)) + + # Test for cfunc2 + func = sut.cfunc2 + func.restype = sut.cls + result = func() + # check if the default values have been set correctly + for i in range(sut.items): + self.assertEqual(result.data[i], float(i+1)) + def test_38368(self): class U(Union): _fields_ = [ diff --git a/Lib/test/test_dataclasses/__init__.py b/Lib/test/test_dataclasses/__init__.py index 7c07dfc77de208..272d427875ae40 100644 --- a/Lib/test/test_dataclasses/__init__.py +++ b/Lib/test/test_dataclasses/__init__.py @@ -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: @@ -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) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index bd299483e7b0bd..7a5fe62b467372 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -1222,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 diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py index 4b492178c1581f..3a4fc959f6f8a7 100644 --- a/Lib/test/test_decorators.py +++ b/Lib/test/test_decorators.py @@ -291,44 +291,6 @@ def bar(): return 42 self.assertEqual(bar(), 42) self.assertEqual(actions, expected_actions) - def test_wrapped_descriptor_inside_classmethod(self): - class BoundWrapper: - def __init__(self, wrapped): - self.__wrapped__ = wrapped - - def __call__(self, *args, **kwargs): - return self.__wrapped__(*args, **kwargs) - - class Wrapper: - def __init__(self, wrapped): - self.__wrapped__ = wrapped - - def __get__(self, instance, owner): - bound_function = self.__wrapped__.__get__(instance, owner) - return BoundWrapper(bound_function) - - def decorator(wrapped): - return Wrapper(wrapped) - - class Class: - @decorator - @classmethod - def inner(cls): - # This should already work. - return 'spam' - - @classmethod - @decorator - def outer(cls): - # Raised TypeError with a message saying that the 'Wrapper' - # object is not callable. - return 'eggs' - - self.assertEqual(Class.inner(), 'spam') - self.assertEqual(Class.outer(), 'eggs') - self.assertEqual(Class().inner(), 'spam') - self.assertEqual(Class().outer(), 'eggs') - def test_bound_function_inside_classmethod(self): class A: def foo(self, cls): @@ -339,91 +301,6 @@ class B: self.assertEqual(B.bar(), 'spam') - def test_wrapped_classmethod_inside_classmethod(self): - class MyClassMethod1: - def __init__(self, func): - self.func = func - - def __call__(self, cls): - if hasattr(self.func, '__get__'): - return self.func.__get__(cls, cls)() - return self.func(cls) - - def __get__(self, instance, owner=None): - if owner is None: - owner = type(instance) - return MethodType(self, owner) - - class MyClassMethod2: - def __init__(self, func): - if isinstance(func, classmethod): - func = func.__func__ - self.func = func - - def __call__(self, cls): - return self.func(cls) - - def __get__(self, instance, owner=None): - if owner is None: - owner = type(instance) - return MethodType(self, owner) - - for myclassmethod in [MyClassMethod1, MyClassMethod2]: - class A: - @myclassmethod - def f1(cls): - return cls - - @classmethod - @myclassmethod - def f2(cls): - return cls - - @myclassmethod - @classmethod - def f3(cls): - return cls - - @classmethod - @classmethod - def f4(cls): - return cls - - @myclassmethod - @MyClassMethod1 - def f5(cls): - return cls - - @myclassmethod - @MyClassMethod2 - def f6(cls): - return cls - - self.assertIs(A.f1(), A) - self.assertIs(A.f2(), A) - self.assertIs(A.f3(), A) - self.assertIs(A.f4(), A) - self.assertIs(A.f5(), A) - self.assertIs(A.f6(), A) - a = A() - self.assertIs(a.f1(), A) - self.assertIs(a.f2(), A) - self.assertIs(a.f3(), A) - self.assertIs(a.f4(), A) - self.assertIs(a.f5(), A) - self.assertIs(a.f6(), A) - - def f(cls): - return cls - - self.assertIs(myclassmethod(f).__get__(a)(), A) - self.assertIs(myclassmethod(f).__get__(a, A)(), A) - self.assertIs(myclassmethod(f).__get__(A, A)(), A) - self.assertIs(myclassmethod(f).__get__(A)(), type(A)) - self.assertIs(classmethod(f).__get__(a)(), A) - self.assertIs(classmethod(f).__get__(a, A)(), A) - self.assertIs(classmethod(f).__get__(A, A)(), A) - self.assertIs(classmethod(f).__get__(A)(), type(A)) class TestClassDecorators(unittest.TestCase): diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 8ab0e1ecbc4a7f..12e2c57e50b0ba 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -13,6 +13,7 @@ import opcode +CACHE = dis.opmap["CACHE"] def get_tb(): def _error(): @@ -42,45 +43,45 @@ def cm(cls, x): cls.x = x == 1 dis_c_instance_method = """\ -%3d RESUME 0 - -%3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (self) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (self) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ - RESUME 0 - LOAD_FAST 1 - LOAD_CONST 1 - COMPARE_OP 72 (==) - LOAD_FAST 0 - STORE_ATTR 0 - RETURN_CONST 0 + RESUME 0 + LOAD_FAST 1 + LOAD_CONST 1 + COMPARE_OP 72 (==) + LOAD_FAST 0 + STORE_ATTR 0 + RETURN_CONST 0 """ dis_c_class_method = """\ -%3d RESUME 0 - -%3d LOAD_FAST 1 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - LOAD_FAST 0 (cls) - STORE_ATTR 0 (x) - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + LOAD_FAST 0 (cls) + STORE_ATTR 0 (x) + RETURN_CONST 0 (None) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_FAST 0 (x) - LOAD_CONST 1 (1) - COMPARE_OP 72 (==) - STORE_FAST 0 (x) - RETURN_CONST 0 (None) +%3d LOAD_FAST 0 (x) + LOAD_CONST 1 (1) + COMPARE_OP 72 (==) + STORE_FAST 0 (x) + RETURN_CONST 0 (None) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -100,51 +101,63 @@ def _f(a): return 1 dis_f = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_GLOBAL 1 (print + NULL) - LOAD_FAST 0 (a) - CALL 1 - POP_TOP +%3d LOAD_GLOBAL 1 (print + NULL) + LOAD_FAST 0 (a) + CALL 1 + POP_TOP -%3d RETURN_CONST 1 (1) +%3d RETURN_CONST 1 (1) +""" % (_f.__code__.co_firstlineno, + _f.__code__.co_firstlineno + 1, + _f.__code__.co_firstlineno + 2) + +dis_f_with_offsets = """\ +%3d 0 RESUME 0 + +%3d 2 LOAD_GLOBAL 1 (print + NULL) + 12 LOAD_FAST 0 (a) + 14 CALL 1 + 22 POP_TOP + +%3d 24 RETURN_CONST 1 (1) """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) dis_f_co_code = """\ - RESUME 0 - LOAD_GLOBAL 1 - LOAD_FAST 0 - CALL 1 - POP_TOP - RETURN_CONST 1 + RESUME 0 + LOAD_GLOBAL 1 + LOAD_FAST 0 + CALL 1 + POP_TOP + RETURN_CONST 1 """ - def bug708901(): for res in range(1, 10): pass dis_bug708901 = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_GLOBAL 1 (range + NULL) - LOAD_CONST 1 (1) +%3d LOAD_GLOBAL 1 (range + NULL) + LOAD_CONST 1 (1) -%3d LOAD_CONST 2 (10) +%3d LOAD_CONST 2 (10) -%3d CALL 2 - GET_ITER - >> FOR_ITER 3 (to 36) - STORE_FAST 0 (res) +%3d CALL 2 + GET_ITER + L1: FOR_ITER 3 (to L2) + STORE_FAST 0 (res) -%3d JUMP_BACKWARD 5 (to 26) +%3d JUMP_BACKWARD 5 (to L1) -%3d >> END_FOR - RETURN_CONST 0 (None) +%3d L2: END_FOR + RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -159,20 +172,20 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ -%3d RESUME 0 +%3d RESUME 0 -%3d LOAD_ASSERTION_ERROR - LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - MAKE_FUNCTION - LOAD_FAST 0 (x) - GET_ITER - CALL 0 +%3d LOAD_ASSERTION_ERROR + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION + LOAD_FAST 0 (x) + GET_ITER + CALL 0 -%3d LOAD_CONST 2 (1) +%3d LOAD_CONST 2 (1) -%3d BINARY_OP 0 (+) - CALL 0 - RAISE_VARARGS 1 +%3d BINARY_OP 0 (+) + CALL 0 + RAISE_VARARGS 1 """ % (bug1333982.__code__.co_firstlineno, bug1333982.__code__.co_firstlineno + 1, __file__, @@ -190,8 +203,8 @@ def bug42562(): dis_bug42562 = """\ - RESUME 0 - RETURN_CONST 0 (None) + RESUME 0 + RETURN_CONST 0 (None) """ # Extended arg followed by NOP @@ -204,11 +217,11 @@ def bug42562(): ]) dis_bug_45757 = """\ - EXTENDED_ARG 1 - NOP - EXTENDED_ARG 1 - LOAD_CONST 297 - RETURN_VALUE + EXTENDED_ARG 1 + NOP + EXTENDED_ARG 1 + LOAD_CONST 297 + RETURN_VALUE """ # [255, 255, 255, 252] is -4 in a 4 byte signed integer @@ -221,10 +234,10 @@ def bug42562(): dis_bug46724 = """\ - >> EXTENDED_ARG 255 - EXTENDED_ARG 65535 - EXTENDED_ARG 16777215 - JUMP_FORWARD -4 (to 0) + L1: EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to L1) """ def func_w_kwargs(a, b, **c): @@ -234,96 +247,96 @@ def wrap_func_w_kwargs(): func_w_kwargs(1, 2, c=5) dis_kw_names = """\ -%3d RESUME 0 - -%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) - LOAD_CONST 1 (1) - LOAD_CONST 2 (2) - LOAD_CONST 3 (5) - LOAD_CONST 4 (('c',)) - CALL_KW 3 - POP_TOP - RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_GLOBAL 1 (func_w_kwargs + NULL) + LOAD_CONST 1 (1) + LOAD_CONST 2 (2) + LOAD_CONST 3 (5) + LOAD_CONST 4 (('c',)) + CALL_KW 3 + POP_TOP + RETURN_CONST 0 (None) """ % (wrap_func_w_kwargs.__code__.co_firstlineno, wrap_func_w_kwargs.__code__.co_firstlineno + 1) dis_intrinsic_1_2 = """\ - 0 RESUME 0 - - 1 LOAD_CONST 0 (0) - LOAD_CONST 1 (('*',)) - IMPORT_NAME 0 (math) - CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) - POP_TOP - RETURN_CONST 2 (None) + 0 RESUME 0 + + 1 LOAD_CONST 0 (0) + LOAD_CONST 1 (('*',)) + IMPORT_NAME 0 (math) + CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) + POP_TOP + RETURN_CONST 2 (None) """ dis_intrinsic_1_5 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (a) - CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) - RETURN_VALUE + 1 LOAD_NAME 0 (a) + CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) + RETURN_VALUE """ dis_intrinsic_1_6 = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 BUILD_LIST 0 - LOAD_NAME 0 (a) - LIST_EXTEND 1 - CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) - RETURN_VALUE + 1 BUILD_LIST 0 + LOAD_NAME 0 (a) + LIST_EXTEND 1 + CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) + RETURN_VALUE """ _BIG_LINENO_FORMAT = """\ - 1 RESUME 0 + 1 RESUME 0 -%3d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) +%3d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ _BIG_LINENO_FORMAT2 = """\ - 1 RESUME 0 + 1 RESUME 0 -%4d LOAD_GLOBAL 0 (spam) - POP_TOP - RETURN_CONST 0 (None) +%4d LOAD_GLOBAL 0 (spam) + POP_TOP + RETURN_CONST 0 (None) """ dis_module_expected_results = """\ Disassembly of f: - 4 RESUME 0 - RETURN_CONST 0 (None) + 4 RESUME 0 + RETURN_CONST 0 (None) Disassembly of g: - 5 RESUME 0 - RETURN_CONST 0 (None) + 5 RESUME 0 + RETURN_CONST 0 (None) """ expr_str = "x + 1" dis_expr_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - RETURN_VALUE + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + RETURN_VALUE """ simple_stmt_str = "x = x + 1" dis_simple_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_NAME 0 (x) - LOAD_CONST 0 (1) - BINARY_OP 0 (+) - STORE_NAME 0 (x) - RETURN_CONST 1 (None) + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + STORE_NAME 0 (x) + RETURN_CONST 1 (None) """ annot_stmt_str = """\ @@ -335,34 +348,34 @@ def wrap_func_w_kwargs(): # leading newline is for a reason (tests lineno) dis_annot_stmt_str = """\ - 0 RESUME 0 - - 2 SETUP_ANNOTATIONS - LOAD_CONST 0 (1) - STORE_NAME 0 (x) - LOAD_NAME 1 (int) - LOAD_NAME 2 (__annotations__) - LOAD_CONST 1 ('x') - STORE_SUBSCR - - 3 LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 0 (1) - CALL 1 - LOAD_NAME 2 (__annotations__) - LOAD_CONST 2 ('y') - STORE_SUBSCR - - 4 LOAD_CONST 0 (1) - LOAD_NAME 4 (lst) - LOAD_NAME 3 (fun) - PUSH_NULL - LOAD_CONST 3 (0) - CALL 1 - STORE_SUBSCR - LOAD_NAME 1 (int) - POP_TOP - RETURN_CONST 4 (None) + 0 RESUME 0 + + 2 SETUP_ANNOTATIONS + LOAD_CONST 0 (1) + STORE_NAME 0 (x) + LOAD_NAME 1 (int) + LOAD_NAME 2 (__annotations__) + LOAD_CONST 1 ('x') + STORE_SUBSCR + + 3 LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 0 (1) + CALL 1 + LOAD_NAME 2 (__annotations__) + LOAD_CONST 2 ('y') + STORE_SUBSCR + + 4 LOAD_CONST 0 (1) + LOAD_NAME 4 (lst) + LOAD_NAME 3 (fun) + PUSH_NULL + LOAD_CONST 3 (0) + CALL 1 + STORE_SUBSCR + LOAD_NAME 1 (int) + POP_TOP + RETURN_CONST 4 (None) """ compound_stmt_str = """\ @@ -372,64 +385,67 @@ def wrap_func_w_kwargs(): # Trailing newline has been deliberately omitted dis_compound_stmt_str = """\ - 0 RESUME 0 + 0 RESUME 0 - 1 LOAD_CONST 0 (0) - STORE_NAME 0 (x) + 1 LOAD_CONST 0 (0) + STORE_NAME 0 (x) - 2 NOP + 2 NOP - 3 >> LOAD_NAME 0 (x) - LOAD_CONST 1 (1) - BINARY_OP 13 (+=) - STORE_NAME 0 (x) + 3 L1: LOAD_NAME 0 (x) + LOAD_CONST 1 (1) + BINARY_OP 13 (+=) + STORE_NAME 0 (x) - 2 JUMP_BACKWARD 7 (to 8) + 2 JUMP_BACKWARD 7 (to L1) """ dis_traceback = """\ -%4d RESUME 0 +%4d RESUME 0 -%4d NOP +%4d NOP -%4d LOAD_CONST 1 (1) - LOAD_CONST 2 (0) - --> BINARY_OP 11 (/) - POP_TOP +%4d L1: LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP -%4d LOAD_FAST_CHECK 1 (tb) - RETURN_VALUE +%4d L2: LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE -None >> PUSH_EXC_INFO + -- L3: PUSH_EXC_INFO -%4d LOAD_GLOBAL 0 (Exception) - CHECK_EXC_MATCH - POP_JUMP_IF_FALSE 23 (to 82) - STORE_FAST 0 (e) +%4d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to L7) + 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 L4: LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) + L5: POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) -%4d LOAD_FAST 1 (tb) - RETURN_VALUE +%4d LOAD_FAST 1 (tb) + RETURN_VALUE -None >> LOAD_CONST 0 (None) - STORE_FAST 0 (e) - DELETE_FAST 0 (e) - RERAISE 1 + -- L6: LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 -%4d >> RERAISE 0 +%4d L7: RERAISE 0 -None >> COPY 3 - POP_EXCEPT - RERAISE 1 + -- L8: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: -4 rows + L1 to L2 -> L3 [0] + L3 to L4 -> L8 [1] lasti + L4 to L5 -> L6 [1] lasti + L6 to L8 -> L8 [1] lasti """ % (TRACEBACK_CODE.co_firstlineno, TRACEBACK_CODE.co_firstlineno + 1, TRACEBACK_CODE.co_firstlineno + 2, @@ -443,25 +459,25 @@ def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' dis_fstring = """\ -%3d RESUME 0 - -%3d LOAD_FAST 0 (a) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 1 (b) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - LOAD_CONST 1 (' ') - LOAD_FAST 2 (c) - CONVERT_VALUE 2 (repr) - FORMAT_SIMPLE - LOAD_CONST 1 (' ') - LOAD_FAST 3 (d) - CONVERT_VALUE 2 (repr) - LOAD_CONST 2 ('4') - FORMAT_WITH_SPEC - BUILD_STRING 7 - RETURN_VALUE +%3d RESUME 0 + +%3d LOAD_FAST 0 (a) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 1 (b) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + LOAD_CONST 1 (' ') + LOAD_FAST 2 (c) + CONVERT_VALUE 2 (repr) + FORMAT_SIMPLE + LOAD_CONST 1 (' ') + LOAD_FAST 3 (d) + CONVERT_VALUE 2 (repr) + LOAD_CONST 2 ('4') + FORMAT_WITH_SPEC + BUILD_STRING 7 + RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) def _with(c): @@ -470,44 +486,45 @@ def _with(c): y = 2 dis_with = """\ -%4d RESUME 0 - -%4d LOAD_FAST 0 (c) - BEFORE_WITH - 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 - POP_TOP - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -%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 - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -None >> COPY 3 - POP_EXCEPT - RERAISE 1 +%4d RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_WITH + L1: POP_TOP + +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d L2: LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%4d L3: PUSH_EXC_INFO + WITH_EXCEPT_START + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L4) + RERAISE 2 + L4: POP_TOP + L5: POP_EXCEPT + POP_TOP + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + + -- L6: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: -2 rows + L1 to L2 -> L3 [1] lasti + L3 to L5 -> L6 [3] lasti """ % (_with.__code__.co_firstlineno, _with.__code__.co_firstlineno + 1, _with.__code__.co_firstlineno + 2, @@ -523,78 +540,89 @@ async def _asyncwith(c): y = 2 dis_asyncwith = """\ -%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 - -%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 - -%4d LOAD_CONST 2 (2) - STORE_FAST 2 (y) - RETURN_CONST 0 (None) - -%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 - -%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 +%4d RETURN_GENERATOR + POP_TOP + L1: RESUME 0 + +%4d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) + L2: SEND 3 (to L5) + L3: YIELD_VALUE 1 + L4: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L2) + L5: END_SEND + L6: POP_TOP + +%4d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%4d L7: LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + L8: SEND 3 (to L11) + L9: YIELD_VALUE 1 + L10: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L8) + L11: END_SEND + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%4d L12: CLEANUP_THROW + + -- L13: JUMP_BACKWARD 26 (to L5) + +%4d L14: CLEANUP_THROW + + -- L15: JUMP_BACKWARD 11 (to L11) + +%4d L16: PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + L17: SEND 4 (to L21) + L18: YIELD_VALUE 1 + L19: RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to L17) + L20: CLEANUP_THROW + L21: END_SEND + TO_BOOL + POP_JUMP_IF_TRUE 1 (to L22) + RERAISE 2 + L22: POP_TOP + L23: POP_EXCEPT + POP_TOP + POP_TOP + +%4d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + + -- L24: COPY 3 + POP_EXCEPT + RERAISE 1 + L25: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: -12 rows + L1 to L3 -> L25 [0] lasti + L3 to L4 -> L12 [3] + L4 to L6 -> L25 [0] lasti + L6 to L7 -> L16 [1] lasti + L7 to L9 -> L25 [0] lasti + L9 to L10 -> L14 [2] + L10 to L13 -> L25 [0] lasti + L14 to L15 -> L25 [0] lasti + L16 to L18 -> L24 [3] lasti + L18 to L19 -> L20 [6] + L19 to L23 -> L24 [3] lasti + L23 to L25 -> L25 [0] lasti """ % (_asyncwith.__code__.co_firstlineno, _asyncwith.__code__.co_firstlineno + 1, _asyncwith.__code__.co_firstlineno + 2, @@ -620,31 +648,32 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ -%4d RESUME 0 +%4d RESUME 0 -%4d NOP +%4d NOP -%4d LOAD_FAST 0 (a) +%4d L1: LOAD_FAST 0 (a) -%4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_VALUE +%4d L2: LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_VALUE -None >> PUSH_EXC_INFO + -- L3: PUSH_EXC_INFO -%4d LOAD_FAST 1 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 +%4d LOAD_FAST 1 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -None >> COPY 3 - POP_EXCEPT - RERAISE 1 + -- L4: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: -2 rows + L1 to L2 -> L3 [0] + L3 to L4 -> L4 [1] lasti """ % (_tryfinally.__code__.co_firstlineno, _tryfinally.__code__.co_firstlineno + 1, _tryfinally.__code__.co_firstlineno + 2, @@ -653,31 +682,31 @@ def _tryfinallyconst(b): ) dis_tryfinallyconst = """\ -%4d RESUME 0 +%4d RESUME 0 -%4d NOP +%4d NOP -%4d NOP +%4d NOP -%4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RETURN_CONST 1 (1) +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RETURN_CONST 1 (1) -None PUSH_EXC_INFO + -- L1: PUSH_EXC_INFO -%4d LOAD_FAST 0 (b) - PUSH_NULL - CALL 0 - POP_TOP - RERAISE 0 +%4d LOAD_FAST 0 (b) + PUSH_NULL + CALL 0 + POP_TOP + RERAISE 0 -None >> COPY 3 - POP_EXCEPT - RERAISE 1 + -- L2: COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: -1 row + L1 to L2 -> L2 [1] lasti """ % (_tryfinallyconst.__code__.co_firstlineno, _tryfinallyconst.__code__.co_firstlineno + 1, _tryfinallyconst.__code__.co_firstlineno + 2, @@ -702,19 +731,19 @@ def foo(x): return foo dis_nested_0 = """\ -None MAKE_CELL 0 (y) + -- MAKE_CELL 0 (y) -%4d RESUME 0 +%4d RESUME 0 -%4d 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) -%4d LOAD_FAST 1 (foo) - RETURN_VALUE +%4d LOAD_FAST 1 (foo) + RETURN_VALUE """ % (_h.__code__.co_firstlineno, _h.__code__.co_firstlineno + 1, __file__, @@ -724,22 +753,22 @@ def foo(x): dis_nested_1 = """%s Disassembly of : -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 + -- 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, @@ -751,28 +780,28 @@ def foo(x): dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: -None COPY_FREE_VARS 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 + -- COPY_FREE_VARS 1 + +%4d RETURN_GENERATOR + POP_TOP + L1: RESUME 0 + LOAD_FAST 0 (.0) + L2: FOR_ITER 10 (to L3) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + YIELD_VALUE 0 + RESUME 5 + POP_TOP + JUMP_BACKWARD 12 (to L2) + L3: END_FOR + RETURN_CONST 0 (None) + + -- L4: CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 ExceptionTable: -1 row + L1 to L4 -> L4 [0] lasti """ % (dis_nested_1, __file__, _h.__code__.co_firstlineno + 3, @@ -784,14 +813,14 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d 0 RESUME_CHECK 0 +%3d RESUME_CHECK 0 -%3d 2 LOAD_FAST_LOAD_FAST 1 (x, y) - 4 STORE_FAST_STORE_FAST 50 (b, a) +%3d LOAD_FAST_LOAD_FAST 1 (x, y) + STORE_FAST_STORE_FAST 50 (b, a) -%3d 6 LOAD_FAST_LOAD_FAST 35 (a, b) - 8 BUILD_TUPLE 2 - 10 RETURN_VALUE +%3d LOAD_FAST_LOAD_FAST 35 (a, b) + BUILD_TUPLE 2 + RETURN_VALUE """ % (load_test.__code__.co_firstlineno, load_test.__code__.co_firstlineno + 1, load_test.__code__.co_firstlineno + 2) @@ -801,25 +830,25 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d RESUME_CHECK 0 - -%3d BUILD_LIST 0 - LOAD_CONST 1 ((1, 2, 3)) - LIST_EXTEND 1 - LOAD_CONST 2 (3) - BINARY_OP 5 (*) - GET_ITER - >> FOR_ITER_LIST 14 (to 48) - STORE_FAST 0 (i) - -%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) - LOAD_FAST 0 (i) - CALL_PY_WITH_DEFAULTS 1 - POP_TOP - JUMP_BACKWARD 16 (to 16) - -%3d >> END_FOR - RETURN_CONST 0 (None) +%3d RESUME_CHECK 0 + +%3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER + L1: FOR_ITER_LIST 14 (to L2) + STORE_FAST 0 (i) + +%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 16 (to L1) + +%3d L2: END_FOR + RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -829,14 +858,14 @@ def extended_arg_quick(): *_, _ = ... dis_extended_arg_quick_code = """\ -%3d 0 RESUME 0 - -%3d 2 LOAD_CONST 1 (Ellipsis) - 4 EXTENDED_ARG 1 - 6 UNPACK_EX 256 - 8 POP_TOP - 10 STORE_FAST 0 (_) - 12 RETURN_CONST 0 (None) +%3d RESUME 0 + +%3d LOAD_CONST 1 (Ellipsis) + EXTENDED_ARG 1 + UNPACK_EX 256 + POP_TOP + STORE_FAST 0 (_) + RETURN_CONST 0 (None) """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) @@ -848,74 +877,19 @@ class DisTestBase(unittest.TestCase): def strip_addresses(self, text): return re.sub(r'\b0x[0-9A-Fa-f]+\b', '0x...', text) - def find_offset_column(self, lines): - for line in lines: - if line and not line.startswith("Disassembly"): - break - else: - return 0, 0 - offset = 5 - while (line[offset] == " "): - offset += 1 - if (line[offset] == ">"): - offset += 2 - while (line[offset] == " "): - offset += 1 - end = offset - while line[end] in "0123456789": - end += 1 - return end-5, end - - def assert_offsets_increasing(self, text, delta): - expected_offset = 0 - lines = text.splitlines() - start, end = self.find_offset_column(lines) - for line in lines: - if not line: - continue - if line.startswith("Disassembly"): - expected_offset = 0 - continue - if line.startswith("Exception"): - break - offset = int(line[start:end]) - self.assertGreaterEqual(offset, expected_offset, line) - expected_offset = offset + delta - def assert_exception_table_increasing(self, lines): prev_start, prev_end = -1, -1 count = 0 for line in lines: - m = re.match(r' (\d+) to (\d+) -> \d+ \[\d+\]', line) + m = re.match(r' L(\d+) to L(\d+) -> L\d+ \[\d+\]', line) start, end = [int(g) for g in m.groups()] self.assertGreaterEqual(end, start) - self.assertGreater(start, prev_end) + self.assertGreaterEqual(start, prev_end) prev_start, prev_end = start, end count += 1 return count - def strip_offsets(self, text): - lines = text.splitlines(True) - start, end = self.find_offset_column(lines) - res = [] - lines = iter(lines) - for line in lines: - if line.startswith("Exception"): - res.append(line) - break - if not line or line.startswith("Disassembly"): - res.append(line) - else: - res.append(line[:start] + line[end:]) - num_rows = self.assert_exception_table_increasing(lines) - if num_rows: - res.append(f"{num_rows} row{'s' if num_rows > 1 else ''}\n") - return "".join(res) - - def do_disassembly_compare(self, got, expected, with_offsets=False): - if not with_offsets: - self.assert_offsets_increasing(got, 2) - got = self.strip_offsets(got) + def do_disassembly_compare(self, got, expected): if got != expected: got = self.strip_addresses(got) self.assertEqual(got, expected) @@ -938,17 +912,16 @@ def get_disassembly(self, func, lasti=-1, wrapper=True, **kwargs): def get_disassemble_as_string(self, func, lasti=-1): return self.get_disassembly(func, lasti, False) - def do_disassembly_test(self, func, expected, with_offsets=False): + def do_disassembly_test(self, func, expected, **kwargs): self.maxDiff = None - got = self.get_disassembly(func, depth=0) - self.do_disassembly_compare(got, expected, with_offsets) + got = self.get_disassembly(func, depth=0, **kwargs) + self.do_disassembly_compare(got, expected) # Add checks for dis.disco if hasattr(func, '__code__'): got_disco = io.StringIO() with contextlib.redirect_stdout(got_disco): - dis.disco(func.__code__) - self.do_disassembly_compare(got_disco.getvalue(), expected, - with_offsets) + dis.disco(func.__code__, **kwargs) + self.do_disassembly_compare(got_disco.getvalue(), expected) def test_opmap(self): self.assertEqual(dis.opmap["CACHE"], 0) @@ -976,6 +949,9 @@ def test_widths(self): def test_dis(self): self.do_disassembly_test(_f, dis_f) + def test_dis_with_offsets(self): + self.do_disassembly_test(_f, dis_f_with_offsets, show_offsets=True) + def test_bug_708901(self): self.do_disassembly_test(bug708901, dis_bug708901) @@ -1036,41 +1012,6 @@ def func(count): from test import dis_module self.do_disassembly_test(dis_module, dis_module_expected_results) - def test_big_offsets(self): - self.maxDiff = None - def func(count): - namespace = {} - func = "def foo(x):\n " + ";".join(["x = x + 1"] * count) + "\n return x" - exec(func, namespace) - return namespace['foo'] - - def expected(count, w): - s = ['''\ - 1 %*d RESUME 0 - - 2 %*d LOAD_FAST 0 (x) - %*d LOAD_CONST 1 (1) - %*d BINARY_OP 0 (+) -''' % (w, 0, w, 2, w, 4, w, 6)] - s += ['''\ - %*d STORE_FAST_LOAD_FAST 0 (x, x) - %*d LOAD_CONST 1 (1) - %*d BINARY_OP 0 (+) -''' % (w, 8*i + 10, w, 8*i + 12, w, 8*i + 14) - for i in range(count-1)] - s += ['''\ - %*d STORE_FAST 0 (x) - - 3 %*d LOAD_FAST 0 (x) - %*d RETURN_VALUE -''' % (w, 8*count + 2, w, 8*count + 4, w, 8*count + 6)] - return ''.join(s) - - for i in range(1, 5): - self.do_disassembly_test(func(i), expected(i, 4), True) - self.do_disassembly_test(func(1200), expected(1200, 4), True) - self.do_disassembly_test(func(1300), expected(1300, 5), True) - def test_disassemble_str(self): self.do_disassembly_test(expr_str, dis_expr_str) self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str) @@ -1151,7 +1092,7 @@ def test_dis_traceback(self): sys.last_exc = e tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti) - self.do_disassembly_test(None, tb_dis, True) + self.do_disassembly_test(None, tb_dis) def test_dis_object(self): self.assertRaises(TypeError, dis.dis, object()) @@ -1160,7 +1101,6 @@ def test_disassemble_recursive(self): def check(expected, **kwargs): dis = self.get_disassembly(_h, **kwargs) dis = self.strip_addresses(dis) - dis = self.strip_offsets(dis) self.assertEqual(dis, expected) check(dis_nested_0, depth=0) @@ -1187,73 +1127,73 @@ def code_quicken(f, times=ADAPTIVE_WARMUP_DELAY): def test_super_instructions(self): self.code_quicken(lambda: load_test(0, 0)) got = self.get_disassembly(load_test, adaptive=True) - self.do_disassembly_compare(got, dis_load_test_quickened_code, True) + self.do_disassembly_compare(got, dis_load_test_quickened_code) @cpython_only @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 2 LOAD_NAME 0 (a) - 4 LOAD_NAME 1 (b) - 6 %s - 10 RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_NAME 1 (b) + %s + RETURN_VALUE """ co_int = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) got = self.get_disassembly(co_int, adaptive=True) - self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)", True) + self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)") co_unicode = compile('a + b', "", "eval") self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'})) got = self.get_disassembly(co_unicode, adaptive=True) - self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True) + self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)") binary_subscr_quicken = """\ - 0 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 2 LOAD_NAME 0 (a) - 4 LOAD_CONST 0 (0) - 6 %s - 10 RETURN_VALUE + 1 LOAD_NAME 0 (a) + LOAD_CONST 0 (0) + %s + RETURN_VALUE """ co_list = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) got = self.get_disassembly(co_list, adaptive=True) - self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_LIST_INT", True) + self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_LIST_INT") co_dict = compile('a[0]', "", "eval") self.code_quicken(lambda: exec(co_dict, {}, {'a': {0: '1'}})) got = self.get_disassembly(co_dict, adaptive=True) - self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT", True) + self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT") @cpython_only @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 2 LOAD_CONST 0 ('a') - 4 LOAD_ATTR_SLOT 0 (__class__) - 24 RETURN_VALUE + 1 LOAD_CONST 0 ('a') + LOAD_ATTR_SLOT 0 (__class__) + RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) got = self.get_disassembly(co, adaptive=True) - self.do_disassembly_compare(got, load_attr_quicken, True) + self.do_disassembly_compare(got, load_attr_quicken) @cpython_only @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 RESUME_CHECK 0 + 0 RESUME_CHECK 0 - 1 LOAD_NAME 0 (str) - PUSH_NULL - LOAD_CONST 0 (1) - CALL_STR_1 1 - RETURN_VALUE + 1 LOAD_NAME 0 (str) + PUSH_NULL + LOAD_CONST 0 (1) + CALL_STR_1 1 + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1276,7 +1216,7 @@ def test_loop_quicken(self): @cpython_only def test_extended_arg_quick(self): got = self.get_disassembly(extended_arg_quick) - self.do_disassembly_compare(got, dis_extended_arg_quick_code, True) + self.do_disassembly_compare(got, dis_extended_arg_quick_code) def get_cached_values(self, quickened, adaptive): def f(): @@ -1288,9 +1228,9 @@ def f(): else: # "copy" the code to un-quicken it: f.__code__ = f.__code__.replace() - for instruction in dis.get_instructions( + for instruction in _unroll_caches_as_Instructions(dis.get_instructions( f, show_caches=True, adaptive=adaptive - ): + ), show_caches=True): if instruction.opname == "CACHE": yield instruction.argrepr @@ -1323,19 +1263,22 @@ def f(): # However, this might change in the future. So we explicitly try to find # a CACHE entry in the instructions. If we can't do that, fail the test - for inst in dis.get_instructions(f, show_caches=True): + for inst in _unroll_caches_as_Instructions( + dis.get_instructions(f, show_caches=True), show_caches=True): if inst.opname == "CACHE": op_offset = inst.offset - 2 cache_offset = inst.offset break + else: + opname = inst.opname else: self.fail("Can't find a CACHE entry in the function provided to do the test") assem_op = self.get_disassembly(f.__code__, lasti=op_offset, wrapper=False) assem_cache = self.get_disassembly(f.__code__, lasti=cache_offset, wrapper=False) - # Make sure --> exists and points to the correct offset - self.assertRegex(assem_op, fr"-->\s+{op_offset}") + # Make sure --> exists and points to the correct op + self.assertRegex(assem_op, fr"--> {opname}") # Make sure when lasti points to cache, it shows the same disassembly self.assertEqual(assem_op, assem_cache) @@ -1637,205 +1580,205 @@ def _prepare_test_cases(): Instruction = dis.Instruction expected_opinfo_outer = [ - 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), + Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='a', argrepr='a', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, 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, label=None, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=4, start_offset=4, starts_line=True, line_number=1, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=52, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=False, line_number=2, label=None, 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, label=None, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=False, line_number=2, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=False, line_number=7, label=None, 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, label=None, positions=None), + Instruction(opname='BUILD_LIST', opcode=47, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='BUILD_MAP', opcode=48, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=False, line_number=7, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=7, label=None, 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, label=None, positions=None), + Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=8, label=None, positions=None), ] expected_opinfo_f = [ - 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), + Instruction(opname='COPY_FREE_VARS', opcode=62, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=52, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=False, line_number=3, label=None, 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, label=None, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=26, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, 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, label=None, positions=None), + Instruction(opname='RETURN_VALUE', opcode=36, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=False, line_number=6, label=None, positions=None), ] expected_opinfo_inner = [ - 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), + Instruction(opname='COPY_FREE_VARS', opcode=62, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=6, argval=6, argrepr='', offset=24, start_offset=24, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=32, start_offset=32, starts_line=False, line_number=4, label=None, 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, label=None, positions=None), ] expected_opinfo_jumpy = [ - 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), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=1, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, label=None, positions=None), + Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to L4', offset=24, start_offset=24, starts_line=False, line_number=3, label=1, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=42, start_offset=42, starts_line=False, line_number=4, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to L2', offset=60, start_offset=60, starts_line=False, line_number=5, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to L1', offset=64, start_offset=64, starts_line=True, line_number=6, label=None, 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, label=2, 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, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to L3', offset=76, start_offset=76, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to L1', offset=80, start_offset=80, starts_line=False, line_number=7, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, label=3, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to L5', offset=86, start_offset=86, starts_line=False, line_number=8, label=None, positions=None), + Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, label=4, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=102, start_offset=102, starts_line=False, line_number=10, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, label=None, 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, label=5, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=40, argval=206, argrepr='to L9', offset=122, start_offset=122, starts_line=False, line_number=11, label=None, 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, label=6, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='BINARY_OP', opcode=45, arg=23, argval=23, argrepr='-=', offset=152, start_offset=152, starts_line=False, line_number=13, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to L7', offset=166, start_offset=166, starts_line=False, line_number=14, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to L5', offset=170, start_offset=170, starts_line=True, line_number=15, label=None, 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, label=7, 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, label=None, positions=None), + Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to L8', offset=182, start_offset=182, starts_line=False, line_number=16, label=None, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to L10', offset=186, start_offset=186, starts_line=True, line_number=17, label=None, 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, label=8, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to L9', offset=198, start_offset=198, starts_line=False, line_number=11, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to L6', offset=202, start_offset=202, starts_line=False, line_number=11, label=None, 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, label=9, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=19, label=None, positions=None), + Instruction(opname='NOP', opcode=30, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=True, line_number=20, label=10, 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, label=None, 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, label=None, positions=None), + Instruction(opname='BINARY_OP', opcode=45, arg=11, argval=11, argrepr='/', offset=234, start_offset=234, starts_line=False, line_number=21, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, label=None, 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, label=None, positions=None), + Instruction(opname='BEFORE_WITH', opcode=2, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=25, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=258, start_offset=258, starts_line=False, line_number=26, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=26, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=2, argval=2, argrepr='', offset=274, start_offset=274, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=282, start_offset=282, starts_line=False, line_number=25, label=None, 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, label=11, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=28, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=1, argval=326, argrepr='to L12', offset=320, start_offset=320, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, label=12, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to L11', offset=334, start_offset=334, starts_line=False, line_number=25, label=None, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=15, argval=392, argrepr='to L13', offset=358, start_offset=358, starts_line=False, line_number=22, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to L11', offset=388, start_offset=388, starts_line=False, line_number=23, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, label=13, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, label=None, 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, label=None, 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, label=None, 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, label=None, positions=None), + Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, label=None, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=None, label=None, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=None, label=None, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, label=None, 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=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), + Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=simple.__code__.co_firstlineno, label=None, 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, label=None), ] class InstructionTestCase(BytecodeTestCase): def assertInstructionsEqual(self, instrs_1, instrs_2, /): - instrs_1 = [instr_1._replace(positions=None) for instr_1 in instrs_1] - instrs_2 = [instr_2._replace(positions=None) for instr_2 in instrs_2] + instrs_1 = [instr_1._replace(positions=None, cache_info=None) for instr_1 in instrs_1] + instrs_2 = [instr_2._replace(positions=None, cache_info=None) for instr_2 in instrs_2] self.assertEqual(instrs_1, instrs_2) class InstructionTests(InstructionTestCase): @@ -1844,6 +1787,12 @@ def __init__(self, *args): super().__init__(*args) self.maxDiff = None + def test_instruction_str(self): + # smoke test for __str__ + instrs = dis.get_instructions(simple) + for instr in instrs: + str(instr) + def test_default_first_line(self): actual = dis.get_instructions(simple) self.assertInstructionsEqual(list(actual), expected_opinfo_simple) @@ -1943,23 +1892,35 @@ def roots(a, b, c): instruction.positions.col_offset, instruction.positions.end_col_offset, ) - for instruction in dis.get_instructions( + for instruction in _unroll_caches_as_Instructions(dis.get_instructions( code, adaptive=adaptive, show_caches=show_caches - ) + ), show_caches=show_caches) ] self.assertEqual(co_positions, dis_positions) 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=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, positions=None) self.assertEqual(instruction.arg, instruction.oparg) + def test_show_caches_with_label(self): + def f(x, y, z): + if x: + res = y + else: + res = z + return res + + output = io.StringIO() + dis.dis(f.__code__, file=output, show_caches=True) + self.assertIn("L1:", output.getvalue()) + 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=True, line_number=1, is_jump_target=False, positions=None) + start_offset=0, starts_line=True, line_number=1, label=None, positions=None) baseopname = instruction.baseopname baseopcode = instruction.baseopcode self.assertIsNotNone(baseopname) @@ -1970,7 +1931,7 @@ def test_baseopname_and_baseopcode(self): # 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=True, line_number=1, is_jump_target=False, positions=None) + offset=0, start_offset=0, starts_line=True, line_number=1, label=None, positions=None) baseopname = instruction.baseopname baseopcode = instruction.baseopcode self.assertIn(name, opcode._specializations[baseopname]) @@ -1979,28 +1940,48 @@ 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=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, 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=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, 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=True, line_number=1, is_jump_target=False, + argrepr='', offset=200, start_offset=200, starts_line=True, line_number=1, label=None, 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=True, line_number=1, is_jump_target=False, + argrepr='', offset=10, start_offset=10, starts_line=True, line_number=1, label=None, positions=None) self.assertEqual(10 + 2 + 1*2 + 100*2, instruction.jump_target) + def test_argval_argrepr(self): + def f(opcode, oparg, offset, *init_args): + arg_resolver = dis.ArgResolver(*init_args) + return arg_resolver.get_argval_argrepr(opcode, oparg, offset) + + offset = 42 + co_consts = (0, 1, 2, 3) + names = {1: 'a', 2: 'b'} + varname_from_oparg = lambda i : names[i] + labels_map = {24: 1} + args = (offset, co_consts, names, varname_from_oparg, labels_map) + self.assertEqual(f(opcode.opmap["POP_TOP"], None, *args), (None, '')) + self.assertEqual(f(opcode.opmap["LOAD_CONST"], 1, *args), (1, '1')) + self.assertEqual(f(opcode.opmap["LOAD_GLOBAL"], 2, *args), ('a', 'a')) + self.assertEqual(f(opcode.opmap["JUMP_BACKWARD"], 11, *args), (24, 'to L1')) + self.assertEqual(f(opcode.opmap["COMPARE_OP"], 3, *args), ('<', '<')) + self.assertEqual(f(opcode.opmap["SET_FUNCTION_ATTRIBUTE"], 2, *args), (2, 'kwdefaults')) + self.assertEqual(f(opcode.opmap["BINARY_OP"], 3, *args), (3, '<<')) + self.assertEqual(f(opcode.opmap["CALL_INTRINSIC_1"], 2, *args), (2, 'INTRINSIC_IMPORT_STAR')) + def test_start_offset(self): # When no extended args are present, # start_offset should be equal to offset @@ -2132,7 +2113,7 @@ def test_from_traceback_dis(self): self.maxDiff = None tb = get_tb() b = dis.Bytecode.from_traceback(tb) - self.assertEqual(self.strip_offsets(b.dis()), dis_traceback) + self.assertEqual(b.dis(), dis_traceback) @requires_debug_ranges() def test_bytecode_co_positions(self): @@ -2254,6 +2235,31 @@ def get_disassembly(self, tb): dis.distb(tb, file=output) return output.getvalue() +def _unroll_caches_as_Instructions(instrs, show_caches=False): + # Cache entries are no longer reported by dis as fake instructions, + # but some tests assume that do. We should rewrite the tests to assume + # the new API, but it will be clearer to keep the tests working as + # before and do that in a separate PR. + + for instr in instrs: + yield instr + if not show_caches: + continue + + offset = instr.offset + for name, size, data in (instr.cache_info or ()): + for i in range(size): + offset += 2 + # Only show the fancy argrepr for a CACHE instruction when it's + # the first entry for a particular cache value: + if i == 0: + argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}" + else: + argrepr = "" + + yield Instruction("CACHE", CACHE, 0, None, argrepr, offset, offset, + False, None, None, instr.positions) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 6e12e82a7a0084..36328f8086c7ad 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -102,15 +102,6 @@ def a_classmethod(cls, v): a_class_attribute = 42 - @classmethod - @property - def a_classmethod_property(cls): - """ - >>> print(SampleClass.a_classmethod_property) - 42 - """ - return cls.a_class_attribute - @functools.cached_property def a_cached_property(self): """ @@ -422,6 +413,23 @@ def test_DocTest(): r""" False >>> test != other_test True + >>> test < other_test + False + >>> other_test < test + True + +Test comparison with lineno None on one side + + >>> no_lineno = parser.get_doctest(docstring, globs, 'some_test', + ... 'some_test', None) + >>> test.lineno is None + False + >>> no_lineno.lineno is None + True + >>> test < no_lineno + False + >>> no_lineno < test + True Compare `DocTestCase`: @@ -525,7 +533,6 @@ def basics(): r""" 1 SampleClass.__init__ 1 SampleClass.a_cached_property 2 SampleClass.a_classmethod - 1 SampleClass.a_classmethod_property 1 SampleClass.a_property 1 SampleClass.a_staticmethod 1 SampleClass.double @@ -582,7 +589,6 @@ def basics(): r""" 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 1 some_module.SampleClass.a_staticmethod 1 some_module.SampleClass.double @@ -625,7 +631,6 @@ def basics(): r""" 1 SampleClass.__init__ 1 SampleClass.a_cached_property 2 SampleClass.a_classmethod - 1 SampleClass.a_classmethod_property 1 SampleClass.a_property 1 SampleClass.a_staticmethod 1 SampleClass.double @@ -647,7 +652,6 @@ def basics(): r""" 1 SampleClass.__init__ 1 SampleClass.a_cached_property 2 SampleClass.a_classmethod - 1 SampleClass.a_classmethod_property 1 SampleClass.a_property 1 SampleClass.a_staticmethod 1 SampleClass.double @@ -2918,6 +2922,9 @@ def test_unicode(): """ Traceback (most recent call last): File ... exec(compile(example.source, filename, "single", + ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + compileflags, True), test.globs) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1, in raise Exception('clé') Exception: clé @@ -3212,25 +3219,173 @@ def test_run_doctestsuite_multiple_times(): """ +def test_exception_with_note(note): + """ + >>> test_exception_with_note('Note') + Traceback (most recent call last): + ... + ValueError: Text + Note + + >>> test_exception_with_note('Note') # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: Text + Note + + >>> test_exception_with_note('''Note + ... multiline + ... example''') + Traceback (most recent call last): + ValueError: Text + Note + multiline + example + + Different note will fail the test: + + >>> def f(x): + ... r''' + ... >>> exc = ValueError('message') + ... >>> exc.add_note('note') + ... >>> raise exc + ... Traceback (most recent call last): + ... ValueError: message + ... wrong note + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File "...", line 5, in f + Failed example: + raise exc + Expected: + Traceback (most recent call last): + ValueError: message + wrong note + Got: + Traceback (most recent call last): + ... + ValueError: message + note + TestResults(failed=1, attempted=...) + """ + exc = ValueError('Text') + exc.add_note(note) + raise exc + + +def test_exception_with_multiple_notes(): + """ + >>> test_exception_with_multiple_notes() + Traceback (most recent call last): + ... + ValueError: Text + One + Two + """ + exc = ValueError('Text') + exc.add_note('One') + exc.add_note('Two') + raise exc + + +def test_syntax_error_with_note(cls, multiline=False): + """ + >>> test_syntax_error_with_note(SyntaxError) + Traceback (most recent call last): + ... + SyntaxError: error + Note + + >>> test_syntax_error_with_note(SyntaxError) + Traceback (most recent call last): + SyntaxError: error + Note + + >>> test_syntax_error_with_note(SyntaxError) + Traceback (most recent call last): + ... + File "x.py", line 23 + bad syntax + SyntaxError: error + Note + + >>> test_syntax_error_with_note(IndentationError) + Traceback (most recent call last): + ... + IndentationError: error + Note + + >>> test_syntax_error_with_note(TabError, multiline=True) + Traceback (most recent call last): + ... + TabError: error + Note + Line + """ + exc = cls("error", ("x.py", 23, None, "bad syntax")) + exc.add_note('Note\nLine' if multiline else 'Note') + raise exc + + +def test_syntax_error_subclass_from_stdlib(): + """ + `ParseError` is a subclass of `SyntaxError`, but it is not a builtin: + + >>> test_syntax_error_subclass_from_stdlib() + Traceback (most recent call last): + ... + xml.etree.ElementTree.ParseError: error + error + Note + Line + """ + from xml.etree.ElementTree import ParseError + exc = ParseError("error\nerror") + exc.add_note('Note\nLine') + raise exc + + +def test_syntax_error_with_incorrect_expected_note(): + """ + >>> def f(x): + ... r''' + ... >>> exc = SyntaxError("error", ("x.py", 23, None, "bad syntax")) + ... >>> exc.add_note('note1') + ... >>> exc.add_note('note2') + ... >>> raise exc + ... Traceback (most recent call last): + ... SyntaxError: error + ... wrong note + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File "...", line 6, in f + Failed example: + raise exc + Expected: + Traceback (most recent call last): + SyntaxError: error + wrong note + Got: + Traceback (most recent call last): + ... + SyntaxError: error + note1 + note2 + TestResults(failed=1, attempted=...) + """ + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(doctest)) tests.addTest(doctest.DocTestSuite()) return tests -def test_coverage(coverdir): - trace = import_helper.import_module('trace') - tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], - trace=0, count=1) - tracer.run('test_main()') - r = tracer.results() - print('Writing coverage results...') - r.write_results(show_missing=True, summary=True, - coverdir=coverdir) - - if __name__ == '__main__': - if '-c' in sys.argv: - test_coverage('/tmp/doctest.cover') - else: - unittest.main() + unittest.main(module='test.test_doctest') diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index d3f396f02e7a72..034f7626c1fc7c 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -748,6 +748,35 @@ def test_iter_attachments_mutation(self): self.assertEqual(len(list(m.iter_attachments())), 2) self.assertEqual(m.get_payload(), orig) + get_payload_surrogate_params = { + + 'good_surrogateescape': ( + "String that can be encod\udcc3\udcabd with surrogateescape", + b'String that can be encod\xc3\xabd with surrogateescape' + ), + + 'string_with_utf8': ( + "String with utf-8 charactër", + b'String with utf-8 charact\xebr' + ), + + 'surrogate_and_utf8': ( + "String that cannot be ëncod\udcc3\udcabd with surrogateescape", + b'String that cannot be \xebncod\\udcc3\\udcabd with surrogateescape' + ), + + 'out_of_range_surrogate': ( + "String with \udfff cannot be encoded with surrogateescape", + b'String with \\udfff cannot be encoded with surrogateescape' + ), + } + + def get_payload_surrogate_as_gh_94606(self, msg, expected): + """test for GH issue 94606""" + m = self._str_msg(msg) + payload = m.get_payload(decode=True) + self.assertEqual(expected, payload) + class TestEmailMessage(TestEmailMessageBase, TestEmailBase): message = EmailMessage diff --git a/Lib/test/test_email/test_utils.py b/Lib/test/test_email/test_utils.py index 25fa48c5ee217b..c9d973df0a2192 100644 --- a/Lib/test/test_email/test_utils.py +++ b/Lib/test/test_email/test_utils.py @@ -5,6 +5,7 @@ import unittest import sys import os.path +import zoneinfo class DateTimeTests(unittest.TestCase): @@ -142,13 +143,9 @@ def test_localtime_epoch_notz_daylight_false(self): t2 = utils.localtime(t0.replace(tzinfo=None)) self.assertEqual(t1, t2) - # XXX: Need a more robust test for Olson's tzdata - @unittest.skipIf(sys.platform.startswith('win'), - "Windows does not use Olson's TZ database") - @unittest.skipUnless(os.path.exists('/usr/share/zoneinfo') or - os.path.exists('/usr/lib/zoneinfo'), - "Can't find the Olson's TZ database") - @test.support.run_with_tz('Europe/Kiev') + @unittest.skipUnless("Europe/Kyiv" in zoneinfo.available_timezones(), + "Can't find a Kyiv timezone database") + @test.support.run_with_tz('Europe/Kyiv') def test_variable_tzname(self): t0 = datetime.datetime(1984, 1, 1, tzinfo=datetime.timezone.utc) t1 = utils.localtime(t0) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 7f1a4e665f3b5d..6c60854bbd76cc 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,16 @@ 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 +PYMEM_ALLOCATOR_MIMALLOC = 7 +if support.Py_GIL_DISABLED: + ALLOCATOR_FOR_CONFIG = PYMEM_ALLOCATOR_MIMALLOC +else: + ALLOCATOR_FOR_CONFIG = PYMEM_ALLOCATOR_MALLOC + Py_STATS = hasattr(sys, '_stats_on') # _PyCoreConfig_InitCompatConfig() @@ -348,7 +351,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 @@ -448,6 +451,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, @@ -455,6 +459,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, @@ -504,6 +509,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', @@ -515,6 +521,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): } if Py_STATS: CONFIG_COMPAT['_pystats'] = 0 + if support.Py_DEBUG: + CONFIG_COMPAT['run_presite'] = None if MS_WINDOWS: CONFIG_COMPAT.update({ 'legacy_windows_stdio': 0, @@ -839,7 +847,7 @@ def test_init_global_config(self): def test_init_from_config(self): preconfig = { - 'allocator': PYMEM_ALLOCATOR_MALLOC, + 'allocator': ALLOCATOR_FOR_CONFIG, 'utf8_mode': 1, } config = { @@ -894,6 +902,7 @@ 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, @@ -905,7 +914,7 @@ def test_init_from_config(self): def test_init_compat_env(self): preconfig = { - 'allocator': PYMEM_ALLOCATOR_MALLOC, + 'allocator': ALLOCATOR_FOR_CONFIG, } config = { 'use_hash_seed': 1, @@ -939,7 +948,7 @@ def test_init_compat_env(self): def test_init_python_env(self): preconfig = { - 'allocator': PYMEM_ALLOCATOR_MALLOC, + 'allocator': ALLOCATOR_FOR_CONFIG, 'utf8_mode': 1, } config = { @@ -981,7 +990,7 @@ def test_init_env_dev_mode(self): api=API_COMPAT) def test_init_env_dev_mode_alloc(self): - preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC) + preconfig = dict(allocator=ALLOCATOR_FOR_CONFIG) config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) @@ -1131,6 +1140,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) @@ -1146,6 +1156,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, @@ -1712,6 +1723,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") @@ -1812,6 +1826,22 @@ def test_no_memleak(self): self.assertEqual(refs, 0, out) self.assertEqual(blocks, 0, out) + @unittest.skipUnless(support.Py_DEBUG, + '-X presite requires a Python debug build') + def test_presite(self): + cmd = [sys.executable, "-I", "-X", "presite=test.reperf", "-c", "print('cmd')"] + proc = subprocess.run( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + self.assertEqual(proc.returncode, 0) + out = proc.stdout.strip() + self.assertIn("10 times sub", out) + self.assertIn("CPU seconds", out) + self.assertIn("cmd", out) + class StdPrinterTests(EmbeddingTestsMixin, unittest.TestCase): # Test PyStdPrinter_Type which is used by _PySys_SetPreliminaryStderr(): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 8c1f285f7b3bc2..f99d4ca204b5a7 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -18,7 +18,7 @@ from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL from test import support -from test.support import ALWAYS_EQ +from test.support import ALWAYS_EQ, REPO_ROOT from test.support import threading_helper from datetime import timedelta @@ -26,14 +26,19 @@ def load_tests(loader, tests, ignore): tests.addTests(doctest.DocTestSuite(enum)) - if os.path.exists('Doc/library/enum.rst'): + + lib_tests = os.path.join(REPO_ROOT, 'Doc/library/enum.rst') + if os.path.exists(lib_tests): tests.addTests(doctest.DocFileSuite( - '../../Doc/library/enum.rst', + lib_tests, + module_relative=False, optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE, )) - if os.path.exists('Doc/howto/enum.rst'): + howto_tests = os.path.join(REPO_ROOT, 'Doc/howto/enum.rst') + if os.path.exists(howto_tests): tests.addTests(doctest.DocFileSuite( - '../../Doc/howto/enum.rst', + howto_tests, + module_relative=False, optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE, )) return tests @@ -171,7 +176,7 @@ class TestHelpers(unittest.TestCase): sunder_names = '_bad_', '_good_', '_what_ho_' dunder_names = '__mal__', '__bien__', '__que_que__' - private_names = '_MyEnum__private', '_MyEnum__still_private' + private_names = '_MyEnum__private', '_MyEnum__still_private', '_MyEnum___triple_private' private_and_sunder_names = '_MyEnum__private_', '_MyEnum__also_private_' random_names = 'okay', '_semi_private', '_weird__', '_MyEnum__' @@ -509,6 +514,7 @@ def test_contains_tf(self): self.assertFalse('first' in MainEnum) val = MainEnum.dupe self.assertIn(val, MainEnum) + self.assertNotIn(float('nan'), MainEnum) # class OtherEnum(Enum): one = auto() @@ -3263,6 +3269,65 @@ def __new__(cls, value): member._value_ = Base(value) return member + def test_extra_member_creation(self): + class IDEnumMeta(EnumMeta): + def __new__(metacls, cls, bases, classdict, **kwds): + # add new entries to classdict + for name in classdict.member_names: + classdict[f'{name}_DESC'] = f'-{classdict[name]}' + return super().__new__(metacls, cls, bases, classdict, **kwds) + class IDEnum(StrEnum, metaclass=IDEnumMeta): + pass + class MyEnum(IDEnum): + ID = 'id' + NAME = 'name' + self.assertEqual(list(MyEnum), [MyEnum.ID, MyEnum.NAME, MyEnum.ID_DESC, MyEnum.NAME_DESC]) + + def test_add_alias(self): + class mixin: + @property + def ORG(self): + return 'huh' + class Color(mixin, Enum): + RED = 1 + GREEN = 2 + BLUE = 3 + Color.RED._add_alias_('ROJO') + self.assertIs(Color.RED, Color['ROJO']) + self.assertIs(Color.RED, Color.ROJO) + Color.BLUE._add_alias_('ORG') + self.assertIs(Color.BLUE, Color['ORG']) + self.assertIs(Color.BLUE, Color.ORG) + self.assertEqual(Color.RED.ORG, 'huh') + self.assertEqual(Color.GREEN.ORG, 'huh') + self.assertEqual(Color.BLUE.ORG, 'huh') + self.assertEqual(Color.ORG.ORG, 'huh') + + def test_add_value_alias_after_creation(self): + class Color(Enum): + RED = 1 + GREEN = 2 + BLUE = 3 + Color.RED._add_value_alias_(5) + self.assertIs(Color.RED, Color(5)) + + def test_add_value_alias_during_creation(self): + class Types(Enum): + Unknown = 0, + Source = 1, 'src' + NetList = 2, 'nl' + def __new__(cls, int_value, *value_aliases): + member = object.__new__(cls) + member._value_ = int_value + for alias in value_aliases: + member._add_value_alias_(alias) + return member + self.assertIs(Types(0), Types.Unknown) + self.assertIs(Types(1), Types.Source) + self.assertIs(Types('src'), Types.Source) + self.assertIs(Types(2), Types.NetList) + self.assertIs(Types('nl'), Types.NetList) + class TestOrder(unittest.TestCase): "test usage of the `_order_` attribute" @@ -4936,12 +5001,14 @@ class CheckedColor(Enum): @bltns.property def zeroth(self): return 'zeroed %s' % self.name - self.assertTrue(_test_simple_enum(CheckedColor, SimpleColor) is None) + _test_simple_enum(CheckedColor, SimpleColor) SimpleColor.MAGENTA._value_ = 9 self.assertRaisesRegex( TypeError, "enum mismatch", _test_simple_enum, CheckedColor, SimpleColor, ) + # + # class CheckedMissing(IntFlag, boundary=KEEP): SIXTY_FOUR = 64 ONE_TWENTY_EIGHT = 128 @@ -4958,8 +5025,28 @@ class Missing: ALL = 2048 + 128 + 64 + 12 M = Missing self.assertEqual(list(CheckedMissing), [M.SIXTY_FOUR, M.ONE_TWENTY_EIGHT, M.TWENTY_FORTY_EIGHT]) - # _test_simple_enum(CheckedMissing, Missing) + # + # + class CheckedUnhashable(Enum): + ONE = dict() + TWO = set() + name = 'python' + self.assertIn(dict(), CheckedUnhashable) + self.assertIn('python', CheckedUnhashable) + self.assertEqual(CheckedUnhashable.name.value, 'python') + self.assertEqual(CheckedUnhashable.name.name, 'name') + # + @_simple_enum() + class Unhashable: + ONE = dict() + TWO = set() + name = 'python' + self.assertIn(dict(), Unhashable) + self.assertIn('python', Unhashable) + self.assertEqual(Unhashable.name.value, 'python') + self.assertEqual(Unhashable.name.name, 'name') + _test_simple_enum(Unhashable, Unhashable) class MiscTestCase(unittest.TestCase): @@ -5166,7 +5253,7 @@ def member_dir(member): allowed.add(name) else: allowed.discard(name) - else: + elif name not in member._member_map_: allowed.add(name) return sorted(allowed) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 106baf959a6898..c57488e44aecc6 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -18,6 +18,12 @@ from test.support.warnings_helper import check_warnings from test import support +try: + from _testcapi import INT_MAX +except ImportError: + INT_MAX = 2**31 - 1 + + class NaiveException(Exception): def __init__(self, x): @@ -253,7 +259,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 +324,14 @@ def baz(): check('(yield i) = 2', 1, 2) check('def f(*):\n pass', 1, 7) + @unittest.skipIf(INT_MAX >= sys.maxsize, "Downcasting to int is safe for col_offset") + @support.requires_resource('cpu') + @support.bigmemtest(INT_MAX, memuse=2, dry_run=False) + def testMemoryErrorBigSource(self, size): + src = b"if True:\n%*s" % (size, b"pass") + with self.assertRaisesRegex(OverflowError, "Parser column offset overflow"): + compile(src, '', 'exec') + @cpython_only def testSettingException(self): # test that setting an exception at the C level works even if the @@ -1777,6 +1791,20 @@ class TestException(MemoryError): gc_collect() + def test_memory_error_in_subinterp(self): + # gh-109894: subinterpreters shouldn't count on last resort memory error + # when MemoryError is raised through PyErr_NoMemory() call, + # and should preallocate memory errors as does the main interpreter. + # interp.static_objects.last_resort_memory_error.args + # should be initialized to empty tuple to avoid crash on attempt to print it. + code = f"""if 1: + import _testcapi + _testcapi.run_in_subinterp(\"[0]*{sys.maxsize}\") + exit(0) + """ + rc, _, err = script_helper.assert_python_ok("-c", code) + self.assertIn(b'MemoryError', err) + class NameErrorTests(unittest.TestCase): def test_name_error_has_name(self): @@ -1816,6 +1844,13 @@ def f(): self.assertIn("nonsense", err.getvalue()) self.assertIn("ZeroDivisionError", err.getvalue()) + def test_gh_111654(self): + def f(): + class TestClass: + TestClass + + self.assertRaises(NameError, f) + # Note: name suggestion tests live in `test_traceback`. @@ -2045,6 +2080,7 @@ def test_multiline_not_highlighted(self): """, [ ' 1 < 2 and', + ' 3 > 4', 'AssertionError', ], ), @@ -2052,7 +2088,7 @@ def test_multiline_not_highlighted(self): for source, expected in cases: with self.subTest(source): result = self.write_source(source) - self.assertEqual(result[-2:], expected) + self.assertEqual(result[-len(expected):], expected) class SyntaxErrorTests(unittest.TestCase): diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 3c1e8c150ae711..d0473500a17735 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -7,8 +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 os_helper, script_helper, is_android, MS_WINDOWS import tempfile import unittest from textwrap import dedent @@ -22,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): @@ -35,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) @@ -67,11 +65,7 @@ def get_output(self, code, filename=None, fd=None): # Sanitizers must not handle SIGSEGV (ex: for test_enable_fd()) option = 'handle_segv=0' - for name in ('ASAN_OPTIONS', 'MSAN_OPTIONS', 'UBSAN_OPTIONS'): - if name in env: - env[name] += f':{option}' - else: - env[name] = option + support.set_sanitizer_env_var(env, option) with support.SuppressCrashReport(): process = script_helper.spawn_python('-c', code, diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index ebfcffd1829174..f490485cdaf3eb 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -10,7 +10,8 @@ from functools import wraps from test.support import ( - cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi + cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi, + infinite_recursion, ) from test.support.os_helper import ( TESTFN, TESTFN_ASCII, TESTFN_UNICODE, make_bad_fd, @@ -183,6 +184,7 @@ def testReprNoCloseFD(self): finally: os.close(fd) + @infinite_recursion(25) def testRecursiveRepr(self): # Issue #25455 with swap_attr(self.f, 'name', self.f): diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index b6daae7e9280ff..5bd640617d6874 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -18,7 +18,6 @@ except ImportError: _testcapi = None -HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE") INF = float("inf") NAN = float("nan") @@ -1505,69 +1504,5 @@ def __init__(self, value): self.assertEqual(getattr(f, 'foo', 'none'), 'bar') -# Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() -# Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() -BIG_ENDIAN = 0 -LITTLE_ENDIAN = 1 -EPSILON = { - 2: 2.0 ** -11, # binary16 - 4: 2.0 ** -24, # binary32 - 8: 2.0 ** -53, # binary64 -} - -@unittest.skipIf(_testcapi is None, 'needs _testcapi') -class PackTests(unittest.TestCase): - def test_pack(self): - self.assertEqual(_testcapi.float_pack(2, 1.5, BIG_ENDIAN), - b'>\x00') - self.assertEqual(_testcapi.float_pack(4, 1.5, BIG_ENDIAN), - b'?\xc0\x00\x00') - self.assertEqual(_testcapi.float_pack(8, 1.5, BIG_ENDIAN), - b'?\xf8\x00\x00\x00\x00\x00\x00') - self.assertEqual(_testcapi.float_pack(2, 1.5, LITTLE_ENDIAN), - b'\x00>') - self.assertEqual(_testcapi.float_pack(4, 1.5, LITTLE_ENDIAN), - b'\x00\x00\xc0?') - self.assertEqual(_testcapi.float_pack(8, 1.5, LITTLE_ENDIAN), - b'\x00\x00\x00\x00\x00\x00\xf8?') - - def test_unpack(self): - self.assertEqual(_testcapi.float_unpack(b'>\x00', BIG_ENDIAN), - 1.5) - self.assertEqual(_testcapi.float_unpack(b'?\xc0\x00\x00', BIG_ENDIAN), - 1.5) - self.assertEqual(_testcapi.float_unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN), - 1.5) - self.assertEqual(_testcapi.float_unpack(b'\x00>', LITTLE_ENDIAN), - 1.5) - self.assertEqual(_testcapi.float_unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN), - 1.5) - self.assertEqual(_testcapi.float_unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN), - 1.5) - - def test_roundtrip(self): - large = 2.0 ** 100 - values = [1.0, 1.5, large, 1.0/7, math.pi] - if HAVE_IEEE_754: - values.extend((INF, NAN)) - for value in values: - for size in (2, 4, 8,): - if size == 2 and value == large: - # too large for 16-bit float - continue - rel_tol = EPSILON[size] - for endian in (BIG_ENDIAN, LITTLE_ENDIAN): - with self.subTest(value=value, size=size, endian=endian): - data = _testcapi.float_pack(size, value, endian) - value2 = _testcapi.float_unpack(data, endian) - if isnan(value): - self.assertTrue(isnan(value2), (value, value2)) - elif size < 8: - self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol), - (value, value2)) - else: - self.assertEqual(value2, value) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 9491c7facdf077..7f17666a8d9697 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -80,9 +80,11 @@ def g(): gen = g() next(gen) self.assertFalse(endly) - # Clearing the frame closes the generator - gen.gi_frame.clear() - self.assertTrue(endly) + + # Cannot clear a suspended frame + with self.assertRaisesRegex(RuntimeError, r'suspended frame'): + gen.gi_frame.clear() + self.assertFalse(endly) def test_clear_executing(self): # Attempting to clear an executing frame is forbidden. @@ -114,9 +116,10 @@ def g(): gen = g() f = next(gen) self.assertFalse(endly) - # Clearing the frame closes the generator - f.clear() - self.assertTrue(endly) + # Cannot clear a suspended frame + with self.assertRaisesRegex(RuntimeError, 'suspended frame'): + f.clear() + self.assertFalse(endly) def test_lineno_with_tracing(self): def record_line(): diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 4f05a149a901b2..27c7f70cef32e3 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -8,6 +8,7 @@ # Unicode identifiers in tests is allowed by PEP 3131. import ast +import dis import os import re import types @@ -514,6 +515,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''' @@ -1579,6 +1628,9 @@ def __repr__(self): self.assertEqual(f'X{x = }Y', 'Xx = '+repr(x)+'Y') self.assertEqual(f"sadsd {1 + 1 = :{1 + 1:1d}f}", "sadsd 1 + 1 = 2.000000") + self.assertEqual(f"{1+2 = # my comment + }", '1+2 = \n 3') + # These next lines contains tabs. Backslash escapes don't # work in f-strings. # patchcheck doesn't like these tabs. So the only way to test @@ -1687,5 +1739,14 @@ def test_syntax_warning_infinite_recursion_in_file(self): self.assertIn(rb'\1', stdout) self.assertEqual(len(stderr.strip().splitlines()), 2) + def test_fstring_without_formatting_bytecode(self): + # f-string without any formatting should emit the same bytecode + # as a normal string. See gh-99606. + def get_code(s): + return [(i.opname, i.oparg) for i in dis.get_instructions(s)] + + for s in ["", "some string"]: + self.assertEqual(get_code(f"'{s}'"), get_code(f"f'{s}'")) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 35b473d5e9a0b4..b3fc5ad42e7fde 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -2,6 +2,7 @@ import types import typing import unittest +import warnings def global_function(): @@ -70,6 +71,27 @@ def test(): pass test.__code__ = self.b.__code__ self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily + def test_invalid___code___assignment(self): + def A(): pass + def B(): yield + async def C(): yield + async def D(x): await x + + for src in [A, B, C, D]: + for dst in [A, B, C, D]: + if src == dst: + continue + + assert src.__code__.co_flags != dst.__code__.co_flags + prev = dst.__code__ + try: + with self.assertWarnsRegex(DeprecationWarning, 'code object of non-matching type'): + dst.__code__ = src.__code__ + finally: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + dst.__code__ = prev + def test___globals__(self): self.assertIs(self.b.__globals__, globals()) self.cannot_set_attr(self.b, '__globals__', 2, diff --git a/Lib/test/test_gdb/__init__.py b/Lib/test/test_gdb/__init__.py index d74075e456792d..99557739af6748 100644 --- a/Lib/test/test_gdb/__init__.py +++ b/Lib/test/test_gdb/__init__.py @@ -9,8 +9,7 @@ from test import support -MS_WINDOWS = (os.name == 'nt') -if MS_WINDOWS: +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. diff --git a/Lib/test/test_gdb/test_cfunction_full.py b/Lib/test/test_gdb/test_cfunction_full.py index 3e90cb1d392f49..572cbdab5d77c0 100644 --- a/Lib/test/test_gdb/test_cfunction_full.py +++ b/Lib/test/test_gdb/test_cfunction_full.py @@ -18,7 +18,7 @@ def check(self, func_name, cmd): gdb_output = self.get_stack_trace( cmd, breakpoint=func_name, - cmds_after_breakpoint=['py-bt-full'], + cmds_after_breakpoint=['bt', 'py-bt-full'], # bpo-45207: Ignore 'Function "meth_varargs" not # defined.' message in stderr. ignore_stderr=True, diff --git a/Lib/test/test_gdb/util.py b/Lib/test/test_gdb/util.py index 7f4e3cba3534bd..8fe9cfc543395e 100644 --- a/Lib/test/test_gdb/util.py +++ b/Lib/test/test_gdb/util.py @@ -1,6 +1,7 @@ import os import re import shlex +import shutil import subprocess import sys import sysconfig @@ -8,6 +9,8 @@ from test import support +GDB_PROGRAM = shutil.which('gdb') or 'gdb' + # Location of custom hooks file in a repository checkout. CHECKOUT_HOOK_PATH = os.path.join(os.path.dirname(sys.executable), 'python-gdb.py') @@ -27,7 +30,7 @@ def clean_environment(): # Temporary value until it's initialized by get_gdb_version() below GDB_VERSION = (0, 0) -def run_gdb(*args, exitcode=0, **env_vars): +def run_gdb(*args, exitcode=0, check=True, **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. @@ -36,7 +39,7 @@ def run_gdb(*args, exitcode=0, **env_vars): if env_vars: env.update(env_vars) - cmd = ['gdb', + cmd = [GDB_PROGRAM, # Batch mode: Exit after processing all the command files # specified with -x/--command '--batch', @@ -59,7 +62,7 @@ def run_gdb(*args, exitcode=0, **env_vars): stdout = proc.stdout stderr = proc.stderr - if proc.returncode != exitcode: + if check and 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" @@ -72,10 +75,10 @@ def run_gdb(*args, exitcode=0, **env_vars): def get_gdb_version(): try: stdout, stderr = run_gdb('--version') - except OSError: + except OSError as exc: # 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") + raise unittest.SkipTest(f"Couldn't find gdb program on the path: {exc}") # Regex to parse: # 'GNU gdb (GDB; SUSE Linux Enterprise 12) 7.7\n' -> 7.7 @@ -106,7 +109,8 @@ def check_usable_gdb(): # disallow this without a customized .gdbinit. stdout, stderr = run_gdb( '--eval-command=python import sys; print(sys.version_info)', - '--args', sys.executable) + '--args', sys.executable, + check=False) if "auto-loading has been declined" in stderr: raise unittest.SkipTest( @@ -144,6 +148,7 @@ def setup_module(): print(f"gdb version {GDB_VERSION[0]}.{GDB_VERSION[1]}:") for line in GDB_VERSION_TEXT.splitlines(): print(" " * 4 + line) + print(f" path: {GDB_PROGRAM}") print() diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index b5eaf824aee706..de96a8764594ba 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -118,17 +118,19 @@ def run_cases_test(self, input: str, expected: str): with open(self.temp_output_filename) as temp_output: lines = temp_output.readlines() - while lines and lines[0].startswith("// "): + while lines and lines[0].startswith(("// ", "#", " #", "\n")): lines.pop(0) + while lines and lines[-1].startswith(("#", "\n")): + lines.pop(-1) actual = "".join(lines) - # if actual.rstrip() != expected.rstrip(): + # if actual.strip() != expected.strip(): # print("Actual:") # print(actual) # print("Expected:") # print(expected) # print("End") - self.assertEqual(actual.rstrip(), expected.rstrip()) + self.assertEqual(actual.strip(), expected.strip()) def test_inst_no_args(self): input = """ @@ -138,6 +140,9 @@ def test_inst_no_args(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); spam(); DISPATCH(); } @@ -152,6 +157,9 @@ def test_inst_one_pop(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *value; value = stack_pointer[-1]; spam(); @@ -169,6 +177,9 @@ def test_inst_one_push(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *res; spam(); STACK_GROW(1); @@ -186,6 +197,9 @@ def test_inst_one_push_one_pop(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *value; PyObject *res; value = stack_pointer[-1]; @@ -204,6 +218,9 @@ def test_binary_op(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *right; PyObject *left; PyObject *res; @@ -225,6 +242,9 @@ def test_overlap(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *right; PyObject *left; PyObject *result; @@ -239,20 +259,32 @@ 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) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(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) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP3); PyObject *arg; PyObject *res; arg = stack_pointer[-1]; @@ -272,6 +304,9 @@ def test_error_if_plain(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); if (cond) goto label; DISPATCH(); } @@ -286,6 +321,9 @@ def test_error_if_plain_with_comment(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); if (cond) goto label; DISPATCH(); } @@ -300,6 +338,9 @@ def test_error_if_pop(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *right; PyObject *left; PyObject *res; @@ -320,12 +361,14 @@ def test_cache_effect(self): """ output = """ TARGET(OP) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(OP); PyObject *value; value = stack_pointer[-1]; - uint16_t counter = read_u16(&next_instr[0].cache); - uint32_t extra = read_u32(&next_instr[1].cache); + uint16_t counter = read_u16(&this_instr[1].cache); + uint32_t extra = read_u32(&this_instr[2].cache); STACK_SHRINK(1); - next_instr += 3; DISPATCH(); } """ @@ -339,6 +382,9 @@ def test_suppress_dispatch(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); goto somewhere; } """ @@ -359,18 +405,12 @@ def test_macro_instruction(self): family(OP, INLINE_CACHE_ENTRIES_OP) = { OP3 }; """ output = """ - TARGET(OP1) { - 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; - DISPATCH(); - } - TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 6; + INSTRUCTION_STATS(OP); + PREDICTED(OP); + _Py_CODEUNIT *this_instr = next_instr - 6; static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); PyObject *right; PyObject *left; @@ -380,22 +420,37 @@ def test_macro_instruction(self): right = stack_pointer[-1]; left = stack_pointer[-2]; { - uint16_t counter = read_u16(&next_instr[0].cache); + uint16_t counter = read_u16(&this_instr[1].cache); op1(left, right); } // OP2 arg2 = stack_pointer[-3]; { - uint32_t extra = read_u32(&next_instr[3].cache); + uint32_t extra = read_u32(&this_instr[4].cache); res = op2(arg2, left, right); } STACK_SHRINK(2); stack_pointer[-1] = res; - next_instr += 5; + DISPATCH(); + } + + TARGET(OP1) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(OP1); + PyObject *right; + PyObject *left; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + uint16_t counter = read_u16(&this_instr[1].cache); + op1(left, right); DISPATCH(); } TARGET(OP3) { + frame->instr_ptr = next_instr; + next_instr += 6; + INSTRUCTION_STATS(OP3); PyObject *right; PyObject *left; PyObject *arg2; @@ -406,7 +461,44 @@ def test_macro_instruction(self): res = op3(arg2, left, right); STACK_SHRINK(2); stack_pointer[-1] = res; - next_instr += 5; + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_pseudo_instruction_no_flags(self): + input = """ + pseudo(OP) = { + OP1, + }; + + inst(OP1, (--)) { + } + """ + output = """ + TARGET(OP1) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP1); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_pseudo_instruction_with_flags(self): + input = """ + pseudo(OP, (HAS_ARG, HAS_JUMP)) = { + OP1, + }; + + inst(OP1, (--)) { + } + """ + output = """ + TARGET(OP1) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP1); DISPATCH(); } """ @@ -420,6 +512,9 @@ def test_array_input(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *above; PyObject **values; PyObject *below; @@ -442,6 +537,9 @@ def test_array_output(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *below; PyObject **values; PyObject *above; @@ -463,6 +561,9 @@ def test_array_input_output(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject **values; PyObject *above; values = stack_pointer - oparg; @@ -482,6 +583,9 @@ def test_array_error_if(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject **values; PyObject *extra; values = stack_pointer - oparg; @@ -502,6 +606,9 @@ def test_cond_effect(self): """ output = """ TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); PyObject *cc; PyObject *input = NULL; PyObject *aa; @@ -534,6 +641,9 @@ def test_macro_cond_effect(self): """ output = """ TARGET(M) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(M); PyObject *right; PyObject *middle; PyObject *left; @@ -573,6 +683,9 @@ def test_macro_push_push(self): """ output = """ TARGET(M) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(M); PyObject *val1; PyObject *val2; // A @@ -591,6 +704,90 @@ def test_macro_push_push(self): """ self.run_cases_test(input, output) + def test_override_inst(self): + input = """ + inst(OP, (--)) { + spam(); + } + override inst(OP, (--)) { + ham(); + } + """ + output = """ + TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(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) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(M); + ham(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_annotated_inst(self): + input = """ + guard inst(OP, (--)) { + ham(); + } + """ + output = """ + TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); + ham(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_annotated_op(self): + input = """ + guard op(OP, (--)) { + spam(); + } + macro(M) = OP; + """ + output = """ + TARGET(M) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(M); + spam(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + input = """ + guard register specializing op(OP, (--)) { + spam(); + } + macro(M) = OP; + """ + self.run_cases_test(input, output) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index bf600a0f4d1834..04cb810d9babbf 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -28,7 +28,7 @@ from itertools import chain from http.cookies import Morsel try: - from multiprocessing.managers import ValueProxy + from multiprocessing.managers import ValueProxy, DictProxy, ListProxy from multiprocessing.pool import ApplyResult from multiprocessing.queues import SimpleQueue as MPSimpleQueue from multiprocessing.queues import Queue as MPQueue @@ -36,6 +36,8 @@ except ImportError: # _multiprocessing module is optional ValueProxy = None + DictProxy = None + ListProxy = None ApplyResult = None MPSimpleQueue = None MPQueue = None @@ -134,7 +136,7 @@ class BaseTest(unittest.TestCase): if ctypes is not None: generic_types.extend((ctypes.Array, ctypes.LibraryLoader)) if ValueProxy is not None: - generic_types.extend((ValueProxy, ApplyResult, + generic_types.extend((ValueProxy, DictProxy, ListProxy, ApplyResult, MPSimpleQueue, MPQueue, MPJoinableQueue)) def test_subscriptable(self): diff --git a/Lib/test/test_genericclass.py b/Lib/test/test_genericclass.py index d8bb37f69e18a1..aece757fc1933e 100644 --- a/Lib/test/test_genericclass.py +++ b/Lib/test/test_genericclass.py @@ -98,7 +98,7 @@ def __mro_entries__(self): return () d = C_too_few() with self.assertRaises(TypeError): - class D(d): ... + class E(d): ... def test_mro_entry_errors_2(self): class C_not_callable: @@ -111,7 +111,7 @@ def __mro_entries__(self): return object c = C_not_tuple() with self.assertRaises(TypeError): - class D(c): ... + class E(c): ... def test_mro_entry_metaclass(self): meta_args = [] diff --git a/Lib/test/test_getpass.py b/Lib/test/test_getpass.py index 98ecec94336e32..80dda2caaa3331 100644 --- a/Lib/test/test_getpass.py +++ b/Lib/test/test_getpass.py @@ -26,7 +26,7 @@ def test_username_priorities_of_env_values(self, environ): environ.get.return_value = None try: getpass.getuser() - except ImportError: # in case there's no pwd module + except OSError: # in case there's no pwd module pass except KeyError: # current user has no pwd entry @@ -47,7 +47,7 @@ def test_username_falls_back_to_pwd(self, environ): getpass.getuser()) getpw.assert_called_once_with(42) else: - self.assertRaises(ImportError, getpass.getuser) + self.assertRaises(OSError, getpass.getuser) class GetpassRawinputTest(unittest.TestCase): diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py index b9cbe1d92c436f..2f7aa69efc184a 100644 --- a/Lib/test/test_getpath.py +++ b/Lib/test/test_getpath.py @@ -818,6 +818,20 @@ def test_symlink_buildpath_macos(self): actual = getpath(ns, expected) self.assertEqual(expected, actual) + def test_explicitly_set_stdlib_dir(self): + """Test the explicitly set stdlib_dir in the config is respected.""" + ns = MockPosixNamespace( + PREFIX="/usr", + argv0="python", + ENV_PATH="/usr/bin", + ) + ns["config"]["stdlib_dir"] = "/custom_stdlib_dir" + expected = dict( + stdlib_dir="/custom_stdlib_dir", + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + # ****************************************************************************** diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index 8430fc234d00ee..b2fe3e28c3bec7 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,55 +320,139 @@ 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) + + lineno = self._test_plural_forms.__code__.co_firstlineno + 12 + with self.assertWarns(DeprecationWarning) as cm: + x = ngettext(singular, plural, 1.0) + self.assertEqual(cm.filename, __file__) + self.assertEqual(cm.lineno, lineno) + 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 + 5) + self.assertEqual(x, tplural) + + if numbers_only: + with self.assertRaises(TypeError): + ngettext(singular, plural, None) + else: + with self.assertWarns(DeprecationWarning) as cm: + 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') - x = gettext.gettext('There is %s file') - eq(x, 'Hay %s fichero') - - 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)') - x = gettext.pgettext('With context', 'There is %s file') - eq(x, 'Hay %s fichero (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') - x = t.gettext('There is %s file') - eq(x, 'Hay %s fichero') - - def test_plural_context_forms2(self): - eq = self.assertEqual - with open(self.mofile, 'rb') as fp: + self.gettext = gettext.gettext + self.ngettext = gettext.ngettext + self.pgettext = gettext.pgettext + self.npgettext = gettext.npgettext + + +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)') - x = gettext.pgettext('With context', 'There is %s file') - eq(x, 'Hay %s fichero (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_glob.py b/Lib/test/test_glob.py index f4b5821f408cb4..aa5fac8eca1354 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -1,5 +1,6 @@ import glob import os +import re import shutil import sys import unittest @@ -349,6 +350,96 @@ def test_glob_many_open_files(self): for it in iters: self.assertEqual(next(it), p) + def test_translate_matching(self): + match = re.compile(glob.translate('*')).match + self.assertIsNotNone(match('foo')) + self.assertIsNotNone(match('foo.bar')) + self.assertIsNone(match('.foo')) + match = re.compile(glob.translate('.*')).match + self.assertIsNotNone(match('.foo')) + match = re.compile(glob.translate('**', recursive=True)).match + self.assertIsNotNone(match('foo')) + self.assertIsNone(match('.foo')) + self.assertIsNotNone(match(os.path.join('foo', 'bar'))) + self.assertIsNone(match(os.path.join('foo', '.bar'))) + self.assertIsNone(match(os.path.join('.foo', 'bar'))) + self.assertIsNone(match(os.path.join('.foo', '.bar'))) + match = re.compile(glob.translate('**/*', recursive=True)).match + self.assertIsNotNone(match(os.path.join('foo', 'bar'))) + self.assertIsNone(match(os.path.join('foo', '.bar'))) + self.assertIsNone(match(os.path.join('.foo', 'bar'))) + self.assertIsNone(match(os.path.join('.foo', '.bar'))) + match = re.compile(glob.translate('*/**', recursive=True)).match + self.assertIsNotNone(match(os.path.join('foo', 'bar'))) + self.assertIsNone(match(os.path.join('foo', '.bar'))) + self.assertIsNone(match(os.path.join('.foo', 'bar'))) + self.assertIsNone(match(os.path.join('.foo', '.bar'))) + match = re.compile(glob.translate('**/.bar', recursive=True)).match + self.assertIsNotNone(match(os.path.join('foo', '.bar'))) + self.assertIsNone(match(os.path.join('.foo', '.bar'))) + match = re.compile(glob.translate('**/*.*', recursive=True)).match + self.assertIsNone(match(os.path.join('foo', 'bar'))) + self.assertIsNone(match(os.path.join('foo', '.bar'))) + self.assertIsNotNone(match(os.path.join('foo', 'bar.txt'))) + self.assertIsNone(match(os.path.join('foo', '.bar.txt'))) + + def test_translate(self): + def fn(pat): + return glob.translate(pat, seps='/') + self.assertEqual(fn('foo'), r'(?s:foo)\Z') + self.assertEqual(fn('foo/bar'), r'(?s:foo/bar)\Z') + self.assertEqual(fn('*'), r'(?s:[^/.][^/]*)\Z') + self.assertEqual(fn('?'), r'(?s:(?!\.)[^/])\Z') + self.assertEqual(fn('a*'), r'(?s:a[^/]*)\Z') + self.assertEqual(fn('*a'), r'(?s:(?!\.)[^/]*a)\Z') + self.assertEqual(fn('.*'), r'(?s:\.[^/]*)\Z') + self.assertEqual(fn('?aa'), r'(?s:(?!\.)[^/]aa)\Z') + self.assertEqual(fn('aa?'), r'(?s:aa[^/])\Z') + self.assertEqual(fn('aa[ab]'), r'(?s:aa[ab])\Z') + self.assertEqual(fn('**'), r'(?s:(?!\.)[^/]*)\Z') + self.assertEqual(fn('***'), r'(?s:(?!\.)[^/]*)\Z') + self.assertEqual(fn('a**'), r'(?s:a[^/]*)\Z') + self.assertEqual(fn('**b'), r'(?s:(?!\.)[^/]*b)\Z') + self.assertEqual(fn('/**/*/*.*/**'), + r'(?s:/(?!\.)[^/]*/[^/.][^/]*/(?!\.)[^/]*\.[^/]*/(?!\.)[^/]*)\Z') + + def test_translate_include_hidden(self): + def fn(pat): + return glob.translate(pat, include_hidden=True, seps='/') + self.assertEqual(fn('foo'), r'(?s:foo)\Z') + self.assertEqual(fn('foo/bar'), r'(?s:foo/bar)\Z') + self.assertEqual(fn('*'), r'(?s:[^/]+)\Z') + self.assertEqual(fn('?'), r'(?s:[^/])\Z') + self.assertEqual(fn('a*'), r'(?s:a[^/]*)\Z') + self.assertEqual(fn('*a'), r'(?s:[^/]*a)\Z') + self.assertEqual(fn('.*'), r'(?s:\.[^/]*)\Z') + self.assertEqual(fn('?aa'), r'(?s:[^/]aa)\Z') + self.assertEqual(fn('aa?'), r'(?s:aa[^/])\Z') + self.assertEqual(fn('aa[ab]'), r'(?s:aa[ab])\Z') + self.assertEqual(fn('**'), r'(?s:[^/]*)\Z') + self.assertEqual(fn('***'), r'(?s:[^/]*)\Z') + self.assertEqual(fn('a**'), r'(?s:a[^/]*)\Z') + self.assertEqual(fn('**b'), r'(?s:[^/]*b)\Z') + self.assertEqual(fn('/**/*/*.*/**'), r'(?s:/[^/]*/[^/]+/[^/]*\.[^/]*/[^/]*)\Z') + + def test_translate_recursive(self): + def fn(pat): + return glob.translate(pat, recursive=True, include_hidden=True, seps='/') + self.assertEqual(fn('*'), r'(?s:[^/]+)\Z') + self.assertEqual(fn('?'), r'(?s:[^/])\Z') + self.assertEqual(fn('**'), r'(?s:.*)\Z') + self.assertEqual(fn('**/**'), r'(?s:.*)\Z') + self.assertRaises(ValueError, fn, '***') + self.assertRaises(ValueError, fn, 'a**') + self.assertRaises(ValueError, fn, '**b') + self.assertEqual(fn('/**/*/*.*/**'), r'(?s:/(?:.+/)?[^/]+/[^/]*\.[^/]*/.*)\Z') + + def test_translate_seps(self): + def fn(pat): + return glob.translate(pat, recursive=True, include_hidden=True, seps=['/', '\\']) + self.assertEqual(fn('foo/bar\\baz'), r'(?s:foo[/\\]bar[/\\]baz)\Z') + self.assertEqual(fn('**/*'), r'(?s:(?:.+[/\\])?[^/\\]+)\Z') + @skip_unless_symlink class SymlinkLoopGlobTests(unittest.TestCase): diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 5d5832b62b2f94..caa4c76a913a01 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -283,6 +283,22 @@ def test_ipv6host_header(self): conn.request('GET', '/foo') self.assertTrue(sock.data.startswith(expected)) + expected = b'GET /foo HTTP/1.1\r\nHost: [fe80::]\r\n' \ + b'Accept-Encoding: identity\r\n\r\n' + conn = client.HTTPConnection('[fe80::%2]') + sock = FakeSocket('') + conn.sock = sock + conn.request('GET', '/foo') + self.assertTrue(sock.data.startswith(expected)) + + expected = b'GET /foo HTTP/1.1\r\nHost: [fe80::]:81\r\n' \ + b'Accept-Encoding: identity\r\n\r\n' + conn = client.HTTPConnection('[fe80::%2]:81') + sock = FakeSocket('') + conn.sock = sock + conn.request('GET', '/foo') + self.assertTrue(sock.data.startswith(expected)) + def test_malformed_headers_coped_with(self): # Issue 19996 body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n" diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 48553f9d48b010..48c0a43f29e27f 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 @@ -410,9 +409,12 @@ def test_case_sensitivity(self): import RAnDoM def test_double_const(self): - # Another brief digression to test the accuracy of manifest float - # constants. - from test import double_const # don't blink -- that *was* the test + # Importing double_const checks that float constants + # serialiazed by marshal as PYC files don't lose precision + # (SF bug 422177). + from test.test_import.data import double_const + unload('test.test_import.data.double_const') + from test.test_import.data import double_const def test_import(self): def test_with_extension(ext): @@ -1969,10 +1971,13 @@ def test_disallowed_reimport(self): 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) + self.addCleanup(lambda: _interpreters.destroy(interpid)) + + excsnap = _interpreters.run_string(interpid, script) + self.assertIsNot(excsnap, None) + + excsnap = _interpreters.run_string(interpid, script) + self.assertIsNot(excsnap, None) class TestSinglePhaseSnapshot(ModuleSnapshot): @@ -2101,12 +2106,18 @@ def re_load(self, name, mod): def add_subinterpreter(self): interpid = _interpreters.create(isolated=False) - _interpreters.run_string(interpid, textwrap.dedent(''' + def ensure_destroyed(): + try: + _interpreters.destroy(interpid) + except _interpreters.InterpreterNotFoundError: + pass + self.addCleanup(ensure_destroyed) + _interpreters.exec(interpid, textwrap.dedent(''' import sys import _testinternalcapi ''')) def clean_up(): - _interpreters.run_string(interpid, textwrap.dedent(f''' + _interpreters.exec(interpid, textwrap.dedent(f''' name = {self.NAME!r} if name in sys.modules: sys.modules.pop(name)._clear_globals() diff --git a/Lib/test/double_const.py b/Lib/test/test_import/data/double_const.py similarity index 100% rename from Lib/test/double_const.py rename to Lib/test/test_import/data/double_const.py diff --git a/Lib/test/test_importlib/test_namespace_pkgs.py b/Lib/test/test_importlib/test_namespace_pkgs.py index 9b3bef02c66820..072e198795d394 100644 --- a/Lib/test/test_importlib/test_namespace_pkgs.py +++ b/Lib/test/test_importlib/test_namespace_pkgs.py @@ -80,7 +80,7 @@ def test_cant_import_other(self): def test_simple_repr(self): import foo.one - assert repr(foo).startswith(" 42: pass self.assertEqual(str(inspect.signature(foo)), '(a: int = 1, *, b, c=None, **kwargs) -> 42') + self.assertEqual(str(inspect.signature(foo)), + inspect.signature(foo).format()) def foo(a:int=1, *args, b, c=None, **kwargs) -> 42: pass self.assertEqual(str(inspect.signature(foo)), '(a: int = 1, *args, b, c=None, **kwargs) -> 42') + self.assertEqual(str(inspect.signature(foo)), + inspect.signature(foo).format()) def foo(): pass self.assertEqual(str(inspect.signature(foo)), '()') + self.assertEqual(str(inspect.signature(foo)), + inspect.signature(foo).format()) def foo(a: list[str]) -> tuple[str, float]: pass self.assertEqual(str(inspect.signature(foo)), '(a: list[str]) -> tuple[str, float]') + self.assertEqual(str(inspect.signature(foo)), + inspect.signature(foo).format()) from typing import Tuple def foo(a: list[str]) -> Tuple[str, float]: pass self.assertEqual(str(inspect.signature(foo)), '(a: list[str]) -> Tuple[str, float]') + self.assertEqual(str(inspect.signature(foo)), + inspect.signature(foo).format()) def test_signature_str_positional_only(self): P = inspect.Parameter @@ -3815,19 +3836,85 @@ def test(a_po, /, *, b, **kwargs): self.assertEqual(str(inspect.signature(test)), '(a_po, /, *, b, **kwargs)') + self.assertEqual(str(inspect.signature(test)), + inspect.signature(test).format()) + + test = S(parameters=[P('foo', P.POSITIONAL_ONLY)]) + self.assertEqual(str(test), '(foo, /)') + self.assertEqual(str(test), test.format()) - self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])), - '(foo, /)') + test = S(parameters=[P('foo', P.POSITIONAL_ONLY), + P('bar', P.VAR_KEYWORD)]) + self.assertEqual(str(test), '(foo, /, **bar)') + self.assertEqual(str(test), test.format()) - self.assertEqual(str(S(parameters=[ - P('foo', P.POSITIONAL_ONLY), - P('bar', P.VAR_KEYWORD)])), - '(foo, /, **bar)') + test = S(parameters=[P('foo', P.POSITIONAL_ONLY), + P('bar', P.VAR_POSITIONAL)]) + self.assertEqual(str(test), '(foo, /, *bar)') + self.assertEqual(str(test), test.format()) - self.assertEqual(str(S(parameters=[ - P('foo', P.POSITIONAL_ONLY), - P('bar', P.VAR_POSITIONAL)])), - '(foo, /, *bar)') + def test_signature_format(self): + from typing import Annotated, Literal + + def func(x: Annotated[int, 'meta'], y: Literal['a', 'b'], z: 'LiteralString'): + pass + + expected_singleline = "(x: Annotated[int, 'meta'], y: Literal['a', 'b'], z: 'LiteralString')" + expected_multiline = """( + x: Annotated[int, 'meta'], + y: Literal['a', 'b'], + z: 'LiteralString' +)""" + self.assertEqual( + inspect.signature(func).format(), + expected_singleline, + ) + self.assertEqual( + inspect.signature(func).format(max_width=None), + expected_singleline, + ) + self.assertEqual( + inspect.signature(func).format(max_width=len(expected_singleline)), + expected_singleline, + ) + self.assertEqual( + inspect.signature(func).format(max_width=len(expected_singleline) - 1), + expected_multiline, + ) + self.assertEqual( + inspect.signature(func).format(max_width=0), + expected_multiline, + ) + self.assertEqual( + inspect.signature(func).format(max_width=-1), + expected_multiline, + ) + + def test_signature_format_all_arg_types(self): + from typing import Annotated, Literal + + def func( + x: Annotated[int, 'meta'], + /, + y: Literal['a', 'b'], + *, + z: 'LiteralString', + **kwargs: object, + ) -> None: + pass + + expected_multiline = """( + x: Annotated[int, 'meta'], + /, + y: Literal['a', 'b'], + *, + z: 'LiteralString', + **kwargs: object +) -> None""" + self.assertEqual( + inspect.signature(func).format(max_width=-1), + expected_multiline, + ) def test_signature_replace_parameters(self): def test(a, b) -> 42: @@ -4730,19 +4817,15 @@ def test_builtins_have_signatures(self): # These have unrepresentable parameter default values of NULL needs_null = {"anext"} no_signature |= needs_null - # These need PEP 457 groups or a signature change to accept None - needs_semantic_update = {"round"} - no_signature |= needs_semantic_update # These need *args support in Argument Clinic - needs_varargs = {"breakpoint", "min", "max", "print", - "__build_class__"} + needs_varargs = {"min", "max", "__build_class__"} no_signature |= needs_varargs - # These simply weren't covered in the initial AC conversion - # for builtin callables - not_converted_yet = {"open", "__import__"} - no_signature |= not_converted_yet # These builtin types are expected to provide introspection info - types_with_signatures = set() + types_with_signatures = { + 'bool', 'classmethod', 'complex', 'enumerate', 'filter', 'float', + 'frozenset', 'list', 'map', 'memoryview', 'object', 'property', + 'reversed', 'set', 'staticmethod', 'tuple', 'zip' + } # Check the signatures we expect to be there ns = vars(builtins) for name, obj in sorted(ns.items()): @@ -4755,15 +4838,19 @@ def test_builtins_have_signatures(self): if (name in no_signature): # Not yet converted continue + if name in {'classmethod', 'staticmethod'}: + # Bug gh-112006: inspect.unwrap() does not work with types + # with the __wrapped__ data descriptor. + continue with self.subTest(builtin=name): self.assertIsNotNone(inspect.signature(obj)) # Check callables that haven't been converted don't claim a signature # This ensures this test will start failing as more signatures are # added, so the affected items can be moved into the scope of the # regression test above - for name in no_signature: + for name in no_signature - needs_null: with self.subTest(builtin=name): - self.assertIsNone(obj.__text_signature__) + self.assertIsNone(ns[name].__text_signature__) def test_python_function_override_signature(self): def func(*args, **kwargs): @@ -4960,5 +5047,66 @@ def test_getsource_reload(self): self.assertInspectEqual(path, module) +class TestRepl(unittest.TestCase): + + def spawn_repl(self, *args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): + """Run the Python REPL with the given arguments. + + kw is extra keyword args to pass to subprocess.Popen. Returns a Popen + object. + """ + + # To run the REPL without using a terminal, spawn python with the command + # line option '-i' and the process name set to ''. + # The directory of argv[0] must match the directory of the Python + # executable for the Popen() call to python to succeed as the directory + # path may be used by Py_GetPath() to build the default module search + # path. + stdin_fname = os.path.join(os.path.dirname(sys.executable), "") + cmd_line = [stdin_fname, '-E', '-i'] + cmd_line.extend(args) + + # Set TERM=vt100, for the rationale see the comments in spawn_python() of + # test.support.script_helper. + env = kw.setdefault('env', dict(os.environ)) + env['TERM'] = 'vt100' + return subprocess.Popen(cmd_line, + executable=sys.executable, + text=True, + stdin=subprocess.PIPE, + stdout=stdout, stderr=stderr, + **kw) + + def run_on_interactive_mode(self, source): + """Spawn a new Python interpreter, pass the given + input source code from the stdin and return the + result back. If the interpreter exits non-zero, it + raises a ValueError.""" + + process = self.spawn_repl() + process.stdin.write(source) + output = kill_python(process) + + if process.returncode != 0: + raise ValueError("Process didn't exit properly.") + return output + + @unittest.skipIf(not has_subprocess_support, "test requires subprocess") + def test_getsource(self): + output = self.run_on_interactive_mode(textwrap.dedent("""\ + def f(): + print(0) + return 1 + 2 + + import inspect + print(f"The source is: <<<{inspect.getsource(f)}>>>") + """)) + + expected = "The source is: <<>>" + self.assertIn(expected, output) + + + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py deleted file mode 100644 index 9c0dac7d6c61fb..00000000000000 --- a/Lib/test/test_interpreters.py +++ /dev/null @@ -1,793 +0,0 @@ -import contextlib -import os -import sys -import threading -from textwrap import dedent -import unittest -import time - -from test import support -from test.support import import_helper -from test.support import threading_helper -_interpreters = import_helper.import_module('_xxsubinterpreters') -_channels = import_helper.import_module('_xxinterpchannels') -from test.support import interpreters - - -def _captured_script(script): - r, w = os.pipe() - indented = script.replace('\n', '\n ') - wrapped = dedent(f""" - import contextlib - with open({w}, 'w', encoding='utf-8') as spipe: - with contextlib.redirect_stdout(spipe): - {indented} - """) - return wrapped, open(r, encoding='utf-8') - - -def clean_up_interpreters(): - for interp in interpreters.list_all(): - if interp.id == 0: # main - continue - try: - interp.close() - except RuntimeError: - pass # already destroyed - - -def _run_output(interp, request, channels=None): - script, rpipe = _captured_script(request) - with rpipe: - interp.run(script, channels=channels) - return rpipe.read() - - -@contextlib.contextmanager -def _running(interp): - r, w = os.pipe() - def run(): - interp.run(dedent(f""" - # wait for "signal" - with open({r}) as rpipe: - rpipe.read() - """)) - - t = threading.Thread(target=run) - t.start() - - yield - - with open(w, 'w') as spipe: - spipe.write('done') - t.join() - - -class TestBase(unittest.TestCase): - - def tearDown(self): - clean_up_interpreters() - - -class CreateTests(TestBase): - - def test_in_main(self): - interp = interpreters.create() - self.assertIsInstance(interp, interpreters.Interpreter) - self.assertIn(interp, interpreters.list_all()) - - def test_in_thread(self): - lock = threading.Lock() - interp = None - def f(): - nonlocal interp - interp = interpreters.create() - lock.acquire() - lock.release() - t = threading.Thread(target=f) - with lock: - t.start() - t.join() - self.assertIn(interp, interpreters.list_all()) - - def test_in_subinterpreter(self): - main, = interpreters.list_all() - interp = interpreters.create() - out = _run_output(interp, dedent(""" - from test.support import interpreters - interp = interpreters.create() - print(interp.id) - """)) - interp2 = interpreters.Interpreter(int(out)) - self.assertEqual(interpreters.list_all(), [main, interp, interp2]) - - def test_after_destroy_all(self): - before = set(interpreters.list_all()) - # Create 3 subinterpreters. - interp_lst = [] - for _ in range(3): - interps = interpreters.create() - interp_lst.append(interps) - # Now destroy them. - for interp in interp_lst: - interp.close() - # Finally, create another. - interp = interpreters.create() - self.assertEqual(set(interpreters.list_all()), before | {interp}) - - def test_after_destroy_some(self): - before = set(interpreters.list_all()) - # Create 3 subinterpreters. - interp1 = interpreters.create() - interp2 = interpreters.create() - interp3 = interpreters.create() - # Now destroy 2 of them. - interp1.close() - interp2.close() - # Finally, create another. - interp = interpreters.create() - self.assertEqual(set(interpreters.list_all()), before | {interp3, interp}) - - -class GetCurrentTests(TestBase): - - def test_main(self): - main = interpreters.get_main() - current = interpreters.get_current() - self.assertEqual(current, main) - - def test_subinterpreter(self): - main = _interpreters.get_main() - interp = interpreters.create() - out = _run_output(interp, dedent(""" - from test.support import interpreters - cur = interpreters.get_current() - print(cur.id) - """)) - current = interpreters.Interpreter(int(out)) - self.assertNotEqual(current, main) - - -class ListAllTests(TestBase): - - def test_initial(self): - interps = interpreters.list_all() - self.assertEqual(1, len(interps)) - - def test_after_creating(self): - main = interpreters.get_current() - first = interpreters.create() - second = interpreters.create() - - ids = [] - for interp in interpreters.list_all(): - ids.append(interp.id) - - self.assertEqual(ids, [main.id, first.id, second.id]) - - def test_after_destroying(self): - main = interpreters.get_current() - first = interpreters.create() - second = interpreters.create() - first.close() - - ids = [] - for interp in interpreters.list_all(): - ids.append(interp.id) - - self.assertEqual(ids, [main.id, second.id]) - - -class TestInterpreterAttrs(TestBase): - - def test_id_type(self): - main = interpreters.get_main() - current = interpreters.get_current() - interp = interpreters.create() - self.assertIsInstance(main.id, _interpreters.InterpreterID) - self.assertIsInstance(current.id, _interpreters.InterpreterID) - self.assertIsInstance(interp.id, _interpreters.InterpreterID) - - def test_main_id(self): - main = interpreters.get_main() - self.assertEqual(main.id, 0) - - def test_custom_id(self): - interp = interpreters.Interpreter(1) - self.assertEqual(interp.id, 1) - - with self.assertRaises(TypeError): - interpreters.Interpreter('1') - - def test_id_readonly(self): - interp = interpreters.Interpreter(1) - with self.assertRaises(AttributeError): - interp.id = 2 - - @unittest.skip('not ready yet (see bpo-32604)') - def test_main_isolated(self): - main = interpreters.get_main() - self.assertFalse(main.isolated) - - @unittest.skip('not ready yet (see bpo-32604)') - def test_subinterpreter_isolated_default(self): - interp = interpreters.create() - self.assertFalse(interp.isolated) - - def test_subinterpreter_isolated_explicit(self): - interp1 = interpreters.create(isolated=True) - interp2 = interpreters.create(isolated=False) - self.assertTrue(interp1.isolated) - self.assertFalse(interp2.isolated) - - @unittest.skip('not ready yet (see bpo-32604)') - def test_custom_isolated_default(self): - interp = interpreters.Interpreter(1) - self.assertFalse(interp.isolated) - - def test_custom_isolated_explicit(self): - interp1 = interpreters.Interpreter(1, isolated=True) - interp2 = interpreters.Interpreter(1, isolated=False) - self.assertTrue(interp1.isolated) - self.assertFalse(interp2.isolated) - - def test_isolated_readonly(self): - interp = interpreters.Interpreter(1) - with self.assertRaises(AttributeError): - interp.isolated = True - - def test_equality(self): - interp1 = interpreters.create() - interp2 = interpreters.create() - self.assertEqual(interp1, interp1) - self.assertNotEqual(interp1, interp2) - - -class TestInterpreterIsRunning(TestBase): - - def test_main(self): - main = interpreters.get_main() - self.assertTrue(main.is_running()) - - @unittest.skip('Fails on FreeBSD') - def test_subinterpreter(self): - interp = interpreters.create() - self.assertFalse(interp.is_running()) - - with _running(interp): - self.assertTrue(interp.is_running()) - self.assertFalse(interp.is_running()) - - def test_from_subinterpreter(self): - interp = interpreters.create() - out = _run_output(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - if _interpreters.is_running({interp.id}): - print(True) - else: - print(False) - """)) - self.assertEqual(out.strip(), 'True') - - def test_already_destroyed(self): - interp = interpreters.create() - interp.close() - with self.assertRaises(RuntimeError): - interp.is_running() - - def test_does_not_exist(self): - interp = interpreters.Interpreter(1_000_000) - with self.assertRaises(RuntimeError): - interp.is_running() - - def test_bad_id(self): - interp = interpreters.Interpreter(-1) - with self.assertRaises(ValueError): - interp.is_running() - - -class TestInterpreterClose(TestBase): - - def test_basic(self): - main = interpreters.get_main() - interp1 = interpreters.create() - interp2 = interpreters.create() - interp3 = interpreters.create() - self.assertEqual(set(interpreters.list_all()), - {main, interp1, interp2, interp3}) - interp2.close() - self.assertEqual(set(interpreters.list_all()), - {main, interp1, interp3}) - - def test_all(self): - before = set(interpreters.list_all()) - interps = set() - for _ in range(3): - interp = interpreters.create() - interps.add(interp) - self.assertEqual(set(interpreters.list_all()), before | interps) - for interp in interps: - interp.close() - self.assertEqual(set(interpreters.list_all()), before) - - def test_main(self): - main, = interpreters.list_all() - with self.assertRaises(RuntimeError): - main.close() - - def f(): - with self.assertRaises(RuntimeError): - main.close() - - t = threading.Thread(target=f) - t.start() - t.join() - - def test_already_destroyed(self): - interp = interpreters.create() - interp.close() - with self.assertRaises(RuntimeError): - interp.close() - - def test_does_not_exist(self): - interp = interpreters.Interpreter(1_000_000) - with self.assertRaises(RuntimeError): - interp.close() - - def test_bad_id(self): - interp = interpreters.Interpreter(-1) - with self.assertRaises(ValueError): - interp.close() - - def test_from_current(self): - main, = interpreters.list_all() - interp = interpreters.create() - out = _run_output(interp, dedent(f""" - from test.support import interpreters - interp = interpreters.Interpreter({int(interp.id)}) - try: - interp.close() - except RuntimeError: - print('failed') - """)) - self.assertEqual(out.strip(), 'failed') - self.assertEqual(set(interpreters.list_all()), {main, interp}) - - def test_from_sibling(self): - main, = interpreters.list_all() - interp1 = interpreters.create() - interp2 = interpreters.create() - self.assertEqual(set(interpreters.list_all()), - {main, interp1, interp2}) - interp1.run(dedent(f""" - from test.support import interpreters - interp2 = interpreters.Interpreter(int({interp2.id})) - interp2.close() - interp3 = interpreters.create() - interp3.close() - """)) - self.assertEqual(set(interpreters.list_all()), {main, interp1}) - - def test_from_other_thread(self): - interp = interpreters.create() - def f(): - interp.close() - - t = threading.Thread(target=f) - t.start() - t.join() - - @unittest.skip('Fails on FreeBSD') - def test_still_running(self): - main, = interpreters.list_all() - interp = interpreters.create() - with _running(interp): - with self.assertRaises(RuntimeError): - interp.close() - self.assertTrue(interp.is_running()) - - -class TestInterpreterRun(TestBase): - - def test_success(self): - interp = interpreters.create() - script, file = _captured_script('print("it worked!", end="")') - with file: - interp.run(script) - out = file.read() - - self.assertEqual(out, 'it worked!') - - def test_in_thread(self): - interp = interpreters.create() - script, file = _captured_script('print("it worked!", end="")') - with file: - def f(): - interp.run(script) - - t = threading.Thread(target=f) - t.start() - t.join() - out = file.read() - - self.assertEqual(out, 'it worked!') - - @support.requires_fork() - def test_fork(self): - interp = interpreters.create() - import tempfile - with tempfile.NamedTemporaryFile('w+', encoding='utf-8') as file: - file.write('') - file.flush() - - expected = 'spam spam spam spam spam' - script = dedent(f""" - import os - try: - os.fork() - except RuntimeError: - with open('{file.name}', 'w', encoding='utf-8') as out: - out.write('{expected}') - """) - interp.run(script) - - file.seek(0) - content = file.read() - self.assertEqual(content, expected) - - @unittest.skip('Fails on FreeBSD') - def test_already_running(self): - interp = interpreters.create() - with _running(interp): - with self.assertRaises(RuntimeError): - interp.run('print("spam")') - - def test_does_not_exist(self): - interp = interpreters.Interpreter(1_000_000) - with self.assertRaises(RuntimeError): - interp.run('print("spam")') - - def test_bad_id(self): - interp = interpreters.Interpreter(-1) - with self.assertRaises(ValueError): - interp.run('print("spam")') - - def test_bad_script(self): - interp = interpreters.create() - with self.assertRaises(TypeError): - interp.run(10) - - def test_bytes_for_script(self): - interp = interpreters.create() - with self.assertRaises(TypeError): - interp.run(b'print("spam")') - - # 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 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): - shareables = [ - # singletons - None, - # builtin objects - b'spam', - 'spam', - 10, - -10, - ] - for obj in shareables: - with self.subTest(obj): - shareable = interpreters.is_shareable(obj) - self.assertTrue(shareable) - - def test_not_shareable(self): - class Cheese: - def __init__(self, name): - self.name = name - def __str__(self): - return self.name - - class SubBytes(bytes): - """A subclass of a shareable type.""" - - not_shareables = [ - # singletons - True, - False, - NotImplemented, - ..., - # builtin types and objects - type, - object, - object(), - Exception(), - 100.0, - # user-defined types and objects - Cheese, - Cheese('Wensleydale'), - SubBytes(b'spam'), - ] - for obj in not_shareables: - with self.subTest(repr(obj)): - self.assertFalse( - interpreters.is_shareable(obj)) - - -class TestChannels(TestBase): - - def test_create(self): - r, s = interpreters.create_channel() - self.assertIsInstance(r, interpreters.RecvChannel) - self.assertIsInstance(s, interpreters.SendChannel) - - def test_list_all(self): - self.assertEqual(interpreters.list_all_channels(), []) - created = set() - for _ in range(3): - ch = interpreters.create_channel() - created.add(ch) - after = set(interpreters.list_all_channels()) - self.assertEqual(after, created) - - -class TestRecvChannelAttrs(TestBase): - - def test_id_type(self): - rch, _ = interpreters.create_channel() - self.assertIsInstance(rch.id, _channels.ChannelID) - - def test_custom_id(self): - rch = interpreters.RecvChannel(1) - self.assertEqual(rch.id, 1) - - with self.assertRaises(TypeError): - interpreters.RecvChannel('1') - - def test_id_readonly(self): - rch = interpreters.RecvChannel(1) - with self.assertRaises(AttributeError): - rch.id = 2 - - def test_equality(self): - ch1, _ = interpreters.create_channel() - ch2, _ = interpreters.create_channel() - self.assertEqual(ch1, ch1) - self.assertNotEqual(ch1, ch2) - - -class TestSendChannelAttrs(TestBase): - - def test_id_type(self): - _, sch = interpreters.create_channel() - self.assertIsInstance(sch.id, _channels.ChannelID) - - def test_custom_id(self): - sch = interpreters.SendChannel(1) - self.assertEqual(sch.id, 1) - - with self.assertRaises(TypeError): - interpreters.SendChannel('1') - - def test_id_readonly(self): - sch = interpreters.SendChannel(1) - with self.assertRaises(AttributeError): - sch.id = 2 - - def test_equality(self): - _, ch1 = interpreters.create_channel() - _, ch2 = interpreters.create_channel() - self.assertEqual(ch1, ch1) - self.assertNotEqual(ch1, ch2) - - -class TestSendRecv(TestBase): - - def test_send_recv_main(self): - r, s = interpreters.create_channel() - orig = b'spam' - s.send_nowait(orig) - obj = r.recv() - - self.assertEqual(obj, orig) - self.assertIsNot(obj, orig) - - def test_send_recv_same_interpreter(self): - interp = interpreters.create() - interp.run(dedent(""" - from test.support import interpreters - r, s = interpreters.create_channel() - orig = b'spam' - s.send_nowait(orig) - obj = r.recv() - assert obj == orig, 'expected: obj == orig' - assert obj is not orig, 'expected: obj is not orig' - """)) - - @unittest.skip('broken (see BPO-...)') - def test_send_recv_different_interpreters(self): - r1, s1 = interpreters.create_channel() - r2, s2 = interpreters.create_channel() - orig1 = b'spam' - s1.send_nowait(orig1) - out = _run_output( - interpreters.create(), - dedent(f""" - obj1 = r.recv() - assert obj1 == b'spam', 'expected: obj1 == orig1' - # When going to another interpreter we get a copy. - assert id(obj1) != {id(orig1)}, 'expected: obj1 is not orig1' - orig2 = b'eggs' - print(id(orig2)) - s.send_nowait(orig2) - """), - channels=dict(r=r1, s=s2), - ) - obj2 = r2.recv() - - self.assertEqual(obj2, b'eggs') - self.assertNotEqual(id(obj2), int(out)) - - def test_send_recv_different_threads(self): - r, s = interpreters.create_channel() - - def f(): - while True: - try: - obj = r.recv() - break - except interpreters.ChannelEmptyError: - time.sleep(0.1) - s.send(obj) - t = threading.Thread(target=f) - t.start() - - orig = b'spam' - s.send(orig) - t.join() - obj = r.recv() - - self.assertEqual(obj, orig) - self.assertIsNot(obj, orig) - - def test_send_recv_nowait_main(self): - r, s = interpreters.create_channel() - orig = b'spam' - s.send_nowait(orig) - obj = r.recv_nowait() - - self.assertEqual(obj, orig) - self.assertIsNot(obj, orig) - - def test_send_recv_nowait_main_with_default(self): - r, _ = interpreters.create_channel() - obj = r.recv_nowait(None) - - self.assertIsNone(obj) - - def test_send_recv_nowait_same_interpreter(self): - interp = interpreters.create() - interp.run(dedent(""" - from test.support import interpreters - r, s = interpreters.create_channel() - orig = b'spam' - s.send_nowait(orig) - obj = r.recv_nowait() - assert obj == orig, 'expected: obj == orig' - # When going back to the same interpreter we get the same object. - assert obj is not orig, 'expected: obj is not orig' - """)) - - @unittest.skip('broken (see BPO-...)') - def test_send_recv_nowait_different_interpreters(self): - r1, s1 = interpreters.create_channel() - r2, s2 = interpreters.create_channel() - orig1 = b'spam' - s1.send_nowait(orig1) - out = _run_output( - interpreters.create(), - dedent(f""" - obj1 = r.recv_nowait() - assert obj1 == b'spam', 'expected: obj1 == orig1' - # When going to another interpreter we get a copy. - assert id(obj1) != {id(orig1)}, 'expected: obj1 is not orig1' - orig2 = b'eggs' - print(id(orig2)) - s.send_nowait(orig2) - """), - channels=dict(r=r1, s=s2), - ) - obj2 = r2.recv_nowait() - - self.assertEqual(obj2, b'eggs') - self.assertNotEqual(id(obj2), int(out)) - - def test_recv_channel_does_not_exist(self): - ch = interpreters.RecvChannel(1_000_000) - with self.assertRaises(interpreters.ChannelNotFoundError): - ch.recv() - - def test_send_channel_does_not_exist(self): - ch = interpreters.SendChannel(1_000_000) - with self.assertRaises(interpreters.ChannelNotFoundError): - ch.send(b'spam') - - def test_recv_nowait_channel_does_not_exist(self): - ch = interpreters.RecvChannel(1_000_000) - with self.assertRaises(interpreters.ChannelNotFoundError): - ch.recv_nowait() - - def test_send_nowait_channel_does_not_exist(self): - ch = interpreters.SendChannel(1_000_000) - with self.assertRaises(interpreters.ChannelNotFoundError): - ch.send_nowait(b'spam') - - def test_recv_nowait_empty(self): - ch, _ = interpreters.create_channel() - with self.assertRaises(interpreters.ChannelEmptyError): - ch.recv_nowait() - - def test_recv_nowait_default(self): - default = object() - rch, sch = interpreters.create_channel() - obj1 = rch.recv_nowait(default) - sch.send_nowait(None) - sch.send_nowait(1) - sch.send_nowait(b'spam') - sch.send_nowait(b'eggs') - obj2 = rch.recv_nowait(default) - obj3 = rch.recv_nowait(default) - obj4 = rch.recv_nowait() - obj5 = rch.recv_nowait(default) - obj6 = rch.recv_nowait(default) - - self.assertIs(obj1, default) - self.assertIs(obj2, None) - self.assertEqual(obj3, 1) - self.assertEqual(obj4, b'spam') - self.assertEqual(obj5, b'eggs') - self.assertIs(obj6, default) diff --git a/Lib/test/test_interpreters/__init__.py b/Lib/test/test_interpreters/__init__.py new file mode 100644 index 00000000000000..4b16ecc31156a5 --- /dev/null +++ b/Lib/test/test_interpreters/__init__.py @@ -0,0 +1,5 @@ +import os +from test.support import load_package_tests + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_interpreters/__main__.py b/Lib/test/test_interpreters/__main__.py new file mode 100644 index 00000000000000..8641229877b2be --- /dev/null +++ b/Lib/test/test_interpreters/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +nittest.main() diff --git a/Lib/test/test_interpreters/test_api.py b/Lib/test/test_interpreters/test_api.py new file mode 100644 index 00000000000000..aefd326977095f --- /dev/null +++ b/Lib/test/test_interpreters/test_api.py @@ -0,0 +1,747 @@ +import os +import threading +from textwrap import dedent +import unittest + +from test import support +from test.support import import_helper +# Raise SkipTest if subinterpreters not supported. +import_helper.import_module('_xxsubinterpreters') +from test.support import interpreters +from test.support.interpreters import InterpreterNotFoundError +from .utils import _captured_script, _run_output, _running, TestBase + + +class ModuleTests(TestBase): + + def test_queue_aliases(self): + first = [ + interpreters.create_queue, + interpreters.Queue, + interpreters.QueueEmpty, + interpreters.QueueFull, + ] + second = [ + interpreters.create_queue, + interpreters.Queue, + interpreters.QueueEmpty, + interpreters.QueueFull, + ] + self.assertEqual(second, first) + + +class CreateTests(TestBase): + + def test_in_main(self): + interp = interpreters.create() + self.assertIsInstance(interp, interpreters.Interpreter) + self.assertIn(interp, interpreters.list_all()) + + def test_in_thread(self): + lock = threading.Lock() + interp = None + def f(): + nonlocal interp + interp = interpreters.create() + lock.acquire() + lock.release() + t = threading.Thread(target=f) + with lock: + t.start() + t.join() + self.assertIn(interp, interpreters.list_all()) + + def test_in_subinterpreter(self): + main, = interpreters.list_all() + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + interp = interpreters.create() + print(interp.id) + """)) + interp2 = interpreters.Interpreter(int(out)) + self.assertEqual(interpreters.list_all(), [main, interp, interp2]) + + def test_after_destroy_all(self): + before = set(interpreters.list_all()) + # Create 3 subinterpreters. + interp_lst = [] + for _ in range(3): + interps = interpreters.create() + interp_lst.append(interps) + # Now destroy them. + for interp in interp_lst: + interp.close() + # Finally, create another. + interp = interpreters.create() + self.assertEqual(set(interpreters.list_all()), before | {interp}) + + def test_after_destroy_some(self): + before = set(interpreters.list_all()) + # Create 3 subinterpreters. + interp1 = interpreters.create() + interp2 = interpreters.create() + interp3 = interpreters.create() + # Now destroy 2 of them. + interp1.close() + interp2.close() + # Finally, create another. + interp = interpreters.create() + self.assertEqual(set(interpreters.list_all()), before | {interp3, interp}) + + +class GetMainTests(TestBase): + + def test_id(self): + main = interpreters.get_main() + self.assertEqual(main.id, 0) + + def test_current(self): + main = interpreters.get_main() + current = interpreters.get_current() + self.assertIs(main, current) + + def test_idempotent(self): + main1 = interpreters.get_main() + main2 = interpreters.get_main() + self.assertIs(main1, main2) + + +class GetCurrentTests(TestBase): + + def test_main(self): + main = interpreters.get_main() + current = interpreters.get_current() + self.assertEqual(current, main) + + def test_subinterpreter(self): + main = interpreters.get_main() + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + cur = interpreters.get_current() + print(cur.id) + """)) + current = interpreters.Interpreter(int(out)) + self.assertEqual(current, interp) + self.assertNotEqual(current, main) + + def test_idempotent(self): + with self.subTest('main'): + cur1 = interpreters.get_current() + cur2 = interpreters.get_current() + self.assertIs(cur1, cur2) + + with self.subTest('subinterpreter'): + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + cur = interpreters.get_current() + print(id(cur)) + cur = interpreters.get_current() + print(id(cur)) + """)) + objid1, objid2 = (int(v) for v in out.splitlines()) + self.assertEqual(objid1, objid2) + + with self.subTest('per-interpreter'): + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + cur = interpreters.get_current() + print(id(cur)) + """)) + id1 = int(out) + id2 = id(interp) + self.assertNotEqual(id1, id2) + + +class ListAllTests(TestBase): + + def test_initial(self): + interps = interpreters.list_all() + self.assertEqual(1, len(interps)) + + def test_after_creating(self): + main = interpreters.get_current() + first = interpreters.create() + second = interpreters.create() + + ids = [] + for interp in interpreters.list_all(): + ids.append(interp.id) + + self.assertEqual(ids, [main.id, first.id, second.id]) + + def test_after_destroying(self): + main = interpreters.get_current() + first = interpreters.create() + second = interpreters.create() + first.close() + + ids = [] + for interp in interpreters.list_all(): + ids.append(interp.id) + + self.assertEqual(ids, [main.id, second.id]) + + def test_idempotent(self): + main = interpreters.get_current() + first = interpreters.create() + second = interpreters.create() + expected = [main, first, second] + + actual = interpreters.list_all() + + self.assertEqual(actual, expected) + for interp1, interp2 in zip(actual, expected): + self.assertIs(interp1, interp2) + + +class InterpreterObjectTests(TestBase): + + def test_init_int(self): + interpid = interpreters.get_current().id + interp = interpreters.Interpreter(interpid) + self.assertEqual(interp.id, interpid) + + def test_init_interpreter_id(self): + interpid = interpreters.get_current()._id + interp = interpreters.Interpreter(interpid) + self.assertEqual(interp._id, interpid) + + def test_init_unsupported(self): + actualid = interpreters.get_current().id + for interpid in [ + str(actualid), + float(actualid), + object(), + None, + '', + ]: + with self.subTest(repr(interpid)): + with self.assertRaises(TypeError): + interpreters.Interpreter(interpid) + + def test_idempotent(self): + main = interpreters.get_main() + interp = interpreters.Interpreter(main.id) + self.assertIs(interp, main) + + def test_init_does_not_exist(self): + with self.assertRaises(InterpreterNotFoundError): + interpreters.Interpreter(1_000_000) + + def test_init_bad_id(self): + with self.assertRaises(ValueError): + interpreters.Interpreter(-1) + + def test_id_type(self): + main = interpreters.get_main() + current = interpreters.get_current() + interp = interpreters.create() + self.assertIsInstance(main.id, int) + self.assertIsInstance(current.id, int) + self.assertIsInstance(interp.id, int) + + def test_id_readonly(self): + interp = interpreters.create() + with self.assertRaises(AttributeError): + interp.id = 1_000_000 + + def test_hashable(self): + interp = interpreters.create() + expected = hash(interp.id) + actual = hash(interp) + self.assertEqual(actual, expected) + + def test_equality(self): + interp1 = interpreters.create() + interp2 = interpreters.create() + self.assertEqual(interp1, interp1) + self.assertNotEqual(interp1, interp2) + + +class TestInterpreterIsRunning(TestBase): + + def test_main(self): + main = interpreters.get_main() + self.assertTrue(main.is_running()) + + @unittest.skip('Fails on FreeBSD') + def test_subinterpreter(self): + interp = interpreters.create() + self.assertFalse(interp.is_running()) + + with _running(interp): + self.assertTrue(interp.is_running()) + self.assertFalse(interp.is_running()) + + def test_finished(self): + r, w = self.pipe() + interp = interpreters.create() + interp.exec_sync(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""" + import _xxsubinterpreters as _interpreters + if _interpreters.is_running({interp.id}): + print(True) + else: + print(False) + """)) + self.assertEqual(out.strip(), 'True') + + def test_already_destroyed(self): + interp = interpreters.create() + interp.close() + with self.assertRaises(InterpreterNotFoundError): + 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.exec_sync(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.exec_sync('t.join()') + self.assertEqual(os.read(r_interp, 1), FINISHED) + + +class TestInterpreterClose(TestBase): + + def test_basic(self): + main = interpreters.get_main() + interp1 = interpreters.create() + interp2 = interpreters.create() + interp3 = interpreters.create() + self.assertEqual(set(interpreters.list_all()), + {main, interp1, interp2, interp3}) + interp2.close() + self.assertEqual(set(interpreters.list_all()), + {main, interp1, interp3}) + + def test_all(self): + before = set(interpreters.list_all()) + interps = set() + for _ in range(3): + interp = interpreters.create() + interps.add(interp) + self.assertEqual(set(interpreters.list_all()), before | interps) + for interp in interps: + interp.close() + self.assertEqual(set(interpreters.list_all()), before) + + def test_main(self): + main, = interpreters.list_all() + with self.assertRaises(RuntimeError): + main.close() + + def f(): + with self.assertRaises(RuntimeError): + main.close() + + t = threading.Thread(target=f) + t.start() + t.join() + + def test_already_destroyed(self): + interp = interpreters.create() + interp.close() + with self.assertRaises(InterpreterNotFoundError): + interp.close() + + def test_from_current(self): + main, = interpreters.list_all() + interp = interpreters.create() + out = _run_output(interp, dedent(f""" + from test.support import interpreters + interp = interpreters.Interpreter({interp.id}) + try: + interp.close() + except RuntimeError: + print('failed') + """)) + self.assertEqual(out.strip(), 'failed') + self.assertEqual(set(interpreters.list_all()), {main, interp}) + + def test_from_sibling(self): + main, = interpreters.list_all() + interp1 = interpreters.create() + interp2 = interpreters.create() + self.assertEqual(set(interpreters.list_all()), + {main, interp1, interp2}) + interp1.exec_sync(dedent(f""" + from test.support import interpreters + interp2 = interpreters.Interpreter({interp2.id}) + interp2.close() + interp3 = interpreters.create() + interp3.close() + """)) + self.assertEqual(set(interpreters.list_all()), {main, interp1}) + + def test_from_other_thread(self): + interp = interpreters.create() + def f(): + interp.close() + + t = threading.Thread(target=f) + t.start() + t.join() + + @unittest.skip('Fails on FreeBSD') + def test_still_running(self): + main, = interpreters.list_all() + interp = interpreters.create() + with _running(interp): + with self.assertRaises(RuntimeError): + 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.exec_sync(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 TestInterpreterPrepareMain(TestBase): + + def test_empty(self): + interp = interpreters.create() + with self.assertRaises(ValueError): + interp.prepare_main() + + def test_dict(self): + values = {'spam': 42, 'eggs': 'ham'} + interp = interpreters.create() + interp.prepare_main(values) + out = _run_output(interp, dedent(""" + print(spam, eggs) + """)) + self.assertEqual(out.strip(), '42 ham') + + def test_tuple(self): + values = {'spam': 42, 'eggs': 'ham'} + values = tuple(values.items()) + interp = interpreters.create() + interp.prepare_main(values) + out = _run_output(interp, dedent(""" + print(spam, eggs) + """)) + self.assertEqual(out.strip(), '42 ham') + + def test_kwargs(self): + values = {'spam': 42, 'eggs': 'ham'} + interp = interpreters.create() + interp.prepare_main(**values) + out = _run_output(interp, dedent(""" + print(spam, eggs) + """)) + self.assertEqual(out.strip(), '42 ham') + + def test_dict_and_kwargs(self): + values = {'spam': 42, 'eggs': 'ham'} + interp = interpreters.create() + interp.prepare_main(values, foo='bar') + out = _run_output(interp, dedent(""" + print(spam, eggs, foo) + """)) + self.assertEqual(out.strip(), '42 ham bar') + + def test_not_shareable(self): + interp = interpreters.create() + # XXX TypeError? + with self.assertRaises(ValueError): + interp.prepare_main(spam={'spam': 'eggs', 'foo': 'bar'}) + + # Make sure neither was actually bound. + with self.assertRaises(interpreters.ExecFailure): + interp.exec_sync('print(foo)') + with self.assertRaises(interpreters.ExecFailure): + interp.exec_sync('print(spam)') + + +class TestInterpreterExecSync(TestBase): + + def test_success(self): + interp = interpreters.create() + script, file = _captured_script('print("it worked!", end="")') + with file: + interp.exec_sync(script) + out = file.read() + + self.assertEqual(out, 'it worked!') + + def test_failure(self): + interp = interpreters.create() + with self.assertRaises(interpreters.ExecFailure): + interp.exec_sync('raise Exception') + + def test_display_preserved_exception(self): + tempdir = self.temp_dir() + modfile = self.make_module('spam', tempdir, text=""" + def ham(): + raise RuntimeError('uh-oh!') + + def eggs(): + ham() + """) + scriptfile = self.make_script('script.py', tempdir, text=""" + from test.support import interpreters + + def script(): + import spam + spam.eggs() + + interp = interpreters.create() + interp.exec_sync(script) + """) + + stdout, stderr = self.assert_python_failure(scriptfile) + self.maxDiff = None + interpmod_line, = (l for l in stderr.splitlines() if ' exec_sync' in l) + # File "{interpreters.__file__}", line 179, in exec_sync + self.assertEqual(stderr, dedent(f"""\ + Traceback (most recent call last): + File "{scriptfile}", line 9, in + interp.exec_sync(script) + ~~~~~~~~~~~~~~~~^^^^^^^^ + {interpmod_line.strip()} + raise ExecFailure(excinfo) + test.support.interpreters.ExecFailure: RuntimeError: uh-oh! + + Uncaught in the interpreter: + + Traceback (most recent call last): + File "{scriptfile}", line 6, in script + spam.eggs() + ~~~~~~~~~^^ + File "{modfile}", line 6, in eggs + ham() + ~~~^^ + File "{modfile}", line 3, in ham + raise RuntimeError('uh-oh!') + RuntimeError: uh-oh! + """)) + self.assertEqual(stdout, '') + + def test_in_thread(self): + interp = interpreters.create() + script, file = _captured_script('print("it worked!", end="")') + with file: + def f(): + interp.exec_sync(script) + + t = threading.Thread(target=f) + t.start() + t.join() + out = file.read() + + self.assertEqual(out, 'it worked!') + + @support.requires_fork() + def test_fork(self): + interp = interpreters.create() + import tempfile + with tempfile.NamedTemporaryFile('w+', encoding='utf-8') as file: + file.write('') + file.flush() + + expected = 'spam spam spam spam spam' + script = dedent(f""" + import os + try: + os.fork() + except RuntimeError: + with open('{file.name}', 'w', encoding='utf-8') as out: + out.write('{expected}') + """) + interp.exec_sync(script) + + file.seek(0) + content = file.read() + self.assertEqual(content, expected) + + @unittest.skip('Fails on FreeBSD') + def test_already_running(self): + interp = interpreters.create() + with _running(interp): + with self.assertRaises(RuntimeError): + interp.exec_sync('print("spam")') + + def test_bad_script(self): + interp = interpreters.create() + with self.assertRaises(TypeError): + interp.exec_sync(10) + + def test_bytes_for_script(self): + interp = interpreters.create() + with self.assertRaises(TypeError): + interp.exec_sync(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.exec_sync(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.exec_sync(f"""if True: + os.write({w_interp}, {RAN!r}) + """) + + os.write(w_thread, DONE) + interp.exec_sync('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.exec_sync() behavior. + + +class TestInterpreterRun(TestBase): + + def test_success(self): + interp = interpreters.create() + script, file = _captured_script('print("it worked!", end="")') + with file: + t = interp.run(script) + t.join() + out = file.read() + + self.assertEqual(out, 'it worked!') + + def test_failure(self): + caught = False + def excepthook(args): + nonlocal caught + caught = True + threading.excepthook = excepthook + try: + interp = interpreters.create() + t = interp.run('raise Exception') + t.join() + + self.assertTrue(caught) + except BaseException: + threading.excepthook = threading.__excepthook__ + + +class TestIsShareable(TestBase): + + def test_default_shareables(self): + shareables = [ + # singletons + None, + # builtin objects + b'spam', + 'spam', + 10, + -10, + True, + False, + 100.0, + (), + (1, ('spam', 'eggs'), True), + ] + for obj in shareables: + with self.subTest(obj): + shareable = interpreters.is_shareable(obj) + self.assertTrue(shareable) + + def test_not_shareable(self): + class Cheese: + def __init__(self, name): + self.name = name + def __str__(self): + return self.name + + class SubBytes(bytes): + """A subclass of a shareable type.""" + + not_shareables = [ + # singletons + NotImplemented, + ..., + # builtin types and objects + type, + object, + object(), + Exception(), + # user-defined types and objects + Cheese, + Cheese('Wensleydale'), + SubBytes(b'spam'), + ] + for obj in not_shareables: + with self.subTest(repr(obj)): + self.assertFalse( + interpreters.is_shareable(obj)) + + +if __name__ == '__main__': + # Test needs to be a package, so we can do relative imports. + unittest.main() diff --git a/Lib/test/test_interpreters/test_channels.py b/Lib/test/test_interpreters/test_channels.py new file mode 100644 index 00000000000000..3c3e18832d4168 --- /dev/null +++ b/Lib/test/test_interpreters/test_channels.py @@ -0,0 +1,328 @@ +import threading +from textwrap import dedent +import unittest +import time + +from test.support import import_helper +# Raise SkipTest if subinterpreters not supported. +_channels = import_helper.import_module('_xxinterpchannels') +from test.support import interpreters +from test.support.interpreters import channels +from .utils import _run_output, TestBase + + +class TestChannels(TestBase): + + def test_create(self): + r, s = channels.create() + self.assertIsInstance(r, channels.RecvChannel) + self.assertIsInstance(s, channels.SendChannel) + + def test_list_all(self): + self.assertEqual(channels.list_all(), []) + created = set() + for _ in range(3): + ch = channels.create() + created.add(ch) + after = set(channels.list_all()) + self.assertEqual(after, created) + + def test_shareable(self): + rch, sch = channels.create() + + 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) + + def test_is_closed(self): + rch, sch = channels.create() + rbefore = rch.is_closed + sbefore = sch.is_closed + rch.close() + rafter = rch.is_closed + safter = sch.is_closed + + self.assertFalse(rbefore) + self.assertFalse(sbefore) + self.assertTrue(rafter) + self.assertTrue(safter) + + +class TestRecvChannelAttrs(TestBase): + + def test_id_type(self): + rch, _ = channels.create() + self.assertIsInstance(rch.id, _channels.ChannelID) + + def test_custom_id(self): + rch = channels.RecvChannel(1) + self.assertEqual(rch.id, 1) + + with self.assertRaises(TypeError): + channels.RecvChannel('1') + + def test_id_readonly(self): + rch = channels.RecvChannel(1) + with self.assertRaises(AttributeError): + rch.id = 2 + + def test_equality(self): + ch1, _ = channels.create() + ch2, _ = channels.create() + self.assertEqual(ch1, ch1) + self.assertNotEqual(ch1, ch2) + + +class TestSendChannelAttrs(TestBase): + + def test_id_type(self): + _, sch = channels.create() + self.assertIsInstance(sch.id, _channels.ChannelID) + + def test_custom_id(self): + sch = channels.SendChannel(1) + self.assertEqual(sch.id, 1) + + with self.assertRaises(TypeError): + channels.SendChannel('1') + + def test_id_readonly(self): + sch = channels.SendChannel(1) + with self.assertRaises(AttributeError): + sch.id = 2 + + def test_equality(self): + _, ch1 = channels.create() + _, ch2 = channels.create() + self.assertEqual(ch1, ch1) + self.assertNotEqual(ch1, ch2) + + +class TestSendRecv(TestBase): + + def test_send_recv_main(self): + r, s = channels.create() + orig = b'spam' + s.send_nowait(orig) + obj = r.recv() + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + def test_send_recv_same_interpreter(self): + interp = interpreters.create() + interp.exec_sync(dedent(""" + from test.support.interpreters import channels + r, s = channels.create() + orig = b'spam' + s.send_nowait(orig) + obj = r.recv() + assert obj == orig, 'expected: obj == orig' + assert obj is not orig, 'expected: obj is not orig' + """)) + + @unittest.skip('broken (see BPO-...)') + def test_send_recv_different_interpreters(self): + r1, s1 = channels.create() + r2, s2 = channels.create() + orig1 = b'spam' + s1.send_nowait(orig1) + out = _run_output( + interpreters.create(), + dedent(f""" + obj1 = r.recv() + assert obj1 == b'spam', 'expected: obj1 == orig1' + # When going to another interpreter we get a copy. + assert id(obj1) != {id(orig1)}, 'expected: obj1 is not orig1' + orig2 = b'eggs' + print(id(orig2)) + s.send_nowait(orig2) + """), + channels=dict(r=r1, s=s2), + ) + obj2 = r2.recv() + + self.assertEqual(obj2, b'eggs') + self.assertNotEqual(id(obj2), int(out)) + + def test_send_recv_different_threads(self): + r, s = channels.create() + + def f(): + while True: + try: + obj = r.recv() + break + except channels.ChannelEmptyError: + time.sleep(0.1) + s.send(obj) + t = threading.Thread(target=f) + t.start() + + orig = b'spam' + s.send(orig) + obj = r.recv() + t.join() + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + def test_send_recv_nowait_main(self): + r, s = channels.create() + orig = b'spam' + s.send_nowait(orig) + obj = r.recv_nowait() + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + def test_send_recv_nowait_main_with_default(self): + r, _ = channels.create() + obj = r.recv_nowait(None) + + self.assertIsNone(obj) + + def test_send_recv_nowait_same_interpreter(self): + interp = interpreters.create() + interp.exec_sync(dedent(""" + from test.support.interpreters import channels + r, s = channels.create() + orig = b'spam' + s.send_nowait(orig) + obj = r.recv_nowait() + assert obj == orig, 'expected: obj == orig' + # When going back to the same interpreter we get the same object. + assert obj is not orig, 'expected: obj is not orig' + """)) + + @unittest.skip('broken (see BPO-...)') + def test_send_recv_nowait_different_interpreters(self): + r1, s1 = channels.create() + r2, s2 = channels.create() + orig1 = b'spam' + s1.send_nowait(orig1) + out = _run_output( + interpreters.create(), + dedent(f""" + obj1 = r.recv_nowait() + assert obj1 == b'spam', 'expected: obj1 == orig1' + # When going to another interpreter we get a copy. + assert id(obj1) != {id(orig1)}, 'expected: obj1 is not orig1' + orig2 = b'eggs' + print(id(orig2)) + s.send_nowait(orig2) + """), + channels=dict(r=r1, s=s2), + ) + obj2 = r2.recv_nowait() + + self.assertEqual(obj2, b'eggs') + self.assertNotEqual(id(obj2), int(out)) + + def test_recv_timeout(self): + r, _ = channels.create() + with self.assertRaises(TimeoutError): + r.recv(timeout=1) + + def test_recv_channel_does_not_exist(self): + ch = channels.RecvChannel(1_000_000) + with self.assertRaises(channels.ChannelNotFoundError): + ch.recv() + + def test_send_channel_does_not_exist(self): + ch = channels.SendChannel(1_000_000) + with self.assertRaises(channels.ChannelNotFoundError): + ch.send(b'spam') + + def test_recv_nowait_channel_does_not_exist(self): + ch = channels.RecvChannel(1_000_000) + with self.assertRaises(channels.ChannelNotFoundError): + ch.recv_nowait() + + def test_send_nowait_channel_does_not_exist(self): + ch = channels.SendChannel(1_000_000) + with self.assertRaises(channels.ChannelNotFoundError): + ch.send_nowait(b'spam') + + def test_recv_nowait_empty(self): + ch, _ = channels.create() + with self.assertRaises(channels.ChannelEmptyError): + ch.recv_nowait() + + def test_recv_nowait_default(self): + default = object() + rch, sch = channels.create() + obj1 = rch.recv_nowait(default) + sch.send_nowait(None) + sch.send_nowait(1) + sch.send_nowait(b'spam') + sch.send_nowait(b'eggs') + obj2 = rch.recv_nowait(default) + obj3 = rch.recv_nowait(default) + obj4 = rch.recv_nowait() + obj5 = rch.recv_nowait(default) + obj6 = rch.recv_nowait(default) + + self.assertIs(obj1, default) + self.assertIs(obj2, None) + self.assertEqual(obj3, 1) + 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 = channels.create() + + def f(): + nonlocal obj + while True: + try: + obj = rch.recv() + break + except channels.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 = channels.create() + 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) + + +if __name__ == '__main__': + # Test needs to be a package, so we can do relative imports. + unittest.main() diff --git a/Lib/test/test_interpreters/test_lifecycle.py b/Lib/test/test_interpreters/test_lifecycle.py new file mode 100644 index 00000000000000..c2917d839904f9 --- /dev/null +++ b/Lib/test/test_interpreters/test_lifecycle.py @@ -0,0 +1,189 @@ +import contextlib +import json +import os +import os.path +import sys +from textwrap import dedent +import unittest + +from test import support +from test.support import import_helper +from test.support import os_helper +# Raise SkipTest if subinterpreters not supported. +import_helper.import_module('_xxsubinterpreters') +from .utils import TestBase + + +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.exec_sync(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): + # Make sure finalization finishes and the correct error code + # is reported, even when subinterpreters get cleaned up at the end. + import subprocess + argv = [sys.executable, '-c', '''if True: + from test.support import interpreters + interp = 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) + + +if __name__ == '__main__': + # Test needs to be a package, so we can do relative imports. + unittest.main() diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py new file mode 100644 index 00000000000000..2a8ca99c1f6e3f --- /dev/null +++ b/Lib/test/test_interpreters/test_queues.py @@ -0,0 +1,299 @@ +import threading +from textwrap import dedent +import unittest +import time + +from test.support import import_helper +# Raise SkipTest if subinterpreters not supported. +_queues = import_helper.import_module('_xxinterpqueues') +from test.support import interpreters +from test.support.interpreters import queues +from .utils import _run_output, TestBase + + +class TestBase(TestBase): + def tearDown(self): + for qid in _queues.list_all(): + try: + _queues.destroy(qid) + except Exception: + pass + + +class QueueTests(TestBase): + + def test_create(self): + with self.subTest('vanilla'): + queue = queues.create() + self.assertEqual(queue.maxsize, 0) + + with self.subTest('small maxsize'): + queue = queues.create(3) + self.assertEqual(queue.maxsize, 3) + + with self.subTest('big maxsize'): + queue = queues.create(100) + self.assertEqual(queue.maxsize, 100) + + with self.subTest('no maxsize'): + queue = queues.create(0) + self.assertEqual(queue.maxsize, 0) + + with self.subTest('negative maxsize'): + queue = queues.create(-10) + self.assertEqual(queue.maxsize, -10) + + with self.subTest('bad maxsize'): + with self.assertRaises(TypeError): + queues.create('1') + + def test_shareable(self): + queue1 = queues.create() + + interp = interpreters.create() + interp.exec_sync(dedent(f""" + from test.support.interpreters import queues + queue1 = queues.Queue({queue1.id}) + """)); + + with self.subTest('same interpreter'): + queue2 = queues.create() + queue1.put(queue2) + queue3 = queue1.get() + self.assertIs(queue3, queue2) + + with self.subTest('from current interpreter'): + queue4 = queues.create() + queue1.put(queue4) + out = _run_output(interp, dedent(""" + queue4 = queue1.get() + print(queue4.id) + """)) + qid = int(out) + self.assertEqual(qid, queue4.id) + + with self.subTest('from subinterpreter'): + out = _run_output(interp, dedent(""" + queue5 = queues.create() + queue1.put(queue5) + print(queue5.id) + """)) + qid = int(out) + queue5 = queue1.get() + self.assertEqual(queue5.id, qid) + + def test_id_type(self): + queue = queues.create() + self.assertIsInstance(queue.id, int) + + def test_custom_id(self): + with self.assertRaises(queues.QueueNotFoundError): + queues.Queue(1_000_000) + + def test_id_readonly(self): + queue = queues.create() + with self.assertRaises(AttributeError): + queue.id = 1_000_000 + + def test_maxsize_readonly(self): + queue = queues.create(10) + with self.assertRaises(AttributeError): + queue.maxsize = 1_000_000 + + def test_hashable(self): + queue = queues.create() + expected = hash(queue.id) + actual = hash(queue) + self.assertEqual(actual, expected) + + def test_equality(self): + queue1 = queues.create() + queue2 = queues.create() + self.assertEqual(queue1, queue1) + self.assertNotEqual(queue1, queue2) + + +class TestQueueOps(TestBase): + + def test_empty(self): + queue = queues.create() + before = queue.empty() + queue.put(None) + during = queue.empty() + queue.get() + after = queue.empty() + + self.assertIs(before, True) + self.assertIs(during, False) + self.assertIs(after, True) + + def test_full(self): + expected = [False, False, False, True, False, False, False] + actual = [] + queue = queues.create(3) + for _ in range(3): + actual.append(queue.full()) + queue.put(None) + actual.append(queue.full()) + for _ in range(3): + queue.get() + actual.append(queue.full()) + + self.assertEqual(actual, expected) + + def test_qsize(self): + expected = [0, 1, 2, 3, 2, 3, 2, 1, 0, 1, 0] + actual = [] + queue = queues.create() + for _ in range(3): + actual.append(queue.qsize()) + queue.put(None) + actual.append(queue.qsize()) + queue.get() + actual.append(queue.qsize()) + queue.put(None) + actual.append(queue.qsize()) + for _ in range(3): + queue.get() + actual.append(queue.qsize()) + queue.put(None) + actual.append(queue.qsize()) + queue.get() + actual.append(queue.qsize()) + + self.assertEqual(actual, expected) + + def test_put_get_main(self): + expected = list(range(20)) + queue = queues.create() + for i in range(20): + queue.put(i) + actual = [queue.get() for _ in range(20)] + + self.assertEqual(actual, expected) + + def test_put_timeout(self): + queue = queues.create(2) + queue.put(None) + queue.put(None) + with self.assertRaises(queues.QueueFull): + queue.put(None, timeout=0.1) + queue.get() + queue.put(None) + + def test_put_nowait(self): + queue = queues.create(2) + queue.put_nowait(None) + queue.put_nowait(None) + with self.assertRaises(queues.QueueFull): + queue.put_nowait(None) + queue.get() + queue.put_nowait(None) + + def test_get_timeout(self): + queue = queues.create() + with self.assertRaises(queues.QueueEmpty): + queue.get(timeout=0.1) + + def test_get_nowait(self): + queue = queues.create() + with self.assertRaises(queues.QueueEmpty): + queue.get_nowait() + + def test_put_get_same_interpreter(self): + interp = interpreters.create() + interp.exec_sync(dedent(""" + from test.support.interpreters import queues + queue = queues.create() + orig = b'spam' + queue.put(orig) + obj = queue.get() + assert obj == orig, 'expected: obj == orig' + assert obj is not orig, 'expected: obj is not orig' + """)) + + def test_put_get_different_interpreters(self): + interp = interpreters.create() + queue1 = queues.create() + queue2 = queues.create() + self.assertEqual(len(queues.list_all()), 2) + + obj1 = b'spam' + queue1.put(obj1) + + out = _run_output( + interp, + dedent(f""" + from test.support.interpreters import queues + queue1 = queues.Queue({queue1.id}) + queue2 = queues.Queue({queue2.id}) + assert queue1.qsize() == 1, 'expected: queue1.qsize() == 1' + obj = queue1.get() + assert queue1.qsize() == 0, 'expected: queue1.qsize() == 0' + assert obj == b'spam', 'expected: obj == obj1' + # When going to another interpreter we get a copy. + assert id(obj) != {id(obj1)}, 'expected: obj is not obj1' + obj2 = b'eggs' + print(id(obj2)) + assert queue2.qsize() == 0, 'expected: queue2.qsize() == 0' + queue2.put(obj2) + assert queue2.qsize() == 1, 'expected: queue2.qsize() == 1' + """)) + self.assertEqual(len(queues.list_all()), 2) + self.assertEqual(queue1.qsize(), 0) + self.assertEqual(queue2.qsize(), 1) + + obj2 = queue2.get() + self.assertEqual(obj2, b'eggs') + self.assertNotEqual(id(obj2), int(out)) + + def test_put_cleared_with_subinterpreter(self): + interp = interpreters.create() + queue = queues.create() + + out = _run_output( + interp, + dedent(f""" + from test.support.interpreters import queues + queue = queues.Queue({queue.id}) + obj1 = b'spam' + obj2 = b'eggs' + queue.put(obj1) + queue.put(obj2) + """)) + self.assertEqual(queue.qsize(), 2) + + obj1 = queue.get() + self.assertEqual(obj1, b'spam') + self.assertEqual(queue.qsize(), 1) + + del interp + self.assertEqual(queue.qsize(), 0) + + def test_put_get_different_threads(self): + queue1 = queues.create() + queue2 = queues.create() + + def f(): + while True: + try: + obj = queue1.get(timeout=0.1) + break + except queues.QueueEmpty: + continue + queue2.put(obj) + t = threading.Thread(target=f) + t.start() + + orig = b'spam' + queue1.put(orig) + obj = queue2.get() + t.join() + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + +if __name__ == '__main__': + # Test needs to be a package, so we can do relative imports. + unittest.main() diff --git a/Lib/test/test_interpreters/test_stress.py b/Lib/test/test_interpreters/test_stress.py new file mode 100644 index 00000000000000..3cc570b3bf7128 --- /dev/null +++ b/Lib/test/test_interpreters/test_stress.py @@ -0,0 +1,38 @@ +import threading +import unittest + +from test import support +from test.support import import_helper +from test.support import threading_helper +# Raise SkipTest if subinterpreters not supported. +import_helper.import_module('_xxsubinterpreters') +from test.support import interpreters +from .utils import TestBase + + +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 + + +if __name__ == '__main__': + # Test needs to be a package, so we can do relative imports. + unittest.main() diff --git a/Lib/test/test_interpreters/utils.py b/Lib/test/test_interpreters/utils.py new file mode 100644 index 00000000000000..3a37ed09dd8943 --- /dev/null +++ b/Lib/test/test_interpreters/utils.py @@ -0,0 +1,147 @@ +import contextlib +import os +import os.path +import subprocess +import sys +import tempfile +import threading +from textwrap import dedent +import unittest + +from test import support +from test.support import os_helper + +from test.support import interpreters + + +def _captured_script(script): + r, w = os.pipe() + indented = script.replace('\n', '\n ') + wrapped = dedent(f""" + import contextlib + with open({w}, 'w', encoding='utf-8') as spipe: + with contextlib.redirect_stdout(spipe): + {indented} + """) + return wrapped, open(r, encoding='utf-8') + + +def clean_up_interpreters(): + for interp in interpreters.list_all(): + if interp.id == 0: # main + continue + try: + interp.close() + except RuntimeError: + pass # already destroyed + + +def _run_output(interp, request, init=None): + script, rpipe = _captured_script(request) + with rpipe: + if init: + interp.prepare_main(init) + interp.exec_sync(script) + return rpipe.read() + + +@contextlib.contextmanager +def _running(interp): + r, w = os.pipe() + def run(): + interp.exec_sync(dedent(f""" + # wait for "signal" + with open({r}) as rpipe: + rpipe.read() + """)) + + t = threading.Thread(target=run) + t.start() + + yield + + with open(w, 'w') as spipe: + spipe.write('done') + t.join() + + +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 temp_dir(self): + tempdir = tempfile.mkdtemp() + tempdir = os.path.realpath(tempdir) + self.addCleanup(lambda: os_helper.rmtree(tempdir)) + return tempdir + + def make_script(self, filename, dirname=None, text=None): + if text: + text = dedent(text) + if dirname is None: + dirname = self.temp_dir() + filename = os.path.join(dirname, filename) + + os.makedirs(os.path.dirname(filename), exist_ok=True) + with open(filename, 'w', encoding='utf-8') as outfile: + outfile.write(text or '') + return filename + + def make_module(self, name, pathentry=None, text=None): + if text: + text = dedent(text) + if pathentry is None: + pathentry = self.temp_dir() + else: + os.makedirs(pathentry, exist_ok=True) + *subnames, basename = name.split('.') + + dirname = pathentry + for subname in subnames: + dirname = os.path.join(dirname, subname) + if os.path.isdir(dirname): + pass + elif os.path.exists(dirname): + raise Exception(dirname) + else: + os.mkdir(dirname) + initfile = os.path.join(dirname, '__init__.py') + if not os.path.exists(initfile): + with open(initfile, 'w'): + pass + filename = os.path.join(dirname, basename + '.py') + + with open(filename, 'w', encoding='utf-8') as outfile: + outfile.write(text or '') + return filename + + @support.requires_subprocess() + def run_python(self, *argv): + proc = subprocess.run( + [sys.executable, *argv], + capture_output=True, + text=True, + ) + return proc.returncode, proc.stdout, proc.stderr + + def assert_python_ok(self, *argv): + exitcode, stdout, stderr = self.run_python(*argv) + self.assertNotEqual(exitcode, 1) + return stdout, stderr + + def assert_python_failure(self, *argv): + exitcode, stdout, stderr = self.run_python(*argv) + self.assertNotEqual(exitcode, 0) + return stdout, stderr + + def tearDown(self): + clean_up_interpreters() diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 022cf21a4709a2..09cced9baef99b 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -77,6 +77,10 @@ def _default_chunk_size(): ) +class BadIndex: + def __index__(self): + 1/0 + class MockRawIOWithoutRead: """A RawIO implementation without read(), so as to exercise the default RawIO.read() which calls readinto().""" @@ -1230,11 +1234,9 @@ def test_recursive_repr(self): # Issue #25455 raw = self.MockRawIO() b = self.tp(raw) - with support.swap_attr(raw, 'name', b): - try: + with support.swap_attr(raw, 'name', b), support.infinite_recursion(25): + with self.assertRaises(RuntimeError): repr(b) # Should not crash - except RuntimeError: - pass def test_flush_error_on_close(self): # Test that buffered file is closed despite failed flush @@ -2709,8 +2711,29 @@ def test_constructor(self): self.assertEqual(t.encoding, "utf-8") self.assertEqual(t.line_buffering, True) self.assertEqual("\xe9\n", t.readline()) - self.assertRaises(TypeError, t.__init__, b, encoding="utf-8", newline=42) - self.assertRaises(ValueError, t.__init__, b, encoding="utf-8", newline='xyzzy') + invalid_type = TypeError if self.is_C else ValueError + with self.assertRaises(invalid_type): + t.__init__(b, encoding=42) + with self.assertRaises(UnicodeEncodeError): + t.__init__(b, encoding='\udcfe') + with self.assertRaises(ValueError): + t.__init__(b, encoding='utf-8\0') + with self.assertRaises(invalid_type): + t.__init__(b, encoding="utf-8", errors=42) + if support.Py_DEBUG or sys.flags.dev_mode or self.is_C: + with self.assertRaises(UnicodeEncodeError): + t.__init__(b, encoding="utf-8", errors='\udcfe') + if support.Py_DEBUG or sys.flags.dev_mode or self.is_C: + with self.assertRaises(ValueError): + t.__init__(b, encoding="utf-8", errors='replace\0') + with self.assertRaises(TypeError): + t.__init__(b, encoding="utf-8", newline=42) + with self.assertRaises(ValueError): + t.__init__(b, encoding="utf-8", newline='\udcfe') + with self.assertRaises(ValueError): + t.__init__(b, encoding="utf-8", newline='\n\0') + with self.assertRaises(ValueError): + t.__init__(b, encoding="utf-8", newline='xyzzy') def test_uninitialized(self): t = self.TextIOWrapper.__new__(self.TextIOWrapper) @@ -2776,11 +2799,9 @@ def test_recursive_repr(self): # Issue #25455 raw = self.BytesIO() t = self.TextIOWrapper(raw, encoding="utf-8") - with support.swap_attr(raw, 'name', t): - try: + with support.swap_attr(raw, 'name', t), support.infinite_recursion(25): + with self.assertRaises(RuntimeError): repr(t) # Should not crash - except RuntimeError: - pass def test_line_buffering(self): r = self.BytesIO() @@ -3756,6 +3777,59 @@ def test_reconfigure_defaults(self): self.assertEqual(txt.detach().getvalue(), b'LF\nCRLF\r\n') + def test_reconfigure_errors(self): + txt = self.TextIOWrapper(self.BytesIO(), 'ascii', 'replace', '\r') + with self.assertRaises(TypeError): # there was a crash + txt.reconfigure(encoding=42) + if self.is_C: + with self.assertRaises(UnicodeEncodeError): + txt.reconfigure(encoding='\udcfe') + with self.assertRaises(LookupError): + txt.reconfigure(encoding='locale\0') + # TODO: txt.reconfigure(encoding='utf-8\0') + # TODO: txt.reconfigure(encoding='nonexisting') + with self.assertRaises(TypeError): + txt.reconfigure(errors=42) + if self.is_C: + with self.assertRaises(UnicodeEncodeError): + txt.reconfigure(errors='\udcfe') + # TODO: txt.reconfigure(errors='ignore\0') + # TODO: txt.reconfigure(errors='nonexisting') + with self.assertRaises(TypeError): + txt.reconfigure(newline=42) + with self.assertRaises(ValueError): + txt.reconfigure(newline='\udcfe') + with self.assertRaises(ValueError): + txt.reconfigure(newline='xyz') + if not self.is_C: + # TODO: Should fail in C too. + with self.assertRaises(ValueError): + txt.reconfigure(newline='\n\0') + if self.is_C: + # TODO: Use __bool__(), not __index__(). + with self.assertRaises(ZeroDivisionError): + txt.reconfigure(line_buffering=BadIndex()) + with self.assertRaises(OverflowError): + txt.reconfigure(line_buffering=2**1000) + with self.assertRaises(ZeroDivisionError): + txt.reconfigure(write_through=BadIndex()) + with self.assertRaises(OverflowError): + txt.reconfigure(write_through=2**1000) + with self.assertRaises(ZeroDivisionError): # there was a crash + txt.reconfigure(line_buffering=BadIndex(), + write_through=BadIndex()) + self.assertEqual(txt.encoding, 'ascii') + self.assertEqual(txt.errors, 'replace') + self.assertIs(txt.line_buffering, False) + self.assertIs(txt.write_through, False) + + txt.reconfigure(encoding='latin1', errors='ignore', newline='\r\n', + line_buffering=True, write_through=True) + self.assertEqual(txt.encoding, 'latin1') + self.assertEqual(txt.errors, 'ignore') + self.assertIs(txt.line_buffering, True) + self.assertIs(txt.write_through, True) + def test_reconfigure_newline(self): raw = self.BytesIO(b'CR\rEOF') txt = self.TextIOWrapper(raw, 'ascii', newline='\n') @@ -4042,19 +4116,18 @@ class PyIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): class MiscIOTest(unittest.TestCase): + # for test__all__, actual values are set in subclasses + name_of_module = None + extra_exported = () + not_exported = () + def tearDown(self): os_helper.unlink(os_helper.TESTFN) def test___all__(self): - for name in self.io.__all__: - obj = getattr(self.io, name, None) - self.assertIsNotNone(obj, name) - if name in ("open", "open_code"): - continue - elif "error" in name.lower() or name == "UnsupportedOperation": - self.assertTrue(issubclass(obj, Exception), name) - elif not name.startswith("SEEK_"): - self.assertTrue(issubclass(obj, self.IOBase)) + support.check__all__(self, self.io, self.name_of_module, + extra=self.extra_exported, + not_exported=self.not_exported) def test_attributes(self): f = self.open(os_helper.TESTFN, "wb", buffering=0) @@ -4396,11 +4469,11 @@ def test_check_encoding_warning(self): ''') proc = assert_python_ok('-X', 'warn_default_encoding', '-c', code) warnings = proc.err.splitlines() - self.assertEqual(len(warnings), 2) + self.assertEqual(len(warnings), 4) self.assertTrue( warnings[0].startswith(b":5: EncodingWarning: ")) self.assertTrue( - warnings[1].startswith(b":8: EncodingWarning: ")) + warnings[2].startswith(b":8: EncodingWarning: ")) def test_text_encoding(self): # PEP 597, bpo-47000. io.text_encoding() returns "locale" or "utf-8" @@ -4416,6 +4489,8 @@ def test_text_encoding(self): class CMiscIOTest(MiscIOTest): io = io + name_of_module = "io", "_io" + extra_exported = "BlockingIOError", def test_readinto_buffer_overflow(self): # Issue #18025 @@ -4480,6 +4555,9 @@ def test_daemon_threads_shutdown_stderr_deadlock(self): class PyMiscIOTest(MiscIOTest): io = pyio + name_of_module = "_pyio", "io" + extra_exported = "BlockingIOError", "open_code", + not_exported = "valid_seek_flags", @unittest.skipIf(os.name == 'nt', 'POSIX signals required for this test.') @@ -4767,7 +4845,7 @@ def load_tests(loader, tests, pattern): mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO, MockNonBlockWriterIO, MockUnseekableIO, MockRawIOWithoutRead, SlowFlushRawIO) - all_members = io.__all__ + ["IncrementalNewlineDecoder"] + all_members = io.__all__ c_io_ns = {name : getattr(io, name) for name in all_members} py_io_ns = {name : getattr(pyio, name) for name in all_members} globs = globals() @@ -4777,9 +4855,11 @@ def load_tests(loader, tests, pattern): if test.__name__.startswith("C"): for name, obj in c_io_ns.items(): setattr(test, name, obj) + test.is_C = True elif test.__name__.startswith("Py"): for name, obj in py_io_ns.items(): setattr(test, name, obj) + test.is_C = False suite = loader.suiteClass() for test in tests: diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 6f204948c9fc48..b4952acc2b61b1 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -4,6 +4,7 @@ """Unittest for ipaddress module.""" +import copy import unittest import re import contextlib @@ -302,6 +303,14 @@ def test_pickle(self): def test_weakref(self): weakref.ref(self.factory('192.0.2.1')) + def test_ipv6_mapped(self): + self.assertEqual(ipaddress.IPv4Address('192.168.1.1').ipv6_mapped, + ipaddress.IPv6Address('::ffff:192.168.1.1')) + self.assertEqual(ipaddress.IPv4Address('192.168.1.1').ipv6_mapped, + ipaddress.IPv6Address('::ffff:c0a8:101')) + self.assertEqual(ipaddress.IPv4Address('192.168.1.1').ipv6_mapped.ipv4_mapped, + ipaddress.IPv4Address('192.168.1.1')) + class AddressTestCase_v6(BaseTestCase, CommonTestMixin_v6): factory = ipaddress.IPv6Address @@ -542,11 +551,17 @@ def assertBadPart(addr, part): def test_pickle(self): self.pickle_test('2001:db8::') + self.pickle_test('2001:db8::%scope') def test_weakref(self): weakref.ref(self.factory('2001:db8::')) weakref.ref(self.factory('2001:db8::%scope')) + def test_copy(self): + addr = self.factory('2001:db8::%scope') + self.assertEqual(addr, copy.copy(addr)) + self.assertEqual(addr, copy.deepcopy(addr)) + class NetmaskTestMixin_v4(CommonTestMixin_v4): """Input validation on interfaces and networks is very similar""" diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 512745e45350d1..705e880d98685e 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1152,6 +1152,78 @@ def test_pairwise(self): with self.assertRaises(TypeError): pairwise(None) # non-iterable argument + def test_pairwise_reenter(self): + def check(reenter_at, expected): + class I: + count = 0 + def __iter__(self): + return self + def __next__(self): + self.count +=1 + if self.count in reenter_at: + return next(it) + return [self.count] # new object + + it = pairwise(I()) + for item in expected: + self.assertEqual(next(it), item) + + check({1}, [ + (([2], [3]), [4]), + ([4], [5]), + ]) + check({2}, [ + ([1], ([1], [3])), + (([1], [3]), [4]), + ([4], [5]), + ]) + check({3}, [ + ([1], [2]), + ([2], ([2], [4])), + (([2], [4]), [5]), + ([5], [6]), + ]) + check({1, 2}, [ + ((([3], [4]), [5]), [6]), + ([6], [7]), + ]) + check({1, 3}, [ + (([2], ([2], [4])), [5]), + ([5], [6]), + ]) + check({1, 4}, [ + (([2], [3]), (([2], [3]), [5])), + ((([2], [3]), [5]), [6]), + ([6], [7]), + ]) + check({2, 3}, [ + ([1], ([1], ([1], [4]))), + (([1], ([1], [4])), [5]), + ([5], [6]), + ]) + + def test_pairwise_reenter2(self): + def check(maxcount, expected): + class I: + count = 0 + def __iter__(self): + return self + def __next__(self): + if self.count >= maxcount: + raise StopIteration + self.count +=1 + if self.count == 1: + return next(it, None) + return [self.count] # new object + + it = pairwise(I()) + self.assertEqual(list(it), expected) + + check(1, []) + check(2, []) + check(3, []) + check(4, [(([2], [3]), [4])]) + def test_product(self): for args, result in [ ([], [()]), # zero iterables diff --git a/Lib/test/test_keywordonlyarg.py b/Lib/test/test_keywordonlyarg.py index df82f677a00a48..918f953cae5702 100644 --- a/Lib/test/test_keywordonlyarg.py +++ b/Lib/test/test_keywordonlyarg.py @@ -170,7 +170,7 @@ def f(v=a, x=b, *, y=c, z=d): pass self.assertEqual(str(err.exception), "name 'b' is not defined") with self.assertRaises(NameError) as err: - f = lambda v=a, x=b, *, y=c, z=d: None + g = lambda v=a, x=b, *, y=c, z=d: None self.assertEqual(str(err.exception), "name 'b' is not defined") diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index 998fd9d46496bb..e94edcbc107ba9 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -5,6 +5,7 @@ import os import select import socket +from test import support import time import unittest @@ -256,6 +257,23 @@ def test_fd_non_inheritable(self): self.addCleanup(kqueue.close) self.assertEqual(os.get_inheritable(kqueue.fileno()), False) + @support.requires_fork() + def test_fork(self): + # gh-110395: kqueue objects must be closed after fork + kqueue = select.kqueue() + if (pid := os.fork()) == 0: + try: + self.assertTrue(kqueue.closed) + with self.assertRaisesRegex(ValueError, "closed kqueue"): + kqueue.fileno() + except: + os._exit(1) + finally: + os._exit(0) + else: + support.wait_process(pid, exitcode=0) + self.assertFalse(kqueue.closed) # child done, we're still open. + if __name__ == "__main__": unittest.main() 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 12f7bbd123b30c..f95a78aff0c711 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -1,5 +1,6 @@ import doctest import textwrap +import types import unittest @@ -92,7 +93,8 @@ class ListComprehensionTest(unittest.TestCase): - def _check_in_scopes(self, code, outputs=None, ns=None, scopes=None, raises=()): + def _check_in_scopes(self, code, outputs=None, ns=None, scopes=None, raises=(), + exec_func=exec): code = textwrap.dedent(code) scopes = scopes or ["module", "class", "function"] for scope in scopes: @@ -119,7 +121,7 @@ def get_output(moddict, name): return moddict[name] newns = ns.copy() if ns else {} try: - exec(newcode, newns) + exec_func(newcode, newns) except raises as e: # We care about e.g. NameError vs UnboundLocalError self.assertIs(type(e), raises) @@ -613,6 +615,45 @@ def test_frame_locals(self): import sys self._check_in_scopes(code, {"val": 0}, ns={"sys": sys}) + def _recursive_replace(self, maybe_code): + if not isinstance(maybe_code, types.CodeType): + return maybe_code + return maybe_code.replace(co_consts=tuple( + self._recursive_replace(c) for c in maybe_code.co_consts + )) + + def _replacing_exec(self, code_string, ns): + co = compile(code_string, "", "exec") + co = self._recursive_replace(co) + exec(co, ns) + + def test_code_replace(self): + code = """ + x = 3 + [x for x in (1, 2)] + dir() + y = [x] + """ + self._check_in_scopes(code, {"y": [3], "x": 3}) + self._check_in_scopes(code, {"y": [3], "x": 3}, exec_func=self._replacing_exec) + + def test_code_replace_extended_arg(self): + num_names = 300 + assignments = "; ".join(f"x{i} = {i}" for i in range(num_names)) + name_list = ", ".join(f"x{i}" for i in range(num_names)) + expected = { + "y": list(range(num_names)), + **{f"x{i}": i for i in range(num_names)} + } + code = f""" + {assignments} + [({name_list}) for {name_list} in (range(300),)] + dir() + y = [{name_list}] + """ + self._check_in_scopes(code, expected) + self._check_in_scopes(code, expected, exec_func=self._replacing_exec) + __test__ = {'doctests' : doctests} diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index cca02a010b80f4..89be432e4b78c0 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.""" @@ -724,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): @@ -2990,6 +2998,39 @@ class ConfigDictTest(BaseTest): }, } + class CustomFormatter(logging.Formatter): + custom_property = "." + + def format(self, record): + return super().format(record) + + config17 = { + 'version': 1, + 'formatters': { + "custom": { + "()": CustomFormatter, + "style": "{", + "datefmt": "%Y-%m-%d %H:%M:%S", + "format": "{message}", # <-- to force an exception when configuring + ".": { + "custom_property": "value" + } + } + }, + 'handlers' : { + 'hand1' : { + 'class' : 'logging.StreamHandler', + 'formatter' : 'custom', + 'level' : 'NOTSET', + 'stream' : 'ext://sys.stdout', + }, + }, + 'root' : { + 'level' : 'WARNING', + 'handlers' : ['hand1'], + }, + } + bad_format = { "version": 1, "formatters": { @@ -3471,7 +3512,10 @@ def test_config16_ok(self): {'msg': 'Hello'})) self.assertEqual(result, 'Hello ++ defaultvalue') - + def test_config17_ok(self): + self.apply_config(self.config17) + h = logging._handlers['hand1'] + self.assertEqual(h.formatter.custom_property, 'value') def setup_via_listener(self, text, verify=None): text = text.encode("utf-8") diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 4977a9369ddf88..23fcbfac1f9c89 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -847,6 +847,92 @@ def test_lock_unlock(self): self._box.lock() self._box.unlock() + def test_get_info(self): + # Test getting message info from Maildir, not the message. + msg = mailbox.MaildirMessage(self._template % 0) + key = self._box.add(msg) + self.assertEqual(self._box.get_info(key), '') + msg.set_info('OurTestInfo') + self._box[key] = msg + self.assertEqual(self._box.get_info(key), 'OurTestInfo') + + def test_set_info(self): + # Test setting message info from Maildir, not the message. + # This should immediately rename the message file. + msg = mailbox.MaildirMessage(self._template % 0) + key = self._box.add(msg) + def check_info(oldinfo, newinfo): + oldfilename = os.path.join(self._box._path, self._box._lookup(key)) + newsubpath = self._box._lookup(key).split(self._box.colon)[0] + if newinfo: + newsubpath += self._box.colon + newinfo + newfilename = os.path.join(self._box._path, newsubpath) + # assert initial conditions + self.assertEqual(self._box.get_info(key), oldinfo) + if not oldinfo: + self.assertNotIn(self._box._lookup(key), self._box.colon) + self.assertTrue(os.path.exists(oldfilename)) + if oldinfo != newinfo: + self.assertFalse(os.path.exists(newfilename)) + # do the rename + self._box.set_info(key, newinfo) + # assert post conditions + if not newinfo: + self.assertNotIn(self._box._lookup(key), self._box.colon) + if oldinfo != newinfo: + self.assertFalse(os.path.exists(oldfilename)) + self.assertTrue(os.path.exists(newfilename)) + self.assertEqual(self._box.get_info(key), newinfo) + # none -> has info + check_info('', 'info1') + # has info -> same info + check_info('info1', 'info1') + # has info -> different info + check_info('info1', 'info2') + # has info -> none + check_info('info2', '') + # none -> none + check_info('', '') + + def test_get_flags(self): + # Test getting message flags from Maildir, not the message. + msg = mailbox.MaildirMessage(self._template % 0) + key = self._box.add(msg) + self.assertEqual(self._box.get_flags(key), '') + msg.set_flags('T') + self._box[key] = msg + self.assertEqual(self._box.get_flags(key), 'T') + + def test_set_flags(self): + msg = mailbox.MaildirMessage(self._template % 0) + key = self._box.add(msg) + self.assertEqual(self._box.get_flags(key), '') + self._box.set_flags(key, 'S') + self.assertEqual(self._box.get_flags(key), 'S') + + def test_add_flag(self): + msg = mailbox.MaildirMessage(self._template % 0) + key = self._box.add(msg) + self.assertEqual(self._box.get_flags(key), '') + self._box.add_flag(key, 'B') + self.assertEqual(self._box.get_flags(key), 'B') + self._box.add_flag(key, 'B') + self.assertEqual(self._box.get_flags(key), 'B') + self._box.add_flag(key, 'AC') + self.assertEqual(self._box.get_flags(key), 'ABC') + + def test_remove_flag(self): + msg = mailbox.MaildirMessage(self._template % 0) + key = self._box.add(msg) + self._box.set_flags(key, 'abc') + self.assertEqual(self._box.get_flags(key), 'abc') + self._box.remove_flag(key, 'b') + self.assertEqual(self._box.get_flags(key), 'ac') + self._box.remove_flag(key, 'b') + self.assertEqual(self._box.get_flags(key), 'ac') + self._box.remove_flag(key, 'ac') + self.assertEqual(self._box.get_flags(key), '') + def test_folder (self): # Test for bug #1569790: verify that folders returned by .get_folder() # use the same factory function. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index d5d2197c36b254..ad382fc2b59891 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -685,6 +685,7 @@ def msum(iterable): ([], 0.0), ([0.0], 0.0), ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100), + ([1e100, 1.0, -1e100, 1e-100, 1e50, -1, -1e50], 1e-100), ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0), ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0), ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0), @@ -733,9 +734,20 @@ def msum(iterable): self.assertEqual(msum(vals), math.fsum(vals)) self.assertEqual(math.fsum([1.0, math.inf]), math.inf) + self.assertTrue(math.isnan(math.fsum([math.nan, 1.0]))) + self.assertEqual(math.fsum([1e100, FloatLike(1.0), -1e100, 1e-100, + 1e50, FloatLike(-1.0), -1e50]), 1e-100) self.assertRaises(OverflowError, math.fsum, [1e+308, 1e+308]) self.assertRaises(ValueError, math.fsum, [math.inf, -math.inf]) self.assertRaises(TypeError, math.fsum, ['spam']) + self.assertRaises(TypeError, math.fsum, 1) + self.assertRaises(OverflowError, math.fsum, [10**1000]) + + def bad_iter(): + yield 1.0 + raise ZeroDivisionError + + self.assertRaises(ZeroDivisionError, math.fsum, bad_iter()) def testGcd(self): gcd = math.gcd @@ -797,6 +809,8 @@ def testHypot(self): # Test allowable types (those with __float__) self.assertEqual(hypot(12.0, 5.0), 13.0) self.assertEqual(hypot(12, 5), 13) + self.assertEqual(hypot(1, -1), math.sqrt(2)) + self.assertEqual(hypot(1, FloatLike(-1.)), math.sqrt(2)) self.assertEqual(hypot(Decimal(12), Decimal(5)), 13) self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32)) self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3)) @@ -948,6 +962,10 @@ def testDist(self): # Test allowable types (those with __float__) self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0) self.assertEqual(dist((14, 1), (2, -4)), 13) + self.assertEqual(dist((FloatLike(14.), 1), (2, -4)), 13) + self.assertEqual(dist((11, 1), (FloatLike(-1.), -4)), 13) + self.assertEqual(dist((14, FloatLike(-1.)), (2, -6)), 13) + self.assertEqual(dist((14, -1), (2, -6)), 13) self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13)) self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))), F(13, 32)) @@ -1005,6 +1023,12 @@ class T(tuple): with self.assertRaises(TypeError): dist([1], 2) + class BadFloat: + __float__ = BadDescr() + + with self.assertRaises(ValueError): + dist([1], [BadFloat()]) + # Verify that the one dimensional case is equivalent to abs() for i in range(20): p, q = random.random(), random.random() @@ -1175,6 +1199,7 @@ def testLdexp(self): def testLog(self): self.assertRaises(TypeError, math.log) + self.assertRaises(TypeError, math.log, 1, 2, 3) self.ftest('log(1/e)', math.log(1/math.e), -1) self.ftest('log(1)', math.log(1), 0) self.ftest('log(e)', math.log(math.e), 1) @@ -1245,6 +1270,8 @@ def testSumProd(self): self.assertEqual(sumprod(iter([10, 20, 30]), (1, 2, 3)), 140) self.assertEqual(sumprod([1.5, 2.5], [3.5, 4.5]), 16.5) self.assertEqual(sumprod([], []), 0) + self.assertEqual(sumprod([-1], [1.]), -1) + self.assertEqual(sumprod([1.], [-1]), -1) # Type preservation and coercion for v in [ @@ -1270,11 +1297,20 @@ def testSumProd(self): self.assertRaises(TypeError, sumprod, [], [], []) # Three args self.assertRaises(TypeError, sumprod, None, [10]) # Non-iterable self.assertRaises(TypeError, sumprod, [10], None) # Non-iterable + self.assertRaises(TypeError, sumprod, ['x'], [1.0]) # Uneven lengths self.assertRaises(ValueError, sumprod, [10, 20], [30]) self.assertRaises(ValueError, sumprod, [10], [20, 30]) + # Overflows + self.assertEqual(sumprod([10**20], [1]), 10**20) + self.assertEqual(sumprod([1], [10**20]), 10**20) + self.assertEqual(sumprod([10**10], [10**10]), 10**20) + self.assertEqual(sumprod([10**7]*10**5, [10**7]*10**5), 10**19) + self.assertRaises(OverflowError, sumprod, [10**1000], [1.0]) + self.assertRaises(OverflowError, sumprod, [1.0], [10**1000]) + # Error in iterator def raise_after(n): for i in range(n): @@ -1285,6 +1321,11 @@ def raise_after(n): with self.assertRaises(RuntimeError): sumprod(raise_after(5), range(10)) + from test.test_iter import BasicIterClass + + self.assertEqual(sumprod(BasicIterClass(1), [1]), 0) + self.assertEqual(sumprod([1], BasicIterClass(1)), 0) + # Error in multiplication class BadMultiply: def __mul__(self, other): @@ -1325,6 +1366,7 @@ def test_sumprod_accuracy(self): sumprod = math.sumprod self.assertEqual(sumprod([0.1] * 10, [1]*10), 1.0) self.assertEqual(sumprod([0.1] * 20, [True, False] * 10), 1.0) + self.assertEqual(sumprod([True, False] * 10, [0.1] * 20), 1.0) self.assertEqual(sumprod([1.0, 10E100, 1.0, -10E100], [1.0]*4), 2.0) @support.requires_resource('cpu') @@ -1523,6 +1565,7 @@ def testPow(self): self.assertTrue(math.isnan(math.pow(2, NAN))) self.assertTrue(math.isnan(math.pow(0, NAN))) self.assertEqual(math.pow(1, NAN), 1) + self.assertRaises(OverflowError, math.pow, 1e+100, 1e+100) # pow(0., x) self.assertEqual(math.pow(0., INF), 0.) @@ -1879,6 +1922,8 @@ def __trunc__(self): return 23 class TestNoTrunc: pass + class TestBadTrunc: + __trunc__ = BadDescr() self.assertEqual(math.trunc(TestTrunc()), 23) self.assertEqual(math.trunc(FloatTrunc()), 23) @@ -1887,6 +1932,7 @@ class TestNoTrunc: self.assertRaises(TypeError, math.trunc, 1, 2) self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) self.assertRaises(TypeError, math.trunc, TestNoTrunc()) + self.assertRaises(ValueError, math.trunc, TestBadTrunc()) def testIsfinite(self): self.assertTrue(math.isfinite(0.0)) @@ -2087,6 +2133,8 @@ def test_mtestfile(self): '\n '.join(failures)) def test_prod(self): + from fractions import Fraction as F + prod = math.prod self.assertEqual(prod([]), 1) self.assertEqual(prod([], start=5), 5) @@ -2098,6 +2146,14 @@ def test_prod(self): self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0) self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0) self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0) + self.assertEqual(prod([1., F(3, 2)]), 1.5) + + # Error in multiplication + class BadMultiply: + def __rmul__(self, other): + raise RuntimeError + with self.assertRaises(RuntimeError): + prod([10., BadMultiply()]) # Test overflow in fast-path for integers self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32) diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index cd2faba1791c77..731299294e6877 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -463,6 +463,20 @@ def test_getbuffer(self): memio.close() self.assertRaises(ValueError, memio.getbuffer) + def test_getbuffer_empty(self): + memio = self.ioclass() + buf = memio.getbuffer() + self.assertEqual(bytes(buf), b"") + # Trying to change the size of the BytesIO while a buffer is exported + # raises a BufferError. + self.assertRaises(BufferError, memio.write, b'x') + buf2 = memio.getbuffer() + self.assertRaises(BufferError, memio.write, b'x') + buf.release() + self.assertRaises(BufferError, memio.write, b'x') + buf2.release() + memio.write(b'x') + def test_read1(self): buf = self.buftype("1234567890") self.assertEqual(self.ioclass(buf).read1(), buf) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 92c99d645b25cc..866ede5b83dff0 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -93,11 +93,12 @@ def test_basic(self): self.assertEqual(end, PAGESIZE + 6) # test seeking around (try to overflow the seek implementation) - m.seek(0,0) + self.assertTrue(m.seekable()) + self.assertEqual(m.seek(0, 0), 0) self.assertEqual(m.tell(), 0) - m.seek(42,1) + self.assertEqual(m.seek(42, 1), 42) self.assertEqual(m.tell(), 42) - m.seek(0,2) + self.assertEqual(m.seek(0, 2), len(m)) self.assertEqual(m.tell(), len(m)) # Try to seek to negative position... @@ -162,7 +163,7 @@ def test_access_parameter(self): # Ensuring that readonly mmap can't be write() to try: - m.seek(0,0) + m.seek(0, 0) m.write(b'abc') except TypeError: pass @@ -171,7 +172,7 @@ def test_access_parameter(self): # Ensuring that readonly mmap can't be write_byte() to try: - m.seek(0,0) + m.seek(0, 0) m.write_byte(b'd') except TypeError: pass @@ -258,7 +259,7 @@ def test_access_parameter(self): try: m = mmap.mmap(f.fileno(), mapsize, prot=prot) except PermissionError: - # on macOS 14, PROT_READ | PROT_WRITE is not allowed + # on macOS 14, PROT_READ | PROT_EXEC is not allowed pass else: self.assertRaises(TypeError, m.write, b"abcdef") diff --git a/Lib/test/test_module/__init__.py b/Lib/test/test_module/__init__.py index 2524e6c87cb459..d49c44df4d839d 100644 --- a/Lib/test/test_module/__init__.py +++ b/Lib/test/test_module/__init__.py @@ -1,4 +1,5 @@ # Test the module type +import importlib.machinery import unittest import weakref from test.support import gc_collect @@ -264,9 +265,38 @@ def test_module_repr_source(self): self.assertEqual(r[-len(ends_with):], ends_with, '{!r} does not end with {!r}'.format(r, ends_with)) + def test_module_repr_with_namespace_package(self): + m = ModuleType('foo') + loader = importlib.machinery.NamespaceLoader('foo', ['bar'], 'baz') + spec = importlib.machinery.ModuleSpec('foo', loader) + m.__loader__ = loader + m.__spec__ = spec + self.assertEqual(repr(m), "") + + def test_module_repr_with_namespace_package_and_custom_loader(self): + m = ModuleType('foo') + loader = BareLoader() + spec = importlib.machinery.ModuleSpec('foo', loader) + m.__loader__ = loader + m.__spec__ = spec + expected_repr_pattern = r"\)>" + self.assertRegex(repr(m), expected_repr_pattern) + self.assertNotIn('from', repr(m)) + + def test_module_repr_with_fake_namespace_package(self): + m = ModuleType('foo') + loader = BareLoader() + loader._path = ['spam'] + spec = importlib.machinery.ModuleSpec('foo', loader) + m.__loader__ = loader + m.__spec__ = spec + expected_repr_pattern = r"\)>" + self.assertRegex(repr(m), expected_repr_pattern) + self.assertNotIn('from', repr(m)) + def test_module_finalization_at_shutdown(self): # Module globals and builtins should still be available during shutdown - rc, out, err = assert_python_ok("-c", "from test import final_a") + rc, out, err = assert_python_ok("-c", "from test.test_module import final_a") self.assertFalse(err) lines = out.splitlines() self.assertEqual(set(lines), { diff --git a/Lib/test/final_a.py b/Lib/test/test_module/final_a.py similarity index 79% rename from Lib/test/final_a.py rename to Lib/test/test_module/final_a.py index 390ee8895a8a9e..a983f3111248e0 100644 --- a/Lib/test/final_a.py +++ b/Lib/test/test_module/final_a.py @@ -3,7 +3,7 @@ """ import shutil -import test.final_b +import test.test_module.final_b x = 'a' @@ -11,7 +11,7 @@ class C: def __del__(self): # Inspect module globals and builtins print("x =", x) - print("final_b.x =", test.final_b.x) + print("final_b.x =", test.test_module.final_b.x) print("shutil.rmtree =", getattr(shutil.rmtree, '__name__', None)) print("len =", getattr(len, '__name__', None)) diff --git a/Lib/test/final_b.py b/Lib/test/test_module/final_b.py similarity index 79% rename from Lib/test/final_b.py rename to Lib/test/test_module/final_b.py index 7228d82b880156..f3e8d5594904f2 100644 --- a/Lib/test/final_b.py +++ b/Lib/test/test_module/final_b.py @@ -3,7 +3,7 @@ """ import shutil -import test.final_a +import test.test_module.final_a x = 'b' @@ -11,7 +11,7 @@ class C: def __del__(self): # Inspect module globals and builtins print("x =", x) - print("final_a.x =", test.final_a.x) + print("final_a.x =", test.test_module.final_a.x) print("shutil.rmtree =", getattr(shutil.rmtree, '__name__', None)) print("len =", getattr(len, '__name__', None)) diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index 2100d998ff0808..a2efbc95f556c6 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -1185,7 +1185,7 @@ def line(*args): 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: @@ -1214,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(): @@ -1241,12 +1241,12 @@ 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) @@ -1378,15 +1378,16 @@ def func(): x = 4 else: x = 6 + 7 self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [ ('branch', 'func', 2, 2), - ('branch', 'func', 3, 4), + ('branch', 'func', 3, 6), ('jump', 'func', 6, 2), ('branch', 'func', 2, 2), - ('branch', 'func', 3, 3), + ('branch', 'func', 3, 4), ('jump', 'func', 4, 2), - ('branch', 'func', 2, 2)]) + ('branch', 'func', 2, 7)]) self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [ ('line', 'get_events', 10), @@ -1394,17 +1395,18 @@ def func(): ('line', 'func', 2), ('branch', 'func', 2, 2), ('line', 'func', 3), - ('branch', 'func', 3, 4), + ('branch', 'func', 3, 6), ('line', 'func', 6), ('jump', 'func', 6, 2), ('line', 'func', 2), ('branch', 'func', 2, 2), ('line', 'func', 3), - ('branch', 'func', 3, 3), + ('branch', 'func', 3, 4), ('line', 'func', 4), ('jump', 'func', 4, 2), ('line', 'func', 2), - ('branch', 'func', 2, 2), + ('branch', 'func', 2, 7), + ('line', 'func', 7), ('line', 'get_events', 11)]) def test_except_star(self): @@ -1434,7 +1436,7 @@ def func(): ('line', 'meth', 1), ('jump', 'func', 5, 5), ('jump', 'func', 5, '[offset=114]'), - ('branch', 'func', '[offset=120]', '[offset=122]'), + ('branch', 'func', '[offset=120]', '[offset=124]'), ('line', 'get_events', 11)]) self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [ @@ -1450,7 +1452,7 @@ def func(): ('return', None), ('jump', 'func', 5, 5), ('jump', 'func', 5, '[offset=114]'), - ('branch', 'func', '[offset=120]', '[offset=122]'), + ('branch', 'func', '[offset=120]', '[offset=124]'), ('return', None), ('line', 'get_events', 11)]) @@ -1788,3 +1790,28 @@ def test_func(x): test_func(1000) sys.monitoring.set_local_events(TEST_TOOL, code, 0) self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), 0) + +class TestTier2Optimizer(CheckEvents): + + def test_monitoring_already_opimized_loop(self): + def test_func(recorder): + set_events = sys.monitoring.set_events + line = E.LINE + i = 0 + for i in range(551): + # Turn on events without branching once i reaches 500. + set_events(TEST_TOOL, line * int(i >= 500)) + pass + pass + pass + + self.assertEqual(sys.monitoring._all_events(), {}) + events = [] + recorder = LineRecorder(events) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, recorder) + try: + test_func(recorder) + finally: + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + sys.monitoring.set_events(TEST_TOOL, 0) + self.assertGreater(len(events), 250) diff --git a/Lib/test/test_msvcrt.py b/Lib/test/test_msvcrt.py index 81ec13026014e6..600c4446fd5cd4 100644 --- a/Lib/test/test_msvcrt.py +++ b/Lib/test/test_msvcrt.py @@ -1,17 +1,17 @@ import os +import subprocess import sys import unittest +from textwrap import dedent -from test.support import os_helper +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; - -from _testconsole import write_input, flush_console_input_buffer +import msvcrt class TestFileOperations(unittest.TestCase): @@ -61,34 +61,45 @@ def test_get_osfhandle(self): 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): - h = msvcrt.get_osfhandle(sys.stdin.fileno()) - flush_console_input_buffer(h) - self.assertEqual(msvcrt.kbhit(), 0) + 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 test_getwch(self): - with open('CONIN$', 'rb', buffering=0) as stdin: - h = msvcrt.get_osfhandle(stdin.fileno()) - flush_console_input_buffer(h) + 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) - write_input(stdin, c_encoded) - self.assertEqual(msvcrt.getwch(), c) + 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): - with open('CONIN$', 'rb', buffering=0) as stdin: - h = msvcrt.get_osfhandle(stdin.fileno()) - flush_console_input_buffer(h) - - write_input(stdin, c_encoded) - self.assertEqual(msvcrt.getwche(), c) + self.check_getwch('getwche') def test_putch(self): msvcrt.putch(b'c') diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index d91dcdfb0c5fac..bf990ed36fbcae 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 @@ -255,6 +256,7 @@ def test_join(self): tester('ntpath.join("a", "b", "c")', 'a\\b\\c') tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c') tester('ntpath.join("a", "b\\", "c")', 'a\\b\\c') + tester('ntpath.join("a", "b", "c\\")', 'a\\b\\c\\') tester('ntpath.join("a", "b", "\\c")', '\\c') tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep') tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b') @@ -312,6 +314,16 @@ def test_join(self): tester("ntpath.join('\\\\computer\\', 'share')", '\\\\computer\\share') tester("ntpath.join('\\\\computer\\share\\', 'a')", '\\\\computer\\share\\a') tester("ntpath.join('\\\\computer\\share\\a\\', 'b')", '\\\\computer\\share\\a\\b') + # Second part is anchored, so that the first part is ignored. + tester("ntpath.join('a', 'Z:b', 'c')", 'Z:b\\c') + tester("ntpath.join('a', 'Z:\\b', 'c')", 'Z:\\b\\c') + tester("ntpath.join('a', '\\\\b\\c', 'd')", '\\\\b\\c\\d') + # Second part has a root but not drive. + tester("ntpath.join('a', '\\b', 'c')", '\\b\\c') + tester("ntpath.join('Z:/a', '/b', 'c')", 'Z:\\b\\c') + tester("ntpath.join('//?/Z:/a', '/b', 'c')", '\\\\?\\Z:\\b\\c') + tester("ntpath.join('D:a', './c:b')", 'D:a\\.\\c:b') + tester("ntpath.join('D:/a', './c:b')", 'D:\\a\\.\\c:b') def test_normpath(self): tester("ntpath.normpath('A//////././//.//B')", r'A\B') @@ -637,6 +649,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() diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 66aece2c4b3eb9..d4680ef0f0e03f 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 @@ -1149,9 +1150,12 @@ def test_putenv_unsetenv(self): def test_putenv_unsetenv_error(self): # Empty variable name is invalid. # "=" and null character are not allowed in a variable name. - for name in ('', '=name', 'na=me', 'name=', 'name\0', 'na\0me'): + for name in ('', '=name', 'na=me', 'name='): self.assertRaises((OSError, ValueError), os.putenv, name, "value") self.assertRaises((OSError, ValueError), os.unsetenv, name) + for name in ('name\0', 'na\0me'): + self.assertRaises(ValueError, os.putenv, name, "value") + self.assertRaises(ValueError, os.unsetenv, name) if sys.platform == "win32": # On Windows, an environment variable string ("name=value" string) @@ -2566,30 +2570,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() @@ -3922,6 +3930,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 - self.CLOCK_RES) + + # 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 - self.CLOCK_RES) + + 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 - self.CLOCK_RES_NS) + else: + dt = time.perf_counter() - t + self.assertGreater(dt, total_time / sec_to_nsec - self.CLOCK_RES) + 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 - self.CLOCK_RES_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 - self.CLOCK_RES_NS) class OSErrorTests(unittest.TestCase): def setUp(self): @@ -3996,14 +4326,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): + affinity1 = os.process_cpu_count() + if affinity1 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() + affinity2 = os.process_cpu_count() + self.assertEqual(affinity2, affinity1 - 1) + # FD inheritance check is only useful for systems with process support. @support.requires_subprocess() @@ -4722,7 +5080,10 @@ def test_fork(self): support.wait_process(pid, exitcode=0) """ assert_python_ok("-c", code) - assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug") + if support.Py_GIL_DISABLED: + assert_python_ok("-c", code, PYTHONMALLOC="mimalloc_debug") + else: + assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug") @unittest.skipUnless(sys.platform in ("linux", "darwin"), "Only Linux and macOS detect this today.") diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 484a5e6c3bd64d..a1acba406ea37c 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 @@ -40,13 +41,43 @@ def test_is_notimplemented(self): only_posix = unittest.skipIf(os.name == 'nt', 'test requires a POSIX-compatible system') +root_in_posix = False +if hasattr(os, 'geteuid'): + root_in_posix = (os.geteuid() == 0) # # Tests for the pure classes. # -class PurePathTest(unittest.TestCase): - cls = pathlib.PurePath + +class PurePathBaseTest(unittest.TestCase): + cls = pathlib._abc.PurePathBase + + def test_magic_methods(self): + P = self.cls + self.assertFalse(hasattr(P, '__fspath__')) + self.assertFalse(hasattr(P, '__bytes__')) + self.assertIs(P.__reduce__, object.__reduce__) + self.assertIs(P.__hash__, object.__hash__) + self.assertIs(P.__eq__, object.__eq__) + self.assertIs(P.__lt__, object.__lt__) + self.assertIs(P.__le__, object.__le__) + self.assertIs(P.__gt__, object.__gt__) + self.assertIs(P.__ge__, object.__ge__) + + +class DummyPurePath(pathlib._abc.PurePathBase): + def __eq__(self, other): + if not isinstance(other, DummyPurePath): + return NotImplemented + return str(self) == str(other) + + def __hash__(self): + return hash(str(self)) + + +class DummyPurePathTest(unittest.TestCase): + cls = DummyPurePath # Keys are canonical paths, values are list of tuples of arguments # supposed to produce equal paths. @@ -78,12 +109,6 @@ def test_constructor_common(self): P('/a', 'b', 'c') P('a/b/c') P('/a/b/c') - P(FakePath("a/b/c")) - self.assertEqual(P(P('a')), P('a')) - self.assertEqual(P(P('a'), 'b'), P('a/b')) - self.assertEqual(P(P('a'), P('b')), P('a/b')) - self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c"))) - self.assertEqual(P(P('./a:b')), P('./a:b')) def test_concrete_class(self): if self.cls is pathlib.PurePath: @@ -116,33 +141,6 @@ def test_different_pathmods_unordered(self): with self.assertRaises(TypeError): p >= q - def test_bytes(self): - P = self.cls - message = (r"argument should be a str or an os\.PathLike object " - r"where __fspath__ returns a str, not 'bytes'") - with self.assertRaisesRegex(TypeError, message): - P(b'a') - with self.assertRaisesRegex(TypeError, message): - P(b'a', 'b') - with self.assertRaisesRegex(TypeError, message): - P('a', b'b') - with self.assertRaises(TypeError): - P('a').joinpath(b'b') - with self.assertRaises(TypeError): - P('a') / b'b' - with self.assertRaises(TypeError): - b'a' / P('b') - with self.assertRaises(TypeError): - P('a').match(b'b') - with self.assertRaises(TypeError): - P('a').relative_to(b'b') - with self.assertRaises(TypeError): - P('a').with_name(b'b') - with self.assertRaises(TypeError): - P('a').with_stem(b'b') - with self.assertRaises(TypeError): - P('a').with_suffix(b'b') - def _check_str_subclass(self, *args): # Issue #21127: it should be possible to construct a PurePath object # from a str subclass instance, and it then gets converted to @@ -183,45 +181,30 @@ def with_segments(self, *pathsegments): for parent in p.parents: self.assertEqual(42, parent.session_id) - def _get_drive_root_parts(self, parts): - path = self.cls(*parts) - return path.drive, path.root, path.parts - - def _check_drive_root_parts(self, arg, *expected): + def _check_parse_path(self, raw_path, *expected): sep = self.pathmod.sep - actual = self._get_drive_root_parts([x.replace('/', sep) for x in arg]) + actual = self.cls._parse_path(raw_path.replace('/', sep)) self.assertEqual(actual, expected) if altsep := self.pathmod.altsep: - actual = self._get_drive_root_parts([x.replace('/', altsep) for x in arg]) + actual = self.cls._parse_path(raw_path.replace('/', altsep)) self.assertEqual(actual, expected) - def test_drive_root_parts_common(self): - check = self._check_drive_root_parts + def test_parse_path_common(self): + check = self._check_parse_path sep = self.pathmod.sep - # Unanchored parts. - check((), '', '', ()) - check(('a',), '', '', ('a',)) - check(('a/',), '', '', ('a',)) - check(('a', 'b'), '', '', ('a', 'b')) - # Expansion. - check(('a/b',), '', '', ('a', 'b')) - check(('a/b/',), '', '', ('a', 'b')) - check(('a', 'b/c', 'd'), '', '', ('a', 'b', 'c', 'd')) - # Collapsing and stripping excess slashes. - check(('a', 'b//c', 'd'), '', '', ('a', 'b', 'c', 'd')) - check(('a', 'b/c/', 'd'), '', '', ('a', 'b', 'c', 'd')) - # Eliminating standalone dots. - check(('.',), '', '', ()) - check(('.', '.', 'b'), '', '', ('b',)) - check(('a', '.', 'b'), '', '', ('a', 'b')) - check(('a', '.', '.'), '', '', ('a',)) - # The first part is anchored. - check(('/a/b',), '', sep, (sep, 'a', 'b')) - check(('/a', 'b'), '', sep, (sep, 'a', 'b')) - check(('/a/', 'b'), '', sep, (sep, 'a', 'b')) - # Ignoring parts before an anchored part. - check(('a', '/b', 'c'), '', sep, (sep, 'b', 'c')) - check(('a', '/b', '/c'), '', sep, (sep, 'c')) + check('', '', '', []) + check('a', '', '', ['a']) + check('a/', '', '', ['a']) + check('a/b', '', '', ['a', 'b']) + check('a/b/', '', '', ['a', 'b']) + check('a/b/c/d', '', '', ['a', 'b', 'c', 'd']) + check('a/b//c/d', '', '', ['a', 'b', 'c', 'd']) + check('a/b/c/d', '', '', ['a', 'b', 'c', 'd']) + check('.', '', '', []) + check('././b', '', '', ['b']) + check('a/./b', '', '', ['a', 'b']) + check('a/./.', '', '', ['a']) + check('/a/b', '', sep, ['a', 'b']) def test_join_common(self): P = self.cls @@ -231,8 +214,6 @@ def test_join_common(self): self.assertIs(type(pp), type(p)) pp = p.joinpath('c', 'd') self.assertEqual(pp, P('a/b/c/d')) - pp = p.joinpath(P('c')) - self.assertEqual(pp, P('a/b/c')) pp = p.joinpath('/c') self.assertEqual(pp, P('/c')) @@ -249,8 +230,6 @@ def test_div_common(self): self.assertEqual(pp, P('a/b/c/d')) pp = 'c' / p / 'd' self.assertEqual(pp, P('c/a/b/d')) - pp = p / P('c') - self.assertEqual(pp, P('a/b/c')) pp = p/ '/c' self.assertEqual(pp, P('/c')) @@ -272,18 +251,6 @@ def test_as_posix_common(self): self.assertEqual(P(pathstr).as_posix(), pathstr) # Other tests for as_posix() are in test_equivalences(). - def test_as_bytes_common(self): - sep = os.fsencode(self.sep) - P = self.cls - self.assertEqual(bytes(P('a/b')), b'a' + sep + b'b') - - def test_as_uri_common(self): - P = self.cls - with self.assertRaises(ValueError): - P('a').as_uri() - with self.assertRaises(ValueError): - P().as_uri() - def test_repr_common(self): for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): with self.subTest(pathstr=pathstr): @@ -296,17 +263,6 @@ def test_repr_common(self): inner = r[len(clsname) + 1 : -1] self.assertEqual(eval(inner), p.as_posix()) - def test_repr_roundtrips(self): - for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): - with self.subTest(pathstr=pathstr): - p = self.cls(pathstr) - r = repr(p) - # The repr() roundtrips. - q = eval(r, pathlib.__dict__) - self.assertIs(q.__class__, p.__class__) - self.assertEqual(q, p) - self.assertEqual(repr(q), r) - def test_eq_common(self): P = self.cls self.assertEqual(P('a/b'), P('a/b')) @@ -389,34 +345,6 @@ def test_match_common(self): self.assertTrue(P().match('**')) self.assertFalse(P().match('**/*')) - def test_ordering_common(self): - # Ordering is tuple-alike. - def assertLess(a, b): - self.assertLess(a, b) - self.assertGreater(b, a) - P = self.cls - a = P('a') - b = P('a/b') - c = P('abc') - d = P('b') - assertLess(a, b) - assertLess(a, c) - assertLess(a, d) - assertLess(b, c) - assertLess(c, d) - P = self.cls - a = P('/a') - b = P('/a/b') - c = P('/abc') - d = P('/b') - assertLess(a, b) - assertLess(a, c) - assertLess(a, d) - assertLess(b, c) - assertLess(c, d) - with self.assertRaises(TypeError): - P() < {} - def test_parts_common(self): # `parts` returns a tuple. sep = self.sep @@ -429,12 +357,6 @@ def test_parts_common(self): parts = p.parts self.assertEqual(parts, (sep, 'a', 'b')) - def test_fspath_common(self): - P = self.cls - p = P('a/b') - self._check_str(p.__fspath__(), ('a/b',)) - self._check_str(os.fspath(p), ('a/b',)) - def test_equivalences(self): for k, tuples in self.equivalences.items(): canon = k.replace('/', self.sep) @@ -613,6 +535,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 +553,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') @@ -656,8 +580,6 @@ def test_with_suffix_common(self): self.assertRaises(ValueError, P('a/b').with_suffix, '.c/.d') self.assertRaises(ValueError, P('a/b').with_suffix, './.d') self.assertRaises(ValueError, P('a/b').with_suffix, '.d/.') - self.assertRaises(ValueError, P('a/b').with_suffix, - (self.pathmod.sep, 'd')) def test_relative_to_common(self): P = self.cls @@ -773,6 +695,29 @@ def test_is_relative_to_common(self): self.assertFalse(p.is_relative_to('')) self.assertFalse(p.is_relative_to(P('a'))) + +class PurePathTest(DummyPurePathTest): + cls = pathlib.PurePath + + def test_constructor_nested(self): + P = self.cls + P(FakePath("a/b/c")) + self.assertEqual(P(P('a')), P('a')) + self.assertEqual(P(P('a'), 'b'), P('a/b')) + self.assertEqual(P(P('a'), P('b')), P('a/b')) + self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c"))) + self.assertEqual(P(P('./a:b')), P('./a:b')) + + def test_join_nested(self): + P = self.cls + p = P('a/b').joinpath(P('c')) + self.assertEqual(p, P('a/b/c')) + + def test_div_nested(self): + P = self.cls + p = P('a/b') / P('c') + self.assertEqual(p, P('a/b/c')) + def test_pickling_common(self): P = self.cls p = P('/a/b') @@ -784,21 +729,105 @@ def test_pickling_common(self): self.assertEqual(hash(pp), hash(p)) self.assertEqual(str(pp), str(p)) + def test_fspath_common(self): + P = self.cls + p = P('a/b') + self._check_str(p.__fspath__(), ('a/b',)) + self._check_str(os.fspath(p), ('a/b',)) + + def test_bytes(self): + P = self.cls + message = (r"argument should be a str or an os\.PathLike object " + r"where __fspath__ returns a str, not 'bytes'") + with self.assertRaisesRegex(TypeError, message): + P(b'a') + with self.assertRaisesRegex(TypeError, message): + P(b'a', 'b') + with self.assertRaisesRegex(TypeError, message): + P('a', b'b') + with self.assertRaises(TypeError): + P('a').joinpath(b'b') + with self.assertRaises(TypeError): + P('a') / b'b' + with self.assertRaises(TypeError): + b'a' / P('b') + with self.assertRaises(TypeError): + P('a').match(b'b') + with self.assertRaises(TypeError): + P('a').relative_to(b'b') + with self.assertRaises(TypeError): + P('a').with_name(b'b') + with self.assertRaises(TypeError): + P('a').with_stem(b'b') + with self.assertRaises(TypeError): + P('a').with_suffix(b'b') + + def test_as_bytes_common(self): + sep = os.fsencode(self.sep) + P = self.cls + self.assertEqual(bytes(P('a/b')), b'a' + sep + b'b') + + def test_ordering_common(self): + # Ordering is tuple-alike. + def assertLess(a, b): + self.assertLess(a, b) + self.assertGreater(b, a) + P = self.cls + a = P('a') + b = P('a/b') + c = P('abc') + d = P('b') + assertLess(a, b) + assertLess(a, c) + assertLess(a, d) + assertLess(b, c) + assertLess(c, d) + P = self.cls + a = P('/a') + b = P('/a/b') + c = P('/abc') + d = P('/b') + assertLess(a, b) + assertLess(a, c) + assertLess(a, d) + assertLess(b, c) + assertLess(c, d) + with self.assertRaises(TypeError): + P() < {} + + def test_as_uri_common(self): + P = self.cls + with self.assertRaises(ValueError): + P('a').as_uri() + with self.assertRaises(ValueError): + P().as_uri() + + def test_repr_roundtrips(self): + for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): + with self.subTest(pathstr=pathstr): + p = self.cls(pathstr) + r = repr(p) + # The repr() roundtrips. + q = eval(r, pathlib.__dict__) + self.assertIs(q.__class__, p.__class__) + self.assertEqual(q, p) + self.assertEqual(repr(q), r) + class PurePosixPathTest(PurePathTest): cls = pathlib.PurePosixPath - def test_drive_root_parts(self): - check = self._check_drive_root_parts + def test_parse_path(self): + check = self._check_parse_path # Collapsing of excess leading slashes, except for the double-slash # special case. - check(('//a', 'b'), '', '//', ('//', 'a', 'b')) - check(('///a', 'b'), '', '/', ('/', 'a', 'b')) - check(('////a', 'b'), '', '/', ('/', 'a', 'b')) + check('//a/b', '', '//', ['a', 'b']) + check('///a/b', '', '/', ['a', 'b']) + check('////a/b', '', '/', ['a', 'b']) # Paths which look like NT paths aren't treated specially. - check(('c:a',), '', '', ('c:a',)) - check(('c:\\a',), '', '', ('c:\\a',)) - check(('\\a',), '', '', ('\\a',)) + check('c:a', '', '', ['c:a',]) + check('c:\\a', '', '', ['c:\\a',]) + check('\\a', '', '', ['\\a',]) def test_root(self): P = self.cls @@ -896,67 +925,53 @@ class PureWindowsPathTest(PurePathTest): ], }) - def test_drive_root_parts(self): - check = self._check_drive_root_parts + def test_parse_path(self): + check = self._check_parse_path # First part is anchored. - check(('c:',), 'c:', '', ('c:',)) - check(('c:/',), 'c:', '\\', ('c:\\',)) - check(('/',), '', '\\', ('\\',)) - check(('c:a',), 'c:', '', ('c:', 'a')) - check(('c:/a',), 'c:', '\\', ('c:\\', 'a')) - check(('/a',), '', '\\', ('\\', 'a')) + check('c:', 'c:', '', []) + check('c:/', 'c:', '\\', []) + check('/', '', '\\', []) + check('c:a', 'c:', '', ['a']) + check('c:/a', 'c:', '\\', ['a']) + check('/a', '', '\\', ['a']) # UNC paths. - check(('//',), '\\\\', '', ('\\\\',)) - check(('//a',), '\\\\a', '', ('\\\\a',)) - check(('//a/',), '\\\\a\\', '', ('\\\\a\\',)) - check(('//a/b',), '\\\\a\\b', '\\', ('\\\\a\\b\\',)) - check(('//a/b/',), '\\\\a\\b', '\\', ('\\\\a\\b\\',)) - check(('//a/b/c',), '\\\\a\\b', '\\', ('\\\\a\\b\\', 'c')) - # Second part is anchored, so that the first part is ignored. - check(('a', 'Z:b', 'c'), 'Z:', '', ('Z:', 'b', 'c')) - check(('a', 'Z:/b', 'c'), 'Z:', '\\', ('Z:\\', 'b', 'c')) - # UNC paths. - check(('a', '//b/c', 'd'), '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd')) + check('//', '\\\\', '', []) + check('//a', '\\\\a', '', []) + check('//a/', '\\\\a\\', '', []) + check('//a/b', '\\\\a\\b', '\\', []) + check('//a/b/', '\\\\a\\b', '\\', []) + check('//a/b/c', '\\\\a\\b', '\\', ['c']) # Collapsing and stripping excess slashes. - check(('a', 'Z://b//c/', 'd/'), 'Z:', '\\', ('Z:\\', 'b', 'c', 'd')) + check('Z://b//c/d/', 'Z:', '\\', ['b', 'c', 'd']) # UNC paths. - check(('a', '//b/c//', 'd'), '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd')) + check('//b/c//d', '\\\\b\\c', '\\', ['d']) # Extended paths. - check(('//./c:',), '\\\\.\\c:', '', ('\\\\.\\c:',)) - check(('//?/c:/',), '\\\\?\\c:', '\\', ('\\\\?\\c:\\',)) - check(('//?/c:/a',), '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'a')) - check(('//?/c:/a', '/b'), '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'b')) + check('//./c:', '\\\\.\\c:', '', []) + check('//?/c:/', '\\\\?\\c:', '\\', []) + check('//?/c:/a', '\\\\?\\c:', '\\', ['a']) # Extended UNC paths (format is "\\?\UNC\server\share"). - check(('//?',), '\\\\?', '', ('\\\\?',)) - check(('//?/',), '\\\\?\\', '', ('\\\\?\\',)) - check(('//?/UNC',), '\\\\?\\UNC', '', ('\\\\?\\UNC',)) - check(('//?/UNC/',), '\\\\?\\UNC\\', '', ('\\\\?\\UNC\\',)) - check(('//?/UNC/b',), '\\\\?\\UNC\\b', '', ('\\\\?\\UNC\\b',)) - check(('//?/UNC/b/',), '\\\\?\\UNC\\b\\', '', ('\\\\?\\UNC\\b\\',)) - check(('//?/UNC/b/c',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',)) - check(('//?/UNC/b/c/',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',)) - check(('//?/UNC/b/c/d',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\', 'd')) + check('//?', '\\\\?', '', []) + check('//?/', '\\\\?\\', '', []) + check('//?/UNC', '\\\\?\\UNC', '', []) + check('//?/UNC/', '\\\\?\\UNC\\', '', []) + check('//?/UNC/b', '\\\\?\\UNC\\b', '', []) + check('//?/UNC/b/', '\\\\?\\UNC\\b\\', '', []) + check('//?/UNC/b/c', '\\\\?\\UNC\\b\\c', '\\', []) + check('//?/UNC/b/c/', '\\\\?\\UNC\\b\\c', '\\', []) + check('//?/UNC/b/c/d', '\\\\?\\UNC\\b\\c', '\\', ['d']) # UNC device paths - check(('//./BootPartition/',), '\\\\.\\BootPartition', '\\', ('\\\\.\\BootPartition\\',)) - check(('//?/BootPartition/',), '\\\\?\\BootPartition', '\\', ('\\\\?\\BootPartition\\',)) - check(('//./PhysicalDrive0',), '\\\\.\\PhysicalDrive0', '', ('\\\\.\\PhysicalDrive0',)) - check(('//?/Volume{}/',), '\\\\?\\Volume{}', '\\', ('\\\\?\\Volume{}\\',)) - check(('//./nul',), '\\\\.\\nul', '', ('\\\\.\\nul',)) - # Second part has a root but not drive. - check(('a', '/b', 'c'), '', '\\', ('\\', 'b', 'c')) - check(('Z:/a', '/b', 'c'), 'Z:', '\\', ('Z:\\', 'b', 'c')) - check(('//?/Z:/a', '/b', 'c'), '\\\\?\\Z:', '\\', ('\\\\?\\Z:\\', 'b', 'c')) - # Joining with the same drive => the first path is appended to if - # the second path is relative. - check(('c:/a/b', 'c:x/y'), 'c:', '\\', ('c:\\', 'a', 'b', 'x', 'y')) - check(('c:/a/b', 'c:/x/y'), 'c:', '\\', ('c:\\', 'x', 'y')) + check('//./BootPartition/', '\\\\.\\BootPartition', '\\', []) + check('//?/BootPartition/', '\\\\?\\BootPartition', '\\', []) + check('//./PhysicalDrive0', '\\\\.\\PhysicalDrive0', '', []) + check('//?/Volume{}/', '\\\\?\\Volume{}', '\\', []) + check('//./nul', '\\\\.\\nul', '', []) # Paths to files with NTFS alternate data streams - check(('./c:s',), '', '', ('c:s',)) - check(('cc:s',), '', '', ('cc:s',)) - check(('C:c:s',), 'C:', '', ('C:', 'c:s')) - check(('C:/c:s',), 'C:', '\\', ('C:\\', 'c:s')) - check(('D:a', './c:b'), 'D:', '', ('D:', 'a', 'c:b')) - check(('D:/a', './c:b'), 'D:', '\\', ('D:\\', 'a', 'c:b')) + check('./c:s', '', '', ['c:s']) + check('cc:s', '', '', ['cc:s']) + check('C:c:s', 'C:', '', ['c:s']) + check('C:/c:s', 'C:', '\\', ['c:s']) + check('D:a/c:b', 'D:', '', ['a', 'c:b']) + check('D:/a/c:b', 'D:', '\\', ['a', 'c:b']) def test_str(self): p = self.cls('a/b/c') @@ -1234,8 +1249,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') @@ -1248,8 +1265,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') @@ -1562,34 +1581,185 @@ class cls(pathlib.PurePath): test_repr_roundtrips = None -@only_posix -class PosixPathAsPureTest(PurePosixPathTest): - cls = pathlib.PosixPath +# +# Tests for the virtual classes. +# -@only_nt -class WindowsPathAsPureTest(PureWindowsPathTest): - cls = pathlib.WindowsPath +class PathBaseTest(PurePathBaseTest): + cls = pathlib._abc.PathBase - def test_owner(self): + def test_unsupported_operation(self): P = self.cls - with self.assertRaises(pathlib.UnsupportedOperation): - P('c:/').owner() + 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_group(self): - P = self.cls - with self.assertRaises(pathlib.UnsupportedOperation): - P('c:/').group() + 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()) -# -# Tests for the concrete classes. -# + def test_as_bytes_common(self): + self.assertRaises(TypeError, bytes, self.cls()) -class PathTest(unittest.TestCase): - """Tests for the FS-accessing functionalities of the Path classes.""" + 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__) - cls = pathlib.Path - can_symlink = os_helper.can_symlink() + +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._abc.PathBase): + """ + Simple implementation of PathBase that keeps files and directories in + memory. + """ + _files = {} + _directories = {} + _symlinks = {} + + def __eq__(self, other): + if not isinstance(other, DummyPath): + return NotImplemented + return str(self) == str(other) + + def __hash__(self): + return hash(str(self)) + + 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(DummyPurePathTest): + """Tests for PathBase methods that use stat(), open() and iterdir().""" + + cls = DummyPath + can_symlink = False # (BASE) # | @@ -1612,37 +1782,43 @@ 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: + super().setUp() + 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: @@ -1722,10 +1898,25 @@ def test_read_write_text(self): self.assertRaises(TypeError, (p / 'fileA').write_text, b'somebytes') self.assertEqual((p / 'fileA').read_text(encoding='latin-1'), 'äbcdefg') - def test_write_text_with_newlines(self): + def test_read_text_with_newlines(self): p = self.cls(BASE) # Check that `\n` character change nothing - (p / 'fileA').write_text('abcde\r\nfghlk\n\rmnopq', newline='\n') + (p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq') + self.assertEqual((p / 'fileA').read_text(newline='\n'), + 'abcde\r\nfghlk\n\rmnopq') + # Check that `\r` character replaces `\n` + (p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq') + self.assertEqual((p / 'fileA').read_text(newline='\r'), + 'abcde\r\nfghlk\n\rmnopq') + # Check that `\r\n` character replaces `\n` + (p / 'fileA').write_bytes(b'abcde\r\nfghlk\n\rmnopq') + self.assertEqual((p / 'fileA').read_text(newline='\r\n'), + 'abcde\r\nfghlk\n\rmnopq') + + def test_write_text_with_newlines(self): + p = self.cls(BASE) + # Check that `\n` character change nothing + (p / 'fileA').write_text('abcde\r\nfghlk\n\rmnopq', newline='\n') self.assertEqual((p / 'fileA').read_bytes(), b'abcde\r\nfghlk\n\rmnopq') # Check that `\r` character replaces `\n` @@ -1799,9 +1990,9 @@ def _check(glob, expected): _check(p.glob("brokenLink"), ['brokenLink']) if not self.can_symlink: - _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE"]) + _check(p.glob("*/"), ["dirA/", "dirB/", "dirC/", "dirE/"]) else: - _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE", "linkB"]) + _check(p.glob("*/"), ["dirA/", "dirB/", "dirC/", "dirE/", "linkB/"]) def test_glob_empty_pattern(self): p = self.cls() @@ -1834,17 +2025,17 @@ def _check(path, glob, expected): _check(p, "*A", ["dirA", "fileA", "linkA"]) _check(p, "*B/*", ["dirB/fileB", "dirB/linkD", "linkB/fileB", "linkB/linkD"]) _check(p, "*/fileB", ["dirB/fileB", "linkB/fileB"]) - _check(p, "*/", ["dirA", "dirB", "dirC", "dirE", "linkB"]) + _check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirE/", "linkB/"]) _check(p, "dir*/*/..", ["dirC/dirD/..", "dirA/linkC/.."]) - _check(p, "dir*/**/", ["dirA", "dirA/linkC", "dirA/linkC/linkD", "dirB", "dirB/linkD", - "dirC", "dirC/dirD", "dirE"]) + _check(p, "dir*/**/", ["dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/", + "dirC/", "dirC/dirD/", "dirE/"]) _check(p, "dir*/**/..", ["dirA/..", "dirA/linkC/..", "dirB/..", "dirC/..", "dirC/dirD/..", "dirE/.."]) - _check(p, "dir*/*/**/", ["dirA/linkC", "dirA/linkC/linkD", "dirB/linkD", "dirC/dirD"]) + _check(p, "dir*/*/**/", ["dirA/linkC/", "dirA/linkC/linkD/", "dirB/linkD/", "dirC/dirD/"]) _check(p, "dir*/*/**/..", ["dirA/linkC/..", "dirC/dirD/.."]) _check(p, "dir*/**/fileC", ["dirC/fileC"]) - _check(p, "dir*/*/../dirD/**/", ["dirC/dirD/../dirD"]) - _check(p, "*/dirD/**/", ["dirC/dirD"]) + _check(p, "dir*/*/../dirD/**/", ["dirC/dirD/../dirD/"]) + _check(p, "*/dirD/**/", ["dirC/dirD/"]) def test_glob_no_follow_symlinks_common(self): if not self.can_symlink: @@ -1859,19 +2050,19 @@ def _check(path, glob, expected): _check(p, "*A", ["dirA", "fileA", "linkA"]) _check(p, "*B/*", ["dirB/fileB", "dirB/linkD"]) _check(p, "*/fileB", ["dirB/fileB"]) - _check(p, "*/", ["dirA", "dirB", "dirC", "dirE"]) + _check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirE/"]) _check(p, "dir*/*/..", ["dirC/dirD/.."]) - _check(p, "dir*/**/", ["dirA", "dirB", "dirC", "dirC/dirD", "dirE"]) + _check(p, "dir*/**/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"]) _check(p, "dir*/**/..", ["dirA/..", "dirB/..", "dirC/..", "dirC/dirD/..", "dirE/.."]) - _check(p, "dir*/*/**/", ["dirC/dirD"]) + _check(p, "dir*/*/**/", ["dirC/dirD/"]) _check(p, "dir*/*/**/..", ["dirC/dirD/.."]) _check(p, "dir*/**/fileC", ["dirC/fileC"]) - _check(p, "dir*/*/../dirD/**/", ["dirC/dirD/../dirD"]) - _check(p, "*/dirD/**/", ["dirC/dirD"]) + _check(p, "dir*/*/../dirD/**/", ["dirC/dirD/../dirD/"]) + _check(p, "*/dirD/**/", ["dirC/dirD/"]) def test_rglob_common(self): def _check(glob, expected): - self.assertEqual(sorted(glob), sorted(P(BASE, q) for q in expected)) + self.assertEqual(set(glob), {P(BASE, q) for q in expected}) P = self.cls p = P(BASE) it = p.rglob("fileA") @@ -1889,25 +2080,25 @@ def _check(glob, expected): "dirC/fileC", "dirC/dirD/fileD"]) if not self.can_symlink: _check(p.rglob("*/"), [ - "dirA", "dirB", "dirC", "dirC/dirD", "dirE", + "dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/", ]) else: _check(p.rglob("*/"), [ - "dirA", "dirA/linkC", "dirB", "dirB/linkD", "dirC", - "dirC/dirD", "dirE", "linkB", + "dirA/", "dirA/linkC/", "dirB/", "dirB/linkD/", "dirC/", + "dirC/dirD/", "dirE/", "linkB/", ]) - _check(p.rglob(""), ["", "dirA", "dirB", "dirC", "dirE", "dirC/dirD"]) + _check(p.rglob(""), ["./", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"]) p = P(BASE, "dirC") _check(p.rglob("*"), ["dirC/fileC", "dirC/novel.txt", "dirC/dirD", "dirC/dirD/fileD"]) _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"]) _check(p.rglob("**/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/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"]) @@ -1926,18 +2117,18 @@ def _check(path, glob, expected): _check(p, "*/fileB", ["dirB/fileB", "dirA/linkC/fileB", "linkB/fileB"]) _check(p, "file*", ["fileA", "dirA/linkC/fileB", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD", "linkB/fileB"]) - _check(p, "*/", ["dirA", "dirA/linkC", "dirA/linkC/linkD", "dirB", "dirB/linkD", - "dirC", "dirC/dirD", "dirE", "linkB", "linkB/linkD"]) - _check(p, "", ["", "dirA", "dirA/linkC", "dirA/linkC/linkD", "dirB", "dirB/linkD", - "dirC", "dirE", "dirC/dirD", "linkB", "linkB/linkD"]) + _check(p, "*/", ["dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/", + "dirC/", "dirC/dirD/", "dirE/", "linkB/", "linkB/linkD/"]) + _check(p, "", ["./", "dirA/", "dirA/linkC/", "dirA/linkC/linkD/", "dirB/", "dirB/linkD/", + "dirC/", "dirE/", "dirC/dirD/", "linkB/", "linkB/linkD/"]) p = P(BASE, "dirC") _check(p, "*", ["dirC/fileC", "dirC/novel.txt", "dirC/dirD", "dirC/dirD/fileD"]) _check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"]) _check(p, "*/*", ["dirC/dirD/fileD"]) - _check(p, "*/", ["dirC/dirD"]) - _check(p, "", ["dirC", "dirC/dirD"]) + _check(p, "*/", ["dirC/dirD/"]) + _check(p, "", ["dirC/", "dirC/dirD/"]) # gh-91616, a re module regression _check(p, "*.txt", ["dirC/novel.txt"]) _check(p, "*.*", ["dirC/novel.txt"]) @@ -1954,16 +2145,16 @@ def _check(path, glob, expected): _check(p, "*/fileA", []) _check(p, "*/fileB", ["dirB/fileB"]) _check(p, "file*", ["fileA", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD", ]) - _check(p, "*/", ["dirA", "dirB", "dirC", "dirC/dirD", "dirE"]) - _check(p, "", ["", "dirA", "dirB", "dirC", "dirE", "dirC/dirD"]) + _check(p, "*/", ["dirA/", "dirB/", "dirC/", "dirC/dirD/", "dirE/"]) + _check(p, "", ["./", "dirA/", "dirB/", "dirC/", "dirE/", "dirC/dirD/"]) p = P(BASE, "dirC") _check(p, "*", ["dirC/fileC", "dirC/novel.txt", "dirC/dirD", "dirC/dirD/fileD"]) _check(p, "file*", ["dirC/fileC", "dirC/dirD/fileD"]) _check(p, "*/*", ["dirC/dirD/fileD"]) - _check(p, "*/", ["dirC/dirD"]) - _check(p, "", ["dirC", "dirC/dirD"]) + _check(p, "*/", ["dirC/dirD/"]) + _check(p, "", ["dirC/", "dirC/dirD/"]) # gh-91616, a re module regression _check(p, "*.txt", ["dirC/novel.txt"]) _check(p, "*.*", ["dirC/novel.txt"]) @@ -1991,9 +2182,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: @@ -2053,7 +2246,7 @@ def test_glob_above_recursion_limit(self): # directory_depth > recursion_limit directory_depth = recursion_limit + 10 base = self.cls(BASE, 'deep') - path = self.cls(base, *(['d'] * directory_depth)) + path = base.joinpath(*(['d'] * directory_depth)) path.mkdir(parents=True) with set_recursion_limit(recursion_limit): @@ -2080,6 +2273,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() @@ -2128,7 +2322,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', @@ -2138,9 +2332,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') @@ -2150,7 +2342,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) @@ -2174,6 +2366,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() @@ -2382,6 +2606,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: @@ -2409,6 +2637,208 @@ def test_complex_symlinks_relative(self): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) + def setUpWalk(self): + # Build: + # TESTFN/ + # TEST1/ a file kid and two directory kids + # tmp1 + # SUB1/ a file kid and a directory kid + # tmp2 + # SUB11/ no kids + # SUB2/ a file kid and a dirsymlink kid + # tmp3 + # link/ a symlink to TEST2 + # broken_link + # broken_link2 + # TEST2/ + # tmp4 a lone file + self.walk_path = self.cls(BASE, "TEST1") + self.sub1_path = self.walk_path / "SUB1" + self.sub11_path = self.sub1_path / "SUB11" + self.sub2_path = self.walk_path / "SUB2" + tmp1_path = self.walk_path / "tmp1" + tmp2_path = self.sub1_path / "tmp2" + tmp3_path = self.sub2_path / "tmp3" + self.link_path = self.sub2_path / "link" + t2_path = self.cls(BASE, "TEST2") + tmp4_path = self.cls(BASE, "TEST2", "tmp4") + broken_link_path = self.sub2_path / "broken_link" + broken_link2_path = self.sub2_path / "broken_link2" + + self.sub11_path.mkdir(parents=True) + self.sub2_path.mkdir(parents=True) + t2_path.mkdir(parents=True) + + for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path: + with path.open("w", encoding='utf-8') as f: + f.write(f"I'm {path} and proud of it. Blame test_pathlib.\n") + + if self.can_symlink: + self.link_path.symlink_to(t2_path) + broken_link_path.symlink_to('broken') + broken_link2_path.symlink_to(self.cls('tmp3', 'broken')) + self.sub2_tree = (self.sub2_path, [], ["broken_link", "broken_link2", "link", "tmp3"]) + else: + self.sub2_tree = (self.sub2_path, [], ["tmp3"]) + + def test_walk_topdown(self): + self.setUpWalk() + walker = self.walk_path.walk() + entry = next(walker) + entry[1].sort() # Ensure we visit SUB1 before SUB2 + self.assertEqual(entry, (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) + entry = next(walker) + self.assertEqual(entry, (self.sub1_path, ["SUB11"], ["tmp2"])) + entry = next(walker) + self.assertEqual(entry, (self.sub11_path, [], [])) + entry = next(walker) + entry[1].sort() + entry[2].sort() + self.assertEqual(entry, self.sub2_tree) + with self.assertRaises(StopIteration): + next(walker) + + def test_walk_prune(self): + self.setUpWalk() + # Prune the search. + all = [] + for root, dirs, files in self.walk_path.walk(): + all.append((root, dirs, files)) + if 'SUB1' in dirs: + # Note that this also mutates the dirs we appended to all! + dirs.remove('SUB1') + + self.assertEqual(len(all), 2) + self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) + + all[1][-1].sort() + all[1][1].sort() + self.assertEqual(all[1], self.sub2_tree) + + def test_walk_bottom_up(self): + self.setUpWalk() + seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False + for path, dirnames, filenames in self.walk_path.walk(top_down=False): + if path == self.walk_path: + self.assertFalse(seen_testfn) + self.assertTrue(seen_sub1) + self.assertTrue(seen_sub2) + self.assertEqual(sorted(dirnames), ["SUB1", "SUB2"]) + self.assertEqual(filenames, ["tmp1"]) + seen_testfn = True + elif path == self.sub1_path: + self.assertFalse(seen_testfn) + self.assertFalse(seen_sub1) + self.assertTrue(seen_sub11) + self.assertEqual(dirnames, ["SUB11"]) + self.assertEqual(filenames, ["tmp2"]) + seen_sub1 = True + elif path == self.sub11_path: + self.assertFalse(seen_sub1) + self.assertFalse(seen_sub11) + self.assertEqual(dirnames, []) + self.assertEqual(filenames, []) + seen_sub11 = True + elif path == self.sub2_path: + self.assertFalse(seen_testfn) + self.assertFalse(seen_sub2) + self.assertEqual(sorted(dirnames), sorted(self.sub2_tree[1])) + self.assertEqual(sorted(filenames), sorted(self.sub2_tree[2])) + seen_sub2 = True + else: + raise AssertionError(f"Unexpected path: {path}") + self.assertTrue(seen_testfn) + + def test_walk_follow_symlinks(self): + if not self.can_symlink: + self.skipTest("symlinks required") + self.setUpWalk() + walk_it = self.walk_path.walk(follow_symlinks=True) + for root, dirs, files in walk_it: + if root == self.link_path: + self.assertEqual(dirs, []) + self.assertEqual(files, ["tmp4"]) + break + else: + self.fail("Didn't follow symlink with follow_symlinks=True") + + def test_walk_symlink_location(self): + if not self.can_symlink: + self.skipTest("symlinks required") + self.setUpWalk() + # Tests whether symlinks end up in filenames or dirnames depending + # on the `follow_symlinks` argument. + walk_it = self.walk_path.walk(follow_symlinks=False) + for root, dirs, files in walk_it: + if root == self.sub2_path: + self.assertIn("link", files) + break + else: + self.fail("symlink not found") + + walk_it = self.walk_path.walk(follow_symlinks=True) + for root, dirs, files in walk_it: + if root == self.sub2_path: + self.assertIn("link", dirs) + break + else: + self.fail("symlink not found") + + def test_walk_above_recursion_limit(self): + recursion_limit = 40 + # directory_depth > recursion_limit + directory_depth = recursion_limit + 10 + base = self.cls(BASE, 'deep') + path = base.joinpath(*(['d'] * directory_depth)) + path.mkdir(parents=True) + + with set_recursion_limit(recursion_limit): + list(base.walk()) + list(base.walk(top_down=False)) + +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, PurePathTest): + """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 @@ -2567,27 +2997,75 @@ def test_chmod_follow_symlinks_true(self): # XXX also need a test for lchmod. - @unittest.skipUnless(pwd, "the pwd module is needed for this test") - def test_owner(self): - p = self.cls(BASE) / 'fileA' - uid = p.stat().st_uid + def _get_pw_name_or_skip_test(self, uid): try: - name = pwd.getpwuid(uid).pw_name + return pwd.getpwuid(uid).pw_name except KeyError: self.skipTest( "user %d doesn't have an entry in the system database" % uid) - self.assertEqual(name, p.owner()) - @unittest.skipUnless(grp, "the grp module is needed for this test") - def test_group(self): + @unittest.skipUnless(pwd, "the pwd module is needed for this test") + def test_owner(self): p = self.cls(BASE) / 'fileA' - gid = p.stat().st_gid + expected_uid = p.stat().st_uid + expected_name = self._get_pw_name_or_skip_test(expected_uid) + + self.assertEqual(expected_name, p.owner()) + + @unittest.skipUnless(pwd, "the pwd module is needed for this test") + @unittest.skipUnless(root_in_posix, "test needs root privilege") + def test_owner_no_follow_symlinks(self): + all_users = [u.pw_uid for u in pwd.getpwall()] + if len(all_users) < 2: + self.skipTest("test needs more than one user") + + target = self.cls(BASE) / 'fileA' + link = self.cls(BASE) / 'linkA' + + uid_1, uid_2 = all_users[:2] + os.chown(target, uid_1, -1) + os.chown(link, uid_2, -1, follow_symlinks=False) + + expected_uid = link.stat(follow_symlinks=False).st_uid + expected_name = self._get_pw_name_or_skip_test(expected_uid) + + self.assertEqual(expected_uid, uid_2) + self.assertEqual(expected_name, link.owner(follow_symlinks=False)) + + def _get_gr_name_or_skip_test(self, gid): try: - name = grp.getgrgid(gid).gr_name + return grp.getgrgid(gid).gr_name except KeyError: self.skipTest( "group %d doesn't have an entry in the system database" % gid) - self.assertEqual(name, p.group()) + + @unittest.skipUnless(grp, "the grp module is needed for this test") + def test_group(self): + p = self.cls(BASE) / 'fileA' + expected_gid = p.stat().st_gid + expected_name = self._get_gr_name_or_skip_test(expected_gid) + + self.assertEqual(expected_name, p.group()) + + @unittest.skipUnless(grp, "the grp module is needed for this test") + @unittest.skipUnless(root_in_posix, "test needs root privilege") + def test_group_no_follow_symlinks(self): + all_groups = [g.gr_gid for g in grp.getgrall()] + if len(all_groups) < 2: + self.skipTest("test needs more than one group") + + target = self.cls(BASE) / 'fileA' + link = self.cls(BASE) / 'linkA' + + gid_1, gid_2 = all_groups[:2] + os.chown(target, -1, gid_1) + os.chown(link, -1, gid_2, follow_symlinks=False) + + expected_gid = link.stat(follow_symlinks=False).st_gid + expected_name = self._get_pw_name_or_skip_test(expected_gid) + + self.assertEqual(expected_gid, gid_2) + self.assertEqual(expected_name, link.group(follow_symlinks=False)) def test_unlink(self): p = self.cls(BASE) / 'fileA' @@ -2938,178 +3416,32 @@ def test_passing_kwargs_deprecated(self): with self.assertWarns(DeprecationWarning): self.cls(foo="bar") - -class WalkTests(unittest.TestCase): - - def setUp(self): - self.addCleanup(os_helper.rmtree, os_helper.TESTFN) - - # Build: - # TESTFN/ - # TEST1/ a file kid and two directory kids - # tmp1 - # SUB1/ a file kid and a directory kid - # tmp2 - # SUB11/ no kids - # SUB2/ a file kid and a dirsymlink kid - # tmp3 - # SUB21/ not readable - # tmp5 - # link/ a symlink to TEST2 - # broken_link - # broken_link2 - # broken_link3 - # TEST2/ - # tmp4 a lone file - self.walk_path = pathlib.Path(os_helper.TESTFN, "TEST1") - self.sub1_path = self.walk_path / "SUB1" - self.sub11_path = self.sub1_path / "SUB11" - self.sub2_path = self.walk_path / "SUB2" + def setUpWalk(self): + super().setUpWalk() sub21_path= self.sub2_path / "SUB21" - tmp1_path = self.walk_path / "tmp1" - tmp2_path = self.sub1_path / "tmp2" - tmp3_path = self.sub2_path / "tmp3" tmp5_path = sub21_path / "tmp3" - self.link_path = self.sub2_path / "link" - t2_path = pathlib.Path(os_helper.TESTFN, "TEST2") - tmp4_path = pathlib.Path(os_helper.TESTFN, "TEST2", "tmp4") - broken_link_path = self.sub2_path / "broken_link" - broken_link2_path = self.sub2_path / "broken_link2" broken_link3_path = self.sub2_path / "broken_link3" - os.makedirs(self.sub11_path) - os.makedirs(self.sub2_path) os.makedirs(sub21_path) - os.makedirs(t2_path) - - for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path, tmp5_path: - with open(path, "x", encoding='utf-8') as f: - f.write(f"I'm {path} and proud of it. Blame test_pathlib.\n") - - if os_helper.can_symlink(): - os.symlink(os.path.abspath(t2_path), self.link_path) - os.symlink('broken', broken_link_path, True) - os.symlink(pathlib.Path('tmp3', 'broken'), broken_link2_path, True) - os.symlink(pathlib.Path('SUB21', 'tmp5'), broken_link3_path, True) - self.sub2_tree = (self.sub2_path, ["SUB21"], - ["broken_link", "broken_link2", "broken_link3", - "link", "tmp3"]) - else: - self.sub2_tree = (self.sub2_path, ["SUB21"], ["tmp3"]) - + tmp5_path.write_text("I am tmp5, blame test_pathlib.") + if self.can_symlink: + os.symlink(tmp5_path, broken_link3_path) + self.sub2_tree[2].append('broken_link3') + self.sub2_tree[2].sort() if not is_emscripten: # Emscripten fails with inaccessible directories. os.chmod(sub21_path, 0) try: os.listdir(sub21_path) except PermissionError: - self.addCleanup(os.chmod, sub21_path, stat.S_IRWXU) + self.sub2_tree[1].append('SUB21') else: os.chmod(sub21_path, stat.S_IRWXU) os.unlink(tmp5_path) os.rmdir(sub21_path) - del self.sub2_tree[1][:1] - - def test_walk_topdown(self): - walker = self.walk_path.walk() - entry = next(walker) - entry[1].sort() # Ensure we visit SUB1 before SUB2 - self.assertEqual(entry, (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) - entry = next(walker) - self.assertEqual(entry, (self.sub1_path, ["SUB11"], ["tmp2"])) - entry = next(walker) - self.assertEqual(entry, (self.sub11_path, [], [])) - entry = next(walker) - entry[1].sort() - entry[2].sort() - self.assertEqual(entry, self.sub2_tree) - with self.assertRaises(StopIteration): - next(walker) - - def test_walk_prune(self, walk_path=None): - if walk_path is None: - walk_path = self.walk_path - # Prune the search. - all = [] - for root, dirs, files in walk_path.walk(): - all.append((root, dirs, files)) - if 'SUB1' in dirs: - # Note that this also mutates the dirs we appended to all! - dirs.remove('SUB1') - - self.assertEqual(len(all), 2) - self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) - - all[1][-1].sort() - all[1][1].sort() - self.assertEqual(all[1], self.sub2_tree) - - def test_file_like_path(self): - self.test_walk_prune(FakePath(self.walk_path).__fspath__()) - - def test_walk_bottom_up(self): - seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False - for path, dirnames, filenames in self.walk_path.walk(top_down=False): - if path == self.walk_path: - self.assertFalse(seen_testfn) - self.assertTrue(seen_sub1) - self.assertTrue(seen_sub2) - self.assertEqual(sorted(dirnames), ["SUB1", "SUB2"]) - self.assertEqual(filenames, ["tmp1"]) - seen_testfn = True - elif path == self.sub1_path: - self.assertFalse(seen_testfn) - self.assertFalse(seen_sub1) - self.assertTrue(seen_sub11) - self.assertEqual(dirnames, ["SUB11"]) - self.assertEqual(filenames, ["tmp2"]) - seen_sub1 = True - elif path == self.sub11_path: - self.assertFalse(seen_sub1) - self.assertFalse(seen_sub11) - self.assertEqual(dirnames, []) - self.assertEqual(filenames, []) - seen_sub11 = True - elif path == self.sub2_path: - self.assertFalse(seen_testfn) - self.assertFalse(seen_sub2) - self.assertEqual(sorted(dirnames), sorted(self.sub2_tree[1])) - self.assertEqual(sorted(filenames), sorted(self.sub2_tree[2])) - seen_sub2 = True - else: - raise AssertionError(f"Unexpected path: {path}") - self.assertTrue(seen_testfn) - - @os_helper.skip_unless_symlink - def test_walk_follow_symlinks(self): - walk_it = self.walk_path.walk(follow_symlinks=True) - for root, dirs, files in walk_it: - if root == self.link_path: - self.assertEqual(dirs, []) - self.assertEqual(files, ["tmp4"]) - break - else: - self.fail("Didn't follow symlink with follow_symlinks=True") - - @os_helper.skip_unless_symlink - def test_walk_symlink_location(self): - # Tests whether symlinks end up in filenames or dirnames depending - # on the `follow_symlinks` argument. - walk_it = self.walk_path.walk(follow_symlinks=False) - for root, dirs, files in walk_it: - if root == self.sub2_path: - self.assertIn("link", files) - break - else: - self.fail("symlink not found") - - walk_it = self.walk_path.walk(follow_symlinks=True) - for root, dirs, files in walk_it: - if root == self.sub2_path: - self.assertIn("link", dirs) - break def test_walk_bad_dir(self): + self.setUpWalk() errors = [] walk_it = self.walk_path.walk(on_error=errors.append) root, dirs, files = next(walk_it) @@ -3131,8 +3463,8 @@ def test_walk_bad_dir(self): def test_walk_many_open_files(self): depth = 30 - base = pathlib.Path(os_helper.TESTFN, 'deep') - path = pathlib.Path(base, *(['d']*depth)) + base = self.cls(BASE, 'deep') + path = self.cls(base, *(['d']*depth)) path.mkdir(parents=True) iters = [base.walk(top_down=False) for _ in range(100)] @@ -3150,21 +3482,9 @@ def test_walk_many_open_files(self): self.assertEqual(next(it), expected) path = path / 'd' - def test_walk_above_recursion_limit(self): - recursion_limit = 40 - # directory_depth > recursion_limit - directory_depth = recursion_limit + 10 - base = pathlib.Path(os_helper.TESTFN, 'deep') - path = pathlib.Path(base, *(['d'] * directory_depth)) - path.mkdir(parents=True) - - with set_recursion_limit(recursion_limit): - list(base.walk()) - list(base.walk(top_down=False)) - @only_posix -class PosixPathTest(PathTest): +class PosixPathTest(PathTest, PurePosixPathTest): cls = pathlib.PosixPath def test_absolute(self): @@ -3178,12 +3498,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): - path = self.cls(*args) - with self.assertRaises(OSError) as cm: - path.resolve(strict=True) - self.assertEqual(cm.exception.errno, errno.ELOOP) - @unittest.skipIf( is_emscripten or is_wasi, "umask is not implemented on Emscripten/WASI." @@ -3230,30 +3544,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 - p = self.cls(BASE, 'linkZ', 'foo') - self.assertEqual(p.resolve(strict=False), p) - # 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 - q = self.cls(BASE, 'linkW', 'foo') - self.assertEqual(q.resolve(strict=False), q) - def test_glob(self): P = self.cls p = P(BASE) @@ -3350,9 +3640,27 @@ 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): +class WindowsPathTest(PathTest, PureWindowsPathTest): cls = pathlib.WindowsPath def test_absolute(self): @@ -3404,7 +3712,7 @@ def test_glob(self): P = self.cls p = P(BASE) self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") }) - self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA") }) + self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA/") }) self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") }) self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\fileA"}) self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"}) @@ -3413,7 +3721,7 @@ def test_rglob(self): P = self.cls p = P(BASE, "dirC") self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") }) - self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD") }) + self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD/") }) self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\fileD"}) def test_expanduser(self): @@ -3469,6 +3777,41 @@ 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')) + + def test_owner(self): + P = self.cls + with self.assertRaises(pathlib.UnsupportedOperation): + P('c:/').owner() + + def test_group(self): + P = self.cls + with self.assertRaises(pathlib.UnsupportedOperation): + P('c:/').group() class PathSubclassTest(PathTest): diff --git a/Lib/test/test_patma.py b/Lib/test/test_patma.py index dedbc828784184..298e78ccee3875 100644 --- a/Lib/test/test_patma.py +++ b/Lib/test/test_patma.py @@ -2760,6 +2760,132 @@ def test_patma_255(self): self.assertEqual(y, 1) self.assertIs(z, x) + def test_patma_runtime_checkable_protocol(self): + # Runtime-checkable protocol + from typing import Protocol, runtime_checkable + + @runtime_checkable + class P(Protocol): + x: int + y: int + + class A: + def __init__(self, x: int, y: int): + self.x = x + self.y = y + + class B(A): ... + + for cls in (A, B): + with self.subTest(cls=cls.__name__): + inst = cls(1, 2) + w = 0 + match inst: + case P() as p: + self.assertIsInstance(p, cls) + self.assertEqual(p.x, 1) + self.assertEqual(p.y, 2) + w = 1 + self.assertEqual(w, 1) + + q = 0 + match inst: + case P(x=x, y=y): + self.assertEqual(x, 1) + self.assertEqual(y, 2) + q = 1 + self.assertEqual(q, 1) + + + def test_patma_generic_protocol(self): + # Runtime-checkable generic protocol + from typing import Generic, TypeVar, Protocol, runtime_checkable + + T = TypeVar('T') # not using PEP695 to be able to backport changes + + @runtime_checkable + class P(Protocol[T]): + a: T + b: T + + class A: + def __init__(self, x: int, y: int): + self.x = x + self.y = y + + class G(Generic[T]): + def __init__(self, x: T, y: T): + self.x = x + self.y = y + + for cls in (A, G): + with self.subTest(cls=cls.__name__): + inst = cls(1, 2) + w = 0 + match inst: + case P(): + w = 1 + self.assertEqual(w, 0) + + def test_patma_protocol_with_match_args(self): + # Runtime-checkable protocol with `__match_args__` + from typing import Protocol, runtime_checkable + + # Used to fail before + # /~https://github.com/python/cpython/issues/110682 + @runtime_checkable + class P(Protocol): + __match_args__ = ('x', 'y') + x: int + y: int + + class A: + def __init__(self, x: int, y: int): + self.x = x + self.y = y + + class B(A): ... + + for cls in (A, B): + with self.subTest(cls=cls.__name__): + inst = cls(1, 2) + w = 0 + match inst: + case P() as p: + self.assertIsInstance(p, cls) + self.assertEqual(p.x, 1) + self.assertEqual(p.y, 2) + w = 1 + self.assertEqual(w, 1) + + q = 0 + match inst: + case P(x=x, y=y): + self.assertEqual(x, 1) + self.assertEqual(y, 2) + q = 1 + self.assertEqual(q, 1) + + j = 0 + match inst: + case P(x=1, y=2): + j = 1 + self.assertEqual(j, 1) + + g = 0 + match inst: + case P(x, y): + self.assertEqual(x, 1) + self.assertEqual(y, 2) + g = 1 + self.assertEqual(g, 1) + + h = 0 + match inst: + case P(1, 2): + h = 1 + self.assertEqual(h, 1) + class TestSyntaxErrors(unittest.TestCase): @@ -3198,6 +3324,35 @@ def test_class_pattern_not_type(self): w = 0 self.assertIsNone(w) + def test_regular_protocol(self): + from typing import Protocol + class P(Protocol): ... + msg = ( + 'Instance and class checks can only be used ' + 'with @runtime_checkable protocols' + ) + w = None + with self.assertRaisesRegex(TypeError, msg): + match 1: + case P(): + w = 0 + self.assertIsNone(w) + + def test_positional_patterns_with_regular_protocol(self): + from typing import Protocol + class P(Protocol): + x: int # no `__match_args__` + y: int + class A: + x = 1 + y = 2 + w = None + with self.assertRaises(TypeError): + match A(): + case P(x, y): + w = 0 + self.assertIsNone(w) + class TestValueErrors(unittest.TestCase): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 8fed1d0f7162fd..d53fe3c611bc35 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -15,6 +15,8 @@ from io import StringIO from test import support from test.support import os_helper +from test.support.import_helper import import_module +from test.support.pty_helper import run_pty # This little helper class is essential for testing pdb under doctest. from test.test_doctest import _FakeInput from unittest.mock import patch @@ -671,6 +673,14 @@ def test_pdb_alias_command(): ... 'pi o', ... 's', ... 'ps', + ... 'alias myp p %2', + ... 'alias myp', + ... 'alias myp p %1', + ... 'myp', + ... 'myp 1', + ... 'myp 1 2', + ... 'alias repeat_second_arg p "%* %2"', + ... 'repeat_second_arg 1 2 3', ... 'continue', ... ]): ... test_function() @@ -692,6 +702,20 @@ def test_pdb_alias_command(): (Pdb) ps self.attr1 = 10 self.attr2 = str + (Pdb) alias myp p %2 + *** Replaceable parameters must be consecutive + (Pdb) alias myp + *** Unknown alias 'myp' + (Pdb) alias myp p %1 + (Pdb) myp + *** Not enough arguments for alias 'myp' + (Pdb) myp 1 + 1 + (Pdb) myp 1 2 + *** Too many arguments for alias 'myp' + (Pdb) alias repeat_second_arg p "%* %2" + (Pdb) repeat_second_arg 1 2 3 + '1 2 3 2' (Pdb) continue """ @@ -754,6 +778,59 @@ def test_pdb_where_command(): (Pdb) continue """ +def test_pdb_interact_command(): + """Test interact command + + >>> g = 0 + >>> dict_g = {} + + >>> def test_function(): + ... x = 1 + ... lst_local = [] + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... 'interact', + ... 'x', + ... 'g', + ... 'x = 2', + ... 'g = 3', + ... 'dict_g["a"] = True', + ... 'lst_local.append(x)', + ... 'exit()', + ... 'p x', + ... 'p g', + ... 'p dict_g', + ... 'p lst_local', + ... 'continue', + ... ]): + ... test_function() + --Return-- + > (4)test_function()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) interact + *pdb interact start* + ... x + 1 + ... g + 0 + ... x = 2 + ... g = 3 + ... dict_g["a"] = True + ... lst_local.append(x) + ... exit() + *exit from pdb interact command* + (Pdb) p x + 1 + (Pdb) p g + 0 + (Pdb) p dict_g + {'a': True} + (Pdb) p lst_local + [2] + (Pdb) continue + """ + def test_convenience_variables(): """Test convenience variables @@ -859,9 +936,11 @@ def test_post_mortem_chained(): >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE ... 'exceptions', ... 'exceptions 0', + ... '$_exception', ... 'up', ... 'down', ... 'exceptions 1', + ... '$_exception', ... 'up', ... 'down', ... 'exceptions -1', @@ -882,6 +961,8 @@ def test_post_mortem_chained(): (Pdb) exceptions 0 > (3)test_function_2() -> 1/0 + (Pdb) $_exception + ZeroDivisionError('division by zero') (Pdb) up > (3)test_function_reraise() -> test_function_2() @@ -891,6 +972,8 @@ def test_post_mortem_chained(): (Pdb) exceptions 1 > (5)test_function_reraise() -> raise ZeroDivisionError('reraised') from e + (Pdb) $_exception + ZeroDivisionError('reraised') (Pdb) up > (5)test_function() -> test_function_reraise() @@ -1510,7 +1593,7 @@ def test_next_until_return_at_return_event(): > (3)test_function() -> test_function_2() (Pdb) break test_function_2 - Breakpoint 1 at :1 + Breakpoint 1 at :2 (Pdb) continue > (2)test_function_2() -> x = 1 @@ -1932,7 +2015,7 @@ def test_pdb_next_command_in_generator_for_loop(): > (3)test_function() -> for i in test_gen(): (Pdb) break test_gen - Breakpoint 1 at :1 + Breakpoint 1 at :2 (Pdb) continue > (2)test_gen() -> yield 0 @@ -2321,6 +2404,31 @@ def test_pdb_issue_gh_108976(): (Pdb) continue """ + +def test_pdb_issue_gh_80731(): + """See GH-80731 + + pdb should correctly print exception info if in an except block. + + >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'import sys', + ... 'sys.exc_info()', + ... 'continue' + ... ]): + ... try: + ... raise ValueError('Correct') + ... except ValueError: + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... pass + > (10)() + -> pass + (Pdb) import sys + (Pdb) sys.exc_info() + (, ValueError('Correct'), ) + (Pdb) continue + """ + + def test_pdb_ambiguous_statements(): """See GH-104301 @@ -2344,6 +2452,119 @@ def test_pdb_ambiguous_statements(): (Pdb) continue """ +def test_pdb_f_trace_lines(): + """GH-80675 + + pdb should work even if f_trace_lines is set to False on some frames. + + >>> reset_Breakpoint() + + >>> def test_function(): + ... import sys + ... frame = sys._getframe() + ... frame.f_trace_lines = False + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... if frame.f_trace_lines != False: + ... print("f_trace_lines is not reset after continue!") + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'continue' + ... ]): + ... test_function() + > (6)test_function() + -> if frame.f_trace_lines != False: + (Pdb) continue + """ + +def test_pdb_function_break(): + """Testing the line number of break on function + + >>> def foo(): pass + + >>> def bar(): + ... + ... pass + + >>> def boo(): + ... # comments + ... global x + ... x = 1 + + >>> def gen(): + ... yield 42 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... pass + + >>> with PdbTestInput([ # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE + ... 'break foo', + ... 'break bar', + ... 'break boo', + ... 'break gen', + ... 'continue' + ... ]): + ... test_function() + > (3)test_function() + -> pass + (Pdb) break foo + Breakpoint ... at :1 + (Pdb) break bar + Breakpoint ... at :3 + (Pdb) break boo + Breakpoint ... at :4 + (Pdb) break gen + Breakpoint ... at :2 + (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): @@ -2352,15 +2573,21 @@ def tearDown(self): @unittest.skipIf(sys.flags.safe_path, 'PYTHONSAFEPATH changes default sys.path') - def _run_pdb(self, pdb_args, commands, expected_returncode=0): + def _run_pdb(self, pdb_args, commands, + expected_returncode=0, + extra_env=None): self.addCleanup(os_helper.rmtree, '__pycache__') cmd = [sys.executable, '-m', 'pdb'] + pdb_args + if extra_env is not None: + env = os.environ | extra_env + else: + env = os.environ with subprocess.Popen( cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, - env = {**os.environ, 'PYTHONIOENCODING': 'utf-8'} + env = {**env, 'PYTHONIOENCODING': 'utf-8'} ) as proc: stdout, stderr = proc.communicate(str.encode(commands)) stdout = stdout and bytes.decode(stdout) @@ -2372,13 +2599,15 @@ def _run_pdb(self, pdb_args, commands, expected_returncode=0): ) return stdout, stderr - def run_pdb_script(self, script, commands, expected_returncode=0): + def run_pdb_script(self, script, commands, + expected_returncode=0, + extra_env=None): """Run 'script' lines with pdb and the pdb 'commands'.""" filename = 'main.py' with open(filename, 'w') as f: f.write(textwrap.dedent(script)) self.addCleanup(os_helper.unlink, filename) - return self._run_pdb([filename], commands, expected_returncode) + return self._run_pdb([filename], commands, expected_returncode, extra_env) def run_pdb_module(self, script, commands): """Runs the script code as part of a module""" @@ -2585,13 +2814,28 @@ def test_issue16180(self): commands = '' expected = "SyntaxError:" stdout, stderr = self.run_pdb_script( - script, commands, expected_returncode=1 + script, commands ) self.assertIn(expected, stdout, '\n\nExpected:\n{}\nGot:\n{}\n' 'Fail to handle a syntax error in the debuggee.' .format(expected, stdout)) + def test_issue84583(self): + # A syntax error from ast.literal_eval should not make pdb exit. + script = "import ast; ast.literal_eval('')\n" + commands = """ + continue + where + quit + """ + stdout, stderr = self.run_pdb_script(script, commands) + # The code should appear 3 times in the stdout: + # 1. when pdb starts + # 2. when the exception is raised, in trackback + # 3. in where command + self.assertEqual(stdout.count("ast.literal_eval('')"), 3) + def test_issue26053(self): # run command of pdb prompt echoes the correct args script = "print('hello')" @@ -2752,8 +2996,7 @@ def test_module_without_a_main(self): stdout, stderr = self._run_pdb( ['-m', module_name], "", expected_returncode=1 ) - self.assertIn("ImportError: No module named t_main.__main__", - stdout.splitlines()) + self.assertIn("ImportError: No module named t_main.__main__;", stdout) def test_package_without_a_main(self): pkg_name = 't_pkg' @@ -2771,6 +3014,22 @@ def test_package_without_a_main(self): "'t_pkg.t_main' is a package and cannot be directly executed", stdout) + def test_nonexistent_module(self): + assert not os.path.exists(os_helper.TESTFN) + stdout, stderr = self._run_pdb(["-m", os_helper.TESTFN], "", expected_returncode=1) + self.assertIn(f"ImportError: No module named {os_helper.TESTFN}", stdout) + + def test_dir_as_script(self): + with os_helper.temp_dir() as temp_dir: + stdout, stderr = self._run_pdb([temp_dir], "", expected_returncode=1) + self.assertIn(f"Error: {temp_dir} is a directory", stdout) + + def test_invalid_cmd_line_options(self): + stdout, stderr = self._run_pdb(["-c"], "", expected_returncode=2) + self.assertIn(f"pdb: error: argument -c/--command: expected one argument", stdout.split('\n')[1]) + stdout, stderr = self._run_pdb(["--spam", "-m", "pdb"], "", expected_returncode=2) + self.assertIn(f"pdb: error: unrecognized arguments: --spam", stdout.split('\n')[1]) + def test_blocks_at_first_code_line(self): script = """ #This is a comment, on line 2 @@ -2933,6 +3192,23 @@ def test_issue42384_symlink(self): self.assertEqual(stdout.split('\n')[2].rstrip('\r'), expected) + def test_safe_path(self): + """ With safe_path set, pdb should not mangle sys.path[0]""" + + script = textwrap.dedent(""" + import sys + import random + print('sys.path[0] is', sys.path[0]) + """) + commands = 'c\n' + + + with os_helper.temp_cwd() as cwd: + stdout, _ = self.run_pdb_script(script, commands, extra_env={'PYTHONSAFEPATH': '1'}) + + unexpected = f'sys.path[0] is {os.path.realpath(cwd)}' + self.assertNotIn(unexpected, stdout) + def test_issue42383(self): with os_helper.temp_cwd() as cwd: with open('foo.py', 'w') as f: @@ -3064,6 +3340,55 @@ def test_checkline_is_not_executable(self): self.assertFalse(db.checkline(os_helper.TESTFN, lineno)) +@support.requires_subprocess() +class PdbTestReadline(unittest.TestCase): + def setUpClass(): + # Ensure that the readline module is loaded + # If this fails, the test is skipped because SkipTest will be raised + readline = import_module('readline') + if readline.backend == "editline": + raise unittest.SkipTest("libedit readline is not supported for pdb") + + def test_basic_completion(self): + script = textwrap.dedent(""" + import pdb; pdb.Pdb().set_trace() + # Concatenate strings so that the output doesn't appear in the source + print('hello' + '!') + """) + + # List everything starting with 'co', there should be multiple matches + # then add ntin and complete 'contin' to 'continue' + input = b"co\t\tntin\t\n" + + output = run_pty(script, input) + + self.assertIn(b'commands', output) + self.assertIn(b'condition', output) + self.assertIn(b'continue', output) + self.assertIn(b'hello!', output) + + def test_expression_completion(self): + script = textwrap.dedent(""" + value = "speci" + import pdb; pdb.Pdb().set_trace() + """) + + # Complete: value + 'al' + input = b"val\t + 'al'\n" + # Complete: p value + 'es' + input += b"p val\t + 'es'\n" + # Complete: $_frame + input += b"$_fra\t\n" + # Continue + input += b"c\n" + + output = run_pty(script, input) + + self.assertIn(b'special', output) + self.assertIn(b'species', output) + self.assertIn(b'$_frame', output) + + def load_tests(loader, tests, pattern): from test import test_pdb tests.addTest(doctest.DocTestSuite(test_pdb)) diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py index fe8707a156e9dc..040be63da11447 100644 --- a/Lib/test/test_perf_profiler.py +++ b/Lib/test/test_perf_profiler.py @@ -353,6 +353,82 @@ def baz(n): self.assertNotIn(f"py::bar:{script}", stdout) self.assertNotIn(f"py::baz:{script}", stdout) + def test_pre_fork_compile(self): + code = """if 1: + import sys + import os + import sysconfig + from _testinternalcapi import ( + compile_perf_trampoline_entry, + perf_trampoline_set_persist_after_fork, + ) + + def foo_fork(): + pass + + def bar_fork(): + foo_fork() + + def foo(): + pass + + def bar(): + foo() + + def compile_trampolines_for_all_functions(): + perf_trampoline_set_persist_after_fork(1) + for _, obj in globals().items(): + if callable(obj) and hasattr(obj, '__code__'): + compile_perf_trampoline_entry(obj.__code__) + + if __name__ == "__main__": + compile_trampolines_for_all_functions() + pid = os.fork() + if pid == 0: + print(os.getpid()) + bar_fork() + else: + bar() + """ + + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + universal_newlines=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(process.returncode, 0) + self.assertNotIn("Error:", stderr) + child_pid = int(stdout.strip()) + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + perf_child_file = pathlib.Path(f"/tmp/perf-{child_pid}.map") + self.assertTrue(perf_file.exists()) + self.assertTrue(perf_child_file.exists()) + + perf_file_contents = perf_file.read_text() + self.assertIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::foo_fork:{script}", perf_file_contents) + self.assertIn(f"py::bar_fork:{script}", perf_file_contents) + + child_perf_file_contents = perf_child_file.read_text() + self.assertIn(f"py::foo_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::bar_fork:{script}", child_perf_file_contents) + + # Pre-compiled perf-map entries of a forked process must be + # identical in both the parent and child perf-map files. + perf_file_lines = perf_file_contents.split("\n") + for line in perf_file_lines: + if ( + f"py::foo_fork:{script}" in line + or f"py::bar_fork:{script}" in line + ): + self.assertIn(line, child_perf_file_contents) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 444f8abe4607b7..1722c84727bbd8 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -6,9 +6,6 @@ from test.support import warnings_helper from test.support.script_helper import assert_python_ok -# Skip these tests if there is no posix module. -posix = import_helper.import_module('posix') - import errno import sys import signal @@ -22,6 +19,11 @@ import textwrap from contextlib import contextmanager +try: + import posix +except ImportError: + import nt as posix + try: import pwd except ImportError: @@ -1012,16 +1014,17 @@ def test_environ(self): def test_putenv(self): with self.assertRaises(ValueError): os.putenv('FRUIT\0VEGETABLE', 'cabbage') - with self.assertRaises(ValueError): - os.putenv(b'FRUIT\0VEGETABLE', b'cabbage') with self.assertRaises(ValueError): os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage') - with self.assertRaises(ValueError): - os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage') with self.assertRaises(ValueError): os.putenv('FRUIT=ORANGE', 'lemon') - with self.assertRaises(ValueError): - os.putenv(b'FRUIT=ORANGE', b'lemon') + if os.name == 'posix': + with self.assertRaises(ValueError): + os.putenv(b'FRUIT\0VEGETABLE', b'cabbage') + with self.assertRaises(ValueError): + os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage') + with self.assertRaises(ValueError): + os.putenv(b'FRUIT=ORANGE', b'lemon') @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()') def test_getcwd_long_pathnames(self): @@ -1205,6 +1208,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() @@ -1219,6 +1223,7 @@ def test_sched_setaffinity(self): self.assertRaises(OSError, posix.sched_setaffinity, -1, mask) @unittest.skipIf(support.is_wasi, "No dynamic linking on WASI") + @unittest.skipUnless(os.name == 'posix', "POSIX-only test") def test_rtld_constants(self): # check presence of major RTLD_* constants posix.RTLD_LAZY diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 9be4640f970aef..86ce1b1d41ba61 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -47,18 +47,26 @@ def tearDown(self): safe_rmdir(os_helper.TESTFN + suffix) def test_join(self): - self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"), - "/bar/baz") - self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz") - self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"), - "/foo/bar/baz/") - - self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"), - b"/bar/baz") - self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"), - b"/foo/bar/baz") - self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"), - b"/foo/bar/baz/") + fn = posixpath.join + self.assertEqual(fn("/foo", "bar", "/bar", "baz"), "/bar/baz") + self.assertEqual(fn("/foo", "bar", "baz"), "/foo/bar/baz") + self.assertEqual(fn("/foo/", "bar/", "baz/"), "/foo/bar/baz/") + + self.assertEqual(fn(b"/foo", b"bar", b"/bar", b"baz"), b"/bar/baz") + self.assertEqual(fn(b"/foo", b"bar", b"baz"), b"/foo/bar/baz") + self.assertEqual(fn(b"/foo/", b"bar/", b"baz/"), b"/foo/bar/baz/") + + self.assertEqual(fn("a", "b"), "a/b") + self.assertEqual(fn("a", "b/"), "a/b/") + self.assertEqual(fn("a/", "b"), "a/b") + self.assertEqual(fn("a/", "b/"), "a/b/") + self.assertEqual(fn("a", "b/c", "d"), "a/b/c/d") + self.assertEqual(fn("a", "b//c", "d"), "a/b//c/d") + self.assertEqual(fn("a", "b/c/", "d"), "a/b/c/d") + self.assertEqual(fn("/a", "b"), "/a/b") + self.assertEqual(fn("/a/", "b"), "/a/b") + self.assertEqual(fn("a", "/b", "c"), "/b/c") + self.assertEqual(fn("a", "/b", "/c"), "/c") def test_split(self): self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar")) diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 6ea7e7db2ce113..4e6fed1ab969ac 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -7,8 +7,8 @@ import itertools import pprint import random +import re import test.support -import test.test_set import types import unittest @@ -535,7 +535,10 @@ def test_dataclass_with_repr(self): def test_dataclass_no_repr(self): dc = dataclass3() formatted = pprint.pformat(dc, width=10) - self.assertRegex(formatted, r"") + self.assertRegex( + formatted, + fr"<{re.escape(__name__)}.dataclass3 object at \w+>", + ) def test_recursive_dataclass(self): dc = dataclass4(None) @@ -619,9 +622,6 @@ def test_set_reprs(self): self.assertEqual(pprint.pformat(frozenset3(range(7)), width=20), 'frozenset3({0, 1, 2, 3, 4, 5, 6})') - @unittest.expectedFailure - #See http://bugs.python.org/issue13907 - @test.support.cpython_only def test_set_of_sets_reprs(self): # This test creates a complex arrangement of frozensets and # compares the pretty-printed repr against a string hard-coded in @@ -632,204 +632,106 @@ def test_set_of_sets_reprs(self): # partial ordering (subset relationships), the output of the # list.sort() method is undefined for lists of sets." # - # In a nutshell, the test assumes frozenset({0}) will always - # sort before frozenset({1}), but: - # # >>> frozenset({0}) < frozenset({1}) # False # >>> frozenset({1}) < frozenset({0}) # False # - # Consequently, this test is fragile and - # implementation-dependent. Small changes to Python's sort - # algorithm cause the test to fail when it should pass. - # XXX Or changes to the dictionary implementation... - - cube_repr_tgt = """\ -{frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}), - frozenset({0}): frozenset({frozenset(), - frozenset({0, 2}), - frozenset({0, 1})}), - frozenset({1}): frozenset({frozenset(), - frozenset({1, 2}), - frozenset({0, 1})}), - frozenset({2}): frozenset({frozenset(), - frozenset({1, 2}), - frozenset({0, 2})}), - frozenset({1, 2}): frozenset({frozenset({2}), - frozenset({1}), - frozenset({0, 1, 2})}), - frozenset({0, 2}): frozenset({frozenset({2}), - frozenset({0}), - frozenset({0, 1, 2})}), - frozenset({0, 1}): frozenset({frozenset({0}), - frozenset({1}), - frozenset({0, 1, 2})}), - frozenset({0, 1, 2}): frozenset({frozenset({1, 2}), - frozenset({0, 2}), - frozenset({0, 1})})}""" - cube = test.test_set.cube(3) - self.assertEqual(pprint.pformat(cube), cube_repr_tgt) - cubo_repr_tgt = """\ -{frozenset({frozenset({0, 2}), frozenset({0})}): frozenset({frozenset({frozenset({0, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0}), - frozenset({0, - 1})}), - frozenset({frozenset(), - frozenset({0})}), - frozenset({frozenset({2}), - frozenset({0, - 2})})}), - frozenset({frozenset({0, 1}), frozenset({1})}): frozenset({frozenset({frozenset({0, - 1}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0}), - frozenset({0, - 1})}), - frozenset({frozenset({1}), - frozenset({1, - 2})}), - frozenset({frozenset(), - frozenset({1})})}), - frozenset({frozenset({1, 2}), frozenset({1})}): frozenset({frozenset({frozenset({1, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({2}), - frozenset({1, - 2})}), - frozenset({frozenset(), - frozenset({1})}), - frozenset({frozenset({1}), - frozenset({0, - 1})})}), - frozenset({frozenset({1, 2}), frozenset({2})}): frozenset({frozenset({frozenset({1, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({1}), - frozenset({1, - 2})}), - frozenset({frozenset({2}), - frozenset({0, - 2})}), - frozenset({frozenset(), - frozenset({2})})}), - frozenset({frozenset(), frozenset({0})}): frozenset({frozenset({frozenset({0}), - frozenset({0, - 1})}), - frozenset({frozenset({0}), - frozenset({0, - 2})}), - frozenset({frozenset(), - frozenset({1})}), - frozenset({frozenset(), - frozenset({2})})}), - frozenset({frozenset(), frozenset({1})}): frozenset({frozenset({frozenset(), - frozenset({0})}), - frozenset({frozenset({1}), - frozenset({1, - 2})}), - frozenset({frozenset(), - frozenset({2})}), - frozenset({frozenset({1}), - frozenset({0, - 1})})}), - frozenset({frozenset({2}), frozenset()}): frozenset({frozenset({frozenset({2}), - frozenset({1, - 2})}), - frozenset({frozenset(), - frozenset({0})}), - frozenset({frozenset(), - frozenset({1})}), - frozenset({frozenset({2}), - frozenset({0, - 2})})}), - frozenset({frozenset({0, 1, 2}), frozenset({0, 1})}): frozenset({frozenset({frozenset({1, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0}), - frozenset({0, - 1})}), - frozenset({frozenset({1}), - frozenset({0, - 1})})}), - frozenset({frozenset({0}), frozenset({0, 1})}): frozenset({frozenset({frozenset(), - frozenset({0})}), - frozenset({frozenset({0, - 1}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0}), - frozenset({0, - 2})}), - frozenset({frozenset({1}), - frozenset({0, - 1})})}), - frozenset({frozenset({2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({0, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({2}), - frozenset({1, - 2})}), - frozenset({frozenset({0}), - frozenset({0, - 2})}), - frozenset({frozenset(), - frozenset({2})})}), - frozenset({frozenset({0, 1, 2}), frozenset({0, 2})}): frozenset({frozenset({frozenset({1, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0, - 1}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0}), - frozenset({0, - 2})}), - frozenset({frozenset({2}), - frozenset({0, - 2})})}), - frozenset({frozenset({1, 2}), frozenset({0, 1, 2})}): frozenset({frozenset({frozenset({0, - 2}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({0, - 1}), - frozenset({0, - 1, - 2})}), - frozenset({frozenset({2}), - frozenset({1, - 2})}), - frozenset({frozenset({1}), - frozenset({1, - 2})})})}""" - - cubo = test.test_set.linegraph(cube) - self.assertEqual(pprint.pformat(cubo), cubo_repr_tgt) + # In this test we list all possible invariants of the result + # for unordered frozensets. + # + # This test has a long history, see: + # - /~https://github.com/python/cpython/commit/969fe57baa0eb80332990f9cda936a33e13fabef + # - /~https://github.com/python/cpython/issues/58115 + # - /~https://github.com/python/cpython/issues/111147 + + import textwrap + + # Single-line, always ordered: + fs0 = frozenset() + fs1 = frozenset(('abc', 'xyz')) + data = frozenset((fs0, fs1)) + self.assertEqual(pprint.pformat(data), + 'frozenset({%r, %r})' % (fs0, fs1)) + self.assertEqual(pprint.pformat(data), repr(data)) + + fs2 = frozenset(('one', 'two')) + data = {fs2: frozenset((fs0, fs1))} + self.assertEqual(pprint.pformat(data), + "{%r: frozenset({%r, %r})}" % (fs2, fs0, fs1)) + self.assertEqual(pprint.pformat(data), repr(data)) + + # Single-line, unordered: + fs1 = frozenset(("xyz", "qwerty")) + fs2 = frozenset(("abcd", "spam")) + fs = frozenset((fs1, fs2)) + self.assertEqual(pprint.pformat(fs), repr(fs)) + + # Multiline, unordered: + def check(res, invariants): + self.assertIn(res, [textwrap.dedent(i).strip() for i in invariants]) + + # Inner-most frozensets are singleline, result is multiline, unordered: + fs1 = frozenset(('regular string', 'other string')) + fs2 = frozenset(('third string', 'one more string')) + check( + pprint.pformat(frozenset((fs1, fs2))), + [ + """ + frozenset({%r, + %r}) + """ % (fs1, fs2), + """ + frozenset({%r, + %r}) + """ % (fs2, fs1), + ], + ) + + # Everything is multiline, unordered: + check( + pprint.pformat( + frozenset(( + frozenset(( + "xyz very-very long string", + "qwerty is also absurdly long", + )), + frozenset(( + "abcd is even longer that before", + "spam is not so long", + )), + )), + ), + [ + """ + frozenset({frozenset({'abcd is even longer that before', + 'spam is not so long'}), + frozenset({'qwerty is also absurdly long', + 'xyz very-very long string'})}) + """, + + """ + frozenset({frozenset({'abcd is even longer that before', + 'spam is not so long'}), + frozenset({'xyz very-very long string', + 'qwerty is also absurdly long'})}) + """, + + """ + frozenset({frozenset({'qwerty is also absurdly long', + 'xyz very-very long string'}), + frozenset({'abcd is even longer that before', + 'spam is not so long'})}) + """, + + """ + frozenset({frozenset({'qwerty is also absurdly long', + 'xyz very-very long string'}), + frozenset({'spam is not so long', + 'abcd is even longer that before'})}) + """, + ], + ) def test_depth(self): nested_tuple = (1, (2, (3, (4, (5, 6))))) diff --git a/Lib/test/test_property.py b/Lib/test/test_property.py index 45aa9e51c06de0..c12c908d2ee32d 100644 --- a/Lib/test/test_property.py +++ b/Lib/test/test_property.py @@ -183,27 +183,6 @@ def test_refleaks_in___init__(self): fake_prop.__init__('fget', 'fset', 'fdel', 'doc') self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_class_property(self): - class A: - @classmethod - @property - def __doc__(cls): - return 'A doc for %r' % cls.__name__ - self.assertEqual(A.__doc__, "A doc for 'A'") - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_class_property_override(self): - class A: - """First""" - @classmethod - @property - def __doc__(cls): - return 'Second' - self.assertEqual(A.__doc__, 'Second') - def test_property_set_name_incorrect_args(self): p = property() diff --git a/Lib/test/test_pstats.py b/Lib/test/test_pstats.py index acc2fa5385d923..d5a5a9738c2498 100644 --- a/Lib/test/test_pstats.py +++ b/Lib/test/test_pstats.py @@ -5,7 +5,9 @@ from pstats import SortKey from enum import StrEnum, _test_simple_enum +import os import pstats +import tempfile import cProfile class AddCallersTestCase(unittest.TestCase): @@ -36,6 +38,33 @@ def test_add(self): stats = pstats.Stats(stream=stream) stats.add(self.stats, self.stats) + def test_dump_and_load_works_correctly(self): + temp_storage_new = tempfile.NamedTemporaryFile(delete=False) + try: + self.stats.dump_stats(filename=temp_storage_new.name) + tmp_stats = pstats.Stats(temp_storage_new.name) + self.assertEqual(self.stats.stats, tmp_stats.stats) + finally: + temp_storage_new.close() + os.remove(temp_storage_new.name) + + def test_load_equivalent_to_init(self): + stats = pstats.Stats() + self.temp_storage = tempfile.NamedTemporaryFile(delete=False) + try: + cProfile.run('import os', filename=self.temp_storage.name) + stats.load_stats(self.temp_storage.name) + created = pstats.Stats(self.temp_storage.name) + self.assertEqual(stats.stats, created.stats) + finally: + self.temp_storage.close() + os.remove(self.temp_storage.name) + + def test_loading_wrong_types(self): + stats = pstats.Stats() + with self.assertRaises(TypeError): + stats.load_stats(42) + def test_sort_stats_int(self): valid_args = {-1: 'stdname', 0: 'calls', diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index a971f6b0250efb..f31a68c5d84e03 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -76,6 +76,15 @@ 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): @@ -170,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)) @@ -360,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_pydoc.py b/Lib/test/test_pydoc.py index 70c5ebd694ca88..eb50510e12b7b6 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -43,8 +43,8 @@ class nonascii: if test.support.HAVE_DOCSTRINGS: expected_data_docstrings = ( - 'dictionary for instance variables (if defined)', - 'list of weak references to the object (if defined)', + 'dictionary for instance variables', + 'list of weak references to the object', ) * 2 else: expected_data_docstrings = ('', '', '', '') @@ -108,10 +108,10 @@ class C(builtins.object) | Data descriptors defined here: | | __dict__ - | dictionary for instance variables (if defined) + | dictionary for instance variables | | __weakref__ - | list of weak references to the object (if defined) + | list of weak references to the object FUNCTIONS doc_func() @@ -169,16 +169,16 @@ class A(builtins.object) Data descriptors defined here: __dict__ - dictionary for instance variables (if defined) + dictionary for instance variables __weakref__ - list of weak references to the object (if defined) + list of weak references to the object class B(builtins.object) Data descriptors defined here: __dict__ - dictionary for instance variables (if defined) + dictionary for instance variables __weakref__ - list of weak references to the object (if defined) + list of weak references to the object Data and other attributes defined here: NO_MEANING = 'eggs' __annotations__ = {'NO_MEANING': } @@ -195,9 +195,9 @@ class C(builtins.object) __class_getitem__(item) from builtins.type Data descriptors defined here: __dict__ - dictionary for instance variables (if defined) + dictionary for instance variables __weakref__ - list of weak references to the object (if defined) + list of weak references to the object Functions doc_func() @@ -829,10 +829,10 @@ class B(A) | Data descriptors inherited from A: | | __dict__ - | dictionary for instance variables (if defined) + | dictionary for instance variables | | __weakref__ - | list of weak references to the object (if defined) + | list of weak references to the object ''' % __name__) doc = pydoc.render_doc(B, renderer=pydoc.HTMLDoc()) @@ -861,15 +861,104 @@ class B(A) Data descriptors inherited from A: __dict__ - dictionary for instance variables (if defined) + dictionary for instance variables __weakref__ - list of weak references to the object (if defined) + list of weak references to the object """ as_text = html2text(doc) expected_lines = [line.strip() for line in expected_text.split("\n") if line] for expected_line in expected_lines: self.assertIn(expected_line, as_text) + def test_long_signatures(self): + from collections.abc import Callable + from typing import Literal, Annotated + + class A: + def __init__(self, + arg1: Callable[[int, int, int], str], + arg2: Literal['some value', 'other value'], + arg3: Annotated[int, 'some docs about this type'], + ) -> None: + ... + + doc = pydoc.render_doc(A) + # clean up the extra text formatting that pydoc performs + doc = re.sub('\b.', '', doc) + self.assertEqual(doc, '''Python Library Documentation: class A in module %s + +class A(builtins.object) + | A( + | arg1: collections.abc.Callable[[int, int, int], str], + | arg2: Literal['some value', 'other value'], + | arg3: Annotated[int, 'some docs about this type'] + | ) -> None + | + | Methods defined here: + | + | __init__( + | self, + | arg1: collections.abc.Callable[[int, int, int], str], + | arg2: Literal['some value', 'other value'], + | arg3: Annotated[int, 'some docs about this type'] + | ) -> None + | + | ---------------------------------------------------------------------- + | Data descriptors defined here: + | + | __dict__ + | dictionary for instance variables + | + | __weakref__ + | list of weak references to the object +''' % __name__) + + def func( + arg1: Callable[[Annotated[int, 'Some doc']], str], + arg2: Literal[1, 2, 3, 4, 5, 6, 7, 8], + ) -> Annotated[int, 'Some other']: + ... + + doc = pydoc.render_doc(func) + # clean up the extra text formatting that pydoc performs + doc = re.sub('\b.', '', doc) + self.assertEqual(doc, '''Python Library Documentation: function func in module %s + +func( + arg1: collections.abc.Callable[[typing.Annotated[int, 'Some doc']], str], + arg2: Literal[1, 2, 3, 4, 5, 6, 7, 8] +) -> Annotated[int, 'Some other'] +''' % __name__) + + def function_with_really_long_name_so_annotations_can_be_rather_small( + arg1: int, + arg2: str, + ): + ... + + doc = pydoc.render_doc(function_with_really_long_name_so_annotations_can_be_rather_small) + # clean up the extra text formatting that pydoc performs + doc = re.sub('\b.', '', doc) + self.assertEqual(doc, '''Python Library Documentation: function function_with_really_long_name_so_annotations_can_be_rather_small in module %s + +function_with_really_long_name_so_annotations_can_be_rather_small( + arg1: int, + arg2: str +) +''' % __name__) + + does_not_have_name = lambda \ + very_long_parameter_name_that_should_not_fit_into_a_single_line, \ + second_very_long_parameter_name: ... + + doc = pydoc.render_doc(does_not_have_name) + # clean up the extra text formatting that pydoc performs + doc = re.sub('\b.', '', doc) + self.assertEqual(doc, '''Python Library Documentation: function in module %s + + lambda very_long_parameter_name_that_should_not_fit_into_a_single_line, second_very_long_parameter_name +''' % __name__) + def test__future__imports(self): # __future__ features are excluded from module help, # except when it's the __future__ module itself diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index a542abaf1f35aa..d941a1a8f9ebc6 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -544,7 +544,7 @@ def handler(text): parser = expat.ParserCreate() parser.CharacterDataHandler = handler - self.assertRaises(Exception, parser.Parse, xml.encode('iso8859')) + self.assertRaises(SpecificException, parser.Parse, xml.encode('iso8859')) class ChardataBufferTest(unittest.TestCase): """ diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 5936d7535edd5f..6d26a61bee4292 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -185,6 +185,20 @@ def test_class_cause(self): else: self.fail("No exception raised") + def test_class_cause_nonexception_result(self): + class ConstructsNone(BaseException): + @classmethod + def __new__(*args, **kwargs): + return None + try: + raise IndexError from ConstructsNone + except TypeError as e: + self.assertIn("should have returned an instance of BaseException", str(e)) + except IndexError: + self.fail("Wrong kind of exception raised") + else: + self.fail("No exception raised") + def test_instance_cause(self): cause = KeyError() try: diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 50bea7be6d54c7..b1e4ef4197d130 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -1081,6 +1081,7 @@ def test_binomialvariate(self): B(n=1, p=-0.5) # Negative p with self.assertRaises(ValueError): B(n=1, p=1.5) # p > 1.0 + self.assertEqual(B(0, 0.5), 0) # n == 0 self.assertEqual(B(10, 0.0), 0) # p == 0.0 self.assertEqual(B(10, 1.0), 10) # p == 1.0 self.assertTrue(B(1, 0.3) in {0, 1}) # n == 1 fast path @@ -1088,6 +1089,9 @@ def test_binomialvariate(self): self.assertTrue(B(1, 0.0) in {0}) # n == 1 fast path self.assertTrue(B(1, 1.0) in {1}) # n == 1 fast path + # BG method very small p + self.assertEqual(B(5, 1e-18), 0) + # BG method p <= 0.5 and n*p=1.25 self.assertTrue(B(5, 0.25) in set(range(6))) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 45bce1925f9e89..993a7d6e264a1f 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -47,7 +47,7 @@ def recurse(actual, expect): recurse(actual, expect) def checkPatternError(self, pattern, errmsg, pos=None): - with self.assertRaises(re.error) as cm: + with self.assertRaises(re.PatternError) as cm: re.compile(pattern) with self.subTest(pattern=pattern): err = cm.exception @@ -56,7 +56,7 @@ def checkPatternError(self, pattern, errmsg, pos=None): self.assertEqual(err.pos, pos) def checkTemplateError(self, pattern, repl, string, errmsg, pos=None): - with self.assertRaises(re.error) as cm: + with self.assertRaises(re.PatternError) as cm: re.sub(pattern, repl, string) with self.subTest(pattern=pattern, repl=repl): err = cm.exception @@ -64,6 +64,9 @@ def checkTemplateError(self, pattern, repl, string, errmsg, pos=None): if pos is not None: self.assertEqual(err.pos, pos) + def test_error_is_PatternError_alias(self): + assert re.error is re.PatternError + def test_keep_buffer(self): # See bug 14212 b = bytearray(b'x') @@ -154,7 +157,7 @@ def test_basic_re_sub(self): (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7)+chr(8))) for c in 'cdehijklmopqsuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ': with self.subTest(c): - with self.assertRaises(re.error): + with self.assertRaises(re.PatternError): self.assertEqual(re.sub('a', '\\' + c, 'a'), '\\' + c) self.assertEqual(re.sub(r'^\s*', 'X', 'test'), 'Xtest') @@ -836,10 +839,10 @@ def test_other_escapes(self): re.purge() # for warnings for c in 'ceghijklmopqyzCEFGHIJKLMNOPQRTVXY': with self.subTest(c): - self.assertRaises(re.error, re.compile, '\\%c' % c) + self.assertRaises(re.PatternError, re.compile, '\\%c' % c) for c in 'ceghijklmopqyzABCEFGHIJKLMNOPQRTVXYZ': with self.subTest(c): - self.assertRaises(re.error, re.compile, '[\\%c]' % c) + self.assertRaises(re.PatternError, re.compile, '[\\%c]' % c) def test_named_unicode_escapes(self): # test individual Unicode named escapes @@ -970,14 +973,14 @@ def test_lookbehind(self): self.assertIsNone(re.match(r'(?:(a)|(x))b(?<=(?(1)c|x))c', 'abc')) self.assertTrue(re.match(r'(?:(a)|(x))b(?<=(?(1)b|x))c', 'abc')) # Group used before defined. - self.assertRaises(re.error, re.compile, r'(a)b(?<=(?(2)b|x))(c)') + self.assertRaises(re.PatternError, re.compile, r'(a)b(?<=(?(2)b|x))(c)') self.assertIsNone(re.match(r'(a)b(?<=(?(1)c|x))(c)', 'abc')) self.assertTrue(re.match(r'(a)b(?<=(?(1)b|x))(c)', 'abc')) # Group defined in the same lookbehind pattern - self.assertRaises(re.error, re.compile, r'(a)b(?<=(.)\2)(c)') - self.assertRaises(re.error, re.compile, r'(a)b(?<=(?P.)(?P=a))(c)') - self.assertRaises(re.error, re.compile, r'(a)b(?<=(a)(?(2)b|x))(c)') - self.assertRaises(re.error, re.compile, r'(a)b(?<=(.)(?<=\2))(c)') + self.assertRaises(re.PatternError, re.compile, r'(a)b(?<=(.)\2)(c)') + self.assertRaises(re.PatternError, re.compile, r'(a)b(?<=(?P.)(?P=a))(c)') + self.assertRaises(re.PatternError, re.compile, r'(a)b(?<=(a)(?(2)b|x))(c)') + self.assertRaises(re.PatternError, re.compile, r'(a)b(?<=(.)(?<=\2))(c)') def test_ignore_case(self): self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC") @@ -1318,8 +1321,8 @@ def test_sre_byte_literals(self): self.assertTrue(re.match((r"\x%02x" % i).encode(), bytes([i]))) self.assertTrue(re.match((r"\x%02x0" % i).encode(), bytes([i])+b"0")) self.assertTrue(re.match((r"\x%02xz" % i).encode(), bytes([i])+b"z")) - self.assertRaises(re.error, re.compile, br"\u1234") - self.assertRaises(re.error, re.compile, br"\U00012345") + self.assertRaises(re.PatternError, re.compile, br"\u1234") + self.assertRaises(re.PatternError, re.compile, br"\U00012345") self.assertTrue(re.match(br"\0", b"\000")) self.assertTrue(re.match(br"\08", b"\0008")) self.assertTrue(re.match(br"\01", b"\001")) @@ -1341,8 +1344,8 @@ def test_sre_byte_class_literals(self): self.assertTrue(re.match((r"[\x%02x]" % i).encode(), bytes([i]))) self.assertTrue(re.match((r"[\x%02x0]" % i).encode(), bytes([i]))) self.assertTrue(re.match((r"[\x%02xz]" % i).encode(), bytes([i]))) - self.assertRaises(re.error, re.compile, br"[\u1234]") - self.assertRaises(re.error, re.compile, br"[\U00012345]") + self.assertRaises(re.PatternError, re.compile, br"[\u1234]") + self.assertRaises(re.PatternError, re.compile, br"[\U00012345]") self.checkPatternError(br"[\567]", r'octal escape value \567 outside of ' r'range 0-0o377', 1) @@ -1675,11 +1678,11 @@ def test_ascii_and_unicode_flag(self): self.assertIsNone(pat.match(b'\xe0')) # Incompatibilities self.assertRaises(ValueError, re.compile, br'\w', re.UNICODE) - self.assertRaises(re.error, re.compile, br'(?u)\w') + self.assertRaises(re.PatternError, re.compile, br'(?u)\w') self.assertRaises(ValueError, re.compile, r'\w', re.UNICODE | re.ASCII) self.assertRaises(ValueError, re.compile, r'(?u)\w', re.ASCII) self.assertRaises(ValueError, re.compile, r'(?a)\w', re.UNICODE) - self.assertRaises(re.error, re.compile, r'(?au)\w') + self.assertRaises(re.PatternError, re.compile, r'(?au)\w') def test_locale_flag(self): enc = locale.getpreferredencoding() @@ -1720,11 +1723,11 @@ def test_locale_flag(self): self.assertIsNone(pat.match(bletter)) # Incompatibilities self.assertRaises(ValueError, re.compile, '', re.LOCALE) - self.assertRaises(re.error, re.compile, '(?L)') + self.assertRaises(re.PatternError, re.compile, '(?L)') self.assertRaises(ValueError, re.compile, b'', re.LOCALE | re.ASCII) self.assertRaises(ValueError, re.compile, b'(?L)', re.ASCII) self.assertRaises(ValueError, re.compile, b'(?a)', re.LOCALE) - self.assertRaises(re.error, re.compile, b'(?aL)') + self.assertRaises(re.PatternError, re.compile, b'(?aL)') def test_scoped_flags(self): self.assertTrue(re.match(r'(?i:a)b', 'Ab')) @@ -1861,6 +1864,29 @@ def test_repeat_minmax_overflow(self): self.assertRaises(OverflowError, re.compile, r".{%d,}?" % 2**128) self.assertRaises(OverflowError, re.compile, r".{%d,%d}" % (2**129, 2**128)) + def test_look_behind_overflow(self): + string = "x" * 2_500_000 + p1 = r"(?<=((.{%d}){%d}){%d})" + p2 = r"(?)', @@ -2037,7 +2063,7 @@ def test_locale_compiled(self): self.assertIsNone(p4.match(b'\xc5\xc5')) def test_error(self): - with self.assertRaises(re.error) as cm: + with self.assertRaises(re.PatternError) as cm: re.compile('(\u20ac))') err = cm.exception self.assertIsInstance(err.pattern, str) @@ -2049,14 +2075,14 @@ def test_error(self): self.assertIn(' at position 3', str(err)) self.assertNotIn(' at position 3', err.msg) # Bytes pattern - with self.assertRaises(re.error) as cm: + with self.assertRaises(re.PatternError) as cm: re.compile(b'(\xa4))') err = cm.exception self.assertIsInstance(err.pattern, bytes) self.assertEqual(err.pattern, b'(\xa4))') self.assertEqual(err.pos, 3) # Multiline pattern - with self.assertRaises(re.error) as cm: + with self.assertRaises(re.PatternError) as cm: re.compile(""" ( abc @@ -2735,6 +2761,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): @@ -2794,7 +2823,7 @@ def test_re_tests(self): with self.subTest(pattern=pattern, string=s): if outcome == SYNTAX_ERROR: # Expected a syntax error - with self.assertRaises(re.error): + with self.assertRaises(re.PatternError): re.compile(pattern) continue diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py index 59dbef90380053..5e0e6f8dfac651 100644 --- a/Lib/test/test_readline.py +++ b/Lib/test/test_readline.py @@ -1,18 +1,16 @@ """ Very minimal unittests for parts of the readline module. """ -from contextlib import ExitStack -from errno import EIO import locale import os -import selectors -import subprocess import sys import tempfile +import textwrap import unittest from test.support import verbose from test.support.import_helper import import_module from test.support.os_helper import unlink, temp_dir, TESTFN +from test.support.pty_helper import run_pty from test.support.script_helper import assert_python_ok # Skip tests if there is no readline module @@ -21,7 +19,7 @@ if hasattr(readline, "_READLINE_LIBRARY_VERSION"): is_editline = ("EditLine wrapper" in readline._READLINE_LIBRARY_VERSION) else: - is_editline = (readline.__doc__ and "libedit" in readline.__doc__) + is_editline = readline.backend == "editline" def setUpModule(): @@ -147,6 +145,9 @@ def test_init(self): TERM='xterm-256color') self.assertEqual(stdout, b'') + def test_backend(self): + self.assertIn(readline.backend, ("readline", "editline")) + auto_history_script = """\ import readline readline.set_auto_history({}) @@ -166,6 +167,25 @@ def test_auto_history_disabled(self): # end, so don't expect it in the output. self.assertIn(b"History length: 0", output) + def test_set_complete_delims(self): + script = textwrap.dedent(""" + import readline + def complete(text, state): + if state == 0 and text == "$": + return "$complete" + return None + if readline.backend == "editline": + readline.parse_and_bind(r'bind "\\t" rl_complete') + else: + readline.parse_and_bind(r'"\\t": complete') + readline.set_completer_delims(" \\t\\n") + readline.set_completer(complete) + print(input()) + """) + + output = run_pty(script, input=b"$\t\n") + self.assertIn(b"$complete", output) + def test_nonascii(self): loc = locale.setlocale(locale.LC_CTYPE, None) if loc in ('C', 'POSIX'): @@ -181,7 +201,7 @@ def test_nonascii(self): script = r"""import readline -is_editline = readline.__doc__ and "libedit" in readline.__doc__ +is_editline = readline.backend == "editline" inserted = "[\xEFnserted]" macro = "|t\xEB[after]" set_pre_input_hook = getattr(readline, "set_pre_input_hook", None) @@ -304,55 +324,5 @@ def test_history_size(self): self.assertEqual(lines[-1].strip(), b"last input") -def run_pty(script, input=b"dummy input\r", env=None): - pty = import_module('pty') - output = bytearray() - [master, slave] = pty.openpty() - args = (sys.executable, '-c', script) - proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env) - os.close(slave) - with ExitStack() as cleanup: - cleanup.enter_context(proc) - def terminate(proc): - try: - proc.terminate() - except ProcessLookupError: - # Workaround for Open/Net BSD bug (Issue 16762) - pass - cleanup.callback(terminate, proc) - cleanup.callback(os.close, master) - # Avoid using DefaultSelector and PollSelector. Kqueue() does not - # work with pseudo-terminals on OS X < 10.9 (Issue 20365) and Open - # BSD (Issue 20667). Poll() does not work with OS X 10.6 or 10.4 - # either (Issue 20472). Hopefully the file descriptor is low enough - # to use with select(). - sel = cleanup.enter_context(selectors.SelectSelector()) - sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE) - os.set_blocking(master, False) - while True: - for [_, events] in sel.select(): - if events & selectors.EVENT_READ: - try: - chunk = os.read(master, 0x10000) - except OSError as err: - # Linux raises EIO when slave is closed (Issue 5380) - if err.errno != EIO: - raise - chunk = b"" - if not chunk: - return output - output.extend(chunk) - if events & selectors.EVENT_WRITE: - try: - input = input[os.write(master, input):] - except OSError as err: - # Apparently EIO means the slave was closed - if err.errno != EIO: - raise - input = b"" # Stop writing - if not input: - sel.modify(master, selectors.EVENT_READ) - - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index da1406def55543..e828941f6c779d 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -14,6 +14,7 @@ import random import re import shlex +import signal import subprocess import sys import sysconfig @@ -21,11 +22,13 @@ import textwrap import unittest from test import support -from test.support import os_helper, TestStats, without_optimizer +from test.support import os_helper, 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.filter import set_match_tests, match_test +from test.libregrtest.result import TestStats from test.libregrtest.utils import normalize_test_name if not support.has_subprocess_support: @@ -142,11 +145,27 @@ def test_header(self): self.assertTrue(ns.header) def test_randomize(self): - for opt in '-r', '--randomize': + for opt in ('-r', '--randomize'): with self.subTest(opt=opt): ns = self.parse_args([opt]) self.assertTrue(ns.randomize) + with os_helper.EnvironmentVarGuard() as env: + # with SOURCE_DATE_EPOCH + env['SOURCE_DATE_EPOCH'] = '1697839080' + ns = self.parse_args(['--randomize']) + regrtest = main.Regrtest(ns) + self.assertFalse(regrtest.randomize) + self.assertIsInstance(regrtest.random_seed, str) + self.assertEqual(regrtest.random_seed, '1697839080') + + # without SOURCE_DATE_EPOCH + del env['SOURCE_DATE_EPOCH'] + ns = self.parse_args(['--randomize']) + regrtest = main.Regrtest(ns) + self.assertTrue(regrtest.randomize) + self.assertIsInstance(regrtest.random_seed, int) + def test_randseed(self): ns = self.parse_args(['--randseed', '12345']) self.assertEqual(ns.random_seed, 12345) @@ -175,34 +194,27 @@ def test_single(self): self.assertTrue(ns.single) self.checkError([opt, '-f', 'foo'], "don't go together") - def test_ignore(self): - for opt in '-i', '--ignore': + def test_match(self): + for opt in '-m', '--match': with self.subTest(opt=opt): ns = self.parse_args([opt, 'pattern']) - self.assertEqual(ns.ignore_tests, ['pattern']) + self.assertEqual(ns.match_tests, [('pattern', True)]) self.checkError([opt], 'expected one argument') - self.addCleanup(os_helper.unlink, os_helper.TESTFN) - with open(os_helper.TESTFN, "w") as fp: - print('matchfile1', file=fp) - print('matchfile2', file=fp) - - filename = os.path.abspath(os_helper.TESTFN) - ns = self.parse_args(['-m', 'match', - '--ignorefile', filename]) - self.assertEqual(ns.ignore_tests, - ['matchfile1', 'matchfile2']) - - def test_match(self): - for opt in '-m', '--match': + for opt in '-i', '--ignore': with self.subTest(opt=opt): ns = self.parse_args([opt, 'pattern']) - self.assertEqual(ns.match_tests, ['pattern']) + self.assertEqual(ns.match_tests, [('pattern', False)]) self.checkError([opt], 'expected one argument') - ns = self.parse_args(['-m', 'pattern1', - '-m', 'pattern2']) - self.assertEqual(ns.match_tests, ['pattern1', 'pattern2']) + ns = self.parse_args(['-m', 'pattern1', '-m', 'pattern2']) + self.assertEqual(ns.match_tests, [('pattern1', True), ('pattern2', True)]) + + ns = self.parse_args(['-m', 'pattern1', '-i', 'pattern2']) + self.assertEqual(ns.match_tests, [('pattern1', True), ('pattern2', False)]) + + ns = self.parse_args(['-i', 'pattern1', '-m', 'pattern2']) + self.assertEqual(ns.match_tests, [('pattern1', False), ('pattern2', True)]) self.addCleanup(os_helper.unlink, os_helper.TESTFN) with open(os_helper.TESTFN, "w") as fp: @@ -210,10 +222,13 @@ def test_match(self): print('matchfile2', file=fp) filename = os.path.abspath(os_helper.TESTFN) - ns = self.parse_args(['-m', 'match', - '--matchfile', filename]) + ns = self.parse_args(['-m', 'match', '--matchfile', filename]) + self.assertEqual(ns.match_tests, + [('match', True), ('matchfile1', True), ('matchfile2', True)]) + + ns = self.parse_args(['-i', 'match', '--ignorefile', filename]) self.assertEqual(ns.match_tests, - ['match', 'matchfile1', 'matchfile2']) + [('match', False), ('matchfile1', False), ('matchfile2', False)]) def test_failfast(self): for opt in '-G', '--failfast': @@ -291,13 +306,23 @@ def test_multiprocess(self): self.assertEqual(ns.use_mp, 2) self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo'], 'invalid int value') - self.checkError([opt, '2', '-T'], "don't go together") - self.checkError([opt, '0', '-T'], "don't go together") - def test_coverage(self): + def test_coverage_sequential(self): for opt in '-T', '--coverage': with self.subTest(opt=opt): - ns = self.parse_args([opt]) + with support.captured_stderr() as stderr: + ns = self.parse_args([opt]) + self.assertTrue(ns.trace) + self.assertIn( + "collecting coverage without -j is imprecise", + stderr.getvalue(), + ) + + @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') + def test_coverage_mp(self): + for opt in '-T', '--coverage': + with self.subTest(opt=opt): + ns = self.parse_args([opt, '-j1']) self.assertTrue(ns.trace) def test_coverdir(self): @@ -376,18 +401,21 @@ def test_unknown_option(self): def check_ci_mode(self, args, use_resources, rerun=True): ns = cmdline._parse_args(args) - if utils.MS_WINDOWS: - self.assertTrue(ns.nowindows) # Check Regrtest attributes which are more reliable than Namespace # which has an unclear API - regrtest = main.Regrtest(ns) + with os_helper.EnvironmentVarGuard() as env: + # Ignore SOURCE_DATE_EPOCH env var if it's set + if 'SOURCE_DATE_EPOCH' in env: + del env['SOURCE_DATE_EPOCH'] + + regrtest = main.Regrtest(ns) + self.assertEqual(regrtest.num_workers, -1) self.assertEqual(regrtest.want_rerun, rerun) self.assertTrue(regrtest.randomize) - self.assertIsNone(regrtest.random_seed) + 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)) @@ -409,9 +437,11 @@ def test_fast_ci_python_cmd(self): 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'] + # it should be possible to override resources individually + args = ['--fast-ci', '-u-network'] + use_resources = sorted(cmdline.ALL_RESOURCES) + use_resources.remove('cpu') + use_resources.remove('network') self.check_ci_mode(args, use_resources) def test_slow_ci(self): @@ -653,21 +683,26 @@ def list_regex(line_format, tests): 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 <= 100_000_000, randseed) - return randseed + def parse_random_seed(self, output: str) -> str: + match = self.regex_search(r'Using random seed: (.*)', output) + return match.group(1) def run_command(self, args, input=None, exitcode=0, **kw): if not input: input = '' if 'stderr' not in kw: kw['stderr'] = subprocess.STDOUT + + env = kw.pop('env', None) + if env is None: + env = dict(os.environ) + env.pop('SOURCE_DATE_EPOCH', None) + proc = subprocess.run(args, - universal_newlines=True, + text=True, input=input, stdout=subprocess.PIPE, + env=env, **kw) if proc.returncode != exitcode: msg = ("Command %s failed with exit code %s, but exit code %s expected!\n" @@ -743,12 +778,14 @@ def setUp(self): self.regrtest_args.append('-n') def check_output(self, output): - self.parse_random_seed(output) + randseed = self.parse_random_seed(output) + self.assertTrue(randseed.isdigit(), randseed) + 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): @@ -789,14 +826,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) @@ -942,7 +971,7 @@ def test_random(self): test_random = int(match.group(1)) # try to reproduce with the random seed - output = self.run_tests('-r', '--randseed=%s' % randseed, test, + output = self.run_tests('-r', f'--randseed={randseed}', test, exitcode=EXITCODE_NO_TESTS_RAN) randseed2 = self.parse_random_seed(output) self.assertEqual(randseed2, randseed) @@ -951,6 +980,35 @@ 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) + randseed = self.parse_random_seed(output) + self.assertTrue(randseed.isdigit(), randseed) + + # check SOURCE_DATE_EPOCH (integer) + timestamp = '1697839080' + env = dict(os.environ, SOURCE_DATE_EPOCH=timestamp) + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN, + env=env) + randseed = self.parse_random_seed(output) + self.assertEqual(randseed, timestamp) + self.check_line(output, 'TESTRANDOM: 520') + + # check SOURCE_DATE_EPOCH (string) + env = dict(os.environ, SOURCE_DATE_EPOCH='XYZ') + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN, + env=env) + randseed = self.parse_random_seed(output) + self.assertEqual(randseed, 'XYZ') + self.check_line(output, 'TESTRANDOM: 22') + + # check SOURCE_DATE_EPOCH (empty string): ignore the env var + env = dict(os.environ, SOURCE_DATE_EPOCH='') + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN, + env=env) + randseed = self.parse_random_seed(output) + self.assertTrue(randseed.isdigit(), randseed) + def test_fromfile(self): # test --fromfile tests = [self.create_test() for index in range(5)] @@ -1973,6 +2031,25 @@ def test_dev_mode(self): self.check_executed_tests(output, tests, stats=len(tests), parallel=True) + def test_unload_tests(self): + # Test that unloading test modules does not break tests + # that import from other tests. + # The test execution order matters for this test. + # Both test_regrtest_a and test_regrtest_c which are executed before + # and after test_regrtest_b import a submodule from the test_regrtest_b + # package and use it in testing. test_regrtest_b itself does not import + # that submodule. + # Previously test_regrtest_c failed because test_regrtest_b.util in + # sys.modules was left after test_regrtest_a (making the import + # statement no-op), but new test_regrtest_b without the util attribute + # was imported for test_regrtest_b. + testdir = os.path.join(os.path.dirname(__file__), + 'regrtestdata', 'import_from_tests') + tests = [f'test_regrtest_{name}' for name in ('a', 'b', 'c')] + args = ['-Wd', '-E', '-bb', '-m', 'test', '--testdir=%s' % testdir, *tests] + output = self.run_python(args) + self.check_executed_tests(output, tests, stats=3) + 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""" @@ -2033,6 +2110,68 @@ def test_add_python_opts(self): 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) + + def test_verbose3(self): + code = textwrap.dedent(r""" + import unittest + from test import support + + class VerboseTests(unittest.TestCase): + def test_pass(self): + print("SPAM SPAM SPAM") + """) + testname = self.create_test(code=code) + + # Run sequentially + output = self.run_tests("--verbose3", testname) + self.check_executed_tests(output, testname, stats=1) + self.assertNotIn('SPAM SPAM SPAM', output) + + # -R option needs a debug build + if support.Py_DEBUG: + # Check for reference leaks, run in parallel + output = self.run_tests("-R", "3:3", "-j1", "--verbose3", testname) + self.check_executed_tests(output, testname, stats=1, parallel=True) + self.assertNotIn('SPAM SPAM SPAM', output) + class TestUtils(unittest.TestCase): def test_format_duration(self): @@ -2068,6 +2207,149 @@ def test_normalize_test_name(self): 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') + + def test_match_test(self): + class Test: + def __init__(self, test_id): + self.test_id = test_id + + def id(self): + return self.test_id + + test_access = Test('test.test_os.FileTests.test_access') + test_chdir = Test('test.test_os.Win32ErrorTests.test_chdir') + test_copy = Test('test.test_shutil.TestCopy.test_copy') + + # Test acceptance + with support.swap_attr(support, '_test_matchers', ()): + # match all + set_match_tests([]) + self.assertTrue(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + + # match all using None + set_match_tests(None) + self.assertTrue(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + + # match the full test identifier + set_match_tests([(test_access.id(), True)]) + self.assertTrue(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + + # match the module name + set_match_tests([('test_os', True)]) + self.assertTrue(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + self.assertFalse(match_test(test_copy)) + + # Test '*' pattern + set_match_tests([('test_*', True)]) + self.assertTrue(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + + # Test case sensitivity + set_match_tests([('filetests', True)]) + self.assertFalse(match_test(test_access)) + set_match_tests([('FileTests', True)]) + self.assertTrue(match_test(test_access)) + + # Test pattern containing '.' and a '*' metacharacter + set_match_tests([('*test_os.*.test_*', True)]) + self.assertTrue(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + self.assertFalse(match_test(test_copy)) + + # Multiple patterns + set_match_tests([(test_access.id(), True), (test_chdir.id(), True)]) + self.assertTrue(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + self.assertFalse(match_test(test_copy)) + + set_match_tests([('test_access', True), ('DONTMATCH', True)]) + self.assertTrue(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + + # Test rejection + with support.swap_attr(support, '_test_matchers', ()): + # match the full test identifier + set_match_tests([(test_access.id(), False)]) + self.assertFalse(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + + # match the module name + set_match_tests([('test_os', False)]) + self.assertFalse(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + self.assertTrue(match_test(test_copy)) + + # Test '*' pattern + set_match_tests([('test_*', False)]) + self.assertFalse(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + + # Test case sensitivity + set_match_tests([('filetests', False)]) + self.assertTrue(match_test(test_access)) + set_match_tests([('FileTests', False)]) + self.assertFalse(match_test(test_access)) + + # Test pattern containing '.' and a '*' metacharacter + set_match_tests([('*test_os.*.test_*', False)]) + self.assertFalse(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + self.assertTrue(match_test(test_copy)) + + # Multiple patterns + set_match_tests([(test_access.id(), False), (test_chdir.id(), False)]) + self.assertFalse(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + self.assertTrue(match_test(test_copy)) + + set_match_tests([('test_access', False), ('DONTMATCH', False)]) + self.assertFalse(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + + # Test mixed filters + with support.swap_attr(support, '_test_matchers', ()): + set_match_tests([('*test_os', False), ('test_access', True)]) + self.assertTrue(match_test(test_access)) + self.assertFalse(match_test(test_chdir)) + self.assertTrue(match_test(test_copy)) + + set_match_tests([('*test_os', True), ('test_access', False)]) + self.assertFalse(match_test(test_access)) + self.assertTrue(match_test(test_chdir)) + self.assertFalse(match_test(test_copy)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 58392f2384a3d9..a28d1595f44533 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -131,6 +131,69 @@ 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()[-8:-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['-1']) + """) + 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_richcmp.py b/Lib/test/test_richcmp.py index 58729a9fea62fa..6fb31c80d7e670 100644 --- a/Lib/test/test_richcmp.py +++ b/Lib/test/test_richcmp.py @@ -221,6 +221,7 @@ def do(bad): self.assertRaises(Exc, func, Bad()) @support.no_tracing + @support.infinite_recursion() def test_recursion(self): # Check that comparison for recursive objects fails gracefully from collections import UserList 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 a2ca4df135846f..b29d316352f219 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -208,8 +208,7 @@ def test_rmtree_fails_on_symlink_onerror(self): errors = [] def onerror(*args): errors.append(args) - with self.assertWarns(DeprecationWarning): - shutil.rmtree(link, onerror=onerror) + shutil.rmtree(link, onerror=onerror) self.assertEqual(len(errors), 1) self.assertIs(errors[0][0], os.path.islink) self.assertEqual(errors[0][1], link) @@ -270,8 +269,7 @@ def test_rmtree_fails_on_junctions_onerror(self): errors = [] def onerror(*args): errors.append(args) - with self.assertWarns(DeprecationWarning): - shutil.rmtree(link, onerror=onerror) + shutil.rmtree(link, onerror=onerror) self.assertEqual(len(errors), 1) self.assertIs(errors[0][0], os.path.islink) self.assertEqual(errors[0][1], link) @@ -319,7 +317,7 @@ def test_rmtree_works_on_junctions(self): self.assertTrue(os.path.exists(dir3)) self.assertTrue(os.path.exists(file1)) - def test_rmtree_errors_onerror(self): + def test_rmtree_errors(self): # filename is guaranteed not to exist filename = tempfile.mktemp(dir=self.mkdtemp()) self.assertRaises(FileNotFoundError, shutil.rmtree, filename) @@ -328,8 +326,8 @@ def test_rmtree_errors_onerror(self): # existing file tmpdir = self.mkdtemp() - write_file((tmpdir, "tstfile"), "") filename = os.path.join(tmpdir, "tstfile") + write_file(filename, "") with self.assertRaises(NotADirectoryError) as cm: shutil.rmtree(filename) self.assertEqual(cm.exception.filename, filename) @@ -337,11 +335,23 @@ def test_rmtree_errors_onerror(self): # test that ignore_errors option is honored shutil.rmtree(filename, ignore_errors=True) self.assertTrue(os.path.exists(filename)) + + self.assertRaises(TypeError, shutil.rmtree, None) + self.assertRaises(TypeError, shutil.rmtree, None, ignore_errors=True) + exc = TypeError if shutil.rmtree.avoids_symlink_attacks else NotImplementedError + with self.assertRaises(exc): + shutil.rmtree(filename, dir_fd='invalid') + with self.assertRaises(exc): + shutil.rmtree(filename, dir_fd='invalid', ignore_errors=True) + + def test_rmtree_errors_onerror(self): + tmpdir = self.mkdtemp() + filename = os.path.join(tmpdir, "tstfile") + write_file(filename, "") errors = [] def onerror(*args): errors.append(args) - with self.assertWarns(DeprecationWarning): - shutil.rmtree(filename, onerror=onerror) + shutil.rmtree(filename, onerror=onerror) self.assertEqual(len(errors), 2) self.assertIs(errors[0][0], os.scandir) self.assertEqual(errors[0][1], filename) @@ -353,23 +363,9 @@ def onerror(*args): self.assertEqual(errors[1][2][1].filename, filename) def test_rmtree_errors_onexc(self): - # filename is guaranteed not to exist - filename = tempfile.mktemp(dir=self.mkdtemp()) - self.assertRaises(FileNotFoundError, shutil.rmtree, filename) - # test that ignore_errors option is honored - shutil.rmtree(filename, ignore_errors=True) - - # existing file tmpdir = self.mkdtemp() - write_file((tmpdir, "tstfile"), "") filename = os.path.join(tmpdir, "tstfile") - with self.assertRaises(NotADirectoryError) as cm: - shutil.rmtree(filename) - self.assertEqual(cm.exception.filename, filename) - self.assertTrue(os.path.exists(filename)) - # test that ignore_errors option is honored - shutil.rmtree(filename, ignore_errors=True) - self.assertTrue(os.path.exists(filename)) + write_file(filename, "") errors = [] def onexc(*args): errors.append(args) @@ -410,8 +406,7 @@ def test_on_error(self): self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) - with self.assertWarns(DeprecationWarning): - shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) + shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) # Test whether onerror has actually been called. self.assertEqual(self.errorState, 3, "Expected call to onerror function did not happen.") @@ -537,8 +532,7 @@ def onexc(*args): self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) - with self.assertWarns(DeprecationWarning): - shutil.rmtree(TESTFN, onerror=onerror, onexc=onexc) + shutil.rmtree(TESTFN, onerror=onerror, onexc=onexc) self.assertTrue(onexc_called) self.assertFalse(onerror_called) @@ -582,6 +576,41 @@ def _raiser(*args, **kwargs): self.assertFalse(shutil._use_fd_functions) self.assertFalse(shutil.rmtree.avoids_symlink_attacks) + @unittest.skipUnless(shutil._use_fd_functions, "requires safe rmtree") + def test_rmtree_fails_on_close(self): + # Test that the error handler is called for failed os.close() and that + # os.close() is only called once for a file descriptor. + tmp = self.mkdtemp() + dir1 = os.path.join(tmp, 'dir1') + os.mkdir(dir1) + dir2 = os.path.join(dir1, 'dir2') + os.mkdir(dir2) + def close(fd): + orig_close(fd) + nonlocal close_count + close_count += 1 + raise OSError + + close_count = 0 + with support.swap_attr(os, 'close', close) as orig_close: + with self.assertRaises(OSError): + shutil.rmtree(dir1) + self.assertTrue(os.path.isdir(dir2)) + self.assertEqual(close_count, 2) + + close_count = 0 + errors = [] + def onexc(*args): + errors.append(args) + with support.swap_attr(os, 'close', close) as orig_close: + shutil.rmtree(dir1, onexc=onexc) + self.assertEqual(len(errors), 2) + self.assertIs(errors[0][0], close) + self.assertEqual(errors[0][1], dir2) + self.assertIs(errors[1][0], close) + self.assertEqual(errors[1][1], dir1) + self.assertEqual(close_count, 2) + @unittest.skipUnless(shutil._use_fd_functions, "dir_fd is not supported") def test_rmtree_with_dir_fd(self): tmp_dir = self.mkdtemp() @@ -638,6 +667,63 @@ def test_rmtree_on_junction(self): finally: shutil.rmtree(TESTFN, ignore_errors=True) + @unittest.skipIf(sys.platform[:6] == 'cygwin', + "This test can't be run on Cygwin (issue #1071513).") + @os_helper.skip_if_dac_override + @os_helper.skip_unless_working_chmod + def test_rmtree_deleted_race_condition(self): + # bpo-37260 + # + # Test that a file or a directory deleted after it is enumerated + # by scandir() but before unlink() or rmdr() is called doesn't + # generate any errors. + def _onexc(fn, path, exc): + assert fn in (os.rmdir, os.unlink) + if not isinstance(exc, PermissionError): + raise + # Make the parent and the children writeable. + for p, mode in zip(paths, old_modes): + os.chmod(p, mode) + # Remove other dirs except one. + keep = next(p for p in dirs if p != path) + for p in dirs: + if p != keep: + os.rmdir(p) + # Remove other files except one. + keep = next(p for p in files if p != path) + for p in files: + if p != keep: + os.unlink(p) + + os.mkdir(TESTFN) + paths = [TESTFN] + [os.path.join(TESTFN, f'child{i}') + for i in range(6)] + dirs = paths[1::2] + files = paths[2::2] + for path in dirs: + os.mkdir(path) + for path in files: + write_file(path, '') + + old_modes = [os.stat(path).st_mode for path in paths] + + # Make the parent and the children non-writeable. + new_mode = stat.S_IREAD|stat.S_IEXEC + for path in reversed(paths): + os.chmod(path, new_mode) + + try: + shutil.rmtree(TESTFN, onexc=_onexc) + except: + # Test failed, so cleanup artifacts. + for path, mode in zip(paths, old_modes): + try: + os.chmod(path, mode) + except OSError: + pass + shutil.rmtree(TESTFN) + raise + class TestCopyTree(BaseTest, unittest.TestCase): @@ -1584,6 +1670,17 @@ def test_tarfile_vs_tar(self): # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] + if sys.platform == 'darwin': + # macOS tar can include extended attributes, + # ACLs and other mac specific metadata into the + # archive (an recentish version of the OS). + # + # This feature can be disabled with the + # '--no-mac-metadata' option on macOS 11 or + # later. + import platform + if int(platform.mac_ver()[0].split('.')[0]) >= 11: + tar_cmd.insert(1, '--no-mac-metadata') subprocess.check_call(tar_cmd, cwd=root_dir, stdout=subprocess.DEVNULL) @@ -2067,6 +2164,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) @@ -2254,9 +2359,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) @@ -2265,16 +2370,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 @@ -2282,7 +2387,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) @@ -2290,13 +2395,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') @@ -2312,6 +2418,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): @@ -2319,9 +2469,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 2a1a1ee22f43da..acb7e9d4c6074d 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -1318,6 +1318,7 @@ def handler(signum, frame): # Python handler self.assertEqual(len(sigs), N, "Some signals were lost") + @unittest.skipIf(sys.platform == "darwin", "crashes due to system bug (FB13453490)") @unittest.skipUnless(hasattr(signal, "SIGUSR1"), "test needs SIGUSR1") @threading_helper.requires_working_threading() @@ -1339,7 +1340,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]: @@ -1372,7 +1373,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 e8ec3b35881fec..33d0975bda8eaa 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -465,6 +465,44 @@ def test_sitecustomize_executed(self): else: self.fail("sitecustomize not imported automatically") + @support.requires_subprocess() + def test_customization_modules_on_startup(self): + mod_names = [ + 'sitecustomize' + ] + + if site.ENABLE_USER_SITE: + mod_names.append('usercustomize') + + temp_dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, temp_dir) + + with EnvironmentVarGuard() as environ: + environ['PYTHONPATH'] = temp_dir + + for module_name in mod_names: + os_helper.rmtree(temp_dir) + os.mkdir(temp_dir) + + customize_path = os.path.join(temp_dir, f'{module_name}.py') + eyecatcher = f'EXECUTED_{module_name}' + + with open(customize_path, 'w') as f: + f.write(f'print("{eyecatcher}")') + + output = subprocess.check_output([sys.executable, '-c', '""']) + self.assertIn(eyecatcher, output.decode('utf-8')) + + # -S blocks any site-packages + output = subprocess.check_output([sys.executable, '-S', '-c', '""']) + self.assertNotIn(eyecatcher, output.decode('utf-8')) + + # -s blocks user site-packages + if 'usercustomize' == module_name: + output = subprocess.check_output([sys.executable, '-s', '-c', '""']) + self.assertNotIn(eyecatcher, output.decode('utf-8')) + + @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 'need SSL support to download license') @test.support.requires_resource('network') diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 99c4c5cbc4902d..4eb5af99d6674c 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 @@ -1101,7 +1082,20 @@ def testInterfaceNameIndex(self): 'socket.if_indextoname() not available.') def testInvalidInterfaceIndexToName(self): self.assertRaises(OSError, socket.if_indextoname, 0) + self.assertRaises(OverflowError, socket.if_indextoname, -1) + self.assertRaises(OverflowError, socket.if_indextoname, 2**1000) self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF') + if hasattr(socket, 'if_nameindex'): + indices = dict(socket.if_nameindex()) + for index in indices: + index2 = index + 2**32 + if index2 not in indices: + with self.assertRaises((OverflowError, OSError)): + socket.if_indextoname(index2) + for index in 2**32-1, 2**64-1: + if index not in indices: + with self.assertRaises((OverflowError, OSError)): + socket.if_indextoname(index) @unittest.skipUnless(hasattr(socket, 'if_nametoindex'), 'socket.if_nametoindex() not available.') @@ -2813,7 +2807,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 +4673,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. @@ -5356,6 +5349,7 @@ def test_create_connection_timeout(self): class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest): + cli = None def __init__(self, methodName='runTest'): SocketTCPTest.__init__(self, methodName=methodName) @@ -5365,7 +5359,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) 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 27871378f1c79e..61b00778f8361c 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -255,7 +255,7 @@ class UTF8ValidatorTest(unittest.TestCase): 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_ssl.py b/Lib/test/test_ssl.py index 06304dcb4ec7b8..3fdfa2960503b8 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -10,6 +10,7 @@ from test.support import threading_helper from test.support import warnings_helper from test.support import asyncore +import array import re import socket import select @@ -1739,6 +1740,10 @@ def test_buffer_types(self): self.assertEqual(bio.read(), b'bar') bio.write(memoryview(b'baz')) self.assertEqual(bio.read(), b'baz') + m = memoryview(bytearray(b'noncontig')) + noncontig_writable = m[::-2] + with self.assertRaises(BufferError): + bio.write(memoryview(noncontig_writable)) def test_error_types(self): bio = ssl.MemoryBIO() @@ -3513,6 +3518,27 @@ def test_recv_zero(self): self.assertEqual(s.recv(0), b"") self.assertEqual(s.recv_into(bytearray()), 0) + def test_recv_into_buffer_protocol_len(self): + server = ThreadedEchoServer(CERTFILE) + self.enterContext(server) + s = socket.create_connection((HOST, server.port)) + self.addCleanup(s.close) + s = test_wrap_socket(s, suppress_ragged_eofs=False) + self.addCleanup(s.close) + + s.send(b"data") + buf = array.array('I', [0, 0]) + self.assertEqual(s.recv_into(buf), 4) + self.assertEqual(bytes(buf)[:4], b"data") + + class B(bytearray): + def __len__(self): + 1/0 + s.send(b"data") + buf = B(6) + self.assertEqual(s.recv_into(buf), 4) + self.assertEqual(bytes(buf), b"data\0\0") + def test_nonblocking_send(self): server = ThreadedEchoServer(CERTFILE, certreqs=ssl.CERT_NONE, @@ -4232,6 +4258,107 @@ def test_session_handling(self): self.assertEqual(str(e.exception), 'Session refers to a different SSLContext.') + @requires_tls_version('TLSv1_2') + @unittest.skipUnless(ssl.HAS_PSK, 'TLS-PSK disabled on this OpenSSL build') + def test_psk(self): + psk = bytes.fromhex('deadbeef') + + client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + client_context.check_hostname = False + client_context.verify_mode = ssl.CERT_NONE + client_context.maximum_version = ssl.TLSVersion.TLSv1_2 + client_context.set_ciphers('PSK') + client_context.set_psk_client_callback(lambda hint: (None, psk)) + + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + server_context.maximum_version = ssl.TLSVersion.TLSv1_2 + server_context.set_ciphers('PSK') + server_context.set_psk_server_callback(lambda identity: psk) + + # correct PSK should connect + server = ThreadedEchoServer(context=server_context) + with server: + with client_context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + + # incorrect PSK should fail + incorrect_psk = bytes.fromhex('cafebabe') + client_context.set_psk_client_callback(lambda hint: (None, incorrect_psk)) + server = ThreadedEchoServer(context=server_context) + with server: + with client_context.wrap_socket(socket.socket()) as s: + with self.assertRaises(ssl.SSLError): + s.connect((HOST, server.port)) + + # identity_hint and client_identity should be sent to the other side + identity_hint = 'identity-hint' + client_identity = 'client-identity' + + def client_callback(hint): + self.assertEqual(hint, identity_hint) + return client_identity, psk + + def server_callback(identity): + self.assertEqual(identity, client_identity) + return psk + + client_context.set_psk_client_callback(client_callback) + server_context.set_psk_server_callback(server_callback, identity_hint) + server = ThreadedEchoServer(context=server_context) + with server: + with client_context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + + # adding client callback to server or vice versa raises an exception + with self.assertRaisesRegex(ssl.SSLError, 'Cannot add PSK server callback'): + client_context.set_psk_server_callback(server_callback, identity_hint) + with self.assertRaisesRegex(ssl.SSLError, 'Cannot add PSK client callback'): + server_context.set_psk_client_callback(client_callback) + + # test with UTF-8 identities + identity_hint = '身份暗示' # Translation: "Identity hint" + client_identity = '客户身份' # Translation: "Customer identity" + + client_context.set_psk_client_callback(client_callback) + server_context.set_psk_server_callback(server_callback, identity_hint) + server = ThreadedEchoServer(context=server_context) + with server: + with client_context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + + @requires_tls_version('TLSv1_3') + @unittest.skipUnless(ssl.HAS_PSK, 'TLS-PSK disabled on this OpenSSL build') + def test_psk_tls1_3(self): + psk = bytes.fromhex('deadbeef') + identity_hint = 'identity-hint' + client_identity = 'client-identity' + + def client_callback(hint): + # identity_hint is not sent to the client in TLS 1.3 + self.assertIsNone(hint) + return client_identity, psk + + def server_callback(identity): + self.assertEqual(identity, client_identity) + return psk + + client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + client_context.check_hostname = False + client_context.verify_mode = ssl.CERT_NONE + client_context.minimum_version = ssl.TLSVersion.TLSv1_3 + client_context.set_ciphers('PSK') + client_context.set_psk_client_callback(client_callback) + + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + server_context.minimum_version = ssl.TLSVersion.TLSv1_3 + server_context.set_ciphers('PSK') + server_context.set_psk_server_callback(server_callback, identity_hint) + + server = ThreadedEchoServer(context=server_context) + with server: + with client_context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + @unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3") class TestPostHandshakeAuth(unittest.TestCase): diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 94f817f8e1d159..4976ac3642bbe4 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -418,6 +418,10 @@ def test_windows_feature_macros(self): "PyMem_Calloc", "PyMem_Free", "PyMem_Malloc", + "PyMem_RawCalloc", + "PyMem_RawFree", + "PyMem_RawMalloc", + "PyMem_RawRealloc", "PyMem_Realloc", "PyMemberDescr_Type", "PyMember_GetOne", @@ -622,6 +626,8 @@ def test_windows_feature_macros(self): "PySys_AddWarnOption", "PySys_AddWarnOptionUnicode", "PySys_AddXOption", + "PySys_Audit", + "PySys_AuditTuple", "PySys_FormatStderr", "PySys_FormatStdout", "PySys_GetObject", @@ -770,6 +776,8 @@ def test_windows_feature_macros(self): "PyUnicode_DecodeUnicodeEscape", "PyUnicode_EncodeFSDefault", "PyUnicode_EncodeLocale", + "PyUnicode_EqualToUTF8", + "PyUnicode_EqualToUTF8AndSize", "PyUnicode_FSConverter", "PyUnicode_FSDecoder", "PyUnicode_Find", @@ -851,6 +859,7 @@ def test_windows_feature_macros(self): "Py_InitializeEx", "Py_Is", "Py_IsFalse", + "Py_IsFinalizing", "Py_IsInitialized", "Py_IsNone", "Py_IsTrue", @@ -897,6 +906,7 @@ def test_windows_feature_macros(self): "_Py_IncRef", "_Py_NoneStruct", "_Py_NotImplementedStruct", + "_Py_SetRefcnt", "_Py_SwappedOp", "_Py_TrueStruct", "_Py_VaBuildValue_SizeT", diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 0eced2fcf98376..a0d0f61e5a192c 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -148,12 +148,19 @@ def test_mode(self): self.assertEqual(modestr, '-r--r--r--') self.assertEqual(self.statmod.S_IMODE(st_mode), 0o444) else: + os.chmod(TESTFN, 0o500) + st_mode, modestr = self.get_mode() + self.assertEqual(modestr[:3], '-r-') + self.assertS_IS("REG", st_mode) + self.assertEqual(self.statmod.S_IMODE(st_mode), 0o444) + os.chmod(TESTFN, 0o700) st_mode, modestr = self.get_mode() self.assertEqual(modestr[:3], '-rw') self.assertS_IS("REG", st_mode) self.assertEqual(self.statmod.S_IFMT(st_mode), self.statmod.S_IFREG) + self.assertEqual(self.statmod.S_IMODE(st_mode), 0o666) @os_helper.skip_unless_working_chmod def test_directory(self): diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index f9b0ac2ad7b116..bf2c254c9ee7d9 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -2302,10 +2302,12 @@ def test_error_cases(self): StatisticsError = statistics.StatisticsError with self.assertRaises(StatisticsError): geometric_mean([]) # empty input - with self.assertRaises(StatisticsError): - geometric_mean([3.5, 0.0, 5.25]) # zero input with self.assertRaises(StatisticsError): geometric_mean([3.5, -4.0, 5.25]) # negative input + with self.assertRaises(StatisticsError): + geometric_mean([0.0, -4.0, 5.25]) # negative input with zero + with self.assertRaises(StatisticsError): + geometric_mean([3.5, -math.inf, 5.25]) # negative infinity with self.assertRaises(StatisticsError): geometric_mean(iter([])) # empty iterator with self.assertRaises(TypeError): @@ -2328,6 +2330,12 @@ def test_special_values(self): with self.assertRaises(ValueError): geometric_mean([Inf, -Inf]) + # Cases with zero + self.assertEqual(geometric_mean([3, 0.0, 5]), 0.0) # Any zero gives a zero + self.assertEqual(geometric_mean([3, -0.0, 5]), 0.0) # Negative zero allowed + self.assertTrue(math.isnan(geometric_mean([0, NaN]))) # NaN beats zero + self.assertTrue(math.isnan(geometric_mean([0, Inf]))) # Because 0.0 * Inf -> NaN + def test_mixed_int_and_float(self): # Regression test for b.p.o. issue #28327 geometric_mean = statistics.geometric_mean @@ -2454,6 +2462,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 @@ -2504,7 +2517,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 diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index 814ef111c5bec8..b4927113db44e3 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -55,6 +55,21 @@ def duplicate_string(text): class StrSubclass(str): pass +class OtherStrSubclass(str): + pass + +class WithStr: + def __init__(self, value): + self.value = value + def __str__(self): + return self.value + +class WithRepr: + def __init__(self, value): + self.value = value + def __repr__(self): + return self.value + class StrTest(string_tests.StringLikeTest, string_tests.MixinStrUnicodeTest, unittest.TestCase): @@ -83,6 +98,10 @@ def __repr__(self): self.assertEqual(realresult, result) self.assertTrue(object is not realresult) + def assertTypedEqual(self, actual, expected): + self.assertIs(type(actual), type(expected)) + self.assertEqual(actual, expected) + def test_literals(self): self.assertEqual('\xff', '\u00ff') self.assertEqual('\uffff', '\U0000ffff') @@ -127,10 +146,13 @@ def test_ascii(self): self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096), ascii("\U00010000" * 39 + "\uffff" * 4096)) - class WrongRepr: - def __repr__(self): - return b'byte-repr' - self.assertRaises(TypeError, ascii, WrongRepr()) + self.assertTypedEqual(ascii('\U0001f40d'), r"'\U0001f40d'") + self.assertTypedEqual(ascii(StrSubclass('abc')), "'abc'") + self.assertTypedEqual(ascii(WithRepr('')), '') + self.assertTypedEqual(ascii(WithRepr(StrSubclass(''))), StrSubclass('')) + self.assertTypedEqual(ascii(WithRepr('<\U0001f40d>')), r'<\U0001f40d>') + self.assertTypedEqual(ascii(WithRepr(StrSubclass('<\U0001f40d>'))), r'<\U0001f40d>') + self.assertRaises(TypeError, ascii, WithRepr(b'byte-repr')) def test_repr(self): # Test basic sanity of repr() @@ -168,10 +190,13 @@ def test_repr(self): self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096), repr("\U00010000" * 39 + "\uffff" * 4096)) - class WrongRepr: - def __repr__(self): - return b'byte-repr' - self.assertRaises(TypeError, repr, WrongRepr()) + self.assertTypedEqual(repr('\U0001f40d'), "'\U0001f40d'") + self.assertTypedEqual(repr(StrSubclass('abc')), "'abc'") + self.assertTypedEqual(repr(WithRepr('')), '') + self.assertTypedEqual(repr(WithRepr(StrSubclass(''))), StrSubclass('')) + self.assertTypedEqual(repr(WithRepr('<\U0001f40d>')), '<\U0001f40d>') + self.assertTypedEqual(repr(WithRepr(StrSubclass('<\U0001f40d>'))), StrSubclass('<\U0001f40d>')) + self.assertRaises(TypeError, repr, WithRepr(b'byte-repr')) def test_iterators(self): # Make sure unicode objects have an __iter__ method @@ -2367,28 +2392,37 @@ def test_ucs4(self): def test_conversion(self): # Make sure __str__() works properly - class ObjectToStr: - def __str__(self): - return "foo" - - class StrSubclassToStr(str): - def __str__(self): - return "foo" - - class StrSubclassToStrSubclass(str): - def __new__(cls, content=""): - return str.__new__(cls, 2*content) - def __str__(self): + class StrWithStr(str): + def __new__(cls, value): + self = str.__new__(cls, "") + self.value = value return self + def __str__(self): + return self.value - self.assertEqual(str(ObjectToStr()), "foo") - self.assertEqual(str(StrSubclassToStr("bar")), "foo") - s = str(StrSubclassToStrSubclass("foo")) - self.assertEqual(s, "foofoo") - self.assertIs(type(s), StrSubclassToStrSubclass) - s = StrSubclass(StrSubclassToStrSubclass("foo")) - self.assertEqual(s, "foofoo") - self.assertIs(type(s), StrSubclass) + self.assertTypedEqual(str(WithStr('abc')), 'abc') + self.assertTypedEqual(str(WithStr(StrSubclass('abc'))), StrSubclass('abc')) + self.assertTypedEqual(StrSubclass(WithStr('abc')), StrSubclass('abc')) + self.assertTypedEqual(StrSubclass(WithStr(StrSubclass('abc'))), + StrSubclass('abc')) + self.assertTypedEqual(StrSubclass(WithStr(OtherStrSubclass('abc'))), + StrSubclass('abc')) + + self.assertTypedEqual(str(StrWithStr('abc')), 'abc') + self.assertTypedEqual(str(StrWithStr(StrSubclass('abc'))), StrSubclass('abc')) + self.assertTypedEqual(StrSubclass(StrWithStr('abc')), StrSubclass('abc')) + self.assertTypedEqual(StrSubclass(StrWithStr(StrSubclass('abc'))), + StrSubclass('abc')) + self.assertTypedEqual(StrSubclass(StrWithStr(OtherStrSubclass('abc'))), + StrSubclass('abc')) + + self.assertTypedEqual(str(WithRepr('')), '') + self.assertTypedEqual(str(WithRepr(StrSubclass(''))), StrSubclass('')) + self.assertTypedEqual(StrSubclass(WithRepr('')), StrSubclass('')) + self.assertTypedEqual(StrSubclass(WithRepr(StrSubclass(''))), + StrSubclass('')) + self.assertTypedEqual(StrSubclass(WithRepr(OtherStrSubclass(''))), + StrSubclass('')) def test_unicode_repr(self): class s1: diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py index 9b663c00223d1b..371e8193b3544d 100644 --- a/Lib/test/test_string_literals.py +++ b/Lib/test/test_string_literals.py @@ -131,6 +131,18 @@ def test_eval_str_invalid_escape(self): self.assertEqual(exc.lineno, 1) self.assertEqual(exc.offset, 1) + # Check that the warning is raised ony once if there are syntax errors + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', category=SyntaxWarning) + with self.assertRaises(SyntaxError) as cm: + eval("'\\e' $") + exc = cm.exception + self.assertEqual(len(w), 1) + self.assertEqual(w[0].category, SyntaxWarning) + self.assertRegex(str(w[0].message), 'invalid escape sequence') + self.assertEqual(w[0].filename, '') + def test_eval_str_invalid_octal_escape(self): for i in range(0o400, 0o1000): with self.assertWarns(SyntaxWarning): diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index c76649cdcd9cce..15f6ee06ffe19b 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -700,20 +700,6 @@ def test__struct_types_immutable(self): with self.assertRaises(TypeError): cls.x = 1 - @support.cpython_only - def test__struct_Struct__new__initialized(self): - # See /~https://github.com/python/cpython/issues/78724 - - s = struct.Struct.__new__(struct.Struct, "b") - s.unpack_from(b"abcd") - - @support.cpython_only - def test__struct_Struct_subclassing(self): - class Bob(struct.Struct): - pass - - s = Bob("b") - s.unpack_from(b"abcd") def test_issue35714(self): # Embedded null characters should not be allowed in format strings. @@ -774,6 +760,15 @@ def test_error_propagation(fmt_str): test_error_propagation('N') test_error_propagation('n') + def test_struct_subclass_instantiation(self): + # Regression test for /~https://github.com/python/cpython/issues/112358 + class MyStruct(struct.Struct): + def __init__(self): + super().__init__('>h') + + my_struct = MyStruct() + self.assertEqual(my_struct.pack(12345), b'\x30\x39') + def test_repr(self): s = struct.Struct('=i2H') self.assertEqual(repr(s), f'Struct({s.format!r})') 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_subclassinit.py b/Lib/test/test_subclassinit.py index 310473a4a2fe58..0d32aa509bd25c 100644 --- a/Lib/test/test_subclassinit.py +++ b/Lib/test/test_subclassinit.py @@ -230,7 +230,7 @@ def __init__(self, name, bases, namespace, otherarg): super().__init__(name, bases, namespace) with self.assertRaises(TypeError): - class MyClass(metaclass=MyMeta, otherarg=1): + class MyClass2(metaclass=MyMeta, otherarg=1): pass class MyMeta(type): @@ -241,10 +241,10 @@ def __init__(self, name, bases, namespace, otherarg): super().__init__(name, bases, namespace) self.otherarg = otherarg - class MyClass(metaclass=MyMeta, otherarg=1): + class MyClass3(metaclass=MyMeta, otherarg=1): pass - self.assertEqual(MyClass.otherarg, 1) + self.assertEqual(MyClass3.otherarg, 1) def test_errors_changed_pep487(self): # These tests failed before Python 3.6, PEP 487 @@ -263,10 +263,10 @@ def __new__(cls, name, bases, namespace, otherarg): self.otherarg = otherarg return self - class MyClass(metaclass=MyMeta, otherarg=1): + class MyClass2(metaclass=MyMeta, otherarg=1): pass - self.assertEqual(MyClass.otherarg, 1) + self.assertEqual(MyClass2.otherarg, 1) def test_type(self): t = type('NewClass', (object,), {}) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index d95ef72b0da47a..5eeea54fd55f1a 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -749,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() @@ -1556,21 +1561,6 @@ def test_class_getitems(self): self.assertIsInstance(subprocess.Popen[bytes], types.GenericAlias) self.assertIsInstance(subprocess.CompletedProcess[str], types.GenericAlias) - @unittest.skipIf(not sysconfig.get_config_var("HAVE_VFORK"), - "vfork() not enabled by configure.") - @mock.patch("subprocess._fork_exec") - def test__use_vfork(self, mock_fork_exec): - self.assertTrue(subprocess._USE_VFORK) # The default value regardless. - mock_fork_exec.side_effect = RuntimeError("just testing args") - with self.assertRaises(RuntimeError): - subprocess.run([sys.executable, "-c", "pass"]) - mock_fork_exec.assert_called_once() - self.assertTrue(mock_fork_exec.call_args.args[-1]) - with mock.patch.object(subprocess, '_USE_VFORK', False): - with self.assertRaises(RuntimeError): - subprocess.run([sys.executable, "-c", "pass"]) - self.assertFalse(mock_fork_exec.call_args_list[-1].args[-1]) - class RunFuncTestCase(BaseTestCase): def run_python(self, code, **kwargs): @@ -1764,9 +1754,9 @@ def test_encoding_warning(self): cp = subprocess.run([sys.executable, "-Xwarn_default_encoding", "-c", code], capture_output=True) lines = cp.stderr.splitlines() - self.assertEqual(len(lines), 2, lines) + self.assertEqual(len(lines), 4, lines) self.assertTrue(lines[0].startswith(b":2: EncodingWarning: ")) - self.assertTrue(lines[1].startswith(b":3: EncodingWarning: ")) + self.assertTrue(lines[2].startswith(b":3: EncodingWarning: ")) def _get_test_grp_name(): @@ -2061,8 +2051,14 @@ def test_group_error(self): def test_extra_groups(self): gid = os.getegid() group_list = [65534 if gid != 65534 else 65533] + self._test_extra_groups_impl(gid=gid, group_list=group_list) + + @unittest.skipUnless(hasattr(os, 'setgroups'), 'no setgroups() on platform') + def test_extra_groups_empty_list(self): + self._test_extra_groups_impl(gid=os.getegid(), group_list=[]) + + def _test_extra_groups_impl(self, *, gid, group_list): name_group = _get_test_grp_name() - perm_error = False if grp is not None: group_list.append(name_group) @@ -2072,11 +2068,8 @@ def test_extra_groups(self): [sys.executable, "-c", "import os, sys, json; json.dump(os.getgroups(), sys.stdout)"], extra_groups=group_list) - except OSError as ex: - if ex.errno != errno.EPERM: - raise - perm_error = True - + except PermissionError: + self.skipTest("setgroup() EPERM; this test may require root.") else: parent_groups = os.getgroups() child_groups = json.loads(output) @@ -2087,12 +2080,15 @@ def test_extra_groups(self): else: desired_gids = group_list - if perm_error: - self.assertEqual(set(child_groups), set(parent_groups)) - else: - self.assertEqual(set(desired_gids), set(child_groups)) + self.assertEqual(set(desired_gids), set(child_groups)) - # make sure we bomb on negative values + if grp is None: + with self.assertRaises(ValueError): + subprocess.check_call(ZERO_RETURN_CMD, + extra_groups=[name_group]) + + # No skip necessary, this test won't make it to a setgroup() call. + def test_extra_groups_invalid_gid_t_values(self): with self.assertRaises(ValueError): subprocess.check_call(ZERO_RETURN_CMD, extra_groups=[-1]) @@ -2101,16 +2097,6 @@ def test_extra_groups(self): cwd=os.curdir, env=os.environ, extra_groups=[2**64]) - if grp is None: - with self.assertRaises(ValueError): - subprocess.check_call(ZERO_RETURN_CMD, - extra_groups=[name_group]) - - @unittest.skipIf(hasattr(os, 'setgroups'), 'setgroups() available on platform') - def test_extra_groups_error(self): - with self.assertRaises(ValueError): - subprocess.check_call(ZERO_RETURN_CMD, extra_groups=[]) - @unittest.skipIf(mswindows or not hasattr(os, 'umask'), 'POSIX umask() is not available.') def test_umask(self): @@ -3359,6 +3345,89 @@ def exit_handler(): self.assertEqual(out, b'') self.assertIn(b"preexec_fn not supported at interpreter shutdown", err) + @unittest.skipIf(not sysconfig.get_config_var("HAVE_VFORK"), + "vfork() not enabled by configure.") + @mock.patch("subprocess._fork_exec") + def test__use_vfork(self, mock_fork_exec): + self.assertTrue(subprocess._USE_VFORK) # The default value regardless. + mock_fork_exec.side_effect = RuntimeError("just testing args") + with self.assertRaises(RuntimeError): + subprocess.run([sys.executable, "-c", "pass"]) + mock_fork_exec.assert_called_once() + # NOTE: These assertions are *ugly* as they require the last arg + # to remain the have_vfork boolean. We really need to refactor away + # from the giant "wall of args" internal C extension API. + self.assertTrue(mock_fork_exec.call_args.args[-1]) + with mock.patch.object(subprocess, '_USE_VFORK', False): + with self.assertRaises(RuntimeError): + subprocess.run([sys.executable, "-c", "pass"]) + self.assertFalse(mock_fork_exec.call_args_list[-1].args[-1]) + + @unittest.skipIf(not sysconfig.get_config_var("HAVE_VFORK"), + "vfork() not enabled by configure.") + @unittest.skipIf(sys.platform != "linux", "Linux only, requires strace.") + def test_vfork_used_when_expected(self): + # This is a performance regression test to ensure we default to using + # vfork() when possible. + strace_binary = "/usr/bin/strace" + # The only system calls we are interested in. + strace_filter = "--trace=clone,clone2,clone3,fork,vfork,exit,exit_group" + true_binary = "/bin/true" + strace_command = [strace_binary, strace_filter] + + try: + does_strace_work_process = subprocess.run( + strace_command + [true_binary], + stderr=subprocess.PIPE, + stdout=subprocess.DEVNULL, + ) + rc = does_strace_work_process.returncode + stderr = does_strace_work_process.stderr + except OSError: + rc = -1 + stderr = "" + if rc or (b"+++ exited with 0 +++" not in stderr): + self.skipTest("strace not found or not working as expected.") + + with self.subTest(name="default_is_vfork"): + vfork_result = assert_python_ok( + "-c", + textwrap.dedent(f"""\ + import subprocess + subprocess.check_call([{true_binary!r}])"""), + __run_using_command=strace_command, + ) + # Match both vfork() and clone(..., flags=...|CLONE_VFORK|...) + self.assertRegex(vfork_result.err, br"(?i)vfork") + # Do NOT check that fork() or other clones did not happen. + # If the OS denys the vfork it'll fallback to plain fork(). + + # Test that each individual thing that would disable the use of vfork + # actually disables it. + for sub_name, preamble, sp_kwarg, expect_permission_error in ( + ("!use_vfork", "subprocess._USE_VFORK = False", "", False), + ("preexec", "", "preexec_fn=lambda: None", False), + ("setgid", "", f"group={os.getgid()}", True), + ("setuid", "", f"user={os.getuid()}", True), + ("setgroups", "", "extra_groups=[]", True), + ): + with self.subTest(name=sub_name): + non_vfork_result = assert_python_ok( + "-c", + textwrap.dedent(f"""\ + import subprocess + {preamble} + try: + subprocess.check_call( + [{true_binary!r}], **dict({sp_kwarg})) + except PermissionError: + if not {expect_permission_error}: + raise"""), + __run_using_command=strace_command, + ) + # Ensure neither vfork() or clone(..., flags=...|CLONE_VFORK|...). + self.assertNotRegex(non_vfork_result.err, br"(?i)vfork") + @unittest.skipUnless(mswindows, "Windows specific tests") class Win32ProcessTestCase(BaseTestCase): diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 902bec78451307..c34b0e5e015702 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -547,111 +547,6 @@ def test_optim_args_from_interpreter_flags(self): with self.subTest(opts=opts): self.check_options(opts, 'optim_args_from_interpreter_flags') - def test_match_test(self): - class Test: - def __init__(self, test_id): - self.test_id = test_id - - def id(self): - return self.test_id - - test_access = Test('test.test_os.FileTests.test_access') - test_chdir = Test('test.test_os.Win32ErrorTests.test_chdir') - - # Test acceptance - with support.swap_attr(support, '_match_test_func', None): - # match all - support.set_match_tests([]) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # match all using None - support.set_match_tests(None, None) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # match the full test identifier - support.set_match_tests([test_access.id()], None) - self.assertTrue(support.match_test(test_access)) - self.assertFalse(support.match_test(test_chdir)) - - # match the module name - support.set_match_tests(['test_os'], None) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # Test '*' pattern - support.set_match_tests(['test_*'], None) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # Test case sensitivity - support.set_match_tests(['filetests'], None) - self.assertFalse(support.match_test(test_access)) - support.set_match_tests(['FileTests'], None) - self.assertTrue(support.match_test(test_access)) - - # Test pattern containing '.' and a '*' metacharacter - support.set_match_tests(['*test_os.*.test_*'], None) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # Multiple patterns - support.set_match_tests([test_access.id(), test_chdir.id()], None) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - support.set_match_tests(['test_access', 'DONTMATCH'], None) - self.assertTrue(support.match_test(test_access)) - self.assertFalse(support.match_test(test_chdir)) - - # Test rejection - with support.swap_attr(support, '_match_test_func', None): - # match all - support.set_match_tests(ignore_patterns=[]) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # match all using None - support.set_match_tests(None, None) - self.assertTrue(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # match the full test identifier - support.set_match_tests(None, [test_access.id()]) - self.assertFalse(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - - # match the module name - support.set_match_tests(None, ['test_os']) - self.assertFalse(support.match_test(test_access)) - self.assertFalse(support.match_test(test_chdir)) - - # Test '*' pattern - support.set_match_tests(None, ['test_*']) - self.assertFalse(support.match_test(test_access)) - self.assertFalse(support.match_test(test_chdir)) - - # Test case sensitivity - support.set_match_tests(None, ['filetests']) - self.assertTrue(support.match_test(test_access)) - support.set_match_tests(None, ['FileTests']) - self.assertFalse(support.match_test(test_access)) - - # Test pattern containing '.' and a '*' metacharacter - support.set_match_tests(None, ['*test_os.*.test_*']) - self.assertFalse(support.match_test(test_access)) - self.assertFalse(support.match_test(test_chdir)) - - # Multiple patterns - support.set_match_tests(None, [test_access.id(), test_chdir.id()]) - self.assertFalse(support.match_test(test_access)) - self.assertFalse(support.match_test(test_chdir)) - - support.set_match_tests(None, ['test_access', 'DONTMATCH']) - self.assertFalse(support.match_test(test_access)) - self.assertTrue(support.match_test(test_chdir)) - @unittest.skipIf(support.is_emscripten, "Unstable in Emscripten") @unittest.skipIf(support.is_wasi, "Unavailable on WASI") def test_fd_count(self): @@ -832,7 +727,7 @@ def test_copy_python_src_ignore(self): self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), ignored | {'build', 'venv'}) - # An other directory + # Another directory path = os.path.join(src_dir, 'Objects') self.assertEqual(support.copy_python_src_ignore(path, os.listdir(path)), ignored) @@ -852,7 +747,6 @@ def test_copy_python_src_ignore(self): # precisionbigmemtest # bigaddrspacetest # requires_resource - # run_doctest # threading_cleanup # reap_threads # can_symlink diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 82c1d7c856a1e5..987e9e32afc325 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -4,6 +4,8 @@ import symtable import unittest +from test import support +from test.support import os_helper TEST_CODE = """ @@ -282,10 +284,62 @@ def test_symtable_repr(self): self.assertEqual(str(self.top), "") self.assertEqual(str(self.spam), "") + def test_symbol_repr(self): + self.assertEqual(repr(self.spam.lookup("glob")), + "") + self.assertEqual(repr(self.spam.lookup("bar")), + "") + self.assertEqual(repr(self.spam.lookup("a")), + "") + self.assertEqual(repr(self.spam.lookup("internal")), + "") + self.assertEqual(repr(self.spam.lookup("other_internal")), + "") + self.assertEqual(repr(self.internal.lookup("x")), + "") + self.assertEqual(repr(self.other_internal.lookup("some_var")), + "") + def test_symtable_entry_repr(self): expected = f"" self.assertEqual(repr(self.top._table), expected) +class CommandLineTest(unittest.TestCase): + maxDiff = None + + def test_file(self): + filename = os_helper.TESTFN + self.addCleanup(os_helper.unlink, filename) + with open(filename, 'w') as f: + f.write(TEST_CODE) + with support.captured_stdout() as stdout: + symtable.main([filename]) + out = stdout.getvalue() + self.assertIn('\n\n', out) + self.assertNotIn('\n\n\n', out) + lines = out.splitlines() + self.assertIn(f"symbol table for module from file {filename!r}:", lines) + self.assertIn(" local symbol 'glob': def_local", lines) + self.assertIn(" global_implicit symbol 'glob': use", lines) + self.assertIn(" local symbol 'spam': def_local", lines) + self.assertIn(" symbol table for function 'spam':", lines) + + def test_stdin(self): + with support.captured_stdin() as stdin: + stdin.write(TEST_CODE) + stdin.seek(0) + with support.captured_stdout() as stdout: + symtable.main([]) + out = stdout.getvalue() + stdin.seek(0) + with support.captured_stdout() as stdout: + symtable.main(['-']) + self.assertEqual(stdout.getvalue(), out) + lines = out.splitlines() + print(out) + self.assertIn("symbol table for module from file '':", lines) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 4c988382f8b411..ece1366076798c 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1004,11 +1004,26 @@ Traceback (most recent call last): SyntaxError: expected ':' + >>> def f[T]() + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + >>> class A ... pass Traceback (most recent call last): SyntaxError: expected ':' + >>> class A[T] + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + + >>> class A[T]() + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + >>> class R&D: ... pass Traceback (most recent call last): @@ -1446,11 +1461,21 @@ Traceback (most recent call last): IndentationError: expected an indented block after function definition on line 1 + >>> def foo[T](x, /, y, *, z=2): + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after function definition on line 1 + >>> class Blech(A): ... pass Traceback (most recent call last): IndentationError: expected an indented block after class definition on line 1 + >>> class Blech[T](A): + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after class definition on line 1 + >>> match something: ... pass Traceback (most recent call last): @@ -1727,6 +1752,28 @@ Traceback (most recent call last): SyntaxError: positional patterns follow keyword patterns +Non-matching 'elif'/'else' statements: + + >>> if a == b: + ... ... + ... elif a == c: + Traceback (most recent call last): + SyntaxError: 'elif' must match an if-statement here + + >>> if x == y: + ... ... + ... else: + Traceback (most recent call last): + SyntaxError: 'else' must match a valid statement here + + >>> elif m == n: + Traceback (most recent call last): + SyntaxError: 'elif' must match an if-statement here + + >>> else: + Traceback (most recent call last): + SyntaxError: 'else' must match a valid statement here + Uses of the star operator which should fail: A[:*b] @@ -1955,6 +2002,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 @@ -1970,8 +2028,8 @@ def _check_error(self, code, errtext, lineno=None, offset=None, end_lineno=None, end_offset=None): """Check that compiling code raises SyntaxError with errtext. - errtest is a regular expression that must be present in the - test of the exception raised. If subclass is specified it + errtext is a regular expression that must be present in the + test of the exception raised. If subclass is specified, it is the expected subclass of SyntaxError (e.g. IndentationError). """ try: @@ -1995,6 +2053,22 @@ def _check_error(self, code, errtext, else: self.fail("compile() did not raise SyntaxError") + def _check_noerror(self, code, + errtext="compile() raised unexpected SyntaxError", + filename="", mode="exec", subclass=None): + """Check that compiling code does not raise a SyntaxError. + + errtext is the message passed to self.fail if there is + a SyntaxError. If the subclass parameter is specified, + it is the subclass of SyntaxError (e.g. IndentationError) + that the raised error is checked against. + """ + try: + compile(code, filename, mode) + except SyntaxError as err: + if (not subclass) or isinstance(err, subclass): + self.fail(errtext) + def test_expression_with_assignment(self): self._check_error( "print(end1 + end2 = ' ')", @@ -2260,15 +2334,26 @@ def test_error_parenthesis(self): """ self._check_error(code, "parenthesis '\\)' does not match opening parenthesis '\\['") + # Examples with dencodings + s = b'# coding=latin\n(aaaaaaaaaaaaaaaaa\naaaaaaaaaaa\xb5' + self._check_error(s, r"'\(' was never closed") + def test_error_string_literal(self): - self._check_error("'blech", "unterminated string literal") - self._check_error('"blech', "unterminated string literal") + self._check_error("'blech", r"unterminated string literal \(.*\)$") + self._check_error('"blech', r"unterminated string literal \(.*\)$") + self._check_error( + r'"blech\"', r"unterminated string literal \(.*\); perhaps you escaped the end quote" + ) + self._check_error( + r'r"blech\"', r"unterminated string literal \(.*\); perhaps you escaped the end quote" + ) self._check_error("'''blech", "unterminated triple-quoted string literal") self._check_error('"""blech', "unterminated triple-quoted string literal") def test_invisible_characters(self): self._check_error('print\x17("Hello")', "invalid non-printable character") + self._check_error(b"with(0,,):\n\x01", "invalid non-printable character") def test_match_call_does_not_raise_syntax_error(self): code = """ @@ -2330,6 +2415,25 @@ def test_syntax_error_on_deeply_nested_blocks(self): """ self._check_error(source, "too many statically nested blocks") + def test_syntax_error_non_matching_elif_else_statements(self): + # Check bpo-45759: 'elif' statements that doesn't match an + # if-statement or 'else' statements that doesn't match any + # valid else-able statement (e.g. 'while') + self._check_error( + "elif m == n:\n ...", + "'elif' must match an if-statement here") + self._check_error( + "else:\n ...", + "'else' must match a valid statement here") + self._check_noerror("if a == b:\n ...\nelif a == c:\n ...") + self._check_noerror("if x == y:\n ...\nelse:\n ...") + self._check_error( + "else = 123", + "invalid syntax") + self._check_error( + "elif 55 = 123", + "cannot assign to literal here") + @support.cpython_only def test_error_on_parser_stack_overflow(self): source = "-" * 100000 + "4" diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 16050171ad139d..6c87dfabad9f0f 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -5,6 +5,7 @@ import locale import operator import os +import random import struct import subprocess import sys @@ -30,10 +31,6 @@ def requires_subinterpreters(meth): 'subinterpreters required')(meth) -# count the number of test runs, used to create unique -# strings to intern in test_intern() -INTERN_NUMRUNS = 0 - DICT_KEY_STRUCT_FORMAT = 'n2BI2n' class DisplayHookTest(unittest.TestCase): @@ -178,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()) @@ -513,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 @@ -522,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] @@ -696,13 +691,23 @@ def test_43581(self): self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding) def test_intern(self): - global INTERN_NUMRUNS - INTERN_NUMRUNS += 1 + has_is_interned = (test.support.check_impl_detail(cpython=True) + or hasattr(sys, '_is_interned')) self.assertRaises(TypeError, sys.intern) - s = "never interned before" + str(INTERN_NUMRUNS) + self.assertRaises(TypeError, sys.intern, b'abc') + if has_is_interned: + self.assertRaises(TypeError, sys._is_interned) + self.assertRaises(TypeError, sys._is_interned, b'abc') + s = "never interned before" + str(random.randrange(0, 10**9)) self.assertTrue(sys.intern(s) is s) + if has_is_interned: + self.assertIs(sys._is_interned(s), True) s2 = s.swapcase().swapcase() + if has_is_interned: + self.assertIs(sys._is_interned(s2), False) self.assertTrue(sys.intern(s2) is s) + if has_is_interned: + self.assertIs(sys._is_interned(s2), False) # Subclasses of string can't be interned, because they # provide too much opportunity for insane things to happen. @@ -714,17 +719,17 @@ def __hash__(self): return 123 self.assertRaises(TypeError, sys.intern, S("abc")) + if has_is_interned: + self.assertIs(sys._is_interned(S("abc")), False) @requires_subinterpreters def test_subinterp_intern_dynamically_allocated(self): - global INTERN_NUMRUNS - INTERN_NUMRUNS += 1 - s = "never interned before" + str(INTERN_NUMRUNS) + 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''' + interp.exec_sync(textwrap.dedent(f''' import sys t = sys.intern({s!r}) assert id(t) != {id(s)}, (id(t), {id(s)}) @@ -739,7 +744,7 @@ def test_subinterp_intern_statically_allocated(self): t = sys.intern(s) interp = interpreters.create() - interp.run(textwrap.dedent(f''' + interp.exec_sync(textwrap.dedent(f''' import sys t = sys.intern({s!r}) assert id(t) == {id(t)}, (id(t), {id(t)}) @@ -1123,14 +1128,20 @@ def check(tracebacklimit, expected): traceback = [ b'Traceback (most recent call last):', b' File "", line 8, in ', + b' f2()', + b' ~~^^', b' File "", line 6, in f2', + b' f1()', + b' ~~^^', b' File "", line 4, in f1', + b' 1 / 0', + b' ~~^~~', b'ZeroDivisionError: division by zero' ] check(10, traceback) check(3, traceback) - check(2, traceback[:1] + traceback[2:]) - check(1, traceback[:1] + traceback[3:]) + check(2, traceback[:1] + traceback[4:]) + check(1, traceback[:1] + traceback[7:]) check(0, [traceback[-1]]) check(-1, [traceback[-1]]) check(1<<1000, traceback) @@ -1213,45 +1224,43 @@ def test_pystats(self): @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) + self.assertEqual('t' in sys.abiflags, support.Py_GIL_DISABLED) @test.support.cpython_only class UnraisableHookTest(unittest.TestCase): - def write_unraisable_exc(self, exc, err_msg, obj): - import _testinternalcapi - import types - err_msg2 = f"Exception ignored {err_msg}" - try: - _testinternalcapi.write_unraisable_exc(exc, err_msg, obj) - return types.SimpleNamespace(exc_type=type(exc), - exc_value=exc, - exc_traceback=exc.__traceback__, - err_msg=err_msg2, - object=obj) - finally: - # Explicitly break any reference cycle - exc = None - def test_original_unraisablehook(self): - for err_msg in (None, "original hook"): - with self.subTest(err_msg=err_msg): - obj = "an object" - - with test.support.captured_output("stderr") as stderr: - with test.support.swap_attr(sys, 'unraisablehook', - sys.__unraisablehook__): - self.write_unraisable_exc(ValueError(42), err_msg, obj) - - err = stderr.getvalue() - if err_msg is not None: - self.assertIn(f'Exception ignored {err_msg}: {obj!r}\n', err) - else: - self.assertIn(f'Exception ignored in: {obj!r}\n', err) - self.assertIn('Traceback (most recent call last):\n', err) - self.assertIn('ValueError: 42\n', err) + _testcapi = import_helper.import_module('_testcapi') + from _testcapi import err_writeunraisable, err_formatunraisable + obj = hex + + with support.swap_attr(sys, 'unraisablehook', + sys.__unraisablehook__): + with support.captured_stderr() as stderr: + err_writeunraisable(ValueError(42), obj) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], f'Exception ignored in: {obj!r}') + self.assertEqual(lines[1], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], 'ValueError: 42') + + with support.captured_stderr() as stderr: + err_writeunraisable(ValueError(42), None) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], 'ValueError: 42') + + with support.captured_stderr() as stderr: + err_formatunraisable(ValueError(42), 'Error in %R', obj) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], f'Error in {obj!r}:') + self.assertEqual(lines[1], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], 'ValueError: 42') + + with support.captured_stderr() as stderr: + err_formatunraisable(ValueError(42), None) + lines = stderr.getvalue().splitlines() + self.assertEqual(lines[0], 'Traceback (most recent call last):') + self.assertEqual(lines[-1], 'ValueError: 42') def test_original_unraisablehook_err(self): # bpo-22836: PyErr_WriteUnraisable() should give sensible reports @@ -1298,6 +1307,8 @@ def test_original_unraisablehook_exception_qualname(self): # Check that the exception is printed with its qualified name # rather than just classname, and the module names appears # unless it is one of the hard-coded exclusions. + _testcapi = import_helper.import_module('_testcapi') + from _testcapi import err_writeunraisable class A: class B: class X(Exception): @@ -1309,9 +1320,7 @@ class X(Exception): with test.support.captured_stderr() as stderr, test.support.swap_attr( sys, 'unraisablehook', sys.__unraisablehook__ ): - expected = self.write_unraisable_exc( - A.B.X(), "msg", "obj" - ) + err_writeunraisable(A.B.X(), "obj") report = stderr.getvalue() self.assertIn(A.B.X.__qualname__, report) if moduleName in ['builtins', '__main__']: @@ -1327,34 +1336,45 @@ def test_original_unraisablehook_wrong_type(self): sys.unraisablehook(exc) def test_custom_unraisablehook(self): + _testcapi = import_helper.import_module('_testcapi') + from _testcapi import err_writeunraisable, err_formatunraisable hook_args = None def hook_func(args): nonlocal hook_args hook_args = args - obj = object() + obj = hex try: with test.support.swap_attr(sys, 'unraisablehook', hook_func): - expected = self.write_unraisable_exc(ValueError(42), - "custom hook", obj) - for attr in "exc_type exc_value exc_traceback err_msg object".split(): - self.assertEqual(getattr(hook_args, attr), - getattr(expected, attr), - (hook_args, expected)) + exc = ValueError(42) + err_writeunraisable(exc, obj) + self.assertIs(hook_args.exc_type, type(exc)) + self.assertIs(hook_args.exc_value, exc) + self.assertIs(hook_args.exc_traceback, exc.__traceback__) + self.assertIsNone(hook_args.err_msg) + self.assertEqual(hook_args.object, obj) + + err_formatunraisable(exc, "custom hook %R", obj) + self.assertIs(hook_args.exc_type, type(exc)) + self.assertIs(hook_args.exc_value, exc) + self.assertIs(hook_args.exc_traceback, exc.__traceback__) + self.assertEqual(hook_args.err_msg, f'custom hook {obj!r}') + self.assertIsNone(hook_args.object) finally: # expected and hook_args contain an exception: break reference cycle expected = None hook_args = None def test_custom_unraisablehook_fail(self): + _testcapi = import_helper.import_module('_testcapi') + from _testcapi import err_writeunraisable def hook_func(*args): raise Exception("hook_func failed") with test.support.captured_output("stderr") as stderr: with test.support.swap_attr(sys, 'unraisablehook', hook_func): - self.write_unraisable_exc(ValueError(42), - "custom hook fail", None) + err_writeunraisable(ValueError(42), "custom hook fail") err = stderr.getvalue() self.assertIn(f'Exception ignored in sys.unraisablehook: ' diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 34c70d6c8de0c4..32e03d7cd25dbe 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -30,9 +30,9 @@ def callback(self, frame, event, arg): if (event == "call" or event == "return" or event == "exception"): - self.add_event(event, frame) + self.add_event(event, frame, arg) - def add_event(self, event, frame=None): + def add_event(self, event, frame=None, arg=None): """Add an event to the log.""" if frame is None: frame = sys._getframe(1) @@ -43,7 +43,7 @@ def add_event(self, event, frame=None): frameno = len(self.frames) self.frames.append(frame) - self.events.append((frameno, event, ident(frame))) + self.events.append((frameno, event, ident(frame), arg)) def get_events(self): """Remove calls to add_event().""" @@ -89,11 +89,16 @@ def trace_pass(self, frame): class TestCaseBase(unittest.TestCase): - def check_events(self, callable, expected): + def check_events(self, callable, expected, check_args=False): events = capture_events(callable, self.new_watcher()) - if events != expected: - self.fail("Expected events:\n%s\nReceived events:\n%s" - % (pprint.pformat(expected), pprint.pformat(events))) + if check_args: + if events != expected: + self.fail("Expected events:\n%s\nReceived events:\n%s" + % (pprint.pformat(expected), pprint.pformat(events))) + else: + if [(frameno, event, ident) for frameno, event, ident, arg in events] != expected: + self.fail("Expected events:\n%s\nReceived events:\n%s" + % (pprint.pformat(expected), pprint.pformat(events))) class ProfileHookTestCase(TestCaseBase): @@ -255,6 +260,21 @@ 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, None), + (2, 'call', f_ident, None), + (2, 'return', f_ident, 0), + (1, 'return', g_ident, None), + ], check_args=True) + def test_stop_iteration(self): def f(): for i in range(2): diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index f02169602e4925..fc5ca72236b1fb 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -9,6 +9,15 @@ import asyncio from test.support import import_helper import contextlib +import os +import tempfile +import textwrap +import subprocess +import warnings +try: + import _testinternalcapi +except ImportError: + _testinternalcapi = None support.requires_working_socket(module=True) @@ -1801,6 +1810,39 @@ def compare_events(self, line_offset, events, expected_events): def make_tracer(): return Tracer(trace_opcode_events=True) + def test_trace_opcodes_after_settrace(self): + """Make sure setting f_trace_opcodes after starting trace works even + if it's the first time f_trace_opcodes is being set. GH-103615""" + + code = textwrap.dedent(""" + import sys + + def opcode_trace_func(frame, event, arg): + if event == "opcode": + print("opcode trace triggered") + return opcode_trace_func + + sys.settrace(opcode_trace_func) + sys._getframe().f_trace = opcode_trace_func + sys._getframe().f_trace_opcodes = True + a = 1 + """) + + # We can't use context manager because Windows can't execute a file while + # it's being written + tmp = tempfile.NamedTemporaryFile(delete=False, suffix='.py') + tmp.write(code.encode('utf-8')) + tmp.close() + try: + p = subprocess.Popen([sys.executable, tmp.name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p.wait() + out = p.stdout.read() + finally: + os.remove(tmp.name) + p.stdout.close() + p.stderr.close() + self.assertIn(b"opcode trace triggered", out) + class RaisingTraceFuncTestCase(unittest.TestCase): def setUp(self): @@ -2001,6 +2043,9 @@ def run_test(self, func, jumpFrom, jumpTo, expected, error=None, stack.enter_context(self.assertRaisesRegex(*error)) if warning is not None: stack.enter_context(self.assertWarnsRegex(*warning)) + else: + stack.enter_context(warnings.catch_warnings()) + warnings.simplefilter('error') func(output) sys.settrace(None) @@ -2064,6 +2109,40 @@ def test_jump_simple_backwards(output): output.append(1) output.append(2) + @jump_test(1, 4, [5], warning=(RuntimeWarning, unbound_locals)) + def test_jump_is_none_forwards(output): + x = None + if x is None: + output.append(3) + else: + output.append(5) + + @jump_test(6, 5, [3, 5, 6]) + def test_jump_is_none_backwards(output): + x = None + if x is None: + output.append(3) + else: + output.append(5) + output.append(6) + + @jump_test(2, 4, [5]) + def test_jump_is_not_none_forwards(output): + x = None + if x is not None: + output.append(3) + else: + output.append(5) + + @jump_test(6, 5, [5, 5, 6]) + def test_jump_is_not_none_backwards(output): + x = None + if x is not None: + output.append(3) + else: + output.append(5) + output.append(6) + @jump_test(3, 5, [2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_block_forwards(output): for i in 1, 2: @@ -2958,16 +3037,21 @@ def test_trace_unpack_long_sequence(self): self.assertEqual(counts, {'call': 1, 'line': 301, 'return': 1}) def test_trace_lots_of_globals(self): + count = 1000 + if _testinternalcapi is not None: + remaining = _testinternalcapi.get_c_recursion_remaining() + count = min(count, remaining) + code = """if 1: def f(): return ( {} ) - """.format("\n+\n".join(f"var{i}\n" for i in range(1000))) - ns = {f"var{i}": i for i in range(1000)} + """.format("\n+\n".join(f"var{i}\n" for i in range(count))) + ns = {f"var{i}": i for i in range(count)} exec(code, ns) counts = self.count_traces(ns["f"]) - self.assertEqual(counts, {'call': 1, 'line': 2000, 'return': 1}) + self.assertEqual(counts, {'call': 1, 'line': count * 2, 'return': 1}) class TestEdgeCases(unittest.TestCase): diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index b6dbf3d52cb4c3..a19c04b1b2cde5 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): @@ -451,11 +472,15 @@ def test_srcdir(self): # should be a full source checkout. Python_h = os.path.join(srcdir, 'Include', 'Python.h') self.assertTrue(os.path.exists(Python_h), Python_h) - # /PC/pyconfig.h always exists even if unused on POSIX. - pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h') + # /PC/pyconfig.h.in always exists even if unused + pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h.in') self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in') self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in) + if os.name == 'nt': + # /pyconfig.h exists on Windows in a build tree + pyconfig_h = os.path.join(sys.executable, '..', 'pyconfig.h') + self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) elif os.name == 'posix': makefile_dir = os.path.dirname(sysconfig.get_makefile_filename()) # Issue #19340: srcdir has been realpath'ed already @@ -472,10 +497,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 +544,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 cc26da05daeafc..761560bfbf8b53 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -43,7 +43,7 @@ def sha256sum(data): TEMPDIR = os.path.abspath(os_helper.TESTFN) + "-tardir" tarextdir = TEMPDIR + '-extract-test' -tarname = support.findfile("testtar.tar") +tarname = support.findfile("testtar.tar", subdir="archivetestdata") gzipname = os.path.join(TEMPDIR, "testtar.tar.gz") bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2") xzname = os.path.join(TEMPDIR, "testtar.tar.xz") @@ -491,7 +491,7 @@ def test_length_zero_header(self): # bpo-39017 (CVE-2019-20907): reading a zero-length header should fail # with an exception with self.assertRaisesRegex(tarfile.ReadError, "file could not be opened successfully"): - with tarfile.open(support.findfile('recursion.tar')) as tar: + with tarfile.open(support.findfile('recursion.tar', subdir='archivetestdata')): pass def test_extractfile_name(self): @@ -2565,7 +2565,7 @@ def test__all__(self): support.check__all__(self, tarfile, not_exported=not_exported) def test_useful_error_message_when_modules_missing(self): - fname = os.path.join(os.path.dirname(__file__), 'testtar.tar.xz') + fname = os.path.join(os.path.dirname(__file__), 'archivetestdata', 'testtar.tar.xz') with self.assertRaises(tarfile.ReadError) as excinfo: error = tarfile.CompressionError('lzma module is not available'), with unittest.mock.patch.object(tarfile.TarFile, 'xzopen', side_effect=error): @@ -2630,7 +2630,7 @@ def test_test_command_verbose(self): self.assertIn(b'is a tar archive.\n', out) def test_test_command_invalid_file(self): - zipname = support.findfile('zipdir.zip') + zipname = support.findfile('zipdir.zip', subdir='archivetestdata') rc, out, err = self.tarfilecmd_failure('-t', zipname) self.assertIn(b' is not a tar archive.', err) self.assertEqual(out, b'') @@ -2672,7 +2672,7 @@ def test_list_command_verbose(self): self.assertEqual(out, expected) def test_list_command_invalid_file(self): - zipname = support.findfile('zipdir.zip') + zipname = support.findfile('zipdir.zip', subdir='archivetestdata') rc, out, err = self.tarfilecmd_failure('-l', zipname) self.assertIn(b' is not a tar archive.', err) self.assertEqual(out, b'') @@ -2797,7 +2797,7 @@ def test_extract_command_different_directory(self): os_helper.rmtree(tarextdir) def test_extract_command_invalid_file(self): - zipname = support.findfile('zipdir.zip') + zipname = support.findfile('zipdir.zip', subdir='archivetestdata') with os_helper.temp_cwd(tarextdir): rc, out, err = self.tarfilecmd_failure('-e', zipname) self.assertIn(b' is not a tar archive.', err) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 1673507e2f7c91..b64b6a4f2baeb5 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1641,6 +1641,28 @@ def test_explicit_cleanup_ignore_errors(self): temp_path.exists(), f"TemporaryDirectory {temp_path!s} exists after cleanup") + @unittest.skipUnless(os.name == "nt", "Only on Windows.") + def test_explicit_cleanup_correct_error(self): + with tempfile.TemporaryDirectory() as working_dir: + temp_dir = self.do_create(dir=working_dir) + with open(os.path.join(temp_dir.name, "example.txt"), 'wb'): + # Previously raised NotADirectoryError on some OSes + # (e.g. Windows). See bpo-43153. + with self.assertRaises(PermissionError): + temp_dir.cleanup() + + @unittest.skipUnless(os.name == "nt", "Only on Windows.") + def test_cleanup_with_used_directory(self): + with tempfile.TemporaryDirectory() as working_dir: + temp_dir = self.do_create(dir=working_dir) + subdir = os.path.join(temp_dir.name, "subdir") + os.mkdir(subdir) + with os_helper.change_cwd(subdir): + # Previously raised RecursionError on some OSes + # (e.g. Windows). See bpo-35144. + with self.assertRaises(PermissionError): + temp_dir.cleanup() + @os_helper.skip_unless_symlink def test_cleanup_with_symlink_to_a_directory(self): # cleanup() should not follow symlinks to directories (issue #12464) @@ -1662,6 +1684,103 @@ def test_cleanup_with_symlink_to_a_directory(self): "were deleted") d2.cleanup() + @os_helper.skip_unless_symlink + def test_cleanup_with_symlink_modes(self): + # cleanup() should not follow symlinks when fixing mode bits (#91133) + with self.do_create(recurse=0) as d2: + file1 = os.path.join(d2, 'file1') + open(file1, 'wb').close() + dir1 = os.path.join(d2, 'dir1') + os.mkdir(dir1) + for mode in range(8): + mode <<= 6 + with self.subTest(mode=format(mode, '03o')): + def test(target, target_is_directory): + d1 = self.do_create(recurse=0) + symlink = os.path.join(d1.name, 'symlink') + os.symlink(target, symlink, + target_is_directory=target_is_directory) + try: + os.chmod(symlink, mode, follow_symlinks=False) + except NotImplementedError: + pass + try: + os.chmod(symlink, mode) + except FileNotFoundError: + pass + os.chmod(d1.name, mode) + d1.cleanup() + self.assertFalse(os.path.exists(d1.name)) + + with self.subTest('nonexisting file'): + test('nonexisting', target_is_directory=False) + with self.subTest('nonexisting dir'): + test('nonexisting', target_is_directory=True) + + with self.subTest('existing file'): + os.chmod(file1, mode) + old_mode = os.stat(file1).st_mode + test(file1, target_is_directory=False) + new_mode = os.stat(file1).st_mode + self.assertEqual(new_mode, old_mode, + '%03o != %03o' % (new_mode, old_mode)) + + with self.subTest('existing dir'): + os.chmod(dir1, mode) + old_mode = os.stat(dir1).st_mode + test(dir1, target_is_directory=True) + new_mode = os.stat(dir1).st_mode + self.assertEqual(new_mode, old_mode, + '%03o != %03o' % (new_mode, old_mode)) + + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') + @os_helper.skip_unless_symlink + def test_cleanup_with_symlink_flags(self): + # cleanup() should not follow symlinks when fixing flags (#91133) + flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + self.check_flags(flags) + + with self.do_create(recurse=0) as d2: + file1 = os.path.join(d2, 'file1') + open(file1, 'wb').close() + dir1 = os.path.join(d2, 'dir1') + os.mkdir(dir1) + def test(target, target_is_directory): + d1 = self.do_create(recurse=0) + symlink = os.path.join(d1.name, 'symlink') + os.symlink(target, symlink, + target_is_directory=target_is_directory) + try: + os.chflags(symlink, flags, follow_symlinks=False) + except NotImplementedError: + pass + try: + os.chflags(symlink, flags) + except FileNotFoundError: + pass + os.chflags(d1.name, flags) + d1.cleanup() + self.assertFalse(os.path.exists(d1.name)) + + with self.subTest('nonexisting file'): + test('nonexisting', target_is_directory=False) + with self.subTest('nonexisting dir'): + test('nonexisting', target_is_directory=True) + + with self.subTest('existing file'): + os.chflags(file1, flags) + old_flags = os.stat(file1).st_flags + test(file1, target_is_directory=False) + new_flags = os.stat(file1).st_flags + self.assertEqual(new_flags, old_flags) + + with self.subTest('existing dir'): + os.chflags(dir1, flags) + old_flags = os.stat(dir1).st_flags + test(dir1, target_is_directory=True) + new_flags = os.stat(dir1).st_flags + self.assertEqual(new_flags, old_flags) + @support.cpython_only def test_del_on_collection(self): # A TemporaryDirectory is deleted when garbage collected @@ -1834,10 +1953,7 @@ def test_modes(self): d.cleanup() self.assertFalse(os.path.exists(d.name)) - @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') - def test_flags(self): - flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK - + def check_flags(self, flags): # skip the test if these flags are not supported (ex: FreeBSD 13) filename = os_helper.TESTFN try: @@ -1846,13 +1962,18 @@ def test_flags(self): 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}") + self.skipTest(f"chflags() doesn't support flags " + f"{flags:#b}: {exc}") else: os.chflags(filename, 0) finally: os_helper.unlink(filename) + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') + def test_flags(self): + flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + self.check_flags(flags) + 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_thread.py b/Lib/test/test_thread.py index 8656fbdd83e9c7..931cb4b797e0b2 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -155,11 +155,137 @@ def task(): started.acquire() self.assertEqual(str(cm.unraisable.exc_value), "task failed") - self.assertIs(cm.unraisable.object, task) + self.assertIsNone(cm.unraisable.object) self.assertEqual(cm.unraisable.err_msg, - "Exception ignored in thread started by") + f"Exception ignored in thread started by {task!r}") self.assertIsNotNone(cm.unraisable.exc_traceback) + def test_join_thread(self): + finished = [] + + def task(): + time.sleep(0.05) + finished.append(thread.get_ident()) + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + handle.join() + self.assertEqual(len(finished), 1) + self.assertEqual(handle.ident, finished[0]) + + def test_join_thread_already_exited(self): + def task(): + pass + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + time.sleep(0.05) + handle.join() + + def test_join_several_times(self): + def task(): + pass + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + handle.join() + with self.assertRaisesRegex(ValueError, "not joinable"): + handle.join() + + def test_joinable_not_joined(self): + handle_destroyed = thread.allocate_lock() + handle_destroyed.acquire() + + def task(): + handle_destroyed.acquire() + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + del handle + handle_destroyed.release() + + def test_join_from_self(self): + errors = [] + handles = [] + start_joinable_thread_returned = thread.allocate_lock() + start_joinable_thread_returned.acquire() + task_tried_to_join = thread.allocate_lock() + task_tried_to_join.acquire() + + def task(): + start_joinable_thread_returned.acquire() + try: + handles[0].join() + except Exception as e: + errors.append(e) + finally: + task_tried_to_join.release() + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + handles.append(handle) + start_joinable_thread_returned.release() + # Can still join after joining failed in other thread + task_tried_to_join.acquire() + handle.join() + + assert len(errors) == 1 + with self.assertRaisesRegex(RuntimeError, "Cannot join current thread"): + raise errors[0] + + def test_detach_from_self(self): + errors = [] + handles = [] + start_joinable_thread_returned = thread.allocate_lock() + start_joinable_thread_returned.acquire() + thread_detached = thread.allocate_lock() + thread_detached.acquire() + + def task(): + start_joinable_thread_returned.acquire() + try: + handles[0].detach() + except Exception as e: + errors.append(e) + finally: + thread_detached.release() + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + handles.append(handle) + start_joinable_thread_returned.release() + thread_detached.acquire() + with self.assertRaisesRegex(ValueError, "not joinable"): + handle.join() + + assert len(errors) == 0 + + def test_detach_then_join(self): + lock = thread.allocate_lock() + lock.acquire() + + def task(): + lock.acquire() + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + # detach() returns even though the thread is blocked on lock + handle.detach() + # join() then cannot be called anymore + with self.assertRaisesRegex(ValueError, "not joinable"): + handle.join() + lock.release() + + def test_join_then_detach(self): + def task(): + pass + + with threading_helper.wait_threads_exit(): + handle = thread.start_joinable_thread(task) + handle.join() + with self.assertRaisesRegex(ValueError, "not joinable"): + handle.detach() + class Barrier: def __init__(self, num_threads): diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 13bfacbac83f13..3060af44fd7e3d 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 ImportError: + interpreters = None + threading_helper.requires_working_threading(module=True) # Between fork() and exec(), only async-safe functions are allowed (issues @@ -35,23 +40,22 @@ platforms_to_skip = ('netbsd5', 'hp-ux11') -# 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 = support.skip_if_sanitizer( - "libasan has a pthread_create() dead lock", - address=True) - - 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.check_sanitizer(address=True): + 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__ @@ -372,8 +376,8 @@ def test_limbo_cleanup(self): # Issue 7481: Failure to start thread should cleanup the limbo map. def fail_new_thread(*args): raise threading.ThreadError() - _start_new_thread = threading._start_new_thread - threading._start_new_thread = fail_new_thread + _start_joinable_thread = threading._start_joinable_thread + threading._start_joinable_thread = fail_new_thread try: t = threading.Thread(target=lambda: None) self.assertRaises(threading.ThreadError, t.start) @@ -381,7 +385,7 @@ def fail_new_thread(*args): t in threading._limbo, "Failed to cleanup _limbo map on failure of Thread.start().") finally: - threading._start_new_thread = _start_new_thread + threading._start_joinable_thread = _start_joinable_thread def test_finalize_running_thread(self): # Issue 1402: the PyGILState_Ensure / _Release functions may be called @@ -478,6 +482,47 @@ def test_enumerate_after_join(self): finally: sys.setswitchinterval(old_interval) + def test_join_from_multiple_threads(self): + # Thread.join() should be thread-safe + errors = [] + + def worker(): + time.sleep(0.005) + + def joiner(thread): + try: + thread.join() + except Exception as e: + errors.append(e) + + for N in range(2, 20): + threads = [threading.Thread(target=worker)] + for i in range(N): + threads.append(threading.Thread(target=joiner, + args=(threads[0],))) + for t in threads: + t.start() + time.sleep(0.01) + for t in threads: + t.join() + if errors: + raise errors[0] + + def test_join_with_timeout(self): + lock = _thread.allocate_lock() + lock.acquire() + + def worker(): + lock.acquire() + + thread = threading.Thread(target=worker) + thread.start() + thread.join(timeout=0.01) + assert thread.is_alive() + lock.release() + thread.join() + assert not thread.is_alive() + def test_no_refcycle_through_target(self): class RunSelfFunction(object): def __init__(self, should_raise): @@ -1311,6 +1356,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.exec_sync(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: diff --git a/Lib/test/test_tkinter/test_images.py b/Lib/test/test_tkinter/test_images.py index 317b0a5c8f4a30..ef1c99f57c6f47 100644 --- a/Lib/test/test_tkinter/test_images.py +++ b/Lib/test/test_tkinter/test_images.py @@ -357,13 +357,18 @@ def test_get(self): self.assertRaises(tkinter.TclError, image.get, 15, 16) def test_write(self): + filename = os_helper.TESTFN + import locale + if locale.getlocale()[0] is None: + # Tcl uses Latin1 in the C locale + filename = os_helper.TESTFN_ASCII image = self.create() - self.addCleanup(os_helper.unlink, os_helper.TESTFN) + self.addCleanup(os_helper.unlink, filename) - image.write(os_helper.TESTFN) + image.write(filename) image2 = tkinter.PhotoImage('::img::test2', master=self.root, format='ppm', - file=os_helper.TESTFN) + file=filename) self.assertEqual(str(image2), '::img::test2') self.assertEqual(image2.type(), 'photo') self.assertEqual(image2.width(), 16) @@ -371,10 +376,10 @@ def test_write(self): self.assertEqual(image2.get(0, 0), image.get(0, 0)) self.assertEqual(image2.get(15, 8), image.get(15, 8)) - image.write(os_helper.TESTFN, format='gif', from_coords=(4, 6, 6, 9)) + image.write(filename, format='gif', from_coords=(4, 6, 6, 9)) image3 = tkinter.PhotoImage('::img::test3', master=self.root, format='gif', - file=os_helper.TESTFN) + file=filename) self.assertEqual(str(image3), '::img::test3') self.assertEqual(image3.type(), 'photo') self.assertEqual(image3.width(), 2) diff --git a/Lib/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py index 0ae27610be6078..6639eaaa59936a 100644 --- a/Lib/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -425,6 +425,329 @@ def test_info_patchlevel(self): self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}')) +class BindTest(AbstractTkTest, unittest.TestCase): + + def setUp(self): + super().setUp() + root = self.root + self.frame = tkinter.Frame(self.root, class_='Test', + width=150, height=100) + self.frame.pack() + + def assertCommandExist(self, funcid): + self.assertEqual(_info_commands(self.root, funcid), (funcid,)) + + def assertCommandNotExist(self, funcid): + self.assertEqual(_info_commands(self.root, funcid), ()) + + def test_bind(self): + event = '' + f = self.frame + self.assertEqual(f.bind(), ()) + self.assertEqual(f.bind(event), '') + def test1(e): pass + def test2(e): pass + + funcid = f.bind(event, test1) + self.assertEqual(f.bind(), (event,)) + script = f.bind(event) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + + funcid2 = f.bind(event, test2, add=True) + script = f.bind(event) + self.assertIn(funcid, script) + self.assertIn(funcid2, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + def test_unbind(self): + event = '' + f = self.frame + self.assertEqual(f.bind(), ()) + self.assertEqual(f.bind(event), '') + def test1(e): pass + def test2(e): pass + + funcid = f.bind(event, test1) + funcid2 = f.bind(event, test2, add=True) + + self.assertRaises(TypeError, f.unbind) + f.unbind(event) + self.assertEqual(f.bind(event), '') + self.assertEqual(f.bind(), ()) + + def test_unbind2(self): + f = self.frame + f.wait_visibility() + f.focus_force() + f.update_idletasks() + event = '' + self.assertEqual(f.bind(), ()) + self.assertEqual(f.bind(event), '') + def test1(e): events.append('a') + def test2(e): events.append('b') + def test3(e): events.append('c') + + funcid = f.bind(event, test1) + funcid2 = f.bind(event, test2, add=True) + funcid3 = f.bind(event, test3, add=True) + events = [] + f.event_generate(event) + self.assertEqual(events, ['a', 'b', 'c']) + + f.unbind(event, funcid2) + script = f.bind(event) + self.assertNotIn(funcid2, script) + self.assertIn(funcid, script) + self.assertIn(funcid3, script) + self.assertEqual(f.bind(), (event,)) + self.assertCommandNotExist(funcid2) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid3) + events = [] + f.event_generate(event) + self.assertEqual(events, ['a', 'c']) + + f.unbind(event, funcid) + f.unbind(event, funcid3) + self.assertEqual(f.bind(event), '') + self.assertEqual(f.bind(), ()) + self.assertCommandNotExist(funcid) + self.assertCommandNotExist(funcid2) + self.assertCommandNotExist(funcid3) + events = [] + f.event_generate(event) + self.assertEqual(events, []) + + # non-idempotent + self.assertRaises(tkinter.TclError, f.unbind, event, funcid2) + + def test_bind_rebind(self): + event = '' + f = self.frame + self.assertEqual(f.bind(), ()) + self.assertEqual(f.bind(event), '') + def test1(e): pass + def test2(e): pass + def test3(e): pass + + funcid = f.bind(event, test1) + funcid2 = f.bind(event, test2, add=True) + script = f.bind(event) + self.assertIn(funcid2, script) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + funcid3 = f.bind(event, test3) + script = f.bind(event) + self.assertNotIn(funcid, script) + self.assertNotIn(funcid2, script) + self.assertIn(funcid3, script) + self.assertCommandExist(funcid3) + + def test_bind_class(self): + event = '' + bind_class = self.root.bind_class + unbind_class = self.root.unbind_class + self.assertRaises(TypeError, bind_class) + self.assertEqual(bind_class('Test'), ()) + self.assertEqual(bind_class('Test', event), '') + self.addCleanup(unbind_class, 'Test', event) + def test1(e): pass + def test2(e): pass + + funcid = bind_class('Test', event, test1) + self.assertEqual(bind_class('Test'), (event,)) + script = bind_class('Test', event) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + + funcid2 = bind_class('Test', event, test2, add=True) + script = bind_class('Test', event) + self.assertIn(funcid, script) + self.assertIn(funcid2, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + def test_unbind_class(self): + event = '' + bind_class = self.root.bind_class + unbind_class = self.root.unbind_class + self.assertEqual(bind_class('Test'), ()) + self.assertEqual(bind_class('Test', event), '') + self.addCleanup(unbind_class, 'Test', event) + def test1(e): pass + def test2(e): pass + + funcid = bind_class('Test', event, test1) + funcid2 = bind_class('Test', event, test2, add=True) + + self.assertRaises(TypeError, unbind_class) + self.assertRaises(TypeError, unbind_class, 'Test') + unbind_class('Test', event) + self.assertEqual(bind_class('Test', event), '') + self.assertEqual(bind_class('Test'), ()) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + unbind_class('Test', event) # idempotent + + def test_bind_class_rebind(self): + event = '' + bind_class = self.root.bind_class + unbind_class = self.root.unbind_class + self.assertEqual(bind_class('Test'), ()) + self.assertEqual(bind_class('Test', event), '') + self.addCleanup(unbind_class, 'Test', event) + def test1(e): pass + def test2(e): pass + def test3(e): pass + + funcid = bind_class('Test', event, test1) + funcid2 = bind_class('Test', event, test2, add=True) + script = bind_class('Test', event) + self.assertIn(funcid2, script) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + funcid3 = bind_class('Test', event, test3) + script = bind_class('Test', event) + self.assertNotIn(funcid, script) + self.assertNotIn(funcid2, script) + self.assertIn(funcid3, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + self.assertCommandExist(funcid3) + + def test_bind_all(self): + event = '' + bind_all = self.root.bind_all + unbind_all = self.root.unbind_all + self.assertNotIn(event, bind_all()) + self.assertEqual(bind_all(event), '') + self.addCleanup(unbind_all, event) + def test1(e): pass + def test2(e): pass + + funcid = bind_all(event, test1) + self.assertIn(event, bind_all()) + script = bind_all(event) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + + funcid2 = bind_all(event, test2, add=True) + script = bind_all(event) + self.assertIn(funcid, script) + self.assertIn(funcid2, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + def test_unbind_all(self): + event = '' + bind_all = self.root.bind_all + unbind_all = self.root.unbind_all + self.assertNotIn(event, bind_all()) + self.assertEqual(bind_all(event), '') + self.addCleanup(unbind_all, event) + def test1(e): pass + def test2(e): pass + + funcid = bind_all(event, test1) + funcid2 = bind_all(event, test2, add=True) + + unbind_all(event) + self.assertEqual(bind_all(event), '') + self.assertNotIn(event, bind_all()) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + unbind_all(event) # idempotent + + def test_bind_all_rebind(self): + event = '' + bind_all = self.root.bind_all + unbind_all = self.root.unbind_all + self.assertNotIn(event, bind_all()) + self.assertEqual(bind_all(event), '') + self.addCleanup(unbind_all, event) + def test1(e): pass + def test2(e): pass + def test3(e): pass + + funcid = bind_all(event, test1) + funcid2 = bind_all(event, test2, add=True) + script = bind_all(event) + self.assertIn(funcid2, script) + self.assertIn(funcid, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + + funcid3 = bind_all(event, test3) + script = bind_all(event) + self.assertNotIn(funcid, script) + self.assertNotIn(funcid2, script) + self.assertIn(funcid3, script) + self.assertCommandExist(funcid) + self.assertCommandExist(funcid2) + self.assertCommandExist(funcid3) + + def test_bindtags(self): + f = self.frame + self.assertEqual(self.root.bindtags(), ('.', 'Tk', 'all')) + self.assertEqual(f.bindtags(), (str(f), 'Test', '.', 'all')) + f.bindtags(('a', 'b c')) + self.assertEqual(f.bindtags(), ('a', 'b c')) + + def test_bind_events(self): + event = '' + root = self.root + t = tkinter.Toplevel(root) + f = tkinter.Frame(t, class_='Test', width=150, height=100) + f.pack() + root.wait_visibility() # needed on Windows + root.update_idletasks() + self.addCleanup(root.unbind_class, 'Test', event) + self.addCleanup(root.unbind_class, 'Toplevel', event) + self.addCleanup(root.unbind_class, 'tag', event) + self.addCleanup(root.unbind_class, 'tag2', event) + self.addCleanup(root.unbind_all, event) + def test(what): + return lambda e: events.append((what, e.widget)) + + root.bind_all(event, test('all')) + root.bind_class('Test', event, test('frame class')) + root.bind_class('Toplevel', event, test('toplevel class')) + root.bind_class('tag', event, test('tag')) + root.bind_class('tag2', event, test('tag2')) + f.bind(event, test('frame')) + t.bind(event, test('toplevel')) + + events = [] + f.event_generate(event) + self.assertEqual(events, [ + ('frame', f), + ('frame class', f), + ('toplevel', f), + ('all', f), + ]) + + events = [] + t.event_generate(event) + self.assertEqual(events, [ + ('toplevel', t), + ('toplevel class', t), + ('all', t), + ]) + + f.bindtags(('tag', 'tag3')) + events = [] + f.event_generate(event) + self.assertEqual(events, [('tag', f)]) + + class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase): def test_default_root(self): @@ -480,5 +803,9 @@ def test_mainloop(self): self.assertRaises(RuntimeError, tkinter.mainloop) +def _info_commands(widget, pattern=None): + return widget.tk.splitlist(widget.tk.call('info', 'commands', pattern)) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tkinter/test_text.py b/Lib/test/test_tkinter/test_text.py index 328e4256ce0711..f809c4510e3a1f 100644 --- a/Lib/test/test_tkinter/test_text.py +++ b/Lib/test/test_tkinter/test_text.py @@ -10,6 +10,7 @@ class TextTest(AbstractTkTest, unittest.TestCase): def setUp(self): super().setUp() self.text = tkinter.Text(self.root) + self.text.pack() def test_debug(self): text = self.text @@ -41,8 +42,6 @@ def test_search(self): self.assertEqual(text.search('test', '1.0', 'end'), '1.3') def test_count(self): - # XXX Some assertions do not check against the intended result, - # but instead check the current result to prevent regression. text = self.text text.insert('1.0', 'Lorem ipsum dolor sit amet,\n' @@ -53,44 +52,27 @@ def test_count(self): options = ('chars', 'indices', 'lines', 'displaychars', 'displayindices', 'displaylines', 'xpixels', 'ypixels') - if self.wantobjects: - self.assertEqual(len(text.count('1.0', 'end', *options)), 8) - else: - text.count('1.0', 'end', *options) - self.assertEqual(text.count('1.0', 'end', 'chars', 'lines'), (124, 4) - if self.wantobjects else '124 4') - self.assertEqual(text.count('1.3', '4.5', 'chars', 'lines'), (92, 3) - if self.wantobjects else '92 3') - self.assertEqual(text.count('4.5', '1.3', 'chars', 'lines'), (-92, -3) - if self.wantobjects else '-92 -3') - self.assertEqual(text.count('1.3', '1.3', 'chars', 'lines'), (0, 0) - if self.wantobjects else '0 0') - self.assertEqual(text.count('1.0', 'end', 'lines'), (4,) - if self.wantobjects else ('4',)) - self.assertEqual(text.count('end', '1.0', 'lines'), (-4,) - if self.wantobjects else ('-4',)) - self.assertEqual(text.count('1.3', '1.5', 'lines'), None - if self.wantobjects else ('0',)) - self.assertEqual(text.count('1.3', '1.3', 'lines'), None - if self.wantobjects else ('0',)) - self.assertEqual(text.count('1.0', 'end'), (124,) # 'indices' by default - if self.wantobjects else ('124',)) + self.assertEqual(len(text.count('1.0', 'end', *options)), 8) + self.assertEqual(text.count('1.0', 'end', 'chars', 'lines'), (124, 4)) + self.assertEqual(text.count('1.3', '4.5', 'chars', 'lines'), (92, 3)) + self.assertEqual(text.count('4.5', '1.3', 'chars', 'lines'), (-92, -3)) + self.assertEqual(text.count('1.3', '1.3', 'chars', 'lines'), (0, 0)) + self.assertEqual(text.count('1.0', 'end', 'lines'), 4) + self.assertEqual(text.count('end', '1.0', 'lines'), -4) + self.assertEqual(text.count('1.3', '1.5', 'lines'), 0) + self.assertEqual(text.count('1.3', '1.3', 'lines'), 0) + self.assertEqual(text.count('1.0', 'end'), 124) # 'indices' by default + self.assertEqual(text.count('1.0', 'end', 'indices'), 124) self.assertRaises(tkinter.TclError, text.count, '1.0', 'end', 'spam') self.assertRaises(tkinter.TclError, text.count, '1.0', 'end', '-lines') - self.assertIsInstance(text.count('1.3', '1.5', 'ypixels'), tuple) - self.assertIsInstance(text.count('1.3', '1.5', 'update', 'ypixels'), int - if self.wantobjects else str) - self.assertEqual(text.count('1.3', '1.3', 'update', 'ypixels'), None - if self.wantobjects else '0') - self.assertEqual(text.count('1.3', '1.5', 'update', 'indices'), 2 - if self.wantobjects else '2') - self.assertEqual(text.count('1.3', '1.3', 'update', 'indices'), None - if self.wantobjects else '0') - self.assertEqual(text.count('1.3', '1.5', 'update'), (2,) - if self.wantobjects else ('2',)) - self.assertEqual(text.count('1.3', '1.3', 'update'), None - if self.wantobjects else ('0',)) + self.assertIsInstance(text.count('1.3', '1.5', 'ypixels'), int) + self.assertIsInstance(text.count('1.3', '1.5', 'update', 'ypixels'), int) + self.assertEqual(text.count('1.3', '1.3', 'update', 'ypixels'), 0) + self.assertEqual(text.count('1.3', '1.5', 'update', 'indices'), 2) + self.assertEqual(text.count('1.3', '1.3', 'update', 'indices'), 0) + self.assertEqual(text.count('1.3', '1.5', 'update'), 2) + self.assertEqual(text.count('1.3', '1.3', 'update'), 0) if __name__ == "__main__": diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 94fb6d933de114..21e8637a7ca905 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -566,6 +566,65 @@ 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) + """) + + self.check_tokenize("""\ + '''Autorzy, którzy tą jednostkę mają wpisani jako AKTUALNA -- czyli + aktualni pracownicy, obecni pracownicy''' +""", """\ + INDENT ' ' (1, 0) (1, 4) + STRING "'''Autorzy, którzy tą jednostkę mają wpisani jako AKTUALNA -- czyli\\n aktualni pracownicy, obecni pracownicy'''" (1, 4) (2, 45) + NEWLINE '\\n' (2, 45) (2, 46) + DEDENT '' (3, 0) (3, 0) """) def test_function(self): @@ -1386,7 +1445,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 +1470,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 ("-", "_"): @@ -1852,19 +1911,9 @@ def test_random_files(self): 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 - # broken on the obscure unicode identifiers in it. *sigh* - # With roundtrip extended to test the 5-tuple mode of untokenize, - # 7 more testfiles fail. Remove them also until the failure is diagnosed. - - testfiles.remove(os.path.join(tempdir, "test_unicode_identifiers.py")) - # 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'): - testfiles.remove(os.path.join(tempdir, "test_%s.py") % f) - if not support.is_resource_enabled("cpu"): testfiles = random.sample(testfiles, 10) @@ -2277,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): diff --git a/Lib/test/test_tools/test_makeunicodedata.py b/Lib/test/test_tools/test_makeunicodedata.py new file mode 100644 index 00000000000000..f31375117e2e92 --- /dev/null +++ b/Lib/test/test_tools/test_makeunicodedata.py @@ -0,0 +1,122 @@ +import unittest +from test.test_tools import skip_if_missing, imports_under_tool +from test import support +from test.support.hypothesis_helper import hypothesis + +st = hypothesis.strategies +given = hypothesis.given +example = hypothesis.example + + +skip_if_missing("unicode") +with imports_under_tool("unicode"): + from dawg import Dawg, build_compression_dawg, lookup, inverse_lookup + + +@st.composite +def char_name_db(draw, min_length=1, max_length=30): + m = draw(st.integers(min_value=min_length, max_value=max_length)) + names = draw( + st.sets(st.text("abcd", min_size=1, max_size=10), min_size=m, max_size=m) + ) + characters = draw(st.sets(st.characters(), min_size=m, max_size=m)) + return list(zip(names, characters)) + + +class TestDawg(unittest.TestCase): + """Tests for the directed acyclic word graph data structure that is used + to store the unicode character names in unicodedata. Tests ported from PyPy + """ + + def test_dawg_direct_simple(self): + dawg = Dawg() + dawg.insert("a", -4) + dawg.insert("c", -2) + dawg.insert("cat", -1) + dawg.insert("catarr", 0) + dawg.insert("catnip", 1) + dawg.insert("zcatnip", 5) + packed, data, inverse = dawg.finish() + + self.assertEqual(lookup(packed, data, b"a"), -4) + self.assertEqual(lookup(packed, data, b"c"), -2) + self.assertEqual(lookup(packed, data, b"cat"), -1) + self.assertEqual(lookup(packed, data, b"catarr"), 0) + self.assertEqual(lookup(packed, data, b"catnip"), 1) + self.assertEqual(lookup(packed, data, b"zcatnip"), 5) + self.assertRaises(KeyError, lookup, packed, data, b"b") + self.assertRaises(KeyError, lookup, packed, data, b"catni") + self.assertRaises(KeyError, lookup, packed, data, b"catnipp") + + self.assertEqual(inverse_lookup(packed, inverse, -4), b"a") + self.assertEqual(inverse_lookup(packed, inverse, -2), b"c") + self.assertEqual(inverse_lookup(packed, inverse, -1), b"cat") + self.assertEqual(inverse_lookup(packed, inverse, 0), b"catarr") + self.assertEqual(inverse_lookup(packed, inverse, 1), b"catnip") + self.assertEqual(inverse_lookup(packed, inverse, 5), b"zcatnip") + self.assertRaises(KeyError, inverse_lookup, packed, inverse, 12) + + def test_forbid_empty_dawg(self): + dawg = Dawg() + self.assertRaises(ValueError, dawg.finish) + + @given(char_name_db()) + @example([("abc", "a"), ("abd", "b")]) + @example( + [ + ("bab", "1"), + ("a", ":"), + ("ad", "@"), + ("b", "<"), + ("aacc", "?"), + ("dab", "D"), + ("aa", "0"), + ("ab", "F"), + ("aaa", "7"), + ("cbd", "="), + ("abad", ";"), + ("ac", "B"), + ("abb", "4"), + ("bb", "2"), + ("aab", "9"), + ("caaaaba", "E"), + ("ca", ">"), + ("bbaaa", "5"), + ("d", "3"), + ("baac", "8"), + ("c", "6"), + ("ba", "A"), + ] + ) + @example( + [ + ("bcdac", "9"), + ("acc", "g"), + ("d", "d"), + ("daabdda", "0"), + ("aba", ";"), + ("c", "6"), + ("aa", "7"), + ("abbd", "c"), + ("badbd", "?"), + ("bbd", "f"), + ("cc", "@"), + ("bb", "8"), + ("daca", ">"), + ("ba", ":"), + ("baac", "3"), + ("dbdddac", "a"), + ("a", "2"), + ("cabd", "b"), + ("b", "="), + ("abd", "4"), + ("adcbd", "5"), + ("abc", "e"), + ("ab", "1"), + ] + ) + def test_dawg(self, data): + # suppress debug prints + with support.captured_stdout() as output: + # it's enough to build it, building will also check the result + build_compression_dawg(data) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index aa8405bd25d120..a6708119b81191 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -8,6 +8,7 @@ import inspect import builtins import unittest +import unittest.mock import re import tempfile import random @@ -24,6 +25,7 @@ import json import textwrap import traceback +import contextlib from functools import partial from pathlib import Path @@ -41,6 +43,14 @@ class TracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that # formatting of SyntaxErrors works based on changes for 2.1. + def setUp(self): + super().setUp() + self.colorize = traceback._COLORIZE + traceback._COLORIZE = False + + def tearDown(self): + super().tearDown() + traceback._COLORIZE = self.colorize def get_exception_format(self, func, exc): try: @@ -215,6 +225,155 @@ def __str__(self): str_name = '.'.join([X.__module__, X.__qualname__]) self.assertEqual(err[0], "%s: %s\n" % (str_name, str_value)) + def test_format_exception_group_without_show_group(self): + eg = ExceptionGroup('A', [ValueError('B')]) + err = traceback.format_exception_only(eg) + self.assertEqual(err, ['ExceptionGroup: A (1 sub-exception)\n']) + + def test_format_exception_group(self): + eg = ExceptionGroup('A', [ValueError('B')]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (1 sub-exception)\n', + ' ValueError: B\n', + ]) + + def test_format_base_exception_group(self): + eg = BaseExceptionGroup('A', [BaseException('B')]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'BaseExceptionGroup: A (1 sub-exception)\n', + ' BaseException: B\n', + ]) + + def test_format_exception_group_with_note(self): + exc = ValueError('B') + exc.add_note('Note') + eg = ExceptionGroup('A', [exc]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (1 sub-exception)\n', + ' ValueError: B\n', + ' Note\n', + ]) + + def test_format_exception_group_explicit_class(self): + eg = ExceptionGroup('A', [ValueError('B')]) + err = traceback.format_exception_only(ExceptionGroup, eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (1 sub-exception)\n', + ' ValueError: B\n', + ]) + + def test_format_exception_group_multiple_exceptions(self): + eg = ExceptionGroup('A', [ValueError('B'), TypeError('C')]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (2 sub-exceptions)\n', + ' ValueError: B\n', + ' TypeError: C\n', + ]) + + def test_format_exception_group_multiline_messages(self): + eg = ExceptionGroup('A\n1', [ValueError('B\n2')]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A\n1 (1 sub-exception)\n', + ' ValueError: B\n', + ' 2\n', + ]) + + def test_format_exception_group_multiline2_messages(self): + exc = ValueError('B\n\n2\n') + exc.add_note('\nC\n\n3') + eg = ExceptionGroup('A\n\n1\n', [exc, IndexError('D')]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A\n\n1\n (2 sub-exceptions)\n', + ' ValueError: B\n', + ' \n', + ' 2\n', + ' \n', + ' \n', # first char of `note` + ' C\n', + ' \n', + ' 3\n', # note ends + ' IndexError: D\n', + ]) + + def test_format_exception_group_syntax_error(self): + exc = SyntaxError("error", ("x.py", 23, None, "bad syntax")) + eg = ExceptionGroup('A\n1', [exc]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A\n1 (1 sub-exception)\n', + ' File "x.py", line 23\n', + ' bad syntax\n', + ' SyntaxError: error\n', + ]) + + def test_format_exception_group_nested_with_notes(self): + exc = IndexError('D') + exc.add_note('Note\nmultiline') + eg = ExceptionGroup('A', [ + ValueError('B'), + ExceptionGroup('C', [exc, LookupError('E')]), + TypeError('F'), + ]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (3 sub-exceptions)\n', + ' ValueError: B\n', + ' ExceptionGroup: C (2 sub-exceptions)\n', + ' IndexError: D\n', + ' Note\n', + ' multiline\n', + ' LookupError: E\n', + ' TypeError: F\n', + ]) + + def test_format_exception_group_with_tracebacks(self): + def f(): + try: + 1 / 0 + except ZeroDivisionError as e: + return e + + def g(): + try: + raise TypeError('g') + except TypeError as e: + return e + + eg = ExceptionGroup('A', [ + f(), + ExceptionGroup('B', [g()]), + ]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (2 sub-exceptions)\n', + ' ZeroDivisionError: division by zero\n', + ' ExceptionGroup: B (1 sub-exception)\n', + ' TypeError: g\n', + ]) + + def test_format_exception_group_with_cause(self): + def f(): + try: + try: + 1 / 0 + except ZeroDivisionError: + raise ValueError(0) + except Exception as e: + return e + + eg = ExceptionGroup('A', [f()]) + err = traceback.format_exception_only(eg, show_group=True) + self.assertEqual(err, [ + 'ExceptionGroup: A (1 sub-exception)\n', + ' ValueError: 0\n', + ]) + @requires_subprocess() def test_encoded_file(self): # Test that tracebacks are correctly printed for encoded source files: @@ -313,6 +472,8 @@ def __del__(self): rc, stdout, stderr = assert_python_ok('-c', code) expected = [b'Traceback (most recent call last):', b' File "", line 8, in __init__', + b' x = 1 / 0', + b' ^^^^^', b'ZeroDivisionError: division by zero'] self.assertEqual(stderr.splitlines(), expected) @@ -370,7 +531,7 @@ def test_signatures(self): self.assertEqual( str(inspect.signature(traceback.print_exception)), ('(exc, /, value=, tb=, ' - 'limit=None, file=None, chain=True)')) + 'limit=None, file=None, chain=True, **kwargs)')) self.assertEqual( str(inspect.signature(traceback.format_exception)), @@ -379,7 +540,7 @@ def test_signatures(self): self.assertEqual( str(inspect.signature(traceback.format_exception_only)), - '(exc, /, value=)') + '(exc, /, value=, *, show_group=False)') class PurePythonExceptionFormattingMixin: @@ -427,6 +588,7 @@ def f(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' if True: raise ValueError("basic caret tests")\n' ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' @@ -445,6 +607,7 @@ def f_with_unicode(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+1}, in f_with_unicode\n' ' if True: raise ValueError("Ĥellö Wörld")\n' ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' @@ -462,6 +625,7 @@ def foo(a: THIS_DOES_NOT_EXIST ) -> int: 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+1}, in f_with_type\n' ' def foo(a: THIS_DOES_NOT_EXIST ) -> int:\n' ' ^^^^^^^^^^^^^^^^^^^\n' @@ -482,9 +646,14 @@ def f_with_multiline(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+1}, in f_with_multiline\n' ' if True: raise ValueError(\n' - ' ^^^^^^^^^^^^^^^^^' + ' ^^^^^^^^^^^^^^^^^\n' + ' "error over multiple lines"\n' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' + ' )\n' + ' ^' ) result_lines = self.get_exception(f_with_multiline) self.assertEqual(result_lines, expected_f.splitlines()) @@ -513,9 +682,10 @@ def f_with_multiline(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n' ' return compile(code, "?", "exec")\n' - ' ^^^^^^^^^^^^^^^^^^^^^^^^^^\n' + ' ~~~~~~~^^^^^^^^^^^^^^^^^^^\n' ' File "?", line 7\n' ' foo(a, z\n' ' ^' @@ -538,9 +708,12 @@ def f_with_multiline(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n' ' 2 + 1 /\n' - ' ^^^' + ' ~~^\n' + ' 0\n' + ' ~' ) result_lines = self.get_exception(f_with_multiline) self.assertEqual(result_lines, expected_f.splitlines()) @@ -555,6 +728,7 @@ def f_with_binary_operator(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' ' return 10 + divisor / 0 + 30\n' ' ~~~~~~~~^~~\n' @@ -572,6 +746,7 @@ def f_with_binary_operator(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' ' return 10 + áóí / 0 + 30\n' ' ~~~~^~~\n' @@ -589,6 +764,7 @@ def f_with_binary_operator(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' ' return 10 + divisor // 0 + 30\n' ' ~~~~~~~~^^~~\n' @@ -600,16 +776,102 @@ def test_caret_for_binary_operators_with_spaces_and_parenthesis(self): def f_with_binary_operator(): a = 1 b = "" - return ( a ) + 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' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' - ' return ( a ) + b\n' - ' ~~~~~~~~~~^~~\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_binary_operators_multiline(self): + def f_with_binary_operator(): + b = 1 + c = "" + a = b \ + +\ + c # test + return a + + 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' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' a = b \\\n' + ' ~~~~~~\n' + ' +\\\n' + ' ^~\n' + ' c # test\n' + ' ~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_for_binary_operators_multiline_two_char(self): + def f_with_binary_operator(): + b = 1 + c = "" + a = ( + (b # test + + ) \ + # + + << (c # test + \ + ) # test + ) + return a + + 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' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+4}, in f_with_binary_operator\n' + ' (b # test +\n' + ' ~~~~~~~~~~~~\n' + ' ) \\\n' + ' ~~~~\n' + ' # +\n' + ' ~~~\n' + ' << (c # test\n' + ' ^^~~~~~~~~~~~\n' + ' \\\n' + ' ~\n' + ' ) # test\n' + ' ~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_for_binary_operators_multiline_with_unicode(self): + def f_with_binary_operator(): + b = 1 + a = ("ááá" + + "áá") + b + return a + + 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' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' + ' a = ("ááá" +\n' + ' ~~~~~~~~\n' + ' "áá") + b\n' + ' ~~~~~~^~~\n' ) result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) @@ -624,6 +886,7 @@ def f_with_subscript(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' " return some_dict['x']['y']['z']\n" ' ~~~~~~~~~~~~~~~~~~~^^^^^\n' @@ -641,6 +904,7 @@ def f_with_subscript(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' " return some_dict['ó']['á']['í']['beta']\n" ' ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^\n' @@ -659,6 +923,7 @@ def f_with_binary_operator(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' ' return b [ a ] + c\n' ' ~~~~~~^^^^^^^^^\n' @@ -666,6 +931,226 @@ 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_subscript_multiline(self): + def f_with_subscript(): + bbbbb = {} + ccc = 1 + ddd = 2 + b = bbbbb \ + [ ccc # test + + + ddd \ + + ] # test + return b + + lineno_f = f_with_subscript.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+4}, in f_with_subscript\n' + ' b = bbbbb \\\n' + ' ~~~~~~~\n' + ' [ ccc # test\n' + ' ^^^^^^^^^^^^^\n' + ' \n' + ' \n' + ' + ddd \\\n' + ' ^^^^^^^^\n' + ' \n' + ' \n' + ' ] # test\n' + ' ^\n' + ) + result_lines = self.get_exception(f_with_subscript) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_for_call(self): + def f_with_call(): + def f1(a): + def f2(b): + raise RuntimeError("fail") + return f2 + return f1("x")("y") + + lineno_f = f_with_call.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+5}, in f_with_call\n' + ' return f1("x")("y")\n' + ' ~~~~~~~^^^^^\n' + f' File "{__file__}", line {lineno_f+3}, in f2\n' + ' raise RuntimeError("fail")\n' + ) + result_lines = self.get_exception(f_with_call) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_for_call_unicode(self): + def f_with_call(): + def f1(a): + def f2(b): + raise RuntimeError("fail") + return f2 + return f1("ó")("á") + + lineno_f = f_with_call.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+5}, in f_with_call\n' + ' return f1("ó")("á")\n' + ' ~~~~~~~^^^^^\n' + f' File "{__file__}", line {lineno_f+3}, in f2\n' + ' raise RuntimeError("fail")\n' + ) + result_lines = self.get_exception(f_with_call) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_for_call_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + def f(a): + raise RuntimeError("fail") + return f ( "x" ) + 2 + + 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' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return f ( "x" ) + 2\n' + ' ~~~~~~^^^^^^^^^^^\n' + f' File "{__file__}", line {lineno_f+2}, in f\n' + ' raise RuntimeError("fail")\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_for_call_multiline(self): + def f_with_call(): + class C: + def y(self, a): + def f(b): + raise RuntimeError("fail") + return f + def g(x): + return C() + a = (g(1).y)( + 2 + )(3)(4) + return a + + lineno_f = f_with_call.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+8}, in f_with_call\n' + ' a = (g(1).y)(\n' + ' ~~~~~~~~~\n' + ' 2\n' + ' ~\n' + ' )(3)(4)\n' + ' ~^^^\n' + f' File "{__file__}", line {lineno_f+4}, in f\n' + ' raise RuntimeError("fail")\n' + ) + result_lines = self.get_exception(f_with_call) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_many_lines(self): + def f(): + x = 1 + if True: x += ( + "a" + + "a" + ) # test + + lineno_f = f.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+2}, in f\n' + ' if True: x += (\n' + ' ^^^^^^\n' + ' ...<2 lines>...\n' + ' ) # test\n' + ' ^\n' + ) + result_lines = self.get_exception(f) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_many_lines_no_caret(self): + def f(): + x = 1 + x += ( + "a" + + "a" + ) + + lineno_f = f.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+2}, in f\n' + ' x += (\n' + ' ...<2 lines>...\n' + ' )\n' + ) + result_lines = self.get_exception(f) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_many_lines_binary_op(self): + def f_with_binary_operator(): + b = 1 + c = "a" + a = ( + b + + b + ) + ( + c + + c + + c + ) + return a + + 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' + ' ~~~~~~~~^^\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' a = (\n' + ' ~\n' + ' b +\n' + ' ~~~\n' + ' b\n' + ' ~\n' + ' ) + (\n' + ' ~~^~~\n' + ' c +\n' + ' ~~~\n' + ' ...<2 lines>...\n' + ' )\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") @@ -682,6 +1167,7 @@ def test_traceback_specialization_with_syntax_error(self): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{TESTFN}", line {lineno_f}, in \n' " 1 $ 0 / 1 / 2\n" ' ^^^^^\n' @@ -704,6 +1190,7 @@ def test_traceback_very_long_line(self): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{TESTFN}", line {lineno_f}, in \n' f' {source}\n' f' {" "*len("if True: ") + "^"*256}\n' @@ -721,6 +1208,7 @@ def f_with_subscript(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' " some_dict['x']['y']['z']\n" ' ~~~~~~~~~~~~~~~~~~~^^^^^\n' @@ -740,6 +1228,7 @@ def exc(): f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | callable()\n' + f' | ~~~~~~~~^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 1}, in exc\n' f' | if True: raise ExceptionGroup("eg", [ValueError(1), TypeError(2)])\n' f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' @@ -805,6 +1294,7 @@ def g(): pass 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_applydescs + 1}, in applydecs\n' ' @dec_error\n' ' ^^^^^^^^^\n' @@ -823,6 +1313,7 @@ class A: pass 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' + ' ~~~~~~~~^^\n' f' File "{__file__}", line {lineno_applydescs_class + 1}, in applydecs_class\n' ' @dec_error\n' ' ^^^^^^^^^\n' @@ -841,6 +1332,7 @@ def f(): "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", " callable()", + " ~~~~~~~~^^", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", " .method", " ^^^^^^", @@ -857,6 +1349,7 @@ def f(): "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", " callable()", + " ~~~~~~~~^^", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", " method", ] @@ -872,6 +1365,7 @@ def f(): "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", " callable()", + " ~~~~~~~~^^", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", " . method", " ^^^^^^", @@ -887,6 +1381,7 @@ def f(): "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", " callable()", + " ~~~~~~~~^^", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f", " width", ] @@ -903,6 +1398,7 @@ def f(): "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", " callable()", + " ~~~~~~~~^^", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", " raise ValueError(width)", ] @@ -921,12 +1417,85 @@ def f(): "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", " callable()", + " ~~~~~~~~^^", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 4}, in f", - " print(1, www(", - " ^^^^", + f" print(1, www(", + f" ~~~~~~^", + f" th))", + f" ^^^^^", + ] + self.assertEqual(actual, expected) + + def test_byte_offset_with_wide_characters_term_highlight(self): + def f(): + 说明说明 = 1 + şçöğıĤellö = 0 # not wide but still non-ascii + return 说明说明 / şçöğıĤellö + + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" ~~~~~~~~^^", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 3}, in f", + f" return 说明说明 / şçöğıĤellö", + f" ~~~~~~~~~^~~~~~~~~~~~", + ] + self.assertEqual(actual, expected) + + def test_byte_offset_with_emojis_term_highlight(self): + def f(): + return "✨🐍" + func_说明说明("📗🚛", + "📗🚛") + "🐍" + + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" ~~~~~~~~^^", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f", + f' return "✨🐍" + func_说明说明("📗🚛",', + f" ^^^^^^^^^^^^^", ] self.assertEqual(actual, expected) + def test_byte_offset_wide_chars_subscript(self): + def f(): + my_dct = { + "✨🚛✨": { + "说明": { + "🐍🐍🐍": None + } + } + } + return my_dct["✨🚛✨"]["说明"]["🐍"]["说明"]["🐍🐍"] + + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" ~~~~~~~~^^", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 8}, in f", + f' return my_dct["✨🚛✨"]["说明"]["🐍"]["说明"]["🐍🐍"]', + f" ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^", + ] + self.assertEqual(actual, expected) + + def test_memory_error(self): + def f(): + raise MemoryError() + + actual = self.get_exception(f) + expected = ['Traceback (most recent call last):', + f' File "{__file__}", line {self.callable_line}, in get_exception', + ' callable()', + ' ~~~~~~~~^^', + f' File "{__file__}", line {f.__code__.co_firstlineno + 1}, in f', + ' raise MemoryError()'] + self.assertEqual(actual, expected) @requires_debug_ranges() @@ -963,11 +1532,21 @@ class CPythonTracebackLegacyErrorCaretTests( 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') + def _filter_debug_ranges(self, expected): + return [line for line in expected if not set(line.strip()) <= set("^~")] + + def _maybe_filter_debug_ranges(self, expected): + if not self.DEBUG_RANGES: + return self._filter_debug_ranges(expected) + return expected + @cpython_only def check_traceback_format(self, cleanup_func=None): from _testcapi import traceback_print @@ -980,6 +1559,11 @@ def check_traceback_format(self, cleanup_func=None): cleanup_func(tb.tb_next) traceback_fmt = 'Traceback (most recent call last):\n' + \ ''.join(traceback.format_tb(tb)) + # clear caret lines from traceback_fmt since internal API does + # not emit them + traceback_fmt = "\n".join( + self._filter_debug_ranges(traceback_fmt.splitlines()) + ) + "\n" file_ = StringIO() traceback_print(tb, file_) python_fmt = file_.getvalue() @@ -1072,12 +1656,16 @@ def f(): 'Traceback (most recent call last):\n' f' File "{__file__}", line {lineno_f+5}, in _check_recursive_traceback_display\n' ' f()\n' + ' ~^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' f()\n' + ' ~^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' f()\n' + ' ~^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' f()\n' + ' ~^^\n' # XXX: The following line changes depending on whether the tests # are run through the interactive interpreter or with -m # It also varies depending on the platform (stack size) @@ -1086,7 +1674,7 @@ def f(): 'RecursionError: maximum recursion depth exceeded\n' ) - expected = result_f.splitlines() + expected = self._maybe_filter_debug_ranges(result_f.splitlines()) actual = stderr_f.getvalue().splitlines() # Check the output text matches expectations @@ -1118,13 +1706,13 @@ def g(count=10): result_g = ( f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' ' [Previous line repeated 7 more times]\n' f' File "{__file__}", line {lineno_g+3}, in g\n' ' raise ValueError\n' @@ -1134,8 +1722,9 @@ def g(count=10): 'Traceback (most recent call last):\n' f' File "{__file__}", line {lineno_g+7}, in _check_recursive_traceback_display\n' ' g()\n' + ' ~^^\n' ) - expected = (tb_line + result_g).splitlines() + expected = self._maybe_filter_debug_ranges((tb_line + result_g).splitlines()) actual = stderr_g.getvalue().splitlines() self.assertEqual(actual, expected) @@ -1158,20 +1747,22 @@ def h(count=10): 'Traceback (most recent call last):\n' f' File "{__file__}", line {lineno_h+7}, in _check_recursive_traceback_display\n' ' h()\n' + ' ~^^\n' f' File "{__file__}", line {lineno_h+2}, in h\n' ' return h(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_h+2}, in h\n' ' return h(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_h+2}, in h\n' ' return h(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' ' [Previous line repeated 7 more times]\n' f' File "{__file__}", line {lineno_h+3}, in h\n' ' g()\n' + ' ~^^\n' ) - expected = (result_h + result_g).splitlines() + expected = self._maybe_filter_debug_ranges((result_h + result_g).splitlines()) actual = stderr_h.getvalue().splitlines() self.assertEqual(actual, expected) @@ -1186,23 +1777,24 @@ def h(count=10): result_g = ( f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+3}, in g\n' ' raise ValueError\n' 'ValueError\n' ) 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+80}, in _check_recursive_traceback_display\n' ' g(traceback._RECURSIVE_CUTOFF)\n' + ' ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' ) - expected = (tb_line + result_g).splitlines() + expected = self._maybe_filter_debug_ranges((tb_line + result_g).splitlines()) actual = stderr_g.getvalue().splitlines() self.assertEqual(actual, expected) @@ -1217,13 +1809,13 @@ def h(count=10): result_g = ( f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+2}, in g\n' ' return g(count-1)\n' - ' ^^^^^^^^^^\n' + ' ~^^^^^^^^^\n' ' [Previous line repeated 1 more time]\n' f' File "{__file__}", line {lineno_g+3}, in g\n' ' raise ValueError\n' @@ -1231,24 +1823,23 @@ 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+112}, in _check_recursive_traceback_display\n' ' g(traceback._RECURSIVE_CUTOFF + 1)\n' + ' ~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' ) - expected = (tb_line + result_g).splitlines() + expected = self._maybe_filter_debug_ranges((tb_line + result_g).splitlines()) actual = stderr_g.getvalue().splitlines() 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(): @@ -1321,7 +1912,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(): ' @@ -1345,6 +1937,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): @@ -1698,6 +2308,7 @@ def exc(): f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' + f' | ~~~~~~~~~~~~~~~~~~~~~^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 1}, in exc\n' f' | raise ExceptionGroup("eg", [ValueError(1), TypeError(2)])\n' f' | ExceptionGroup: eg (2 sub-exceptions)\n' @@ -1733,6 +2344,7 @@ def exc(): f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' + f' | ~~~~~~~~~~~~~~~~~~~~~^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 5}, in exc\n' f' | raise EG("eg2", [ValueError(3), TypeError(4)]) from e\n' f' | ExceptionGroup: eg2 (2 sub-exceptions)\n' @@ -1784,6 +2396,7 @@ def exc(): f'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' f' exception_or_callable()\n' + f' ~~~~~~~~~~~~~~~~~~~~~^^\n' f' File "{__file__}", line {exc.__code__.co_firstlineno + 8}, in exc\n' f' raise ImportError(5)\n' f'ImportError: 5\n') @@ -1830,6 +2443,7 @@ def exc(): f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' + f' | ~~~~~~~~~~~~~~~~~~~~~^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 11}, in exc\n' f' | raise EG("top", [VE(5)])\n' f' | ExceptionGroup: top (1 sub-exception)\n' @@ -1989,6 +2603,7 @@ def exc(): expected = (f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' + f' | ~~~~~~~~~~~~~~~~~~~~~^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 9}, in exc\n' f' | raise ExceptionGroup("nested", excs)\n' f' | ExceptionGroup: nested (2 sub-exceptions)\n' @@ -2040,6 +2655,7 @@ def exc(): expected = (f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' + f' | ~~~~~~~~~~~~~~~~~~~~~^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 10}, in exc\n' f' | raise ExceptionGroup("nested", excs)\n' f' | ExceptionGroup: nested (2 sub-exceptions)\n' @@ -2308,7 +2924,7 @@ def test_basics(self): def test_lazy_lines(self): linecache.clearcache() f = traceback.FrameSummary("f", 1, "dummy", lookup_line=False) - self.assertEqual(None, f._line) + self.assertEqual(None, f._lines) linecache.lazycache("f", globals()) self.assertEqual( '"""Test cases for traceback module"""', @@ -2425,7 +3041,7 @@ def some_inner(k, v): def test_custom_format_frame(self): class CustomStackSummary(traceback.StackSummary): - def format_frame_summary(self, frame_summary): + def format_frame_summary(self, frame_summary, colorize=False): return f'{frame_summary.filename}:{frame_summary.lineno}' def some_inner(): @@ -2450,7 +3066,7 @@ def g(): tb = g() class Skip_G(traceback.StackSummary): - def format_frame_summary(self, frame_summary): + def format_frame_summary(self, frame_summary, colorize=False): if frame_summary.name == 'g': return None return super().format_frame_summary(frame_summary) @@ -2470,10 +3086,9 @@ def __repr__(self) -> str: raise Exception("Unrepresentable") class TestTracebackException(unittest.TestCase): - - def test_smoke(self): + def do_test_smoke(self, exc, expected_type_str): try: - 1/0 + raise exc except Exception as e: exc_obj = e exc = traceback.TracebackException.from_exception(e) @@ -2483,9 +3098,23 @@ def test_smoke(self): self.assertEqual(None, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(type(exc_obj), exc.exc_type) + with self.assertWarns(DeprecationWarning): + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(expected_type_str, exc.exc_type_str) self.assertEqual(str(exc_obj), str(exc)) + def test_smoke_builtin(self): + self.do_test_smoke(ValueError(42), 'ValueError') + + def test_smoke_user_exception(self): + class MyException(Exception): + pass + + self.do_test_smoke( + MyException('bad things happened'), + ('test.test_traceback.TestTracebackException.' + 'test_smoke_user_exception..MyException')) + def test_from_exception(self): # Check all the parameters are accepted. def foo(): @@ -2506,7 +3135,9 @@ def foo(): self.assertEqual(None, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(type(exc_obj), exc.exc_type) + with self.assertWarns(DeprecationWarning): + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(type(exc_obj).__name__, exc.exc_type_str) self.assertEqual(str(exc_obj), str(exc)) def test_cause(self): @@ -2528,7 +3159,9 @@ def test_cause(self): self.assertEqual(exc_context, exc.__context__) self.assertEqual(True, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(type(exc_obj), exc.exc_type) + with self.assertWarns(DeprecationWarning): + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(type(exc_obj).__name__, exc.exc_type_str) self.assertEqual(str(exc_obj), str(exc)) def test_context(self): @@ -2548,7 +3181,9 @@ def test_context(self): self.assertEqual(exc_context, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(type(exc_obj), exc.exc_type) + with self.assertWarns(DeprecationWarning): + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(type(exc_obj).__name__, exc.exc_type_str) self.assertEqual(str(exc_obj), str(exc)) def test_long_context_chain(self): @@ -2593,7 +3228,9 @@ def test_compact_with_cause(self): self.assertEqual(None, exc.__context__) self.assertEqual(True, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(type(exc_obj), exc.exc_type) + with self.assertWarns(DeprecationWarning): + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(type(exc_obj).__name__, exc.exc_type_str) self.assertEqual(str(exc_obj), str(exc)) def test_compact_no_cause(self): @@ -2613,9 +3250,22 @@ def test_compact_no_cause(self): self.assertEqual(exc_context, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(type(exc_obj), exc.exc_type) + with self.assertWarns(DeprecationWarning): + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(type(exc_obj).__name__, exc.exc_type_str) self.assertEqual(str(exc_obj), str(exc)) + def test_no_save_exc_type(self): + try: + 1/0 + except Exception as e: + exc = e + + te = traceback.TracebackException.from_exception( + exc, save_exc_type=False) + with self.assertWarns(DeprecationWarning): + self.assertIsNone(te.exc_type) + def test_no_refs_to_exception_and_traceback_objects(self): try: 1/0 @@ -2864,6 +3514,7 @@ def test_exception_group_format(self): f' | Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+9}, in _get_exception_group', f' | f()', + f' | ~^^', f' | File "{__file__}", line {lno_f+1}, in f', f' | 1/0', f' | ~^~', @@ -2872,6 +3523,7 @@ def test_exception_group_format(self): f' | Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+13}, in _get_exception_group', f' | g(42)', + f' | ~^^^^', f' | File "{__file__}", line {lno_g+1}, in g', f' | raise ValueError(v)', f' | ValueError: 42', @@ -2880,6 +3532,7 @@ def test_exception_group_format(self): f' | Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+20}, in _get_exception_group', f' | g(24)', + f' | ~^^^^', f' | File "{__file__}", line {lno_g+1}, in g', f' | raise ValueError(v)', f' | ValueError: 24', @@ -3601,6 +4254,115 @@ def test_levenshtein_distance_short_circuit(self): res3 = traceback._levenshtein_distance(a, b, threshold) self.assertGreater(res3, threshold, msg=(a, b, threshold)) +class TestColorizedTraceback(unittest.TestCase): + def test_colorized_traceback(self): + def foo(*args): + x = {'a':{'b': None}} + y = x['a']['b']['c'] + + def baz(*args): + return foo(1,2,3,4) + + def bar(): + return baz(1, + 2,3 + ,4) + try: + bar() + except Exception as e: + exc = traceback.TracebackException.from_exception( + e, capture_locals=True + ) + lines = "".join(exc.format(colorize=True)) + red = traceback._ANSIColors.RED + boldr = traceback._ANSIColors.BOLD_RED + reset = traceback._ANSIColors.RESET + self.assertIn("y = " + red + "x['a']['b']" + reset + boldr + "['c']" + reset, lines) + self.assertIn("return " + red + "foo" + reset + boldr + "(1,2,3,4)" + reset, lines) + self.assertIn("return " + red + "baz" + reset + boldr + "(1," + reset, lines) + self.assertIn(boldr + "2,3" + reset, lines) + self.assertIn(boldr + ",4)" + reset, lines) + self.assertIn(red + "bar" + reset + boldr + "()" + reset, lines) + + def test_colorized_syntax_error(self): + try: + compile("a $ b", "", "exec") + except SyntaxError as e: + exc = traceback.TracebackException.from_exception( + e, capture_locals=True + ) + actual = "".join(exc.format(colorize=True)) + red = traceback._ANSIColors.RED + magenta = traceback._ANSIColors.MAGENTA + boldm = traceback._ANSIColors.BOLD_MAGENTA + boldr = traceback._ANSIColors.BOLD_RED + reset = traceback._ANSIColors.RESET + expected = "".join([ + f' File {magenta}""{reset}, line {magenta}1{reset}\n', + f' a {boldr}${reset} b\n', + f' {boldr}^{reset}\n', + f'{boldm}SyntaxError{reset}: {magenta}invalid syntax{reset}\n'] + ) + self.assertIn(expected, actual) + + def test_colorized_traceback_is_the_default(self): + def foo(): + 1/0 + + from _testcapi import exception_print + try: + foo() + self.fail("No exception thrown.") + except Exception as e: + with captured_output("stderr") as tbstderr: + with unittest.mock.patch('traceback._can_colorize', return_value=True): + exception_print(e) + actual = tbstderr.getvalue().splitlines() + + red = traceback._ANSIColors.RED + boldr = traceback._ANSIColors.BOLD_RED + magenta = traceback._ANSIColors.MAGENTA + boldm = traceback._ANSIColors.BOLD_MAGENTA + reset = traceback._ANSIColors.RESET + lno_foo = foo.__code__.co_firstlineno + expected = ['Traceback (most recent call last):', + f' File {magenta}"{__file__}"{reset}, ' + f'line {magenta}{lno_foo+5}{reset}, in {magenta}test_colorized_traceback_is_the_default{reset}', + f' {red}foo{reset+boldr}(){reset}', + f' {red}~~~{reset+boldr}^^{reset}', + f' File {magenta}"{__file__}"{reset}, ' + f'line {magenta}{lno_foo+1}{reset}, in {magenta}foo{reset}', + f' {red}1{reset+boldr}/{reset+red}0{reset}', + f' {red}~{reset+boldr}^{reset+red}~{reset}', + f'{boldm}ZeroDivisionError{reset}: {magenta}division by zero{reset}'] + self.assertEqual(actual, expected) + + def test_colorized_detection_checks_for_environment_variables(self): + if sys.platform == "win32": + virtual_patching = unittest.mock.patch("nt._supports_virtual_terminal", return_value=True) + else: + virtual_patching = contextlib.nullcontext() + with virtual_patching: + with unittest.mock.patch("os.isatty") as isatty_mock: + isatty_mock.return_value = True + with unittest.mock.patch("os.environ", {'TERM': 'dumb'}): + self.assertEqual(traceback._can_colorize(), False) + with unittest.mock.patch("os.environ", {'PYTHON_COLORS': '1'}): + self.assertEqual(traceback._can_colorize(), True) + with unittest.mock.patch("os.environ", {'PYTHON_COLORS': '0'}): + self.assertEqual(traceback._can_colorize(), False) + with unittest.mock.patch("os.environ", {'NO_COLOR': '1'}): + self.assertEqual(traceback._can_colorize(), False) + with unittest.mock.patch("os.environ", {'NO_COLOR': '1', "PYTHON_COLORS": '1'}): + self.assertEqual(traceback._can_colorize(), True) + with unittest.mock.patch("os.environ", {'FORCE_COLOR': '1'}): + self.assertEqual(traceback._can_colorize(), True) + with unittest.mock.patch("os.environ", {'FORCE_COLOR': '1', 'NO_COLOR': '1'}): + self.assertEqual(traceback._can_colorize(), False) + with unittest.mock.patch("os.environ", {'FORCE_COLOR': '1', "PYTHON_COLORS": '0'}): + self.assertEqual(traceback._can_colorize(), False) + isatty_mock.return_value = False + self.assertEqual(traceback._can_colorize(), False) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_ttk/test_style.py b/Lib/test/test_ttk/test_style.py index f9c56ec2357451..9a04a95dc40d65 100644 --- a/Lib/test/test_ttk/test_style.py +++ b/Lib/test/test_ttk/test_style.py @@ -2,6 +2,7 @@ import sys import tkinter from tkinter import ttk +from tkinter import TclError from test import support from test.support import requires from test.test_tkinter.support import AbstractTkTest, get_tk_patchlevel @@ -122,7 +123,6 @@ def test_theme_use(self): self.style.theme_use(curr_theme) - def test_configure_custom_copy(self): style = self.style @@ -176,6 +176,270 @@ def test_map_custom_copy(self): for key, value in default.items(): self.assertEqual(style.map(newname, key), value) + def test_element_options(self): + style = self.style + element_names = style.element_names() + self.assertNotIsInstance(element_names, str) + for name in element_names: + self.assertIsInstance(name, str) + element_options = style.element_options(name) + self.assertNotIsInstance(element_options, str) + for optname in element_options: + self.assertIsInstance(optname, str) + + def test_element_create_errors(self): + style = self.style + with self.assertRaises(TypeError): + style.element_create('plain.newelem') + with self.assertRaisesRegex(TclError, 'No such element type spam'): + style.element_create('plain.newelem', 'spam') + + def test_element_create_from(self): + style = self.style + style.element_create('plain.background', 'from', 'default') + self.assertIn('plain.background', style.element_names()) + style.element_create('plain.arrow', 'from', 'default', 'rightarrow') + self.assertIn('plain.arrow', style.element_names()) + + def test_element_create_from_errors(self): + style = self.style + with self.assertRaises(IndexError): + style.element_create('plain.newelem', 'from') + with self.assertRaisesRegex(TclError, 'theme "spam" doesn\'t exist'): + style.element_create('plain.newelem', 'from', 'spam') + + def test_element_create_image(self): + style = self.style + image = tkinter.PhotoImage(master=self.root, width=12, height=10) + style.element_create('block', 'image', image) + self.assertIn('block', style.element_names()) + + style.layout('TestLabel1', [('block', {'sticky': 'news'})]) + a = ttk.Label(self.root, style='TestLabel1') + a.pack(expand=True, fill='both') + self.assertEqual(a.winfo_reqwidth(), 12) + self.assertEqual(a.winfo_reqheight(), 10) + + imgfile = support.findfile('python.xbm', subdir='tkinterdata') + img1 = tkinter.BitmapImage(master=self.root, file=imgfile, + foreground='yellow', background='blue') + img2 = tkinter.BitmapImage(master=self.root, file=imgfile, + foreground='blue', background='yellow') + img3 = tkinter.BitmapImage(master=self.root, file=imgfile, + foreground='white', background='black') + style.element_create('Button.button', 'image', + img1, ('pressed', img2), ('active', img3), + border=(2, 4), sticky='we') + self.assertIn('Button.button', style.element_names()) + + style.layout('Button', [('Button.button', {'sticky': 'news'})]) + b = ttk.Button(self.root, style='Button') + b.pack(expand=True, fill='both') + self.assertEqual(b.winfo_reqwidth(), 16) + self.assertEqual(b.winfo_reqheight(), 16) + + def test_element_create_image_errors(self): + style = self.style + image = tkinter.PhotoImage(master=self.root, width=10, height=10) + with self.assertRaises(IndexError): + style.element_create('block2', 'image') + with self.assertRaises(TypeError): + style.element_create('block2', 'image', image, 1) + with self.assertRaises(ValueError): + style.element_create('block2', 'image', image, ()) + with self.assertRaisesRegex(TclError, 'Invalid state name'): + style.element_create('block2', 'image', image, ('spam', image)) + with self.assertRaisesRegex(TclError, 'Invalid state name'): + style.element_create('block2', 'image', image, (1, image)) + with self.assertRaises(TypeError): + style.element_create('block2', 'image', image, ('pressed', 1, image)) + with self.assertRaises(TypeError): + style.element_create('block2', 'image', image, (1, 'selected', image)) + with self.assertRaisesRegex(TclError, 'bad option'): + style.element_create('block2', 'image', image, spam=1) + + def test_element_create_vsapi_1(self): + style = self.style + if 'xpnative' not in style.theme_names(): + self.skipTest("requires 'xpnative' theme") + style.element_create('smallclose', 'vsapi', 'WINDOW', 19, [ + ('disabled', 4), + ('pressed', 3), + ('active', 2), + ('', 1)]) + style.layout('CloseButton', + [('CloseButton.smallclose', {'sticky': 'news'})]) + b = ttk.Button(self.root, style='CloseButton') + b.pack(expand=True, fill='both') + self.assertEqual(b.winfo_reqwidth(), 13) + self.assertEqual(b.winfo_reqheight(), 13) + + def test_element_create_vsapi_2(self): + style = self.style + if 'xpnative' not in style.theme_names(): + self.skipTest("requires 'xpnative' theme") + style.element_create('pin', 'vsapi', 'EXPLORERBAR', 3, [ + ('pressed', '!selected', 3), + ('active', '!selected', 2), + ('pressed', 'selected', 6), + ('active', 'selected', 5), + ('selected', 4), + ('', 1)]) + style.layout('Explorer.Pin', + [('Explorer.Pin.pin', {'sticky': 'news'})]) + pin = ttk.Checkbutton(self.root, style='Explorer.Pin') + pin.pack(expand=True, fill='both') + self.assertEqual(pin.winfo_reqwidth(), 16) + self.assertEqual(pin.winfo_reqheight(), 16) + + def test_element_create_vsapi_3(self): + style = self.style + if 'xpnative' not in style.theme_names(): + self.skipTest("requires 'xpnative' theme") + style.element_create('headerclose', 'vsapi', 'EXPLORERBAR', 2, [ + ('pressed', 3), + ('active', 2), + ('', 1)]) + style.layout('Explorer.CloseButton', + [('Explorer.CloseButton.headerclose', {'sticky': 'news'})]) + b = ttk.Button(self.root, style='Explorer.CloseButton') + b.pack(expand=True, fill='both') + self.assertEqual(b.winfo_reqwidth(), 16) + self.assertEqual(b.winfo_reqheight(), 16) + + def test_theme_create(self): + style = self.style + curr_theme = style.theme_use() + curr_layout = style.layout('TLabel') + style.theme_create('testtheme1') + self.assertIn('testtheme1', style.theme_names()) + + style.theme_create('testtheme2', settings={ + 'elem' : {'element create': ['from', 'default'],}, + 'TLabel' : { + 'configure': {'padding': 10}, + 'layout': [('elem', {'sticky': 'we'})], + }, + }) + self.assertIn('testtheme2', style.theme_names()) + + style.theme_create('testtheme3', 'testtheme2') + self.assertIn('testtheme3', style.theme_names()) + + style.theme_use('testtheme1') + self.assertEqual(style.element_names(), ()) + self.assertEqual(style.layout('TLabel'), curr_layout) + + style.theme_use('testtheme2') + self.assertEqual(style.element_names(), ('elem',)) + self.assertEqual(style.lookup('TLabel', 'padding'), '10') + self.assertEqual(style.layout('TLabel'), [('elem', {'sticky': 'we'})]) + + style.theme_use('testtheme3') + self.assertEqual(style.element_names(), ()) + self.assertEqual(style.lookup('TLabel', 'padding'), '') + self.assertEqual(style.layout('TLabel'), [('elem', {'sticky': 'we'})]) + + style.theme_use(curr_theme) + + def test_theme_create_image(self): + style = self.style + curr_theme = style.theme_use() + image = tkinter.PhotoImage(master=self.root, width=10, height=10) + new_theme = 'testtheme4' + style.theme_create(new_theme, settings={ + 'block' : { + 'element create': ['image', image, {'width': 120, 'height': 100}], + }, + 'TestWidget.block2' : { + 'element create': ['image', image], + }, + 'TestWidget' : { + 'configure': { + 'anchor': 'left', + 'padding': (3, 0, 0, 2), + 'foreground': 'yellow', + }, + 'map': { + 'foreground': [ + ('pressed', 'red'), + ('active', 'disabled', 'blue'), + ], + }, + 'layout': [ + ('TestWidget.block', {'sticky': 'we', 'side': 'left'}), + ('TestWidget.border', { + 'sticky': 'nsw', + 'border': 1, + 'children': [ + ('TestWidget.block2', {'sticky': 'nswe'}) + ] + }) + ], + }, + }) + + style.theme_use(new_theme) + self.assertIn('block', style.element_names()) + self.assertEqual(style.lookup('TestWidget', 'anchor'), 'left') + self.assertEqual(style.lookup('TestWidget', 'padding'), '3 0 0 2') + self.assertEqual(style.lookup('TestWidget', 'foreground'), 'yellow') + self.assertEqual(style.lookup('TestWidget', 'foreground', + ['active']), 'yellow') + self.assertEqual(style.lookup('TestWidget', 'foreground', + ['active', 'pressed']), 'red') + self.assertEqual(style.lookup('TestWidget', 'foreground', + ['active', 'disabled']), 'blue') + self.assertEqual(style.layout('TestWidget'), + [ + ('TestWidget.block', {'side': 'left', 'sticky': 'we'}), + ('TestWidget.border', { + 'sticky': 'nsw', + 'border': '1', + 'children': [('TestWidget.block2', {'sticky': 'nswe'})] + }) + ]) + + b = ttk.Label(self.root, style='TestWidget') + b.pack(expand=True, fill='both') + self.assertEqual(b.winfo_reqwidth(), 134) + self.assertEqual(b.winfo_reqheight(), 100) + + style.theme_use(curr_theme) + + def test_theme_create_vsapi(self): + style = self.style + if 'xpnative' not in style.theme_names(): + self.skipTest("requires 'xpnative' theme") + curr_theme = style.theme_use() + new_theme = 'testtheme5' + style.theme_create(new_theme, settings={ + 'pin' : { + 'element create': ['vsapi', 'EXPLORERBAR', 3, [ + ('pressed', '!selected', 3), + ('active', '!selected', 2), + ('pressed', 'selected', 6), + ('active', 'selected', 5), + ('selected', 4), + ('', 1)]], + }, + 'Explorer.Pin' : { + 'layout': [('Explorer.Pin.pin', {'sticky': 'news'})], + }, + }) + + style.theme_use(new_theme) + self.assertIn('pin', style.element_names()) + self.assertEqual(style.layout('Explorer.Pin'), + [('Explorer.Pin.pin', {'sticky': 'nswe'})]) + + pin = ttk.Checkbutton(self.root, style='Explorer.Pin') + pin.pack(expand=True, fill='both') + self.assertEqual(pin.winfo_reqwidth(), 16) + self.assertEqual(pin.winfo_reqheight(), 16) + + style.theme_use(curr_theme) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_ttk_textonly.py b/Lib/test/test_ttk_textonly.py index 96dc179a69ecac..e6525c4d6c6982 100644 --- a/Lib/test/test_ttk_textonly.py +++ b/Lib/test/test_ttk_textonly.py @@ -179,7 +179,7 @@ def test_format_elemcreate(self): # don't format returned values as a tcl script # minimum acceptable for image type self.assertEqual(ttk._format_elemcreate('image', False, 'test'), - ("test ", ())) + ("test", ())) # specifying a state spec self.assertEqual(ttk._format_elemcreate('image', False, 'test', ('', 'a')), ("test {} a", ())) @@ -203,17 +203,19 @@ def test_format_elemcreate(self): # don't format returned values as a tcl script # minimum acceptable for vsapi self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b'), - ("a b ", ())) + ('a', 'b', ('', 1), ())) # now with a state spec with multiple states self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b', - ('a', 'b', 'c')), ("a b {a b} c", ())) + [('a', 'b', 'c')]), ('a', 'b', ('a b', 'c'), ())) # state spec and option self.assertEqual(ttk._format_elemcreate('vsapi', False, 'a', 'b', - ('a', 'b'), opt='x'), ("a b a b", ("-opt", "x"))) + [('a', 'b')], opt='x'), ('a', 'b', ('a', 'b'), ("-opt", "x"))) # format returned values as a tcl script # state spec with a multivalue and an option self.assertEqual(ttk._format_elemcreate('vsapi', True, 'a', 'b', - ('a', 'b', [1, 2]), opt='x'), ("{a b {a b} {1 2}}", "-opt x")) + opt='x'), ("a b {{} 1}", "-opt x")) + self.assertEqual(ttk._format_elemcreate('vsapi', True, 'a', 'b', + [('a', 'b', [1, 2])], opt='x'), ("a b {{a b} {1 2}}", "-opt x")) # Testing type = from # from type expects at least a type name @@ -222,9 +224,9 @@ def test_format_elemcreate(self): self.assertEqual(ttk._format_elemcreate('from', False, 'a'), ('a', ())) self.assertEqual(ttk._format_elemcreate('from', False, 'a', 'b'), - ('a', ('b', ))) + ('a', ('b',))) self.assertEqual(ttk._format_elemcreate('from', True, 'a', 'b'), - ('{a}', 'b')) + ('a', 'b')) def test_format_layoutlist(self): @@ -326,6 +328,22 @@ def test_script_from_settings(self): "ttk::style element create thing image {name {state1 state2} val} " "-opt {3 2m}") + vsapi = {'pin': {'element create': + ['vsapi', 'EXPLORERBAR', 3, [ + ('pressed', '!selected', 3), + ('active', '!selected', 2), + ('pressed', 'selected', 6), + ('active', 'selected', 5), + ('selected', 4), + ('', 1)]]}} + self.assertEqual(ttk._script_from_settings(vsapi), + "ttk::style element create pin vsapi EXPLORERBAR 3 {" + "{pressed !selected} 3 " + "{active !selected} 2 " + "{pressed selected} 6 " + "{active selected} 5 " + "selected 4 " + "{} 1} ") def test_tclobj_to_py(self): self.assertEqual( diff --git a/Lib/test/test_tty.py b/Lib/test/test_tty.py new file mode 100644 index 00000000000000..af20864aac361e --- /dev/null +++ b/Lib/test/test_tty.py @@ -0,0 +1,84 @@ +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): + mode0 = termios.tcgetattr(self.fd) + mode1 = tty.setraw(self.fd) + self.assertEqual(mode1, mode0) + 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): + mode0 = termios.tcgetattr(self.fd) + mode1 = tty.setcbreak(self.fd) + self.assertEqual(mode1, mode0) + 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_type_aliases.py b/Lib/test/test_type_aliases.py index 8f0a998e1f3dc1..9c325bc595f585 100644 --- a/Lib/test/test_type_aliases.py +++ b/Lib/test/test_type_aliases.py @@ -2,7 +2,7 @@ import types import unittest from test.support import check_syntax_error, run_code -from test import mod_generics_cache +from test.typinganndata import mod_generics_cache from typing import Callable, TypeAliasType, TypeVar, get_args diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 9a11fab237235e..5a911da56f8f8a 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -66,6 +66,14 @@ def foo(): pass """ +parenthesized_withstmt = """\ +with (a as b): # type: int + pass + +with (a, b): # type: int + pass +""" + vardecl = """\ a = 0 # type: int """ @@ -300,6 +308,14 @@ def test_withstmt(self): tree = self.classic_parse(withstmt) self.assertEqual(tree.body[0].type_comment, None) + def test_parenthesized_withstmt(self): + for tree in self.parse_all(parenthesized_withstmt, minver=9): + self.assertEqual(tree.body[0].type_comment, "int") + self.assertEqual(tree.body[1].type_comment, "int") + tree = self.classic_parse(parenthesized_withstmt) + self.assertEqual(tree.body[0].type_comment, None) + self.assertEqual(tree.body[1].type_comment, None) + def test_vardecl(self): for tree in self.parse_all(vardecl): self.assertEqual(tree.body[0].type_comment, "int") diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 9e891f113840be..2d10c39840ddf3 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -9,8 +9,7 @@ import pickle import re import sys -import warnings -from unittest import TestCase, main, skipUnless, skip +from unittest import TestCase, main, skip from unittest.mock import patch from copy import copy, deepcopy @@ -45,9 +44,8 @@ import weakref import types -from test.support import import_helper, captured_stderr, cpython_only -from test import mod_generics_cache -from test import _typed_dict_helper +from test.support import captured_stderr, cpython_only, infinite_recursion +from test.typinganndata import mod_generics_cache, _typed_dict_helper CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes' @@ -185,7 +183,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 +280,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 +337,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 +481,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): @@ -550,10 +548,16 @@ def test_many_weakrefs(self): with self.subTest(cls=cls): vals = weakref.WeakValueDictionary() - for x in range(100000): + 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. @@ -1244,20 +1248,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') @@ -1431,12 +1435,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') @@ -1804,11 +1808,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): @@ -2005,13 +2009,13 @@ def test_callable_instance_type_error(self): def f(): pass with self.assertRaises(TypeError): - self.assertIsInstance(f, Callable[[], None]) + isinstance(f, Callable[[], None]) with self.assertRaises(TypeError): - self.assertIsInstance(f, Callable[[], Any]) + isinstance(f, Callable[[], Any]) with self.assertRaises(TypeError): - self.assertNotIsInstance(None, Callable[[], None]) + isinstance(None, Callable[[], None]) with self.assertRaises(TypeError): - self.assertNotIsInstance(None, Callable[[], Any]) + isinstance(None, Callable[[], Any]) def test_repr(self): Callable = self.Callable @@ -2557,10 +2561,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 @@ -2836,7 +2840,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) @@ -3529,13 +3533,26 @@ def __subclasshook__(cls, other): def test_issubclass_fails_correctly(self): @runtime_checkable - class P(Protocol): + class NonCallableMembers(Protocol): x = 1 + class NotRuntimeCheckable(Protocol): + def callable_member(self) -> int: ... + + @runtime_checkable + class RuntimeCheckable(Protocol): + def callable_member(self) -> int: ... + class C: pass - with self.assertRaisesRegex(TypeError, r"issubclass\(\) arg 1 must be a class"): - issubclass(C(), P) + # These three all exercise different code paths, + # but should result in the same error message: + for protocol in NonCallableMembers, NotRuntimeCheckable, RuntimeCheckable: + with self.subTest(proto_name=protocol.__name__): + with self.assertRaisesRegex( + TypeError, r"issubclass\(\) arg 1 must be a class" + ): + issubclass(C(), protocol) def test_defining_generic_protocols(self): T = TypeVar('T') @@ -3658,11 +3675,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') @@ -3801,6 +3818,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) @@ -4054,6 +4104,22 @@ def method(self) -> None: ... self.assertIsInstance(Foo(), ProtocolWithMixedMembers) self.assertNotIsInstance(42, ProtocolWithMixedMembers) + def test_protocol_issubclass_error_message(self): + class Vec2D(Protocol): + x: float + y: float + + def square_norm(self) -> float: + return self.x ** 2 + self.y ** 2 + + self.assertEqual(Vec2D.__protocol_attrs__, {'x', 'y', 'square_norm'}) + expected_error_message = ( + "Protocols with non-method members don't support issubclass()." + " Non-method members: 'x', 'y'." + ) + with self.assertRaisesRegex(TypeError, re.escape(expected_error_message)): + issubclass(int, Vec2D) + class GenericTests(BaseTestCase): @@ -4094,12 +4160,12 @@ 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], @@ -4836,7 +4902,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): @@ -5074,15 +5140,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): @@ -5124,15 +5190,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): @@ -5584,10 +5650,11 @@ def fun(x: a): pass def cmp(o1, o2): return o1 == o2 - r1 = namespace1() - r2 = namespace2() - self.assertIsNot(r1, r2) - self.assertRaises(RecursionError, cmp, r1, r2) + with infinite_recursion(): + r1 = namespace1() + r2 = namespace2() + self.assertIsNot(r1, r2) + self.assertRaises(RecursionError, cmp, r1, r2) def test_union_forward_recursion(self): ValueList = List['Value'] @@ -7265,15 +7332,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): @@ -7481,6 +7548,83 @@ class GenericNamedTuple(NamedTuple, Generic[T]): self.assertEqual(CallNamedTuple.__orig_bases__, (NamedTuple,)) + def test_setname_called_on_values_in_class_dictionary(self): + class Vanilla: + def __set_name__(self, owner, name): + self.name = name + + class Foo(NamedTuple): + attr = Vanilla() + + foo = Foo() + self.assertEqual(len(foo), 0) + self.assertNotIn('attr', Foo._fields) + self.assertIsInstance(foo.attr, Vanilla) + self.assertEqual(foo.attr.name, "attr") + + class Bar(NamedTuple): + attr: Vanilla = Vanilla() + + bar = Bar() + self.assertEqual(len(bar), 1) + self.assertIn('attr', Bar._fields) + self.assertIsInstance(bar.attr, Vanilla) + self.assertEqual(bar.attr.name, "attr") + + def test_setname_raises_the_same_as_on_other_classes(self): + class CustomException(BaseException): pass + + class Annoying: + def __set_name__(self, owner, name): + raise CustomException + + annoying = Annoying() + + with self.assertRaises(CustomException) as cm: + class NormalClass: + attr = annoying + normal_exception = cm.exception + + with self.assertRaises(CustomException) as cm: + class NamedTupleClass(NamedTuple): + attr = annoying + namedtuple_exception = cm.exception + + self.assertIs(type(namedtuple_exception), CustomException) + self.assertIs(type(namedtuple_exception), type(normal_exception)) + + self.assertEqual(len(namedtuple_exception.__notes__), 1) + self.assertEqual( + len(namedtuple_exception.__notes__), len(normal_exception.__notes__) + ) + + expected_note = ( + "Error calling __set_name__ on 'Annoying' instance " + "'attr' in 'NamedTupleClass'" + ) + self.assertEqual(namedtuple_exception.__notes__[0], expected_note) + self.assertEqual( + namedtuple_exception.__notes__[0], + normal_exception.__notes__[0].replace("NormalClass", "NamedTupleClass") + ) + + def test_strange_errors_when_accessing_set_name_itself(self): + class CustomException(Exception): pass + + class Meta(type): + def __getattribute__(self, attr): + if attr == "__set_name__": + raise CustomException + return object.__getattribute__(self, attr) + + class VeryAnnoying(metaclass=Meta): pass + + very_annoying = VeryAnnoying() + + with self.assertRaises(CustomException): + class Foo(NamedTuple): + attr = very_annoying + class TypedDictTests(BaseTestCase): def test_basics_functional_syntax(self): @@ -7638,6 +7782,46 @@ class Cat(Animal): 'voice': str, }) + def test_keys_inheritance_with_same_name(self): + class NotTotal(TypedDict, total=False): + a: int + + class Total(NotTotal): + a: int + + self.assertEqual(NotTotal.__required_keys__, frozenset()) + self.assertEqual(NotTotal.__optional_keys__, frozenset(['a'])) + self.assertEqual(Total.__required_keys__, frozenset(['a'])) + self.assertEqual(Total.__optional_keys__, frozenset()) + + class Base(TypedDict): + a: NotRequired[int] + b: Required[int] + + class Child(Base): + a: Required[int] + b: NotRequired[int] + + self.assertEqual(Base.__required_keys__, frozenset(['b'])) + self.assertEqual(Base.__optional_keys__, frozenset(['a'])) + self.assertEqual(Child.__required_keys__, frozenset(['a'])) + self.assertEqual(Child.__optional_keys__, frozenset(['b'])) + + def test_multiple_inheritance_with_same_key(self): + class Base1(TypedDict): + a: NotRequired[int] + + class Base2(TypedDict): + a: Required[str] + + class Child(Base1, Base2): + pass + + # Last base wins + self.assertEqual(Child.__annotations__, {'a': Required[str]}) + self.assertEqual(Child.__required_keys__, frozenset(['a'])) + self.assertEqual(Child.__optional_keys__, frozenset()) + def test_required_notrequired_keys(self): self.assertEqual(NontotalMovie.__required_keys__, frozenset({"title"})) @@ -8037,15 +8221,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): @@ -8085,15 +8269,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): @@ -8192,7 +8376,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 @@ -8504,6 +8688,40 @@ class X(Annotated[int, (1, 10)]): ... self.assertEqual(X.__mro__, (X, int, object), "Annotated should be transparent.") + def test_annotated_cached_with_types(self): + class A(str): ... + class B(str): ... + + field_a1 = Annotated[str, A("X")] + field_a2 = Annotated[str, B("X")] + a1_metadata = field_a1.__metadata__[0] + a2_metadata = field_a2.__metadata__[0] + + self.assertIs(type(a1_metadata), A) + self.assertEqual(a1_metadata, A("X")) + self.assertIs(type(a2_metadata), B) + self.assertEqual(a2_metadata, B("X")) + self.assertIsNot(type(a1_metadata), type(a2_metadata)) + + field_b1 = Annotated[str, A("Y")] + field_b2 = Annotated[str, B("Y")] + b1_metadata = field_b1.__metadata__[0] + b2_metadata = field_b2.__metadata__[0] + + self.assertIs(type(b1_metadata), A) + self.assertEqual(b1_metadata, A("Y")) + self.assertIs(type(b2_metadata), B) + self.assertEqual(b2_metadata, B("Y")) + self.assertIsNot(type(b1_metadata), type(b2_metadata)) + + field_c1 = Annotated[int, 1] + field_c2 = Annotated[int, 1.0] + field_c3 = Annotated[int, True] + + self.assertIs(type(field_c1.__metadata__[0]), int) + self.assertIs(type(field_c2.__metadata__[0]), float) + self.assertIs(type(field_c3.__metadata__[0]), bool) + class TypeAliasTests(BaseTestCase): def test_canonical_usage_with_variable_annotation(self): @@ -8539,7 +8757,7 @@ class C(TypeAlias): pass with self.assertRaises(TypeError): - class C(type(TypeAlias)): + class D(type(TypeAlias)): pass def test_repr(self): @@ -8929,19 +9147,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): @@ -9022,15 +9240,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): @@ -9426,5 +9644,11 @@ def test_is_not_instance_of_iterable(self): self.assertNotIsInstance(type_to_test, collections.abc.Iterable) +def load_tests(loader, tests, pattern): + import doctest + tests.addTests(doctest.DocTestSuite(typing)) + return tests + + if __name__ == '__main__': main() diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 6adf03316ca0bb..d3bf4ea7c7d437 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -104,6 +104,26 @@ def test_name_inverse_lookup(self): if looked_name := self.db.name(char, None): self.assertEqual(self.db.lookup(looked_name), char) + def test_no_names_in_pua(self): + puas = [*range(0xe000, 0xf8ff), + *range(0xf0000, 0xfffff), + *range(0x100000, 0x10ffff)] + for i in puas: + char = chr(i) + self.assertRaises(ValueError, self.db.name, char) + + def test_lookup_nonexistant(self): + # just make sure that lookup can fail + for nonexistant in [ + "LATIN SMLL LETR A", + "OPEN HANDS SIGHS", + "DREGS", + "HANDBUG", + "MODIFIER LETTER CYRILLIC SMALL QUESTION MARK", + "???", + ]: + self.assertRaises(KeyError, self.db.lookup, nonexistant) + def test_digit(self): self.assertEqual(self.db.digit('A', None), None) self.assertEqual(self.db.digit('9'), 9) diff --git a/Lib/test/test_unittest/test_async_case.py b/Lib/test/test_unittest/test_async_case.py index a465103b59b6ec..ba1ab838cd4a22 100644 --- a/Lib/test/test_unittest/test_async_case.py +++ b/Lib/test/test_unittest/test_async_case.py @@ -484,5 +484,19 @@ async def test_demo1(self): result = test.run() self.assertTrue(result.wasSuccessful()) + def test_loop_factory(self): + asyncio.set_event_loop_policy(None) + + class TestCase1(unittest.IsolatedAsyncioTestCase): + loop_factory = asyncio.EventLoop + + async def test_demo1(self): + pass + + test = TestCase1('test_demo1') + result = test.run() + self.assertTrue(result.wasSuccessful()) + self.assertIsNone(support.maybe_get_event_loop_policy()) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_unittest/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py index d23eb87696f406..6af8acc3b0617e 100644 --- a/Lib/test/test_unittest/testmock/testmock.py +++ b/Lib/test/test_unittest/testmock/testmock.py @@ -1058,7 +1058,7 @@ def test_assert_called_with_failure_message(self): actual = 'not called.' expected = "mock(1, '2', 3, bar='foo')" - message = 'expected call not found.\nExpected: %s\nActual: %s' + message = 'expected call not found.\nExpected: %s\n Actual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), mock.assert_called_with, 1, '2', 3, bar='foo' @@ -1073,7 +1073,7 @@ def test_assert_called_with_failure_message(self): for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo(1, '2', 3, bar='foo')" - message = 'expected call not found.\nExpected: %s\nActual: %s' + message = 'expected call not found.\nExpected: %s\n Actual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth, 1, '2', 3, bar='foo' @@ -1083,7 +1083,7 @@ def test_assert_called_with_failure_message(self): for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo(bar='foo')" - message = 'expected call not found.\nExpected: %s\nActual: %s' + message = 'expected call not found.\nExpected: %s\n Actual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth, bar='foo' @@ -1093,7 +1093,7 @@ def test_assert_called_with_failure_message(self): for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo(1, 2, 3)" - message = 'expected call not found.\nExpected: %s\nActual: %s' + message = 'expected call not found.\nExpected: %s\n Actual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth, 1, 2, 3 @@ -1103,7 +1103,7 @@ def test_assert_called_with_failure_message(self): for meth in asserters: actual = "foo(1, '2', 3, foo='foo')" expected = "foo()" - message = 'expected call not found.\nExpected: %s\nActual: %s' + message = 'expected call not found.\nExpected: %s\n Actual: %s' self.assertRaisesWithMsg( AssertionError, message % (expected, actual), meth ) @@ -1552,7 +1552,7 @@ def f(x=None): pass '^{}$'.format( re.escape('Calls not found.\n' 'Expected: [call()]\n' - 'Actual: [call(1)]'))) as cm: + ' Actual: [call(1)]'))) as cm: mock.assert_has_calls([call()]) self.assertIsNone(cm.exception.__cause__) @@ -1564,7 +1564,7 @@ def f(x=None): pass 'Error processing expected calls.\n' "Errors: [None, TypeError('too many positional arguments')]\n" "Expected: [call(), call(1, 2)]\n" - 'Actual: [call(1)]'))) as cm: + ' Actual: [call(1)]'))) as cm: mock.assert_has_calls([call(), call(1, 2)]) self.assertIsInstance(cm.exception.__cause__, TypeError) diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index bdf7b0588bee67..6f698a8d891815 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -730,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_userdict.py b/Lib/test/test_userdict.py index 483910aaa4620e..9a03f2d04ce970 100644 --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -1,6 +1,6 @@ # Check every path through every method of UserDict -from test import mapping_tests +from test import mapping_tests, support import unittest import collections @@ -213,6 +213,11 @@ class G(collections.UserDict): else: self.fail("g[42] didn't raise KeyError") + # Decorate existing test with recursion limit, because + # the test is for C structure, but `UserDict` is a Python structure. + test_repr_deep = support.infinite_recursion()( + mapping_tests.TestHashMappingProtocol.test_repr_deep, + ) if __name__ == "__main__": diff --git a/Lib/test/test_userlist.py b/Lib/test/test_userlist.py index 1ed67dac805967..76d253753528b0 100644 --- a/Lib/test/test_userlist.py +++ b/Lib/test/test_userlist.py @@ -3,6 +3,8 @@ from collections import UserList from test import list_tests import unittest +from test import support + class UserListTest(list_tests.CommonTest): type2test = UserList @@ -65,5 +67,11 @@ def test_userlist_copy(self): self.assertEqual(u, v) self.assertEqual(type(u), type(v)) + # Decorate existing test with recursion limit, because + # the test is for C structure, but `UserList` is a Python structure. + test_repr_deep = support.infinite_recursion()( + list_tests.CommonTest.test_repr_deep, + ) + if __name__ == "__main__": unittest.main() 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_venv.py b/Lib/test/test_venv.py index 0ffe3e1d0cc498..617d14dcb9c5fe 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -46,14 +46,18 @@ def check_output(cmd, encoding=None): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - encoding=encoding) + stderr=subprocess.PIPE) out, err = p.communicate() if p.returncode: if verbose and err: - print(err.decode('utf-8', 'backslashreplace')) + print(err.decode(encoding or 'utf-8', 'backslashreplace')) raise subprocess.CalledProcessError( p.returncode, cmd, out, err) + if encoding: + return ( + out.decode(encoding, 'backslashreplace'), + err.decode(encoding, 'backslashreplace'), + ) return out, err class BaseTest(unittest.TestCase): @@ -281,8 +285,8 @@ def test_sysconfig(self): ('get_config_h_filename()', sysconfig.get_config_h_filename())): with self.subTest(call): cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call - out, err = check_output(cmd) - self.assertEqual(out.strip(), expected.encode(), err) + out, err = check_output(cmd, encoding='utf-8') + self.assertEqual(out.strip(), expected, err) @requireVenvCreate @unittest.skipUnless(can_symlink(), 'Needs symlinks') @@ -303,8 +307,8 @@ def test_sysconfig_symlinks(self): ('get_config_h_filename()', sysconfig.get_config_h_filename())): with self.subTest(call): cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call - out, err = check_output(cmd) - self.assertEqual(out.strip(), expected.encode(), err) + out, err = check_output(cmd, encoding='utf-8') + self.assertEqual(out.strip(), expected, err) if sys.platform == 'win32': ENV_SUBDIRS = ( @@ -569,7 +573,11 @@ 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) diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 83237f5fe0d1b3..50b0f3fff04c57 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -5,6 +5,8 @@ import re import sys import textwrap +import types +from typing import overload, get_overloads import unittest from test import support from test.support import import_helper @@ -16,6 +18,7 @@ from test.test_warnings.data import stacklevel as warning_tests import warnings as original_warnings +from warnings import deprecated py_warnings = import_helper.import_fresh_module('warnings', @@ -90,7 +93,7 @@ def test_module_all_attribute(self): self.assertTrue(hasattr(self.module, '__all__')) target_api = ["warn", "warn_explicit", "showwarning", "formatwarning", "filterwarnings", "simplefilter", - "resetwarnings", "catch_warnings"] + "resetwarnings", "catch_warnings", "deprecated"] self.assertSetEqual(set(self.module.__all__), set(target_api)) @@ -372,6 +375,28 @@ def test_append_duplicate(self): "appended duplicate changed order of filters" ) + def test_argument_validation(self): + with self.assertRaises(ValueError): + self.module.filterwarnings(action='foo') + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', message=0) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', category=0) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', category=int) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', module=0) + with self.assertRaises(TypeError): + self.module.filterwarnings('ignore', lineno=int) + with self.assertRaises(ValueError): + self.module.filterwarnings('ignore', lineno=-1) + with self.assertRaises(ValueError): + self.module.simplefilter(action='foo') + with self.assertRaises(TypeError): + self.module.simplefilter('ignore', lineno=int) + with self.assertRaises(ValueError): + self.module.simplefilter('ignore', lineno=-1) + def test_catchwarnings_with_simplefilter_ignore(self): with original_warnings.catch_warnings(module=self.module): self.module.resetwarnings() @@ -1233,6 +1258,10 @@ def test_conflicting_envvar_and_command_line(self): self.assertEqual(stderr.splitlines(), [b"Traceback (most recent call last):", b" File \"\", line 1, in ", + b' import sys, warnings; sys.stdout.write(str(sys.warnoptions)); warnings.w' + b"arn('Message', DeprecationWarning)", + b' ~~~~~~~~~~' + b'~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', b"DeprecationWarning: Message"]) def test_default_filter_configuration(self): @@ -1373,6 +1402,283 @@ def test_late_resource_warning(self): self.assertTrue(err.startswith(expected), ascii(err)) +class DeprecatedTests(unittest.TestCase): + def test_dunder_deprecated(self): + @deprecated("A will go away soon") + class A: + pass + + self.assertEqual(A.__deprecated__, "A will go away soon") + self.assertIsInstance(A, type) + + @deprecated("b will go away soon") + def b(): + pass + + self.assertEqual(b.__deprecated__, "b will go away soon") + self.assertIsInstance(b, types.FunctionType) + + @overload + @deprecated("no more ints") + def h(x: int) -> int: ... + @overload + def h(x: str) -> str: ... + def h(x): + return x + + overloads = get_overloads(h) + self.assertEqual(len(overloads), 2) + self.assertEqual(overloads[0].__deprecated__, "no more ints") + + def test_class(self): + @deprecated("A will go away soon") + class A: + pass + + with self.assertWarnsRegex(DeprecationWarning, "A will go away soon"): + A() + with self.assertWarnsRegex(DeprecationWarning, "A will go away soon"): + with self.assertRaises(TypeError): + A(42) + + def test_class_with_init(self): + @deprecated("HasInit will go away soon") + class HasInit: + def __init__(self, x): + self.x = x + + with self.assertWarnsRegex(DeprecationWarning, "HasInit will go away soon"): + instance = HasInit(42) + self.assertEqual(instance.x, 42) + + def test_class_with_new(self): + has_new_called = False + + @deprecated("HasNew will go away soon") + class HasNew: + def __new__(cls, x): + nonlocal has_new_called + has_new_called = True + return super().__new__(cls) + + def __init__(self, x) -> None: + self.x = x + + with self.assertWarnsRegex(DeprecationWarning, "HasNew will go away soon"): + instance = HasNew(42) + self.assertEqual(instance.x, 42) + self.assertTrue(has_new_called) + + def test_class_with_inherited_new(self): + new_base_called = False + + class NewBase: + def __new__(cls, x): + nonlocal new_base_called + new_base_called = True + return super().__new__(cls) + + def __init__(self, x) -> None: + self.x = x + + @deprecated("HasInheritedNew will go away soon") + class HasInheritedNew(NewBase): + pass + + with self.assertWarnsRegex(DeprecationWarning, "HasInheritedNew will go away soon"): + instance = HasInheritedNew(42) + self.assertEqual(instance.x, 42) + self.assertTrue(new_base_called) + + def test_class_with_new_but_no_init(self): + new_called = False + + @deprecated("HasNewNoInit will go away soon") + class HasNewNoInit: + def __new__(cls, x): + nonlocal new_called + new_called = True + obj = super().__new__(cls) + obj.x = x + return obj + + with self.assertWarnsRegex(DeprecationWarning, "HasNewNoInit will go away soon"): + instance = HasNewNoInit(42) + self.assertEqual(instance.x, 42) + self.assertTrue(new_called) + + def test_mixin_class(self): + @deprecated("Mixin will go away soon") + class Mixin: + pass + + class Base: + def __init__(self, a) -> None: + self.a = a + + with self.assertWarnsRegex(DeprecationWarning, "Mixin will go away soon"): + class Child(Base, Mixin): + pass + + instance = Child(42) + self.assertEqual(instance.a, 42) + + def test_existing_init_subclass(self): + @deprecated("C will go away soon") + class C: + def __init_subclass__(cls) -> None: + cls.inited = True + + with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"): + C() + + with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"): + class D(C): + pass + + self.assertTrue(D.inited) + self.assertIsInstance(D(), D) # no deprecation + + def test_existing_init_subclass_in_base(self): + class Base: + def __init_subclass__(cls, x) -> None: + cls.inited = x + + @deprecated("C will go away soon") + class C(Base, x=42): + pass + + self.assertEqual(C.inited, 42) + + with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"): + C() + + with self.assertWarnsRegex(DeprecationWarning, "C will go away soon"): + class D(C, x=3): + pass + + self.assertEqual(D.inited, 3) + + def test_init_subclass_has_correct_cls(self): + init_subclass_saw = None + + @deprecated("Base will go away soon") + class Base: + def __init_subclass__(cls) -> None: + nonlocal init_subclass_saw + init_subclass_saw = cls + + self.assertIsNone(init_subclass_saw) + + with self.assertWarnsRegex(DeprecationWarning, "Base will go away soon"): + class C(Base): + pass + + self.assertIs(init_subclass_saw, C) + + def test_init_subclass_with_explicit_classmethod(self): + init_subclass_saw = None + + @deprecated("Base will go away soon") + class Base: + @classmethod + def __init_subclass__(cls) -> None: + nonlocal init_subclass_saw + init_subclass_saw = cls + + self.assertIsNone(init_subclass_saw) + + with self.assertWarnsRegex(DeprecationWarning, "Base will go away soon"): + class C(Base): + pass + + self.assertIs(init_subclass_saw, C) + + def test_function(self): + @deprecated("b will go away soon") + def b(): + pass + + with self.assertWarnsRegex(DeprecationWarning, "b will go away soon"): + b() + + def test_method(self): + class Capybara: + @deprecated("x will go away soon") + def x(self): + pass + + instance = Capybara() + with self.assertWarnsRegex(DeprecationWarning, "x will go away soon"): + instance.x() + + def test_property(self): + class Capybara: + @property + @deprecated("x will go away soon") + def x(self): + pass + + @property + def no_more_setting(self): + return 42 + + @no_more_setting.setter + @deprecated("no more setting") + def no_more_setting(self, value): + pass + + instance = Capybara() + with self.assertWarnsRegex(DeprecationWarning, "x will go away soon"): + instance.x + + with py_warnings.catch_warnings(): + py_warnings.simplefilter("error") + self.assertEqual(instance.no_more_setting, 42) + + with self.assertWarnsRegex(DeprecationWarning, "no more setting"): + instance.no_more_setting = 42 + + def test_category(self): + @deprecated("c will go away soon", category=RuntimeWarning) + def c(): + pass + + with self.assertWarnsRegex(RuntimeWarning, "c will go away soon"): + c() + + def test_turn_off_warnings(self): + @deprecated("d will go away soon", category=None) + def d(): + pass + + with py_warnings.catch_warnings(): + py_warnings.simplefilter("error") + d() + + def test_only_strings_allowed(self): + with self.assertRaisesRegex( + TypeError, + "Expected an object of type str for 'message', not 'type'" + ): + @deprecated + class Foo: ... + + with self.assertRaisesRegex( + TypeError, + "Expected an object of type str for 'message', not 'function'" + ): + @deprecated + def foo(): ... + + def test_no_retained_references_to_wrapper_instance(self): + @deprecated('depr') + def d(): pass + + self.assertFalse(any( + isinstance(cell.cell_contents, deprecated) for cell in d.__closure__ + )) + def setUpModule(): py_warnings.onceregistry.clear() c_warnings.onceregistry.clear() 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 6d413aa68a338d..b9e7937b0bbc00 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2535,6 +2535,7 @@ def __eq__(self, o): e.extend([ET.Element('bar')]) self.assertRaises(ValueError, e.remove, X('baz')) + @support.infinite_recursion(25) def test_recursive_repr(self): # Issue #25455 e = ET.Element('foo') diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 0f6c0f2107ce6b..a51764b9297363 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -1754,7 +1754,7 @@ def test_unsupported_version(self): @requires_zlib() def test_read_unicode_filenames(self): # bug #10801 - fname = findfile('zip_cp437_header.zip') + fname = findfile('zip_cp437_header.zip', subdir='archivetestdata') with zipfile.ZipFile(fname) as zipfp: for name in zipfp.namelist(): zipfp.open(name).close() @@ -1769,13 +1769,9 @@ def test_write_unicode_filenames(self): self.assertEqual(zf.filelist[0].filename, "foo.txt") self.assertEqual(zf.filelist[1].filename, "\xf6.txt") - @requires_zlib() - def test_read_zipfile_containing_unicode_path_extra_field(self): + def create_zipfile_with_extra_data(self, filename, extra_data_name): with zipfile.ZipFile(TESTFN, mode='w') as zf: - # create a file with a non-ASCII name - filename = '이름.txt' - filename_encoded = filename.encode('utf-8') - + filename_encoded = filename.encode("utf-8") # create a ZipInfo object with Unicode path extra field zip_info = zipfile.ZipInfo(filename) @@ -1785,7 +1781,7 @@ def test_read_zipfile_containing_unicode_path_extra_field(self): import zlib filename_crc = struct.pack('= (1, 2, 5, 3): + if ZLIB_RUNTIME_VERSION_TUPLE >= (1, 2, 5, 3): sync_opt.append('Z_BLOCK') sync_opt = [getattr(zlib, opt) for opt in sync_opt @@ -512,18 +526,7 @@ def test_odd_flush(self): # Try 17K of data # generate random data stream - try: - # In 2.3 and later, WichmannHill is the RNG of the bug report - gen = random.WichmannHill() - except AttributeError: - try: - # 2.2 called it Random - gen = random.Random() - except AttributeError: - # others might simply have a single RNG - gen = random - gen.seed(1) - data = gen.randbytes(17 * 1024) + data = random.randbytes(17 * 1024) # compress, sync-flush, and decompress first = co.compress(data) @@ -804,16 +807,7 @@ def test_large_unconsumed_tail(self, size): def test_wbits(self): # wbits=0 only supported since zlib v1.2.3.5 - # Register "1.2.3" as "1.2.3.0" - # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux" - v = zlib.ZLIB_RUNTIME_VERSION.split('-', 1)[0].split('.') - if len(v) < 4: - v.append('0') - elif not v[-1].isnumeric(): - v[-1] = '0' - - v = tuple(map(int, v)) - supports_wbits_0 = v >= (1, 2, 3, 5) + supports_wbits_0 = ZLIB_RUNTIME_VERSION_TUPLE >= (1, 2, 3, 5) co = zlib.compressobj(level=1, wbits=15) zlib15 = co.compress(HAMLET_SCENE) + co.flush() diff --git a/Lib/test/test_zoneinfo/__init__.py b/Lib/test/test_zoneinfo/__init__.py index c3ea567103275d..4b16ecc31156a5 100644 --- a/Lib/test/test_zoneinfo/__init__.py +++ b/Lib/test/test_zoneinfo/__init__.py @@ -1,2 +1,5 @@ -from .test_zoneinfo import * -from .test_zoneinfo_property import * +import os +from test.support import load_package_tests + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index ae921f7432c466..3766ceac8385f2 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -1001,6 +1001,80 @@ def test_tzstr_from_utc(self): self.assertEqual(dt_act, dt_utc) + def test_extreme_tzstr(self): + tzstrs = [ + # Extreme offset hour + "AAA24", + "AAA+24", + "AAA-24", + "AAA24BBB,J60/2,J300/2", + "AAA+24BBB,J60/2,J300/2", + "AAA-24BBB,J60/2,J300/2", + "AAA4BBB24,J60/2,J300/2", + "AAA4BBB+24,J60/2,J300/2", + "AAA4BBB-24,J60/2,J300/2", + # Extreme offset minutes + "AAA4:00BBB,J60/2,J300/2", + "AAA4:59BBB,J60/2,J300/2", + "AAA4BBB5:00,J60/2,J300/2", + "AAA4BBB5:59,J60/2,J300/2", + # Extreme offset seconds + "AAA4:00:00BBB,J60/2,J300/2", + "AAA4:00:59BBB,J60/2,J300/2", + "AAA4BBB5:00:00,J60/2,J300/2", + "AAA4BBB5:00:59,J60/2,J300/2", + # Extreme total offset + "AAA24:59:59BBB5,J60/2,J300/2", + "AAA-24:59:59BBB5,J60/2,J300/2", + "AAA4BBB24:59:59,J60/2,J300/2", + "AAA4BBB-24:59:59,J60/2,J300/2", + # Extreme months + "AAA4BBB,M12.1.1/2,M1.1.1/2", + "AAA4BBB,M1.1.1/2,M12.1.1/2", + # Extreme weeks + "AAA4BBB,M1.5.1/2,M1.1.1/2", + "AAA4BBB,M1.1.1/2,M1.5.1/2", + # Extreme weekday + "AAA4BBB,M1.1.6/2,M2.1.1/2", + "AAA4BBB,M1.1.1/2,M2.1.6/2", + # Extreme numeric offset + "AAA4BBB,0/2,20/2", + "AAA4BBB,0/2,0/14", + "AAA4BBB,20/2,365/2", + "AAA4BBB,365/2,365/14", + # Extreme julian offset + "AAA4BBB,J1/2,J20/2", + "AAA4BBB,J1/2,J1/14", + "AAA4BBB,J20/2,J365/2", + "AAA4BBB,J365/2,J365/14", + # Extreme transition hour + "AAA4BBB,J60/167,J300/2", + "AAA4BBB,J60/+167,J300/2", + "AAA4BBB,J60/-167,J300/2", + "AAA4BBB,J60/2,J300/167", + "AAA4BBB,J60/2,J300/+167", + "AAA4BBB,J60/2,J300/-167", + # Extreme transition minutes + "AAA4BBB,J60/2:00,J300/2", + "AAA4BBB,J60/2:59,J300/2", + "AAA4BBB,J60/2,J300/2:00", + "AAA4BBB,J60/2,J300/2:59", + # Extreme transition seconds + "AAA4BBB,J60/2:00:00,J300/2", + "AAA4BBB,J60/2:00:59,J300/2", + "AAA4BBB,J60/2,J300/2:00:00", + "AAA4BBB,J60/2,J300/2:00:59", + # Extreme total transition time + "AAA4BBB,J60/167:59:59,J300/2", + "AAA4BBB,J60/-167:59:59,J300/2", + "AAA4BBB,J60/2,J300/167:59:59", + "AAA4BBB,J60/2,J300/-167:59:59", + ] + + for tzstr in tzstrs: + with self.subTest(tzstr=tzstr): + self.zone_from_tzstr(tzstr) + def test_invalid_tzstr(self): invalid_tzstrs = [ "PST8PDT", # DST but no transition specified @@ -1008,16 +1082,33 @@ def test_invalid_tzstr(self): "GMT,M3.2.0/2,M11.1.0/3", # Transition rule but no DST "GMT0+11,M3.2.0/2,M11.1.0/3", # Unquoted alphanumeric in DST "PST8PDT,M3.2.0/2", # Only one transition rule - # Invalid offsets - "STD+25", - "STD-25", - "STD+374", - "STD+374DST,M3.2.0/2,M11.1.0/3", - "STD+23DST+25,M3.2.0/2,M11.1.0/3", - "STD-23DST-25,M3.2.0/2,M11.1.0/3", + # Invalid offset hours + "AAA168", + "AAA+168", + "AAA-168", + "AAA168BBB,J60/2,J300/2", + "AAA+168BBB,J60/2,J300/2", + "AAA-168BBB,J60/2,J300/2", + "AAA4BBB168,J60/2,J300/2", + "AAA4BBB+168,J60/2,J300/2", + "AAA4BBB-168,J60/2,J300/2", + # Invalid offset minutes + "AAA4:0BBB,J60/2,J300/2", + "AAA4:100BBB,J60/2,J300/2", + "AAA4BBB5:0,J60/2,J300/2", + "AAA4BBB5:100,J60/2,J300/2", + # Invalid offset seconds + "AAA4:00:0BBB,J60/2,J300/2", + "AAA4:00:100BBB,J60/2,J300/2", + "AAA4BBB5:00:0,J60/2,J300/2", + "AAA4BBB5:00:100,J60/2,J300/2", # Completely invalid dates "AAA4BBB,M1443339,M11.1.0/3", "AAA4BBB,M3.2.0/2,0349309483959c", + "AAA4BBB,,J300/2", + "AAA4BBB,z,J300/2", + "AAA4BBB,J60/2,", + "AAA4BBB,J60/2,z", # Invalid months "AAA4BBB,M13.1.1/2,M1.1.1/2", "AAA4BBB,M1.1.1/2,M13.1.1/2", @@ -1037,6 +1128,26 @@ def test_invalid_tzstr(self): # Invalid julian offset "AAA4BBB,J0/2,J20/2", "AAA4BBB,J20/2,J366/2", + # Invalid transition time + "AAA4BBB,J60/2/3,J300/2", + "AAA4BBB,J60/2,J300/2/3", + # Invalid transition hour + "AAA4BBB,J60/168,J300/2", + "AAA4BBB,J60/+168,J300/2", + "AAA4BBB,J60/-168,J300/2", + "AAA4BBB,J60/2,J300/168", + "AAA4BBB,J60/2,J300/+168", + "AAA4BBB,J60/2,J300/-168", + # Invalid transition minutes + "AAA4BBB,J60/2:0,J300/2", + "AAA4BBB,J60/2:100,J300/2", + "AAA4BBB,J60/2,J300/2:0", + "AAA4BBB,J60/2,J300/2:100", + # Invalid transition seconds + "AAA4BBB,J60/2:00:0,J300/2", + "AAA4BBB,J60/2:00:100,J300/2", + "AAA4BBB,J60/2,J300/2:00:0", + "AAA4BBB,J60/2,J300/2:00:100", ] for invalid_tzstr in invalid_tzstrs: diff --git a/Lib/test/_typed_dict_helper.py b/Lib/test/typinganndata/_typed_dict_helper.py similarity index 100% rename from Lib/test/_typed_dict_helper.py rename to Lib/test/typinganndata/_typed_dict_helper.py diff --git a/Lib/test/mod_generics_cache.py b/Lib/test/typinganndata/mod_generics_cache.py similarity index 100% rename from Lib/test/mod_generics_cache.py rename to Lib/test/typinganndata/mod_generics_cache.py diff --git a/Lib/test/ziptestdata/README.md b/Lib/test/ziptestdata/README.md deleted file mode 100644 index 6b9147db76e178..00000000000000 --- a/Lib/test/ziptestdata/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Test data for `test_zipfile` - -The test executables in this directory are created manually from header.sh and -the `testdata_module_inside_zip.py` file. You must have infozip's zip utility -installed (`apt install zip` on Debian). - -## Purpose - -These are used to test executable files with an appended zipfile, in a scenario -where the executable is _not_ a Python interpreter itself so our automatic -zipimport machinery (that'd look for `__main__.py`) is not being used. - -## Updating the test executables - -If you update header.sh or the testdata_module_inside_zip.py file, rerun the -commands below. These are expected to be rarely changed, if ever. - -### Standard old format (2.0) zip file - -``` -zip -0 zip2.zip testdata_module_inside_zip.py -cat header.sh zip2.zip >exe_with_zip -rm zip2.zip -``` - -### Modern format (4.5) zip64 file - -Redirecting from stdin forces infozip's zip tool to create a zip64. - -``` -zip -0 zip64.zip -cat header.sh zip64.zip >exe_with_z64 -rm zip64.zip -``` - diff --git a/Lib/threading.py b/Lib/threading.py index 31cefd2143a8c4..85aff58968082d 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -5,6 +5,7 @@ import _thread import functools import warnings +import _weakref from time import monotonic as _time from _weakrefset import WeakSet @@ -33,11 +34,12 @@ 'setprofile_all_threads','settrace_all_threads'] # Rename some stuff so "from threading import *" is safe -_start_new_thread = _thread.start_new_thread +_start_joinable_thread = _thread.start_joinable_thread _daemon_threads_allowed = _thread.daemon_threads_allowed _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 @@ -588,7 +590,7 @@ def __repr__(self): return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: {status}>" def _at_fork_reinit(self): - # Private method called by Thread._reset_internal_locks() + # Private method called by Thread._after_fork() self._cond._at_fork_reinit() def is_set(self): @@ -923,6 +925,8 @@ class is implemented. if _HAVE_THREAD_NATIVE_ID: self._native_id = None self._tstate_lock = None + self._join_lock = None + self._handle = None self._started = Event() self._is_stopped = False self._initialized = True @@ -932,22 +936,32 @@ class is implemented. # For debugging and _after_fork() _dangling.add(self) - def _reset_internal_locks(self, is_alive): - # private! Called by _after_fork() to reset our internal locks as - # they may be in an invalid state leading to a deadlock or crash. + def _after_fork(self, new_ident=None): + # Private! Called by threading._after_fork(). self._started._at_fork_reinit() - if is_alive: + if new_ident is not None: + # This thread is alive. + self._ident = new_ident + if self._handle is not None: + self._handle.after_fork_alive() + assert self._handle.ident == new_ident # bpo-42350: If the fork happens when the thread is already stopped # (ex: after threading._shutdown() has been called), _tstate_lock # is None. Do nothing in this case. if self._tstate_lock is not None: self._tstate_lock._at_fork_reinit() self._tstate_lock.acquire() + if self._join_lock is not None: + self._join_lock._at_fork_reinit() else: - # The thread isn't alive after fork: it doesn't have a tstate + # This thread isn't alive after fork: it doesn't have a tstate # anymore. self._is_stopped = True self._tstate_lock = None + self._join_lock = None + if self._handle is not None: + self._handle.after_fork_dead() + self._handle = None def __repr__(self): assert self._initialized, "Thread.__init__() was not called" @@ -979,15 +993,18 @@ def start(self): if self._started.is_set(): raise RuntimeError("threads can only be started once") + self._join_lock = _allocate_lock() + with _active_limbo_lock: _limbo[self] = self try: - _start_new_thread(self._bootstrap, ()) + # Start joinable thread + self._handle = _start_joinable_thread(self._bootstrap) except Exception: with _active_limbo_lock: del _limbo[self] raise - self._started.wait() + self._started.wait() # Will set ident and native_id def run(self): """Method representing the thread's activity. @@ -1143,6 +1160,22 @@ def join(self, timeout=None): # historically .join(timeout=x) for x<0 has acted as if timeout=0 self._wait_for_tstate_lock(timeout=max(timeout, 0)) + if self._is_stopped: + self._join_os_thread() + + def _join_os_thread(self): + join_lock = self._join_lock + if join_lock is None: + return + with join_lock: + # Calling join() multiple times would raise an exception + # in one of the callers. + if self._handle is not None: + self._handle.join() + self._handle = None + # No need to keep this around + self._join_lock = None + def _wait_for_tstate_lock(self, block=True, timeout=-1): # Issue #18808: wait for the thread state to be gone. # At the end of the thread's life, after all knowledge of the thread @@ -1222,7 +1255,10 @@ def is_alive(self): if self._is_stopped or not self._started.is_set(): return False self._wait_for_tstate_lock(False) - return not self._is_stopped + if not self._is_stopped: + return True + self._join_os_thread() + return False @property def daemon(self): @@ -1574,7 +1610,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 @@ -1592,8 +1628,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. @@ -1627,6 +1666,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 @@ -1674,15 +1714,13 @@ def _after_fork(): # Any lock/condition variable may be currently locked or in an # invalid state, so we reinitialize them. if thread is current: - # There is only one active thread. We reset the ident to - # its new value since it can have changed. - thread._reset_internal_locks(True) + # This is the one and only active thread. ident = get_ident() - thread._ident = ident + thread._after_fork(new_ident=ident) new_active[ident] = thread else: # All the others are already stopped. - thread._reset_internal_locks(False) + thread._after_fork() thread._stop() _limbo.clear() diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 440e7f100c8c47..124882420c255c 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1527,10 +1527,24 @@ def bind(self, sequence=None, func=None, add=None): return self._bind(('bind', self._w), sequence, func, add) def unbind(self, sequence, funcid=None): - """Unbind for this widget for event SEQUENCE the - function identified with FUNCID.""" - self.tk.call('bind', self._w, sequence, '') - if funcid: + """Unbind for this widget the event SEQUENCE. + + If FUNCID is given, only unbind the function identified with FUNCID + and also delete the corresponding Tcl command. + + Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE + unbound. + """ + if funcid is None: + self.tk.call('bind', self._w, sequence, '') + else: + lines = self.tk.call('bind', self._w, sequence).split('\n') + prefix = f'if {{"[{funcid} ' + keep = '\n'.join(line for line in lines + if not line.startswith(prefix)) + if not keep.strip(): + keep = '' + self.tk.call('bind', self._w, sequence, keep) self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): @@ -1538,7 +1552,7 @@ def bind_all(self, sequence=None, func=None, add=None): An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" - return self._bind(('bind', 'all'), sequence, func, add, 0) + return self._root()._bind(('bind', 'all'), sequence, func, add, True) def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" @@ -1552,7 +1566,7 @@ def bind_class(self, className, sequence=None, func=None, add=None): whether it will replace the previous function. See bind for the return value.""" - return self._bind(('bind', className), sequence, func, add, 0) + return self._root()._bind(('bind', className), sequence, func, add, True) def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE @@ -3715,25 +3729,28 @@ def compare(self, index1, op, index2): return self.tk.getboolean(self.tk.call( self._w, 'compare', index1, op, index2)) - def count(self, index1, index2, *args): # new in Tk 8.5 + def count(self, index1, index2, *options): # new in Tk 8.5 """Counts the number of relevant things between the two indices. - If index1 is after index2, the result will be a negative number + + If INDEX1 is after INDEX2, the result will be a negative number (and this holds for each of the possible options). - The actual items which are counted depends on the options given by - args. The result is a list of integers, one for the result of each - counting option given. Valid counting options are "chars", + The actual items which are counted depends on the options given. + The result is a tuple of integers, one for the result of each + counting option given, if more than one option is specified, + otherwise it is an integer. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", - "lines", "xpixels" and "ypixels". There is an additional possible + "lines", "xpixels" and "ypixels". The default value, if no + option is specified, is "indices". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" - args = ['-%s' % arg for arg in args] - args += [index1, index2] - res = self.tk.call(self._w, 'count', *args) or None - if res is not None and len(args) <= 3: - return (res, ) - else: - return res + options = ['-%s' % arg for arg in options] + res = self.tk.call(self._w, 'count', *options, index1, index2) + if not isinstance(res, int): + res = self._getints(res) + if len(res) == 1: + res, = res + return res def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index efeabb7a92c627..5ca938a670831a 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -95,40 +95,47 @@ def _format_mapdict(mapdict, script=False): def _format_elemcreate(etype, script=False, *args, **kw): """Formats args and kw according to the given element factory etype.""" - spec = None + specs = () opts = () - if etype in ("image", "vsapi"): - if etype == "image": # define an element based on an image - # first arg should be the default image name - iname = args[0] - # next args, if any, are statespec/value pairs which is almost - # a mapdict, but we just need the value - imagespec = _join(_mapdict_values(args[1:])) - spec = "%s %s" % (iname, imagespec) - + if etype == "image": # define an element based on an image + # first arg should be the default image name + iname = args[0] + # next args, if any, are statespec/value pairs which is almost + # a mapdict, but we just need the value + imagespec = (iname, *_mapdict_values(args[1:])) + if script: + specs = (imagespec,) else: - # define an element whose visual appearance is drawn using the - # Microsoft Visual Styles API which is responsible for the - # themed styles on Windows XP and Vista. - # Availability: Tk 8.6, Windows XP and Vista. - class_name, part_id = args[:2] - statemap = _join(_mapdict_values(args[2:])) - spec = "%s %s %s" % (class_name, part_id, statemap) + specs = (_join(imagespec),) + opts = _format_optdict(kw, script) + if etype == "vsapi": + # define an element whose visual appearance is drawn using the + # Microsoft Visual Styles API which is responsible for the + # themed styles on Windows XP and Vista. + # Availability: Tk 8.6, Windows XP and Vista. + if len(args) < 3: + class_name, part_id = args + statemap = (((), 1),) + else: + class_name, part_id, statemap = args + specs = (class_name, part_id, tuple(_mapdict_values(statemap))) opts = _format_optdict(kw, script) elif etype == "from": # clone an element # it expects a themename and optionally an element to clone from, # otherwise it will clone {} (empty element) - spec = args[0] # theme name + specs = (args[0],) # theme name if len(args) > 1: # elementfrom specified opts = (_format_optvalue(args[1], script),) if script: - spec = '{%s}' % spec + specs = _join(specs) opts = ' '.join(opts) + return specs, opts + else: + return *specs, opts - return spec, opts def _format_layoutlist(layout, indent=0, indent_size=2): """Formats a layout list so we can pass the result to ttk::style @@ -214,10 +221,10 @@ def _script_from_settings(settings): elemargs = eopts[1:argc] elemkw = eopts[argc] if argc < len(eopts) and eopts[argc] else {} - spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw) + specs, eopts = _format_elemcreate(etype, True, *elemargs, **elemkw) script.append("ttk::style element create %s %s %s %s" % ( - name, etype, spec, opts)) + name, etype, specs, eopts)) return '\n'.join(script) @@ -434,9 +441,9 @@ def layout(self, style, layoutspec=None): def element_create(self, elementname, etype, *args, **kw): """Create a new element in the current theme of given etype.""" - spec, opts = _format_elemcreate(etype, False, *args, **kw) + *specs, opts = _format_elemcreate(etype, False, *args, **kw) self.tk.call(self._name, "element", "create", elementname, etype, - spec, *opts) + *specs, *opts) def element_names(self): 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/trace.py b/Lib/trace.py index fb9a423ea09fce..7cb6f897634b14 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -202,7 +202,8 @@ def update(self, other): for key in other_callers: callers[key] = 1 - def write_results(self, show_missing=True, summary=False, coverdir=None): + def write_results(self, show_missing=True, summary=False, coverdir=None, *, + ignore_missing_files=False): """ Write the coverage results. @@ -211,6 +212,9 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): :param coverdir: If None, the results of each module are placed in its directory, otherwise it is included in the directory specified. + :param ignore_missing_files: If True, counts for files that no longer + exist are silently ignored. Otherwise, a missing file + will raise a FileNotFoundError. """ if self.calledfuncs: print() @@ -253,6 +257,9 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): if filename.endswith(".pyc"): filename = filename[:-1] + if ignore_missing_files and not os.path.isfile(filename): + continue + if coverdir is None: dir = os.path.dirname(os.path.abspath(filename)) modulename = _modname(filename) @@ -278,7 +285,6 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): percent = int(100 * n_hits / n_lines) sums[modulename] = n_lines, percent, modulename, filename - if summary and sums: print("lines cov% module (path)") for m in sorted(sums): diff --git a/Lib/traceback.py b/Lib/traceback.py index 67941ff45988c2..1cf008c7e9da97 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1,10 +1,13 @@ """Extract, format and print information about Python stack traces.""" +import os +import io import collections.abc import itertools import linecache import sys import textwrap +import warnings from contextlib import suppress __all__ = ['extract_stack', 'extract_tb', 'format_exception', @@ -18,6 +21,8 @@ # Formatting and printing lists of traceback lines. # +_COLORIZE = True + def print_list(extracted_list, file=None): """Print the list of tuples as returned by extract_tb() or extract_stack() as a formatted stack trace to the given file.""" @@ -109,7 +114,7 @@ def _parse_value_tb(exc, value, tb): def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ - file=None, chain=True): + file=None, chain=True, **kwargs): """Print exception up to 'limit' stack trace entries from 'tb' to 'file'. This differs from print_tb() in the following ways: (1) if @@ -120,9 +125,44 @@ def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ occurred with a caret on the next line indicating the approximate position of the error. """ + colorize = kwargs.get("colorize", False) value, tb = _parse_value_tb(exc, value, tb) te = TracebackException(type(value), value, tb, limit=limit, compact=True) - te.print(file=file, chain=chain) + te.print(file=file, chain=chain, colorize=colorize) + + +BUILTIN_EXCEPTION_LIMIT = object() + +def _can_colorize(): + if sys.platform == "win32": + try: + import nt + if not nt._supports_virtual_terminal(): + return False + except (ImportError, AttributeError): + return False + + if os.environ.get("PYTHON_COLORS") == "0": + return False + if os.environ.get("PYTHON_COLORS") == "1": + return True + if "NO_COLOR" in os.environ: + return False + if not _COLORIZE: + return False + if "FORCE_COLOR" in os.environ: + return True + if os.environ.get("TERM") == "dumb": + return False + try: + return os.isatty(sys.stderr.fileno()) + except io.UnsupportedOperation: + return sys.stderr.isatty() + +def _print_exception_bltin(exc, /): + file = sys.stderr if sys.stderr is not None else sys.__stderr__ + colorize = _can_colorize() + return print_exception(exc, limit=BUILTIN_EXCEPTION_LIMIT, file=file, colorize=colorize) def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ @@ -140,34 +180,42 @@ def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \ return list(te.format(chain=chain)) -def format_exception_only(exc, /, value=_sentinel): +def format_exception_only(exc, /, value=_sentinel, *, show_group=False): """Format the exception part of a traceback. The return value is a list of strings, each ending in a newline. - Normally, the list contains a single string; however, for - 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 always the last - string in the list. + 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 ``__notes__``. + 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. """ if value is _sentinel: value = exc te = TracebackException(type(value), value, None, compact=True) - return list(te.format_exception_only()) + return list(te.format_exception_only(show_group=show_group)) # -- not official API but folk probably use these two functions. -def _format_final_exc_line(etype, value): +def _format_final_exc_line(etype, value, *, insert_final_newline=True, colorize=False): valuestr = _safe_string(value, 'exception') - if value is None or not valuestr: - line = "%s\n" % etype + end_char = "\n" if insert_final_newline else "" + if colorize: + if value is None or not valuestr: + line = f"{_ANSIColors.BOLD_MAGENTA}{etype}{_ANSIColors.RESET}{end_char}" + else: + line = f"{_ANSIColors.BOLD_MAGENTA}{etype}{_ANSIColors.RESET}: {_ANSIColors.MAGENTA}{valuestr}{_ANSIColors.RESET}{end_char}" else: - line = "%s: %s\n" % (etype, valuestr) + if value is None or not valuestr: + line = f"{etype}{end_char}" + else: + line = f"{etype}: {valuestr}{end_char}" return line def _safe_string(value, what, func=str): @@ -263,7 +311,7 @@ class FrameSummary: """ __slots__ = ('filename', 'lineno', 'end_lineno', 'colno', 'end_colno', - 'name', '_line', 'locals') + 'name', '_lines', '_lines_dedented', 'locals') def __init__(self, filename, lineno, name, *, lookup_line=True, locals=None, line=None, @@ -279,15 +327,16 @@ def __init__(self, filename, lineno, name, *, lookup_line=True, """ self.filename = filename self.lineno = lineno + self.end_lineno = lineno if end_lineno is None else end_lineno + self.colno = colno + self.end_colno = end_colno self.name = name - self._line = line + self._lines = line + self._lines_dedented = None if lookup_line: self.line self.locals = {k: _safe_string(v, 'local', func=repr) for k, v in locals.items()} if locals else None - self.end_lineno = end_lineno - self.colno = colno - self.end_colno = end_colno def __eq__(self, other): if isinstance(other, FrameSummary): @@ -312,19 +361,39 @@ def __repr__(self): def __len__(self): return 4 + def _set_lines(self): + if ( + self._lines is None + and self.lineno is not None + and self.end_lineno is not None + ): + lines = [] + for lineno in range(self.lineno, self.end_lineno + 1): + # treat errors (empty string) and empty lines (newline) as the same + lines.append(linecache.getline(self.filename, lineno).rstrip()) + self._lines = "\n".join(lines) + "\n" + @property - def _original_line(self): + def _original_lines(self): # Returns the line as-is from the source, without modifying whitespace. - self.line - return self._line + self._set_lines() + return self._lines + + @property + def _dedented_lines(self): + # Returns _original_lines, but dedented + self._set_lines() + if self._lines_dedented is None and self._lines is not None: + self._lines_dedented = textwrap.dedent(self._lines) + return self._lines_dedented @property def line(self): - if self._line is None: - if self.lineno is None: - return None - self._line = linecache.getline(self.filename, self.lineno) - return self._line.strip() + self._set_lines() + if self._lines is None: + return None + # return only the first line, stripped + return self._lines.partition("\n")[0].strip() def walk_stack(f): @@ -374,6 +443,14 @@ def _get_code_position(code, instruction_index): _RECURSIVE_CUTOFF = 3 # Also hardcoded in traceback.c. +class _ANSIColors: + RED = '\x1b[31m' + BOLD_RED = '\x1b[1;31m' + MAGENTA = '\x1b[35m' + BOLD_MAGENTA = '\x1b[1;35m' + GREY = '\x1b[90m' + RESET = '\x1b[0m' + class StackSummary(list): """A list of FrameSummary objects, representing a stack of frames.""" @@ -406,12 +483,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 +503,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 +515,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: @@ -460,62 +541,193 @@ def from_list(klass, a_list): result.append(FrameSummary(filename, lineno, name, line=line)) return result - def format_frame_summary(self, frame_summary): + def format_frame_summary(self, frame_summary, **kwargs): """Format the lines for a single FrameSummary. Returns a string representing one frame involved in the stack. This gets called for every frame to be printed in the stack summary. """ + colorize = kwargs.get("colorize", False) row = [] - 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)) - - orig_line_len = len(frame_summary._original_line) - frame_line_len = len(frame_summary.line.lstrip()) - stripped_characters = orig_line_len - frame_line_len + filename = frame_summary.filename + if frame_summary.filename.startswith("-"): + filename = "" + if colorize: + row.append(' File {}"{}"{}, line {}{}{}, in {}{}{}\n'.format( + _ANSIColors.MAGENTA, + filename, + _ANSIColors.RESET, + _ANSIColors.MAGENTA, + frame_summary.lineno, + _ANSIColors.RESET, + _ANSIColors.MAGENTA, + frame_summary.name, + _ANSIColors.RESET, + ) + ) + else: + row.append(' File "{}", line {}, in {}\n'.format( + filename, frame_summary.lineno, frame_summary.name)) + if frame_summary._dedented_lines and frame_summary._dedented_lines.strip(): if ( - frame_summary.colno is not None - and frame_summary.end_colno is not None + frame_summary.colno is None or + frame_summary.end_colno is None ): - start_offset = _byte_offset_to_character_offset( - frame_summary._original_line, frame_summary.colno) + 1 - end_offset = _byte_offset_to_character_offset( - frame_summary._original_line, frame_summary.end_colno) + 1 - + # only output first line if column information is missing + row.append(textwrap.indent(frame_summary.line, ' ') + "\n") + else: + # get first and last line + all_lines_original = frame_summary._original_lines.splitlines() + first_line = all_lines_original[0] + # assume all_lines_original has enough lines (since we constructed it) + last_line = all_lines_original[frame_summary.end_lineno - frame_summary.lineno] + + # character index of the start/end of the instruction + start_offset = _byte_offset_to_character_offset(first_line, frame_summary.colno) + end_offset = _byte_offset_to_character_offset(last_line, frame_summary.end_colno) + + all_lines = frame_summary._dedented_lines.splitlines()[ + :frame_summary.end_lineno - frame_summary.lineno + 1 + ] + + # adjust start/end offset based on dedent + dedent_characters = len(first_line) - len(all_lines[0]) + start_offset = max(0, start_offset - dedent_characters) + end_offset = max(0, end_offset - dedent_characters) + + # When showing this on a terminal, some of the non-ASCII characters + # might be rendered as double-width characters, so we need to take + # that into account when calculating the length of the line. + dp_start_offset = _display_width(all_lines[0], offset=start_offset) + dp_end_offset = _display_width(all_lines[-1], offset=end_offset) + + # get exact code segment corresponding to the instruction + segment = "\n".join(all_lines) + segment = segment[start_offset:len(segment) - (len(all_lines[-1]) - end_offset)] + + # attempt to parse for anchors anchors = None - if frame_summary.lineno == frame_summary.end_lineno: - with suppress(Exception): - anchors = _extract_caret_anchors_from_line_segment( - frame_summary._original_line[start_offset - 1:end_offset - 1] - ) - else: - end_offset = stripped_characters + len(stripped_line) - - # show indicators if primary char doesn't span the frame line - if end_offset - start_offset < len(stripped_line) or ( - anchors and anchors.right_start_offset - anchors.left_end_offset > 0): - row.append(' ') - row.append(' ' * (start_offset - stripped_characters)) - - if anchors: - row.append(anchors.primary_char * (anchors.left_end_offset)) - row.append(anchors.secondary_char * (anchors.right_start_offset - anchors.left_end_offset)) - row.append(anchors.primary_char * (end_offset - start_offset - anchors.right_start_offset)) - else: - row.append('^' * (end_offset - start_offset)) + with suppress(Exception): + anchors = _extract_caret_anchors_from_line_segment(segment) + + # only use carets if there are anchors or the carets do not span all lines + show_carets = False + if anchors or all_lines[0][:start_offset].lstrip() or all_lines[-1][end_offset:].rstrip(): + show_carets = True + + result = [] + + # only display first line, last line, and lines around anchor start/end + significant_lines = {0, len(all_lines) - 1} + + anchors_left_end_offset = 0 + anchors_right_start_offset = 0 + primary_char = "^" + secondary_char = "^" + if anchors: + anchors_left_end_offset = anchors.left_end_offset + anchors_right_start_offset = anchors.right_start_offset + # computed anchor positions do not take start_offset into account, + # so account for it here + if anchors.left_end_lineno == 0: + anchors_left_end_offset += start_offset + if anchors.right_start_lineno == 0: + anchors_right_start_offset += start_offset + + # account for display width + anchors_left_end_offset = _display_width( + all_lines[anchors.left_end_lineno], offset=anchors_left_end_offset + ) + anchors_right_start_offset = _display_width( + all_lines[anchors.right_start_lineno], offset=anchors_right_start_offset + ) - row.append('\n') + primary_char = anchors.primary_char + secondary_char = anchors.secondary_char + significant_lines.update( + range(anchors.left_end_lineno - 1, anchors.left_end_lineno + 2) + ) + significant_lines.update( + range(anchors.right_start_lineno - 1, anchors.right_start_lineno + 2) + ) + # remove bad line numbers + significant_lines.discard(-1) + significant_lines.discard(len(all_lines)) + + def output_line(lineno): + """output all_lines[lineno] along with carets""" + result.append(all_lines[lineno] + "\n") + if not show_carets: + return + num_spaces = len(all_lines[lineno]) - len(all_lines[lineno].lstrip()) + carets = [] + num_carets = dp_end_offset if lineno == len(all_lines) - 1 else _display_width(all_lines[lineno]) + # compute caret character for each position + for col in range(num_carets): + if col < num_spaces or (lineno == 0 and col < dp_start_offset): + # before first non-ws char of the line, or before start of instruction + carets.append(' ') + elif anchors and ( + lineno > anchors.left_end_lineno or + (lineno == anchors.left_end_lineno and col >= anchors_left_end_offset) + ) and ( + lineno < anchors.right_start_lineno or + (lineno == anchors.right_start_lineno and col < anchors_right_start_offset) + ): + # within anchors + carets.append(secondary_char) + else: + carets.append(primary_char) + if colorize: + # Replace the previous line with a red version of it only in the parts covered + # by the carets. + line = result[-1] + colorized_line_parts = [] + colorized_carets_parts = [] + + for color, group in itertools.groupby(itertools.zip_longest(line, carets, fillvalue=""), key=lambda x: x[1]): + caret_group = list(group) + if color == "^": + colorized_line_parts.append(_ANSIColors.BOLD_RED + "".join(char for char, _ in caret_group) + _ANSIColors.RESET) + colorized_carets_parts.append(_ANSIColors.BOLD_RED + "".join(caret for _, caret in caret_group) + _ANSIColors.RESET) + elif color == "~": + colorized_line_parts.append(_ANSIColors.RED + "".join(char for char, _ in caret_group) + _ANSIColors.RESET) + colorized_carets_parts.append(_ANSIColors.RED + "".join(caret for _, caret in caret_group) + _ANSIColors.RESET) + else: + colorized_line_parts.append("".join(char for char, _ in caret_group)) + colorized_carets_parts.append("".join(caret for _, caret in caret_group)) + + colorized_line = "".join(colorized_line_parts) + colorized_carets = "".join(colorized_carets_parts) + result[-1] = colorized_line + result.append(colorized_carets + "\n") + else: + result.append("".join(carets) + "\n") + + # display significant lines + sig_lines_list = sorted(significant_lines) + for i, lineno in enumerate(sig_lines_list): + if i: + linediff = lineno - sig_lines_list[i - 1] + if linediff == 2: + # 1 line in between - just output it + output_line(lineno - 1) + elif linediff > 2: + # > 1 line in between - abbreviate + result.append(f"...<{linediff - 1} lines>...\n") + output_line(lineno) + + row.append( + textwrap.indent(textwrap.dedent("".join(result)), ' ', lambda line: True) + ) if frame_summary.locals: for name, value in sorted(frame_summary.locals.items()): row.append(' {name} = {value}\n'.format(name=name, value=value)) return ''.join(row) - def format(self): + def format(self, **kwargs): """Format the stack ready for printing. Returns a list of strings ready for printing. Each string in the @@ -527,13 +739,14 @@ def format(self): repetitions are shown, followed by a summary line stating the exact number of further repetitions. """ + colorize = kwargs.get("colorize", False) result = [] last_file = None last_line = None last_name = None count = 0 for frame_summary in self: - formatted_frame = self.format_frame_summary(frame_summary) + formatted_frame = self.format_frame_summary(frame_summary, colorize=colorize) if formatted_frame is None: continue if (last_file is None or last_file != frame_summary.filename or @@ -571,7 +784,9 @@ def _byte_offset_to_character_offset(str, offset): _Anchors = collections.namedtuple( "_Anchors", [ + "left_end_lineno", "left_end_offset", + "right_start_lineno", "right_start_offset", "primary_char", "secondary_char", @@ -580,52 +795,173 @@ def _byte_offset_to_character_offset(str, offset): ) def _extract_caret_anchors_from_line_segment(segment): + """ + Given source code `segment` corresponding to a FrameSummary, determine: + - for binary ops, the location of the binary op + - for indexing and function calls, the location of the brackets. + `segment` is expected to be a valid Python expression. + """ import ast try: - tree = ast.parse(segment) + # Without parentheses, `segment` is parsed as a statement. + # Binary ops, subscripts, and calls are expressions, so + # we can wrap them with parentheses to parse them as + # (possibly multi-line) expressions. + # e.g. if we try to highlight the addition in + # x = ( + # a + + # b + # ) + # then we would ast.parse + # a + + # b + # which is not a valid statement because of the newline. + # Adding brackets makes it a valid expression. + # ( + # a + + # b + # ) + # Line locations will be different than the original, + # which is taken into account later on. + tree = ast.parse(f"(\n{segment}\n)") except SyntaxError: return None if len(tree.body) != 1: return None - normalize = lambda offset: _byte_offset_to_character_offset(segment, offset) + lines = segment.splitlines() + + def normalize(lineno, offset): + """Get character index given byte offset""" + return _byte_offset_to_character_offset(lines[lineno], offset) + + def next_valid_char(lineno, col): + """Gets the next valid character index in `lines`, if + the current location is not valid. Handles empty lines. + """ + while lineno < len(lines) and col >= len(lines[lineno]): + col = 0 + lineno += 1 + assert lineno < len(lines) and col < len(lines[lineno]) + return lineno, col + + def increment(lineno, col): + """Get the next valid character index in `lines`.""" + col += 1 + lineno, col = next_valid_char(lineno, col) + return lineno, col + + def nextline(lineno, col): + """Get the next valid character at least on the next line""" + col = 0 + lineno += 1 + lineno, col = next_valid_char(lineno, col) + return lineno, col + + def increment_until(lineno, col, stop): + """Get the next valid non-"\\#" character that satisfies the `stop` predicate""" + while True: + ch = lines[lineno][col] + if ch in "\\#": + lineno, col = nextline(lineno, col) + elif not stop(ch): + lineno, col = increment(lineno, col) + else: + break + return lineno, col + + def setup_positions(expr, force_valid=True): + """Get the lineno/col position of the end of `expr`. If `force_valid` is True, + forces the position to be a valid character (e.g. if the position is beyond the + end of the line, move to the next line) + """ + # -2 since end_lineno is 1-indexed and because we added an extra + # bracket + newline to `segment` when calling ast.parse + lineno = expr.end_lineno - 2 + col = normalize(lineno, expr.end_col_offset) + return next_valid_char(lineno, col) if force_valid else (lineno, col) + statement = tree.body[0] match statement: case ast.Expr(expr): match expr: case ast.BinOp(): - operator_start = normalize(expr.left.end_col_offset) - operator_end = normalize(expr.right.col_offset) - operator_str = segment[operator_start:operator_end] - operator_offset = len(operator_str) - len(operator_str.lstrip()) + # ast gives these locations for BinOp subexpressions + # ( left_expr ) + ( right_expr ) + # left^^^^^ right^^^^^ + lineno, col = setup_positions(expr.left) + + # First operator character is the first non-space/')' character + lineno, col = increment_until(lineno, col, lambda x: not x.isspace() and x != ')') - left_anchor = expr.left.end_col_offset + operator_offset - right_anchor = left_anchor + 1 + # binary op is 1 or 2 characters long, on the same line, + # before the right subexpression + right_col = col + 1 if ( - operator_offset + 1 < len(operator_str) - and not operator_str[operator_offset + 1].isspace() + right_col < len(lines[lineno]) + and ( + # operator char should not be in the right subexpression + expr.right.lineno - 2 > lineno or + right_col < normalize(expr.right.lineno - 2, expr.right.col_offset) + ) + and not (ch := lines[lineno][right_col]).isspace() + and ch not in "\\#" ): - right_anchor += 1 + right_col += 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)) + # right_col can be invalid since it is exclusive + return _Anchors(lineno, col, lineno, right_col) case ast.Subscript(): - 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) + # ast gives these locations for value and slice subexpressions + # ( value_expr ) [ slice_expr ] + # value^^^^^ slice^^^^^ + # subscript^^^^^^^^^^^^^^^^^^^^ + + # find left bracket + left_lineno, left_col = setup_positions(expr.value) + left_lineno, left_col = increment_until(left_lineno, left_col, lambda x: x == '[') + # find right bracket (final character of expression) + right_lineno, right_col = setup_positions(expr, force_valid=False) + return _Anchors(left_lineno, left_col, right_lineno, right_col) + case ast.Call(): + # ast gives these locations for function call expressions + # ( func_expr ) (args, kwargs) + # func^^^^^ + # call^^^^^^^^^^^^^^^^^^^^^^^^ + + # find left bracket + left_lineno, left_col = setup_positions(expr.func) + left_lineno, left_col = increment_until(left_lineno, left_col, lambda x: x == '(') + # find right bracket (final character of expression) + right_lineno, right_col = setup_positions(expr, force_valid=False) + return _Anchors(left_lineno, left_col, right_lineno, right_col) return None +_WIDE_CHAR_SPECIFIERS = "WF" + +def _display_width(line, offset=None): + """Calculate the extra amount of width space the given source + code segment might take if it were to be displayed on a fixed + width output device. Supports wide unicode characters and emojis.""" + + if offset is None: + offset = len(line) + + # Fast track for ASCII-only strings + if line.isascii(): + return offset + + import unicodedata + + return sum( + 2 if unicodedata.east_asian_width(char) in _WIDE_CHAR_SPECIFIERS else 1 + for char in line[:offset] + ) + + class _ExceptionPrintContext: def __init__(self): @@ -673,7 +1009,8 @@ class TracebackException: - :attr:`__suppress_context__` The *__suppress_context__* value from the original exception. - :attr:`stack` A `StackSummary` representing the traceback. - - :attr:`exc_type` The class of the original traceback. + - :attr:`exc_type` (deprecated) The class of the original traceback. + - :attr:`exc_type_str` String display of exc_type - :attr:`filename` For syntax errors - the filename where the error occurred. - :attr:`lineno` For syntax errors - the linenumber where the error @@ -691,7 +1028,7 @@ class TracebackException: def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, - max_group_width=15, max_group_depth=10, _seen=None): + max_group_width=15, max_group_depth=10, save_exc_type=True, _seen=None): # NB: we need to accept exc_traceback, exc_value, exc_traceback to # permit backwards compat with the existing API, otherwise we # need stub thunk objects just to glue it together. @@ -708,12 +1045,23 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, _walk_tb_with_full_positions(exc_traceback), limit=limit, lookup_lines=lookup_lines, capture_locals=capture_locals) - self.exc_type = exc_type + + self._exc_type = exc_type if save_exc_type else None + # Capture now to permit freeing resources: only complication is in the # unofficial API _format_final_exc_line self._str = _safe_string(exc_value, 'exception') self.__notes__ = getattr(exc_value, '__notes__', None) + self._is_syntax_error = False + self._have_exc_type = exc_type is not None + if exc_type is not None: + self.exc_type_qualname = exc_type.__qualname__ + self.exc_type_module = exc_type.__module__ + else: + self.exc_type_qualname = None + self.exc_type_module = None + if exc_type and issubclass(exc_type, SyntaxError): # Handle SyntaxError's specially self.filename = exc_value.filename @@ -725,6 +1073,7 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, self.offset = exc_value.offset self.end_offset = exc_value.end_offset self.msg = exc_value.msg + self._is_syntax_error = True elif exc_type and issubclass(exc_type, ImportError) and \ getattr(exc_value, "name_from", None) is not None: wrong_name = getattr(exc_value, "name_from", None) @@ -741,9 +1090,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__ = \ @@ -823,6 +1172,24 @@ def from_exception(cls, exc, *args, **kwargs): """Create a TracebackException from an exception.""" return cls(type(exc), exc, exc.__traceback__, *args, **kwargs) + @property + def exc_type(self): + warnings.warn('Deprecated in 3.13. Use exc_type_str instead.', + DeprecationWarning, stacklevel=2) + return self._exc_type + + @property + def exc_type_str(self): + if not self._have_exc_type: + return None + stype = self.exc_type_qualname + smod = self.exc_type_module + if smod not in ("__main__", "builtins"): + if not isinstance(smod, str): + smod = "" + stype = smod + '.' + stype + return stype + def _load_lines(self): """Private API. force all lines in the stack to be loaded.""" for frame in self.stack: @@ -836,36 +1203,45 @@ def __eq__(self, other): def __str__(self): return self._str - def format_exception_only(self, *, show_group=False, _depth=0): + def format_exception_only(self, *, show_group=False, _depth=0, **kwargs): """Format the exception part of the traceback. The return value is a generator of strings, each ending in a newline. - Normally, the generator emits a single string; however, for - 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. + Generator yields the exception message. + For :exc:`SyntaxError` exceptions, it + also yields (before the exception message) + several lines that (when printed) + display detailed information about where the syntax error occurred. + Following the message, generator also yields + all the exception's ``__notes__``. + + 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. """ + colorize = kwargs.get("colorize", False) indent = 3 * _depth * ' ' - if self.exc_type is None: - yield indent + _format_final_exc_line(None, self._str) + if not self._have_exc_type: + yield indent + _format_final_exc_line(None, self._str, colorize=colorize) return - stype = self.exc_type.__qualname__ - smod = self.exc_type.__module__ - if smod not in ("__main__", "builtins"): - if not isinstance(smod, str): - smod = "" - stype = smod + '.' + stype - - if not issubclass(self.exc_type, SyntaxError): - yield indent + _format_final_exc_line(stype, self._str) + stype = self.exc_type_str + if not self._is_syntax_error: + if _depth > 0: + # Nested exceptions needs correct handling of multiline messages. + formatted = _format_final_exc_line( + stype, self._str, insert_final_newline=False, colorize=colorize + ).split('\n') + yield from [ + indent + l + '\n' + for l in formatted + ] + else: + yield _format_final_exc_line(stype, self._str, colorize=colorize) else: - yield from [indent + l for l in self._format_syntax_error(stype)] + yield from [indent + l for l in self._format_syntax_error(stype, colorize=colorize)] if ( isinstance(self.__notes__, collections.abc.Sequence) @@ -879,15 +1255,26 @@ def format_exception_only(self, *, show_group=False, _depth=0): if self.exceptions and show_group: for ex in self.exceptions: - yield from ex.format_exception_only(show_group=show_group, _depth=_depth+1) + yield from ex.format_exception_only(show_group=show_group, _depth=_depth+1, colorize=colorize) - def _format_syntax_error(self, stype): + def _format_syntax_error(self, stype, **kwargs): """Format SyntaxError exceptions (internal helper).""" # Show exactly where the problem was found. + colorize = kwargs.get("colorize", False) filename_suffix = '' if self.lineno is not None: - yield ' File "{}", line {}\n'.format( - self.filename or "", self.lineno) + if colorize: + yield ' File {}"{}"{}, line {}{}{}\n'.format( + _ANSIColors.MAGENTA, + self.filename or "", + _ANSIColors.RESET, + _ANSIColors.MAGENTA, + self.lineno, + _ANSIColors.RESET, + ) + else: + yield ' File "{}", line {}\n'.format( + self.filename or "", self.lineno) elif self.filename is not None: filename_suffix = ' ({})'.format(self.filename) @@ -899,25 +1286,58 @@ def _format_syntax_error(self, stype): rtext = text.rstrip('\n') ltext = rtext.lstrip(' \n\f') spaces = len(rtext) - len(ltext) - yield ' {}\n'.format(ltext) - - if self.offset is not None: + if self.offset is None: + yield ' {}\n'.format(ltext) + else: 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 colno = offset - 1 - spaces end_colno = end_offset - 1 - spaces + caretspace = ' ' if colno >= 0: # non-space whitespace (likes tabs) must be kept for alignment caretspace = ((c if c.isspace() else ' ') for c in ltext[:colno]) - yield ' {}{}'.format("".join(caretspace), ('^' * (end_colno - colno) + "\n")) + start_color = end_color = "" + if colorize: + # colorize from colno to end_colno + ltext = ( + ltext[:colno] + + _ANSIColors.BOLD_RED + ltext[colno:end_colno] + _ANSIColors.RESET + + ltext[end_colno:] + ) + start_color = _ANSIColors.BOLD_RED + end_color = _ANSIColors.RESET + yield ' {}\n'.format(ltext) + yield ' {}{}{}{}\n'.format( + "".join(caretspace), + start_color, + ('^' * (end_colno - colno)), + end_color, + ) + else: + yield ' {}\n'.format(ltext) msg = self.msg or "" - yield "{}: {}{}\n".format(stype, msg, filename_suffix) + if colorize: + yield "{}{}{}: {}{}{}{}\n".format( + _ANSIColors.BOLD_MAGENTA, + stype, + _ANSIColors.RESET, + _ANSIColors.MAGENTA, + msg, + _ANSIColors.RESET, + filename_suffix) + else: + yield "{}: {}{}\n".format(stype, msg, filename_suffix) - def format(self, *, chain=True, _ctx=None): + def format(self, *, chain=True, _ctx=None, **kwargs): """Format the exception. If chain is not *True*, *__cause__* and *__context__* will not be formatted. @@ -929,7 +1349,7 @@ def format(self, *, chain=True, _ctx=None): The message indicating which exception occurred is always the last string in the output. """ - + colorize = kwargs.get("colorize", False) if _ctx is None: _ctx = _ExceptionPrintContext() @@ -959,8 +1379,8 @@ def format(self, *, chain=True, _ctx=None): if exc.exceptions is None: if exc.stack: yield from _ctx.emit('Traceback (most recent call last):\n') - yield from _ctx.emit(exc.stack.format()) - yield from _ctx.emit(exc.format_exception_only()) + yield from _ctx.emit(exc.stack.format(colorize=colorize)) + yield from _ctx.emit(exc.format_exception_only(colorize=colorize)) elif _ctx.exception_group_depth > self.max_group_depth: # exception group, but depth exceeds limit yield from _ctx.emit( @@ -975,9 +1395,9 @@ def format(self, *, chain=True, _ctx=None): yield from _ctx.emit( 'Exception Group Traceback (most recent call last):\n', margin_char = '+' if is_toplevel else None) - yield from _ctx.emit(exc.stack.format()) + yield from _ctx.emit(exc.stack.format(colorize=colorize)) - yield from _ctx.emit(exc.format_exception_only()) + yield from _ctx.emit(exc.format_exception_only(colorize=colorize)) num_excs = len(exc.exceptions) if num_excs <= self.max_group_width: n = num_excs @@ -1018,11 +1438,12 @@ def format(self, *, chain=True, _ctx=None): _ctx.exception_group_depth = 0 - def print(self, *, file=None, chain=True): + def print(self, *, file=None, chain=True, **kwargs): """Print the result of self.format(chain=chain) to 'file'.""" + colorize = kwargs.get("colorize", False) if file is None: file = sys.stderr - for line in self.format(chain=chain): + for line in self.format(chain=chain, colorize=colorize): print(line, file=file, end="") diff --git a/Lib/tty.py b/Lib/tty.py index 7d916029ff2ce9..283e5c334f5751 100644 --- a/Lib/tty.py +++ b/Lib/tty.py @@ -39,6 +39,7 @@ def cfmakeraw(mode): # Case B: MIN>0, TIME=0 # A pending read shall block until MIN (here 1) bytes are received, # or a signal is received. + mode[CC] = list(mode[CC]) mode[CC][VMIN] = 1 mode[CC][VTIME] = 0 @@ -54,6 +55,7 @@ def cfmakecbreak(mode): # Case B: MIN>0, TIME=0 # A pending read shall block until MIN (here 1) bytes are received, # or a signal is received. + mode[CC] = list(mode[CC]) mode[CC][VMIN] = 1 mode[CC][VTIME] = 0 diff --git a/Lib/turtledemo/__main__.py b/Lib/turtledemo/__main__.py index f6c9d6aa6f9a32..2ab6c15e2c079e 100755 --- a/Lib/turtledemo/__main__.py +++ b/Lib/turtledemo/__main__.py @@ -161,7 +161,7 @@ def __init__(self, filename=None): label='Help', underline=0) root['menu'] = self.mBar - pane = PanedWindow(orient=HORIZONTAL, sashwidth=5, + pane = PanedWindow(root, orient=HORIZONTAL, sashwidth=5, sashrelief=SOLID, bg='#ddd') pane.add(self.makeTextFrame(pane)) pane.add(self.makeGraphFrame(pane)) diff --git a/Lib/typing.py b/Lib/typing.py index 639be75747dae0..61b88a560e9dc5 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -212,8 +212,12 @@ def _should_unflatten_callable_args(typ, args): For example:: - assert collections.abc.Callable[[int, int], str].__args__ == (int, int, str) - assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) + >>> import collections.abc + >>> P = ParamSpec('P') + >>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str) + True + >>> collections.abc.Callable[P, str].__args__ == (P, str) + True As a result, if we need to reconstruct the Callable from its __args__, we need to unflatten it. @@ -255,7 +259,10 @@ def _collect_parameters(args): For example:: - assert _collect_parameters((T, Callable[P, T])) == (T, P) + >>> P = ParamSpec('P') + >>> T = TypeVar('T') + >>> _collect_parameters((T, Callable[P, T])) + (~T, ~P) """ parameters = [] for t in args: @@ -483,7 +490,7 @@ def __getitem__(self, parameters): return self._getitem(self, parameters) -class _LiteralSpecialForm(_SpecialForm, _root=True): +class _TypedCacheSpecialForm(_SpecialForm, _root=True): def __getitem__(self, parameters): if not isinstance(parameters, tuple): parameters = (parameters,) @@ -716,7 +723,7 @@ def Optional(self, parameters): arg = _type_check(parameters, f"{self} requires a single type.") return Union[arg, type(None)] -@_LiteralSpecialForm +@_TypedCacheSpecialForm @_tp_cache(typed=True) def Literal(self, *parameters): """Special typing form to define literal types (a.k.a. value types). @@ -937,13 +944,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) @@ -1676,7 +1676,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. @@ -1781,6 +1782,31 @@ def _pickle_pskwargs(pskwargs): del _pickle_psargs, _pickle_pskwargs +# Preload these once, as globals, as a micro-optimisation. +# This makes a significant difference to the time it takes +# to do `isinstance()`/`issubclass()` checks +# against runtime-checkable protocols with only one callable member. +_abc_instancecheck = ABCMeta.__instancecheck__ +_abc_subclasscheck = ABCMeta.__subclasscheck__ + + +def _type_check_issubclass_arg_1(arg): + """Raise TypeError if `arg` is not an instance of `type` + in `issubclass(arg, )`. + + In most cases, this is verified by type.__subclasscheck__. + Checking it again unnecessarily would slow down issubclass() checks, + so, we don't perform this check unless we absolutely have to. + + For various error paths, however, + we want to ensure that *this* error message is shown to the user + where relevant, rather than a typing.py-specific error message. + """ + if not isinstance(arg, type): + # Same error message as for issubclass(1, int). + raise TypeError('issubclass() arg 1 must be a class') + + class _ProtocolMeta(ABCMeta): # This metaclass is somewhat unfortunate, # but is necessary for several reasons... @@ -1820,22 +1846,26 @@ def __subclasscheck__(cls, other): getattr(cls, '_is_protocol', False) and not _allow_reckless_class_checks() ): - if not isinstance(other, type): - # Same error message as for issubclass(1, int). - raise TypeError('issubclass() arg 1 must be a class') if ( not cls.__callable_proto_members_only__ and cls.__dict__.get("__subclasshook__") is _proto_hook ): + _type_check_issubclass_arg_1(other) + non_method_attrs = sorted( + attr for attr in cls.__protocol_attrs__ + if not callable(getattr(cls, attr, None)) + ) raise TypeError( - "Protocols with non-method members don't support issubclass()" + "Protocols with non-method members don't support issubclass()." + f" Non-method members: {str(non_method_attrs)[1:-1]}." ) if not getattr(cls, '_is_runtime_protocol', False): + _type_check_issubclass_arg_1(other) raise TypeError( "Instance and class checks can only be used with " "@runtime_checkable protocols" ) - return super().__subclasscheck__(other) + return _abc_subclasscheck(cls, other) def __instancecheck__(cls, instance): # We need this method for situations where attributes are @@ -1844,7 +1874,7 @@ def __instancecheck__(cls, instance): return type.__instancecheck__(cls, instance) if not getattr(cls, "_is_protocol", False): # i.e., it's a concrete subclass of a protocol - return super().__instancecheck__(instance) + return _abc_instancecheck(cls, instance) if ( not getattr(cls, '_is_runtime_protocol', False) and @@ -1853,7 +1883,7 @@ def __instancecheck__(cls, instance): raise TypeError("Instance and class checks can only be used with" " @runtime_checkable protocols") - if super().__instancecheck__(instance): + if _abc_instancecheck(cls, instance): return True getattr_static = _lazy_load_getattr_static() @@ -1999,8 +2029,9 @@ def __mro_entries__(self, bases): return (self.__origin__,) -@_SpecialForm -def Annotated(self, params): +@_TypedCacheSpecialForm +@_tp_cache(typed=True) +def Annotated(self, *params): """Add context-specific metadata to a type. Example: Annotated[int, runtime_check.Unsigned] indicates to the @@ -2047,7 +2078,7 @@ def Annotated(self, params): where T1, T2 etc. are TypeVars, which would be invalid, because only one type should be passed to Annotated. """ - if not isinstance(params, tuple) or len(params) < 2: + if len(params) < 2: raise TypeError("Annotated[...] should be used " "with at least two arguments (a type and an " "annotation).") @@ -2250,14 +2281,15 @@ def get_origin(tp): Examples:: - assert get_origin(Literal[42]) is Literal - assert get_origin(int) is None - assert get_origin(ClassVar[int]) is ClassVar - assert get_origin(Generic) is Generic - assert get_origin(Generic[T]) is Generic - assert get_origin(Union[T, int]) is Union - assert get_origin(List[Tuple[T, T]][int]) is list - assert get_origin(P.args) is P + >>> P = ParamSpec('P') + >>> assert get_origin(Literal[42]) is Literal + >>> assert get_origin(int) is None + >>> assert get_origin(ClassVar[int]) is ClassVar + >>> assert get_origin(Generic) is Generic + >>> assert get_origin(Generic[T]) is Generic + >>> assert get_origin(Union[T, int]) is Union + >>> assert get_origin(List[Tuple[T, T]][int]) is list + >>> assert get_origin(P.args) is P """ if isinstance(tp, _AnnotatedAlias): return Annotated @@ -2278,11 +2310,12 @@ def get_args(tp): Examples:: - assert get_args(Dict[str, int]) == (str, int) - assert get_args(int) == () - assert get_args(Union[int, Union[T, int], str][int]) == (int, str) - assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) - assert get_args(Callable[[], T][int]) == ([], int) + >>> T = TypeVar('T') + >>> assert get_args(Dict[str, int]) == (str, int) + >>> assert get_args(int) == () + >>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str) + >>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) + >>> assert get_args(Callable[[], T][int]) == ([], int) """ if isinstance(tp, _AnnotatedAlias): return (tp.__origin__,) + tp.__metadata__ @@ -2301,12 +2334,15 @@ def is_typeddict(tp): For example:: - class Film(TypedDict): - title: str - year: int - - is_typeddict(Film) # => True - is_typeddict(Union[list, str]) # => False + >>> from typing import TypedDict + >>> class Film(TypedDict): + ... title: str + ... year: int + ... + >>> is_typeddict(Film) + True + >>> is_typeddict(dict) + False """ return isinstance(tp, _TypedDictMeta) @@ -2732,11 +2768,26 @@ def __new__(cls, typename, bases, ns): class_getitem = _generic_class_getitem nm_tpl.__class_getitem__ = classmethod(class_getitem) # update from user namespace without overriding special namedtuple attributes - for key in ns: + for key, val in ns.items(): if key in _prohibited: raise AttributeError("Cannot overwrite NamedTuple attribute " + key) - elif key not in _special and key not in nm_tpl._fields: - setattr(nm_tpl, key, ns[key]) + elif key not in _special: + if key not in nm_tpl._fields: + setattr(nm_tpl, key, val) + try: + set_name = type(val).__set_name__ + except AttributeError: + pass + else: + try: + set_name(val, nm_tpl, key) + except BaseException as e: + e.add_note( + f"Error calling __set_name__ on {type(val).__name__!r} " + f"instance {key!r} in {typename!r}" + ) + raise + if Generic in bases: nm_tpl.__init_subclass__() return nm_tpl @@ -2858,8 +2909,14 @@ def __new__(cls, name, bases, ns, total=True): for base in bases: annotations.update(base.__dict__.get('__annotations__', {})) - required_keys.update(base.__dict__.get('__required_keys__', ())) - optional_keys.update(base.__dict__.get('__optional_keys__', ())) + + base_required = base.__dict__.get('__required_keys__', set()) + required_keys |= base_required + optional_keys -= base_required + + base_optional = base.__dict__.get('__optional_keys__', set()) + required_keys -= base_optional + optional_keys |= base_optional annotations.update(own_annotations) for annotation_key, annotation_type in own_annotations.items(): @@ -2871,14 +2928,23 @@ def __new__(cls, name, bases, ns, total=True): annotation_origin = get_origin(annotation_type) if annotation_origin is Required: - required_keys.add(annotation_key) + is_required = True elif annotation_origin is NotRequired: - optional_keys.add(annotation_key) - elif total: + is_required = False + else: + is_required = total + + if is_required: required_keys.add(annotation_key) + optional_keys.discard(annotation_key) else: optional_keys.add(annotation_key) + required_keys.discard(annotation_key) + assert required_keys.isdisjoint(optional_keys), ( + f"Required keys overlap with optional keys in {name}:" + f" {required_keys=}, {optional_keys=}" + ) tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) tp_dict.__optional_keys__ = frozenset(optional_keys) @@ -2904,15 +2970,15 @@ def TypedDict(typename, fields=_sentinel, /, *, total=True): Usage:: - class Point2D(TypedDict): - x: int - y: int - label: str - - a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK - b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check - - assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') + >>> class Point2D(TypedDict): + ... x: int + ... y: int + ... label: str + ... + >>> a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK + >>> b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check + >>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') + True The type info can be accessed via the Point2D.__annotations__ dict, and the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. @@ -3351,7 +3417,7 @@ def override[F: _Func](method: F, /) -> F: Usage:: class Base: - def method(self) -> None: ... + def method(self) -> None: pass class Child(Base): @@ -3410,8 +3476,8 @@ def get_protocol_members(tp: type, /) -> frozenset[str]: >>> class P(Protocol): ... def a(self) -> str: ... ... b: int - >>> get_protocol_members(P) - frozenset({'a', 'b'}) + >>> get_protocol_members(P) == frozenset({'a', 'b'}) + True Raise a TypeError for arguments that are not Protocols. """ diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index bd2a471156065b..63ff6a5d1f8b61 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -25,12 +25,15 @@ class IsolatedAsyncioTestCase(TestCase): # them inside the same task. # Note: the test case modifies event loop policy if the policy was not instantiated - # yet. + # yet, unless loop_factory=asyncio.EventLoop is set. # asyncio.get_event_loop_policy() creates a default policy on demand but never # returns None # I believe this is not an issue in user level tests but python itself for testing # should reset a policy in every test module # by calling asyncio.set_event_loop_policy(None) in tearDownModule() + # or set loop_factory=asyncio.EventLoop + + loop_factory = None def __init__(self, methodName='runTest'): super().__init__(methodName) @@ -118,7 +121,7 @@ def _callMaybeAsync(self, func, /, *args, **kwargs): def _setupAsyncioRunner(self): assert self._asyncioRunner is None, 'asyncio runner is already initialized' - runner = asyncio.Runner(debug=True) + runner = asyncio.Runner(debug=True, loop_factory=self.loop_factory) self._asyncioRunner = runner def _tearDownAsyncioRunner(self): diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index e8c8360e0ae13e..c6b46eea657a21 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -857,7 +857,7 @@ def _format_mock_call_signature(self, args, kwargs): def _format_mock_failure_message(self, args, kwargs, action='call'): - message = 'expected %s not found.\nExpected: %s\nActual: %s' + message = 'expected %s not found.\nExpected: %s\n Actual: %s' expected_string = self._format_mock_call_signature(args, kwargs) call_args = self.call_args actual_string = self._format_mock_call_signature(*call_args) @@ -960,7 +960,7 @@ def assert_called_with(self, /, *args, **kwargs): if self.call_args is None: expected = self._format_mock_call_signature(args, kwargs) actual = 'not called.' - error_message = ('expected call not found.\nExpected: %s\nActual: %s' + error_message = ('expected call not found.\nExpected: %s\n Actual: %s' % (expected, actual)) raise AssertionError(error_message) @@ -1011,7 +1011,7 @@ def assert_has_calls(self, calls, any_order=False): raise AssertionError( f'{problem}\n' f'Expected: {_CallList(calls)}' - f'{self._calls_repr(prefix="Actual").rstrip(".")}' + f'{self._calls_repr(prefix=" Actual").rstrip(".")}' ) from cause return diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate index 458740a35b0d20..a4e0609045a9d5 100644 --- a/Lib/venv/scripts/common/activate +++ b/Lib/venv/scripts/common/activate @@ -14,12 +14,9 @@ deactivate () { unset _OLD_VIRTUAL_PYTHONHOME fi - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting + # Call hash to forget past commands. Without forgetting # past commands the $PATH changes we made may not be respected - if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r 2> /dev/null - fi + hash -r 2> /dev/null if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then PS1="${_OLD_VIRTUAL_PS1:-}" @@ -39,14 +36,18 @@ deactivate () { deactivate nondestructive # on Windows, a path can contain colons and backslashes and has to be converted: -if [ "$OSTYPE" = "cygwin" ] || [ "$OSTYPE" = "msys" ] ; then - # transform D:\path\to\venv to /d/path/to/venv on MSYS - # and to /cygdrive/d/path/to/venv on Cygwin - export VIRTUAL_ENV=$(cygpath "__VENV_DIR__") -else - # use the path as-is - export VIRTUAL_ENV="__VENV_DIR__" -fi +case "$(uname)" in + CYGWIN*|MSYS*) + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + VIRTUAL_ENV=$(cygpath "__VENV_DIR__") + export VIRTUAL_ENV + ;; + *) + # use the path as-is + export VIRTUAL_ENV="__VENV_DIR__" + ;; +esac _OLD_VIRTUAL_PATH="$PATH" PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH" @@ -69,9 +70,6 @@ if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then export PS1 fi -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting +# Call hash to forget past commands. Without forgetting # past commands the $PATH changes we made may not be respected -if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then - hash -r 2> /dev/null -fi +hash -r 2> /dev/null diff --git a/Lib/warnings.py b/Lib/warnings.py index 32e58072b9cc33..b8ff078569d2ce 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -5,7 +5,7 @@ __all__ = ["warn", "warn_explicit", "showwarning", "formatwarning", "filterwarnings", "simplefilter", - "resetwarnings", "catch_warnings"] + "resetwarnings", "catch_warnings", "deprecated"] def showwarning(message, category, filename, lineno, file=None, line=None): """Hook to write a warning to a file; replace if you like.""" @@ -139,14 +139,18 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, 'lineno' -- an integer line number, 0 matches all warnings 'append' -- if true, append to the list of filters """ - assert action in ("error", "ignore", "always", "default", "module", - "once"), "invalid action: %r" % (action,) - assert isinstance(message, str), "message must be a string" - assert isinstance(category, type), "category must be a class" - assert issubclass(category, Warning), "category must be a Warning subclass" - assert isinstance(module, str), "module must be a string" - assert isinstance(lineno, int) and lineno >= 0, \ - "lineno must be an int >= 0" + if action not in {"error", "ignore", "always", "default", "module", "once"}: + raise ValueError(f"invalid action: {action!r}") + if not isinstance(message, str): + raise TypeError("message must be a string") + if not isinstance(category, type) or not issubclass(category, Warning): + raise TypeError("category must be a Warning subclass") + if not isinstance(module, str): + raise TypeError("module must be a string") + if not isinstance(lineno, int): + raise TypeError("lineno must be an int") + if lineno < 0: + raise ValueError("lineno must be an int >= 0") if message or module: import re @@ -172,10 +176,12 @@ def simplefilter(action, category=Warning, lineno=0, append=False): 'lineno' -- an integer line number, 0 matches all warnings 'append' -- if true, append to the list of filters """ - assert action in ("error", "ignore", "always", "default", "module", - "once"), "invalid action: %r" % (action,) - assert isinstance(lineno, int) and lineno >= 0, \ - "lineno must be an int >= 0" + if action not in {"error", "ignore", "always", "default", "module", "once"}: + raise ValueError(f"invalid action: {action!r}") + if not isinstance(lineno, int): + raise TypeError("lineno must be an int") + if lineno < 0: + raise ValueError("lineno must be an int >= 0") _add_filter(action, None, category, None, lineno, append=append) def _add_filter(*item, append): @@ -508,6 +514,135 @@ def __exit__(self, *exc_info): self._module._showwarnmsg_impl = self._showwarnmsg_impl +class deprecated: + """Indicate that a class, function or overload is deprecated. + + When this decorator is applied to an object, the type checker + will generate a diagnostic on usage of the deprecated object. + + Usage: + + @deprecated("Use B instead") + class A: + pass + + @deprecated("Use g instead") + def f(): + pass + + @overload + @deprecated("int support is deprecated") + def g(x: int) -> int: ... + @overload + def g(x: str) -> int: ... + + The warning specified by *category* will be emitted at runtime + on use of deprecated objects. For functions, that happens on calls; + for classes, on instantiation and on creation of subclasses. + If the *category* is ``None``, no warning is emitted at runtime. + The *stacklevel* determines where the + warning is emitted. If it is ``1`` (the default), the warning + is emitted at the direct caller of the deprecated object; if it + is higher, it is emitted further up the stack. + Static type checker behavior is not affected by the *category* + and *stacklevel* arguments. + + The deprecation message passed to the decorator is saved in the + ``__deprecated__`` attribute on the decorated object. + If applied to an overload, the decorator + must be after the ``@overload`` decorator for the attribute to + exist on the overload as returned by ``get_overloads()``. + + See PEP 702 for details. + + """ + def __init__( + self, + message: str, + /, + *, + category: type[Warning] | None = DeprecationWarning, + stacklevel: int = 1, + ) -> None: + if not isinstance(message, str): + raise TypeError( + f"Expected an object of type str for 'message', not {type(message).__name__!r}" + ) + self.message = message + self.category = category + self.stacklevel = stacklevel + + def __call__(self, arg, /): + # Make sure the inner functions created below don't + # retain a reference to self. + msg = self.message + category = self.category + stacklevel = self.stacklevel + if category is None: + arg.__deprecated__ = msg + return arg + elif isinstance(arg, type): + import functools + from types import MethodType + + original_new = arg.__new__ + + @functools.wraps(original_new) + def __new__(cls, *args, **kwargs): + if cls is arg: + warn(msg, category=category, stacklevel=stacklevel + 1) + if original_new is not object.__new__: + return original_new(cls, *args, **kwargs) + # Mirrors a similar check in object.__new__. + elif cls.__init__ is object.__init__ and (args or kwargs): + raise TypeError(f"{cls.__name__}() takes no arguments") + else: + return original_new(cls) + + arg.__new__ = staticmethod(__new__) + + original_init_subclass = arg.__init_subclass__ + # We need slightly different behavior if __init_subclass__ + # is a bound method (likely if it was implemented in Python) + if isinstance(original_init_subclass, MethodType): + original_init_subclass = original_init_subclass.__func__ + + @functools.wraps(original_init_subclass) + def __init_subclass__(*args, **kwargs): + warn(msg, category=category, stacklevel=stacklevel + 1) + return original_init_subclass(*args, **kwargs) + + arg.__init_subclass__ = classmethod(__init_subclass__) + # Or otherwise, which likely means it's a builtin such as + # object's implementation of __init_subclass__. + else: + @functools.wraps(original_init_subclass) + def __init_subclass__(*args, **kwargs): + warn(msg, category=category, stacklevel=stacklevel + 1) + return original_init_subclass(*args, **kwargs) + + arg.__init_subclass__ = __init_subclass__ + + arg.__deprecated__ = __new__.__deprecated__ = msg + __init_subclass__.__deprecated__ = msg + return arg + elif callable(arg): + import functools + + @functools.wraps(arg) + def wrapper(*args, **kwargs): + warn(msg, category=category, stacklevel=stacklevel + 1) + return arg(*args, **kwargs) + + arg.__deprecated__ = wrapper.__deprecated__ = msg + return wrapper + else: + raise TypeError( + "@deprecated decorator with non-None category must be applied to " + f"a class or callable, not {arg!r}" + ) + + _DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}" def _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info): diff --git a/Lib/wsgiref/simple_server.py b/Lib/wsgiref/simple_server.py index 93d01a863adf59..a0f2397fcf0006 100644 --- a/Lib/wsgiref/simple_server.py +++ b/Lib/wsgiref/simple_server.py @@ -84,10 +84,6 @@ def get_environ(self): env['PATH_INFO'] = urllib.parse.unquote(path, 'iso-8859-1') env['QUERY_STRING'] = query - - host = self.address_string() - if host != self.client_address[0]: - env['REMOTE_HOST'] = host env['REMOTE_ADDR'] = self.client_address[0] if self.headers.get('content-type') is None: diff --git a/Lib/wsgiref/util.py b/Lib/wsgiref/util.py index cbbe094cba1624..63b923317373f5 100644 --- a/Lib/wsgiref/util.py +++ b/Lib/wsgiref/util.py @@ -4,7 +4,7 @@ __all__ = [ 'FileWrapper', 'guess_scheme', 'application_uri', 'request_uri', - 'shift_path_info', 'setup_testing_defaults', + 'shift_path_info', 'setup_testing_defaults', 'is_hop_by_hop', ] diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index 2c963de18e4f95..fe629ed1cf2fc5 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -545,6 +545,7 @@ def _decodeExtra(self, filename_crc): if up_unicode_name: self.filename = _sanitize_filename(up_unicode_name) else: + import warnings warnings.warn("Empty unicode path extra field (0x7075)", stacklevel=2) except struct.error as e: raise BadZipFile("Corrupt unicode path extra field (0x7075)") from e @@ -1135,8 +1136,12 @@ def seek(self, offset, whence=os.SEEK_SET): read_offset = new_pos - curr_pos buff_offset = read_offset + self._offset + if buff_offset >= 0 and buff_offset < len(self._readbuffer): + # Just move the _offset index if the new position is in the _readbuffer + self._offset = buff_offset + read_offset = 0 # Fast seek uncompressed unencrypted file - if self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: + elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: # disable CRC checking after first seeking - it would be invalid self._expected_crc = None # seek actual file taking already buffered data into account @@ -1147,10 +1152,6 @@ def seek(self, offset, whence=os.SEEK_SET): # flush read buffer self._readbuffer = b'' self._offset = 0 - elif buff_offset >= 0 and buff_offset < len(self._readbuffer): - # Just move the _offset index if the new position is in the _readbuffer - self._offset = buff_offset - read_offset = 0 elif read_offset < 0: # Position is before the current position. Reset the ZipExtFile self._fileobj.seek(self._orig_compress_start) @@ -2226,12 +2227,79 @@ def _compile(file, optimize=-1): return (fname, archivename) +def main(args=None): + import argparse + + description = 'A simple command-line interface for zipfile module.' + parser = argparse.ArgumentParser(description=description) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-l', '--list', metavar='', + help='Show listing of a zipfile') + group.add_argument('-e', '--extract', nargs=2, + metavar=('', ''), + help='Extract zipfile into target dir') + group.add_argument('-c', '--create', nargs='+', + metavar=('', ''), + help='Create zipfile from sources') + group.add_argument('-t', '--test', metavar='', + help='Test if a zipfile is valid') + parser.add_argument('--metadata-encoding', metavar='', + help='Specify encoding of member names for -l, -e and -t') + args = parser.parse_args(args) + + encoding = args.metadata_encoding + + if args.test is not None: + src = args.test + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + badfile = zf.testzip() + if badfile: + print("The following enclosed file is corrupted: {!r}".format(badfile)) + print("Done testing") + + elif args.list is not None: + src = args.list + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + zf.printdir() + + elif args.extract is not None: + src, curdir = args.extract + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + zf.extractall(curdir) + + elif args.create is not None: + if encoding: + print("Non-conforming encodings not supported with -c.", + file=sys.stderr) + sys.exit(1) + + zip_name = args.create.pop(0) + files = args.create + + def addToZip(zf, path, zippath): + if os.path.isfile(path): + zf.write(path, zippath, ZIP_DEFLATED) + elif os.path.isdir(path): + if zippath: + zf.write(path, zippath) + for nm in sorted(os.listdir(path)): + addToZip(zf, + os.path.join(path, nm), os.path.join(zippath, nm)) + # else: ignore + + with ZipFile(zip_name, 'w') as zf: + for path in files: + zippath = os.path.basename(path) + if not zippath: + zippath = os.path.basename(os.path.dirname(path)) + if zippath in ('', os.curdir, os.pardir): + zippath = '' + addToZip(zf, path, zippath) + + from ._path import ( # noqa: E402 Path, # used privately for tests CompleteDirs, # noqa: F401 ) - -# used privately for tests -from .__main__ import main # noqa: F401, E402 diff --git a/Lib/zipfile/__main__.py b/Lib/zipfile/__main__.py index a9e5fb1b8d72c4..868d99efc3c4a3 100644 --- a/Lib/zipfile/__main__.py +++ b/Lib/zipfile/__main__.py @@ -1,77 +1,4 @@ -import sys -import os -from . import ZipFile, ZIP_DEFLATED - - -def main(args=None): - import argparse - - description = 'A simple command-line interface for zipfile module.' - parser = argparse.ArgumentParser(description=description) - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-l', '--list', metavar='', - help='Show listing of a zipfile') - group.add_argument('-e', '--extract', nargs=2, - metavar=('', ''), - help='Extract zipfile into target dir') - group.add_argument('-c', '--create', nargs='+', - metavar=('', ''), - help='Create zipfile from sources') - group.add_argument('-t', '--test', metavar='', - help='Test if a zipfile is valid') - parser.add_argument('--metadata-encoding', metavar='', - help='Specify encoding of member names for -l, -e and -t') - args = parser.parse_args(args) - - encoding = args.metadata_encoding - - if args.test is not None: - src = args.test - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - badfile = zf.testzip() - if badfile: - print("The following enclosed file is corrupted: {!r}".format(badfile)) - print("Done testing") - - elif args.list is not None: - src = args.list - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - zf.printdir() - - elif args.extract is not None: - src, curdir = args.extract - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - zf.extractall(curdir) - - elif args.create is not None: - if encoding: - print("Non-conforming encodings not supported with -c.", - file=sys.stderr) - sys.exit(1) - - zip_name = args.create.pop(0) - files = args.create - - def addToZip(zf, path, zippath): - if os.path.isfile(path): - zf.write(path, zippath, ZIP_DEFLATED) - elif os.path.isdir(path): - if zippath: - zf.write(path, zippath) - for nm in sorted(os.listdir(path)): - addToZip(zf, - os.path.join(path, nm), os.path.join(zippath, nm)) - # else: ignore - - with ZipFile(zip_name, 'w') as zf: - for path in files: - zippath = os.path.basename(path) - if not zippath: - zippath = os.path.basename(os.path.dirname(path)) - if zippath in ('', os.curdir, os.pardir): - zippath = '' - addToZip(zf, path, zippath) - +from . import main if __name__ == "__main__": main() diff --git a/Lib/zipimport.py b/Lib/zipimport.py index 5b9f614f02f7af..823a82ee830465 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -352,7 +352,7 @@ def _read_directory(archive): with fp: # GH-87235: On macOS all file descriptors for /dev/fd/N share the same - # file offset, reset the file offset after scanning the zipfile diretory + # file offset, reset the file offset after scanning the zipfile directory # to not cause problems when some runs 'python3 /dev/fd/9 9[^<0-9:.+-]+|<[a-zA-Z0-9+\-]+>)" + - r"((?P[+-]?\d{1,2}(:\d{2}(:\d{2})?)?)" + - r"((?P[^0-9:.+-]+|<[a-zA-Z0-9+\-]+>)" + - r"((?P[+-]?\d{1,2}(:\d{2}(:\d{2})?)?))?" + - r")?" + # dst - r")?$" # stdoff + r""" + (?P[^<0-9:.+-]+|<[a-zA-Z0-9+-]+>) + (?: + (?P[+-]?\d{1,3}(?::\d{2}(?::\d{2})?)?) + (?: + (?P[^0-9:.+-]+|<[a-zA-Z0-9+-]+>) + (?P[+-]?\d{1,3}(?::\d{2}(?::\d{2})?)?)? + )? # dst + )? # stdoff + """, + re.ASCII|re.VERBOSE ) - # fmt: on - m = parser_re.match(offset_str) + m = parser_re.fullmatch(offset_str) if m is None: raise ValueError(f"{tz_str} is not a valid TZ string") @@ -696,16 +699,17 @@ def _parse_tz_str(tz_str): def _parse_dst_start_end(dststr): - date, *time = dststr.split("/") - if date[0] == "M": + date, *time = dststr.split("/", 1) + type = date[:1] + if type == "M": n_is_julian = False - m = re.match(r"M(\d{1,2})\.(\d).(\d)$", date) + m = re.fullmatch(r"M(\d{1,2})\.(\d).(\d)", date, re.ASCII) if m is None: raise ValueError(f"Invalid dst start/end date: {dststr}") date_offset = tuple(map(int, m.groups())) offset = _CalendarOffset(*date_offset) else: - if date[0] == "J": + if type == "J": n_is_julian = True date = date[1:] else: @@ -715,38 +719,54 @@ def _parse_dst_start_end(dststr): offset = _DayOffset(doy, n_is_julian) if time: - time_components = list(map(int, time[0].split(":"))) - n_components = len(time_components) - if n_components < 3: - time_components.extend([0] * (3 - n_components)) - offset.hour, offset.minute, offset.second = time_components + offset.hour, offset.minute, offset.second = _parse_transition_time(time[0]) return offset +def _parse_transition_time(time_str): + match = re.fullmatch( + r"(?P[+-])?(?P\d{1,3})(:(?P\d{2})(:(?P\d{2}))?)?", + time_str, + re.ASCII + ) + if match is None: + raise ValueError(f"Invalid time: {time_str}") + + h, m, s = (int(v or 0) for v in match.group("h", "m", "s")) + + if h > 167: + raise ValueError( + f"Hour must be in [0, 167]: {time_str}" + ) + + if match.group("sign") == "-": + h, m, s = -h, -m, -s + + return h, m, s + + def _parse_tz_delta(tz_delta): - match = re.match( - r"(?P[+-])?(?P\d{1,2})(:(?P\d{2})(:(?P\d{2}))?)?", + match = re.fullmatch( + r"(?P[+-])?(?P\d{1,3})(:(?P\d{2})(:(?P\d{2}))?)?", tz_delta, + re.ASCII ) # Anything passed to this function should already have hit an equivalent # regular expression to find the section to parse. assert match is not None, tz_delta - h, m, s = ( - int(v) if v is not None else 0 - for v in map(match.group, ("h", "m", "s")) - ) + h, m, s = (int(v or 0) for v in match.group("h", "m", "s")) total = h * 3600 + m * 60 + s - if not -86400 < total < 86400: + if h > 24: raise ValueError( - f"Offset must be strictly between -24h and +24h: {tz_delta}" + f"Offset hours must be in [0, 24]: {tz_delta}" ) # Yes, +5 maps to an offset of -5h if match.group("sign") != "-": - total *= -1 + total = -total return total diff --git a/Mac/BuildScript/backport_gh110950_fix.patch b/Mac/BuildScript/backport_gh110950_fix.patch new file mode 100644 index 00000000000000..793f5a78d8c6ab --- /dev/null +++ b/Mac/BuildScript/backport_gh110950_fix.patch @@ -0,0 +1,25 @@ +From https://core.tcl-lang.org/tk/info/ed7cfbac8db11aa0 + +Note: the diff here is hand-tweaked so that it applies cleanly to both Tk 8.6.8 and 8.6.13. + +diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c +index 71d7c3385..e6a68356c 100644 +--- a/macosx/tkMacOSXInit.c ++++ b/macosx/tkMacOSXInit.c +@@ -128,6 +128,16 @@ static int TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip, + observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:); + observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:); + #undef observe ++} ++ ++ ++/* ++ * Fix for 10b38a7a7c. ++ */ ++ ++- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app ++{ ++ return YES; + } + + -(void)applicationWillFinishLaunching:(NSNotification *)aNotification diff --git a/Mac/BuildScript/backport_gh71383_fix.patch b/Mac/BuildScript/backport_gh71383_fix.patch new file mode 100644 index 00000000000000..d77b1045e8c165 --- /dev/null +++ b/Mac/BuildScript/backport_gh71383_fix.patch @@ -0,0 +1,89 @@ +Adapted from https://core.tcl-lang.org/tk/info/b1876b9ebc4b + +Index: generic/tkInt.h +================================================================== +--- a/generic/tkInt.h.orig ++++ b/generic/tkInt.h +@@ -1094,10 +1094,11 @@ + /* + * Themed widget set init function: + */ + + MODULE_SCOPE int Ttk_Init(Tcl_Interp *interp); ++MODULE_SCOPE void Ttk_TkDestroyedHandler(Tcl_Interp *interp); + + /* + * Internal functions shared among Tk modules but not exported to the outside + * world: + */ + +Index: generic/tkWindow.c +================================================================== +--- a/generic/tkWindow.c.orig ++++ b/generic/tkWindow.c +@@ -1619,10 +1619,11 @@ + TkBindFree(winPtr->mainPtr); + TkDeleteAllImages(winPtr->mainPtr); + TkFontPkgFree(winPtr->mainPtr); + TkFocusFree(winPtr->mainPtr); + TkStylePkgFree(winPtr->mainPtr); ++ Ttk_TkDestroyedHandler(winPtr->mainPtr->interp); + + /* + * When embedding Tk into other applications, make sure that all + * destroy events reach the server. Otherwise the embedding + * application may also attempt to destroy the windows, resulting + +Index: generic/ttk/ttkTheme.c +================================================================== +--- a/generic/ttk/ttkTheme.c.orig ++++ b/generic/ttk/ttkTheme.c +@@ -415,17 +415,10 @@ + StylePackageData *pkgPtr = (StylePackageData *)clientData; + Tcl_HashSearch search; + Tcl_HashEntry *entryPtr; + Cleanup *cleanup; + +- /* +- * Cancel any pending ThemeChanged calls: +- */ +- if (pkgPtr->themeChangePending) { +- Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr); +- } +- + /* + * Free themes. + */ + entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search); + while (entryPtr != NULL) { +@@ -528,10 +521,29 @@ + if (!pkgPtr->themeChangePending) { + Tcl_DoWhenIdle(ThemeChangedProc, pkgPtr); + pkgPtr->themeChangePending = 1; + } + } ++ ++/* Ttk_TkDestroyedHandler -- ++ * See bug [310c74ecf440]: idle calls to ThemeChangedProc() ++ * need to be canceled when Tk is destroyed, since the interp ++ * may still be active afterward; canceling them from ++ * Ttk_StylePkgFree() would be too late. ++ */ ++void Ttk_TkDestroyedHandler( ++ Tcl_Interp* interp) ++{ ++ StylePackageData* pkgPtr = GetStylePackageData(interp); ++ ++ /* ++ * Cancel any pending ThemeChanged calls: ++ */ ++ if (pkgPtr->themeChangePending) { ++ Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr); ++ } ++} + + /* + * Ttk_CreateTheme -- + * Create a new theme and register it in the global theme table. + * + diff --git a/Mac/BuildScript/backport_gh92603_fix.patch b/Mac/BuildScript/backport_gh92603_fix.patch new file mode 100644 index 00000000000000..9a37b029650340 --- /dev/null +++ b/Mac/BuildScript/backport_gh92603_fix.patch @@ -0,0 +1,82 @@ +Accepted upstream for release in Tk 8.6.14: +https://core.tcl-lang.org/tk/info/cf3830280b + +--- tk8.6.13/macosx/tkMacOSXWindowEvent.c.orig ++++ tk8.6.13-patched/macosx/tkMacOSXWindowEvent.c +@@ -239,8 +239,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification; + if (winPtr) { + TKContentView *view = [window contentView]; + +-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101500 +- if (@available(macOS 10.15, *)) { ++#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 ++ if (@available(macOS 10.14, *)) { + [view viewDidChangeEffectiveAppearance]; + } + #endif +@@ -1237,29 +1237,8 @@ static const char *const accentNames[] = { + } else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) { + TkSendVirtualEvent(tkwin, "DarkAqua", NULL); + } +- if ([NSApp macOSVersion] < 101500) { +- +- /* +- * Mojave cannot handle the KVO shenanigans that we need for the +- * highlight and accent color notifications. +- */ +- +- return; +- } + if (!defaultColor) { + defaultColor = [NSApp macOSVersion] < 110000 ? "Blue" : "Multicolor"; +- preferences = [[NSUserDefaults standardUserDefaults] retain]; +- +- /* +- * AppKit calls this method when the user changes the Accent Color +- * but not when the user changes the Highlight Color. So we register +- * to receive KVO notifications for Highlight Color as well. +- */ +- +- [preferences addObserver:self +- forKeyPath:@"AppleHighlightColor" +- options:NSKeyValueObservingOptionNew +- context:NULL]; + } + NSString *accent = [preferences stringForKey:@"AppleAccentColor"]; + NSArray *words = [[preferences stringForKey:@"AppleHighlightColor"] +--- tk8.6.13/macosx/tkMacOSXWm.c.orig ++++ tk8.6.13-patched/macosx/tkMacOSXWm.c +@@ -1289,6 +1289,11 @@ TkWmDeadWindow( + [NSApp _setMainWindow:nil]; + } + [deadNSWindow close]; ++#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 ++ NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; ++ [preferences removeObserver:deadNSWindow.contentView ++ forKeyPath:@"AppleHighlightColor"]; ++#endif + [deadNSWindow release]; + + #if DEBUG_ZOMBIES > 1 +@@ -6763,6 +6768,21 @@ TkMacOSXMakeRealWindowExist( + } + TKContentView *contentView = [[TKContentView alloc] + initWithFrame:NSZeroRect]; ++#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 ++ NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; ++ ++ /* ++ * AppKit calls the viewDidChangeEffectiveAppearance method when the ++ * user changes the Accent Color but not when the user changes the ++ * Highlight Color. So we register to receive KVO notifications for ++ * Highlight Color as well. ++ */ ++ ++ [preferences addObserver:contentView ++ forKeyPath:@"AppleHighlightColor" ++ options:NSKeyValueObservingOptionNew ++ context:NULL]; ++#endif + [window setContentView:contentView]; + [contentView release]; + [window setDelegate:NSApp]; diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index c54de880c20360..938c895c784f33 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -261,14 +261,14 @@ def library_recipes(): tcl_checksum='81656d3367af032e0ae6157eff134f89' tk_checksum='5e0faecba458ee1386078fb228d008ba' - tk_patches = ['tk868_on_10_8_10_9.patch'] + tk_patches = ['backport_gh71383_fix.patch', 'tk868_on_10_8_10_9.patch', 'backport_gh110950_fix.patch'] else: tcl_tk_ver='8.6.13' tcl_checksum='43a1fae7412f61ff11de2cfd05d28cfc3a73762f354a417c62370a54e2caf066' tk_checksum='2e65fa069a23365440a3c56c556b8673b5e32a283800d8d9b257e3f584ce0675' - tk_patches = [ ] + tk_patches = ['backport_gh92603_fix.patch', 'backport_gh71383_fix.patch', 'backport_gh110950_fix.patch'] base_url = "https://prdownloads.sourceforge.net/tcl/{what}{version}-src.tar.gz" @@ -359,9 +359,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.42.0", - url="https://sqlite.org/2023/sqlite-autoconf-3420000.tar.gz", - checksum="0c5a92bc51cf07cae45b4a1e94653dea", + name="SQLite 3.43.1", + url="https://sqlite.org/2023/sqlite-autoconf-3430100.tar.gz", + checksum="77e61befe9c3298da0504f87772a24b0", extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' @@ -1147,7 +1147,9 @@ def buildPython(): # will find them during its extension import sanity checks. print("Running configure...") + print(" NOTE: --with-mimalloc=no pending resolution of weak linking issues") runCommand("%s -C --enable-framework --enable-universalsdk=/ " + "--with-mimalloc=no " "--with-universal-archs=%s " "%s " "%s " @@ -1490,7 +1492,7 @@ def packageFromRecipe(targetDir, recipe): IFPkgFlagRelocatable=False, IFPkgFlagRestartAction="NoRestart", IFPkgFlagRootVolumeOnly=True, - IFPkgFlagUpdateInstalledLangauges=False, + IFPkgFlagUpdateInstalledLanguages=False, ) writePlist(pl, os.path.join(packageContents, 'Info.plist')) diff --git a/Mac/Makefile.in b/Mac/Makefile.in index 78b4499cca986a..32e3a0f55c5d71 100644 --- a/Mac/Makefile.in +++ b/Mac/Makefile.in @@ -257,6 +257,8 @@ install_IDLE: rm "$(DESTDIR)$(LIBDEST)/idlelib/config-extensions.def~" ; \ fi touch "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" + chmod -R ugo+rX,go-w "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app" + chmod ugo+x "$(DESTDIR)$(PYTHONAPPSDIR)/IDLE.app/Contents/MacOS/IDLE" $(INSTALLED_PYTHONAPP): install_Python diff --git a/Mac/PythonLauncher/Makefile.in b/Mac/PythonLauncher/Makefile.in index 4c05f26e8358bc..9decadbdc60f00 100644 --- a/Mac/PythonLauncher/Makefile.in +++ b/Mac/PythonLauncher/Makefile.in @@ -27,6 +27,8 @@ install: Python\ Launcher.app -test -d "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" && rm -r "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" /bin/cp -r "Python Launcher.app" "$(DESTDIR)$(PYTHONAPPSDIR)" touch "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" + chmod -R ugo+rX,go-w "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" + chmod ugo+x "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app/Contents/MacOS/Python Launcher" clean: rm -f *.o "Python Launcher" diff --git a/Makefile.pre.in b/Makefile.pre.in index d62b4d24b3e183..5fb6ffc4e8f0cf 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -100,7 +100,7 @@ CONFIGURE_LDFLAGS= @LDFLAGS@ # command line to append to these values without stomping the pre-set # values. PY_CFLAGS= $(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -PY_CFLAGS_NODIST=$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST) -I$(srcdir)/Include/internal +PY_CFLAGS_NODIST=$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST) -I$(srcdir)/Include/internal -I$(srcdir)/Include/internal/mimalloc # Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to # be able to build extension modules using the directories specified in the # environment variables @@ -336,6 +336,20 @@ IO_OBJS= \ Modules/_io/bytesio.o \ Modules/_io/stringio.o + +########################################################################## +# mimalloc + +MIMALLOC_HEADERS= \ + $(srcdir)/Include/internal/pycore_mimalloc.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/atomic.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/internal.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/prim.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/track.h \ + $(srcdir)/Include/internal/mimalloc/mimalloc/types.h + + ########################################################################## # Parser @@ -347,20 +361,36 @@ PEGEN_OBJS= \ Parser/string_parser.o \ Parser/peg_api.o +TOKENIZER_OBJS= \ + Parser/lexer/buffer.o \ + Parser/lexer/lexer.o \ + Parser/lexer/state.o \ + Parser/tokenizer/file_tokenizer.o \ + Parser/tokenizer/readline_tokenizer.o \ + Parser/tokenizer/string_tokenizer.o \ + Parser/tokenizer/utf8_tokenizer.o \ + Parser/tokenizer/helpers.o PEGEN_HEADERS= \ $(srcdir)/Include/internal/pycore_parser.h \ $(srcdir)/Parser/pegen.h \ $(srcdir)/Parser/string_parser.h +TOKENIZER_HEADERS= \ + Parser/lexer/buffer.h \ + Parser/lexer/lexer.h \ + Parser/lexer/state.h \ + Parser/tokenizer/tokenizer.h \ + Parser/tokenizer/helpers.h + POBJS= \ Parser/token.o \ -PARSER_OBJS= $(POBJS) $(PEGEN_OBJS) Parser/myreadline.o Parser/tokenizer.o +PARSER_OBJS= $(POBJS) $(PEGEN_OBJS) $(TOKENIZER_OBJS) Parser/myreadline.o PARSER_HEADERS= \ $(PEGEN_HEADERS) \ - $(srcdir)/Parser/tokenizer.h + $(TOKENIZER_HEADERS) ########################################################################## # Python @@ -379,9 +409,10 @@ PYTHON_OBJS= \ Python/codecs.o \ Python/compile.o \ Python/context.o \ + Python/critical_section.o \ + Python/crossinterp.o \ Python/dynamic_annotations.o \ Python/errors.o \ - Python/executor.o \ Python/flowgraph.o \ Python/frame.o \ Python/frozenmain.o \ @@ -624,7 +655,8 @@ build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \ .PHONY: check-clean-src check-clean-src: @if test -n "$(VPATH)" -a \( \ - -f "$(srcdir)/Programs/python.o" \ + -f "$(srcdir)/$(BUILDPYTHON)" \ + -o -f "$(srcdir)/Programs/python.o" \ -o -f "$(srcdir)\Python/frozen_modules/importlib._bootstrap.h" \ \); then \ echo "Error: The source directory ($(srcdir)) is not clean" ; \ @@ -657,7 +689,7 @@ profile-run-stamp: $(MAKE) profile-gen-stamp # Next, run the profile task to generate the profile information. @ # FIXME: can't run for a cross build - $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true + $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) $(LLVM_PROF_MERGER) # Remove profile generation binary since we are done with it. $(MAKE) clean-retain-profile @@ -706,7 +738,7 @@ profile-bolt-stamp: $(BUILDPYTHON) mv "$${bin}.bolt_inst" "$${bin}"; \ done # Run instrumented binaries to collect data. - $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true + $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) # Merge all the data files together. for bin in $(BOLT_BINARIES); do \ @MERGE_FDATA@ $${bin}.*.fdata > "$${bin}.fdata"; \ @@ -1059,7 +1091,7 @@ regen-re: $(BUILDPYTHON) $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/generate_re_casefix.py $(srcdir)/Lib/re/_casefix.py Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS) - $(LINKCC) $(PY_LDFLAGS_NOLTO) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ # "Bootstrap Python" used to run deepfreeze.py @@ -1160,7 +1192,7 @@ Programs/_freeze_module.o: Programs/_freeze_module.c Makefile Modules/getpath_noop.o: $(srcdir)/Modules/getpath_noop.c Makefile Programs/_freeze_module: Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) - $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) + $(LINKCC) $(PY_CORE_LDFLAGS) -o $@ Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) # We manually freeze getpath.py rather than through freeze_modules Python/frozen_modules/getpath.h: Modules/getpath.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) @@ -1311,6 +1343,14 @@ check-abidump: all regen-limited-abi: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.toml +############################################################################ +# Regenerate Unicode Data + +.PHONY: regen-unicodedata +regen-unicodedata: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/unicode/makeunicodedata.py + + ############################################################################ # Regenerate all generated files @@ -1319,10 +1359,10 @@ regen-limited-abi: all 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 + regen-test-levenshtein regen-global-objects regen-sbom @echo - @echo "Note: make regen-stdlib-module-names, make regen-limited-abi" - @echo "and make regen-configure should be run manually" + @echo "Note: make regen-stdlib-module-names, make regen-limited-abi, " + @echo "make regen-configure and make regen-unicodedata should be run manually" ############################################################################ # Special rules for object files @@ -1396,11 +1436,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: @@ -1519,6 +1561,23 @@ 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 +Objects/obmalloc.o: $(srcdir)/Objects/mimalloc/alloc.c \ + $(srcdir)/Objects/mimalloc/alloc-aligned.c \ + $(srcdir)/Objects/mimalloc/alloc-posix.c \ + $(srcdir)/Objects/mimalloc/arena.c \ + $(srcdir)/Objects/mimalloc/bitmap.c \ + $(srcdir)/Objects/mimalloc/heap.c \ + $(srcdir)/Objects/mimalloc/init.c \ + $(srcdir)/Objects/mimalloc/options.c \ + $(srcdir)/Objects/mimalloc/os.c \ + $(srcdir)/Objects/mimalloc/page.c \ + $(srcdir)/Objects/mimalloc/random.c \ + $(srcdir)/Objects/mimalloc/segment.c \ + $(srcdir)/Objects/mimalloc/segment-map.c \ + $(srcdir)/Objects/mimalloc/stats.c \ + $(srcdir)/Objects/mimalloc/prim/prim.c + +Objects/mimalloc/page.o: $(srcdir)/Objects/mimalloc/page-queue.c .PHONY: regen-cases regen-cases: @@ -1528,16 +1587,22 @@ regen-cases: $(PYTHON_FOR_REGEN) \ $(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 + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/opcode_id_generator.py -o $(srcdir)/Include/opcode_ids.h.new $(srcdir)/Python/bytecodes.c + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/uop_id_generator.py -o $(srcdir)/Include/internal/pycore_uop_ids.h.new $(srcdir)/Python/bytecodes.c + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/tier1_generator.py -o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/tier2_generator.py -o $(srcdir)/Python/executor_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)/Include/internal/pycore_uop_ids.h $(srcdir)/Include/internal/pycore_uop_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 @@ -1550,14 +1615,9 @@ 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)/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 @@ -1701,7 +1761,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/longobject.h \ $(srcdir)/Include/cpython/memoryobject.h \ $(srcdir)/Include/cpython/methodobject.h \ - $(srcdir)/Include/cpython/modsupport.h \ $(srcdir)/Include/cpython/object.h \ $(srcdir)/Include/cpython/objimpl.h \ $(srcdir)/Include/cpython/odictobject.h \ @@ -1716,6 +1775,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/pyerrors.h \ $(srcdir)/Include/cpython/pyfpe.h \ $(srcdir)/Include/cpython/pyframe.h \ + $(srcdir)/Include/cpython/pyhash.h \ $(srcdir)/Include/cpython/pylifecycle.h \ $(srcdir)/Include/cpython/pymem.h \ $(srcdir)/Include/cpython/pystate.h \ @@ -1731,12 +1791,13 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/warnings.h \ $(srcdir)/Include/cpython/weakrefobject.h \ \ + @MIMALLOC_HEADERS@ \ + \ $(srcdir)/Include/internal/pycore_abstract.h \ $(srcdir)/Include/internal/pycore_asdl.h \ $(srcdir)/Include/internal/pycore_ast.h \ $(srcdir)/Include/internal/pycore_ast_state.h \ $(srcdir)/Include/internal/pycore_atexit.h \ - $(srcdir)/Include/internal/pycore_atomic.h \ $(srcdir)/Include/internal/pycore_bitutils.h \ $(srcdir)/Include/internal/pycore_bytes_methods.h \ $(srcdir)/Include/internal/pycore_bytesobject.h \ @@ -1750,6 +1811,8 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_complexobject.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ + $(srcdir)/Include/internal/pycore_critical_section.h \ + $(srcdir)/Include/internal/pycore_crossinterp.h \ $(srcdir)/Include/internal/pycore_dict.h \ $(srcdir)/Include/internal/pycore_dict_state.h \ $(srcdir)/Include/internal/pycore_descrobject.h \ @@ -1790,6 +1853,7 @@ PYTHON_HEADERS= \ $(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 \ @@ -1815,6 +1879,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_token.h \ $(srcdir)/Include/internal/pycore_traceback.h \ $(srcdir)/Include/internal/pycore_tracemalloc.h \ + $(srcdir)/Include/internal/pycore_tstate.h \ $(srcdir)/Include/internal/pycore_tuple.h \ $(srcdir)/Include/internal/pycore_typeobject.h \ $(srcdir)/Include/internal/pycore_typevarobject.h \ @@ -1837,7 +1902,7 @@ $(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) TESTOPTS= $(EXTRATESTOPTS) TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS) -TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py +TESTRUNNER= $(TESTPYTHON) -m test TESTTIMEOUT= # Remove "test_python_*" directories of previous failed test jobs. @@ -1853,21 +1918,6 @@ cleantest: all test: all $(TESTRUNNER) --fast-ci --timeout=$(TESTTIMEOUT) $(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]' -exec rm -f {} ';' || true - $(TESTPYTHON) -E $(srcdir)/Lib/compileall.py - -find $(srcdir)/Lib -name '*.py[co]' -exec rm -f {} ';' || true - $(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) - $(TESTRUNNER) --slow-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 @@ -1880,8 +1930,9 @@ testuniversal: all $(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. +# 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 \ @@ -1889,11 +1940,6 @@ buildbottest: all fi $(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) -# Like testall, but run Python tests with HOSTRUNNER directly. -.PHONY: hostrunnertest -hostrunnertest: all - $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS) - .PHONY: pythoninfo pythoninfo: all $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo @@ -2122,10 +2168,12 @@ LIBSUBDIRS= asyncio \ json \ logging \ multiprocessing multiprocessing/dummy \ + pathlib \ pydoc_data \ re \ site-packages \ sqlite3 \ + sysconfig \ tkinter \ tomllib \ turtledemo \ @@ -2141,10 +2189,12 @@ LIBSUBDIRS= asyncio \ TESTSUBDIRS= idlelib/idle_test \ test \ test/audiodata \ + test/archivetestdata \ test/certdata \ test/certdata/capath \ test/cjkencodings \ test/crashers \ + test/configdata \ test/data \ test/decimaltestdata \ test/dtracedata \ @@ -2152,6 +2202,9 @@ TESTSUBDIRS= idlelib/idle_test \ test/leakers \ test/libregrtest \ test/mathdata \ + test/regrtestdata \ + test/regrtestdata/import_from_tests \ + test/regrtestdata/import_from_tests/test_regrtest_b \ test/subprocessdata \ test/support \ test/support/_hypothesis_stubs \ @@ -2164,6 +2217,7 @@ TESTSUBDIRS= idlelib/idle_test \ 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 \ @@ -2254,8 +2308,7 @@ TESTSUBDIRS= idlelib/idle_test \ test/tracedmodules \ test/typinganndata \ test/xmltestdata \ - test/xmltestdata/c14n-20 \ - test/ziptestdata + test/xmltestdata/c14n-20 COMPILEALL_OPTS=-j0 @@ -2601,15 +2654,13 @@ 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; \ - if ! command -v $$RUNTIME; then echo "$@ needs either Podman or Docker container runtime." >&2; exit 1; fi; \ - if command -v selinuxenabled >/dev/null && selinuxenabled; then OPT=":Z"; fi; \ - CMD="$$RUNTIME run --rm --pull=always -v $(abs_srcdir):/src$$OPT quay.io/tiran/cpython_autoconf:271"; \ - echo $$CMD; \ - $$CMD || exit $? + $(srcdir)/Tools/build/regen-configure.sh + +.PHONY: regen-sbom +regen-sbom: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_sbom.py # Create a tags file for vi tags:: @@ -2696,6 +2747,7 @@ clobber: clean -rm -rf build platform -rm -rf $(PYTHONFRAMEWORKDIR) -rm -f python-config.py python-config + -rm -rf cross-build # Make things extra clean, before making a distribution: # remove all generated files, even Makefile[.pre] diff --git a/Misc/ACKS b/Misc/ACKS index ccdfae66832f0e..12335c911ae42a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -630,6 +630,7 @@ Dinu Gherman Subhendu Ghosh Jonathan Giddy Johannes Gijsbers +Stephen Gildea Michael Gilfix Julian Gindi Yannick Gingras @@ -787,6 +788,7 @@ Thomas Holmes Craig Holmquist Philip Homburg Naofumi Honda +Constantin Hong Weipeng Hong Jeffrey Honig Rob Hooft @@ -1345,6 +1347,7 @@ Michele Orrù Tomáš Orsava Oleg Oshmyan Denis Osipov +Savannah Ostrowski Denis S. Otkidach Peter Otten Michael Otteneder @@ -1373,6 +1376,7 @@ Peter Parente Alexandre Parenteau Dan Parisien HyeSoo Park +Moonsik Park William Park Claude Paroz Heikki Partanen @@ -1456,6 +1460,7 @@ Paul Prescod Donovan Preston Eric Price Paul Price +Matt Prodani Iuliia Proskurnia Dorian Pula Jyrki Pulliainen @@ -1479,6 +1484,7 @@ Ajith Ramachandran Dhushyanth Ramasamy Ashwin Ramaswami Jeff Ramnani +Grant Ramsay Bayard Randel Varpu Rantala Brodie Rao diff --git a/Misc/HISTORY b/Misc/HISTORY index e66b695f21c977..b66413277259dc 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -16169,7 +16169,7 @@ Core and Builtins codec subsystem, for example UTF-8 is turned into utf-8. - Issue #4200: Changed the atexit module to store its state in its - PyModuleDef atexitmodule. This fixes a bug with multiple subinterpeters. + PyModuleDef atexitmodule. This fixes a bug with multiple subinterpreters. - Issue #4237: io.FileIO() was raising invalid warnings caused by insufficient initialization of PyFileIOObject struct members. diff --git a/Misc/NEWS.d/3.10.0a1.rst b/Misc/NEWS.d/3.10.0a1.rst index a9f25b482508ba..731eed3447d2bc 100644 --- a/Misc/NEWS.d/3.10.0a1.rst +++ b/Misc/NEWS.d/3.10.0a1.rst @@ -605,8 +605,8 @@ Opt out serialization/deserialization for _random.Random .. nonce: jxJ4yn .. section: Core and Builtins -Rename `PyPegen*` functions to `PyParser*`, so that we can remove the old -set of `PyParser*` functions that were using the old parser, but keep +Rename ``PyPegen*`` functions to ``PyParser*``, so that we can remove the old +set of ``PyParser*`` functions that were using the old parser, but keep everything backwards-compatible. .. diff --git a/Misc/NEWS.d/3.10.0a7.rst b/Misc/NEWS.d/3.10.0a7.rst index 3a1694f444616a..d9cdfbd04c88d4 100644 --- a/Misc/NEWS.d/3.10.0a7.rst +++ b/Misc/NEWS.d/3.10.0a7.rst @@ -274,7 +274,7 @@ Co-authored-by: Tim Peters Only handle asynchronous exceptions and requests to drop the GIL when returning from a call or on the back edges of loops. Makes sure that -:meth:`__exit__` is always called in with statements, even for interrupts. +:meth:`~object.__exit__` is always called in with statements, even for interrupts. .. diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst index 7c991e7667b01a..26c44b6c1af0ed 100644 --- a/Misc/NEWS.d/3.11.0a1.rst +++ b/Misc/NEWS.d/3.11.0a1.rst @@ -1720,7 +1720,7 @@ Improve the speed and accuracy of statistics.pvariance(). .. nonce: WI9zQY .. section: Library -Remove :meth:`__getitem__` methods of +Remove :meth:`~object.__getitem__` methods of :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` and :class:`fileinput.FileInput`, deprecated since Python 3.9. diff --git a/Misc/NEWS.d/3.12.0a1.rst b/Misc/NEWS.d/3.12.0a1.rst index 633738de92bef7..29d04fa0e175bf 100644 --- a/Misc/NEWS.d/3.12.0a1.rst +++ b/Misc/NEWS.d/3.12.0a1.rst @@ -1913,7 +1913,7 @@ Stinner. .. nonce: Uxc9al .. section: Library -Allow :mod:`venv` to pass along :envvar:`PYTHON*` variables to ``ensurepip`` +Allow :mod:`venv` to pass along :envvar:`!PYTHON*` variables to ``ensurepip`` and ``pip`` when they do not impact path resolution .. diff --git a/Misc/NEWS.d/3.12.0b1.rst b/Misc/NEWS.d/3.12.0b1.rst index 0944dfd0e90ab9..007a6ad4ffd4d4 100644 --- a/Misc/NEWS.d/3.12.0b1.rst +++ b/Misc/NEWS.d/3.12.0b1.rst @@ -880,7 +880,7 @@ Update the ``repr`` of :class:`typing.Unpack` according to :pep:`692`. .. section: Library Make :mod:`dis` display the names of the args for -:opcode:`CALL_INTRINSIC_*`. +:opcode:`!CALL_INTRINSIC_*`. .. 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.13.0a2.rst b/Misc/NEWS.d/3.13.0a2.rst new file mode 100644 index 00000000000000..c1b1be523325e8 --- /dev/null +++ b/Misc/NEWS.d/3.13.0a2.rst @@ -0,0 +1,1622 @@ +.. date: 2023-11-20-14-13-02 +.. gh-issue: 112243 +.. nonce: FKdQnr +.. release date: 2023-11-22 +.. section: Core and Builtins + +Don't include comments in f-string debug expressions. Patch by Pablo Galindo + +.. + +.. date: 2023-11-20-10-40-40 +.. gh-issue: 112287 +.. nonce: 15gWAK +.. section: Core and Builtins + +Slightly optimize the Tier 2 (uop) interpreter by only loading ``oparg`` and +``operand`` when needed. Also double the trace size limit again, to 512 this +time. + +.. + +.. date: 2023-11-19-15-57-23 +.. gh-issue: 112266 +.. nonce: BSJMbR +.. section: Core and Builtins + +Change docstrings of :attr:`~object.__dict__` and +:attr:`~object.__weakref__`. + +.. + +.. date: 2023-11-17-16-49-32 +.. gh-issue: 111807 +.. nonce: QvjP9_ +.. section: Core and Builtins + +Lower the max parser stack depth to 1000 under WASI debug builds. + +.. + +.. date: 2023-11-15-20-20-51 +.. gh-issue: 111798 +.. nonce: cs-3t3 +.. section: Core and Builtins + +When Python is built in debug mode, set the C recursion limit to 500 instead +of 1500. A debug build is likely built with low optimization level which +implies higher stack memory usage than a release build. Patch by Victor +Stinner. + +.. + +.. date: 2023-11-15-16-14-10 +.. gh-issue: 106529 +.. nonce: Y48ax9 +.. section: Core and Builtins + +Enable translating unspecialized ``FOR_ITER`` to Tier 2. + +.. + +.. date: 2023-11-14-22-12-11 +.. gh-issue: 111916 +.. nonce: ZGCayL +.. section: Core and Builtins + +Make hashlib related modules thread-safe without the GIL + +.. + +.. date: 2023-11-07-12-59-02 +.. gh-issue: 81137 +.. nonce: qFpJCY +.. section: Core and Builtins + +Deprecate assignment to a function's ``__code__`` field when the new code +object is of a mismatched type (e.g., from a generator to a plain function). + +.. + +.. date: 2023-11-06-16-44-09 +.. gh-issue: 79932 +.. nonce: 2qv7uD +.. section: Core and Builtins + +Raise exception if :meth:`frame.clear` is called on a suspended frame. + +.. + +.. date: 2023-11-05-20-59-10 +.. gh-issue: 81925 +.. nonce: wKHLSS +.. section: Core and Builtins + +Implement native thread ids for GNU KFreeBSD. + +.. + +.. date: 2023-11-05-06-40-35 +.. gh-issue: 111843 +.. nonce: c045cB +.. section: Core and Builtins + +Use exponential backoff to reduce the number of failed tier 2 optimization +attempts by over 99%. + +.. + +.. date: 2023-11-04-13-36-51 +.. gh-issue: 110829 +.. nonce: Pa0CJI +.. section: Core and Builtins + +Joining a thread now ensures the underlying OS thread has exited. This is +required for safer fork() in multi-threaded processes. + +.. + +.. date: 2023-11-03-22-48-29 +.. gh-issue: 109369 +.. nonce: ELYaxJ +.. section: Core and Builtins + +Make sure that tier 2 traces are de-optimized if the code is instrumented + +.. + +.. date: 2023-11-03-19-25-38 +.. gh-issue: 111772 +.. nonce: aRQvOn +.. section: Core and Builtins + +Specialize slot loads and stores for _Py_T_OBJECT as well as Py_T_OBJECT_EX + +.. + +.. date: 2023-11-03-01-23-48 +.. gh-issue: 111666 +.. nonce: l8Q8G5 +.. section: Core and Builtins + +Speed up :meth:`BaseExceptionGroup.derive`, +:meth:`BaseExceptionGroup.subgroup`, and :meth:`BaseExceptionGroup.split` by +changing how they parse passed arguments. + +.. + +.. date: 2023-11-03-01-04-55 +.. gh-issue: 111654 +.. nonce: scUhDO +.. section: Core and Builtins + +Fix runtime crash when some error happens in opcode +``LOAD_FROM_DICT_OR_DEREF``. + +.. + +.. date: 2023-11-02-15-00-57 +.. gh-issue: 111623 +.. nonce: BZxYc8 +.. section: Core and Builtins + +Add support for sharing tuples between interpreters using the +cross-interpreter API. Patch by Anthony Shaw. + +.. + +.. date: 2023-11-02-14-49-19 +.. gh-issue: 111354 +.. nonce: gIS3f- +.. section: Core and Builtins + +The oparg of :opcode:`YIELD_VALUE` is now ``1`` if the instruction is part +of a yield-from or await, and ``0`` otherwise. + +The SUSPENDED frame state is now split into ``SUSPENDED`` and +``SUSPENDED_YIELD_FROM``. This simplifies the code in ``_PyGen_yf``. + +.. + +.. date: 2023-10-31-21-33-35 +.. gh-issue: 111520 +.. nonce: vw-rxJ +.. section: Core and Builtins + +Merge the Tier 1 (bytecode) and Tier 2 (micro-ops) interpreters together, +moving the Tier 2 interpreter loop and switch into +``_PyEval_EvalFrameDefault()`` in ``Python/ceval.c``. The +``Python/executor.c`` file is gone. Also the ``TIER_ONE`` and ``TIER_TWO`` +macros are now handled by the code generator. + +**Beware!** This changes the environment variables to enable micro-ops and +their debugging to ``PYTHON_UOPS`` and ``PYTHON_LLTRACE``. + +.. + +.. date: 2023-10-31-14-25-21 +.. gh-issue: 109181 +.. nonce: 11h6Mc +.. section: Core and Builtins + +Speed up :obj:`Traceback` object creation by lazily compute the line number. +Patch by Pablo Galindo + +.. + +.. date: 2023-10-29-20-11-21 +.. gh-issue: 111420 +.. nonce: IUT-GK +.. section: Core and Builtins + +Allow type comments in parenthesized ``with`` statements + +.. + +.. date: 2023-10-29-12-33-33 +.. gh-issue: 111438 +.. nonce: bHTLLl +.. section: Core and Builtins + +Add support for sharing floats between interpreters using the +cross-interpreter API. Patch by Anthony Shaw. + +.. + +.. date: 2023-10-29-11-35-21 +.. gh-issue: 111435 +.. nonce: ageUWQ +.. section: Core and Builtins + +Add support for sharing of True and False between interpreters using the +cross-interpreter API. Patch by Anthony Shaw. + +.. + +.. date: 2023-10-27-19-38-33 +.. gh-issue: 102388 +.. nonce: vd5YUZ +.. section: Core and Builtins + +Fix a bug where ``iso2022_jp_3`` and ``iso2022_jp_2004`` codecs read out of +bounds + +.. + +.. date: 2023-10-27-12-17-49 +.. gh-issue: 111366 +.. nonce: _TSknV +.. section: Core and Builtins + +Fix an issue in the :mod:`codeop` that was causing :exc:`SyntaxError` +exceptions raised in the presence of invalid syntax to not contain precise +error messages. Patch by Pablo Galindo + +.. + +.. date: 2023-10-27-11-51-40 +.. gh-issue: 111380 +.. nonce: vgSbir +.. section: Core and Builtins + +Fix a bug that was causing :exc:`SyntaxWarning` to appear twice when parsing +if invalid syntax is encountered later. Patch by Pablo galindo + +.. + +.. date: 2023-10-27-11-22-09 +.. gh-issue: 111374 +.. nonce: e9lrPZ +.. section: Core and Builtins + +Added a new environment variable :envvar:`PYTHON_FROZEN_MODULES`. It +determines whether or not frozen modules are ignored by the import +machinery, equivalent of the :option:`-X frozen_modules <-X>` command-line +option. + +.. + +.. date: 2023-10-26-18-45-20 +.. gh-issue: 111354 +.. nonce: GrT-Wf +.. section: Core and Builtins + +Remove ``oparg`` from :opcode:`YIELD_VALUE`. Change ``oparg`` of +:opcode:`RESUME` to include information about the except-depth. These +changes make it possible to simplify the code in generator close. + +.. + +.. date: 2023-10-23-22-11-09 +.. gh-issue: 94438 +.. nonce: y2pITu +.. section: Core and Builtins + +Fix a regression that prevented jumping across ``is None`` and ``is not +None`` when debugging. Patch by Savannah Ostrowski. + +.. + +.. date: 2023-10-23-15-44-47 +.. gh-issue: 67224 +.. nonce: S4D6CR +.. section: Core and Builtins + +Show source lines in tracebacks when using the ``-c`` option when running +Python. Patch by Pablo Galindo + +.. + +.. date: 2023-10-20-23-14-06 +.. gh-issue: 111123 +.. nonce: jjVc3M +.. section: Core and Builtins + +Fix a bug where a :keyword:`global` declaration in an :keyword:`except` +block is rejected when the global is used in the :keyword:`else` block. + +.. + +.. date: 2023-10-17-11-03-45 +.. gh-issue: 110938 +.. nonce: X3sbMb +.. section: Core and Builtins + +Fix error messages for indented blocks with functions and classes with +generic type parameters. Patch by Pablo Galindo + +.. + +.. date: 2023-10-16-15-51-37 +.. gh-issue: 109214 +.. nonce: -RGTFH +.. section: Core and Builtins + +Remove unnecessary instruction pointer updates before returning from frames. + +.. + +.. date: 2023-10-16-12-12-48 +.. gh-issue: 110912 +.. nonce: uEJGi_ +.. section: Core and Builtins + +Correctly display the traceback for :exc:`MemoryError` exceptions using the +:mod:`traceback` module. Patch by Pablo Galindo + +.. + +.. date: 2023-10-15-22-18-45 +.. gh-issue: 109894 +.. nonce: UAmo06 +.. section: Core and Builtins + +Fixed crash due to improperly initialized static :exc:`MemoryError` in +subinterpreter. + +.. + +.. date: 2023-10-15-20-45-35 +.. gh-issue: 110892 +.. nonce: oA6eVY +.. section: Core and Builtins + +Return ``NULL`` for ``PyTrace_RETURN`` events caused by an exception + +.. + +.. date: 2023-10-14-12-19-34 +.. gh-issue: 110864 +.. nonce: -baPDE +.. section: Core and Builtins + +Fix argument parsing by ``_PyArg_UnpackKeywordsWithVararg`` for functions +defining pos-or-keyword, vararg, and kw-only parameters. + +.. + +.. date: 2023-10-13-16-55-55 +.. gh-issue: 109094 +.. nonce: ziL4cJ +.. section: Core and Builtins + +Replace ``prev_instr`` on the interpreter frame by ``instr_ptr`` which +points to the beginning of the instruction that is currently executing (or +will execute once the frame resumes). + +.. + +.. date: 2023-10-13-09-21-29 +.. gh-issue: 110805 +.. nonce: vhU7A7 +.. section: Core and Builtins + +Allow the repl to show source code and complete tracebacks. Patch by Pablo +Galindo + +.. + +.. date: 2023-10-12-17-15-23 +.. gh-issue: 110722 +.. nonce: sjMwQe +.. section: Core and Builtins + +Add :envvar:`PYTHON_PRESITE=package.module` to import a module early in the +interpreter lifecycle before ``site.py`` is executed. Python needs to be +:ref:`built in debug mode ` for this option to exist. + +.. + +.. date: 2023-10-12-12-09-01 +.. gh-issue: 110481 +.. nonce: 3Er3it +.. section: Core and Builtins + +Implement biased reference counting in ``--disable-gil`` builds. + +.. + +.. date: 2023-10-09-19-54-33 +.. gh-issue: 110543 +.. nonce: 1wrxO8 +.. section: Core and Builtins + +Fix regression in Python 3.12 where :meth:`types.CodeType.replace` would +produce a broken code object if called on a module or class code object that +contains a comprehension. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-09-30-17-30-11 +.. gh-issue: 89519 +.. nonce: hz2pZf +.. section: Core and Builtins + +Removed chained :class:`classmethod` descriptors (introduced in +:issue:`19072`). This can no longer be used to wrap other descriptors such +as :class:`property`. The core design of this feature was flawed and caused +a number of downstream problems. To "pass-through" a :class:`classmethod`, +consider using the :attr:`!__wrapped__` attribute that was added in Python +3.10. + +.. + +.. date: 2023-09-15-23-39-43 +.. gh-issue: 103615 +.. nonce: WZavly +.. section: Core and Builtins + +Use local events for opcode tracing + +.. + +.. bpo: 46657 +.. date: 2023-09-06-12-36-11 +.. nonce: xea1T_ +.. section: Core and Builtins + +Add mimalloc memory allocator support. + +.. + +.. date: 2023-08-31-11-42-16 +.. gh-issue: 106718 +.. nonce: _-57DA +.. section: Core and Builtins + +When PyConfig.stdlib_dir is explicitly set, it's now respected and won't be +overridden by PyConfig.home. + +.. + +.. date: 2023-07-20-11-41-16 +.. gh-issue: 106905 +.. nonce: AyZpuB +.. section: Core and Builtins + +Fix incorrect SystemError about AST constructor recursion depth mismatch. + +.. + +.. date: 2022-12-27-02-51-45 +.. gh-issue: 100445 +.. nonce: C8f6ph +.. section: Core and Builtins + +Improve error message for unterminated strings with escapes. + +.. + +.. bpo: 45759 +.. date: 2021-11-10-10-40-05 +.. nonce: WJoB3D +.. section: Core and Builtins + +Improved error messages for ``elif``/``else`` statements not matching any +valid statements. Patch by Jeremiah Vivian. + +.. + +.. date: 2023-11-14-18-43-55 +.. gh-issue: 111942 +.. nonce: x1pnrj +.. section: Library + +Fix SystemError in the TextIOWrapper constructor with non-encodable "errors" +argument in non-debug mode. + +.. + +.. date: 2023-11-14-16-31-59 +.. gh-issue: 111995 +.. nonce: OoX8JJ +.. section: Library + +Added the ``NI_IDN`` constant to the :mod:`socket` module when present in C +at build time for use with :func:`socket.getnameinfo`. + +.. + +.. date: 2023-11-11-16-42-48 +.. gh-issue: 109538 +.. nonce: cMG5ux +.. section: Library + +Issue warning message instead of having :class:`RuntimeError` be displayed +when event loop has already been closed at :meth:`StreamWriter.__del__`. + +.. + +.. date: 2023-11-10-22-08-28 +.. gh-issue: 111942 +.. nonce: MDFm6v +.. section: Library + +Fix crashes in :meth:`io.TextIOWrapper.reconfigure` when pass invalid +arguments, e.g. non-string encoding. + +.. + +.. date: 2023-11-09-12-57-43 +.. gh-issue: 111460 +.. nonce: TQaz9I +.. section: Library + +:mod:`curses`: restore wide character support (including +:func:`curses.unget_wch` and :meth:`~curses.window.get_wch`) on macOS, which +was unavailable due to a regression in Python 3.12. + +.. + +.. date: 2023-11-09-10-45-56 +.. gh-issue: 103791 +.. nonce: sdfkja +.. section: Library + +:class:`contextlib.suppress` now supports suppressing exceptions raised as +part of a :exc:`BaseExceptionGroup`, in addition to the recent support for +:exc:`ExceptionGroup`. + +.. + +.. date: 2023-11-08-23-32-03 +.. gh-issue: 111835 +.. nonce: ufFiuW +.. section: Library + +The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.seekable` method +that can be used where it requires a file-like object with seekable and the +:meth:`~mmap.mmap.seek` method return the new absolute position. Patch by +Donghee Na. + +.. + +.. date: 2023-11-08-15-58-57 +.. gh-issue: 111804 +.. nonce: uAXTOL +.. section: Library + +Remove posix.fallocate() under WASI as the underlying posix_fallocate() is +not available in WASI preview2. + +.. + +.. date: 2023-11-08-11-50-49 +.. gh-issue: 111841 +.. nonce: iSqdQf +.. section: Library + +Fix truncating arguments on an embedded null character in :meth:`os.putenv` +and :meth:`os.unsetenv` on Windows. + +.. + +.. date: 2023-11-08-07-42-53 +.. gh-issue: 111768 +.. nonce: g-WpnV +.. section: Library + +:func:`wsgiref.util.is_hop_by_hop` is now exposed correctly in ``__all__``. + +.. + +.. date: 2023-11-04-21-12-27 +.. gh-issue: 80731 +.. nonce: Wq51xg +.. section: Library + +Avoid executing the default function in :class:`cmd.Cmd` in an except block + +.. + +.. date: 2023-11-04-10-24-25 +.. gh-issue: 111541 +.. nonce: x0RBI1 +.. section: Library + +Fix :mod:`doctest` for :exc:`SyntaxError` not-builtin subclasses. + +.. + +.. date: 2023-11-04-01-20-23 +.. gh-issue: 111719 +.. nonce: fUiKBD +.. section: Library + +Add extra argument validation for ``alias`` command in :mod:`pdb` + +.. + +.. date: 2023-11-02-12-15-46 +.. gh-issue: 111482 +.. nonce: FWqZIU +.. section: Library + +:mod:`time`: Make :func:`time.clock_gettime()` and +:func:`time.clock_gettime_ns()` functions up to 2x faster by faster calling +convention. Patch by Victor Stinner. + +.. + +.. date: 2023-11-01-14-03-24 +.. gh-issue: 110894 +.. nonce: 7-wZxC +.. section: Library + +Call loop exception handler for exceptions in ``client_connected_cb`` of +:func:`asyncio.start_server` so that applications can handle it. Patch by +Kumar Aditya. + +.. + +.. date: 2023-10-31-07-46-56 +.. gh-issue: 111531 +.. nonce: 6zUV_G +.. section: Library + +Fix reference leaks in ``bind_class()`` and ``bind_all()`` methods of +:mod:`tkinter` widgets. + +.. + +.. date: 2023-10-30-14-47-23 +.. gh-issue: 111246 +.. nonce: QJ_ehs +.. section: Library + +:meth:`asyncio.loop.create_unix_server` will now automatically remove the +Unix socket when the server is closed. + +.. + +.. date: 2023-10-30-08-50-46 +.. gh-issue: 111356 +.. nonce: Bc8LvA +.. section: Library + +Added :func:`io.text_encoding()`, :data:`io.DEFAULT_BUFFER_SIZE`, and +:class:`io.IncrementalNewlineDecoder` to ``io.__all__``. + +.. + +.. date: 2023-10-29-03-46-27 +.. gh-issue: 66425 +.. nonce: FWTdDo +.. section: Library + +Remove the code to set the REMOTE_HOST header from wsgiref module, as it is +unreachable. This header is used for performance reasons, which is not +necessary in the wsgiref module. + +.. + +.. date: 2023-10-28-22-11-11 +.. gh-issue: 111429 +.. nonce: mJGxuQ +.. section: Library + +Speed up :meth:`pathlib.PurePath.relative_to` and +:meth:`~pathlib.PurePath.is_relative_to`. + +.. + +.. date: 2023-10-28-04-21-17 +.. gh-issue: 111342 +.. nonce: m8Ln1k +.. section: Library + +Fixed typo in :func:`math.sumprod`. + +.. + +.. date: 2023-10-27-12-46-56 +.. gh-issue: 68166 +.. nonce: 0EbWW4 +.. section: Library + +Remove mention of not supported "vsapi" element type in +:meth:`tkinter.ttk.Style.element_create`. Add tests for ``element_create()`` +and other ``ttk.Style`` methods. Add examples for ``element_create()`` in +the documentation. + +.. + +.. date: 2023-10-27-09-56-20 +.. gh-issue: 111388 +.. nonce: SlmDbC +.. section: Library + +Add ``show_group`` parameter to :func:`traceback.format_exception_only`, +which allows to format :exc:`ExceptionGroup` instances. + +.. + +.. date: 2023-10-25-11-54-00 +.. gh-issue: 79033 +.. nonce: 5ePgFl +.. section: Library + +Another attempt at fixing :func:`asyncio.Server.wait_closed()`. It now +blocks until both conditions are true: the server is closed, *and* there are +no more active connections. (This means that in some cases where in 3.12.0 +this function would *incorrectly* have returned immediately, it will now +block; in particular, when there are no active connections but the server +hasn't been closed yet.) + +.. + +.. date: 2023-10-25-11-13-35 +.. gh-issue: 111259 +.. nonce: z7ndeA +.. section: Library + +Optimize recursive wildcards in :mod:`pathlib`. + +.. + +.. date: 2023-10-25-08-42-05 +.. gh-issue: 111295 +.. nonce: H2K4lf +.. section: Library + +Fix :mod:`time` not checking for errors when initializing. + +.. + +.. date: 2023-10-24-12-20-46 +.. gh-issue: 111253 +.. nonce: HFywSK +.. section: Library + +Add error checking during :mod:`!_socket` module init. + +.. + +.. date: 2023-10-24-12-09-46 +.. gh-issue: 111251 +.. nonce: urFYtn +.. section: Library + +Fix :mod:`_blake2` not checking for errors when initializing. + +.. + +.. date: 2023-10-23-23-14-54 +.. gh-issue: 111233 +.. nonce: sCdCC0 +.. section: Library + +Fix :mod:`select` not checking for errors when initializing. + +.. + +.. date: 2023-10-23-22-40-47 +.. gh-issue: 111230 +.. nonce: k3Jm84 +.. section: Library + +Fix :mod:`ssl` not checking for errors when initializing. + +.. + +.. date: 2023-10-23-13-53-58 +.. gh-issue: 111174 +.. nonce: Oohmzd +.. section: Library + +Fix crash in :meth:`io.BytesIO.getbuffer` called repeatedly for empty +BytesIO. + +.. + +.. date: 2023-10-22-21-28-05 +.. gh-issue: 111187 +.. nonce: _W11Ab +.. section: Library + +Postpone removal version for locale.getdefaultlocale() to Python 3.15. + +.. + +.. date: 2023-10-21-13-57-06 +.. gh-issue: 111159 +.. nonce: GoHp7s +.. section: Library + +Fix :mod:`doctest` output comparison for exceptions with notes. + +.. + +.. date: 2023-10-20-15-29-10 +.. gh-issue: 110910 +.. nonce: u2oPwX +.. section: Library + +Fix invalid state handling in :class:`asyncio.TaskGroup` and +:class:`asyncio.Timeout`. They now raise proper RuntimeError if they are +improperly used and are left in consistent state after this. + +.. + +.. date: 2023-10-19-22-46-34 +.. gh-issue: 111092 +.. nonce: hgut12 +.. section: Library + +Make turtledemo run without default root enabled. + +.. + +.. date: 2023-10-16-18-41-51 +.. gh-issue: 110944 +.. nonce: CmUKXo +.. section: Library + +Support alias and convenience vars for :mod:`pdb` completion + +.. + +.. date: 2023-10-15-08-08-26 +.. gh-issue: 110745 +.. nonce: mxEkh0 +.. section: Library + +Added *newline* parameter to :meth:`pathlib.Path.read_text`. Patch by Junya +Okabe. + +.. + +.. date: 2023-10-14-21-33-57 +.. gh-issue: 84583 +.. nonce: -Cmn4_ +.. section: Library + +Make :mod:`pdb` enter post-mortem mode even for :exc:`SyntaxError` + +.. + +.. date: 2023-10-14-20-15-53 +.. gh-issue: 80675 +.. nonce: _M-cQC +.. section: Library + +Set ``f_trace_lines = True`` on all frames upon :func:`pdb.set_trace()` + +.. + +.. date: 2023-10-13-06-47-20 +.. gh-issue: 110771 +.. nonce: opwdlc +.. section: Library + +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. + +.. + +.. date: 2023-10-12-15-16-44 +.. gh-issue: 110774 +.. nonce: AdCb5A +.. section: Library + +Support setting the :class:`asyncio.Runner` loop_factory kwarg in +:class:`unittest.IsolatedAsyncioTestCase` + +.. + +.. date: 2023-10-10-17-56-41 +.. gh-issue: 110392 +.. nonce: 6g6CnP +.. section: Library + +Fix :func:`tty.setraw` and :func:`tty.setcbreak`: previously they returned +partially modified list of the original tty attributes. +:func:`tty.cfmakeraw` and :func:`tty.cfmakecbreak` now make a copy of the +list of special characters before modifying it. + +.. + +.. date: 2023-10-09-23-59-04 +.. gh-issue: 59013 +.. nonce: qPbS-G +.. section: Library + +Make line number of function breakpoint more precise in :mod:`pdb` + +.. + +.. date: 2023-10-08-18-38-09 +.. gh-issue: 88434 +.. nonce: 2Q_IkG +.. section: Library + +Emit deprecation warning for non-integer numbers in :mod:`gettext` functions +and methods that consider plural forms even if the translation was not +found. + +.. + +.. date: 2023-10-08-14-17-06 +.. gh-issue: 110395 +.. nonce: _tdCsV +.. section: Library + +Ensure that :func:`select.kqueue` objects correctly appear as closed in +forked children, to prevent operations on an invalid file descriptor. + +.. + +.. date: 2023-10-02-05-23-27 +.. gh-issue: 110196 +.. nonce: djwt0z +.. section: Library + +Add ``__reduce__`` method to :class:`IPv6Address` in order to keep +``scope_id`` + +.. + +.. date: 2023-09-25-20-05-41 +.. gh-issue: 109747 +.. nonce: _cRJH8 +.. section: Library + +Improve errors for unsupported look-behind patterns. Now re.error is raised +instead of OverflowError or RuntimeError for too large width of look-behind +pattern. + +.. + +.. date: 2023-09-15-12-30-21 +.. gh-issue: 109466 +.. nonce: 6ah-aw +.. section: Library + +Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which retuns the +IPv4-mapped IPv6 address. + +.. + +.. date: 2023-09-08-12-10-10 +.. gh-issue: 85098 +.. nonce: DfQbeJ +.. section: Library + +Implement the CLI of the :mod:`symtable` module and improve the repr of +:class:`~symtable.Symbol`. + +.. + +.. date: 2023-09-02-16-07-23 +.. gh-issue: 108791 +.. nonce: fBcAqh +.. section: Library + +Improved error handling in :mod:`pdb` command line interface, making it +produce more concise error messages. + +.. + +.. date: 2023-08-30-19-10-35 +.. gh-issue: 105931 +.. nonce: Lpwve8 +.. section: Library + +Change :mod:`compileall` to only strip the stripdir prefix from the full +path recorded in the compiled ``.pyc`` file, when the prefix matches the +start of the full path in its entirety. When the prefix does not match, no +stripping is performed and a warning to this effect is displayed. + +Previously all path components of the stripdir prefix that matched the full +path were removed, while those that did not match were left alone (including +ones interspersed between matching components). + +.. + +.. date: 2023-07-29-19-00-39 +.. gh-issue: 107431 +.. nonce: 1GzJ2p +.. section: Library + +Make the ``DictProxy`` and ``ListProxy`` types in +:mod:`multiprocessing.managers` :ref:`Generic Alias +Types` for ``[]`` use in typing contexts. + +.. + +.. date: 2023-07-13-00-24-52 +.. gh-issue: 72904 +.. nonce: Yn5-j0 +.. section: Library + +Add :func:`glob.translate`. This function converts a pathname with +shell-style wildcards to a regular expression. + +.. + +.. date: 2023-05-30-02-01-14 +.. gh-issue: 90026 +.. nonce: FyCXw8 +.. section: Library + +Define ``USE_XATTRS`` on Cygwin so that XATTR-related functions in the +:mod:`os` module become available. + +.. + +.. date: 2023-04-26-16-37-00 +.. gh-issue: 90890 +.. nonce: fIag4w +.. section: Library + +New methods :meth:`mailbox.Maildir.get_info`, +:meth:`mailbox.Maildir.set_info`, :meth:`mailbox.Maildir.get_flags`, +:meth:`mailbox.Maildir.set_flags`, :meth:`mailbox.Maildir.add_flag`, +:meth:`mailbox.Maildir.remove_flag`. These methods speed up accessing a +message's info and/or flags and are useful when it is not necessary to +access the message's contents, as when iterating over a Maildir to find +messages with specific flags. + +.. + +.. date: 2023-04-15-14-45-21 +.. gh-issue: 102956 +.. nonce: Z6qeUy +.. section: Library + +Fix returning of empty byte strings after seek in zipfile module + +.. + +.. date: 2023-03-22-02-01-30 +.. gh-issue: 102895 +.. nonce: HiEqaZ +.. section: Library + +Added a parameter ``local_exit`` for :func:`code.interact` to prevent +``exit()`` and ``quit`` from closing ``sys.stdin`` and raise ``SystemExit``. + +.. + +.. date: 2022-10-14-21-11-10 +.. gh-issue: 97928 +.. nonce: Pdxh1G +.. section: Library + +Change the behavior of :meth:`tkinter.Text.count`. It now always returns an +integer if one or less counting options are specified. Previously it could +return a single count as a 1-tuple, an integer (only if option ``"update"`` +was specified) or ``None`` if no items found. The result is now the same if +``wantobjects`` is set to ``0``. + +.. + +.. date: 2022-10-05-15-01-36 +.. gh-issue: 96954 +.. nonce: ezwkrU +.. section: Library + +Switch the storage of the unicode codepoint names to use a different +data-structure, a `directed acyclic word graph +`_. +This makes the unicodedata shared library about 440 KiB smaller. Contributed +by Carl Friedrich Bolz-Tereick using code from the PyPy project. + +.. + +.. date: 2022-05-28-20-55-07 +.. gh-issue: 73561 +.. nonce: YRmAvy +.. section: Library + +Omit the interface scope from an IPv6 address when used as Host header by +:mod:`http.client`. + +.. + +.. date: 2022-05-06-15-49-57 +.. gh-issue: 86826 +.. nonce: rf006W +.. section: Library + +:mod:`zipinfo` now supports the full range of values in the TZ string +determined by RFC 8536 and detects all invalid formats. Both Python and C +implementations now raise exceptions of the same type on invalid data. + +.. + +.. date: 2023-11-17-15-20-41 +.. gh-issue: 111808 +.. nonce: jtIayt +.. section: Tests + +Make the default value of ``test.support.infinite_recursion()`` to be +conditional based on whether optimizations were used when compiling the +interpreter. This helps with platforms like WASI whose stack size is greatly +restricted in debug builds. + +.. + +.. date: 2023-11-03-18-59-13 +.. gh-issue: 110722 +.. nonce: jvT1pb +.. section: Tests + +Gathering line coverage of standard libraries within the regression test +suite is now precise, as well as much faster. Patch by Łukasz Langa. + +.. + +.. date: 2023-10-31-22-09-25 +.. gh-issue: 110367 +.. nonce: UhQi44 +.. section: Tests + +Make regrtest ``--verbose3`` option compatible with ``--huntrleaks -jN`` +options. The ``./python -m test -j1 -R 3:3 --verbose3`` command now works as +expected. Patch by Victor Stinner. + +.. + +.. date: 2023-10-21-19-27-36 +.. gh-issue: 111165 +.. nonce: FU6mUk +.. section: Tests + +Remove no longer used functions ``run_unittest()`` and ``run_doctest()`` +from the :mod:`test.support` module. + +.. + +.. date: 2023-10-21-00-10-36 +.. gh-issue: 110932 +.. nonce: jktjJU +.. section: Tests + +Fix regrtest if the ``SOURCE_DATE_EPOCH`` environment variable is defined: +use the variable value as the random seed. Patch by Victor Stinner. + +.. + +.. date: 2023-10-17-17-54-36 +.. gh-issue: 110995 +.. nonce: Fx8KRD +.. section: Tests + +test_gdb: Fix detection of gdb built without Python scripting support. Patch +by Victor Stinner. + +.. + +.. date: 2023-10-16-13-47-24 +.. gh-issue: 110918 +.. nonce: aFgZK3 +.. section: Tests + +Test case matching patterns specified by options ``--match``, ``--ignore``, +``--matchfile`` and ``--ignorefile`` are now tested in the order of +specification, and the last match determines whether the test case be run or +ignored. + +.. + +.. date: 2023-09-15-15-00-14 +.. gh-issue: 108747 +.. nonce: ql0owS +.. section: Tests + +Add unit test for ``usercustomize`` and ``sitecustomize`` hooks from +:class:`site`. + +.. + +.. date: 2023-11-15-16-56-20 +.. gh-issue: 96954 +.. nonce: 6FYvKn +.. section: Build + +Make ``make regen-unicodedata`` work for out-of-tree builds of CPython. + +.. + +.. date: 2023-11-15-13-40-29 +.. gh-issue: 112088 +.. nonce: UJQxxh +.. section: Build + +Add ``Tools/build/regen-configure.sh`` script to regenerate the +``configure`` with an Ubuntu container image. The +``quay.io/tiran/cpython_autoconf:271`` container image +(`tiran/cpython_autoconf `_) is +no longer used. Patch by Victor Stinner. + +.. + +.. date: 2023-10-20-15-29-31 +.. gh-issue: 111046 +.. nonce: 2DxQl8 +.. section: Build + +For wasi-threads, memory is now exported to fix compatibility issues with +some wasm runtimes. + +.. + +.. date: 2023-10-17-03-10-40 +.. gh-issue: 110828 +.. nonce: 31vQ9B +.. section: Build + +AIX 32bit needs ``-latomic`` to build the :mod:`!_testcapi` extension +module. + +.. + +.. date: 2023-10-17-01-56-11 +.. gh-issue: 85283 +.. nonce: V156T2 +.. section: Build + +The ``errno``, ``md5``, ``resource``, ``winsound``, ``_ctypes_test``, +``_multiprocessing.posixshmem``, ``_scproxy``, ``_stat``, +``_testimportmultiple`` and ``_uuid`` C extensions are now built with the +:ref:`limited C API `. Patch by Victor Stinner. + +.. + +.. date: 2023-11-13-22-35-27 +.. gh-issue: 111856 +.. nonce: vEtA5z +.. section: Windows + +Fixes :func:`~os.fstat` on file systems that do not support file ID +requests. This includes FAT32 and exFAT. + +.. + +.. date: 2023-10-25-05-01-28 +.. gh-issue: 111293 +.. nonce: FSsLT6 +.. section: Windows + +Fix :data:`os.DirEntry.inode` dropping higher 64 bits of a file id on some +filesystems on Windows. + +.. + +.. date: 2023-10-19-21-46-18 +.. gh-issue: 110913 +.. nonce: CWlPfg +.. section: Windows + +WindowsConsoleIO now correctly chunks large buffers without splitting up +UTF-8 sequences. + +.. + +.. date: 2023-10-31-22-13-05 +.. gh-issue: 59703 +.. nonce: SML6Ag +.. section: macOS + +For macOS framework builds, in ``getpath.c`` use the system ``dladdr`` +function to find the path to the shared library rather than depending on +deprecated macOS APIs. + +.. + +.. date: 2023-10-18-17-26-36 +.. gh-issue: 110950 +.. nonce: sonoma +.. section: macOS + +Update macOS installer to include an upstream Tcl/Tk fix for the ``Secure +coding is not enabled for restorable state!`` warning encountered in Tkinter +on macOS 14 Sonoma. + +.. + +.. date: 2023-10-18-01-40-36 +.. gh-issue: 111015 +.. nonce: NaLI2L +.. section: macOS + +Ensure that IDLE.app and Python Launcher.app are installed with appropriate +permissions on macOS builds. + +.. + +.. date: 2023-09-02-08-49-57 +.. gh-issue: 71383 +.. nonce: Ttkchg +.. section: macOS + +Update macOS installer to include an upstream Tcl/Tk fix for the +``ttk::ThemeChanged`` error encountered in Tkinter. + +.. + +.. date: 2023-08-30-16-33-57 +.. gh-issue: 92603 +.. nonce: ATkKVO +.. section: macOS + +Update macOS installer to include a fix accepted by upstream Tcl/Tk for a +crash encountered after the first :meth:`tkinter.Tk` instance is destroyed. + +.. + +.. bpo: 35668 +.. date: 2019-01-07-06-18-25 +.. nonce: JimxP5 +.. section: IDLE + +Add docstrings to the IDLE debugger module. Fix two bugs: initialize +Idb.botframe (should be in Bdb); in Idb.in_rpc_code, check whether +prev_frame is None before trying to use it. Greatly expand test_debugger. + +.. + +.. date: 2023-11-09-13-04-29 +.. gh-issue: 111903 +.. nonce: 7Prryr +.. section: Tools/Demos + +Argument Clinic now supports the ``@critical_section`` directive that +instructs Argument Clinic to generate a critical section around the function +call, which locks the ``self`` object in ``--disable-gil`` builds. Patch by +Sam Gross. + +.. + +.. date: 2023-11-15-18-36-21 +.. gh-issue: 112026 +.. nonce: _Yybr5 +.. section: C API + +Add again the private ``_PyThreadState_UncheckedGet()`` function as an alias +to the new public :c:func:`PyThreadState_GetUnchecked` function. Patch by +Victor Stinner. + +.. + +.. date: 2023-11-15-17-10-09 +.. gh-issue: 112026 +.. nonce: ts9yyn +.. section: C API + +Restore the removed ``_PyDict_GetItemStringWithError()`` function. It is +used by numpy. Patch by Victor Stinner. + +.. + +.. date: 2023-11-15-16-07-57 +.. gh-issue: 112026 +.. nonce: bnr8dd +.. section: C API + +Restore removed private C API functions, macros and structures which have no +simple replacement for now: + +* _PyDict_GetItem_KnownHash() +* _PyDict_NewPresized() +* _PyHASH_BITS +* _PyHASH_IMAG +* _PyHASH_INF +* _PyHASH_MODULUS +* _PyHASH_MULTIPLIER +* _PyLong_Copy() +* _PyLong_FromDigits() +* _PyLong_New() +* _PyLong_Sign() +* _PyObject_CallMethodId() +* _PyObject_CallMethodNoArgs() +* _PyObject_CallMethodOneArg() +* _PyObject_CallOneArg() +* _PyObject_EXTRA_INIT +* _PyObject_FastCallDict() +* _PyObject_GetAttrId() +* _PyObject_Vectorcall() +* _PyObject_VectorcallMethod() +* _PyStack_AsDict() +* _PyThread_CurrentFrames() +* _PyUnicodeWriter structure +* _PyUnicodeWriter_Dealloc() +* _PyUnicodeWriter_Finish() +* _PyUnicodeWriter_Init() +* _PyUnicodeWriter_Prepare() +* _PyUnicodeWriter_PrepareKind() +* _PyUnicodeWriter_WriteASCIIString() +* _PyUnicodeWriter_WriteChar() +* _PyUnicodeWriter_WriteLatin1String() +* _PyUnicodeWriter_WriteStr() +* _PyUnicodeWriter_WriteSubstring() +* _PyUnicode_AsString() +* _PyUnicode_FromId() +* _PyVectorcall_Function() +* _Py_IDENTIFIER() +* _Py_c_abs() +* _Py_c_diff() +* _Py_c_neg() +* _Py_c_pow() +* _Py_c_prod() +* _Py_c_quot() +* _Py_c_sum() +* _Py_static_string() +* _Py_static_string_init() + +Patch by Victor Stinner. + +.. + +.. date: 2023-11-13-17-57-11 +.. gh-issue: 112026 +.. nonce: WJLJcI +.. section: C API + +Add again ```` and ```` includes in ``Python.h``, but +don't include them in the limited C API version 3.13 and newer. Patch by +Victor Stinner. + +.. + +.. date: 2023-11-10-10-24-28 +.. gh-issue: 111956 +.. nonce: ImE6Cx +.. section: C API + +Add internal-only one-time initialization API: ``_PyOnceFlag`` and +``_PyOnceFlag_CallOnce``. + +.. + +.. date: 2023-11-10-10-21-38 +.. gh-issue: 111262 +.. nonce: 2utB5m +.. section: C API + +Add :c:func:`PyDict_Pop` and :c:func:`PyDict_PopString` functions: remove a +key from a dictionary and optionally return the removed value. This is +similar to :meth:`dict.pop`, but without the default value and not raising +:exc:`KeyError` if the key missing. Patch by Stefan Behnel and Victor +Stinner. + +.. + +.. date: 2023-11-08-20-28-03 +.. gh-issue: 111863 +.. nonce: RPeFAX +.. section: C API + +Rename ``Py_NOGIL`` to ``Py_GIL_DISABLED``. Patch by Hugo van Kemenade. + +.. + +.. date: 2023-11-08-18-37-19 +.. gh-issue: 111138 +.. nonce: 3Ypq8h +.. section: C API + +Add :c:func:`PyList_Extend` and :c:func:`PyList_Clear` functions: similar to +Python ``list.extend()`` and ``list.clear()`` methods. Patch by Victor +Stinner. + +.. + +.. date: 2023-10-31-18-22-03 +.. gh-issue: 108765 +.. nonce: _beYv8 +.. section: C API + +On Windows, ``Python.h`` no longer includes the ```` standard +header file. If needed, it should now be included explicitly. Patch by +Victor Stinner. + +.. + +.. date: 2023-10-31-14-58-17 +.. gh-issue: 111569 +.. nonce: _V8iu4 +.. section: C API + +Implement "Python Critical Sections" from :pep:`703`. These are macros to +help replace the GIL with per-object locks in the ``--disable-gil`` build of +CPython. The macros are no-ops in the default build. + +.. + +.. date: 2023-10-30-18-13-01 +.. gh-issue: 111506 +.. nonce: EUdO22 +.. section: C API + +In the limited C API version 3.13, :c:func:`Py_SET_REFCNT` function is now +implemented as an opaque function call. Patch by Victor Stinner. + +.. + +.. date: 2023-10-19-22-39-24 +.. gh-issue: 108082 +.. nonce: uJytvc +.. section: C API + +Add :c:func:`PyErr_FormatUnraisable` function. + +.. + +.. date: 2023-10-17-10-21-59 +.. gh-issue: 110964 +.. nonce: OxqEjd +.. section: C API + +Move the undocumented private _PyArg functions and _PyArg_Parser structure +to internal C API (``pycore_modsupport.h``). Patch by Victor Stinner. + +.. + +.. date: 2023-10-13-14-18-06 +.. gh-issue: 110815 +.. nonce: tEFLVl +.. section: C API + +Support non-ASCII keyword names in :c:func:`PyArg_ParseTupleAndKeywords`. + +.. + +.. date: 2023-10-02-23-08-53 +.. gh-issue: 109587 +.. nonce: UqqnDY +.. section: C API + +Introduced :c:func:`PyUnstable_PerfTrampoline_CompileCode`, +:c:func:`PyUnstable_PerfTrampoline_SetPersistAfterFork` and +:c:func:`PyUnstable_CopyPerfMapFile`. These functions allow extension +modules to initialize trampolines eagerly, after the application is "warmed +up". This makes it possible to have perf-trampolines running in an +always-enabled fashion. + +.. + +.. date: 2023-08-28-17-40-51 +.. gh-issue: 85283 +.. nonce: raFNiD +.. section: C API + +Add the :c:func:`PySys_Audit` function to the limited C API. Patch by Victor +Stinner. + +.. + +.. date: 2023-08-28-17-34-10 +.. gh-issue: 85283 +.. nonce: f1zXcc +.. section: C API + +Add :c:func:`PyMem_RawMalloc`, :c:func:`PyMem_RawCalloc`, +:c:func:`PyMem_RawRealloc` and :c:func:`PyMem_RawFree` to the limited C API. +Patch by Victor Stinner. + +.. + +.. date: 2023-07-12-12-14-52 +.. gh-issue: 106672 +.. nonce: fkRjmi +.. section: C API + +Functions :c:func:`PyDict_GetItem`, :c:func:`PyDict_GetItemString`, +:c:func:`PyMapping_HasKey`, :c:func:`PyMapping_HasKeyString`, +:c:func:`PyObject_HasAttr`, :c:func:`PyObject_HasAttrString`, and +:c:func:`PySys_GetObject`, which clear all errors occurred during calling +the function, report now them using :func:`sys.unraisablehook`. + +.. + +.. date: 2023-06-08-21-12-44 +.. gh-issue: 67565 +.. nonce: UkK3x- +.. section: C API + +Remove redundant C-contiguity check in :file:`getargs.c`, :mod:`binascii`, +:mod:`ssl` and Argument Clinic. Patched by Stefan Krah and Furkan Onder diff --git a/Misc/NEWS.d/3.6.0a2.rst b/Misc/NEWS.d/3.6.0a2.rst index 1b336d7bc5137a..05b3d9f0463c1c 100644 --- a/Misc/NEWS.d/3.6.0a2.rst +++ b/Misc/NEWS.d/3.6.0a2.rst @@ -603,7 +603,7 @@ configuring text widget colors to a new function. .. nonce: RbyFuV .. section: IDLE -Rename many `idlelib/*.py` and `idle_test/test_*.py` files. Edit files to +Rename many ``idlelib/*.py`` and ``idle_test/test_*.py`` files. Edit files to replace old names with new names when the old name referred to the module rather than the class it contained. See the issue and IDLE section in What's New in 3.6 for more. diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst index 3cbbbf7465032b..2b9dbd5d63a87e 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. .. @@ -3592,7 +3592,7 @@ Python 3.5. .. nonce: V8Ou3K .. section: Library -Deprecate :meth:`__getitem__` methods of +Deprecate :meth:`~object.__getitem__` methods of :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` and :class:`fileinput.FileInput`. diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst index 9818c17705074b..0444b53895b166 100644 --- a/Misc/NEWS.d/3.9.0a1.rst +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -2534,7 +2534,7 @@ object when `self._spec_signature` exists. Patch by Elizabeth Uselton .. nonce: iXGuoi .. section: Library -Make `from tkinter import *` import only the expected objects. +Make ``from tkinter import *`` import only the expected objects. .. @@ -3117,9 +3117,9 @@ Ensure cookies with ``expires`` attribute are handled in .. section: Library Fix an unintended ValueError from :func:`subprocess.run` when checking for -conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` -args when they were explicitly provided but with `None` values within a -passed in `**kwargs` dict rather than as passed directly by name. Patch +conflicting *input* and *stdin* or *capture_output* and *stdout* or *stderr* +args when they were explicitly provided but with ``None`` values within a +passed in ``**kwargs`` dict rather than as passed directly by name. Patch contributed by Rémi Lapeyre. .. @@ -3546,7 +3546,7 @@ Patch by Stein Karlsen. .. nonce: XaJDei .. section: Library -lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or +lib2to3 now recognizes expressions after ``*`` and ``**`` like in ``f(*[] or [])``. .. 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/Build/2023-07-23-00-38-51.gh-issue-106962.VVYrWB.rst b/Misc/NEWS.d/next/Build/2023-07-23-00-38-51.gh-issue-106962.VVYrWB.rst deleted file mode 100644 index 32e196fe26d3b7..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-07-23-00-38-51.gh-issue-106962.VVYrWB.rst +++ /dev/null @@ -1 +0,0 @@ -Detect MPI compilers in :file:`configure`. diff --git a/Misc/NEWS.d/next/Build/2023-07-25-02-30-00.gh-issue-95855.wA7rAf.rst b/Misc/NEWS.d/next/Build/2023-07-25-02-30-00.gh-issue-95855.wA7rAf.rst deleted file mode 100644 index fdc8b33f1de5dc..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-07-25-02-30-00.gh-issue-95855.wA7rAf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Refactor platform triplet detection code and add detection for MIPS soft -float and musl libc. diff --git a/Misc/NEWS.d/next/Build/2023-07-28-18-17-33.gh-issue-106881.U3Ezdq.rst b/Misc/NEWS.d/next/Build/2023-07-28-18-17-33.gh-issue-106881.U3Ezdq.rst deleted file mode 100644 index 7febf99c48a79b..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-07-28-18-17-33.gh-issue-106881.U3Ezdq.rst +++ /dev/null @@ -1 +0,0 @@ -Check for ``linux/limits.h`` before including it in ``Modules/posixmodule.c``. diff --git a/Misc/NEWS.d/next/Build/2023-08-01-17-12-53.gh-issue-105481.42nsDE.rst b/Misc/NEWS.d/next/Build/2023-08-01-17-12-53.gh-issue-105481.42nsDE.rst deleted file mode 100644 index 1e61c37b609469..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-08-01-17-12-53.gh-issue-105481.42nsDE.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Build/2023-08-09-17-05-33.gh-issue-107814.c0Oapq.rst b/Misc/NEWS.d/next/Build/2023-08-09-17-05-33.gh-issue-107814.c0Oapq.rst deleted file mode 100644 index d3723353470ce2..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-08-09-17-05-33.gh-issue-107814.c0Oapq.rst +++ /dev/null @@ -1 +0,0 @@ -When calling ``find_python.bat`` with ``-q`` it did not properly silence the output of nuget. That is now fixed. diff --git a/Misc/NEWS.d/next/Build/2023-08-24-18-36-31.gh-issue-108447.Ofsygr.rst b/Misc/NEWS.d/next/Build/2023-08-24-18-36-31.gh-issue-108447.Ofsygr.rst deleted file mode 100644 index a695ef503e406e..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-08-24-18-36-31.gh-issue-108447.Ofsygr.rst +++ /dev/null @@ -1 +0,0 @@ -Fix x86_64 GNU/Hurd build diff --git a/Misc/NEWS.d/next/Build/2023-08-30-02-52-52.gh-issue-108634.3dpBvf.rst b/Misc/NEWS.d/next/Build/2023-08-30-02-52-52.gh-issue-108634.3dpBvf.rst deleted file mode 100644 index d1530787067d42..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-08-30-02-52-52.gh-issue-108634.3dpBvf.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Build/2023-09-01-01-39-26.gh-issue-108740.JHExAQ.rst b/Misc/NEWS.d/next/Build/2023-09-01-01-39-26.gh-issue-108740.JHExAQ.rst deleted file mode 100644 index 190d50387f339e..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-09-01-01-39-26.gh-issue-108740.JHExAQ.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Build/2023-09-02-18-04-15.gh-issue-63760.r8hJ6q.rst b/Misc/NEWS.d/next/Build/2023-09-02-18-04-15.gh-issue-63760.r8hJ6q.rst deleted file mode 100644 index 9a7249e923e0c7..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-09-02-18-04-15.gh-issue-63760.r8hJ6q.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst b/Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst deleted file mode 100644 index d86a110e0de68c..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-09-07-19-58-05.gh-issue-109054.5r3S3l.rst +++ /dev/null @@ -1,6 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Build/2023-09-26-16-00-50.gh-issue-109740.wboWdQ.rst b/Misc/NEWS.d/next/Build/2023-09-26-16-00-50.gh-issue-109740.wboWdQ.rst deleted file mode 100644 index f59f462aecd1fc..00000000000000 --- a/Misc/NEWS.d/next/Build/2023-09-26-16-00-50.gh-issue-109740.wboWdQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -The experimental ``--disable-gil`` configure flag now includes "t" (for "threaded") in -extension ABI tags. diff --git a/Misc/NEWS.d/next/Build/2023-11-27-13-55-47.gh-issue-103065.o72OiA.rst b/Misc/NEWS.d/next/Build/2023-11-27-13-55-47.gh-issue-103065.o72OiA.rst new file mode 100644 index 00000000000000..e2240b7c656a2f --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-11-27-13-55-47.gh-issue-103065.o72OiA.rst @@ -0,0 +1 @@ +Introduce ``Tools/wasm/wasi.py`` to simplify doing a WASI build. diff --git a/Misc/NEWS.d/next/Build/2023-12-08-11-33-37.gh-issue-112867.ZzDfXQ.rst b/Misc/NEWS.d/next/Build/2023-12-08-11-33-37.gh-issue-112867.ZzDfXQ.rst new file mode 100644 index 00000000000000..a36814854882bb --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-12-08-11-33-37.gh-issue-112867.ZzDfXQ.rst @@ -0,0 +1 @@ +Fix the build for the case that WITH_PYMALLOC_RADIX_TREE=0 set. 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 bcea7a1f9825b1..00000000000000 --- a/Misc/NEWS.d/next/C API/2020-11-11-22-36-29.bpo-42327.ODSZBM.rst +++ /dev/null @@ -1 +0,0 @@ -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. 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 536e484116690d..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 :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. 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-21-11-53-09.gh-issue-65210.PhFRBJ.rst b/Misc/NEWS.d/next/C API/2023-06-21-11-53-09.gh-issue-65210.PhFRBJ.rst new file mode 100644 index 00000000000000..a15646f4dad127 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-06-21-11-53-09.gh-issue-65210.PhFRBJ.rst @@ -0,0 +1,3 @@ +Change the declaration of the *keywords* parameter of +:c:func:`PyArg_ParseTupleAndKeywords` and +:c:func:`PyArg_VaParseTupleAndKeywords` for better compatibility with C++. 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-23-02-57-15.gh-issue-106004.-OToh6.rst b/Misc/NEWS.d/next/C API/2023-06-23-02-57-15.gh-issue-106004.-OToh6.rst deleted file mode 100644 index c7a006b2bc0759..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-06-23-02-57-15.gh-issue-106004.-OToh6.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. 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/C API/2023-07-22-14-40-48.gh-issue-106320.H3u7x4.rst b/Misc/NEWS.d/next/C API/2023-07-22-14-40-48.gh-issue-106320.H3u7x4.rst deleted file mode 100644 index 1e0ba0d71e7555..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-22-14-40-48.gh-issue-106320.H3u7x4.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/C API/2023-07-25-13-41-09.gh-issue-107226.N919zH.rst b/Misc/NEWS.d/next/C API/2023-07-25-13-41-09.gh-issue-107226.N919zH.rst deleted file mode 100644 index 6178f18517d48f..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-25-13-41-09.gh-issue-107226.N919zH.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`PyModule_AddObjectRef` is now only available in the limited API -version 3.10 or later. diff --git a/Misc/NEWS.d/next/C API/2023-07-25-17-23-08.gh-issue-107249.xqk2ke.rst b/Misc/NEWS.d/next/C API/2023-07-25-17-23-08.gh-issue-107249.xqk2ke.rst deleted file mode 100644 index a7139024329fae..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-07-25-17-23-08.gh-issue-107249.xqk2ke.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement the :c:macro:`Py_UNUSED` macro for Windows MSVC compiler. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-08-10-11-12-25.gh-issue-107810.oJ40Qx.rst b/Misc/NEWS.d/next/C API/2023-08-10-11-12-25.gh-issue-107810.oJ40Qx.rst deleted file mode 100644 index c8a1f6d122b61b..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-10-11-12-25.gh-issue-107810.oJ40Qx.rst +++ /dev/null @@ -1 +0,0 @@ -Improve :exc:`DeprecationWarning` for uses of :c:type:`PyType_Spec` with metaclasses that have custom ``tp_new``. diff --git a/Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst b/Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst deleted file mode 100644 index 58ee3f169a28cc..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/C API/2023-08-14-10-59-03.gh-issue-107916.KH4Muo.rst b/Misc/NEWS.d/next/C API/2023-08-14-10-59-03.gh-issue-107916.KH4Muo.rst deleted file mode 100644 index f1f16609b118ba..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-14-10-59-03.gh-issue-107916.KH4Muo.rst +++ /dev/null @@ -1,4 +0,0 @@ -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`. diff --git a/Misc/NEWS.d/next/C API/2023-08-16-17-16-19.gh-issue-108014.wXN3CF.rst b/Misc/NEWS.d/next/C API/2023-08-16-17-16-19.gh-issue-108014.wXN3CF.rst deleted file mode 100644 index fee3d5b941dc8d..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-16-17-16-19.gh-issue-108014.wXN3CF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`Py_IsFinalizing` function: check if the main Python interpreter is -:term:`shutting down `. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-08-22-13-00-54.gh-issue-108337.wceHZm.rst b/Misc/NEWS.d/next/C API/2023-08-22-13-00-54.gh-issue-108337.wceHZm.rst deleted file mode 100644 index 476123a051bb3f..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-22-13-00-54.gh-issue-108337.wceHZm.rst +++ /dev/null @@ -1 +0,0 @@ -Add atomic operations on additional data types in pyatomic.h. diff --git a/Misc/NEWS.d/next/C API/2023-08-22-18-45-20.gh-issue-108314.nOlmwq.rst b/Misc/NEWS.d/next/C API/2023-08-22-18-45-20.gh-issue-108314.nOlmwq.rst deleted file mode 100644 index 90ae50a291b937..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-22-18-45-20.gh-issue-108314.nOlmwq.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/C API/2023-08-24-20-08-02.gh-issue-108014.20DOSS.rst b/Misc/NEWS.d/next/C API/2023-08-24-20-08-02.gh-issue-108014.20DOSS.rst deleted file mode 100644 index 35cb153ba09076..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-24-20-08-02.gh-issue-108014.20DOSS.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/C API/2023-08-30-02-54-06.gh-issue-108634.oV3Xzk.rst b/Misc/NEWS.d/next/C API/2023-08-30-02-54-06.gh-issue-108634.oV3Xzk.rst deleted file mode 100644 index 0427644ad37246..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-08-30-02-54-06.gh-issue-108634.oV3Xzk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Python built with :file:`configure` :option:`--with-trace-refs` (tracing -references) now supports the :ref:`Limited API `. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-09-01-16-28-09.gh-issue-108511.gg-QDG.rst b/Misc/NEWS.d/next/C API/2023-09-01-16-28-09.gh-issue-108511.gg-QDG.rst deleted file mode 100644 index 1e5f32905aa24d..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-01-16-28-09.gh-issue-108511.gg-QDG.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add functions :c:func:`PyObject_HasAttrWithError`, -:c:func:`PyObject_HasAttrStringWithError`, -:c:func:`PyMapping_HasKeyWithError` and -:c:func:`PyMapping_HasKeyStringWithError`. diff --git a/Misc/NEWS.d/next/C API/2023-09-01-18-42-31.gh-issue-108765.IyYNDu.rst b/Misc/NEWS.d/next/C API/2023-09-01-18-42-31.gh-issue-108765.IyYNDu.rst deleted file mode 100644 index 7b33481f225b5a..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-01-18-42-31.gh-issue-108765.IyYNDu.rst +++ /dev/null @@ -1,6 +0,0 @@ -``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. diff --git a/Misc/NEWS.d/next/C API/2023-09-01-20-41-49.gh-issue-108765.5dXc1r.rst b/Misc/NEWS.d/next/C API/2023-09-01-20-41-49.gh-issue-108765.5dXc1r.rst deleted file mode 100644 index cc512df7e1bc08..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-01-20-41-49.gh-issue-108765.5dXc1r.rst +++ /dev/null @@ -1,4 +0,0 @@ -``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. diff --git a/Misc/NEWS.d/next/C API/2023-09-01-21-10-29.gh-issue-108765.eeXtYF.rst b/Misc/NEWS.d/next/C API/2023-09-01-21-10-29.gh-issue-108765.eeXtYF.rst deleted file mode 100644 index ff8f79998fa968..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-01-21-10-29.gh-issue-108765.eeXtYF.rst +++ /dev/null @@ -1,4 +0,0 @@ -``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. diff --git a/Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst b/Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst deleted file mode 100644 index c13b6d9db053fc..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-02-22-35-55.gh-issue-108765.4TOdBT.rst +++ /dev/null @@ -1,5 +0,0 @@ -``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. diff --git a/Misc/NEWS.d/next/C API/2023-09-12-13-09-36.gh-issue-108724.-yMsC8.rst b/Misc/NEWS.d/next/C API/2023-09-12-13-09-36.gh-issue-108724.-yMsC8.rst deleted file mode 100644 index 5cddf9bc239700..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-12-13-09-36.gh-issue-108724.-yMsC8.rst +++ /dev/null @@ -1 +0,0 @@ -Add :c:type:`PyMutex` internal-only lightweight locking API. diff --git a/Misc/NEWS.d/next/C API/2023-09-17-21-47-31.gh-issue-109521.JDF6i9.rst b/Misc/NEWS.d/next/C API/2023-09-17-21-47-31.gh-issue-109521.JDF6i9.rst deleted file mode 100644 index 338650c9246686..00000000000000 --- a/Misc/NEWS.d/next/C API/2023-09-17-21-47-31.gh-issue-109521.JDF6i9.rst +++ /dev/null @@ -1,5 +0,0 @@ -: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. diff --git a/Misc/NEWS.d/next/C API/2023-11-15-01-26-59.gh-issue-111545.iAoFtA.rst b/Misc/NEWS.d/next/C API/2023-11-15-01-26-59.gh-issue-111545.iAoFtA.rst new file mode 100644 index 00000000000000..7bde2498acf999 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-11-15-01-26-59.gh-issue-111545.iAoFtA.rst @@ -0,0 +1,2 @@ +Add :c:func:`Py_HashPointer` function to hash a pointer. Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst b/Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst new file mode 100644 index 00000000000000..113119efd6aebb --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst @@ -0,0 +1,2 @@ +Fix support of format units "es", "et", "es#", and "et#" in nested tuples in +:c:func:`PyArg_ParseTuple`-like functions. diff --git a/Misc/NEWS.d/next/C API/2023-12-02-02-08-11.gh-issue-106560.THvuji.rst b/Misc/NEWS.d/next/C API/2023-12-02-02-08-11.gh-issue-106560.THvuji.rst new file mode 100644 index 00000000000000..59b461ec47ad64 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-12-02-02-08-11.gh-issue-106560.THvuji.rst @@ -0,0 +1,2 @@ +Fix redundant declarations in the public C API. Declare PyBool_Type, +PyLong_Type and PySys_Audit() only once. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-08-13-13-25-15.bpo-34392.9kIlMF.rst b/Misc/NEWS.d/next/Core and Builtins/2018-08-13-13-25-15.bpo-34392.9kIlMF.rst new file mode 100644 index 00000000000000..bc4fd1ad1f5c7c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-08-13-13-25-15.bpo-34392.9kIlMF.rst @@ -0,0 +1 @@ +Added :func:`sys._is_interned`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-07-05-37-53.gh-issue-94606.hojJ54.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-07-05-37-53.gh-issue-94606.hojJ54.rst new file mode 100644 index 00000000000000..5201ab7d842088 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-07-05-37-53.gh-issue-94606.hojJ54.rst @@ -0,0 +1,3 @@ +Fix UnicodeEncodeError when :func:`email.message.get_payload` reads a message +with a Unicode surrogate character and the message content is not well-formed for +surrogateescape encoding. Patch by Sidney Markowitz. 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-03-26-19-11-10.gh-issue-93627.0UgwBL.rst b/Misc/NEWS.d/next/Core and Builtins/2023-03-26-19-11-10.gh-issue-93627.0UgwBL.rst deleted file mode 100644 index 854da44b560b21..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-03-26-19-11-10.gh-issue-93627.0UgwBL.rst +++ /dev/null @@ -1 +0,0 @@ -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`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-04-00-40-04.gh-issue-96663.PdR9hK.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-04-00-40-04.gh-issue-96663.PdR9hK.rst deleted file mode 100644 index cb806b5ea7a9f3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-04-04-00-40-04.gh-issue-96663.PdR9hK.rst +++ /dev/null @@ -1 +0,0 @@ -Add a better, more introspect-able error message when setting attributes on classes without a ``__dict__`` and no slot member for the attribute. 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 dbfcd658d945d4..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 :c:member:`~PyTypeObject.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 417e45a6655db6..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 Donghee 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-20-10-53-17.gh-issue-105724.d23L4M.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-20-10-53-17.gh-issue-105724.d23L4M.rst deleted file mode 100644 index 281c139d1a8d1c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-20-10-53-17.gh-issue-105724.d23L4M.rst +++ /dev/null @@ -1 +0,0 @@ -Improve ``assert`` error messages by providing exact error range. 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 57a30f601379c2..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. 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-42-56.gh-issue-106213.TCUgzM.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-29-09-42-56.gh-issue-106213.TCUgzM.rst deleted file mode 100644 index 431f9cc0e4bb7d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-06-29-09-42-56.gh-issue-106213.TCUgzM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Changed the way that Emscripten call trampolines work for compatibility with -Wasm/JS Promise integration. 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 0d074ffa9942d4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-04-04-50-14.gh-issue-100288.yNQ1ez.rst +++ /dev/null @@ -1,2 +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 cc9c6e39a77fd2..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 Donghee 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-14-55-45.gh-issue-106723.KsMufQ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-13-14-55-45.gh-issue-106723.KsMufQ.rst deleted file mode 100644 index 207f397f17d3f3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-13-14-55-45.gh-issue-106723.KsMufQ.rst +++ /dev/null @@ -1 +0,0 @@ -Propagate ``frozen_modules`` to multiprocessing spawned process interpreters. 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-07-16-07-55-19.gh-issue-106485.wPb1bH.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-16-07-55-19.gh-issue-106485.wPb1bH.rst deleted file mode 100644 index 1f80082821edac..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-16-07-55-19.gh-issue-106485.wPb1bH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Reduce the number of materialized instances dictionaries by dematerializing -them when possible. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-18-16-13-51.gh-issue-106092.bObgRM.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-18-16-13-51.gh-issue-106092.bObgRM.rst deleted file mode 100644 index 7fb5b45c763e45..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-18-16-13-51.gh-issue-106092.bObgRM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a segmentation fault caused by a use-after-free bug in ``frame_dealloc`` -when the trashcan delays the deallocation of a ``PyFrameObject``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-01-15-58.gh-issue-106908.cDmcVI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-20-01-15-58.gh-issue-106908.cDmcVI.rst deleted file mode 100644 index 9c9b84599cb551..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-01-15-58.gh-issue-106908.cDmcVI.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix various hangs, reference leaks, test failures, and tracing/introspection -bugs when running with :envvar:`PYTHONUOPS` or :option:`-X uops <-X>` -enabled. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-12-21-37.gh-issue-105699.08ywGV.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-20-12-21-37.gh-issue-105699.08ywGV.rst deleted file mode 100644 index 82312718cd047e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-12-21-37.gh-issue-105699.08ywGV.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst deleted file mode 100644 index 4a257c6282220f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst +++ /dev/null @@ -1,3 +0,0 @@ -Python no longer crashes due an infrequent race when initialzing -per-interpreter interned strings. The crash would manifest when the -interpreter was finalized. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-21-14-37-48.gh-issue-106917.1jWp_m.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-21-14-37-48.gh-issue-106917.1jWp_m.rst deleted file mode 100644 index 82c74d5465458a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-21-14-37-48.gh-issue-106917.1jWp_m.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-22-14-35-38.gh-issue-107015.Ghp58t.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-22-14-35-38.gh-issue-107015.Ghp58t.rst deleted file mode 100644 index 77618a5bd50f2a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-22-14-35-38.gh-issue-107015.Ghp58t.rst +++ /dev/null @@ -1,3 +0,0 @@ -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`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-23-13-07-34.gh-issue-107122.9HFUyb.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-23-13-07-34.gh-issue-107122.9HFUyb.rst deleted file mode 100644 index 08decfd89b7cf0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-23-13-07-34.gh-issue-107122.9HFUyb.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`dbm.gnu.gdbm.clear` to :mod:`dbm.gnu`. Patch By Donghee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst deleted file mode 100644 index f68036cef34365..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-23-21-16-54.gh-issue-107122.VNuNcq.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`dbm.ndbm.ndbm.clear` to :mod:`dbm.ndbm`. Patch By Donghee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-24-11-11-41.gh-issue-104621.vM8Y_l.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-24-11-11-41.gh-issue-104621.vM8Y_l.rst deleted file mode 100644 index 86c976295f2620..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-24-11-11-41.gh-issue-104621.vM8Y_l.rst +++ /dev/null @@ -1 +0,0 @@ -Unsupported modules now always fail to be imported. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-25-15-29-26.gh-issue-106931.kKU1le.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-25-15-29-26.gh-issue-106931.kKU1le.rst deleted file mode 100644 index e0def5331b6c82..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-25-15-29-26.gh-issue-106931.kKU1le.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-25-22-35-35.gh-issue-77377.EHAbXx.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-25-22-35-35.gh-issue-77377.EHAbXx.rst deleted file mode 100644 index 194851dea13352..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-25-22-35-35.gh-issue-77377.EHAbXx.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-26-12-18-10.gh-issue-106897.EsGurc.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-26-12-18-10.gh-issue-106897.EsGurc.rst deleted file mode 100644 index d787dc4aad2d29..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-26-12-18-10.gh-issue-106897.EsGurc.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-26-18-53-34.gh-issue-106895.DdEwV8.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-26-18-53-34.gh-issue-106895.DdEwV8.rst deleted file mode 100644 index 370a29d34c860a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-26-18-53-34.gh-issue-106895.DdEwV8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise a ``ValueError`` when a monitoring callback funtion returns -``DISABLE`` for events that cannot be disabled locally. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-26-21-28-06.gh-issue-106898.8Wjuiv.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-26-21-28-06.gh-issue-106898.8Wjuiv.rst deleted file mode 100644 index f1b1c4c64b4aca..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-26-21-28-06.gh-issue-106898.8Wjuiv.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst deleted file mode 100644 index 60d3304a3fab93..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst +++ /dev/null @@ -1 +0,0 @@ -Isolate :mod:`!_decimal` (apply :pep:`687`). Patch by Charlie Zhao. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-47-29.gh-issue-104432.oGHF-z.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-47-29.gh-issue-104432.oGHF-z.rst deleted file mode 100644 index a9ab5cd43f0ffb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-47-29.gh-issue-104432.oGHF-z.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-29-22-01-30.gh-issue-104584.tINuoA.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-29-22-01-30.gh-issue-104584.tINuoA.rst deleted file mode 100644 index 059524831597b7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-29-22-01-30.gh-issue-104584.tINuoA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue which caused incorrect inline caches to be read when running -with :envvar:`PYTHONUOPS` or :option:`-X uops <-X>` enabled. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-30-05-20-16.gh-issue-107263.q0IU2M.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-30-05-20-16.gh-issue-107263.q0IU2M.rst deleted file mode 100644 index fb0940b456dae5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-30-05-20-16.gh-issue-107263.q0IU2M.rst +++ /dev/null @@ -1,3 +0,0 @@ -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 diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-30-14-18-49.gh-issue-107455.Es53l7.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-30-14-18-49.gh-issue-107455.Es53l7.rst deleted file mode 100644 index 84a93251e799d5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-30-14-18-49.gh-issue-107455.Es53l7.rst +++ /dev/null @@ -1,3 +0,0 @@ -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`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-30-18-05-11.gh-issue-100964.HluhBJ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-30-18-05-11.gh-issue-100964.HluhBJ.rst deleted file mode 100644 index 99ebc926e2ce2d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-07-30-18-05-11.gh-issue-100964.HluhBJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Clear generators' exception state after ``return`` to break reference -cycles. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-01-09-41-36.gh-issue-106608.OFZogw.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-01-09-41-36.gh-issue-106608.OFZogw.rst deleted file mode 100644 index 20d43a7c4f754a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-01-09-41-36.gh-issue-106608.OFZogw.rst +++ /dev/null @@ -1 +0,0 @@ -Make ``_PyUOpExecutorObject`` variable length. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-02-09-55-21.gh-issue-107557.P1z-in.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-02-09-55-21.gh-issue-107557.P1z-in.rst deleted file mode 100644 index 392f59c79e8de9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-02-09-55-21.gh-issue-107557.P1z-in.rst +++ /dev/null @@ -1 +0,0 @@ -Generate the cases needed for the barebones tier 2 abstract interpreter for optimization passes in CPython. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-02-12-24-51.gh-issue-107080.PNolFU.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-02-12-24-51.gh-issue-107080.PNolFU.rst deleted file mode 100644 index 5084c854360e35..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-02-12-24-51.gh-issue-107080.PNolFU.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-03-11-13-09.gh-issue-107596.T3yPGI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-03-11-13-09.gh-issue-107596.T3yPGI.rst deleted file mode 100644 index 8912de73680b44..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-03-11-13-09.gh-issue-107596.T3yPGI.rst +++ /dev/null @@ -1 +0,0 @@ -Specialize subscripting :class:`str` objects by :class:`int` indexes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-03-13-38-14.gh-issue-84436.gl1wHx.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-03-13-38-14.gh-issue-84436.gl1wHx.rst deleted file mode 100644 index 71044c32feebcc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-03-13-38-14.gh-issue-84436.gl1wHx.rst +++ /dev/null @@ -1 +0,0 @@ -Skip reference count modifications for many known immortal objects. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-04-21-25-26.gh-issue-107724.EbBXMr.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-04-21-25-26.gh-issue-107724.EbBXMr.rst deleted file mode 100644 index 6e853cf72a3348..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-04-21-25-26.gh-issue-107724.EbBXMr.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-04-47-18.gh-issue-107674.0sYhR2.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-05-04-47-18.gh-issue-107674.0sYhR2.rst deleted file mode 100644 index acfbf1fa2adf2c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-04-47-18.gh-issue-107674.0sYhR2.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed performance regression in ``sys.settrace``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-09-06-56.gh-issue-105848.Drc-1-.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-05-09-06-56.gh-issue-105848.Drc-1-.rst deleted file mode 100644 index 6c1c3229475f6f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-09-06-56.gh-issue-105848.Drc-1-.rst +++ /dev/null @@ -1,3 +0,0 @@ -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). diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-15-45-07.gh-issue-107659.QgtQ5M.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-05-15-45-07.gh-issue-107659.QgtQ5M.rst deleted file mode 100644 index 31cc6982400d5d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-05-15-45-07.gh-issue-107659.QgtQ5M.rst +++ /dev/null @@ -1 +0,0 @@ -Add docstrings for :func:`ctypes.pointer` and :func:`ctypes.POINTER`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-08-02-46-46.gh-issue-107758.R5kyBI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-08-02-46-46.gh-issue-107758.R5kyBI.rst deleted file mode 100644 index 192f1df26e613e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-08-02-46-46.gh-issue-107758.R5kyBI.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-09-08-31-20.gh-issue-84805.7JRWua.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-09-08-31-20.gh-issue-84805.7JRWua.rst deleted file mode 100644 index 23dfba989fa552..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-09-08-31-20.gh-issue-84805.7JRWua.rst +++ /dev/null @@ -1,2 +0,0 @@ -Autogenerate signature for :c:macro:`METH_NOARGS` and :c:macro:`METH_O` -extension functions. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-09-15-05-27.gh-issue-107526.PB32z-.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-09-15-05-27.gh-issue-107526.PB32z-.rst deleted file mode 100644 index 42ea09e78d41cc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-09-15-05-27.gh-issue-107526.PB32z-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Revert converting ``vars``, ``dir``, ``next``, ``getattr``, and ``iter`` to -argument clinic. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-10-00-00-48.gh-issue-106581.o7zDty.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-10-00-00-48.gh-issue-106581.o7zDty.rst deleted file mode 100644 index dff1ebd9cf70f0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-10-00-00-48.gh-issue-106581.o7zDty.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible assertion failures and missing instrumentation events when -:envvar:`PYTHONUOPS` or :option:`-X uops <-X>` is enabled. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst deleted file mode 100644 index b4b90ad4ea0ecc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix abort / segfault when using all eight type watcher slots, on platforms -where ``char`` is signed by default. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst deleted file mode 100644 index fc2369ddabb83c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-11-16-18-19.gh-issue-108035.e2msOD.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-13-17-18-22.gh-issue-108390.TkBccC.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-13-17-18-22.gh-issue-108390.TkBccC.rst deleted file mode 100644 index 3ed596007b56f7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-13-17-18-22.gh-issue-108390.TkBccC.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-15-11-09-50.gh-issue-107944.zQLp3j.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-15-11-09-50.gh-issue-107944.zQLp3j.rst deleted file mode 100644 index 9a53332c70261d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-15-11-09-50.gh-issue-107944.zQLp3j.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve error message for function calls with bad keyword arguments. Patch -by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-15-13-06-05.gh-issue-107971.lPbx04.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-15-13-06-05.gh-issue-107971.lPbx04.rst deleted file mode 100644 index dc10f672d8871e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-15-13-06-05.gh-issue-107971.lPbx04.rst +++ /dev/null @@ -1,2 +0,0 @@ -Opcode IDs are generated from bytecodes.c instead of being hard coded in -opcode.py. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-18-18-21-27.gh-issue-108113.1h0poE.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-18-18-21-27.gh-issue-108113.1h0poE.rst deleted file mode 100644 index 66680578c9b43b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-18-18-21-27.gh-issue-108113.1h0poE.rst +++ /dev/null @@ -1,8 +0,0 @@ -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``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-21-21-13-30.gh-issue-107901.hszvdk.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-21-21-13-30.gh-issue-107901.hszvdk.rst deleted file mode 100644 index 112e093736dd5d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-21-21-13-30.gh-issue-107901.hszvdk.rst +++ /dev/null @@ -1 +0,0 @@ -Fix missing line number on :opcode:`JUMP_BACKWARD` at the end of a for loop. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-23-14-54-15.gh-issue-105481.40q-c4.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-23-14-54-15.gh-issue-105481.40q-c4.rst deleted file mode 100644 index 19746ebb701d02..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-23-14-54-15.gh-issue-105481.40q-c4.rst +++ /dev/null @@ -1,2 +0,0 @@ -The regen-opcode build stage was removed and its work is now done in -regen-cases. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-25-14-51-06.gh-issue-106176.D1EA2a.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-25-14-51-06.gh-issue-106176.D1EA2a.rst deleted file mode 100644 index 7f63d1086ea39e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-25-14-51-06.gh-issue-106176.D1EA2a.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-26-04-31-01.gh-issue-108487.1Gbr9k.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-26-04-31-01.gh-issue-108487.1Gbr9k.rst deleted file mode 100644 index 277b7c067e2528..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-26-04-31-01.gh-issue-108487.1Gbr9k.rst +++ /dev/null @@ -1 +0,0 @@ -Move an assert that would cause a spurious crash in a devious case that should only trigger deoptimization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-26-10-36-45.gh-issue-108614.wl5l-W.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-26-10-36-45.gh-issue-108614.wl5l-W.rst deleted file mode 100644 index ace670c9ba7fdf..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-26-10-36-45.gh-issue-108614.wl5l-W.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add RESUME_CHECK instruction, to avoid having to handle instrumentation, -signals, and contexts switches in the tier 2 execution engine. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-28-03-38-28.gh-issue-108716.HJBPwt.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-28-03-38-28.gh-issue-108716.HJBPwt.rst deleted file mode 100644 index f63eb8689d63a3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-28-03-38-28.gh-issue-108716.HJBPwt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Turn off deep-freezing of code objects. Modules are still frozen, so that a -file system search is not needed for common modules. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-28-22-22-15.gh-issue-108488.e8-fxg.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-28-22-22-15.gh-issue-108488.e8-fxg.rst deleted file mode 100644 index f9d6f593b8eb9b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-28-22-22-15.gh-issue-108488.e8-fxg.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-29-17-53-12.gh-issue-108654.jbkDVo.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-29-17-53-12.gh-issue-108654.jbkDVo.rst deleted file mode 100644 index 032e0331b20e75..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-29-17-53-12.gh-issue-108654.jbkDVo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restore locals shadowed by an inlined comprehension if the comprehension -raises an exception. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-30-15-41-47.gh-issue-108520.u0ZGP_.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-30-15-41-47.gh-issue-108520.u0ZGP_.rst deleted file mode 100644 index 44131fb11f068c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-30-15-41-47.gh-issue-108520.u0ZGP_.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-31-21-29-28.gh-issue-108727.blNRGM.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-31-21-29-28.gh-issue-108727.blNRGM.rst deleted file mode 100644 index 34959ae3bb99ac..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-08-31-21-29-28.gh-issue-108727.blNRGM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Define ``tp_dealloc`` for ``CounterOptimizer_Type``. This fixes a segfault -on deallocation. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-05-11-31-27.gh-issue-104584.IRSXA2.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-05-11-31-27.gh-issue-104584.IRSXA2.rst deleted file mode 100644 index 7f556bf8c31c11..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-05-11-31-27.gh-issue-104584.IRSXA2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash when running with :envvar:`PYTHONUOPS` or :option:`-X uops <-X>` -enabled and an error occurs during optimization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-05-20-52-17.gh-issue-108959.6z45Sy.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-05-20-52-17.gh-issue-108959.6z45Sy.rst deleted file mode 100644 index 792bbc454f2b27..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-05-20-52-17.gh-issue-108959.6z45Sy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix caret placement for error locations for subscript and binary operations -that involve non-semantic parentheses and spaces. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst deleted file mode 100644 index 94a143b86b6708..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-06-13-28-42.gh-issue-108732.I6DkEQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make iteration variables of module- and class-scoped comprehensions visible -to pdb and other tools that use ``frame.f_locals`` again. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-06-22-50-25.gh-issue-108976.MUKaIJ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-06-22-50-25.gh-issue-108976.MUKaIJ.rst deleted file mode 100644 index 4b89375f0f57ef..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-06-22-50-25.gh-issue-108976.MUKaIJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash that occurs after de-instrumenting a code object in a monitoring -callback. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-16-05-36.gh-issue-88943.rH_X3W.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-16-05-36.gh-issue-88943.rH_X3W.rst deleted file mode 100644 index a99830fe4227c9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-16-05-36.gh-issue-88943.rH_X3W.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-24-42.gh-issue-109118.yPXRAe.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-24-42.gh-issue-109118.yPXRAe.rst deleted file mode 100644 index f14fce4423896f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-24-42.gh-issue-109118.yPXRAe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix interpreter crash when a NameError is raised inside the type parameters -of a generic class. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst deleted file mode 100644 index 175046c771cdf3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-18-49-01.gh-issue-109052.TBU4nC.rst +++ /dev/null @@ -1 +0,0 @@ -Use the base opcode when comparing code objects to avoid interference from instrumentation diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst deleted file mode 100644 index 14661d14e190ce..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-08-01-50-41.gh-issue-109114.adqgtb.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-08-01-50-41.gh-issue-109114.adqgtb.rst deleted file mode 100644 index 3d95dd5d29450c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-08-01-50-41.gh-issue-109114.adqgtb.rst +++ /dev/null @@ -1,3 +0,0 @@ -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 diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-08-18-31-04.gh-issue-109156.KK1EXI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-08-18-31-04.gh-issue-109156.KK1EXI.rst deleted file mode 100644 index e681482c3a879e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-08-18-31-04.gh-issue-109156.KK1EXI.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for de-instrumenting instructions while keeping the instrumentation for lines diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-09-12-49-46.gh-issue-109118.gx0X4h.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-09-12-49-46.gh-issue-109118.gx0X4h.rst deleted file mode 100644 index 87069c85870410..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-09-12-49-46.gh-issue-109118.gx0X4h.rst +++ /dev/null @@ -1,2 +0,0 @@ -Disallow nested scopes (lambdas, generator expressions, and comprehensions) -within PEP 695 annotation scopes that are nested within classes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-09-21-17-18.gh-issue-109179.ZR8qs2.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-09-21-17-18.gh-issue-109179.ZR8qs2.rst deleted file mode 100644 index dd95a8ec7920aa..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-09-21-17-18.gh-issue-109179.ZR8qs2.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where the C traceback display drops notes from :exc:`SyntaxError`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-10-18-53-55.gh-issue-109207.Fei8bY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-10-18-53-55.gh-issue-109207.Fei8bY.rst deleted file mode 100644 index f9da3ac4d1abbd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-10-18-53-55.gh-issue-109207.Fei8bY.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a SystemError in ``__repr__`` of symtable entry object. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-11-12-41-42.gh-issue-109216.60QOSb.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-11-12-41-42.gh-issue-109216.60QOSb.rst deleted file mode 100644 index aa8b2832af23a5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-11-12-41-42.gh-issue-109216.60QOSb.rst +++ /dev/null @@ -1 +0,0 @@ -Fix possible memory leak in :opcode:`BUILD_MAP`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-11-15-11-03.gh-issue-109256.6mfhvF.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-11-15-11-03.gh-issue-109256.6mfhvF.rst deleted file mode 100644 index 6c33faea0ae6c4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-11-15-11-03.gh-issue-109256.6mfhvF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Opcode IDs for specialized opcodes are allocated in their own range to -improve stability of the IDs for the 'real' opcodes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-11-15-51-55.gh-issue-109195.iwxmuo.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-11-15-51-55.gh-issue-109195.iwxmuo.rst deleted file mode 100644 index 5427232c2df9a0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-11-15-51-55.gh-issue-109195.iwxmuo.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-12-15-45-49.gh-issue-109341.4V5bkm.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-12-15-45-49.gh-issue-109341.4V5bkm.rst deleted file mode 100644 index 9e99ef7eb73273..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-12-15-45-49.gh-issue-109341.4V5bkm.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash when compiling an invalid AST involving a :class:`ast.TypeAlias`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst deleted file mode 100644 index 23b81c1c0a3baa..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-12-16-00-42.gh-issue-109351.kznGeR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash when compiling an invalid AST involving a named (walrus) -expression. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-08-42-45.gh-issue-109219.UiN8sc.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-08-42-45.gh-issue-109219.UiN8sc.rst deleted file mode 100644 index 2c141f09d7e754..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-08-42-45.gh-issue-109219.UiN8sc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix compiling type param scopes that use a name which is also free in an -inner scope. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst deleted file mode 100644 index e95f5b84e8e187..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst +++ /dev/null @@ -1,2 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst deleted file mode 100644 index 2fb18d5ae88347..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst +++ /dev/null @@ -1 +0,0 @@ -Deopted instructions correctly for tool initialization and modified the incorrect assertion in instrumentation, when a previous tool already sets INSTRUCTION events diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-14-20-15-57.gh-issue-107265.qHZL_6.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-14-20-15-57.gh-issue-107265.qHZL_6.rst deleted file mode 100644 index c30c21f034a1bc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-14-20-15-57.gh-issue-107265.qHZL_6.rst +++ /dev/null @@ -1 +0,0 @@ -Deopt opcodes hidden by the executor when base opcode is needed diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-18-15-35-08.gh-issue-109496.Kleoz3.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-18-15-35-08.gh-issue-109496.Kleoz3.rst deleted file mode 100644 index 51b2144fed7841..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-18-15-35-08.gh-issue-109496.Kleoz3.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-20-13-18-08.gh-issue-109596.RG0K2G.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-20-13-18-08.gh-issue-109596.RG0K2G.rst deleted file mode 100644 index 23ef73d578651d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-20-13-18-08.gh-issue-109596.RG0K2G.rst +++ /dev/null @@ -1,3 +0,0 @@ -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 diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-20-23-04-15.gh-issue-109627.xxe7De.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-20-23-04-15.gh-issue-109627.xxe7De.rst deleted file mode 100644 index 397d76e291419f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-20-23-04-15.gh-issue-109627.xxe7De.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug where the compiler does not assign a new jump target label to a -duplicated small exit block. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-22-13-38-17.gh-issue-109719.fx5OTz.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-22-13-38-17.gh-issue-109719.fx5OTz.rst deleted file mode 100644 index 83be54c9ca793e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-22-13-38-17.gh-issue-109719.fx5OTz.rst +++ /dev/null @@ -1 +0,0 @@ -Fix missing jump target labels when compiler reorders cold/warm blocks. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-25-09-24-10.gh-issue-109793.zFQBkv.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-25-09-24-10.gh-issue-109793.zFQBkv.rst deleted file mode 100644 index d2dc4c830a9031..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-25-09-24-10.gh-issue-109793.zFQBkv.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst deleted file mode 100644 index 793c89f4445f54..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-25-14-28-14.gh-issue-109823.kbVTKF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bug where compiler does not adjust labels when removing an empty basic -block which is a jump target. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-26-21-26-54.gh-issue-109923.WO3CHi.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-26-21-26-54.gh-issue-109923.WO3CHi.rst deleted file mode 100644 index f2184592af0051..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-26-21-26-54.gh-issue-109923.WO3CHi.rst +++ /dev/null @@ -1 +0,0 @@ -Set line number on the ``POP_TOP`` that follows a ``RETURN_GENERATOR``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst deleted file mode 100644 index 8be373f0f6b6cd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2023-09-27-21-35-49.gh-issue-109889.t5hIRT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the compiler's redundant NOP detection algorithm to skip over NOPs with -no line number when looking for the next instruction's lineno. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-22-13-17-54.gh-issue-112320.EddM51.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-22-13-17-54.gh-issue-112320.EddM51.rst new file mode 100644 index 00000000000000..0da2fd33b0ea52 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-22-13-17-54.gh-issue-112320.EddM51.rst @@ -0,0 +1,4 @@ +The Tier 2 translator now tracks the confidence level for staying "on trace" +(i.e. not exiting back to the Tier 1 interpreter) for branch instructions +based on the number of bits set in the branch "counter". Trace translation +ends when the confidence drops below 1/3rd. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-24-14-10-57.gh-issue-112367.9z1IDp.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-24-14-10-57.gh-issue-112367.9z1IDp.rst new file mode 100644 index 00000000000000..991e45ad47fabe --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-24-14-10-57.gh-issue-112367.9z1IDp.rst @@ -0,0 +1,2 @@ +Avoid undefined behaviour when using the perf trampolines by not freeing the +code arenas until shutdown. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst new file mode 100644 index 00000000000000..adc0e3a6bbc89a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-20-36-38.gh-issue-99606.fDY5hK.rst @@ -0,0 +1,2 @@ +Make code generated for an empty f-string identical to the code of an empty +normal string. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-25-22-39-44.gh-issue-112387.AbBq5W.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-22-39-44.gh-issue-112387.AbBq5W.rst new file mode 100644 index 00000000000000..adac11bf4c90a1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-22-39-44.gh-issue-112387.AbBq5W.rst @@ -0,0 +1,2 @@ +Fix error positions for decoded strings with backwards tokenize errors. +Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-25-22-58-49.gh-issue-112388.MU3cIM.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-22-58-49.gh-issue-112388.MU3cIM.rst new file mode 100644 index 00000000000000..1c82be2febda4f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-25-22-58-49.gh-issue-112388.MU3cIM.rst @@ -0,0 +1,2 @@ +Fix an error that was causing the parser to try to overwrite tokenizer +errors. Patch by pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-26-21-30-11.gh-issue-111058.q4DqDY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-26-21-30-11.gh-issue-111058.q4DqDY.rst new file mode 100644 index 00000000000000..de5661f911aa82 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-26-21-30-11.gh-issue-111058.q4DqDY.rst @@ -0,0 +1,3 @@ +Change coro.cr_frame/gen.gi_frame to return ``None`` after the coroutine/generator has been closed. +This fixes a bug where :func:`~inspect.getcoroutinestate` and :func:`~inspect.getgeneratorstate` +return the wrong state for a closed coroutine/generator. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-11-27-18-55-30.gh-issue-112217.SwFLMj.rst b/Misc/NEWS.d/next/Core and Builtins/2023-11-27-18-55-30.gh-issue-112217.SwFLMj.rst new file mode 100644 index 00000000000000..d4efbab6b2d128 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-11-27-18-55-30.gh-issue-112217.SwFLMj.rst @@ -0,0 +1 @@ +Add check for the type of ``__cause__`` returned from calling the type ``T`` in ``raise from T``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-01-19-02-21.gh-issue-105967.Puq5Cn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-01-19-02-21.gh-issue-105967.Puq5Cn.rst new file mode 100644 index 00000000000000..c69511218e3e16 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-01-19-02-21.gh-issue-105967.Puq5Cn.rst @@ -0,0 +1,4 @@ +Workaround a bug in Apple's macOS platform zlib library where +:func:`zlib.crc32` and :func:`binascii.crc32` could produce incorrect results +on multi-gigabyte inputs. Including when using :mod:`zipfile` on zips +containing large data. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-03-15-29-53.gh-issue-112660.gldBvh.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-03-15-29-53.gh-issue-112660.gldBvh.rst new file mode 100644 index 00000000000000..ea9052b3e35c48 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-03-15-29-53.gh-issue-112660.gldBvh.rst @@ -0,0 +1,2 @@ +Do not clear unexpected errors during formatting error messages for +ImportError and AttributeError for modules. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-03-19-34-51.gh-issue-112625.QWTlwS.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-03-19-34-51.gh-issue-112625.QWTlwS.rst new file mode 100644 index 00000000000000..4970e10f3f4dcb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-03-19-34-51.gh-issue-112625.QWTlwS.rst @@ -0,0 +1 @@ +Fixes a bug where a bytearray object could be cleared while iterating over an argument in the ``bytearray.join()`` method that could result in reading memory after it was freed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-04-23-09-07.gh-issue-112730.BXHlFa.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-04-23-09-07.gh-issue-112730.BXHlFa.rst new file mode 100644 index 00000000000000..51758dd5f4c318 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-04-23-09-07.gh-issue-112730.BXHlFa.rst @@ -0,0 +1 @@ +Use color to highlight error locations in tracebacks. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-07-12-00-04.gh-issue-74616.kgTGVb.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-07-12-00-04.gh-issue-74616.kgTGVb.rst new file mode 100644 index 00000000000000..5c345be9de6d0b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-07-12-00-04.gh-issue-74616.kgTGVb.rst @@ -0,0 +1,2 @@ +:func:`input` now raises a ValueError when output on the terminal if the +prompt contains embedded null characters instead of silently truncating it. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-07-13-19-55.gh-issue-112125.4ADN7i.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-07-13-19-55.gh-issue-112125.4ADN7i.rst new file mode 100644 index 00000000000000..52cd45029fb8c7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-07-13-19-55.gh-issue-112125.4ADN7i.rst @@ -0,0 +1 @@ +Fix None.__ne__(None) returning NotImplemented instead of False diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-11-00-50-00.gh-issue-112943.RHNZie.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-11-00-50-00.gh-issue-112943.RHNZie.rst new file mode 100644 index 00000000000000..4bc2fe7c26d904 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-11-00-50-00.gh-issue-112943.RHNZie.rst @@ -0,0 +1,2 @@ +Correctly compute end column offsets for multiline tokens in the +:mod:`tokenize` module. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-11-19-53-32.gh-issue-90350.-FQy3E.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-11-19-53-32.gh-issue-90350.-FQy3E.rst new file mode 100644 index 00000000000000..6b7881bbd19f59 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-11-19-53-32.gh-issue-90350.-FQy3E.rst @@ -0,0 +1 @@ +Optimize builtin functions :func:`min` and :func:`max`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-12-04-53-19.gh-issue-108866.xbJ-9a.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-12-04-53-19.gh-issue-108866.xbJ-9a.rst new file mode 100644 index 00000000000000..96606924d4a3ec --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-12-04-53-19.gh-issue-108866.xbJ-9a.rst @@ -0,0 +1,3 @@ +Change the API and contract of ``_PyExecutorObject`` to return the +next_instr pointer, instead of the frame, and to always execute at least one +instruction. diff --git a/Misc/NEWS.d/next/Documentation/2023-03-16-15-39-26.gh-issue-102759.ehpHw6.rst b/Misc/NEWS.d/next/Documentation/2023-03-16-15-39-26.gh-issue-102759.ehpHw6.rst deleted file mode 100644 index d3df6c8997aa35..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-03-16-15-39-26.gh-issue-102759.ehpHw6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Align function signature for ``functools.reduce`` in documentation and docstring -with the C implementation. diff --git a/Misc/NEWS.d/next/Documentation/2023-03-19-09-39-31.gh-issue-102823.OzsOz0.rst b/Misc/NEWS.d/next/Documentation/2023-03-19-09-39-31.gh-issue-102823.OzsOz0.rst deleted file mode 100644 index 1e32f3c89231c8..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-03-19-09-39-31.gh-issue-102823.OzsOz0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document the return type of ``x // y`` when ``x`` and ``y`` have type -:class:`float`. diff --git a/Misc/NEWS.d/next/Documentation/2023-05-16-22-08-24.gh-issue-54738.mJvCnj.rst b/Misc/NEWS.d/next/Documentation/2023-05-16-22-08-24.gh-issue-54738.mJvCnj.rst deleted file mode 100644 index 4da58fc982b6d7..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-05-16-22-08-24.gh-issue-54738.mJvCnj.rst +++ /dev/null @@ -1 +0,0 @@ -Add documentation on how to localize the :mod:`argparse` module. 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-29-14-10-24.gh-issue-105052.MGFwbm.rst b/Misc/NEWS.d/next/Documentation/2023-05-29-14-10-24.gh-issue-105052.MGFwbm.rst deleted file mode 100644 index 8fdc38d439f54f..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-05-29-14-10-24.gh-issue-105052.MGFwbm.rst +++ /dev/null @@ -1 +0,0 @@ -Update ``timeit`` doc to specify that time in seconds is just the default. 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/Documentation/2023-07-21-11-51-57.gh-issue-106948.K_JQ7j.rst b/Misc/NEWS.d/next/Documentation/2023-07-21-11-51-57.gh-issue-106948.K_JQ7j.rst deleted file mode 100644 index 42b6348153b56a..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-07-21-11-51-57.gh-issue-106948.K_JQ7j.rst +++ /dev/null @@ -1 +0,0 @@ -Add a number of standard external names to ``nitpick_ignore``. diff --git a/Misc/NEWS.d/next/Documentation/2023-07-22-15-14-13.gh-issue-107008.3JQ1Vt.rst b/Misc/NEWS.d/next/Documentation/2023-07-22-15-14-13.gh-issue-107008.3JQ1Vt.rst deleted file mode 100644 index a0fa27ec10303e..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-07-22-15-14-13.gh-issue-107008.3JQ1Vt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document the :mod:`curses` module variables :const:`~curses.LINES` and -:const:`~curses.COLS`. diff --git a/Misc/NEWS.d/next/Documentation/2023-07-26-16-33-04.gh-issue-107305.qB2LS4.rst b/Misc/NEWS.d/next/Documentation/2023-07-26-16-33-04.gh-issue-107305.qB2LS4.rst deleted file mode 100644 index 038f9e68a5422a..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-07-26-16-33-04.gh-issue-107305.qB2LS4.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add documentation for :c:type:`PyInterpreterConfig` and -:c:func:`Py_NewInterpreterFromConfig`. Also clarify some of the nearby docs -relative to per-interpreter GIL. diff --git a/Misc/NEWS.d/next/Documentation/2023-09-10-02-39-06.gh-issue-109209.0LBewo.rst b/Misc/NEWS.d/next/Documentation/2023-09-10-02-39-06.gh-issue-109209.0LBewo.rst deleted file mode 100644 index 79cc0b72ec742f..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2023-09-10-02-39-06.gh-issue-109209.0LBewo.rst +++ /dev/null @@ -1 +0,0 @@ -The minimum Sphinx version required for the documentation is now 4.2. diff --git a/Misc/NEWS.d/next/Documentation/2023-11-30-02-33-59.gh-issue-111699._O5G_y.rst b/Misc/NEWS.d/next/Documentation/2023-11-30-02-33-59.gh-issue-111699._O5G_y.rst new file mode 100644 index 00000000000000..2d31345e6c2044 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2023-11-30-02-33-59.gh-issue-111699._O5G_y.rst @@ -0,0 +1 @@ +Relocate ``smtpd`` deprecation notice to its own section rather than under ``locale`` in What's New in Python 3.12 document 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/IDLE/2023-12-10-20-01-11.gh-issue-112898.98aWv2.rst b/Misc/NEWS.d/next/IDLE/2023-12-10-20-01-11.gh-issue-112898.98aWv2.rst new file mode 100644 index 00000000000000..1c20e46b1e5f7b --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2023-12-10-20-01-11.gh-issue-112898.98aWv2.rst @@ -0,0 +1 @@ +Fix processing unsaved files when quitting IDLE on macOS. diff --git a/Misc/NEWS.d/next/Library/2019-06-14-22-37-32.bpo-37260.oecdIf.rst b/Misc/NEWS.d/next/Library/2019-06-14-22-37-32.bpo-37260.oecdIf.rst new file mode 100644 index 00000000000000..a5f2c5e8e18919 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-14-22-37-32.bpo-37260.oecdIf.rst @@ -0,0 +1,2 @@ +Fixed a race condition in :func:`shutil.rmtree` in which directory entries removed by another process or thread while ``shutil.rmtree()`` is running can cause it to raise FileNotFoundError. Patch by Jeffrey Kintscher. + 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-03-09-15-08-29.bpo-39912.xPOBBY.rst b/Misc/NEWS.d/next/Library/2020-03-09-15-08-29.bpo-39912.xPOBBY.rst new file mode 100644 index 00000000000000..fb8579725a2d7d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-09-15-08-29.bpo-39912.xPOBBY.rst @@ -0,0 +1,3 @@ +:func:`warnings.filterwarnings()` and :func:`warnings.simplefilter()` now raise +appropriate exceptions instead of ``AssertionError``. Patch contributed by +Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2020-05-03-00-33-15.bpo-18319.faPTlx.rst b/Misc/NEWS.d/next/Library/2020-05-03-00-33-15.bpo-18319.faPTlx.rst deleted file mode 100644 index 94d7cc9deadbb1..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-03-00-33-15.bpo-18319.faPTlx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure ``gettext(msg)`` retrieve translations even if a plural form exists. In -other words: ``gettext(msg) == ngettext(msg, '', 1)``. diff --git a/Misc/NEWS.d/next/Library/2020-05-21-23-32-46.bpo-40262.z4fQv1.rst b/Misc/NEWS.d/next/Library/2020-05-21-23-32-46.bpo-40262.z4fQv1.rst new file mode 100644 index 00000000000000..c017a1c8df09d8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-21-23-32-46.bpo-40262.z4fQv1.rst @@ -0,0 +1,2 @@ +The :meth:`ssl.SSLSocket.recv_into` method no longer requires the *buffer* +argument to implement ``__len__`` and supports buffers with arbitrary item size. diff --git a/Misc/NEWS.d/next/Library/2020-07-28-20-48-05.bpo-41422.iMwnMu.rst b/Misc/NEWS.d/next/Library/2020-07-28-20-48-05.bpo-41422.iMwnMu.rst new file mode 100644 index 00000000000000..8bde68f8f2afc8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-28-20-48-05.bpo-41422.iMwnMu.rst @@ -0,0 +1,2 @@ +Fixed memory leaks of :class:`pickle.Pickler` and :class:`pickle.Unpickler` involving cyclic references via the +internal memo mapping. 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/2020-11-10-07-04-15.bpo-40988.5kBC-O.rst b/Misc/NEWS.d/next/Library/2020-11-10-07-04-15.bpo-40988.5kBC-O.rst deleted file mode 100644 index 9323d93c59b05a..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-11-10-07-04-15.bpo-40988.5kBC-O.rst +++ /dev/null @@ -1,3 +0,0 @@ -Improve performance of :class:`functools.singledispatchmethod` by caching the -generated dispatch wrapper. Optimization suggested by frederico. Patch by -@mental32, Alex Waygood and Pieter Eendebak. diff --git a/Misc/NEWS.d/next/Library/2020-12-14-09-31-13.bpo-35332.s22wAx.rst b/Misc/NEWS.d/next/Library/2020-12-14-09-31-13.bpo-35332.s22wAx.rst new file mode 100644 index 00000000000000..80564b99a079c6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-12-14-09-31-13.bpo-35332.s22wAx.rst @@ -0,0 +1,3 @@ +The :func:`shutil.rmtree` function now ignores errors when calling +:func:`os.close` when *ignore_errors* is ``True``, and +:func:`os.close` no longer retried after error. 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/2021-08-16-17-52-26.bpo-44850.r8jx5u.rst b/Misc/NEWS.d/next/Library/2021-08-16-17-52-26.bpo-44850.r8jx5u.rst deleted file mode 100644 index 1fe5497f856e90..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-08-16-17-52-26.bpo-44850.r8jx5u.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve performance of :func:`operator.methodcaller` using the :pep:`590` ``vectorcall`` convention. -Patch by Anthony Lee and Pieter Eendebak. diff --git a/Misc/NEWS.d/next/Library/2021-10-31-16-06-28.bpo-43633.vflwXv.rst b/Misc/NEWS.d/next/Library/2021-10-31-16-06-28.bpo-43633.vflwXv.rst deleted file mode 100644 index 025de1e1a7d6ef..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-10-31-16-06-28.bpo-43633.vflwXv.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2021-11-23-22-22-49.bpo-32731.kNOASr.rst b/Misc/NEWS.d/next/Library/2021-11-23-22-22-49.bpo-32731.kNOASr.rst new file mode 100644 index 00000000000000..92f3b870c11131 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-23-22-22-49.bpo-32731.kNOASr.rst @@ -0,0 +1,3 @@ +:func:`getpass.getuser` now raises :exc:`OSError` for all failures rather +than :exc:`ImportError` on systems lacking the :mod:`pwd` module or +:exc:`KeyError` if the password database is empty. diff --git a/Misc/NEWS.d/next/Library/2021-12-06-22-10-53.bpo-43153.J7mjSy.rst b/Misc/NEWS.d/next/Library/2021-12-06-22-10-53.bpo-43153.J7mjSy.rst new file mode 100644 index 00000000000000..7800e0a4869adf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-06-22-10-53.bpo-43153.J7mjSy.rst @@ -0,0 +1,4 @@ +On Windows, ``tempfile.TemporaryDirectory`` previously masked a +``PermissionError`` with ``NotADirectoryError`` during directory cleanup. It +now correctly raises ``PermissionError`` if errors are not ignored. Patch by +Andrei Kulakov and Ken Jin. 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/2022-11-26-22-05-22.gh-issue-99203.j0DUae.rst b/Misc/NEWS.d/next/Library/2022-11-26-22-05-22.gh-issue-99203.j0DUae.rst deleted file mode 100644 index fcfb044d476acc..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-11-26-22-05-22.gh-issue-99203.j0DUae.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst b/Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst new file mode 100644 index 00000000000000..7991048fc48e03 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst @@ -0,0 +1,2 @@ +Fix a bug in :class:`tempfile.TemporaryDirectory` cleanup, which now no longer +dereferences symlinks when working around file system permission errors. diff --git a/Misc/NEWS.d/next/Library/2022-12-24-12-50-54.gh-issue-84867.OhaLbU.rst b/Misc/NEWS.d/next/Library/2022-12-24-12-50-54.gh-issue-84867.OhaLbU.rst deleted file mode 100644 index 8b45dcee481916..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-12-24-12-50-54.gh-issue-84867.OhaLbU.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`unittest.TestLoader` no longer loads test cases from exact -:class:`unittest.TestCase` and :class:`unittest.FunctionTestCase` classes. diff --git a/Misc/NEWS.d/next/Library/2023-02-08-00-43-29.gh-issue-83162.ufdI9F.rst b/Misc/NEWS.d/next/Library/2023-02-08-00-43-29.gh-issue-83162.ufdI9F.rst new file mode 100644 index 00000000000000..6074dd7f101a6d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-02-08-00-43-29.gh-issue-83162.ufdI9F.rst @@ -0,0 +1,3 @@ +Renamed :exc:`!re.error` to :exc:`PatternError` for clarity, and kept +:exc:`!re.error` for backward compatibility. Patch by Matthias Bussonnier and +Adam Chhina. 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-02-20-12-00-11.gh-issue-88233.o5Zb0t.rst b/Misc/NEWS.d/next/Library/2023-02-20-12-00-11.gh-issue-88233.o5Zb0t.rst deleted file mode 100644 index 945f92d3dfa93b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-02-20-12-00-11.gh-issue-88233.o5Zb0t.rst +++ /dev/null @@ -1,2 +0,0 @@ -Refactored ``zipfile._strip_extra`` to use higher level abstactions for -extras instead of a heavy-state loop. diff --git a/Misc/NEWS.d/next/Library/2023-02-20-15-41-59.gh-issue-102029.9ZPG99.rst b/Misc/NEWS.d/next/Library/2023-02-20-15-41-59.gh-issue-102029.9ZPG99.rst deleted file mode 100644 index 4d6f05f2524528..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-02-20-15-41-59.gh-issue-102029.9ZPG99.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate passing any arguments to :func:`threading.RLock`. 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-03-14-01-19-57.gh-issue-100061.CiXJYn.rst b/Misc/NEWS.d/next/Library/2023-03-14-01-19-57.gh-issue-100061.CiXJYn.rst deleted file mode 100644 index dfed34f6ae9768..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-03-14-01-19-57.gh-issue-100061.CiXJYn.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that causes wrong matches for regular expressions with possessive -qualifier. 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-08-12-43-52.gh-issue-101162.yOCd_J.rst b/Misc/NEWS.d/next/Library/2023-04-08-12-43-52.gh-issue-101162.yOCd_J.rst deleted file mode 100644 index e9fadc8f436d9b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-08-12-43-52.gh-issue-101162.yOCd_J.rst +++ /dev/null @@ -1,2 +0,0 @@ -Forbid using :func:`builtins.issubclass` with :class:`types.GenericAlias` as -the first argument. 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-09-05-30-41.gh-issue-103384.zAV7iB.rst b/Misc/NEWS.d/next/Library/2023-04-09-05-30-41.gh-issue-103384.zAV7iB.rst deleted file mode 100644 index 3e9d3cf9ae92b6..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-04-09-05-30-41.gh-issue-103384.zAV7iB.rst +++ /dev/null @@ -1 +0,0 @@ -Generalize the regex pattern ``BaseConfigurator.INDEX_PATTERN`` to allow spaces and non-alphanumeric characters in keys. 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-04-29-20-49-13.gh-issue-104003.-8Ruk2.rst b/Misc/NEWS.d/next/Library/2023-04-29-20-49-13.gh-issue-104003.-8Ruk2.rst new file mode 100644 index 00000000000000..82d61ca8b8bc97 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-29-20-49-13.gh-issue-104003.-8Ruk2.rst @@ -0,0 +1,3 @@ +Add :func:`warnings.deprecated`, a decorator to mark deprecated functions to +static type checkers and to warn on usage of deprecated classes and functions. +See :pep:`702`. Patch by Jelle Zijlstra. 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-07-00-13-00.gh-issue-70303.frwUKH.rst b/Misc/NEWS.d/next/Library/2023-06-07-00-13-00.gh-issue-70303.frwUKH.rst deleted file mode 100644 index 39a891ac5964ab..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-07-00-13-00.gh-issue-70303.frwUKH.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. 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-15-56-45.gh-issue-105509.YIG57j.rst b/Misc/NEWS.d/next/Library/2023-06-08-15-56-45.gh-issue-105509.YIG57j.rst deleted file mode 100644 index 26d8a66c2c4e03..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-08-15-56-45.gh-issue-105509.YIG57j.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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. 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 f47754e172251f..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:`errno` 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 0c24ff70334e17..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-06-30-16-42-44.gh-issue-106263.tk-t93.rst b/Misc/NEWS.d/next/Library/2023-06-30-16-42-44.gh-issue-106263.tk-t93.rst deleted file mode 100644 index d86a6bfdabbfb0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-06-30-16-42-44.gh-issue-106263.tk-t93.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash when calling ``repr`` with a manually constructed SignalDict object. -Patch by Charlie Zhao. 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-03-46-20.gh-issue-106350.LLcTEe.rst b/Misc/NEWS.d/next/Library/2023-07-03-03-46-20.gh-issue-106350.LLcTEe.rst deleted file mode 100644 index 681d63a6668be8..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-03-03-46-20.gh-issue-106350.LLcTEe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Detect possible memory allocation failure in the libtommath function :c:func:`mp_init` -used by the ``_tkinter`` module. 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-14-52-31.gh-issue-106052.ak8nbs.rst b/Misc/NEWS.d/next/Library/2023-07-07-14-52-31.gh-issue-106052.ak8nbs.rst deleted file mode 100644 index f2d4c2f7b18ec7..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-14-52-31.gh-issue-106052.ak8nbs.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`re` module: fix the matching of possessive quantifiers in the case of -a subpattern containing backtracking. 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-18-22-07.gh-issue-106527.spHQ0W.rst b/Misc/NEWS.d/next/Library/2023-07-07-18-22-07.gh-issue-106527.spHQ0W.rst deleted file mode 100644 index 204bda1c73eb36..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-07-18-22-07.gh-issue-106527.spHQ0W.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce overhead to add and remove :mod:`asyncio` readers and writers. 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-00-36-33.gh-issue-106558.Zqsj6F.rst b/Misc/NEWS.d/next/Library/2023-07-09-00-36-33.gh-issue-106558.Zqsj6F.rst deleted file mode 100644 index 8fe677f5d84b5f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-09-00-36-33.gh-issue-106558.Zqsj6F.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove ref cycle in callers of -:func:`~multiprocessing.managers.convert_to_error` by deleting ``result`` -from scope in a ``finally`` block. 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-09-13-10-54.gh-issue-106566.NN35-U.rst b/Misc/NEWS.d/next/Library/2023-07-09-13-10-54.gh-issue-106566.NN35-U.rst deleted file mode 100644 index 3b88dc79183876..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-09-13-10-54.gh-issue-106566.NN35-U.rst +++ /dev/null @@ -1 +0,0 @@ -Optimize ``(?!)`` (pattern which alwais fails) in regular expressions. diff --git a/Misc/NEWS.d/next/Library/2023-07-11-08-56-40.gh-issue-106584.g-SBtC.rst b/Misc/NEWS.d/next/Library/2023-07-11-08-56-40.gh-issue-106584.g-SBtC.rst deleted file mode 100644 index a13b61bf1c121b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-11-08-56-40.gh-issue-106584.g-SBtC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix exit code for ``unittest`` if all tests are skipped. -Patch by Egor Eliseev. 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-12-10-59-08.gh-issue-106670.goQ2Sy.rst b/Misc/NEWS.d/next/Library/2023-07-12-10-59-08.gh-issue-106670.goQ2Sy.rst deleted file mode 100644 index 0bb18312a673fc..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-12-10-59-08.gh-issue-106670.goQ2Sy.rst +++ /dev/null @@ -1 +0,0 @@ -Add the new ``exceptions`` command to the Pdb debugger. It makes it possible to move between chained exceptions when using post mortem debugging. 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-01-47-39.gh-issue-106734.eMYSoz.rst b/Misc/NEWS.d/next/Library/2023-07-14-01-47-39.gh-issue-106734.eMYSoz.rst deleted file mode 100644 index 37d2ab19ed1017..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-14-01-47-39.gh-issue-106734.eMYSoz.rst +++ /dev/null @@ -1 +0,0 @@ -Disable tab completion in multiline mode of :mod:`pdb` 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 bcda64153413df..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 :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. 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-10-24-56.gh-issue-106774.FJcqCj.rst b/Misc/NEWS.d/next/Library/2023-07-15-10-24-56.gh-issue-106774.FJcqCj.rst deleted file mode 100644 index ed467573b89e14..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-15-10-24-56.gh-issue-106774.FJcqCj.rst +++ /dev/null @@ -1 +0,0 @@ -Update the bundled copy of pip to version 23.2.1. 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 b9cf35adf95523..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 d26ac90d3978d4..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 -Donghee Na. diff --git a/Misc/NEWS.d/next/Library/2023-07-19-09-11-08.gh-issue-106751.U9nD_B.rst b/Misc/NEWS.d/next/Library/2023-07-19-09-11-08.gh-issue-106751.U9nD_B.rst deleted file mode 100644 index b9a9b563ad2267..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-19-09-11-08.gh-issue-106751.U9nD_B.rst +++ /dev/null @@ -1 +0,0 @@ -Optimize :meth:`_PollLikeSelector.select` for many iteration case. 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 1b3ffdc95120a2..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 -Donghee Na. diff --git a/Misc/NEWS.d/next/Library/2023-07-20-06-00-35.gh-issue-106739.W1hygr.rst b/Misc/NEWS.d/next/Library/2023-07-20-06-00-35.gh-issue-106739.W1hygr.rst deleted file mode 100644 index 168e2019395696..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-20-06-00-35.gh-issue-106739.W1hygr.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-07-22-12-53-53.gh-issue-105002.gkfsW0.rst b/Misc/NEWS.d/next/Library/2023-07-22-12-53-53.gh-issue-105002.gkfsW0.rst deleted file mode 100644 index b4c133a5cb1244..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-22-12-53-53.gh-issue-105002.gkfsW0.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst b/Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst deleted file mode 100644 index 07fdcc96fa38a6..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst +++ /dev/null @@ -1,3 +0,0 @@ -Do not report ``MultipartInvariantViolationDefect`` defect -when the :class:`email.parser.Parser` class is used -to parse emails with ``headersonly=True``. diff --git a/Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst b/Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst deleted file mode 100644 index e75b6c0f1d6759..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-22-14-29-34.gh-issue-65495.fw84qM.rst +++ /dev/null @@ -1 +0,0 @@ -Use lowercase ``mail from`` and ``rcpt to`` in :class:`smptlib.SMTP`. diff --git a/Misc/NEWS.d/next/Library/2023-07-22-15-51-33.gh-issue-83006.21zaCz.rst b/Misc/NEWS.d/next/Library/2023-07-22-15-51-33.gh-issue-83006.21zaCz.rst deleted file mode 100644 index e64d1860828430..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-22-15-51-33.gh-issue-83006.21zaCz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document behavior of :func:`shutil.disk_usage` for non-mounted filesystems -on Unix. diff --git a/Misc/NEWS.d/next/Library/2023-07-22-16-44-58.gh-issue-82500.cQYoPj.rst b/Misc/NEWS.d/next/Library/2023-07-22-16-44-58.gh-issue-82500.cQYoPj.rst deleted file mode 100644 index 065394fd6ee712..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-22-16-44-58.gh-issue-82500.cQYoPj.rst +++ /dev/null @@ -1 +0,0 @@ -Fix overflow on 32-bit systems with :mod:`asyncio` :func:`os.sendfile` implemention. diff --git a/Misc/NEWS.d/next/Library/2023-07-22-21-57-34.gh-issue-107089.Dnget2.rst b/Misc/NEWS.d/next/Library/2023-07-22-21-57-34.gh-issue-107089.Dnget2.rst deleted file mode 100644 index 3c29ddaa634ca8..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-22-21-57-34.gh-issue-107089.Dnget2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Shelves opened with :func:`shelve.open` have a much faster :meth:`clear` -method. Patch by James Cave. diff --git a/Misc/NEWS.d/next/Library/2023-07-23-12-26-23.gh-issue-62519.w8-81X.rst b/Misc/NEWS.d/next/Library/2023-07-23-12-26-23.gh-issue-62519.w8-81X.rst deleted file mode 100644 index 96e2a3dcc24fb0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-23-12-26-23.gh-issue-62519.w8-81X.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make :func:`gettext.pgettext` search plural definitions when -translation is not found. diff --git a/Misc/NEWS.d/next/Library/2023-07-23-13-05-32.gh-issue-105578.XAQtyR.rst b/Misc/NEWS.d/next/Library/2023-07-23-13-05-32.gh-issue-105578.XAQtyR.rst deleted file mode 100644 index 4a03f5c35ff6c0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-23-13-05-32.gh-issue-105578.XAQtyR.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate :class:`typing.AnyStr` in favor of the new Type Parameter syntax. -See PEP 695. diff --git a/Misc/NEWS.d/next/Library/2023-07-26-22-52-48.gh-issue-78722.6SKBLt.rst b/Misc/NEWS.d/next/Library/2023-07-26-22-52-48.gh-issue-78722.6SKBLt.rst deleted file mode 100644 index aea26ee2f99467..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-26-22-52-48.gh-issue-78722.6SKBLt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix issue where :meth:`pathlib.Path.iterdir` did not raise :exc:`OSError` -until iterated. diff --git a/Misc/NEWS.d/next/Library/2023-07-28-14-56-35.gh-issue-107369.bvTq8F.rst b/Misc/NEWS.d/next/Library/2023-07-28-14-56-35.gh-issue-107369.bvTq8F.rst deleted file mode 100644 index 76aeab65e90a20..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-28-14-56-35.gh-issue-107369.bvTq8F.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize :func:`textwrap.indent`. It is ~30% faster for large input. Patch -by Inada Naoki. diff --git a/Misc/NEWS.d/next/Library/2023-07-29-02-01-24.gh-issue-107406.ze6sQP.rst b/Misc/NEWS.d/next/Library/2023-07-29-02-01-24.gh-issue-107406.ze6sQP.rst deleted file mode 100644 index b78e57f591e78c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-29-02-01-24.gh-issue-107406.ze6sQP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement new :meth:`__repr__` method for :class:`struct.Struct`. -Now it returns ``Struct()``. diff --git a/Misc/NEWS.d/next/Library/2023-07-29-02-36-50.gh-issue-107409.HG27Nu.rst b/Misc/NEWS.d/next/Library/2023-07-29-02-36-50.gh-issue-107409.HG27Nu.rst deleted file mode 100644 index 1ecc7207605c70..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-29-02-36-50.gh-issue-107409.HG27Nu.rst +++ /dev/null @@ -1 +0,0 @@ -Set :attr:`!__wrapped__` attribute in :func:`reprlib.recursive_repr`. diff --git a/Misc/NEWS.d/next/Library/2023-07-31-07-36-24.gh-issue-107396.3_Kh6D.rst b/Misc/NEWS.d/next/Library/2023-07-31-07-36-24.gh-issue-107396.3_Kh6D.rst deleted file mode 100644 index 73bff4bdbe024d..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-07-31-07-36-24.gh-issue-107396.3_Kh6D.rst +++ /dev/null @@ -1 +0,0 @@ -tarfiles; Fixed use before assignment of self.exception for gzip decompression diff --git a/Misc/NEWS.d/next/Library/2023-08-01-15-17-20.gh-issue-105481.vMbmj_.rst b/Misc/NEWS.d/next/Library/2023-08-01-15-17-20.gh-issue-105481.vMbmj_.rst deleted file mode 100644 index 153c18a6f00953..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-01-15-17-20.gh-issue-105481.vMbmj_.rst +++ /dev/null @@ -1 +0,0 @@ -: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. diff --git a/Misc/NEWS.d/next/Library/2023-08-01-21-43-58.gh-issue-105481.cl2ajS.rst b/Misc/NEWS.d/next/Library/2023-08-01-21-43-58.gh-issue-105481.cl2ajS.rst deleted file mode 100644 index d02f909e870188..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-01-21-43-58.gh-issue-105481.cl2ajS.rst +++ /dev/null @@ -1,2 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-03-11-31-11.gh-issue-107576.pO_s9I.rst b/Misc/NEWS.d/next/Library/2023-08-03-11-31-11.gh-issue-107576.pO_s9I.rst deleted file mode 100644 index 67677dd3c8ed24..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-03-11-31-11.gh-issue-107576.pO_s9I.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :func:`types.get_original_bases` to only return -:attr:`!__orig_bases__` if it is present on ``cls`` directly. Patch by -James Hilton-Balfe. diff --git a/Misc/NEWS.d/next/Library/2023-08-03-12-52-19.gh-issue-107077.-pzHD6.rst b/Misc/NEWS.d/next/Library/2023-08-03-12-52-19.gh-issue-107077.-pzHD6.rst deleted file mode 100644 index ecaf437a48e0ae..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-03-12-52-19.gh-issue-107077.-pzHD6.rst +++ /dev/null @@ -1,6 +0,0 @@ -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 diff --git a/Misc/NEWS.d/next/Library/2023-08-05-05-10-41.gh-issue-106684.P9zRXb.rst b/Misc/NEWS.d/next/Library/2023-08-05-05-10-41.gh-issue-106684.P9zRXb.rst deleted file mode 100644 index 02c52d714e9df7..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-05-05-10-41.gh-issue-106684.P9zRXb.rst +++ /dev/null @@ -1 +0,0 @@ -Raise :exc:`ResourceWarning` when :class:`asyncio.StreamWriter` is not closed leading to memory leaks. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2023-08-06-10-52-12.gh-issue-72684.Ls2mSf.rst b/Misc/NEWS.d/next/Library/2023-08-06-10-52-12.gh-issue-72684.Ls2mSf.rst deleted file mode 100644 index 1ac0e6d790456c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-06-10-52-12.gh-issue-72684.Ls2mSf.rst +++ /dev/null @@ -1,3 +0,0 @@ -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`. diff --git a/Misc/NEWS.d/next/Library/2023-08-06-15-29-00.gh-issue-100814.h195gW.rst b/Misc/NEWS.d/next/Library/2023-08-06-15-29-00.gh-issue-100814.h195gW.rst deleted file mode 100644 index 86cb7bf79f3078..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-06-15-29-00.gh-issue-100814.h195gW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Passing a callable object as an option value to a Tkinter image now raises -the expected TclError instead of an AttributeError. diff --git a/Misc/NEWS.d/next/Library/2023-08-07-14-12-07.gh-issue-107715.238r2f.rst b/Misc/NEWS.d/next/Library/2023-08-07-14-12-07.gh-issue-107715.238r2f.rst deleted file mode 100644 index deea9af01c4ebd..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-07-14-12-07.gh-issue-107715.238r2f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :meth:`doctest.DocTestFinder.find` in presence of class names with special -characters. Patch by Gertjan van Zwieten. diff --git a/Misc/NEWS.d/next/Library/2023-08-07-14-24-42.gh-issue-107710.xfOCfj.rst b/Misc/NEWS.d/next/Library/2023-08-07-14-24-42.gh-issue-107710.xfOCfj.rst deleted file mode 100644 index 70f8b58e7ff5f5..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-07-14-24-42.gh-issue-107710.xfOCfj.rst +++ /dev/null @@ -1 +0,0 @@ -Speed up :func:`logging.getHandlerNames`. diff --git a/Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst b/Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst new file mode 100644 index 00000000000000..f582ad5df39e84 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst @@ -0,0 +1 @@ +Support tab completion in :mod:`cmd` for ``editline``. diff --git a/Misc/NEWS.d/next/Library/2023-08-08-16-09-59.gh-issue-56166.WUMhYG.rst b/Misc/NEWS.d/next/Library/2023-08-08-16-09-59.gh-issue-56166.WUMhYG.rst deleted file mode 100644 index 34d776ae8fc3ff..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-08-16-09-59.gh-issue-56166.WUMhYG.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-08-19-57-45.gh-issue-107782.mInjFE.rst b/Misc/NEWS.d/next/Library/2023-08-08-19-57-45.gh-issue-107782.mInjFE.rst deleted file mode 100644 index fb8a50de3a9eee..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-08-19-57-45.gh-issue-107782.mInjFE.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`pydoc` is now able to show signatures which are not representable in -Python, e.g. for ``getattr`` and ``dict.pop``. diff --git a/Misc/NEWS.d/next/Library/2023-08-09-13-49-37.gh-issue-107805.ezem0k.rst b/Misc/NEWS.d/next/Library/2023-08-09-13-49-37.gh-issue-107805.ezem0k.rst deleted file mode 100644 index 263df68f8e5c80..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-09-13-49-37.gh-issue-107805.ezem0k.rst +++ /dev/null @@ -1 +0,0 @@ -Fix signatures of module-level generated functions in :mod:`turtle`. diff --git a/Misc/NEWS.d/next/Library/2023-08-09-15-37-20.gh-issue-107812.CflAXa.rst b/Misc/NEWS.d/next/Library/2023-08-09-15-37-20.gh-issue-107812.CflAXa.rst deleted file mode 100644 index 0aac44fb418836..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-09-15-37-20.gh-issue-107812.CflAXa.rst +++ /dev/null @@ -1 +0,0 @@ -Extend socket's netlink support to the FreeBSD platform. diff --git a/Misc/NEWS.d/next/Library/2023-08-10-17-36-22.gh-issue-107845.dABiMJ.rst b/Misc/NEWS.d/next/Library/2023-08-10-17-36-22.gh-issue-107845.dABiMJ.rst deleted file mode 100644 index 32c1fb93f4ab2c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-10-17-36-22.gh-issue-107845.dABiMJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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``. diff --git a/Misc/NEWS.d/next/Library/2023-08-14-11-18-13.gh-issue-107913.4ooY6i.rst b/Misc/NEWS.d/next/Library/2023-08-14-11-18-13.gh-issue-107913.4ooY6i.rst deleted file mode 100644 index de5e21abfc3ae7..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-14-11-18-13.gh-issue-107913.4ooY6i.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-14-17-15-59.gh-issue-76913.LLD0rT.rst b/Misc/NEWS.d/next/Library/2023-08-14-17-15-59.gh-issue-76913.LLD0rT.rst deleted file mode 100644 index 5f9a84e714ae20..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-14-17-15-59.gh-issue-76913.LLD0rT.rst +++ /dev/null @@ -1 +0,0 @@ -Add *merge_extra* parameter/feature to :class:`logging.LoggerAdapter` diff --git a/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst b/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst deleted file mode 100644 index 6a4feaac25bc11..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-14-20-01-14.gh-issue-50002.E-bpj8.rst b/Misc/NEWS.d/next/Library/2023-08-14-20-01-14.gh-issue-50002.E-bpj8.rst deleted file mode 100644 index ca5c0740802eae..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-14-20-01-14.gh-issue-50002.E-bpj8.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`xml.dom.minidom` now preserves whitespaces in attributes. diff --git a/Misc/NEWS.d/next/Library/2023-08-14-20-18-59.gh-issue-81555.cWdP4a.rst b/Misc/NEWS.d/next/Library/2023-08-14-20-18-59.gh-issue-81555.cWdP4a.rst deleted file mode 100644 index 241a50f8b41c2b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-14-20-18-59.gh-issue-81555.cWdP4a.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`xml.dom.minidom` now only quotes ``"`` in attributes. diff --git a/Misc/NEWS.d/next/Library/2023-08-14-21-10-52.gh-issue-103363.u64_QI.rst b/Misc/NEWS.d/next/Library/2023-08-14-21-10-52.gh-issue-103363.u64_QI.rst new file mode 100644 index 00000000000000..d4a27d624eb5e6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-14-21-10-52.gh-issue-103363.u64_QI.rst @@ -0,0 +1,2 @@ +Add *follow_symlinks* keyword-only argument to :meth:`pathlib.Path.owner` +and :meth:`~pathlib.Path.group`, defaulting to ``True``. diff --git a/Misc/NEWS.d/next/Library/2023-08-14-23-11-11.gh-issue-106242.71HMym.rst b/Misc/NEWS.d/next/Library/2023-08-14-23-11-11.gh-issue-106242.71HMym.rst deleted file mode 100644 index 44237a9f15708c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-14-23-11-11.gh-issue-106242.71HMym.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes :func:`os.path.normpath` to handle embedded null characters without truncating the path. diff --git a/Misc/NEWS.d/next/Library/2023-08-15-18-20-00.gh-issue-107963.20g5BG.rst b/Misc/NEWS.d/next/Library/2023-08-15-18-20-00.gh-issue-107963.20g5BG.rst deleted file mode 100644 index ea968367d0bdee..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-15-18-20-00.gh-issue-107963.20g5BG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`multiprocessing.set_forkserver_preload` to check the given list -of modules names. Patch by Donghee Na. diff --git a/Misc/NEWS.d/next/Library/2023-08-16-00-24-07.gh-issue-107995.TlTp5t.rst b/Misc/NEWS.d/next/Library/2023-08-16-00-24-07.gh-issue-107995.TlTp5t.rst deleted file mode 100644 index 7247f6b3abc9bc..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-16-00-24-07.gh-issue-107995.TlTp5t.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-16-14-30-13.gh-issue-105539.29lA6c.rst b/Misc/NEWS.d/next/Library/2023-08-16-14-30-13.gh-issue-105539.29lA6c.rst deleted file mode 100644 index 0098c7f2438e9b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-16-14-30-13.gh-issue-105539.29lA6c.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`sqlite3` now emits an :exc:`ResourceWarning` if a -:class:`sqlite3.Connection` object is not :meth:`closed -` explicitly. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2023-08-16-21-20-55.gh-issue-107932.I7hFsp.rst b/Misc/NEWS.d/next/Library/2023-08-16-21-20-55.gh-issue-107932.I7hFsp.rst deleted file mode 100644 index 850cfcb6226d43..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-16-21-20-55.gh-issue-107932.I7hFsp.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``dis`` module to properly report and display bytecode that do not have source lines. diff --git a/Misc/NEWS.d/next/Library/2023-08-17-12-59-35.gh-issue-108083.9J7UcT.rst b/Misc/NEWS.d/next/Library/2023-08-17-12-59-35.gh-issue-108083.9J7UcT.rst deleted file mode 100644 index ff499ced73a309..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-17-12-59-35.gh-issue-108083.9J7UcT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix bugs in the constructor of :mod:`sqlite3.Connection` and -:meth:`sqlite3.Connection.close` where exceptions could be leaked. Patch by -Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst b/Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst deleted file mode 100644 index 1d959a3b22284c..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-17-14-45-25.gh-issue-105736.NJsH7r.rst +++ /dev/null @@ -1,3 +0,0 @@ -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__``. diff --git a/Misc/NEWS.d/next/Library/2023-08-18-22-58-07.gh-issue-83417.61J4yM.rst b/Misc/NEWS.d/next/Library/2023-08-18-22-58-07.gh-issue-83417.61J4yM.rst deleted file mode 100644 index fbb8bdb2073efa..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-18-22-58-07.gh-issue-83417.61J4yM.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-22-12-05-47.gh-issue-108322.kf3NJX.rst b/Misc/NEWS.d/next/Library/2023-08-22-12-05-47.gh-issue-108322.kf3NJX.rst deleted file mode 100644 index 5416c01a43f113..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-22-12-05-47.gh-issue-108322.kf3NJX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Speed-up NormalDist.samples() by using the inverse CDF method instead of -calling random.gauss(). diff --git a/Misc/NEWS.d/next/Library/2023-08-22-13-51-10.gh-issue-108278.11d_qG.rst b/Misc/NEWS.d/next/Library/2023-08-22-13-51-10.gh-issue-108278.11d_qG.rst deleted file mode 100644 index 85bedc1f3f852d..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-22-13-51-10.gh-issue-108278.11d_qG.rst +++ /dev/null @@ -1,9 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-22-16-18-49.gh-issue-108294.KEeUcM.rst b/Misc/NEWS.d/next/Library/2023-08-22-16-18-49.gh-issue-108294.KEeUcM.rst deleted file mode 100644 index de2a3a8a8ad891..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-22-16-18-49.gh-issue-108294.KEeUcM.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`time.sleep` now raises an auditing event. diff --git a/Misc/NEWS.d/next/Library/2023-08-22-17-27-12.gh-issue-108111.N7a4u_.rst b/Misc/NEWS.d/next/Library/2023-08-22-17-27-12.gh-issue-108111.N7a4u_.rst deleted file mode 100644 index 8eafa6cfbbf8cf..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-22-17-27-12.gh-issue-108111.N7a4u_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a regression introduced in GH-101251 for 3.12, resulting in an incorrect -offset calculation in :meth:`gzip.GzipFile.seek`. diff --git a/Misc/NEWS.d/next/Library/2023-08-22-22-29-42.gh-issue-64662.jHl_Bt.rst b/Misc/NEWS.d/next/Library/2023-08-22-22-29-42.gh-issue-64662.jHl_Bt.rst deleted file mode 100644 index 1b4c33a82b0b86..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-22-22-29-42.gh-issue-64662.jHl_Bt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix support for virtual tables in :meth:`sqlite3.Connection.iterdump`. Patch -by Aviv Palivoda. diff --git a/Misc/NEWS.d/next/Library/2023-08-23-17-34-39.gh-issue-107811.3Fng72.rst b/Misc/NEWS.d/next/Library/2023-08-23-17-34-39.gh-issue-107811.3Fng72.rst deleted file mode 100644 index ffca4131db228b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-23-17-34-39.gh-issue-107811.3Fng72.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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. diff --git a/Misc/NEWS.d/next/Library/2023-08-25-00-14-34.gh-issue-108463.mQApp_.rst b/Misc/NEWS.d/next/Library/2023-08-25-00-14-34.gh-issue-108463.mQApp_.rst deleted file mode 100644 index a5ab8e2f9d4b59..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-25-00-14-34.gh-issue-108463.mQApp_.rst +++ /dev/null @@ -1 +0,0 @@ -Make expressions/statements work as expected in pdb diff --git a/Misc/NEWS.d/next/Library/2023-08-26-08-38-57.gh-issue-108295.Pn0QRM.rst b/Misc/NEWS.d/next/Library/2023-08-26-08-38-57.gh-issue-108295.Pn0QRM.rst deleted file mode 100644 index 7e61ed4de75ce6..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-26-08-38-57.gh-issue-108295.Pn0QRM.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crashes related to use of weakrefs on :data:`typing.TypeVar`. diff --git a/Misc/NEWS.d/next/Library/2023-08-26-12-35-39.gh-issue-105829.kyYhWI.rst b/Misc/NEWS.d/next/Library/2023-08-26-12-35-39.gh-issue-105829.kyYhWI.rst deleted file mode 100644 index eaa2a5a4330e28..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-26-12-35-39.gh-issue-105829.kyYhWI.rst +++ /dev/null @@ -1 +0,0 @@ -Fix concurrent.futures.ProcessPoolExecutor deadlock diff --git a/Misc/NEWS.d/next/Library/2023-08-29-11-29-15.gh-issue-108278.-UhsnJ.rst b/Misc/NEWS.d/next/Library/2023-08-29-11-29-15.gh-issue-108278.-UhsnJ.rst deleted file mode 100644 index fa2dbdf88b31c9..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-29-11-29-15.gh-issue-108278.-UhsnJ.rst +++ /dev/null @@ -1,10 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-08-30-20-10-28.gh-issue-108682.c2gzLQ.rst b/Misc/NEWS.d/next/Library/2023-08-30-20-10-28.gh-issue-108682.c2gzLQ.rst deleted file mode 100644 index 148d4329142740..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-08-30-20-10-28.gh-issue-108682.c2gzLQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Enum: raise :exc:`TypeError` if ``super().__new__()`` is called from a -custom ``__new__``. diff --git a/Misc/NEWS.d/next/Library/2023-09-01-13-14-08.gh-issue-108751.2itqwe.rst b/Misc/NEWS.d/next/Library/2023-09-01-13-14-08.gh-issue-108751.2itqwe.rst deleted file mode 100644 index 7bc21fe6c81760..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-01-13-14-08.gh-issue-108751.2itqwe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`copy.replace` function which allows to create a modified copy of -an object. It supports named tuples, dataclasses, and many other objects. diff --git a/Misc/NEWS.d/next/Library/2023-09-03-04-37-52.gh-issue-108469.kusj40.rst b/Misc/NEWS.d/next/Library/2023-09-03-04-37-52.gh-issue-108469.kusj40.rst deleted file mode 100644 index ac0f682963daec..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-03-04-37-52.gh-issue-108469.kusj40.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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) diff --git a/Misc/NEWS.d/next/Library/2023-09-06-06-17-23.gh-issue-108843.WJMhsS.rst b/Misc/NEWS.d/next/Library/2023-09-06-06-17-23.gh-issue-108843.WJMhsS.rst deleted file mode 100644 index 0f15761c14bb7d..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-06-06-17-23.gh-issue-108843.WJMhsS.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an issue in :func:`ast.unparse` when unparsing f-strings containing many quote types. diff --git a/Misc/NEWS.d/next/Library/2023-09-06-14-47-28.gh-issue-109033.piUzDx.rst b/Misc/NEWS.d/next/Library/2023-09-06-14-47-28.gh-issue-109033.piUzDx.rst deleted file mode 100644 index 15ec0b437d4339..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-06-14-47-28.gh-issue-109033.piUzDx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Exceptions raised by os.utime builtin function now include the related -filename diff --git a/Misc/NEWS.d/next/Library/2023-09-06-19-33-41.gh-issue-108682.35Xnc5.rst b/Misc/NEWS.d/next/Library/2023-09-06-19-33-41.gh-issue-108682.35Xnc5.rst deleted file mode 100644 index 8c13d43ee9744b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-06-19-33-41.gh-issue-108682.35Xnc5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Enum: require ``names=()`` or ``type=...`` to create an empty enum using -the functional syntax. diff --git a/Misc/NEWS.d/next/Library/2023-09-08-12-09-55.gh-issue-108987.x5AIG8.rst b/Misc/NEWS.d/next/Library/2023-09-08-12-09-55.gh-issue-108987.x5AIG8.rst deleted file mode 100644 index 16526ee748d869..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-08-12-09-55.gh-issue-108987.x5AIG8.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-08-22-26-26.gh-issue-109164.-9BFWR.rst b/Misc/NEWS.d/next/Library/2023-09-08-22-26-26.gh-issue-109164.-9BFWR.rst deleted file mode 100644 index b439c14ff535ff..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-08-22-26-26.gh-issue-109164.-9BFWR.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`pdb`: Replace :mod:`getopt` with :mod:`argparse` for parsing command line arguments. diff --git a/Misc/NEWS.d/next/Library/2023-09-09-09-05-41.gh-issue-109174.OJea5s.rst b/Misc/NEWS.d/next/Library/2023-09-09-09-05-41.gh-issue-109174.OJea5s.rst deleted file mode 100644 index 63461fac3b96f7..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-09-09-05-41.gh-issue-109174.OJea5s.rst +++ /dev/null @@ -1 +0,0 @@ -Add support of :class:`types.SimpleNamespace` in :func:`copy.replace`. diff --git a/Misc/NEWS.d/next/Library/2023-09-09-15-08-37.gh-issue-50644.JUAZOh.rst b/Misc/NEWS.d/next/Library/2023-09-09-15-08-37.gh-issue-50644.JUAZOh.rst deleted file mode 100644 index a7a442e35289d3..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-09-15-08-37.gh-issue-50644.JUAZOh.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-09-17-09-54.gh-issue-109187.dIayNW.rst b/Misc/NEWS.d/next/Library/2023-09-09-17-09-54.gh-issue-109187.dIayNW.rst deleted file mode 100644 index 31b3ef77807cde..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-09-17-09-54.gh-issue-109187.dIayNW.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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. diff --git a/Misc/NEWS.d/next/Library/2023-09-11-00-32-18.gh-issue-107219.3zqyFT.rst b/Misc/NEWS.d/next/Library/2023-09-11-00-32-18.gh-issue-107219.3zqyFT.rst deleted file mode 100644 index 10afbcf823386a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-11-00-32-18.gh-issue-107219.3zqyFT.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-12-13-01-55.gh-issue-109319.YaCMtW.rst b/Misc/NEWS.d/next/Library/2023-09-12-13-01-55.gh-issue-109319.YaCMtW.rst deleted file mode 100644 index d3cd86b040821a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-12-13-01-55.gh-issue-109319.YaCMtW.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate the ``dis.HAVE_ARGUMENT`` field in favour of ``dis.hasarg``. diff --git a/Misc/NEWS.d/next/Library/2023-09-13-17-22-44.gh-issue-109375.ijJHZ9.rst b/Misc/NEWS.d/next/Library/2023-09-13-17-22-44.gh-issue-109375.ijJHZ9.rst deleted file mode 100644 index 9b7a85d05f66ca..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-13-17-22-44.gh-issue-109375.ijJHZ9.rst +++ /dev/null @@ -1 +0,0 @@ -The :mod:`pdb` ``alias`` command now prevents registering aliases without arguments. diff --git a/Misc/NEWS.d/next/Library/2023-09-15-12-20-23.gh-issue-109096.VksX1D.rst b/Misc/NEWS.d/next/Library/2023-09-15-12-20-23.gh-issue-109096.VksX1D.rst deleted file mode 100644 index bf1308498a8eb0..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-15-12-20-23.gh-issue-109096.VksX1D.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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. diff --git a/Misc/NEWS.d/next/Library/2023-09-15-17-12-53.gh-issue-109461.VNFPTK.rst b/Misc/NEWS.d/next/Library/2023-09-15-17-12-53.gh-issue-109461.VNFPTK.rst deleted file mode 100644 index 28f0c16e620146..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-15-17-12-53.gh-issue-109461.VNFPTK.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`logging`: Use a context manager for lock acquisition. diff --git a/Misc/NEWS.d/next/Library/2023-09-18-07-43-22.gh-issue-109543.1tOGoV.rst b/Misc/NEWS.d/next/Library/2023-09-18-07-43-22.gh-issue-109543.1tOGoV.rst deleted file mode 100644 index e790f7750c332a..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-18-07-43-22.gh-issue-109543.1tOGoV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove unnecessary :func:`hasattr` check during :data:`typing.TypedDict` -creation. diff --git a/Misc/NEWS.d/next/Library/2023-09-19-01-22-43.gh-issue-109559.ijaycU.rst b/Misc/NEWS.d/next/Library/2023-09-19-01-22-43.gh-issue-109559.ijaycU.rst deleted file mode 100644 index 2c25a7b302dd02..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-19-01-22-43.gh-issue-109559.ijaycU.rst +++ /dev/null @@ -1 +0,0 @@ -Update :mod:`unicodedata` database to Unicode 15.1.0. diff --git a/Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst b/Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst deleted file mode 100644 index e741e60ff41a9b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-19-17-56-24.gh-issue-109109.WJvvX2.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-20-07-38-14.gh-issue-109599.IaSLJz.rst b/Misc/NEWS.d/next/Library/2023-09-20-07-38-14.gh-issue-109599.IaSLJz.rst deleted file mode 100644 index 8a15e765545f88..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-20-07-38-14.gh-issue-109599.IaSLJz.rst +++ /dev/null @@ -1 +0,0 @@ -Expose the type of PyCapsule objects as ``types.CapsuleType``. diff --git a/Misc/NEWS.d/next/Library/2023-09-20-17-45-46.gh-issue-109613.P13ogN.rst b/Misc/NEWS.d/next/Library/2023-09-20-17-45-46.gh-issue-109613.P13ogN.rst deleted file mode 100644 index e21a758fc2eb05..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-20-17-45-46.gh-issue-109613.P13ogN.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-21-14-26-44.gh-issue-74481.KAUDcD.rst b/Misc/NEWS.d/next/Library/2023-09-21-14-26-44.gh-issue-74481.KAUDcD.rst deleted file mode 100644 index c2aca4eae64eda..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-21-14-26-44.gh-issue-74481.KAUDcD.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``set_error_mode`` related constants in ``msvcrt`` module in Python debug build. diff --git a/Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst b/Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst deleted file mode 100644 index 9f794bb58ba63b..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-21-19-42-22.gh-issue-109653.bL3iLH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Reduce the import time of :mod:`typing` by around a third. -Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-09-22-20-16-44.gh-issue-109593.LboaNM.rst b/Misc/NEWS.d/next/Library/2023-09-22-20-16-44.gh-issue-109593.LboaNM.rst deleted file mode 100644 index 292aea0be24dfb..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-22-20-16-44.gh-issue-109593.LboaNM.rst +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-23-12-47-45.gh-issue-109653.9wZBfs.rst b/Misc/NEWS.d/next/Library/2023-09-23-12-47-45.gh-issue-109653.9wZBfs.rst deleted file mode 100644 index 1d0f0e4f83b5e1..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-23-12-47-45.gh-issue-109653.9wZBfs.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce the import time of :mod:`enum` by over 50%. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-09-23-14-40-51.gh-issue-109786.UX3pKv.rst b/Misc/NEWS.d/next/Library/2023-09-23-14-40-51.gh-issue-109786.UX3pKv.rst new file mode 100644 index 00000000000000..07222fa339d703 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-09-23-14-40-51.gh-issue-109786.UX3pKv.rst @@ -0,0 +1,2 @@ +Fix possible reference leaks and crash when re-enter the ``__next__()`` method of +:class:`itertools.pairwise`. diff --git a/Misc/NEWS.d/next/Library/2023-09-24-13-28-35.gh-issue-109653.9IFU0B.rst b/Misc/NEWS.d/next/Library/2023-09-24-13-28-35.gh-issue-109653.9IFU0B.rst deleted file mode 100644 index c4f5a62433a2c1..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-24-13-28-35.gh-issue-109653.9IFU0B.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve import time of :mod:`functools` by around 13%. Patch by Alex -Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-09-24-16-43-33.gh-issue-109782.gMC_7z.rst b/Misc/NEWS.d/next/Library/2023-09-24-16-43-33.gh-issue-109782.gMC_7z.rst deleted file mode 100644 index 7612e59dc45412..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-24-16-43-33.gh-issue-109782.gMC_7z.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure the signature of :func:`os.path.isdir` is identical on all platforms. -Patch by Amin Alaee. diff --git a/Misc/NEWS.d/next/Library/2023-09-25-09-59-59.gh-issue-109818.dLRtT-.rst b/Misc/NEWS.d/next/Library/2023-09-25-09-59-59.gh-issue-109818.dLRtT-.rst deleted file mode 100644 index 184086af2585ea..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-25-09-59-59.gh-issue-109818.dLRtT-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`reprlib.recursive_repr` not copying ``__type_params__`` from -decorated function. diff --git a/Misc/NEWS.d/next/Library/2023-09-25-23-00-37.gh-issue-109631.eWSqpO.rst b/Misc/NEWS.d/next/Library/2023-09-25-23-00-37.gh-issue-109631.eWSqpO.rst deleted file mode 100644 index 58af2e57068267..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-25-23-00-37.gh-issue-109631.eWSqpO.rst +++ /dev/null @@ -1,3 +0,0 @@ -: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. diff --git a/Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst b/Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst deleted file mode 100644 index 44a6df1083762f..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-28-18-08-02.gh-issue-110045.0YIGKv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update the :mod:`symtable` module to support the new scopes introduced by -:pep:`695`. diff --git a/Misc/NEWS.d/next/Library/2023-09-28-18-50-33.gh-issue-110038.nx_gCu.rst b/Misc/NEWS.d/next/Library/2023-09-28-18-50-33.gh-issue-110038.nx_gCu.rst deleted file mode 100644 index 6b2abd802fccdc..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-28-18-50-33.gh-issue-110038.nx_gCu.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-09-28-18-53-11.gh-issue-110036.fECxTj.rst b/Misc/NEWS.d/next/Library/2023-09-28-18-53-11.gh-issue-110036.fECxTj.rst deleted file mode 100644 index ddb11b5c3546a1..00000000000000 --- a/Misc/NEWS.d/next/Library/2023-09-28-18-53-11.gh-issue-110036.fECxTj.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Library/2023-10-11-02-34-01.gh-issue-110109.RFCmHs.rst b/Misc/NEWS.d/next/Library/2023-10-11-02-34-01.gh-issue-110109.RFCmHs.rst new file mode 100644 index 00000000000000..4f12d128f49fb3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-11-02-34-01.gh-issue-110109.RFCmHs.rst @@ -0,0 +1,3 @@ +Add private ``pathlib._PurePathBase`` class: a base class for +:class:`pathlib.PurePath` that omits certain magic methods. It may be made +public (along with ``_PathBase``) in future. diff --git a/Misc/NEWS.d/next/Library/2023-10-12-18-19-47.gh-issue-82300.P8-O38.rst b/Misc/NEWS.d/next/Library/2023-10-12-18-19-47.gh-issue-82300.P8-O38.rst new file mode 100644 index 00000000000000..d7e6b225489b99 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-12-18-19-47.gh-issue-82300.P8-O38.rst @@ -0,0 +1 @@ +Add ``track`` parameter to :class:`multiprocessing.shared_memory.SharedMemory` that allows using shared memory blocks without having to register with the POSIX resource tracker that automatically releases them upon process exit. diff --git a/Misc/NEWS.d/next/Library/2023-10-23-03-49-34.gh-issue-102980.aXBd54.rst b/Misc/NEWS.d/next/Library/2023-10-23-03-49-34.gh-issue-102980.aXBd54.rst new file mode 100644 index 00000000000000..d4bae4790d6fa4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-23-03-49-34.gh-issue-102980.aXBd54.rst @@ -0,0 +1 @@ +Redirect the output of ``interact`` command of :mod:`pdb` to the same channel as the debugger. Add tests and improve docs. diff --git a/Misc/NEWS.d/next/Library/2023-10-25-16-37-13.gh-issue-75666.BpsWut.rst b/Misc/NEWS.d/next/Library/2023-10-25-16-37-13.gh-issue-75666.BpsWut.rst new file mode 100644 index 00000000000000..d774cc4f7c687f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-25-16-37-13.gh-issue-75666.BpsWut.rst @@ -0,0 +1,6 @@ +Fix the behavior of :mod:`tkinter` widget's ``unbind()`` method with two +arguments. Previously, ``widget.unbind(sequence, funcid)`` destroyed the +current binding for *sequence*, leaving *sequence* unbound, and deleted the +*funcid* command. Now it removes only *funcid* from the binding for +*sequence*, keeping other commands, and deletes the *funcid* command. It +leaves *sequence* unbound only if *funcid* was the last bound command. diff --git a/Misc/NEWS.d/next/Library/2023-11-05-20-09-27.gh-issue-99367.HLaWKo.rst b/Misc/NEWS.d/next/Library/2023-11-05-20-09-27.gh-issue-99367.HLaWKo.rst new file mode 100644 index 00000000000000..0920da221e423f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-05-20-09-27.gh-issue-99367.HLaWKo.rst @@ -0,0 +1 @@ +Do not mangle ``sys.path[0]`` in :mod:`pdb` if safe_path is set diff --git a/Misc/NEWS.d/next/Library/2023-11-08-16-11-04.gh-issue-110275.Bm6GwR.rst b/Misc/NEWS.d/next/Library/2023-11-08-16-11-04.gh-issue-110275.Bm6GwR.rst new file mode 100644 index 00000000000000..194dd5cb623f0f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-08-16-11-04.gh-issue-110275.Bm6GwR.rst @@ -0,0 +1,2 @@ +Named tuple's methods ``_replace()`` and ``__replace__()`` now raise +TypeError instead of ValueError for invalid keyword arguments. diff --git a/Misc/NEWS.d/next/Library/2023-11-08-18-53-07.gh-issue-68166.1iTh4Y.rst b/Misc/NEWS.d/next/Library/2023-11-08-18-53-07.gh-issue-68166.1iTh4Y.rst new file mode 100644 index 00000000000000..30379b8fa1afaf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-08-18-53-07.gh-issue-68166.1iTh4Y.rst @@ -0,0 +1,2 @@ +Add support of the "vsapi" element type in +:meth:`tkinter.ttk.Style.element_create`. diff --git a/Misc/NEWS.d/next/Library/2023-11-09-11-07-34.gh-issue-111874.dzYc3j.rst b/Misc/NEWS.d/next/Library/2023-11-09-11-07-34.gh-issue-111874.dzYc3j.rst new file mode 100644 index 00000000000000..50408202a7a5a1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-09-11-07-34.gh-issue-111874.dzYc3j.rst @@ -0,0 +1,4 @@ +When creating a :class:`typing.NamedTuple` class, ensure +:func:`~object.__set_name__` is called on all objects that define +``__set_name__`` and exist in the values of the ``NamedTuple`` class's class +dictionary. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-11-15-01-36-04.gh-issue-106922.qslOVH.rst b/Misc/NEWS.d/next/Library/2023-11-15-01-36-04.gh-issue-106922.qslOVH.rst new file mode 100644 index 00000000000000..b68e75ab87cd0b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-15-01-36-04.gh-issue-106922.qslOVH.rst @@ -0,0 +1 @@ +Display multiple lines with ``traceback`` when errors span multiple lines. diff --git a/Misc/NEWS.d/next/Library/2023-11-15-04-53-37.gh-issue-112105.I3RcVN.rst b/Misc/NEWS.d/next/Library/2023-11-15-04-53-37.gh-issue-112105.I3RcVN.rst new file mode 100644 index 00000000000000..4243dcb190434f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-15-04-53-37.gh-issue-112105.I3RcVN.rst @@ -0,0 +1 @@ +Make :func:`readline.set_completer_delims` work with libedit diff --git a/Misc/NEWS.d/next/Library/2023-11-16-10-42-15.gh-issue-112139.WpHosf.rst b/Misc/NEWS.d/next/Library/2023-11-16-10-42-15.gh-issue-112139.WpHosf.rst new file mode 100644 index 00000000000000..090dc8847d9556 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-16-10-42-15.gh-issue-112139.WpHosf.rst @@ -0,0 +1,3 @@ +Add :meth:`Signature.format` to format signatures to string with extra options. +And use it in :mod:`pydoc` to render more readable signatures that have new +lines between parameters. diff --git a/Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst b/Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst new file mode 100644 index 00000000000000..6b61d051966846 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-16-17-18-09.gh-issue-112137.QvjGjN.rst @@ -0,0 +1 @@ +Change :mod:`dis` output to display logical labels for jump targets instead of offsets. diff --git a/Misc/NEWS.d/next/Library/2023-11-21-02-58-14.gh-issue-77621.MYv5XS.rst b/Misc/NEWS.d/next/Library/2023-11-21-02-58-14.gh-issue-77621.MYv5XS.rst new file mode 100644 index 00000000000000..f3e6efc389afca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-21-02-58-14.gh-issue-77621.MYv5XS.rst @@ -0,0 +1,2 @@ +Slightly improve the import time of the :mod:`pathlib` module by deferring +some imports. Patch by Barney Gale. diff --git a/Misc/NEWS.d/next/Library/2023-11-22-19-43-54.gh-issue-112292.5nDU87.rst b/Misc/NEWS.d/next/Library/2023-11-22-19-43-54.gh-issue-112292.5nDU87.rst new file mode 100644 index 00000000000000..8345e33791cde0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-22-19-43-54.gh-issue-112292.5nDU87.rst @@ -0,0 +1,2 @@ +Fix a crash in :mod:`readline` when imported from a sub interpreter. Patch +by Anthony Shaw diff --git a/Misc/NEWS.d/next/Library/2023-11-22-23-08-47.gh-issue-81620.mfZ2Wf.rst b/Misc/NEWS.d/next/Library/2023-11-22-23-08-47.gh-issue-81620.mfZ2Wf.rst new file mode 100644 index 00000000000000..ff35806e4d5ed6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-22-23-08-47.gh-issue-81620.mfZ2Wf.rst @@ -0,0 +1 @@ +Add extra tests for :func:`random.binomialvariate` diff --git a/Misc/NEWS.d/next/Library/2023-11-23-10-41-21.gh-issue-112332.rhTBaa.rst b/Misc/NEWS.d/next/Library/2023-11-23-10-41-21.gh-issue-112332.rhTBaa.rst new file mode 100644 index 00000000000000..bd686ad052e5b2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-23-10-41-21.gh-issue-112332.rhTBaa.rst @@ -0,0 +1,2 @@ +Deprecate the ``exc_type`` field of :class:`traceback.TracebackException`. +Add ``exc_type_str`` to replace it. diff --git a/Misc/NEWS.d/next/Library/2023-11-23-12-37-22.gh-issue-112137.kM46Q6.rst b/Misc/NEWS.d/next/Library/2023-11-23-12-37-22.gh-issue-112137.kM46Q6.rst new file mode 100644 index 00000000000000..1b2e41ae96ff09 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-23-12-37-22.gh-issue-112137.kM46Q6.rst @@ -0,0 +1 @@ +Change :mod:`dis` output to display no-lineno as "--" instead of "None". diff --git a/Misc/NEWS.d/next/Library/2023-11-23-17-25-27.gh-issue-112345.FFApHx.rst b/Misc/NEWS.d/next/Library/2023-11-23-17-25-27.gh-issue-112345.FFApHx.rst new file mode 100644 index 00000000000000..b2b9894e6bef3a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-23-17-25-27.gh-issue-112345.FFApHx.rst @@ -0,0 +1,3 @@ +Improve error message when trying to call :func:`issubclass` against a +:class:`typing.Protocol` that has non-method members. +Patch by Randolf Scholz. diff --git a/Misc/NEWS.d/next/Library/2023-11-24-09-27-01.gh-issue-112361.kYtnHW.rst b/Misc/NEWS.d/next/Library/2023-11-24-09-27-01.gh-issue-112361.kYtnHW.rst new file mode 100644 index 00000000000000..5a83f93f9fbec8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-24-09-27-01.gh-issue-112361.kYtnHW.rst @@ -0,0 +1,2 @@ +Speed up a small handful of :mod:`pathlib` methods by removing some +temporary objects. diff --git a/Misc/NEWS.d/next/Library/2023-11-24-21-00-24.gh-issue-94722.GMIQIn.rst b/Misc/NEWS.d/next/Library/2023-11-24-21-00-24.gh-issue-94722.GMIQIn.rst new file mode 100644 index 00000000000000..41bd57f46ed82a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-24-21-00-24.gh-issue-94722.GMIQIn.rst @@ -0,0 +1,2 @@ +Fix bug where comparison between instances of :class:`~doctest.DocTest` fails if +one of them has ``None`` as its lineno. diff --git a/Misc/NEWS.d/next/Library/2023-11-25-20-29-28.gh-issue-112405.cOtzxC.rst b/Misc/NEWS.d/next/Library/2023-11-25-20-29-28.gh-issue-112405.cOtzxC.rst new file mode 100644 index 00000000000000..f6f1bee2a0c38f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-25-20-29-28.gh-issue-112405.cOtzxC.rst @@ -0,0 +1 @@ +Optimize :meth:`pathlib.PurePath.relative_to`. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-11-26-13-26-56.gh-issue-112358.smhaeZ.rst b/Misc/NEWS.d/next/Library/2023-11-26-13-26-56.gh-issue-112358.smhaeZ.rst new file mode 100644 index 00000000000000..e473ded46a1309 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-26-13-26-56.gh-issue-112358.smhaeZ.rst @@ -0,0 +1,2 @@ +Revert change to :class:`struct.Struct` initialization that broke some cases +of subclassing. diff --git a/Misc/NEWS.d/next/Library/2023-11-26-13-44-19.gh-issue-112414.kx2E7S.rst b/Misc/NEWS.d/next/Library/2023-11-26-13-44-19.gh-issue-112414.kx2E7S.rst new file mode 100644 index 00000000000000..058e5a33227e5a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-26-13-44-19.gh-issue-112414.kx2E7S.rst @@ -0,0 +1,3 @@ +Fix regression in Python 3.12 where calling :func:`repr` on a module that +had been imported using a custom :term:`loader` could fail with +:exc:`AttributeError`. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-11-27-12-41-23.gh-issue-63284.q2Qi9q.rst b/Misc/NEWS.d/next/Library/2023-11-27-12-41-23.gh-issue-63284.q2Qi9q.rst new file mode 100644 index 00000000000000..abb57dccd5a91a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-27-12-41-23.gh-issue-63284.q2Qi9q.rst @@ -0,0 +1 @@ +Added support for TLS-PSK (pre-shared key) mode to the :mod:`ssl` module. diff --git a/Misc/NEWS.d/next/Library/2023-11-28-02-39-30.gh-issue-101336.ya433z.rst b/Misc/NEWS.d/next/Library/2023-11-28-02-39-30.gh-issue-101336.ya433z.rst new file mode 100644 index 00000000000000..c222febae6b554 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-28-02-39-30.gh-issue-101336.ya433z.rst @@ -0,0 +1 @@ +Add ``keep_alive`` keyword parameter for :meth:`AbstractEventLoop.create_server` and :meth:`BaseEventLoop.create_server`. diff --git a/Misc/NEWS.d/next/Library/2023-11-28-20-01-33.gh-issue-112509.QtoKed.rst b/Misc/NEWS.d/next/Library/2023-11-28-20-01-33.gh-issue-112509.QtoKed.rst new file mode 100644 index 00000000000000..a16d67e7776bcb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-28-20-01-33.gh-issue-112509.QtoKed.rst @@ -0,0 +1,3 @@ +Fix edge cases that could cause a key to be present in both the +``__required_keys__`` and ``__optional_keys__`` attributes of a +:class:`typing.TypedDict`. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2023-11-28-20-47-39.gh-issue-112328.Z2AxEY.rst b/Misc/NEWS.d/next/Library/2023-11-28-20-47-39.gh-issue-112328.Z2AxEY.rst new file mode 100644 index 00000000000000..6e6902486b7bc9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-28-20-47-39.gh-issue-112328.Z2AxEY.rst @@ -0,0 +1,2 @@ +[Enum] Make ``EnumDict``, ``EnumDict.member_names``, +``EnumType._add_alias_`` and ``EnumType._add_value_alias_`` public. diff --git a/Misc/NEWS.d/next/Library/2023-11-29-02-26-32.gh-issue-112510.j-zXGc.rst b/Misc/NEWS.d/next/Library/2023-11-29-02-26-32.gh-issue-112510.j-zXGc.rst new file mode 100644 index 00000000000000..02de6fa80c1b3e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-29-02-26-32.gh-issue-112510.j-zXGc.rst @@ -0,0 +1 @@ +Add :data:`readline.backend` for the backend readline uses (``editline`` or ``readline``) diff --git a/Misc/NEWS.d/next/Library/2023-11-29-10-51-41.gh-issue-112516.rFKUKN.rst b/Misc/NEWS.d/next/Library/2023-11-29-10-51-41.gh-issue-112516.rFKUKN.rst new file mode 100644 index 00000000000000..530cf992dcd77a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-11-29-10-51-41.gh-issue-112516.rFKUKN.rst @@ -0,0 +1 @@ +Update the bundled copy of pip to version 23.3.1. diff --git a/Misc/NEWS.d/next/Library/2023-12-01-08-28-09.gh-issue-112578.bfNbfi.rst b/Misc/NEWS.d/next/Library/2023-12-01-08-28-09.gh-issue-112578.bfNbfi.rst new file mode 100644 index 00000000000000..1de5b1fe26ce6d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-01-08-28-09.gh-issue-112578.bfNbfi.rst @@ -0,0 +1 @@ +Fix a spurious :exc:`RuntimeWarning` when executing the :mod:`zipfile` module. diff --git a/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst new file mode 100644 index 00000000000000..feb7a8643b97f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst @@ -0,0 +1,3 @@ +Fix a crash in :func:`socket.if_indextoname` with specific value (UINT_MAX). +Fix an integer overflow in :func:`socket.if_indextoname` on 64-bit +non-Windows platforms. diff --git a/Misc/NEWS.d/next/Library/2023-12-01-18-05-09.gh-issue-110190.5bf-c9.rst b/Misc/NEWS.d/next/Library/2023-12-01-18-05-09.gh-issue-110190.5bf-c9.rst new file mode 100644 index 00000000000000..730b9d49119805 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-01-18-05-09.gh-issue-110190.5bf-c9.rst @@ -0,0 +1 @@ +Fix ctypes structs with array on Arm platform by setting ``MAX_STRUCT_SIZE`` to 32 in stgdict. Patch by Diego Russo. diff --git a/Misc/NEWS.d/next/Library/2023-12-01-21-05-46.gh-issue-112334.DmNXKh.rst b/Misc/NEWS.d/next/Library/2023-12-01-21-05-46.gh-issue-112334.DmNXKh.rst new file mode 100644 index 00000000000000..3a53a8bf84230f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-01-21-05-46.gh-issue-112334.DmNXKh.rst @@ -0,0 +1,11 @@ +Fixed a performance regression in 3.12's :mod:`subprocess` on Linux where it +would no longer use the fast-path ``vfork()`` system call when it could have +due to a logic bug, instead falling back to the safe but slower ``fork()``. + +Also fixed a second 3.12.0 potential security bug. If a value of +``extra_groups=[]`` was passed to :mod:`subprocess.Popen` or related APIs, +the underlying ``setgroups(0, NULL)`` system call to clear the groups list +would not be made in the child process prior to ``exec()``. + +This was identified via code inspection in the process of fixing the first +bug. diff --git a/Misc/NEWS.d/next/Library/2023-12-02-12-55-17.gh-issue-112618.7_FT8-.rst b/Misc/NEWS.d/next/Library/2023-12-02-12-55-17.gh-issue-112618.7_FT8-.rst new file mode 100644 index 00000000000000..c732de15609c96 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-02-12-55-17.gh-issue-112618.7_FT8-.rst @@ -0,0 +1,2 @@ +Fix a caching bug relating to :data:`typing.Annotated`. +``Annotated[str, True]`` is no longer identical to ``Annotated[str, 1]``. diff --git a/Misc/NEWS.d/next/Library/2023-12-03-01-01-52.gh-issue-112622.1Z8cpx.rst b/Misc/NEWS.d/next/Library/2023-12-03-01-01-52.gh-issue-112622.1Z8cpx.rst new file mode 100644 index 00000000000000..91c88bac334dcb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-03-01-01-52.gh-issue-112622.1Z8cpx.rst @@ -0,0 +1,2 @@ +Ensure ``name`` parameter is passed to event loop in +:func:`asyncio.create_task`. diff --git a/Misc/NEWS.d/next/Library/2023-12-03-12-41-48.gh-issue-112645.blMsKf.rst b/Misc/NEWS.d/next/Library/2023-12-03-12-41-48.gh-issue-112645.blMsKf.rst new file mode 100644 index 00000000000000..4e8f6ebdb882e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-03-12-41-48.gh-issue-112645.blMsKf.rst @@ -0,0 +1 @@ +Remove deprecation error on passing ``onerror`` to :func:`shutil.rmtree`. diff --git a/Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst b/Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst new file mode 100644 index 00000000000000..36d793f787302e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst @@ -0,0 +1,5 @@ +Speedup :func:`isinstance` checks by roughly 20% for +:func:`runtime-checkable protocols ` +that only have one callable member. +Speedup :func:`issubclass` checks for these protocols by roughly 10%. +Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-12-04-16-45-11.gh-issue-74690.pQYP5U.rst b/Misc/NEWS.d/next/Library/2023-12-04-16-45-11.gh-issue-74690.pQYP5U.rst new file mode 100644 index 00000000000000..8102f02e941c29 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-04-16-45-11.gh-issue-74690.pQYP5U.rst @@ -0,0 +1,2 @@ +Speedup :func:`issubclass` checks against simple :func:`runtime-checkable +protocols ` by around 6%. Patch by Alex Waygood. diff --git a/Misc/NEWS.d/next/Library/2023-12-04-21-30-34.gh-issue-112727.jpgNRB.rst b/Misc/NEWS.d/next/Library/2023-12-04-21-30-34.gh-issue-112727.jpgNRB.rst new file mode 100644 index 00000000000000..bbe7aae5732d9a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-04-21-30-34.gh-issue-112727.jpgNRB.rst @@ -0,0 +1 @@ +Speed up :meth:`pathlib.Path.absolute`. Patch by Barney Gale. diff --git a/Misc/NEWS.d/next/Library/2023-12-05-01-19-28.gh-issue-112736.rdHDrU.rst b/Misc/NEWS.d/next/Library/2023-12-05-01-19-28.gh-issue-112736.rdHDrU.rst new file mode 100644 index 00000000000000..6c09e622923af8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-05-01-19-28.gh-issue-112736.rdHDrU.rst @@ -0,0 +1 @@ +The use of del-safe symbols in ``subprocess`` was refactored to allow for use in cross-platform build environments. diff --git a/Misc/NEWS.d/next/Library/2023-12-05-16-20-40.gh-issue-94692.-e5C3c.rst b/Misc/NEWS.d/next/Library/2023-12-05-16-20-40.gh-issue-94692.-e5C3c.rst new file mode 100644 index 00000000000000..c67ba6c9ececdb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-05-16-20-40.gh-issue-94692.-e5C3c.rst @@ -0,0 +1,4 @@ +:func:`shutil.rmtree` now only catches OSError exceptions. Previously a +symlink attack resistant version of ``shutil.rmtree()`` could ignore or pass +to the error handler arbitrary exception when invalid arguments were +provided. diff --git a/Misc/NEWS.d/next/Library/2023-12-05-18-57-53.gh-issue-79325.P2vMVK.rst b/Misc/NEWS.d/next/Library/2023-12-05-18-57-53.gh-issue-79325.P2vMVK.rst new file mode 100644 index 00000000000000..f3c32d27b5fe66 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-05-18-57-53.gh-issue-79325.P2vMVK.rst @@ -0,0 +1,2 @@ +Fix an infinite recursion error in :func:`tempfile.TemporaryDirectory` +cleanup on Windows. diff --git a/Misc/NEWS.d/next/Library/2023-12-06-14-06-14.gh-issue-51944.-5qq_L.rst b/Misc/NEWS.d/next/Library/2023-12-06-14-06-14.gh-issue-51944.-5qq_L.rst new file mode 100644 index 00000000000000..821eefa7cffcd5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-06-14-06-14.gh-issue-51944.-5qq_L.rst @@ -0,0 +1,6 @@ +Add the following constants to the :mod:`termios` module. These values are +present in macOS system headers: ``ALTWERASE``, ``B14400``, ``B28800``, +``B7200``, ``B76800``, ``CCAR_OFLOW``, ``CCTS_OFLOW``, ``CDSR_OFLOW``, +``CDTR_IFLOW``, ``CIGNORE``, ``CRTS_IFLOW``, ``EXTPROC``, ``IUTF8``, +``MDMBUF``, ``NL2``, ``NL3``, ``NOKERNINFO``, ``ONOEOT``, ``OXTABS``, +``VDSUSP``, ``VSTATUS``. diff --git a/Misc/NEWS.d/next/Library/2023-12-07-16-55-41.gh-issue-87286.MILC9_.rst b/Misc/NEWS.d/next/Library/2023-12-07-16-55-41.gh-issue-87286.MILC9_.rst new file mode 100644 index 00000000000000..bfeec3c95207cb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-07-16-55-41.gh-issue-87286.MILC9_.rst @@ -0,0 +1,3 @@ +Added :const:`LOG_FTP`, :const:`LOG_NETINFO`, :const:`LOG_REMOTEAUTH`, +:const:`LOG_INSTALL`, :const:`LOG_RAS`, and :const:`LOG_LAUNCHD` tot the +:mod:`syslog` module, all of them constants on used on macOS. diff --git a/Misc/NEWS.d/next/Library/2023-12-08-11-17-17.gh-issue-112540.Pm5egX.rst b/Misc/NEWS.d/next/Library/2023-12-08-11-17-17.gh-issue-112540.Pm5egX.rst new file mode 100644 index 00000000000000..263b13d1762bf1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-08-11-17-17.gh-issue-112540.Pm5egX.rst @@ -0,0 +1,2 @@ +The statistics.geometric_mean() function now returns zero for datasets +containing a zero. Formerly, it would raise an exception. diff --git a/Misc/NEWS.d/next/Library/2023-12-11-14-12-46.gh-issue-110190.e0iEUa.rst b/Misc/NEWS.d/next/Library/2023-12-11-14-12-46.gh-issue-110190.e0iEUa.rst new file mode 100644 index 00000000000000..3bfed1e0f1dc91 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-11-14-12-46.gh-issue-110190.e0iEUa.rst @@ -0,0 +1 @@ +Fix ctypes structs with array on PPC64LE platform by setting ``MAX_STRUCT_SIZE`` to 64 in stgdict. Patch by Diego Russo. diff --git a/Misc/NEWS.d/next/Library/2023-12-11-16-13-15.gh-issue-112970.87jmKP.rst b/Misc/NEWS.d/next/Library/2023-12-11-16-13-15.gh-issue-112970.87jmKP.rst new file mode 100644 index 00000000000000..58ca26af511383 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-11-16-13-15.gh-issue-112970.87jmKP.rst @@ -0,0 +1 @@ +Use :c:func:`!closefrom` on Linux where available (e.g. glibc-2.34), rather than only FreeBSD. diff --git a/Misc/NEWS.d/next/Library/2023-12-12-05-48-17.gh-issue-112989.ZAa_eq.rst b/Misc/NEWS.d/next/Library/2023-12-12-05-48-17.gh-issue-112989.ZAa_eq.rst new file mode 100644 index 00000000000000..ceeab8cc7d6bec --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-12-05-48-17.gh-issue-112989.ZAa_eq.rst @@ -0,0 +1 @@ +Reduce overhead to connect sockets with :mod:`asyncio` SelectorEventLoop. diff --git a/Misc/NEWS.d/next/Library/2023-12-12-16-32-55.gh-issue-112962.ZZWXZn.rst b/Misc/NEWS.d/next/Library/2023-12-12-16-32-55.gh-issue-112962.ZZWXZn.rst new file mode 100644 index 00000000000000..b99e6bc90ae791 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-12-16-32-55.gh-issue-112962.ZZWXZn.rst @@ -0,0 +1,3 @@ +:mod:`dis` module functions add cache information to the +:class:`~dis.Instruction` instance rather than creating fake +:class:`~dis.Instruction` instances to represent the cache entries. diff --git a/Misc/NEWS.d/next/Security/2023-03-07-21-46-29.gh-issue-102509.5ouaH_.rst b/Misc/NEWS.d/next/Security/2023-03-07-21-46-29.gh-issue-102509.5ouaH_.rst deleted file mode 100644 index d1a8e8b5a8d3c4..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-03-07-21-46-29.gh-issue-102509.5ouaH_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Start initializing ``ob_digit`` during creation of :c:type:`PyLongObject` -objects. Patch by Illia Volochii. 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-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 c67ec45737b535..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-06-13-20-52-24.gh-issue-102988.Kei7Vf.rst +++ /dev/null @@ -1,4 +0,0 @@ -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`. diff --git a/Misc/NEWS.d/next/Security/2023-08-05-03-51-05.gh-issue-107774.VPjaTR.rst b/Misc/NEWS.d/next/Security/2023-08-05-03-51-05.gh-issue-107774.VPjaTR.rst deleted file mode 100644 index b89b50c79f7e2a..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-08-05-03-51-05.gh-issue-107774.VPjaTR.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Security/2023-08-22-17-39-12.gh-issue-108310.fVM3sg.rst b/Misc/NEWS.d/next/Security/2023-08-22-17-39-12.gh-issue-108310.fVM3sg.rst deleted file mode 100644 index 403c77a9d480ee..00000000000000 --- a/Misc/NEWS.d/next/Security/2023-08-22-17-39-12.gh-issue-108310.fVM3sg.rst +++ /dev/null @@ -1,7 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Security/2023-12-06-14-06-59.gh-issue-112302.3bl20f.rst b/Misc/NEWS.d/next/Security/2023-12-06-14-06-59.gh-issue-112302.3bl20f.rst new file mode 100644 index 00000000000000..65e4dc3762d3c0 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2023-12-06-14-06-59.gh-issue-112302.3bl20f.rst @@ -0,0 +1,2 @@ +Created a Software Bill-of-Materials document and tooling for tracking +dependencies. diff --git a/Misc/NEWS.d/next/Tests/2020-05-16-18-00-21.bpo-40648.p2uPqy.rst b/Misc/NEWS.d/next/Tests/2020-05-16-18-00-21.bpo-40648.p2uPqy.rst new file mode 100644 index 00000000000000..8fbe42d263feb9 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-05-16-18-00-21.bpo-40648.p2uPqy.rst @@ -0,0 +1 @@ +Test modes that file can get with chmod() on Windows. diff --git a/Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst b/Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst deleted file mode 100644 index e28b94a171c40e..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-06-09-21-27-38.gh-issue-69714.49tyHW.rst +++ /dev/null @@ -1 +0,0 @@ -Add additional tests to :mod:`calendar` to achieve full test coverage. diff --git a/Misc/NEWS.d/next/Tests/2023-04-05-06-45-20.gh-issue-103186.640Eg-.rst b/Misc/NEWS.d/next/Tests/2023-04-05-06-45-20.gh-issue-103186.640Eg-.rst deleted file mode 100644 index 2f596aa5f47bda..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-04-05-06-45-20.gh-issue-103186.640Eg-.rst +++ /dev/null @@ -1 +0,0 @@ -Suppress and assert expected RuntimeWarnings in test_sys_settrace.py 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/Tests/2023-07-22-13-49-40.gh-issue-106714.btYI5S.rst b/Misc/NEWS.d/next/Tests/2023-07-22-13-49-40.gh-issue-106714.btYI5S.rst deleted file mode 100644 index 955620521c8f68..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-07-22-13-49-40.gh-issue-106714.btYI5S.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_capi: Fix test_no_FatalError_infinite_loop() to no longer write a -coredump, by using test.support.SuppressCrashReport. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-07-24-16-56-59.gh-issue-107178.Gq1usE.rst b/Misc/NEWS.d/next/Tests/2023-07-24-16-56-59.gh-issue-107178.Gq1usE.rst deleted file mode 100644 index dd6becf6b00130..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-07-24-16-56-59.gh-issue-107178.Gq1usE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add the C API test for functions in the Mapping Protocol, the Sequence -Protocol and some functions in the Object Protocol. diff --git a/Misc/NEWS.d/next/Tests/2023-07-25-14-36-33.gh-issue-107237.y1pY79.rst b/Misc/NEWS.d/next/Tests/2023-07-25-14-36-33.gh-issue-107237.y1pY79.rst deleted file mode 100644 index a04f7eeddef174..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-07-25-14-36-33.gh-issue-107237.y1pY79.rst +++ /dev/null @@ -1,2 +0,0 @@ -``test_logging``: Fix ``test_udp_reconnection()`` by increasing the timeout -from 100 ms to 5 minutes (LONG_TIMEOUT). Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-08-23-04-08-18.gh-issue-105776.oE6wp_.rst b/Misc/NEWS.d/next/Tests/2023-08-23-04-08-18.gh-issue-105776.oE6wp_.rst deleted file mode 100644 index 0e0a3aa9b11e68..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-08-23-04-08-18.gh-issue-105776.oE6wp_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_cppext when the C compiler command ``-std=c11`` option: remove -``-std=`` options from the compiler command. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-08-24-04-23-35.gh-issue-108388.mr0MeE.rst b/Misc/NEWS.d/next/Tests/2023-08-24-04-23-35.gh-issue-108388.mr0MeE.rst deleted file mode 100644 index 8cf77b1cc187f1..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-08-24-04-23-35.gh-issue-108388.mr0MeE.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-08-24-06-10-36.gh-issue-108388.YCVB0D.rst b/Misc/NEWS.d/next/Tests/2023-08-24-06-10-36.gh-issue-108388.YCVB0D.rst deleted file mode 100644 index ddff07be024d47..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-08-24-06-10-36.gh-issue-108388.YCVB0D.rst +++ /dev/null @@ -1,2 +0,0 @@ -Convert test_concurrent_futures to a package of 7 sub-tests. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-09-02-05-13-38.gh-issue-108794.tGHXBt.rst b/Misc/NEWS.d/next/Tests/2023-09-02-05-13-38.gh-issue-108794.tGHXBt.rst deleted file mode 100644 index 00027c7c07da2e..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-02-05-13-38.gh-issue-108794.tGHXBt.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-02-19-06-52.gh-issue-108822.arTbBI.rst b/Misc/NEWS.d/next/Tests/2023-09-02-19-06-52.gh-issue-108822.arTbBI.rst deleted file mode 100644 index e1c6df2adcb0ae..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-02-19-06-52.gh-issue-108822.arTbBI.rst +++ /dev/null @@ -1,4 +0,0 @@ -``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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-03-02-01-55.gh-issue-108834.iAwXzj.rst b/Misc/NEWS.d/next/Tests/2023-09-03-02-01-55.gh-issue-108834.iAwXzj.rst deleted file mode 100644 index 43b9948db0075c..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-03-02-01-55.gh-issue-108834.iAwXzj.rst +++ /dev/null @@ -1,6 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-03-06-17-12.gh-issue-108834.fjV-CJ.rst b/Misc/NEWS.d/next/Tests/2023-09-03-06-17-12.gh-issue-108834.fjV-CJ.rst deleted file mode 100644 index 734cc66aebee15..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-03-06-17-12.gh-issue-108834.fjV-CJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Rename regrtest ``--verbose2`` option (``-w``) to ``--rerun``. Keep -``--verbose2`` as a deprecated alias. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-09-03-20-15-49.gh-issue-108834.Osvmhf.rst b/Misc/NEWS.d/next/Tests/2023-09-03-20-15-49.gh-issue-108834.Osvmhf.rst deleted file mode 100644 index 098861ffa30374..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-03-20-15-49.gh-issue-108834.Osvmhf.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-03-21-18-35.gh-issue-108851.CCuHyI.rst b/Misc/NEWS.d/next/Tests/2023-09-03-21-18-35.gh-issue-108851.CCuHyI.rst deleted file mode 100644 index 7a5b3052af22f2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-03-21-18-35.gh-issue-108851.CCuHyI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add ``get_recursion_available()`` and ``get_recursion_depth()`` functions to -the :mod:`test.support` module. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-09-03-21-41-10.gh-issue-108851.xFTYOE.rst b/Misc/NEWS.d/next/Tests/2023-09-03-21-41-10.gh-issue-108851.xFTYOE.rst deleted file mode 100644 index b35aaebb410afb..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-03-21-41-10.gh-issue-108851.xFTYOE.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-04-15-18-14.gh-issue-89392.8A4T5p.rst b/Misc/NEWS.d/next/Tests/2023-09-04-15-18-14.gh-issue-89392.8A4T5p.rst deleted file mode 100644 index e1dea8e78cdd4e..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-04-15-18-14.gh-issue-89392.8A4T5p.rst +++ /dev/null @@ -1,2 +0,0 @@ -Removed support of ``test_main()`` function in tests. They now always use -normal unittest test runner. diff --git a/Misc/NEWS.d/next/Tests/2023-09-05-20-46-35.gh-issue-108927.TpwWav.rst b/Misc/NEWS.d/next/Tests/2023-09-05-20-46-35.gh-issue-108927.TpwWav.rst new file mode 100644 index 00000000000000..b1a78370afedb2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-09-05-20-46-35.gh-issue-108927.TpwWav.rst @@ -0,0 +1,4 @@ +Fixed order dependence in running tests in the same process +when a test that has submodules (e.g. test_importlib) follows a test that +imports its submodule (e.g. test_importlib.util) and precedes a test +(e.g. test_unittest or test_compileall) that uses that submodule. diff --git a/Misc/NEWS.d/next/Tests/2023-09-05-21-42-54.gh-issue-91960.abClTs.rst b/Misc/NEWS.d/next/Tests/2023-09-05-21-42-54.gh-issue-91960.abClTs.rst deleted file mode 100644 index f63e0874499193..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-05-21-42-54.gh-issue-91960.abClTs.rst +++ /dev/null @@ -1 +0,0 @@ -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). diff --git a/Misc/NEWS.d/next/Tests/2023-09-05-23-00-09.gh-issue-108962.R4NwuU.rst b/Misc/NEWS.d/next/Tests/2023-09-05-23-00-09.gh-issue-108962.R4NwuU.rst deleted file mode 100644 index 380fb20b8881b2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-05-23-00-09.gh-issue-108962.R4NwuU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Skip ``test_tempfile.test_flags()`` if ``chflags()`` fails with "OSError: -[Errno 45] Operation not supported" (ex: on FreeBSD 13). Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-09-06-15-36-51.gh-issue-91960.P3nD5v.rst b/Misc/NEWS.d/next/Tests/2023-09-06-15-36-51.gh-issue-91960.P3nD5v.rst deleted file mode 100644 index 46472abf9802bc..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-06-15-36-51.gh-issue-91960.P3nD5v.rst +++ /dev/null @@ -1,7 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-06-18-27-53.gh-issue-109015.1dS1AQ.rst b/Misc/NEWS.d/next/Tests/2023-09-06-18-27-53.gh-issue-109015.1dS1AQ.rst deleted file mode 100644 index cb641be9312e1a..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-06-18-27-53.gh-issue-109015.1dS1AQ.rst +++ /dev/null @@ -1,6 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-06-22-06-22.gh-issue-108996.IBhR3U.rst b/Misc/NEWS.d/next/Tests/2023-09-06-22-06-22.gh-issue-108996.IBhR3U.rst deleted file mode 100644 index 887f8b74bcfa30..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-06-22-06-22.gh-issue-108996.IBhR3U.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for ``msvcrt``. diff --git a/Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst b/Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst deleted file mode 100644 index 18e1e85242005a..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-10-19-59-57.gh-issue-109230.SRNLFQ.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-10-22-32-20.gh-issue-109237.SvgKwD.rst b/Misc/NEWS.d/next/Tests/2023-09-10-22-32-20.gh-issue-109237.SvgKwD.rst deleted file mode 100644 index 1d762bbe1d2592..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-10-22-32-20.gh-issue-109237.SvgKwD.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-10-23-05-50.gh-issue-108996.tJBru6.rst b/Misc/NEWS.d/next/Tests/2023-09-10-23-05-50.gh-issue-108996.tJBru6.rst deleted file mode 100644 index ab6b5b5952b044..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-10-23-05-50.gh-issue-108996.tJBru6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix and enable ``test_msvcrt``. diff --git a/Misc/NEWS.d/next/Tests/2023-09-11-18-19-52.gh-issue-109276.btfFtT.rst b/Misc/NEWS.d/next/Tests/2023-09-11-18-19-52.gh-issue-109276.btfFtT.rst deleted file mode 100644 index 5fcf6624f2e84d..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-11-18-19-52.gh-issue-109276.btfFtT.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-11-19-11-57.gh-issue-109276.qxI4OG.rst b/Misc/NEWS.d/next/Tests/2023-09-11-19-11-57.gh-issue-109276.qxI4OG.rst deleted file mode 100644 index cf4074b2fe23cc..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-11-19-11-57.gh-issue-109276.qxI4OG.rst +++ /dev/null @@ -1,6 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-13-05-58-09.gh-issue-104736.lA25Fu.rst b/Misc/NEWS.d/next/Tests/2023-09-13-05-58-09.gh-issue-104736.lA25Fu.rst deleted file mode 100644 index 85c370fc87ac41..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-13-05-58-09.gh-issue-104736.lA25Fu.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-14-22-58-47.gh-issue-109396.J1a4jR.rst b/Misc/NEWS.d/next/Tests/2023-09-14-22-58-47.gh-issue-109396.J1a4jR.rst deleted file mode 100644 index 71150ecae76434..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-14-22-58-47.gh-issue-109396.J1a4jR.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-14-23-27-40.gh-issue-109425.j-uFep.rst b/Misc/NEWS.d/next/Tests/2023-09-14-23-27-40.gh-issue-109425.j-uFep.rst deleted file mode 100644 index bfe18569ae97f3..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-14-23-27-40.gh-issue-109425.j-uFep.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-19-13-33-20.gh-issue-109566.aX0g9o.rst b/Misc/NEWS.d/next/Tests/2023-09-19-13-33-20.gh-issue-109566.aX0g9o.rst deleted file mode 100644 index 10f90132c37ec9..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-19-13-33-20.gh-issue-109566.aX0g9o.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-19-19-08-22.gh-issue-109580.G02Zam.rst b/Misc/NEWS.d/next/Tests/2023-09-19-19-08-22.gh-issue-109580.G02Zam.rst deleted file mode 100644 index b917cbf6fd0a05..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-19-19-08-22.gh-issue-109580.G02Zam.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-20-02-32-17.gh-issue-103053.AoUJuK.rst b/Misc/NEWS.d/next/Tests/2023-09-20-02-32-17.gh-issue-103053.AoUJuK.rst deleted file mode 100644 index 6d67bf237bdbb2..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-20-02-32-17.gh-issue-103053.AoUJuK.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-25-14-41-18.gh-issue-109276.uC_cWo.rst b/Misc/NEWS.d/next/Tests/2023-09-25-14-41-18.gh-issue-109276.uC_cWo.rst deleted file mode 100644 index 66651cf6f4b966..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-25-14-41-18.gh-issue-109276.uC_cWo.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-25-23-59-37.gh-issue-109739.MUn7K5.rst b/Misc/NEWS.d/next/Tests/2023-09-25-23-59-37.gh-issue-109739.MUn7K5.rst deleted file mode 100644 index 291524c758ca68..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-25-23-59-37.gh-issue-109739.MUn7K5.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-26-00-49-18.gh-issue-109748.nxlT1i.rst b/Misc/NEWS.d/next/Tests/2023-09-26-00-49-18.gh-issue-109748.nxlT1i.rst deleted file mode 100644 index 840366ba8d1611..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-26-00-49-18.gh-issue-109748.nxlT1i.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-26-18-12-01.gh-issue-109566.CP0Vhf.rst b/Misc/NEWS.d/next/Tests/2023-09-26-18-12-01.gh-issue-109566.CP0Vhf.rst deleted file mode 100644 index d865f629fdb05b..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-26-18-12-01.gh-issue-109566.CP0Vhf.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-28-12-25-19.gh-issue-109972.GYnwIP.rst b/Misc/NEWS.d/next/Tests/2023-09-28-12-25-19.gh-issue-109972.GYnwIP.rst deleted file mode 100644 index 7b6007678388b1..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-28-12-25-19.gh-issue-109972.GYnwIP.rst +++ /dev/null @@ -1,2 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-28-14-47-14.gh-issue-109594.DB5KPP.rst b/Misc/NEWS.d/next/Tests/2023-09-28-14-47-14.gh-issue-109594.DB5KPP.rst deleted file mode 100644 index 5a4ae2b0837df6..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-28-14-47-14.gh-issue-109594.DB5KPP.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-28-18-14-52.gh-issue-110033.2yHMx0.rst b/Misc/NEWS.d/next/Tests/2023-09-28-18-14-52.gh-issue-110033.2yHMx0.rst deleted file mode 100644 index fb6089377083bf..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-28-18-14-52.gh-issue-110033.2yHMx0.rst +++ /dev/null @@ -1,5 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-29-00-19-21.gh-issue-109974.Sh_g-r.rst b/Misc/NEWS.d/next/Tests/2023-09-29-00-19-21.gh-issue-109974.Sh_g-r.rst deleted file mode 100644 index a130cf690a57cb..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-29-00-19-21.gh-issue-109974.Sh_g-r.rst +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-29-12-48-42.gh-issue-110088.qUhRga.rst b/Misc/NEWS.d/next/Tests/2023-09-29-12-48-42.gh-issue-110088.qUhRga.rst deleted file mode 100644 index cf44a123c2c925..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-29-12-48-42.gh-issue-110088.qUhRga.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tests/2023-09-29-14-11-30.gh-issue-110031.fQnFnc.rst b/Misc/NEWS.d/next/Tests/2023-09-29-14-11-30.gh-issue-110031.fQnFnc.rst deleted file mode 100644 index a8a163c567d2b3..00000000000000 --- a/Misc/NEWS.d/next/Tests/2023-09-29-14-11-30.gh-issue-110031.fQnFnc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Skip test_threading tests using thread+fork if Python is built with Address -Sanitizer (ASAN). Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2023-12-04-15-56-11.gh-issue-112334.FFc9Ti.rst b/Misc/NEWS.d/next/Tests/2023-12-04-15-56-11.gh-issue-112334.FFc9Ti.rst new file mode 100644 index 00000000000000..aeaad6e5055522 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-12-04-15-56-11.gh-issue-112334.FFc9Ti.rst @@ -0,0 +1,2 @@ +Adds a regression test to verify that ``vfork()`` is used when expected by +:mod:`subprocess` on vfork enabled POSIX systems (Linux). diff --git a/Misc/NEWS.d/next/Tests/2023-12-05-19-50-03.gh-issue-112769.kdLJmS.rst b/Misc/NEWS.d/next/Tests/2023-12-05-19-50-03.gh-issue-112769.kdLJmS.rst new file mode 100644 index 00000000000000..1bbbb26fc322fa --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-12-05-19-50-03.gh-issue-112769.kdLJmS.rst @@ -0,0 +1,3 @@ +The tests now correctly compare zlib version when +:const:`zlib.ZLIB_RUNTIME_VERSION` contains non-integer suffixes. For +example zlib-ng defines the version as ``1.3.0.zlib-ng``. diff --git a/Misc/NEWS.d/next/Tests/2023-12-09-21-27-46.gh-issue-109980.y--500.rst b/Misc/NEWS.d/next/Tests/2023-12-09-21-27-46.gh-issue-109980.y--500.rst new file mode 100644 index 00000000000000..c475a33919db98 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-12-09-21-27-46.gh-issue-109980.y--500.rst @@ -0,0 +1,2 @@ +Fix ``test_tarfile_vs_tar`` in ``test_shutil`` for macOS, where system tar +can include more information in the archive than :mod:`shutil.make_archive`. diff --git a/Misc/NEWS.d/next/Tools-Demos/2022-07-23-00-33-28.gh-issue-95065.NfCCpp.rst b/Misc/NEWS.d/next/Tools-Demos/2022-07-23-00-33-28.gh-issue-95065.NfCCpp.rst deleted file mode 100644 index 3641716769cd56..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2022-07-23-00-33-28.gh-issue-95065.NfCCpp.rst +++ /dev/null @@ -1,6 +0,0 @@ -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 :ref:`clinic-howto-deprecate-positional` for more information. -Patch by Erlend E. Aasland with help from Alex Waygood, -Nikita Sobolev, and Serhiy Storchaka. 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/Tools-Demos/2023-07-21-23-16-05.gh-issue-106970.NLRnml.rst b/Misc/NEWS.d/next/Tools-Demos/2023-07-21-23-16-05.gh-issue-106970.NLRnml.rst deleted file mode 100644 index 194e3351b0470c..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-07-21-23-16-05.gh-issue-106970.NLRnml.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-07-30-23-32-16.gh-issue-107467.5O9p3G.rst b/Misc/NEWS.d/next/Tools-Demos/2023-07-30-23-32-16.gh-issue-107467.5O9p3G.rst deleted file mode 100644 index 2996837371be0f..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-07-30-23-32-16.gh-issue-107467.5O9p3G.rst +++ /dev/null @@ -1,2 +0,0 @@ -The Argument Clinic command-line tool now prints to stderr instead of stdout -on failure. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-04-00-04-40.gh-issue-107609.2DqgtL.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-04-00-04-40.gh-issue-107609.2DqgtL.rst deleted file mode 100644 index 080a6c15d9b8c5..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-08-04-00-04-40.gh-issue-107609.2DqgtL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix duplicate module check in Argument Clinic. Previously, a duplicate -definition would incorrectly be silently accepted. Patch by Erlend E. -Aasland. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-07-16-30-48.gh-issue-95065.-im4R5.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-07-16-30-48.gh-issue-95065.-im4R5.rst deleted file mode 100644 index 7284f5bd548810..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-08-07-16-30-48.gh-issue-95065.-im4R5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Argument Clinic now supports overriding automatically generated signature by -using directive ``@text_signature``. See :ref:`clinic-howto-override-signature`. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-08-12-21-41.gh-issue-104683.DRsAQE.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-08-12-21-41.gh-issue-104683.DRsAQE.rst deleted file mode 100644 index ee3a70967b098b..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-08-08-12-21-41.gh-issue-104683.DRsAQE.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``--exclude`` option to Argument Clinic CLI. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-13-11-18-06.gh-issue-107880.gBVVQ7.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-13-11-18-06.gh-issue-107880.gBVVQ7.rst deleted file mode 100644 index fd9d6717f3a33f..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-08-13-11-18-06.gh-issue-107880.gBVVQ7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Argument Clinic can now clone :meth:`!__init__` and :meth:`!__new__` -methods. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst deleted file mode 100644 index ffdcfa6a429e64..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-08-15-19-50-49.gh-issue-107704.Uu84vd.rst +++ /dev/null @@ -1,4 +0,0 @@ -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 :ref:`clinic-howto-deprecate-keyword` for more information. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-08-25-22-40-12.gh-issue-108494.4RbDdu.rst b/Misc/NEWS.d/next/Tools-Demos/2023-08-25-22-40-12.gh-issue-108494.4RbDdu.rst deleted file mode 100644 index b96da7c0a16df8..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-08-25-22-40-12.gh-issue-108494.4RbDdu.rst +++ /dev/null @@ -1,3 +0,0 @@ -:ref:`Argument Clinic ` now has a partial support of the -:ref:`Limited API `: see :ref:`clinic-howto-limited-capi`. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst b/Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst deleted file mode 100644 index 13c1163ab53443..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update GitHub CI workflows to use OpenSSL 3.0.11 and multissltests to use -1.1.1w, 3.0.11, and 3.1.3. 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-18-13-01-26.gh-issue-106844.mci4xO.rst b/Misc/NEWS.d/next/Windows/2023-07-18-13-01-26.gh-issue-106844.mci4xO.rst deleted file mode 100644 index 1fdf162ef4ecdd..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-07-18-13-01-26.gh-issue-106844.mci4xO.rst +++ /dev/null @@ -1 +0,0 @@ -Fix integer overflow and truncating by the null character in :func:`!_winapi.LCMapStringEx` which affects :func:`ntpath.normcase`. diff --git a/Misc/NEWS.d/next/Windows/2023-08-22-00-36-57.gh-issue-106242.q24ITw.rst b/Misc/NEWS.d/next/Windows/2023-08-22-00-36-57.gh-issue-106242.q24ITw.rst deleted file mode 100644 index ffe42ec5dc3faf..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-08-22-00-36-57.gh-issue-106242.q24ITw.rst +++ /dev/null @@ -1,4 +0,0 @@ -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. diff --git a/Misc/NEWS.d/next/Windows/2023-09-28-17-09-23.gh-issue-109991.CIMftz.rst b/Misc/NEWS.d/next/Windows/2023-09-28-17-09-23.gh-issue-109991.CIMftz.rst deleted file mode 100644 index ee988f90863426..00000000000000 --- a/Misc/NEWS.d/next/Windows/2023-09-28-17-09-23.gh-issue-109991.CIMftz.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows build to use OpenSSL 3.0.11. diff --git a/Misc/NEWS.d/next/Windows/2023-12-03-19-22-37.gh-issue-112278.FiloCE.rst b/Misc/NEWS.d/next/Windows/2023-12-03-19-22-37.gh-issue-112278.FiloCE.rst new file mode 100644 index 00000000000000..0350d105d97375 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-12-03-19-22-37.gh-issue-112278.FiloCE.rst @@ -0,0 +1,2 @@ +Reduce the time cost for some functions in :mod:`platform` on Windows if +current user has no permission to the WMI. diff --git a/Misc/NEWS.d/next/Windows/2023-12-05-22-56-30.gh-issue-111650.xlWmvM.rst b/Misc/NEWS.d/next/Windows/2023-12-05-22-56-30.gh-issue-111650.xlWmvM.rst new file mode 100644 index 00000000000000..5a3493356e30be --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-12-05-22-56-30.gh-issue-111650.xlWmvM.rst @@ -0,0 +1,3 @@ +Ensures the ``Py_GIL_DISABLED`` preprocessor variable is defined in +:file:`pyconfig.h` so that extension modules written in C are able to use +it. diff --git a/Misc/NEWS.d/next/Windows/2023-12-11-20-23-04.gh-issue-71383.9pZh6t.rst b/Misc/NEWS.d/next/Windows/2023-12-11-20-23-04.gh-issue-71383.9pZh6t.rst new file mode 100644 index 00000000000000..cf2883357a962a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-12-11-20-23-04.gh-issue-71383.9pZh6t.rst @@ -0,0 +1,2 @@ +Update Tcl/Tk in Windows installer to 8.6.13 with a patch to suppress +incorrect ThemeChanged warnings. diff --git a/Misc/NEWS.d/next/macOS/2023-07-30-23-42-20.gh-issue-99079.JAtoh1.rst b/Misc/NEWS.d/next/macOS/2023-07-30-23-42-20.gh-issue-99079.JAtoh1.rst deleted file mode 100644 index d0eef4ec1003ce..00000000000000 --- a/Misc/NEWS.d/next/macOS/2023-07-30-23-42-20.gh-issue-99079.JAtoh1.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use OpenSSL 3.0.9. diff --git a/Misc/NEWS.d/next/macOS/2023-09-27-22-35-22.gh-issue-109991.-xJzaF.rst b/Misc/NEWS.d/next/macOS/2023-09-27-22-35-22.gh-issue-109991.-xJzaF.rst deleted file mode 100644 index 8d369988274f28..00000000000000 --- a/Misc/NEWS.d/next/macOS/2023-09-27-22-35-22.gh-issue-109991.-xJzaF.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use OpenSSL 3.0.11. diff --git a/Misc/NEWS.d/next/macOS/2023-12-06-12-11-13.gh-issue-109981.mOHg10.rst b/Misc/NEWS.d/next/macOS/2023-12-06-12-11-13.gh-issue-109981.mOHg10.rst new file mode 100644 index 00000000000000..f86ab2c37ee6ec --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2023-12-06-12-11-13.gh-issue-109981.mOHg10.rst @@ -0,0 +1,3 @@ +Use ``/dev/fd`` on macOS to determine the number of open files in +``test.support.os_helper.fd_count`` to avoid a crash with "guarded" file +descriptors when probing for open files. diff --git a/Misc/NEWS.d/next/macOS/2023-12-07-14-19-46.gh-issue-110820.DIxb_F.rst b/Misc/NEWS.d/next/macOS/2023-12-07-14-19-46.gh-issue-110820.DIxb_F.rst new file mode 100644 index 00000000000000..0badace7928745 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2023-12-07-14-19-46.gh-issue-110820.DIxb_F.rst @@ -0,0 +1,3 @@ +Make sure the preprocessor definitions for ``ALIGNOF_MAX_ALIGN_T``, +``SIZEOF_LONG_DOUBLE`` and ``HAVE_GCC_ASM_FOR_X64`` are correct for +Universal 2 builds on macOS. diff --git a/Misc/NEWS.d/next/macOS/2023-12-07-15-53-16.gh-issue-110017.UMYzMR.rst b/Misc/NEWS.d/next/macOS/2023-12-07-15-53-16.gh-issue-110017.UMYzMR.rst new file mode 100644 index 00000000000000..eab1746f1ae3f7 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2023-12-07-15-53-16.gh-issue-110017.UMYzMR.rst @@ -0,0 +1,2 @@ +Disable a signal handling stress test on macOS due to a bug in macOS +(FB13453490). 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/sbom.spdx.json b/Misc/sbom.spdx.json new file mode 100644 index 00000000000000..09355640db888e --- /dev/null +++ b/Misc/sbom.spdx.json @@ -0,0 +1,2294 @@ +{ + "SPDXID": "SPDXRef-DOCUMENT", + "files": [ + { + "SPDXID": "SPDXRef-FILE-Modules-expat-COPYING", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "39e6f567a10e36b2e77727e98e60bbcb3eb3af0b" + }, + { + "algorithm": "SHA256", + "checksumValue": "122f2c27000472a201d337b9b31f7eb2b52d091b02857061a8880371612d9534" + } + ], + "fileName": "Modules/expat/COPYING" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-ascii.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b0235fa3cf845a7d68e8e66dd344d5e32e8951b5" + }, + { + "algorithm": "SHA256", + "checksumValue": "42f8b392c70366743eacbc60ce021389ccaa333598dd49eef6ee5c93698ca205" + } + ], + "fileName": "Modules/expat/ascii.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-asciitab.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "cbb53d16ca1f35ee9c9e296116efd222ae611ed9" + }, + { + "algorithm": "SHA256", + "checksumValue": "1cc0ae749019fc0e488cd1cf245f6beaa6d4f7c55a1fc797e5aa40a408bc266b" + } + ], + "fileName": "Modules/expat/asciitab.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-expat.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ab7bb32514d170592dfb3f76e41bbdc075a4e7e0" + }, + { + "algorithm": "SHA256", + "checksumValue": "f521acdad222644365b0e81a33bcd6939a98c91b225c47582cc84bd73d96febc" + } + ], + "fileName": "Modules/expat/expat.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-expat-config.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "73627287302ee3e84347c4fe21f37a9cb828bc3b" + }, + { + "algorithm": "SHA256", + "checksumValue": "f17e59f9d95eeb05694c02508aa284d332616c22cbe2e6a802d8a0710310eaab" + } + ], + "fileName": "Modules/expat/expat_config.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-expat-external.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b70ce53fdc25ae482681ae2f6623c3c8edc9c1b7" + }, + { + "algorithm": "SHA256", + "checksumValue": "86afb425ec9999eb4f1ec9ab2fb41c58c4aa5cb9bf934b8c94264670fc5a961d" + } + ], + "fileName": "Modules/expat/expat_external.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-iasciitab.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "1b0e9014c0baa4c6254d2b5e6a67c70148309c34" + }, + { + "algorithm": "SHA256", + "checksumValue": "ad8b01e9f323cc4208bcd22241df383d7e8641fe3c8b3415aa513de82531f89f" + } + ], + "fileName": "Modules/expat/iasciitab.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-internal.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "2790d37e7de2f13dccc4f4fb352cbdf9ed6abaa2" + }, + { + "algorithm": "SHA256", + "checksumValue": "d2efe5a1018449968a689f444cca432e3d5875aba6ad08ee18ca235d64f41bb9" + } + ], + "fileName": "Modules/expat/internal.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-latin1tab.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d335ecca380e331a0ea7dc33838a4decd93ec1e4" + }, + { + "algorithm": "SHA256", + "checksumValue": "eab66226da100372e01e42e1cbcd8ac2bbbb5c1b5f95d735289cc85c7a8fc2ba" + } + ], + "fileName": "Modules/expat/latin1tab.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-nametab.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "cf2bc9626c945826602ba9170786e9a2a44645e4" + }, + { + "algorithm": "SHA256", + "checksumValue": "67dcf415d37a4b692a6a8bb46f990c02d83f2ef3d01a65cd61c8594a084246f2" + } + ], + "fileName": "Modules/expat/nametab.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-pyexpatns.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "baa44fe4581895d42e8d5e83d8ce6a69b1c34dbe" + }, + { + "algorithm": "SHA256", + "checksumValue": "33a7b9ac8bf4571e23272cdf644c6f9808bd44c66b149e3c41ab3870d1888609" + } + ], + "fileName": "Modules/expat/pyexpatns.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-siphash.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "2b984f806f10fbfbf72d8d1b7ba2992413c15299" + }, + { + "algorithm": "SHA256", + "checksumValue": "fbce56cd680e690043bbf572188cc2d0a25dbfc0d47ac8cb98eb3de768d4e694" + } + ], + "fileName": "Modules/expat/siphash.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-utf8tab.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b77c8fcfb551553c81d6fbd94c798c8aa04ad021" + }, + { + "algorithm": "SHA256", + "checksumValue": "8cd26bd461d334d5e1caedb3af4518d401749f2fc66d56208542b29085159c18" + } + ], + "fileName": "Modules/expat/utf8tab.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-winconfig.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "e774ae6ee9391aa6ffb8f775fb74e48f4b428959" + }, + { + "algorithm": "SHA256", + "checksumValue": "3c71cea9a6174718542331971a35db317902b2433be9d8dd1cb24239b635c0cc" + } + ], + "fileName": "Modules/expat/winconfig.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmlparse.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b580e827e16baa6b035586ffcd4d90301e5a353f" + }, + { + "algorithm": "SHA256", + "checksumValue": "483518bbd69338eefc706cd7fc0b6039df2d3e347f64097989059ed6d2385a1e" + } + ], + "fileName": "Modules/expat/xmlparse.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmlrole.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "5ef21312af73deb2428be3fe97a65244608e76de" + }, + { + "algorithm": "SHA256", + "checksumValue": "6fcf8c72ac0112c1b98bd2039c632a66b4c3dc516ce7c1f981390951121ef3c0" + } + ], + "fileName": "Modules/expat/xmlrole.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmlrole.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c1a4ea6356643d0820edb9c024c20ad2aaf562dc" + }, + { + "algorithm": "SHA256", + "checksumValue": "2b5d674be6ef20c7e3f69295176d75e68c5616e4dfce0a186fdd5e2ed8315f7a" + } + ], + "fileName": "Modules/expat/xmlrole.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmltok.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "e6d66ae9fd61d7950c62c5d87693c30a707e8577" + }, + { + "algorithm": "SHA256", + "checksumValue": "1110f651bdccfa765ad3d6f3857a35887ab35fc0fe7f3f3488fde2b238b482e3" + } + ], + "fileName": "Modules/expat/xmltok.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmltok.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "9c2a544875fd08ba9c2397296c97263518a410aa" + }, + { + "algorithm": "SHA256", + "checksumValue": "4299a03828b98bfe47ec6809f6e279252954a9a911dc7e0f19551bd74e3af971" + } + ], + "fileName": "Modules/expat/xmltok.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmltok-impl.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "aa96882de8e3d1d3083124b595aa911efe44e5ad" + }, + { + "algorithm": "SHA256", + "checksumValue": "0fbcba7931707c60301305dab78d2298d96447d0a5513926d8b18135228c0818" + } + ], + "fileName": "Modules/expat/xmltok_impl.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmltok-impl.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "788332fe8040bed71172cddedb69abd848cc62f7" + }, + { + "algorithm": "SHA256", + "checksumValue": "f05ad4fe5e98429a7349ff04f57192cac58c324601f2a2e5e697ab0bc05d36d5" + } + ], + "fileName": "Modules/expat/xmltok_impl.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-expat-xmltok-ns.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "2d82d0a1201f78d478b30d108ff8fc27ee3e2672" + }, + { + "algorithm": "SHA256", + "checksumValue": "6ce6d03193279078d55280150fe91e7370370b504a6c123a79182f28341f3e90" + } + ], + "fileName": "Modules/expat/xmltok_ns.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-MD5.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "f77449b2b4eb99f1da0938633cc558baf9c444fb" + }, + { + "algorithm": "SHA256", + "checksumValue": "0f252967debca5b35362ca53951ea16ca8bb97a19a1d24f6695f44d50010859e" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_MD5.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-MD5.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c24e6779a91c840f3d65d24abbce225b608b676e" + }, + { + "algorithm": "SHA256", + "checksumValue": "9cd062e782801013e3cacaba583e44e1b5e682e217d20208d5323354d42011f1" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_MD5.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA1.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "560f6ff541b5eff480ea047b147f4212bb0db7ed" + }, + { + "algorithm": "SHA256", + "checksumValue": "0ade3ab264e912d7b4e5cdcf773db8c63e4440540d295922d74b06bcfc74c77a" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_SHA1.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA1.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "853b77d45379146faaeac5fe899b28db386ad13c" + }, + { + "algorithm": "SHA256", + "checksumValue": "b13eb14f91582703819235ea7c8f807bb93e4f1e6b695499dc1d86021dc39e72" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_SHA1.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA2.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "667120b6100c946cdaa442f1173c723339923071" + }, + { + "algorithm": "SHA256", + "checksumValue": "b189459b863341a3a9c5c78c0208b6554a2f2ac26e0748fbd4432a91db21fae6" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_SHA2.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA2.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "81db38b0b920e63ec33c7109d1144c35cf091da0" + }, + { + "algorithm": "SHA256", + "checksumValue": "631c9ba19c1c2c835bb63d3f2f22b8d76fb535edfed3c254ff2a52f12af3fe61" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_SHA2.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA3.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "9c832b98a2f2a68202d2da016fb718965d7b7602" + }, + { + "algorithm": "SHA256", + "checksumValue": "38d350d1184238966cfa821a59ae00343f362182b6c2fbea7f2651763d757fb7" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_SHA3.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA3.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ecc766fb6f7ee85e902b593b61b41e5a728fca34" + }, + { + "algorithm": "SHA256", + "checksumValue": "bae290a94366a2460f51e8468144baaade91d9048db111e10d2e2ffddc3f98cf" + } + ], + "fileName": "Modules/_hacl/Hacl_Hash_SHA3.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-Hacl-Streaming-Types.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ab7b4d9465a2765a07f8d5bccace7182b28ed1b8" + }, + { + "algorithm": "SHA256", + "checksumValue": "26913613f3b4f8ffff0a3e211a5ebc849159094e5e11de0a31fcb95b6105b74c" + } + ], + "fileName": "Modules/_hacl/Hacl_Streaming_Types.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-include-krml-FStar-UInt128-Verified.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "2ea61d6a236147462045f65c20311819d74db80c" + }, + { + "algorithm": "SHA256", + "checksumValue": "2c22b4d49ba06d6a3053cdc66405bd5ae953a28fcfed1ab164e8f5e0f6e2fb8b" + } + ], + "fileName": "Modules/_hacl/include/krml/FStar_UInt128_Verified.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-include-krml-FStar-UInt-8-16-32-64.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "1a647d841180ac8ca667afa968c353425e81ad0d" + }, + { + "algorithm": "SHA256", + "checksumValue": "e5d1c5854833bec7ea02e227ec35bd7b49c5fb9e0f339efa0dd83e1595f722d4" + } + ], + "fileName": "Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-include-krml-fstar-uint128-struct-endianness.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "1987119a563a8fdc5966286e274f716dbcea77ee" + }, + { + "algorithm": "SHA256", + "checksumValue": "fe57e1bc5ce3224d106e36cb8829b5399c63a68a70b0ccd0c91d82a4565c8869" + } + ], + "fileName": "Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-include-krml-internal-target.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "903c9eb76b01f3a95c04c3bc841c2fb71dea5403" + }, + { + "algorithm": "SHA256", + "checksumValue": "08ec602c7f90a1540389c0cfc95769fa7fec251e7ca143ef83c0b9f7afcf89a7" + } + ], + "fileName": "Modules/_hacl/include/krml/internal/target.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-include-krml-lowstar-endianness.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "964e09bd99ff2366afd6193b59863fc925e7fb05" + }, + { + "algorithm": "SHA256", + "checksumValue": "3734c7942bec9a434e16df069fa45bdcb84b130f14417bc5f7bfe8546272d9f5" + } + ], + "fileName": "Modules/_hacl/include/krml/lowstar_endianness.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-include-krml-types.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "df8e0ed74a5970d09d3cc4c6e7c6c7a4c4e5015c" + }, + { + "algorithm": "SHA256", + "checksumValue": "de7444c345caa4c47902c4380500356a3ee7e199d2aab84fd8c4960410154f3d" + } + ], + "fileName": "Modules/_hacl/include/krml/types.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-MD5.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "5dd4ee3c835a0d176a6e9fecbe9752fd1474ff41" + }, + { + "algorithm": "SHA256", + "checksumValue": "d82ef594cba44203576d67b047240316bb3c542912ebb7034afa1e07888cec56" + } + ], + "fileName": "Modules/_hacl/internal/Hacl_Hash_MD5.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-SHA1.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "515b3082eb7c30597773e1c63ec46688f6da3634" + }, + { + "algorithm": "SHA256", + "checksumValue": "10aacf847006b8e0dfb64d5c327443f954db6718b4aec712fb3268230df6a752" + } + ], + "fileName": "Modules/_hacl/internal/Hacl_Hash_SHA1.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-SHA2.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "a044ec12b70ba97b67e9a312827d6270452a20ca" + }, + { + "algorithm": "SHA256", + "checksumValue": "a1426b54fa7273ba5b50817c25b2b26fc85c4d1befb14092cd27dc4c99439463" + } + ], + "fileName": "Modules/_hacl/internal/Hacl_Hash_SHA2.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-SHA3.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "cfb7b520c39a73cb84c541d370455f92b998781f" + }, + { + "algorithm": "SHA256", + "checksumValue": "fd41997f9e96b3c9a3337b1b51fab965a1e21b0c16f353d156f1a1fa00709fbf" + } + ], + "fileName": "Modules/_hacl/internal/Hacl_Hash_SHA3.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-hacl-python-hacl-namespaces.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "f5c7b3ed911af6c8d582e8b3714b0c36195dc994" + }, + { + "algorithm": "SHA256", + "checksumValue": "07de72398b12957e014e97b9ac197bceef12d6d6505c2bfe8b23ee17b94ec5fa" + } + ], + "fileName": "Modules/_hacl/python_hacl_namespaces.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2-config.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ff5e3ae2360adf7279a9c54d12a1d32e16a1f223" + }, + { + "algorithm": "SHA256", + "checksumValue": "1eb919e885244e43cdf7b2104ad30dc9271513478c0026f6bfb4bad6e2f0ab42" + } + ], + "fileName": "Modules/_blake2/impl/blake2-config.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2-impl.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "28b947b43bdc680b9f4335712bb2a5f2d5d32623" + }, + { + "algorithm": "SHA256", + "checksumValue": "4277092643b289f1d36d32cf0fd2efc30ead8bdd99342e5da3b3609dd8ea7d86" + } + ], + "fileName": "Modules/_blake2/impl/blake2-impl.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "caa3da7953109d0d2961e3b686d2d285c484b901" + }, + { + "algorithm": "SHA256", + "checksumValue": "2f6c9d0ecf70be474f2853b52394993625a32960e0a64eae147ef97a3a5c1460" + } + ], + "fileName": "Modules/_blake2/impl/blake2.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2b-load-sse2.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "029a98f87a178936d9e5211c7798b3e0fc622f94" + }, + { + "algorithm": "SHA256", + "checksumValue": "b392a6e7b43813a05609e994db5fc3552c5912bd482efc781daa0778eb56ab4e" + } + ], + "fileName": "Modules/_blake2/impl/blake2b-load-sse2.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2b-load-sse41.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "fb466dd72344170d09e311e5ea12de99ce071357" + }, + { + "algorithm": "SHA256", + "checksumValue": "cc3072c92164142bf2f9dda4e6c08db61be68ec15a95442415e861090d08f6a2" + } + ], + "fileName": "Modules/_blake2/impl/blake2b-load-sse41.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2b-ref.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4c0d79128cf891a95b1f668031d55c0c6d2e0270" + }, + { + "algorithm": "SHA256", + "checksumValue": "07b257d44e9cc2d95d4911629c92138feafd16d63fef0a5fa7b38914dfd82349" + } + ], + "fileName": "Modules/_blake2/impl/blake2b-ref.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2b-round.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4c7418e2026417c9c6736fcd305a31f23e05a661" + }, + { + "algorithm": "SHA256", + "checksumValue": "fa34a60c2d198a0585033f43fd4003f4ba279c9ebcabdf5d6650def0e6d1e914" + } + ], + "fileName": "Modules/_blake2/impl/blake2b-round.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2b.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "6fa074693aa7305018dfa8db48010a8ef1050ad4" + }, + { + "algorithm": "SHA256", + "checksumValue": "c8c6dd861ac193d4a0e836242ff44900f83423f86d2c2940c8c4c1e41fbd5812" + } + ], + "fileName": "Modules/_blake2/impl/blake2b.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2s-load-sse2.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ad3f79b6cbe3fd812722114a0d5d08064e69e4d0" + }, + { + "algorithm": "SHA256", + "checksumValue": "57f1ac6c09f4a50d95811529062220eab4f29cec3805bc6081dec00426c6df62" + } + ], + "fileName": "Modules/_blake2/impl/blake2s-load-sse2.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2s-load-sse41.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "51c32d79f419f3d2eb9875cd9a7f5c0d7892f8a8" + }, + { + "algorithm": "SHA256", + "checksumValue": "ecc9e09adcbe098629eafd305596bed8d7004be1d83f326995def42bbde93b23" + } + ], + "fileName": "Modules/_blake2/impl/blake2s-load-sse41.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2s-load-xop.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "2749a7ba0104b765d4f56f13faf70b6eb89cf203" + }, + { + "algorithm": "SHA256", + "checksumValue": "8bc95595cec4c50f5d70f2b330d3798de07cc784e8890791b3328890e602d5c5" + } + ], + "fileName": "Modules/_blake2/impl/blake2s-load-xop.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2s-ref.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "883fcfe85f9063819f21b1100296d1f9eb55bac1" + }, + { + "algorithm": "SHA256", + "checksumValue": "9715c00d0f11587a139b07fa26678e6d26e44d3d4910b96158d158da2b022bfb" + } + ], + "fileName": "Modules/_blake2/impl/blake2s-ref.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2s-round.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "5d9f69adda40ed163b287b9ed4cedb35b88f2daa" + }, + { + "algorithm": "SHA256", + "checksumValue": "65d90111c89c43bb18a9e1d1a4fdbd9f85bebd1ff00129335b85995d0f30ee8b" + } + ], + "fileName": "Modules/_blake2/impl/blake2s-round.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-blake2-impl-blake2s.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d2691353fa54ac6ffcd7c0a294984dc9d7968ef7" + }, + { + "algorithm": "SHA256", + "checksumValue": "cfd7948c9fd50e9f9c62f8a93b20a254d1d510a862d1092af4f187b7c1a859a3" + } + ], + "fileName": "Modules/_blake2/impl/blake2s.c" + }, + { + "SPDXID": "SPDXRef-FILE-Lib-ctypes-macholib-init-.py", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "0fbc026a9771d9675e7094790b5b945334d3cb53" + }, + { + "algorithm": "SHA256", + "checksumValue": "1e77c01eec8f167ed10b754f153c0c743c8e5196ae9c81dffc08f129ab56dbfd" + } + ], + "fileName": "Lib/ctypes/macholib/__init__.py" + }, + { + "SPDXID": "SPDXRef-FILE-Lib-ctypes-macholib-dyld.py", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4a78ebd73ce4167c722689781a15fe0b4578e967" + }, + { + "algorithm": "SHA256", + "checksumValue": "eb8e7b17f1533bc3e86e23e8695f7a5e4b7a99ef1b1575d10af54f389161b655" + } + ], + "fileName": "Lib/ctypes/macholib/dyld.py" + }, + { + "SPDXID": "SPDXRef-FILE-Lib-ctypes-macholib-dylib.py", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "f339420cc01bd01f8d0da19b6102f099075e8bcd" + }, + { + "algorithm": "SHA256", + "checksumValue": "f19ee056b18165cc6735efab0b4ca3508be9405b9646c38113316c15e8278a6f" + } + ], + "fileName": "Lib/ctypes/macholib/dylib.py" + }, + { + "SPDXID": "SPDXRef-FILE-Lib-ctypes-macholib-framework.py", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "0b219f58467d7f193fa1de0c1b118485840d855b" + }, + { + "algorithm": "SHA256", + "checksumValue": "302439e40d9cbdd61b8b7cffd0b7e1278a6811b635044ee366a36e0d991f62da" + } + ], + "fileName": "Lib/ctypes/macholib/framework.py" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-README.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "bda6e0bd6121f7069b420bdc0bc7c49414d948d1" + }, + { + "algorithm": "SHA256", + "checksumValue": "89926cd0fe6cfb33a2b5b7416c101e9b5d42b0d639d348e0871acf6ffc8258a3" + } + ], + "fileName": "Modules/_decimal/libmpdec/README.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-basearith.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "33757ce2ec0c93c1b5e03c45a495563a00e498ae" + }, + { + "algorithm": "SHA256", + "checksumValue": "ad498362c31a5b99ab19fce320ac540cf14c5c4ec09478f0ad3858da1428113d" + } + ], + "fileName": "Modules/_decimal/libmpdec/basearith.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-basearith.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "bf03919412c068e6969e7ac48850f91bfcd3b2b1" + }, + { + "algorithm": "SHA256", + "checksumValue": "2eaac88a71b9bcf3144396c12dcfeced573e0e550a0050d75b9ed3903248596d" + } + ], + "fileName": "Modules/_decimal/libmpdec/basearith.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-bench.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c925b7f26754ae182aaa461d51802e8b6a2bb5e9" + }, + { + "algorithm": "SHA256", + "checksumValue": "007e38542ec8d9d8805fe243b5390d79211b9360e2797a20079e833e68ad9e45" + } + ], + "fileName": "Modules/_decimal/libmpdec/bench.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-bench-full.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "cb22686269685a53a17afdea9ed984714e399d9d" + }, + { + "algorithm": "SHA256", + "checksumValue": "1b9e892d4b268deea835ec8906f20a1e5d25e037b2e698edcd34315613f3608c" + } + ], + "fileName": "Modules/_decimal/libmpdec/bench_full.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-bits.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "fc91c2450cdf1e785d1347411662294c3945eb27" + }, + { + "algorithm": "SHA256", + "checksumValue": "ce7741e58ea761a24250c0bfa10058cec8c4fd220dca70a41de3927a2e4f5376" + } + ], + "fileName": "Modules/_decimal/libmpdec/bits.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-constants.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "7187c18916b0a546ec19b4fc4bec43d0d9fb5fc2" + }, + { + "algorithm": "SHA256", + "checksumValue": "cd430b8657cf8a616916e02f9bd5ca044d5fc19e69333f5d427e1fdb90b0864b" + } + ], + "fileName": "Modules/_decimal/libmpdec/constants.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-constants.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "af9cbd016fb0ef0b30ced49c0aa4ce2ca3c20125" + }, + { + "algorithm": "SHA256", + "checksumValue": "19dc46df04abb7ee08e9a403f87c8aac8d4a077efcce314c597f8b73e22884f2" + } + ], + "fileName": "Modules/_decimal/libmpdec/constants.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-context.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "666162870230bebd3f2383020d908806fd03909e" + }, + { + "algorithm": "SHA256", + "checksumValue": "9a265d366f31894aad78bca7fcdc1457bc4a3aa3887ca231b7d78e41f79541c0" + } + ], + "fileName": "Modules/_decimal/libmpdec/context.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-convolute.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "0545547a8b37b922fbe2574fbad8fc3bf16f1d33" + }, + { + "algorithm": "SHA256", + "checksumValue": "66fe27b9bb37039cad5be32b105ed509e5aefa15c1957a9058af8ee23cddc97a" + } + ], + "fileName": "Modules/_decimal/libmpdec/convolute.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-convolute.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "05ff0936c5bb08f40d460f5843004a1cc0751d9b" + }, + { + "algorithm": "SHA256", + "checksumValue": "c00d17450c2b8e1d7f1eb8a084f7e6a68f257a453f8701600e860bf357c531d7" + } + ], + "fileName": "Modules/_decimal/libmpdec/convolute.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-crt.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "fe8176849bc99a306332ba25caa4e91bfa3c6f7d" + }, + { + "algorithm": "SHA256", + "checksumValue": "1f4e65c44864c3e911a6e91f33adec76765293e90553459e3ebce35a58898dba" + } + ], + "fileName": "Modules/_decimal/libmpdec/crt.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-crt.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "1930b9e0910014b3479aec4e940f02118d9e4a08" + }, + { + "algorithm": "SHA256", + "checksumValue": "7d31f1d0dd73b62964dab0f7a1724473bf87f1f95d8febf0b40c15430ae9a47c" + } + ], + "fileName": "Modules/_decimal/libmpdec/crt.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-difradix2.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "415c51e7d7f517b6366bec2a809610d0d38ada14" + }, + { + "algorithm": "SHA256", + "checksumValue": "0a9fef8a374f55277e9f6000b7277bb037b9763c32b156c29950422b057498bd" + } + ], + "fileName": "Modules/_decimal/libmpdec/difradix2.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-difradix2.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d8a998c3bee4c3d9059ba7bf9ae6a8b64649c2ba" + }, + { + "algorithm": "SHA256", + "checksumValue": "5c6766496224de657400995b58b64db3e7084004bf00daebdd7e08d0c5995243" + } + ], + "fileName": "Modules/_decimal/libmpdec/difradix2.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-README.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "158f6ad18edf348efa4fdd7cf61114c77c1d22e9" + }, + { + "algorithm": "SHA256", + "checksumValue": "7b0da2758097a2688f06b3c7ca46b2ebc8329addbd28bb4f5fe95626cc81f8a9" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/README.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-compare.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ef80ba26847287fb351ab0df0a78b5f08ba0b5b7" + }, + { + "algorithm": "SHA256", + "checksumValue": "452666ee4eb10a8cf0a926cb3bcf5e95b5c361fa129dbdfe27b654e6d640417e" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/compare.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-div.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "6ca3a369b3d1e140fdc93c4fdbedb724f7daf969" + }, + { + "algorithm": "SHA256", + "checksumValue": "6d369f5a24d0bb1e7cb6a4f8b0e97a273260e7668c8a540a8fcc92e039f7af2e" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/div.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-divmod.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "3872a28b4f77e07e1760256067ea338a8dd183f8" + }, + { + "algorithm": "SHA256", + "checksumValue": "5db54bae75ac3d7fa12f1bb0f7ce1bf797df86a81030e8c3ce44d3b1f9b958b7" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/divmod.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-multiply.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "25dbc94fd4ee5dec21061d2d40dd5d0f88849cb1" + }, + { + "algorithm": "SHA256", + "checksumValue": "22ed39b18fa740a27aacfd29a7bb40066be24500ba49b9b1f24e2af1e039fcd9" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/multiply.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-pow.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "13d3b7657dc2dc5000fea428f57963d520792ef7" + }, + { + "algorithm": "SHA256", + "checksumValue": "cd8c037649b3d4d6897c9acd2f92f3f9d5390433061d5e48623a5d526a3f4f9c" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/pow.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-powmod.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "1f7e6c3d3e38df52bbcec0f5a180a8f328679618" + }, + { + "algorithm": "SHA256", + "checksumValue": "e29614b43abf1856b656a84d6b67c22cc5dc7af8cbae8ddc7acf17022220ee12" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/powmod.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-shift.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "0bd9ce89c7987d1109eb7b0c8f1f9a1298e1422e" + }, + { + "algorithm": "SHA256", + "checksumValue": "203f2dbf11d115580cb3c7c524ac6ccca2a7b31d89545db1b6263381b5de2b6a" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/shift.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-sqrt.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b401ba0814e17c9164c0df26e01cc0a355382f46" + }, + { + "algorithm": "SHA256", + "checksumValue": "f3dc2ce321833bbd4b3d1d9ea6fa2e0bcc1bfe1e39abb8d55be53e46c33949db" + } + ], + "fileName": "Modules/_decimal/libmpdec/examples/sqrt.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-fnt.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "060615ddef089a5a8f879a57e4968d920972a0e2" + }, + { + "algorithm": "SHA256", + "checksumValue": "a9f923524d53a9445769f27405375ec3d95fa804bb11db5ee249ae047f11cfce" + } + ], + "fileName": "Modules/_decimal/libmpdec/fnt.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-fnt.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b205043ebeaf065b16505a299342a992654f19b0" + }, + { + "algorithm": "SHA256", + "checksumValue": "3b03e69adf78fde68c8f87d33595d557237581d33fc067e1039eed9e9f2cc44c" + } + ], + "fileName": "Modules/_decimal/libmpdec/fnt.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-fourstep.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "702c27599b43280c94906235d7e1a74193ba701b" + }, + { + "algorithm": "SHA256", + "checksumValue": "cf2e69b946ec14b087e523c0ff606553070d13c23e851fb0ba1df51a728017e6" + } + ], + "fileName": "Modules/_decimal/libmpdec/fourstep.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-fourstep.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "ee5291c265ef1f5ae373bc243a4d96975eb3e7b5" + }, + { + "algorithm": "SHA256", + "checksumValue": "dbaced03b52d0f880c377b86c943bcb36f24d557c99a5e9732df3ad5debb5917" + } + ], + "fileName": "Modules/_decimal/libmpdec/fourstep.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-io.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "12402bcf7f0161adb83f78163f41cc10a5e5de5f" + }, + { + "algorithm": "SHA256", + "checksumValue": "cba044c76b6bc3ae6cfa49df1121cad7552140157b9e61e11cbb6580cc5d74cf" + } + ], + "fileName": "Modules/_decimal/libmpdec/io.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-io.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "28c653cd40b1ce46575e41f5dbfda5f6dd0db4d1" + }, + { + "algorithm": "SHA256", + "checksumValue": "259eab89fe27914e0e39e61199094a357ac60d86b2aab613c909040ff64a4a0c" + } + ], + "fileName": "Modules/_decimal/libmpdec/io.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-REFERENCES.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "218d1d7bedb335cd2c31eae89a15873c3139e13f" + }, + { + "algorithm": "SHA256", + "checksumValue": "a57e8bed93ded481ef264166aec2c49d1a7f3252f29a873ee41fff053cfd9c20" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/REFERENCES.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-bignum.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "f67eab2431336cf6eeafb30cdafd7e54c251def3" + }, + { + "algorithm": "SHA256", + "checksumValue": "dc34aa122c208ce79e3fc6baee8628094ffaf6a662862dd5647836241f6ebd79" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/bignum.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-fnt.py", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "a58cfbcd8ea57d66ddfd11fb5a170138c8bbfb3a" + }, + { + "algorithm": "SHA256", + "checksumValue": "122de20eebf87274af2d02072251a94500e7df2d5ef29e81aeabeda991c079e3" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/fnt.py" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-matrix-transform.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "9a947f6b660150cbd457c4458da2956a36c5824d" + }, + { + "algorithm": "SHA256", + "checksumValue": "592659e7192e3a939b797f5bc7455455834a285f5d8b643ccd780b5114914f73" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/matrix-transform.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-mulmod-64.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "69fe9afb8353b5a2b57917469c51c64ac518169d" + }, + { + "algorithm": "SHA256", + "checksumValue": "229a80ca940c594a32e3345412370cbc097043fe59c66a6153cbcf01e7837266" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/mulmod-64.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-mulmod-ppro.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "720d468a1f51098036c7a0c869810fff22ed9b79" + }, + { + "algorithm": "SHA256", + "checksumValue": "f3549fc73f697a087267c7b042e30a409e191cbba69a2c0902685e507fbae9f7" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/mulmod-ppro.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-six-step.txt", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "6815ec3a39baebebe7b3f51d45d10c180a659f17" + }, + { + "algorithm": "SHA256", + "checksumValue": "bf15f73910a173c98fca9db56122b6cc71983668fa8b934c46ca21a57398ec54" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/six-step.txt" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-umodarith.lisp", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "c91ac4438e661ce78f86e981257546e5adff39ae" + }, + { + "algorithm": "SHA256", + "checksumValue": "783a1b4b9b7143677b0c3d30ffaf28aa0cb01956409031fa38ed8011970bdee0" + } + ], + "fileName": "Modules/_decimal/libmpdec/literature/umodarith.lisp" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-mpalloc.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "7e8dfb4b7a801b48c501969b001153203b14679e" + }, + { + "algorithm": "SHA256", + "checksumValue": "5ba2f4c80302e71fb216aa247c858e0bf6c8cfabffe7980ac17d4d023c0fef2b" + } + ], + "fileName": "Modules/_decimal/libmpdec/mpalloc.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-mpalloc.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "bccb6a6ae76fd7f6c8a9102a78958bcad7862950" + }, + { + "algorithm": "SHA256", + "checksumValue": "f7412521de38afb837fcabc2b1d48b971b86bfaa55f3f40d58ff9e46e92debd3" + } + ], + "fileName": "Modules/_decimal/libmpdec/mpalloc.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-mpdecimal.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "f4539afb1ace58c52d18ffd0cc7704f53ca55182" + }, + { + "algorithm": "SHA256", + "checksumValue": "4f89b8095e408a18deff79cfb605299e615bae747898eb105d8936064f7fb626" + } + ], + "fileName": "Modules/_decimal/libmpdec/mpdecimal.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-mpdecimal.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4b80e25ac49b7e1ea0d1e84967ee32a3d111fc4c" + }, + { + "algorithm": "SHA256", + "checksumValue": "ea0b9c6b296c13aed6ecaa50b463e39a9c1bdc059b84f50507fd8247b2e660f9" + } + ], + "fileName": "Modules/_decimal/libmpdec/mpdecimal.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-mpsignal.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "5c7305a6db0fddf64c6d97e29d3b0c402e3d5d6e" + }, + { + "algorithm": "SHA256", + "checksumValue": "653171cf2549719478417db7e9800fa0f9d99c02dec6da6876329ccf2c07b93f" + } + ], + "fileName": "Modules/_decimal/libmpdec/mpsignal.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-numbertheory.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d736b874c43777ca021dde5289ea718893f39219" + }, + { + "algorithm": "SHA256", + "checksumValue": "bdbf2e246f341a3ba3f6f9d8759e7cb222eb9b15f9ed1e7c9f6a59cbb9f8bc91" + } + ], + "fileName": "Modules/_decimal/libmpdec/numbertheory.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-numbertheory.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d341508d8c6dd4c4cbd8b99afc8029945f9bbe0d" + }, + { + "algorithm": "SHA256", + "checksumValue": "2f7d5b40af508fa6ac86f5d62101fa3bf683c63b24aa87c9548e3fdd13abc57b" + } + ], + "fileName": "Modules/_decimal/libmpdec/numbertheory.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-sixstep.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "cbd05d68bb3940d0d7d0818b14cc03b090a4dd74" + }, + { + "algorithm": "SHA256", + "checksumValue": "7602aaf98ec9525bc4b3cab9631615e1be2efd9af894002ef4e3f5ec63924fcf" + } + ], + "fileName": "Modules/_decimal/libmpdec/sixstep.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-sixstep.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4c059463ec4b4522562dab24760fc64c172c9eee" + }, + { + "algorithm": "SHA256", + "checksumValue": "a191366348b3d3dd49b9090ec5c77dbd77bb3a523c01ff32adafa137e5097ce7" + } + ], + "fileName": "Modules/_decimal/libmpdec/sixstep.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-transpose.c", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "cc5593ac9fdb60480cc23fc9d6f27d85670bd35f" + }, + { + "algorithm": "SHA256", + "checksumValue": "2d12fcae512143a9376c8a0d4c1ba3008e420e024497a7e7ec64c6bec23fcddc" + } + ], + "fileName": "Modules/_decimal/libmpdec/transpose.c" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-transpose.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "2f616425756b6cbdf7d189744870b98b613455bd" + }, + { + "algorithm": "SHA256", + "checksumValue": "fafeb2b901b2b41bf0df00be7d99b84df1a78e3cc1e582e09cbfc3b6d44d4abe" + } + ], + "fileName": "Modules/_decimal/libmpdec/transpose.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-typearith.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "b1e9341e173cc8e219ad4aa45fad36d92cce10d3" + }, + { + "algorithm": "SHA256", + "checksumValue": "25e0a0703b51744277834e6b2398d7b7d2c17f92bf30f8b6f949e0486ae2b346" + } + ], + "fileName": "Modules/_decimal/libmpdec/typearith.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-umodarith.h", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "46f6483fce136cd3cc2f7516ee119a487d86333e" + }, + { + "algorithm": "SHA256", + "checksumValue": "bfe1ddb2ca92906456b80745adcbe02c83cadac3ef69caa21bc09b7292cc152b" + } + ], + "fileName": "Modules/_decimal/libmpdec/umodarith.h" + }, + { + "SPDXID": "SPDXRef-FILE-Modules-decimal-libmpdec-vcdiv64.asm", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "d0cc1052fcba08b773d935b0ae2dc6b80d0f2f68" + }, + { + "algorithm": "SHA256", + "checksumValue": "aacc3e47ea8f41e8840c6c67f64ec96d54696a16889903098fa1aab56949a00f" + } + ], + "fileName": "Modules/_decimal/libmpdec/vcdiv64.asm" + }, + { + "SPDXID": "SPDXRef-FILE-Lib-ensurepip-bundled-pip-23.3.1-py3-none-any.whl", + "checksums": [ + { + "algorithm": "SHA1", + "checksumValue": "4b2baddc0673f73017e531648a9ee27e47925e7a" + }, + { + "algorithm": "SHA256", + "checksumValue": "55eb67bb6171d37447e82213be585b75fe2b12b359e993773aca4de9247a052b" + } + ], + "fileName": "Lib/ensurepip/_bundled/pip-23.3.1-py3-none-any.whl" + } + ], + "packages": [ + { + "SPDXID": "SPDXRef-PACKAGE-expat", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "6b902ab103843592be5e99504f846ec109c1abb692e85347587f237a4ffa1033" + } + ], + "downloadLocation": "/~https://github.com/libexpat/libexpat/releases/download/R_2_5_0/expat-2.5.0.tar.gz", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceLocator": "cpe:2.3:a:libexpat_project:libexpat:2.5.0:*:*:*:*:*:*:*", + "referenceType": "cpe23Type" + } + ], + "licenseConcluded": "MIT", + "name": "expat", + "originator": "Organization: Expat development team", + "primaryPackagePurpose": "SOURCE", + "versionInfo": "2.5.0" + }, + { + "SPDXID": "SPDXRef-PACKAGE-hacl-star", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "c23ac158b238c368389dc86bfc315263e5c0e57785da74144aea2cab9a3d51a2" + } + ], + "downloadLocation": "/~https://github.com/hacl-star/hacl-star/archive/521af282fdf6d60227335120f18ae9309a4b8e8c.zip", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceLocator": "cpe:2.3:a:hacl-star:hacl-star:521af282fdf6d60227335120f18ae9309a4b8e8c:*:*:*:*:*:*:*", + "referenceType": "cpe23Type" + } + ], + "licenseConcluded": "Apache-2.0", + "name": "hacl-star", + "originator": "Organization: HACL* Developers", + "primaryPackagePurpose": "SOURCE", + "versionInfo": "521af282fdf6d60227335120f18ae9309a4b8e8c" + }, + { + "SPDXID": "SPDXRef-PACKAGE-libb2", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "53626fddce753c454a3fea581cbbc7fe9bbcf0bc70416d48fdbbf5d87ef6c72e" + } + ], + "downloadLocation": "/~https://github.com/BLAKE2/libb2/releases/download/v0.98.1/libb2-0.98.1.tar.gz", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceLocator": "cpe:2.3:a:blake2:libb2:0.98.1:*:*:*:*:*:*:*", + "referenceType": "cpe23Type" + } + ], + "licenseConcluded": "CC0-1.0", + "name": "libb2", + "originator": "Organization: BLAKE2 - fast secure hashing", + "primaryPackagePurpose": "SOURCE", + "versionInfo": "0.98.1" + }, + { + "SPDXID": "SPDXRef-PACKAGE-macholib", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "c76f268f5054024e962f2515a0e522baf85313064f6740d80375afc850787a38" + } + ], + "downloadLocation": "https://files.pythonhosted.org/packages/ec/57/f0a712efc3ed982cf4038a3cee172057303b9be914c32c93b2fbec27f785/macholib-1.0.tar.gz", + "externalRefs": [ + { + "referenceCategory": "PACKAGE_MANAGER", + "referenceLocator": "pkg:pypi/macholib@1.0", + "referenceType": "purl" + } + ], + "licenseConcluded": "MIT", + "name": "macholib", + "originator": "Person: Ronald Oussoren (ronaldoussoren@mac.com)", + "primaryPackagePurpose": "SOURCE", + "versionInfo": "1.0" + }, + { + "SPDXID": "SPDXRef-PACKAGE-mpdecimal", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "9f9cd4c041f99b5c49ffb7b59d9f12d95b683d88585608aa56a6307667b2b21f" + } + ], + "downloadLocation": "https://www.bytereef.org/software/mpdecimal/releases/mpdecimal-2.5.1.tar.gz", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceLocator": "cpe:2.3:a:bytereef:mpdecimal:2.5.1:*:*:*:*:*:*:*", + "referenceType": "cpe23Type" + } + ], + "licenseConcluded": "BSD-2-Clause", + "name": "mpdecimal", + "originator": "Organization: bytereef.org", + "primaryPackagePurpose": "SOURCE", + "versionInfo": "2.5.1" + }, + { + "SPDXID": "SPDXRef-PACKAGE-pip", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "7ccf472345f20d35bdc9d1841ff5f313260c2c33fe417f48c30ac46cccabf5be" + } + ], + "downloadLocation": "https://files.pythonhosted.org/packages/50/c2/e06851e8cc28dcad7c155f4753da8833ac06a5c704c109313b8d5a62968a/pip-23.2.1-py3-none-any.whl", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceLocator": "cpe:2.3:a:pypa:pip:23.2.1:*:*:*:*:*:*:*", + "referenceType": "cpe23Type" + }, + { + "referenceCategory": "PACKAGE_MANAGER", + "referenceLocator": "pkg:pypi/pip@23.2.1", + "referenceType": "purl" + } + ], + "licenseConcluded": "MIT", + "name": "pip", + "originator": "Organization: Python Packaging Authority", + "primaryPackagePurpose": "SOURCE", + "versionInfo": "23.2.1" + } + ], + "relationships": [ + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-COPYING", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-ascii.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-asciitab.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-expat.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-expat-config.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-expat-external.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-iasciitab.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-internal.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-latin1tab.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-nametab.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-pyexpatns.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-siphash.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-utf8tab.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-winconfig.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmlparse.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmlrole.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmlrole.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmltok.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmltok.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmltok-impl.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmltok-impl.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-expat-xmltok-ns.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-expat" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-MD5.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-MD5.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA1.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA1.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA2.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA2.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA3.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Hash-SHA3.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-Hacl-Streaming-Types.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-include-krml-FStar-UInt128-Verified.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-include-krml-FStar-UInt-8-16-32-64.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-include-krml-fstar-uint128-struct-endianness.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-include-krml-internal-target.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-include-krml-lowstar-endianness.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-include-krml-types.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-MD5.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-SHA1.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-SHA2.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-internal-Hacl-Hash-SHA3.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-hacl-python-hacl-namespaces.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-hacl-star" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2-config.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2-impl.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2b-load-sse2.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2b-load-sse41.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2b-ref.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2b-round.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2b.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2s-load-sse2.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2s-load-sse41.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2s-load-xop.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2s-ref.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2s-round.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-blake2-impl-blake2s.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-libb2" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Lib-ctypes-macholib-init-.py", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-macholib" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Lib-ctypes-macholib-dyld.py", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-macholib" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Lib-ctypes-macholib-dylib.py", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-macholib" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Lib-ctypes-macholib-framework.py", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-macholib" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-README.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-basearith.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-basearith.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-bench.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-bench-full.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-bits.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-constants.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-constants.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-context.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-convolute.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-convolute.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-crt.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-crt.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-difradix2.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-difradix2.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-README.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-compare.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-div.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-divmod.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-multiply.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-pow.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-powmod.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-shift.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-examples-sqrt.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-fnt.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-fnt.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-fourstep.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-fourstep.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-io.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-io.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-REFERENCES.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-bignum.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-fnt.py", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-matrix-transform.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-mulmod-64.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-mulmod-ppro.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-six-step.txt", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-literature-umodarith.lisp", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-mpalloc.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-mpalloc.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-mpdecimal.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-mpdecimal.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-mpsignal.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-numbertheory.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-numbertheory.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-sixstep.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-sixstep.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-transpose.c", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-transpose.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-typearith.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-umodarith.h", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Modules-decimal-libmpdec-vcdiv64.asm", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-mpdecimal" + }, + { + "relatedSpdxElement": "SPDXRef-FILE-Lib-ensurepip-bundled-pip-23.3.1-py3-none-any.whl", + "relationshipType": "CONTAINS", + "spdxElementId": "SPDXRef-PACKAGE-pip" + } + ], + "spdxVersion": "SPDX-2.3" +} \ No newline at end of file diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 8df3f85e61eec6..22b25dd0ec141f 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2460,3 +2460,24 @@ 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' +[function.PyMem_RawMalloc] + added = '3.13' +[function.PyMem_RawCalloc] + added = '3.13' +[function.PyMem_RawRealloc] + added = '3.13' +[function.PyMem_RawFree] + added = '3.13' +[function.PySys_Audit] + added = '3.13' +[function.PySys_AuditTuple] + added = '3.13' +[function._Py_SetRefcnt] + added = '3.13' + abi_only = true diff --git a/Modules/Setup b/Modules/Setup index 8676f9ddce4841..8ad9a5aebbfcaa 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 @@ -272,6 +273,7 @@ PYTHONPATH=$(COREPYTHONPATH) #_xxsubinterpreters _xxsubinterpretersmodule.c #_xxinterpchannels _xxinterpchannelsmodule.c +#_xxinterpqueues _xxinterpqueuesmodule.c #_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c #_testbuffer _testbuffer.c #_testinternalcapi _testinternalcapi.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 7b3216a50bb284..8a65a9cffb1b9d 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -41,8 +41,11 @@ @MODULE__QUEUE_TRUE@_queue _queuemodule.c @MODULE__RANDOM_TRUE@_random _randommodule.c @MODULE__STRUCT_TRUE@_struct _struct.c + +# build supports subinterpreters @MODULE__XXSUBINTERPRETERS_TRUE@_xxsubinterpreters _xxsubinterpretersmodule.c @MODULE__XXINTERPCHANNELS_TRUE@_xxinterpchannels _xxinterpchannelsmodule.c +@MODULE__XXINTERPQUEUES_TRUE@_xxinterpqueues _xxinterpqueuesmodule.c @MODULE__ZONEINFO_TRUE@_zoneinfo _zoneinfo.c # needs libm @@ -158,8 +161,8 @@ @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 _testinternalcapi/test_lock.c _testinternalcapi/pytime.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/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__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c +@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/bytearray.c _testcapi/bytes.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/pyos.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c _testcapi/sys.c _testcapi/hash.c @MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c @MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index c66a8623413f4b..3a11cdc926f138 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_dict.h" // _PyDict_GetItem_KnownHash() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() @@ -816,7 +817,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; } @@ -834,7 +835,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; } @@ -2181,7 +2182,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; } @@ -3513,15 +3514,11 @@ _asyncio_current_task_impl(PyObject *module, PyObject *loop) Py_INCREF(loop); } - ret = PyDict_GetItemWithError(state->current_tasks, loop); + int rc = PyDict_GetItemRef(state->current_tasks, loop, &ret); Py_DECREF(loop); - if (ret == NULL && PyErr_Occurred()) { - return NULL; - } - else if (ret == NULL) { + if (rc == 0) { Py_RETURN_NONE; } - Py_INCREF(ret); return ret; } diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index c2cac98c7529eb..0c3ae5a2fac275 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -17,6 +17,7 @@ # define Py_BUILD_CORE_MODULE 1 #endif +#include #include "Python.h" #include "pycore_strhex.h" // _Py_strhex() @@ -42,7 +43,8 @@ typedef struct { PyObject_HEAD blake2b_param param; blake2b_state state; - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; } BLAKE2bObject; #include "clinic/blake2b_impl.c.h" @@ -59,9 +61,11 @@ new_BLAKE2bObject(PyTypeObject *type) { BLAKE2bObject *self; self = (BLAKE2bObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->lock = NULL; + if (self == NULL) { + return NULL; } + HASHLIB_INIT_MUTEX(self); + return self; } @@ -278,18 +282,19 @@ _blake2_blake2b_update(BLAKE2bObject *self, PyObject *data) GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) - self->lock = PyThread_allocate_lock(); - - if (self->lock != NULL) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); - blake2b_update(&self->state, buf.buf, buf.len); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; + } + if (self->use_mutex) { + Py_BEGIN_ALLOW_THREADS + PyMutex_Lock(&self->mutex); + blake2b_update(&self->state, buf.buf, buf.len); + PyMutex_Unlock(&self->mutex); + Py_END_ALLOW_THREADS } else { blake2b_update(&self->state, buf.buf, buf.len); } + PyBuffer_Release(&buf); Py_RETURN_NONE; @@ -389,10 +394,6 @@ py_blake2b_dealloc(PyObject *self) /* Try not to leave state in memory. */ secure_zero_memory(&obj->param, sizeof(obj->param)); secure_zero_memory(&obj->state, sizeof(obj->state)); - if (obj->lock) { - PyThread_free_lock(obj->lock); - obj->lock = NULL; - } PyTypeObject *type = Py_TYPE(self); PyObject_Free(self); diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index 0d1d88c6603684..5df9fd3df493ee 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -74,6 +74,12 @@ _blake2_free(void *module) Py_DECREF(x); \ } while(0) +#define ADD_INT_CONST(NAME, VALUE) do { \ + if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \ + return -1; \ + } \ +} while (0) + static int blake2_exec(PyObject *m) { @@ -95,10 +101,10 @@ blake2_exec(PyObject *m) ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES); - PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); + ADD_INT_CONST("BLAKE2B_SALT_SIZE", BLAKE2B_SALTBYTES); + ADD_INT_CONST("BLAKE2B_PERSON_SIZE", BLAKE2B_PERSONALBYTES); + ADD_INT_CONST("BLAKE2B_MAX_KEY_SIZE", BLAKE2B_KEYBYTES); + ADD_INT_CONST("BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); /* BLAKE2s */ st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec( @@ -117,14 +123,17 @@ blake2_exec(PyObject *m) ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); ADD_INT(d, "MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); - PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); + ADD_INT_CONST("BLAKE2S_SALT_SIZE", BLAKE2S_SALTBYTES); + ADD_INT_CONST("BLAKE2S_PERSON_SIZE", BLAKE2S_PERSONALBYTES); + ADD_INT_CONST("BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); + ADD_INT_CONST("BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); return 0; } +#undef ADD_INT +#undef ADD_INT_CONST + static PyModuleDef_Slot _blake2_slots[] = { {Py_mod_exec, blake2_exec}, {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 1c47328ece13e8..3014773ab52331 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -17,6 +17,7 @@ # define Py_BUILD_CORE_MODULE 1 #endif +#include #include "Python.h" #include "pycore_strhex.h" // _Py_strhex() @@ -42,7 +43,8 @@ typedef struct { PyObject_HEAD blake2s_param param; blake2s_state state; - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; } BLAKE2sObject; #include "clinic/blake2s_impl.c.h" @@ -59,9 +61,11 @@ new_BLAKE2sObject(PyTypeObject *type) { BLAKE2sObject *self; self = (BLAKE2sObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->lock = NULL; + if (self == NULL) { + return NULL; } + HASHLIB_INIT_MUTEX(self); + return self; } @@ -278,18 +282,19 @@ _blake2_blake2s_update(BLAKE2sObject *self, PyObject *data) GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) - self->lock = PyThread_allocate_lock(); - - if (self->lock != NULL) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); - blake2s_update(&self->state, buf.buf, buf.len); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; + } + if (self->use_mutex) { + Py_BEGIN_ALLOW_THREADS + PyMutex_Lock(&self->mutex); + blake2s_update(&self->state, buf.buf, buf.len); + PyMutex_Unlock(&self->mutex); + Py_END_ALLOW_THREADS } else { blake2s_update(&self->state, buf.buf, buf.len); } + PyBuffer_Release(&buf); Py_RETURN_NONE; @@ -389,10 +394,6 @@ py_blake2s_dealloc(PyObject *self) /* Try not to leave state in memory. */ secure_zero_memory(&obj->param, sizeof(obj->param)); secure_zero_memory(&obj->state, sizeof(obj->state)); - if (obj->lock) { - PyThread_free_lock(obj->lock); - obj->lock = NULL; - } PyTypeObject *type = Py_TYPE(self); PyObject_Free(self); diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 869cbea78dd267..47d62717eb76e7 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_long.h" // _PyLong_UnsignedLong_Converter() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(py_blake2b_new__doc__, "blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" @@ -97,10 +98,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyObject_GetBuffer(fastargs[2], &key, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("blake2b", "argument 'key'", "contiguous buffer", fastargs[2]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -109,10 +106,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyObject_GetBuffer(fastargs[3], &salt, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("blake2b", "argument 'salt'", "contiguous buffer", fastargs[3]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -121,10 +114,6 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyObject_GetBuffer(fastargs[4], &person, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&person, 'C')) { - _PyArg_BadArgument("blake2b", "argument 'person'", "contiguous buffer", fastargs[4]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -276,4 +265,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=2ad807e0c83d8c25 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e18eeaee40623bfc input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index affc203486b174..7a0f6eeff5b5b5 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_long.h" // _PyLong_UnsignedLong_Converter() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(py_blake2s_new__doc__, "blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" @@ -97,10 +98,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyObject_GetBuffer(fastargs[2], &key, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("blake2s", "argument 'key'", "contiguous buffer", fastargs[2]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -109,10 +106,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyObject_GetBuffer(fastargs[3], &salt, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("blake2s", "argument 'salt'", "contiguous buffer", fastargs[3]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -121,10 +114,6 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (PyObject_GetBuffer(fastargs[4], &person, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&person, 'C')) { - _PyArg_BadArgument("blake2s", "argument 'person'", "contiguous buffer", fastargs[4]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -276,4 +265,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=90ca2b52b8c40785 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=24690e4e2586cafd input=a9049054013a1b77]*/ diff --git a/Modules/_csv.c b/Modules/_csv.c index 9568334b8069c8..ae6b6457ffad9a 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -10,6 +10,11 @@ module instead. #define MODULE_VERSION "1.0" +// clinic/_csv.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include // offsetof() @@ -155,15 +160,9 @@ static PyObject * get_dialect_from_registry(PyObject *name_obj, _csvstate *module_state) { PyObject *dialect_obj; - - dialect_obj = PyDict_GetItemWithError(module_state->dialects, name_obj); - if (dialect_obj == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(module_state->error_obj, "unknown dialect"); + if (PyDict_GetItemRef(module_state->dialects, name_obj, &dialect_obj) == 0) { + PyErr_SetString(module_state->error_obj, "unknown dialect"); } - else - Py_INCREF(dialect_obj); - return dialect_obj; } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 184af2132c2707..f909a9496b6526 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -110,7 +110,9 @@ bytes(cdata) #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCall() -#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() +#ifdef MS_WIN32 +# include "pycore_modsupport.h" // _PyArg_NoKeywords() +#endif #include @@ -182,7 +184,7 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) DictRemoverObject *self = (DictRemoverObject *)myself; if (self->key && self->dict) { if (-1 == PyDict_DelItem(self->dict, self->key)) { - _PyErr_WriteUnraisableMsg("on calling _ctypes.DictRemover", NULL); + PyErr_FormatUnraisable("Exception ignored on calling _ctypes.DictRemover"); } Py_CLEAR(self->key); Py_CLEAR(self->dict); @@ -241,26 +243,13 @@ PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) static int _PyDict_GetItemProxy(PyObject *dict, PyObject *key, PyObject **presult) { - PyObject *item = PyDict_GetItemWithError(dict, key); - if (item == NULL) { - if (PyErr_Occurred()) { - return -1; - } - *presult = NULL; - return 0; + int rc = PyDict_GetItemRef(dict, key, presult); + PyObject *item = *presult; + if (item && PyWeakref_CheckProxy(item)) { + rc = PyWeakref_GetRef(item, presult); + Py_DECREF(item); } - - if (!PyWeakref_CheckProxy(item)) { - *presult = Py_NewRef(item); - return 0; - } - PyObject *ref; - if (PyWeakref_GetRef(item, &ref) < 0) { - return -1; - } - // ref is NULL if the referenced object was destroyed - *presult = ref; - return 0; + return rc; } /******************************************************************/ @@ -563,18 +552,19 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt dict->paramfunc = StructUnionType_paramfunc; - fields = PyDict_GetItemWithError((PyObject *)dict, &_Py_ID(_fields_)); + if (PyDict_GetItemRef((PyObject *)dict, &_Py_ID(_fields_), &fields) < 0) { + Py_DECREF(result); + return NULL; + } if (fields) { if (PyObject_SetAttr((PyObject *)result, &_Py_ID(_fields_), fields) < 0) { Py_DECREF(result); + Py_DECREF(fields); return NULL; } + Py_DECREF(fields); return (PyObject *)result; } - else if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } else { StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); @@ -1108,11 +1098,15 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->flags |= TYPEFLAG_ISPOINTER; - proto = PyDict_GetItemWithError(typedict, &_Py_ID(_type_)); /* Borrowed ref */ + if (PyDict_GetItemRef(typedict, &_Py_ID(_type_), &proto) < 0) { + Py_DECREF((PyObject *)stgdict); + return NULL; + } if (proto) { StgDictObject *itemdict; const char *current_format; if (-1 == PyCPointerType_SetProto(stgdict, proto)) { + Py_DECREF(proto); Py_DECREF((PyObject *)stgdict); return NULL; } @@ -1132,15 +1126,12 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } else { stgdict->format = _ctypes_alloc_format_string("&", current_format); } + Py_DECREF(proto); if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); return NULL; } } - else if (PyErr_Occurred()) { - Py_DECREF((PyObject *)stgdict); - return NULL; - } /* create the new instance (which is a class, since we are a metatype!) */ @@ -2459,58 +2450,61 @@ make_funcptrtype_dict(StgDictObject *stgdict) stgdict->getfunc = NULL; stgdict->ffi_type_pointer = ffi_type_pointer; - ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_flags_)); + if (PyDict_GetItemRef((PyObject *)stgdict, &_Py_ID(_flags_), &ob) < 0) { + return -1; + } if (!ob || !PyLong_Check(ob)) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_TypeError, "class must define _flags_ which must be an integer"); - } + Py_XDECREF(ob); return -1; } stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER; + Py_DECREF(ob); /* _argtypes_ is optional... */ - ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_argtypes_)); + if (PyDict_GetItemRef((PyObject *)stgdict, &_Py_ID(_argtypes_), &ob) < 0) { + return -1; + } if (ob) { converters = converters_from_argtypes(ob); - if (!converters) + if (!converters) { + Py_DECREF(ob); return -1; - stgdict->argtypes = Py_NewRef(ob); + } + stgdict->argtypes = ob; stgdict->converters = converters; } - else if (PyErr_Occurred()) { + + if (PyDict_GetItemRef((PyObject *)stgdict, &_Py_ID(_restype_), &ob) < 0) { return -1; } - - ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_restype_)); if (ob) { if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, "_restype_ must be a type, a callable, or None"); + Py_DECREF(ob); return -1; } - stgdict->restype = Py_NewRef(ob); + stgdict->restype = ob; if (PyObject_GetOptionalAttr(ob, &_Py_ID(_check_retval_), &stgdict->checker) < 0) { return -1; } } - else if (PyErr_Occurred()) { +/* XXX later, maybe. + if (PyDict_GetItemRef((PyObject *)stgdict, &_Py _ID(_errcheck_), &ob) < 0) { return -1; } -/* XXX later, maybe. - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_); if (ob) { if (!PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, "_errcheck_ must be callable"); + Py_DECREF(ob); return -1; } - stgdict->errcheck = Py_NewRef(ob); - } - else if (PyErr_Occurred()) { - return -1; + stgdict->errcheck = ob; } */ return 0; @@ -3810,13 +3804,12 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje return Py_NewRef(v); } if (kwds && name) { - v = PyDict_GetItemWithError(kwds, name); + if (PyDict_GetItemRef(kwds, name, &v) < 0) { + return NULL; + } if (v) { ++*pindex; - return Py_NewRef(v); - } - else if (PyErr_Occurred()) { - return NULL; + return v; } } if (defval) { @@ -4868,15 +4861,12 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) return NULL; PyObject *result; - if (_PyDict_GetItemProxy(cache, key, &result) < 0) { - Py_DECREF(key); - return NULL; - } - if (result) { + if (_PyDict_GetItemProxy(cache, key, &result) != 0) { + // found or error Py_DECREF(key); return result; } - + // not found if (!PyType_Check(itemtype)) { PyErr_SetString(PyExc_TypeError, "Expected a type object"); diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index ddfb2c8a332a9e..ecc60417790417 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -1,10 +1,25 @@ -#include +#include "pyconfig.h" // Py_GIL_DISABLED -#ifdef MS_WIN32 -#include +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 #endif +// gh-85283: On Windows, Py_LIMITED_API requires Py_BUILD_CORE to not attempt +// linking the extension to python3.lib (which fails). Py_BUILD_CORE_MODULE is +// needed to import Python symbols. Then Python.h undefines Py_BUILD_CORE and +// Py_BUILD_CORE_MODULE if Py_LIMITED_API is defined. +#define Py_BUILD_CORE +#define Py_BUILD_CORE_MODULE + +#include + +#include // printf() #include // qsort() +#include // memset() +#ifdef MS_WIN32 +# include +#endif #define EXPORT(x) Py_EXPORTED_SYMBOL x @@ -81,11 +96,10 @@ typedef struct { } Test2; EXPORT(int) -_testfunc_array_in_struct1(Test2 in) +_testfunc_array_in_struct2(Test2 in) { int result = 0; - - for (unsigned i = 0; i < 16; i++) + for (unsigned i = 0; i < sizeof(in.data)/sizeof(in.data[0]); i++) result += in.data[i]; /* As the structure is passed by value, changes to it shouldn't be * reflected in the caller. @@ -94,22 +108,25 @@ _testfunc_array_in_struct1(Test2 in) return result; } -typedef struct { - double data[2]; -} Test3; - +/* + * Test3A struct test the MAX_STRUCT_SIZE 16 with single precision floats. + * These structs should be passed via registers on all platforms and they are + * used for within bounds tests. + */ typedef struct { float data[2]; float more_data[2]; -} Test3B; +} Test3A; EXPORT(double) -_testfunc_array_in_struct2(Test3 in) +_testfunc_array_in_struct3A(Test3A in) { double result = 0; - for (unsigned i = 0; i < 2; i++) + for (unsigned i = 0; i < sizeof(in.data)/sizeof(in.data[0]); i++) result += in.data[i]; + for (unsigned i = 0; i < sizeof(in.more_data)/sizeof(in.more_data[0]); i++) + result += in.more_data[i]; /* As the structure is passed by value, changes to it shouldn't be * reflected in the caller. */ @@ -117,20 +134,116 @@ _testfunc_array_in_struct2(Test3 in) return result; } +/* The structs Test3B..Test3E use the same functions hence using the MACRO + * to define their implementation. + */ + +#define _TESTFUNC_ARRAY_IN_STRUCT_IMPL \ + double result = 0; \ + \ + for (unsigned i = 0; i < sizeof(in.data)/sizeof(in.data[0]); i++) \ + result += in.data[i]; \ + /* As the structure is passed by value, changes to it shouldn't be \ + * reflected in the caller. \ + */ \ + memset(in.data, 0, sizeof(in.data)); \ + return result; \ + +#define _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL \ + for (unsigned i = 0; i < sizeof(s.data)/sizeof(s.data[0]); i++) \ + s.data[i] = (double)i+1; \ + return s; \ + + +/* + * Test3B struct test the MAX_STRUCT_SIZE 16 with double precision floats. + * These structs should be passed via registers on all platforms and they are + * used for within bounds tests. + */ +typedef struct { + double data[2]; +} Test3B; + EXPORT(double) -_testfunc_array_in_struct2a(Test3B in) +_testfunc_array_in_struct3B(Test3B in) { - double result = 0; + _TESTFUNC_ARRAY_IN_STRUCT_IMPL +} - for (unsigned i = 0; i < 2; i++) - result += in.data[i]; - for (unsigned i = 0; i < 2; i++) - result += in.more_data[i]; - /* As the structure is passed by value, changes to it shouldn't be - * reflected in the caller. - */ - memset(in.data, 0, sizeof(in.data)); - return result; +EXPORT(Test3B) +_testfunc_array_in_struct3B_set_defaults(void) +{ + Test3B s; + _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL +} + +/* + * Test3C struct tests the MAX_STRUCT_SIZE 32. Structs containing arrays of up + * to four floating point types are passed in registers on Arm platforms. + * This struct is used for within bounds test on Arm platfroms and for an + * out-of-bounds tests for platfroms where MAX_STRUCT_SIZE is less than 32. + * See gh-110190. + */ +typedef struct { + double data[4]; +} Test3C; + +EXPORT(double) +_testfunc_array_in_struct3C(Test3C in) +{ + _TESTFUNC_ARRAY_IN_STRUCT_IMPL +} + +EXPORT(Test3C) +_testfunc_array_in_struct3C_set_defaults(void) +{ + Test3C s; + _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL +} + +/* + * Test3D struct tests the MAX_STRUCT_SIZE 64. Structs containing arrays of up + * to eight floating point types are passed in registers on PPC64LE platforms. + * This struct is used for within bounds test on PPC64LE platfroms and for an + * out-of-bounds tests for platfroms where MAX_STRUCT_SIZE is less than 64. + * See gh-110190. + */ +typedef struct { + double data[8]; +} Test3D; + +EXPORT(double) +_testfunc_array_in_struct3D(Test3D in) +{ + _TESTFUNC_ARRAY_IN_STRUCT_IMPL +} + +EXPORT(Test3D) +_testfunc_array_in_struct3D_set_defaults(void) +{ + Test3D s; + _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL +} + +/* + * Test3E struct tests the out-of-bounds for all architectures. + * See gh-110190. + */ +typedef struct { + double data[9]; +} Test3E; + +EXPORT(double) +_testfunc_array_in_struct3E(Test3E in) +{ + _TESTFUNC_ARRAY_IN_STRUCT_IMPL +} + +EXPORT(Test3E) +_testfunc_array_in_struct3E_set_defaults(void) +{ + Test3E s; + _TESTFUNC_ARRAY_IN_STRUCT_SET_DEFAULTS_IMPL } typedef union { diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 1bd8fec97179e9..154e9f43983cdb 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -9,7 +9,6 @@ #endif #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_pyerrors.h" // _PyErr_WriteUnraisableMsg() #include "pycore_runtime.h" // _Py_ID() #include @@ -216,8 +215,9 @@ static void _CallPythonObject(void *mem, result = PyObject_Vectorcall(callable, args, nargs, NULL); if (result == NULL) { - _PyErr_WriteUnraisableMsg("on calling ctypes callback function", - callable); + PyErr_FormatUnraisable( + "Exception ignored on calling ctypes callback function %R", + callable); } #ifdef MS_WIN32 @@ -258,9 +258,10 @@ static void _CallPythonObject(void *mem, if (keep == NULL) { /* Could not convert callback result. */ - _PyErr_WriteUnraisableMsg("on converting result " - "of ctypes callback function", - callable); + PyErr_FormatUnraisable( + "Exception ignored on converting result " + "of ctypes callback function %R", + callable); } else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { if (keep == Py_None) { @@ -270,9 +271,10 @@ static void _CallPythonObject(void *mem, else if (PyErr_WarnEx(PyExc_RuntimeWarning, "memory leak in callback function.", 1) == -1) { - _PyErr_WriteUnraisableMsg("on converting result " - "of ctypes callback function", - callable); + PyErr_FormatUnraisable( + "Exception ignored on converting result " + "of ctypes callback function %R", + callable); } } } diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index fc08c42bd3574a..3b11cd7f58ce4b 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -168,16 +168,18 @@ _ctypes_get_errobj(int **pspace) if (error_object_name == NULL) return NULL; } - errobj = PyDict_GetItemWithError(dict, error_object_name); + if (PyDict_GetItemRef(dict, error_object_name, &errobj) < 0) { + return NULL; + } if (errobj) { if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) { PyErr_SetString(PyExc_RuntimeError, "ctypes.error_object is an invalid capsule"); + Py_DECREF(errobj); return NULL; } - Py_INCREF(errobj); } - else if (!PyErr_Occurred()) { + else { void *space = PyMem_Calloc(2, sizeof(int)); if (space == NULL) return NULL; @@ -192,9 +194,6 @@ _ctypes_get_errobj(int **pspace) return NULL; } } - else { - return NULL; - } *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM); return errobj; } @@ -1405,7 +1404,7 @@ static PyObject *load_library(PyObject *self, PyObject *args) #ifdef _WIN64 return PyLong_FromVoidPtr(hMod); #else - return Py_BuildValue("i", hMod); + return PyLong_FromLong((int)hMod); #endif } @@ -1922,13 +1921,11 @@ create_pointer_type(PyObject *module, PyObject *cls) PyTypeObject *typ; PyObject *key; - result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls); - if (result) { - return Py_NewRef(result); - } - else if (PyErr_Occurred()) { - return NULL; + if (PyDict_GetItemRef(_ctypes_ptrtype_cache, cls, &result) != 0) { + // found or error + return result; } + // not found if (PyUnicode_CheckExact(cls)) { PyObject *name = PyUnicode_FromFormat("LP_%U", cls); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), @@ -1986,16 +1983,14 @@ create_pointer_inst(PyObject *module, PyObject *arg) PyObject *result; PyObject *typ; - typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); - if (typ) { - return PyObject_CallOneArg(typ, arg); - } - else if (PyErr_Occurred()) { + if (PyDict_GetItemRef(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg), &typ) < 0) { return NULL; } - typ = create_pointer_type(NULL, (PyObject *)Py_TYPE(arg)); - if (typ == NULL) - return NULL; + if (typ == NULL) { + typ = create_pointer_type(NULL, (PyObject *)Py_TYPE(arg)); + if (typ == NULL) + return NULL; + } result = PyObject_CallOneArg(typ, arg); Py_DECREF(typ); return result; diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 6fbcf77a115371..dfdb96b0e7258a 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -697,29 +697,47 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct stgdict->align = total_align; stgdict->length = len; /* ADD ffi_ofs? */ -#define MAX_STRUCT_SIZE 16 +/* + * The value of MAX_STRUCT_SIZE depends on the platform Python is running on. + */ +#if defined(__aarch64__) || defined(__arm__) +# define MAX_STRUCT_SIZE 32 +#elif defined(__powerpc64__) +# define MAX_STRUCT_SIZE 64 +#else +# define MAX_STRUCT_SIZE 16 +#endif if (arrays_seen && (size <= MAX_STRUCT_SIZE)) { /* - * See bpo-22273. Arrays are normally treated as pointers, which is - * fine when an array name is being passed as parameter, but not when - * passing structures by value that contain arrays. On 64-bit Linux, - * small structures passed by value are passed in registers, and in + * See bpo-22273 and gh-110190. Arrays are normally treated as + * pointers, which is fine when an array name is being passed as + * parameter, but not when passing structures by value that contain + * arrays. + * Small structures passed by value are passed in registers, and in * order to do this, libffi needs to know the true type of the array * members of structs. Treating them as pointers breaks things. * - * By small structures, we mean ones that are 16 bytes or less. In that - * case, there can't be more than 16 elements after unrolling arrays, - * as we (will) disallow bitfields. So we can collect the true ffi_type - * values in a fixed-size local array on the stack and, if any arrays - * were seen, replace the ffi_type_pointer.elements with a more - * accurate set, to allow libffi to marshal them into registers - * correctly. It means one more loop over the fields, but if we got - * here, the structure is small, so there aren't too many of those. + * Small structures have different sizes depending on the platform + * where Python is running on: * - * Although the passing in registers is specific to 64-bit Linux, the - * array-in-struct vs. pointer problem is general. But we restrict the - * type transformation to small structs nonetheless. + * * x86-64: 16 bytes or less + * * Arm platforms (both 32 and 64 bit): 32 bytes or less + * * PowerPC 64 Little Endian: 64 bytes or less + * + * In that case, there can't be more than 16, 32 or 64 elements after + * unrolling arrays, as we (will) disallow bitfields. + * So we can collect the true ffi_type values in a fixed-size local + * array on the stack and, if any arrays were seen, replace the + * ffi_type_pointer.elements with a more accurate set, to allow + * libffi to marshal them into registers correctly. + * It means one more loop over the fields, but if we got here, + * the structure is small, so there aren't too many of those. + * + * Although the passing in registers is specific to the above + * platforms, the array-in-struct vs. pointer problem is general. + * But we restrict the type transformation to small structs + * nonetheless. * * Note that although a union may be small in terms of memory usage, it * could contain many overlapping declarations of arrays, e.g. @@ -745,6 +763,8 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct * struct { uint_32 e1; uint_32 e2; ... uint_32 e_4; } f6; * } * + * The same principle applies for a struct 32 or 64 bytes in size. + * * So the struct/union needs setting up as follows: all non-array * elements copied across as is, and all array elements replaced with * an equivalent struct which has as many fields as the array has diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 292b57c083d0c8..2ec8f34c5c220b 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -10,6 +10,11 @@ static const char PyCursesVersion[] = "2.1"; /* Includes */ +// clinic/_curses_panel.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "py_curses.h" diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index d339a8aa798361..d04d1e973af030 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -3673,7 +3673,7 @@ _curses_mousemask_impl(PyObject *module, unsigned long newmask) #endif /*[clinic input] -_curses.napms +_curses.napms -> int ms: int Duration in milliseconds. @@ -3682,13 +3682,13 @@ _curses.napms Sleep for specified time. [clinic start generated code]*/ -static PyObject * +static int _curses_napms_impl(PyObject *module, int ms) -/*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/ +/*[clinic end generated code: output=5f292a6a724491bd input=c6d6e01f2f1df9f7]*/ { PyCursesInitialised; - return Py_BuildValue("i", napms(ms)); + return napms(ms); } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 0d356779cfe192..cb5403e8461ff0 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -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,7 +1923,8 @@ 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; } @@ -1935,7 +1942,7 @@ 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); @@ -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; @@ -3943,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); @@ -3964,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 = '-'; @@ -4046,8 +4060,8 @@ static PyObject * timezone_getinitargs(PyDateTime_TimeZone *self, PyObject *Py_UNUSED(ignored)) { if (self->name == NULL) - return Py_BuildValue("(O)", self->offset); - return Py_BuildValue("(OO)", self->offset, self->name); + return PyTuple_Pack(1, self->offset); + return PyTuple_Pack(2, self->offset, self->name); } static PyMethodDef timezone_methods[] = { @@ -4616,7 +4630,7 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) { } int hour = 0, minute = 0, second = 0, microsecond = 0; - int tzoffset, tzimicrosecond = 0; + int tzoffset = 0, tzimicrosecond = 0; int rv = parse_isoformat_time(p, len, &hour, &minute, &second, µsecond, &tzoffset, &tzimicrosecond); @@ -6134,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); @@ -6246,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; @@ -6257,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); @@ -6266,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. */ @@ -6370,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); @@ -6692,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; } @@ -6706,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) { @@ -6727,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) @@ -6775,77 +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; - } + /* -23:59 */ + PyObject *min = create_timezone_from_delta(-1, 60, 0, 1); + DATETIME_ADD_MACRO(d, "min", min); - x = create_timezone(delta, NULL); - Py_DECREF(delta); - DATETIME_ADD_MACRO(d, "max", x); + /* +23:59 */ + PyObject *max = create_timezone_from_delta(0, (23 * 60 + 59) * 60, 0, 0); + DATETIME_ADD_MACRO(d, "max", max); - /* Epoch */ - PyDateTime_Epoch = new_datetime(1970, 1, 1, 0, 0, 0, 0, - PyDateTime_TimeZone_UTC, 0); - if (PyDateTime_Epoch == NULL) { - return -1; - } - - /* 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_Add(module, "datetime_CAPI", x) < 0) { - 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 @@ -6866,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 bd807698927e86..ee33fe625be3d7 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -2,6 +2,11 @@ /* DBM module using dictionary interface */ +// clinic/_dbmmodule.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include @@ -552,11 +557,6 @@ dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, } const char *name = PyBytes_AS_STRING(filenamebytes); - if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) { - Py_DECREF(filenamebytes); - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return NULL; - } PyObject *self = newdbmobject(state, name, iflags, mode); Py_DECREF(filenamebytes); return self; diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index b49ea3cbb410ef..8b93f8e2cbcf0b 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3593,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); @@ -5877,6 +5883,7 @@ cfunc_noargs(PyTypeObject *t, const char *name) return NULL; } +static int minalloc_is_set = 0; static int _decimal_exec(PyObject *m) @@ -5899,7 +5906,12 @@ _decimal_exec(PyObject *m) mpd_reallocfunc = PyMem_Realloc; mpd_callocfunc = mpd_callocfunc_em; mpd_free = PyMem_Free; - mpd_setminalloc(_Py_DEC_MINALLOC); + + /* 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); 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/_functoolsmodule.c b/Modules/_functoolsmodule.c index 8ea493ad9ab278..9ab847165dc097 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1087,19 +1087,9 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds The cache dict holds one reference to the link. We created one other reference when the link was created. The linked list only has borrowed references. */ - popresult = _PyDict_Pop_KnownHash(self->cache, link->key, - link->hash, Py_None); - if (popresult == Py_None) { - /* Getting here means that the user function call or another - thread has already removed the old key from the dictionary. - This link is now an orphan. Since we don't want to leave the - cache in an inconsistent state, we don't restore the link. */ - Py_DECREF(popresult); - Py_DECREF(link); - Py_DECREF(key); - return result; - } - if (popresult == NULL) { + int res = _PyDict_Pop_KnownHash((PyDictObject*)self->cache, link->key, + link->hash, &popresult); + if (res < 0) { /* An error arose while trying to remove the oldest key (the one being evicted) from the cache. We restore the link to its original position as the oldest link. Then we allow the @@ -1110,10 +1100,22 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds Py_DECREF(result); return NULL; } + if (res == 0) { + /* Getting here means that the user function call or another + thread has already removed the old key from the dictionary. + This link is now an orphan. Since we don't want to leave the + cache in an inconsistent state, we don't restore the link. */ + assert(popresult == NULL); + Py_DECREF(link); + Py_DECREF(key); + return result; + } + /* Keep a reference to the old key and old result to prevent their ref counts from going to zero during the update. That will prevent potentially arbitrary object clean-up code (i.e. __del__) from running while we're still adjusting the links. */ + assert(popresult != NULL); oldkey = link->key; oldresult = link->result; @@ -1272,7 +1274,11 @@ lru_cache_dealloc(lru_cache_object *obj) static PyObject * lru_cache_call(lru_cache_object *self, PyObject *args, PyObject *kwds) { - return self->wrapper(self, args, kwds); + PyObject *result; + Py_BEGIN_CRITICAL_SECTION(self); + result = self->wrapper(self, args, kwds); + Py_END_CRITICAL_SECTION(); + return result; } static PyObject * @@ -1285,6 +1291,7 @@ lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) } /*[clinic input] +@critical_section _functools._lru_cache_wrapper.cache_info Report cache statistics @@ -1292,7 +1299,7 @@ Report cache statistics static PyObject * _functools__lru_cache_wrapper_cache_info_impl(PyObject *self) -/*[clinic end generated code: output=cc796a0b06dbd717 input=f05e5b6ebfe38645]*/ +/*[clinic end generated code: output=cc796a0b06dbd717 input=00e1acb31aa21ecc]*/ { lru_cache_object *_self = (lru_cache_object *) self; if (_self->maxsize == -1) { @@ -1306,6 +1313,7 @@ _functools__lru_cache_wrapper_cache_info_impl(PyObject *self) } /*[clinic input] +@critical_section _functools._lru_cache_wrapper.cache_clear Clear the cache and cache statistics @@ -1313,7 +1321,7 @@ Clear the cache and cache statistics static PyObject * _functools__lru_cache_wrapper_cache_clear_impl(PyObject *self) -/*[clinic end generated code: output=58423b35efc3e381 input=6ca59dba09b12584]*/ +/*[clinic end generated code: output=58423b35efc3e381 input=dfa33acbecf8b4b2]*/ { lru_cache_object *_self = (lru_cache_object *) self; lru_list_elem *list = lru_cache_unlink_list(_self); diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index eff36fd7fb669b..db868c18160fda 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -1,8 +1,12 @@ - /* GDBM module using dictionary interface */ /* Author: Anthony Baxter, after dbmmodule.c */ /* Doc strings: Mitch Chapman */ +// clinic/_gdbmmodule.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "gdbm.h" diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index ee6fb8b4b03643..0e230f332ff6cb 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -22,6 +22,7 @@ # define Py_BUILD_CORE_MODULE 1 #endif +#include #include "Python.h" #include "pycore_hashtable.h" #include "pycore_pyhash.h" // _Py_HashBytes() @@ -227,16 +228,16 @@ typedef struct { PyObject_HEAD EVP_MD_CTX *ctx; /* OpenSSL message digest context */ // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; /* OpenSSL context lock */ + bool use_mutex; + PyMutex mutex; /* OpenSSL context lock */ } EVPobject; typedef struct { PyObject_HEAD HMAC_CTX *ctx; /* OpenSSL hmac context */ // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; /* HMAC context lock */ + bool use_mutex; + PyMutex mutex; /* HMAC context lock */ } HMACobject; #include "clinic/_hashopenssl.c.h" @@ -414,8 +415,7 @@ newEVPobject(PyTypeObject *type) if (retval == NULL) { return NULL; } - - retval->lock = NULL; + HASHLIB_INIT_MUTEX(retval); retval->ctx = EVP_MD_CTX_new(); if (retval->ctx == NULL) { @@ -453,8 +453,6 @@ static void EVP_dealloc(EVPobject *self) { PyTypeObject *tp = Py_TYPE(self); - if (self->lock != NULL) - PyThread_free_lock(self->lock); EVP_MD_CTX_free(self->ctx); PyObject_Free(self); Py_DECREF(tp); @@ -582,16 +580,14 @@ EVP_update(EVPobject *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &view); - if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); - /* fail? lock = NULL and we fail over to non-threaded code. */ + if (!self->use_mutex && view.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); result = EVP_hash(self, view.buf, view.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { result = EVP_hash(self, view.buf, view.len); @@ -1540,7 +1536,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, } self->ctx = ctx; - self->lock = NULL; + HASHLIB_INIT_MUTEX(self); if ((msg_obj != NULL) && (msg_obj != Py_None)) { if (!_hmac_update(self, msg_obj)) @@ -1582,16 +1578,14 @@ _hmac_update(HMACobject *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROR(obj, &view, return 0); - if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); - /* fail? lock = NULL and we fail over to non-threaded code. */ + if (!self->use_mutex && view.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); r = HMAC_Update(self->ctx, (const unsigned char*)view.buf, view.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { r = HMAC_Update(self->ctx, (const unsigned char*)view.buf, view.len); @@ -1633,7 +1627,7 @@ _hashlib_HMAC_copy_impl(HMACobject *self) return NULL; } retval->ctx = ctx; - retval->lock = NULL; + HASHLIB_INIT_MUTEX(retval); return (PyObject *)retval; } @@ -1642,9 +1636,6 @@ static void _hmac_dealloc(HMACobject *self) { PyTypeObject *tp = Py_TYPE(self); - if (self->lock != NULL) { - PyThread_free_lock(self->lock); - } HMAC_CTX_free(self->ctx); PyObject_Free(self); Py_DECREF(tp); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index e8caf9f0df6dbf..f02207ace9f3d2 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -8,11 +8,11 @@ */ #include "Python.h" -#include "pycore_bytesobject.h" // _PyBytes_Join() -#include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_pyerrors.h" // _Py_FatalErrorFormat() -#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() +#include "pycore_bytesobject.h" // _PyBytes_Join() +#include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _Py_FatalErrorFormat() +#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "_iomodule.h" @@ -82,6 +82,7 @@ _bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readint } /*[clinic input] +@critical_section _io._BufferedIOBase.readinto buffer: Py_buffer(accept={rwbuffer}) / @@ -89,12 +90,13 @@ _io._BufferedIOBase.readinto static PyObject * _io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/ +/*[clinic end generated code: output=8c8cda6684af8038 input=5273d20db7f56e1a]*/ { return _bufferediobase_readinto_generic(self, buffer, 0); } /*[clinic input] +@critical_section _io._BufferedIOBase.readinto1 buffer: Py_buffer(accept={rwbuffer}) / @@ -102,7 +104,7 @@ _io._BufferedIOBase.readinto1 static PyObject * _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer) -/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/ +/*[clinic end generated code: output=358623e4fd2b69d3 input=d6eb723dedcee654]*/ { return _bufferediobase_readinto_generic(self, buffer, 1); } @@ -431,12 +433,13 @@ buffered_dealloc(buffered *self) } /*[clinic input] +@critical_section _io._Buffered.__sizeof__ [clinic start generated code]*/ static PyObject * _io__Buffered___sizeof___impl(buffered *self) -/*[clinic end generated code: output=0231ef7f5053134e input=753c782d808d34df]*/ +/*[clinic end generated code: output=0231ef7f5053134e input=07a32d578073ea64]*/ { size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->buffer) { @@ -488,12 +491,13 @@ _io__Buffered__dealloc_warn(buffered *self, PyObject *source) /* Flush and close */ /*[clinic input] +@critical_section _io._Buffered.flush as _io__Buffered_simple_flush [clinic start generated code]*/ static PyObject * _io__Buffered_simple_flush_impl(buffered *self) -/*[clinic end generated code: output=29ebb3820db1bdfd input=f33ef045e7250767]*/ +/*[clinic end generated code: output=29ebb3820db1bdfd input=5248cb84a65f80bd]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(flush)); @@ -513,20 +517,28 @@ buffered_closed(buffered *self) return closed; } +/*[clinic input] +@critical_section +@getter +_io._Buffered.closed +[clinic start generated code]*/ + static PyObject * -buffered_closed_get(buffered *self, void *context) +_io__Buffered_closed_get_impl(buffered *self) +/*[clinic end generated code: output=f08ce57290703a1a input=18eddefdfe4a3d2f]*/ { CHECK_INITIALIZED(self) return PyObject_GetAttr(self->raw, &_Py_ID(closed)); } /*[clinic input] +@critical_section _io._Buffered.close [clinic start generated code]*/ static PyObject * _io__Buffered_close_impl(buffered *self) -/*[clinic end generated code: output=7280b7b42033be0c input=d20b83d1ddd7d805]*/ +/*[clinic end generated code: output=7280b7b42033be0c input=56d95935b03fd326]*/ { PyObject *res = NULL; int r; @@ -583,12 +595,13 @@ _io__Buffered_close_impl(buffered *self) } /*[clinic input] +@critical_section _io._Buffered.detach [clinic start generated code]*/ static PyObject * _io__Buffered_detach_impl(buffered *self) -/*[clinic end generated code: output=dd0fc057b8b779f7 input=482762a345cc9f44]*/ +/*[clinic end generated code: output=dd0fc057b8b779f7 input=d4ef1828a678be37]*/ { PyObject *raw; CHECK_INITIALIZED(self) @@ -605,50 +618,68 @@ _io__Buffered_detach_impl(buffered *self) /* Inquiries */ /*[clinic input] +@critical_section _io._Buffered.seekable [clinic start generated code]*/ static PyObject * _io__Buffered_seekable_impl(buffered *self) -/*[clinic end generated code: output=90172abb5ceb6e8f input=7d35764f5fb5262b]*/ +/*[clinic end generated code: output=90172abb5ceb6e8f input=e3a4fc1d297b2fd3]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(seekable)); } /*[clinic input] +@critical_section _io._Buffered.readable [clinic start generated code]*/ static PyObject * _io__Buffered_readable_impl(buffered *self) -/*[clinic end generated code: output=92afa07661ecb698 input=640619addb513b8b]*/ +/*[clinic end generated code: output=92afa07661ecb698 input=abe54107d59bca9a]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(readable)); } /*[clinic input] +@critical_section _io._Buffered.writable [clinic start generated code]*/ static PyObject * _io__Buffered_writable_impl(buffered *self) -/*[clinic end generated code: output=4e3eee8d6f9d8552 input=b35ea396b2201554]*/ +/*[clinic end generated code: output=4e3eee8d6f9d8552 input=45eb76bf6a10e6f7]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable)); } + +/*[clinic input] +@critical_section +@getter +_io._Buffered.name +[clinic start generated code]*/ + static PyObject * -buffered_name_get(buffered *self, void *context) +_io__Buffered_name_get_impl(buffered *self) +/*[clinic end generated code: output=d2adf384051d3d10 input=6b84a0e6126f545e]*/ { CHECK_INITIALIZED(self) return PyObject_GetAttr(self->raw, &_Py_ID(name)); } +/*[clinic input] +@critical_section +@getter +_io._Buffered.mode +[clinic start generated code]*/ + static PyObject * -buffered_mode_get(buffered *self, void *context) +_io__Buffered_mode_get_impl(buffered *self) +/*[clinic end generated code: output=0feb205748892fa4 input=0762d5e28542fd8c]*/ { CHECK_INITIALIZED(self) return PyObject_GetAttr(self->raw, &_Py_ID(mode)); @@ -657,24 +688,26 @@ buffered_mode_get(buffered *self, void *context) /* Lower-level APIs */ /*[clinic input] +@critical_section _io._Buffered.fileno [clinic start generated code]*/ static PyObject * _io__Buffered_fileno_impl(buffered *self) -/*[clinic end generated code: output=b717648d58a95ee3 input=768ea30b3f6314a7]*/ +/*[clinic end generated code: output=b717648d58a95ee3 input=1c4fead777bae20a]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(fileno)); } /*[clinic input] +@critical_section _io._Buffered.isatty [clinic start generated code]*/ static PyObject * _io__Buffered_isatty_impl(buffered *self) -/*[clinic end generated code: output=c20e55caae67baea input=9ea007b11559bee4]*/ +/*[clinic end generated code: output=c20e55caae67baea input=e53d182d7e490e3a]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(isatty)); @@ -880,12 +913,13 @@ buffered_flush_and_rewind_unlocked(buffered *self) } /*[clinic input] +@critical_section _io._Buffered.flush [clinic start generated code]*/ static PyObject * _io__Buffered_flush_impl(buffered *self) -/*[clinic end generated code: output=da2674ef1ce71f3a input=fda63444697c6bf4]*/ +/*[clinic end generated code: output=da2674ef1ce71f3a input=6b30de9f083419c2]*/ { PyObject *res; @@ -901,6 +935,7 @@ _io__Buffered_flush_impl(buffered *self) } /*[clinic input] +@critical_section _io._Buffered.peek size: Py_ssize_t = 0 / @@ -909,7 +944,7 @@ _io._Buffered.peek static PyObject * _io__Buffered_peek_impl(buffered *self, Py_ssize_t size) -/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/ +/*[clinic end generated code: output=ba7a097ca230102b input=56733376f926d982]*/ { PyObject *res = NULL; @@ -933,6 +968,7 @@ _io__Buffered_peek_impl(buffered *self, Py_ssize_t size) } /*[clinic input] +@critical_section _io._Buffered.read size as n: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -940,7 +976,7 @@ _io._Buffered.read static PyObject * _io__Buffered_read_impl(buffered *self, Py_ssize_t n) -/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/ +/*[clinic end generated code: output=f41c78bb15b9bbe9 input=bdb4b0425b295472]*/ { PyObject *res; @@ -974,6 +1010,7 @@ _io__Buffered_read_impl(buffered *self, Py_ssize_t n) } /*[clinic input] +@critical_section _io._Buffered.read1 size as n: Py_ssize_t = -1 / @@ -981,7 +1018,7 @@ _io._Buffered.read1 static PyObject * _io__Buffered_read1_impl(buffered *self, Py_ssize_t n) -/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/ +/*[clinic end generated code: output=bcc4fb4e54d103a3 input=3d0ad241aa52b36c]*/ { Py_ssize_t have, r; PyObject *res = NULL; @@ -1110,6 +1147,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) } /*[clinic input] +@critical_section _io._Buffered.readinto buffer: Py_buffer(accept={rwbuffer}) / @@ -1117,12 +1155,13 @@ _io._Buffered.readinto static PyObject * _io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/ +/*[clinic end generated code: output=bcb376580b1d8170 input=777c33e7adaa2bcd]*/ { return _buffered_readinto_generic(self, buffer, 0); } /*[clinic input] +@critical_section _io._Buffered.readinto1 buffer: Py_buffer(accept={rwbuffer}) / @@ -1130,7 +1169,7 @@ _io._Buffered.readinto1 static PyObject * _io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/ +/*[clinic end generated code: output=6e5c6ac5868205d6 input=ef03cc5fc92a6895]*/ { return _buffered_readinto_generic(self, buffer, 1); } @@ -1245,6 +1284,7 @@ _buffered_readline(buffered *self, Py_ssize_t limit) } /*[clinic input] +@critical_section _io._Buffered.readline size: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -1252,7 +1292,7 @@ _io._Buffered.readline static PyObject * _io__Buffered_readline_impl(buffered *self, Py_ssize_t size) -/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/ +/*[clinic end generated code: output=24dd2aa6e33be83c input=e81ca5abd4280776]*/ { CHECK_INITIALIZED(self) return _buffered_readline(self, size); @@ -1260,12 +1300,13 @@ _io__Buffered_readline_impl(buffered *self, Py_ssize_t size) /*[clinic input] +@critical_section _io._Buffered.tell [clinic start generated code]*/ static PyObject * _io__Buffered_tell_impl(buffered *self) -/*[clinic end generated code: output=386972ae84716c1e input=ad61e04a6b349573]*/ +/*[clinic end generated code: output=386972ae84716c1e input=ab12e67d8abcb42f]*/ { Py_off_t pos; @@ -1279,6 +1320,7 @@ _io__Buffered_tell_impl(buffered *self) } /*[clinic input] +@critical_section _io._Buffered.seek target as targetobj: object whence: int = 0 @@ -1287,7 +1329,7 @@ _io._Buffered.seek static PyObject * _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) -/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/ +/*[clinic end generated code: output=7ae0e8dc46efdefb input=b5a12be70e0ad07b]*/ { Py_off_t target, n; PyObject *res = NULL; @@ -1376,6 +1418,7 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) } /*[clinic input] +@critical_section _io._Buffered.truncate cls: defining_class pos: object = None @@ -1384,7 +1427,7 @@ _io._Buffered.truncate static PyObject * _io__Buffered_truncate_impl(buffered *self, PyTypeObject *cls, PyObject *pos) -/*[clinic end generated code: output=fe3882fbffe79f1a input=f5b737d97d76303f]*/ +/*[clinic end generated code: output=fe3882fbffe79f1a input=e3cbf794575bd794]*/ { PyObject *res = NULL; @@ -1998,6 +2041,7 @@ _bufferedwriter_flush_unlocked(buffered *self) } /*[clinic input] +@critical_section _io.BufferedWriter.write buffer: Py_buffer / @@ -2005,7 +2049,7 @@ _io.BufferedWriter.write static PyObject * _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer) -/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/ +/*[clinic end generated code: output=7f8d1365759bfc6b input=6a9c041de0c337be]*/ { PyObject *res = NULL; Py_ssize_t written, avail, remaining; @@ -2482,9 +2526,9 @@ static PyMemberDef bufferedreader_members[] = { }; static PyGetSetDef bufferedreader_getset[] = { - {"closed", (getter)buffered_closed_get, NULL, NULL}, - {"name", (getter)buffered_name_get, NULL, NULL}, - {"mode", (getter)buffered_mode_get, NULL, NULL}, + _IO__BUFFERED_CLOSED_GETSETDEF + _IO__BUFFERED_NAME_GETSETDEF + _IO__BUFFERED_MODE_GETSETDEF {NULL} }; @@ -2542,9 +2586,9 @@ static PyMemberDef bufferedwriter_members[] = { }; static PyGetSetDef bufferedwriter_getset[] = { - {"closed", (getter)buffered_closed_get, NULL, NULL}, - {"name", (getter)buffered_name_get, NULL, NULL}, - {"mode", (getter)buffered_mode_get, NULL, NULL}, + _IO__BUFFERED_CLOSED_GETSETDEF + _IO__BUFFERED_NAME_GETSETDEF + _IO__BUFFERED_MODE_GETSETDEF {NULL} }; @@ -2660,9 +2704,9 @@ static PyMemberDef bufferedrandom_members[] = { }; static PyGetSetDef bufferedrandom_getset[] = { - {"closed", (getter)buffered_closed_get, NULL, NULL}, - {"name", (getter)buffered_name_get, NULL, NULL}, - {"mode", (getter)buffered_mode_get, NULL, NULL}, + _IO__BUFFERED_CLOSED_GETSETDEF + _IO__BUFFERED_NAME_GETSETDEF + _IO__BUFFERED_MODE_GETSETDEF {NULL} }; diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index f3074203f54ea2..16b8ac600ace79 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -126,12 +126,13 @@ unshare_buffer(bytesio *self, size_t size) static int resize_buffer(bytesio *self, size_t size) { + assert(self->buf != NULL); + assert(self->exports == 0); + /* Here, unsigned types are used to avoid dealing with signed integer overflow, which is undefined in C. */ size_t alloc = PyBytes_GET_SIZE(self->buf); - assert(self->buf != NULL); - /* For simplicity, stay in the range of the signed type. Anyway, Python doesn't allow strings to be longer than this. */ if (size > PY_SSIZE_T_MAX) @@ -1074,7 +1075,7 @@ bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags) "bytesiobuf_getbuffer: view==NULL argument is obsolete"); return -1; } - if (SHARED_BUF(b)) { + if (b->exports == 0 && SHARED_BUF(b)) { if (unshare_buffer(b, b->string_size) < 0) return -1; } diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 49a3573ab97473..112408a95df036 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_io_open__doc__, "open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" @@ -403,4 +404,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=aaf96c8d9bd20abc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5d60f4e778a600a4 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 7577bdec5c3b20..ec46d5409a3d82 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -7,6 +7,8 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() +#include "pycore_modsupport.h" // _PyArg_BadArgument() PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, "readinto($self, buffer, /)\n" @@ -29,11 +31,9 @@ _io__BufferedIOBase_readinto(PyObject *self, PyObject *arg) _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); - goto exit; - } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__BufferedIOBase_readinto_impl(self, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -65,11 +65,9 @@ _io__BufferedIOBase_readinto1(PyObject *self, PyObject *arg) _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto1", "argument", "contiguous buffer", arg); - goto exit; - } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__BufferedIOBase_readinto1_impl(self, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -289,7 +287,13 @@ _io__Buffered___sizeof___impl(buffered *self); static PyObject * _io__Buffered___sizeof__(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered___sizeof___impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered___sizeof___impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered__dealloc_warn__doc__, @@ -314,7 +318,35 @@ _io__Buffered_simple_flush_impl(buffered *self); static PyObject * _io__Buffered_simple_flush(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_simple_flush_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_simple_flush_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO__BUFFERED_CLOSED_GETSETDEF) +# undef _IO__BUFFERED_CLOSED_GETSETDEF +# define _IO__BUFFERED_CLOSED_GETSETDEF {"closed", (getter)_io__Buffered_closed_get, (setter)_io__Buffered_closed_set, NULL}, +#else +# define _IO__BUFFERED_CLOSED_GETSETDEF {"closed", (getter)_io__Buffered_closed_get, NULL, NULL}, +#endif + +static PyObject * +_io__Buffered_closed_get_impl(buffered *self); + +static PyObject * +_io__Buffered_closed_get(buffered *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_closed_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_close__doc__, @@ -331,7 +363,13 @@ _io__Buffered_close_impl(buffered *self); static PyObject * _io__Buffered_close(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_close_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_close_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_detach__doc__, @@ -348,7 +386,13 @@ _io__Buffered_detach_impl(buffered *self); static PyObject * _io__Buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_detach_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_detach_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_seekable__doc__, @@ -365,7 +409,13 @@ _io__Buffered_seekable_impl(buffered *self); static PyObject * _io__Buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_seekable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_seekable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_readable__doc__, @@ -382,7 +432,13 @@ _io__Buffered_readable_impl(buffered *self); static PyObject * _io__Buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_readable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_readable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_writable__doc__, @@ -399,7 +455,57 @@ _io__Buffered_writable_impl(buffered *self); static PyObject * _io__Buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_writable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_writable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO__BUFFERED_NAME_GETSETDEF) +# undef _IO__BUFFERED_NAME_GETSETDEF +# define _IO__BUFFERED_NAME_GETSETDEF {"name", (getter)_io__Buffered_name_get, (setter)_io__Buffered_name_set, NULL}, +#else +# define _IO__BUFFERED_NAME_GETSETDEF {"name", (getter)_io__Buffered_name_get, NULL, NULL}, +#endif + +static PyObject * +_io__Buffered_name_get_impl(buffered *self); + +static PyObject * +_io__Buffered_name_get(buffered *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_name_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO__BUFFERED_MODE_GETSETDEF) +# undef _IO__BUFFERED_MODE_GETSETDEF +# define _IO__BUFFERED_MODE_GETSETDEF {"mode", (getter)_io__Buffered_mode_get, (setter)_io__Buffered_mode_set, NULL}, +#else +# define _IO__BUFFERED_MODE_GETSETDEF {"mode", (getter)_io__Buffered_mode_get, NULL, NULL}, +#endif + +static PyObject * +_io__Buffered_mode_get_impl(buffered *self); + +static PyObject * +_io__Buffered_mode_get(buffered *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_mode_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_fileno__doc__, @@ -416,7 +522,13 @@ _io__Buffered_fileno_impl(buffered *self); static PyObject * _io__Buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_fileno_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_fileno_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_isatty__doc__, @@ -433,7 +545,13 @@ _io__Buffered_isatty_impl(buffered *self); static PyObject * _io__Buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_isatty_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_isatty_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_flush__doc__, @@ -450,7 +568,13 @@ _io__Buffered_flush_impl(buffered *self); static PyObject * _io__Buffered_flush(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_flush_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_flush_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_peek__doc__, @@ -489,7 +613,9 @@ _io__Buffered_peek(buffered *self, PyObject *const *args, Py_ssize_t nargs) size = ival; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_peek_impl(self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -522,7 +648,9 @@ _io__Buffered_read(buffered *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_read_impl(self, n); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -564,7 +692,9 @@ _io__Buffered_read1(buffered *self, PyObject *const *args, Py_ssize_t nargs) n = ival; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_read1_impl(self, n); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -591,11 +721,9 @@ _io__Buffered_readinto(buffered *self, PyObject *arg) _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); - goto exit; - } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_readinto_impl(self, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -627,11 +755,9 @@ _io__Buffered_readinto1(buffered *self, PyObject *arg) _PyArg_BadArgument("readinto1", "argument", "read-write bytes-like object", arg); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto1", "argument", "contiguous buffer", arg); - goto exit; - } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_readinto1_impl(self, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -669,7 +795,9 @@ _io__Buffered_readline(buffered *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_readline_impl(self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -689,7 +817,13 @@ _io__Buffered_tell_impl(buffered *self); static PyObject * _io__Buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__Buffered_tell_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io__Buffered_tell_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io__Buffered_seek__doc__, @@ -722,7 +856,9 @@ _io__Buffered_seek(buffered *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_seek_impl(self, targetobj, whence); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -768,7 +904,9 @@ _io__Buffered_truncate(buffered *self, PyTypeObject *cls, PyObject *const *args, } pos = args[0]; skip_optional_posonly: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io__Buffered_truncate_impl(self, cls, pos); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -944,11 +1082,9 @@ _io_BufferedWriter_write(buffered *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); - goto exit; - } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_BufferedWriter_write_impl(self, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -1094,4 +1230,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=f940cea085f0bf91 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0999c33f666dc692 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index d42ab48cef2859..37023e49087647 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_io_BytesIO_readable__doc__, "readable($self, /)\n" @@ -331,10 +332,6 @@ _io_BytesIO_readinto(bytesio *self, PyObject *arg) _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); - goto exit; - } return_value = _io_BytesIO_readinto_impl(self, &buffer); exit: @@ -537,4 +534,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b753fdf1ba36c461 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2be0e05a8871b7e2 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index deb99fa9d99bd0..cf3ba28b066cf7 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_io_FileIO_close__doc__, "close($self, /)\n" @@ -248,10 +249,6 @@ _io_FileIO_readinto(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_s _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument 1", "contiguous buffer", args[0]); - goto exit; - } return_value = _io_FileIO_readinto_impl(self, cls, &buffer); exit: @@ -380,10 +377,6 @@ _io_FileIO_write(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssiz if (PyObject_GetBuffer(args[0], &b, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", "argument 1", "contiguous buffer", args[0]); - goto exit; - } return_value = _io_FileIO_write_impl(self, cls, &b); exit: @@ -535,4 +528,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=2ce6ce923ccef86e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1c0f4a36f76b0c6a input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 9ac80b687925a4..6bdfa1444015ac 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_io__IOBase_seek__doc__, "seek($self, offset, whence=os.SEEK_SET, /)\n" @@ -437,4 +438,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=95e1633805d10294 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a22bc5db0ecaacb input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index ccdae18d2af24a..fc2962d1c9c9a7 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -7,6 +7,8 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_io_StringIO_getvalue__doc__, "getvalue($self, /)\n" @@ -23,7 +25,13 @@ _io_StringIO_getvalue_impl(stringio *self); static PyObject * _io_StringIO_getvalue(stringio *self, PyObject *Py_UNUSED(ignored)) { - return _io_StringIO_getvalue_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_getvalue_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_StringIO_tell__doc__, @@ -41,7 +49,13 @@ _io_StringIO_tell_impl(stringio *self); static PyObject * _io_StringIO_tell(stringio *self, PyObject *Py_UNUSED(ignored)) { - return _io_StringIO_tell_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_tell_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_StringIO_read__doc__, @@ -75,7 +89,9 @@ _io_StringIO_read(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_StringIO_read_impl(self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -111,7 +127,9 @@ _io_StringIO_readline(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_StringIO_readline_impl(self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -149,7 +167,9 @@ _io_StringIO_truncate(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_StringIO_truncate_impl(self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -203,7 +223,9 @@ _io_StringIO_seek(stringio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_StringIO_seek_impl(self, pos, whence); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -221,6 +243,21 @@ PyDoc_STRVAR(_io_StringIO_write__doc__, #define _IO_STRINGIO_WRITE_METHODDEF \ {"write", (PyCFunction)_io_StringIO_write, METH_O, _io_StringIO_write__doc__}, +static PyObject * +_io_StringIO_write_impl(stringio *self, PyObject *obj); + +static PyObject * +_io_StringIO_write(stringio *self, PyObject *obj) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_write_impl(self, obj); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_io_StringIO_close__doc__, "close($self, /)\n" "--\n" @@ -241,7 +278,13 @@ _io_StringIO_close_impl(stringio *self); static PyObject * _io_StringIO_close(stringio *self, PyObject *Py_UNUSED(ignored)) { - return _io_StringIO_close_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_close_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_StringIO___init____doc__, @@ -329,7 +372,13 @@ _io_StringIO_readable_impl(stringio *self); static PyObject * _io_StringIO_readable(stringio *self, PyObject *Py_UNUSED(ignored)) { - return _io_StringIO_readable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_readable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_StringIO_writable__doc__, @@ -347,7 +396,13 @@ _io_StringIO_writable_impl(stringio *self); static PyObject * _io_StringIO_writable(stringio *self, PyObject *Py_UNUSED(ignored)) { - return _io_StringIO_writable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_writable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_StringIO_seekable__doc__, @@ -365,6 +420,124 @@ _io_StringIO_seekable_impl(stringio *self); static PyObject * _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { - return _io_StringIO_seekable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_seekable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_io_StringIO___getstate____doc__, +"__getstate__($self, /)\n" +"--\n" +"\n"); + +#define _IO_STRINGIO___GETSTATE___METHODDEF \ + {"__getstate__", (PyCFunction)_io_StringIO___getstate__, METH_NOARGS, _io_StringIO___getstate____doc__}, + +static PyObject * +_io_StringIO___getstate___impl(stringio *self); + +static PyObject * +_io_StringIO___getstate__(stringio *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO___getstate___impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_io_StringIO___setstate____doc__, +"__setstate__($self, state, /)\n" +"--\n" +"\n"); + +#define _IO_STRINGIO___SETSTATE___METHODDEF \ + {"__setstate__", (PyCFunction)_io_StringIO___setstate__, METH_O, _io_StringIO___setstate____doc__}, + +static PyObject * +_io_StringIO___setstate___impl(stringio *self, PyObject *state); + +static PyObject * +_io_StringIO___setstate__(stringio *self, PyObject *state) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO___setstate___impl(self, state); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO_STRINGIO_CLOSED_GETSETDEF) +# undef _IO_STRINGIO_CLOSED_GETSETDEF +# define _IO_STRINGIO_CLOSED_GETSETDEF {"closed", (getter)_io_StringIO_closed_get, (setter)_io_StringIO_closed_set, NULL}, +#else +# define _IO_STRINGIO_CLOSED_GETSETDEF {"closed", (getter)_io_StringIO_closed_get, NULL, NULL}, +#endif + +static PyObject * +_io_StringIO_closed_get_impl(stringio *self); + +static PyObject * +_io_StringIO_closed_get(stringio *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_closed_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO_STRINGIO_LINE_BUFFERING_GETSETDEF) +# undef _IO_STRINGIO_LINE_BUFFERING_GETSETDEF +# define _IO_STRINGIO_LINE_BUFFERING_GETSETDEF {"line_buffering", (getter)_io_StringIO_line_buffering_get, (setter)_io_StringIO_line_buffering_set, NULL}, +#else +# define _IO_STRINGIO_LINE_BUFFERING_GETSETDEF {"line_buffering", (getter)_io_StringIO_line_buffering_get, NULL, NULL}, +#endif + +static PyObject * +_io_StringIO_line_buffering_get_impl(stringio *self); + +static PyObject * +_io_StringIO_line_buffering_get(stringio *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_line_buffering_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO_STRINGIO_NEWLINES_GETSETDEF) +# undef _IO_STRINGIO_NEWLINES_GETSETDEF +# define _IO_STRINGIO_NEWLINES_GETSETDEF {"newlines", (getter)_io_StringIO_newlines_get, (setter)_io_StringIO_newlines_set, NULL}, +#else +# define _IO_STRINGIO_NEWLINES_GETSETDEF {"newlines", (getter)_io_StringIO_newlines_get, NULL, NULL}, +#endif + +static PyObject * +_io_StringIO_newlines_get_impl(stringio *self); + +static PyObject * +_io_StringIO_newlines_get(stringio *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_StringIO_newlines_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } -/*[clinic end generated code: output=57e86cd679344ee7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=27726751d98ab617 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index bc14327388fb2f..a492f340c74c0d 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -7,6 +7,8 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_io__TextIOBase_detach__doc__, "detach($self, /)\n" @@ -629,7 +631,9 @@ _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t na } write_through_obj = args[4]; skip_optional_kwonly: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper_reconfigure_impl(self, encoding, errors, newline_obj, line_buffering_obj, write_through_obj); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -649,7 +653,13 @@ _io_TextIOWrapper_detach_impl(textio *self); static PyObject * _io_TextIOWrapper_detach(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_detach_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_detach_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_write__doc__, @@ -674,7 +684,9 @@ _io_TextIOWrapper_write(textio *self, PyObject *arg) goto exit; } text = arg; + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper_write_impl(self, text); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -707,7 +719,9 @@ _io_TextIOWrapper_read(textio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper_read_impl(self, n); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -749,7 +763,9 @@ _io_TextIOWrapper_readline(textio *self, PyObject *const *args, Py_ssize_t nargs size = ival; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper_readline_impl(self, size); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -803,7 +819,9 @@ _io_TextIOWrapper_seek(textio *self, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper_seek_impl(self, cookieObj, whence); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -827,7 +845,13 @@ _io_TextIOWrapper_tell_impl(textio *self); static PyObject * _io_TextIOWrapper_tell(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_tell_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_tell_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_truncate__doc__, @@ -855,7 +879,9 @@ _io_TextIOWrapper_truncate(textio *self, PyObject *const *args, Py_ssize_t nargs } pos = args[0]; skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper_truncate_impl(self, pos); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -875,7 +901,13 @@ _io_TextIOWrapper_fileno_impl(textio *self); static PyObject * _io_TextIOWrapper_fileno(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_fileno_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_fileno_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_seekable__doc__, @@ -892,7 +924,13 @@ _io_TextIOWrapper_seekable_impl(textio *self); static PyObject * _io_TextIOWrapper_seekable(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_seekable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_seekable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_readable__doc__, @@ -909,7 +947,13 @@ _io_TextIOWrapper_readable_impl(textio *self); static PyObject * _io_TextIOWrapper_readable(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_readable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_readable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_writable__doc__, @@ -926,7 +970,13 @@ _io_TextIOWrapper_writable_impl(textio *self); static PyObject * _io_TextIOWrapper_writable(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_writable_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_writable_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_isatty__doc__, @@ -943,7 +993,13 @@ _io_TextIOWrapper_isatty_impl(textio *self); static PyObject * _io_TextIOWrapper_isatty(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_isatty_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_isatty_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_flush__doc__, @@ -960,7 +1016,13 @@ _io_TextIOWrapper_flush_impl(textio *self); static PyObject * _io_TextIOWrapper_flush(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_flush_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_flush_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_io_TextIOWrapper_close__doc__, @@ -977,6 +1039,56 @@ _io_TextIOWrapper_close_impl(textio *self); static PyObject * _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { - return _io_TextIOWrapper_close_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper_close_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF) +# undef _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF +# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, NULL}, +#else +# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, NULL, NULL}, +#endif + +static PyObject * +_io_TextIOWrapper__CHUNK_SIZE_get_impl(textio *self); + +static PyObject * +_io_TextIOWrapper__CHUNK_SIZE_get(textio *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper__CHUNK_SIZE_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF) +# undef _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF +# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, NULL}, +#else +# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", NULL, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, NULL}, +#endif + +static int +_io_TextIOWrapper__CHUNK_SIZE_set_impl(textio *self, PyObject *value); + +static int +_io_TextIOWrapper__CHUNK_SIZE_set(textio *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _io_TextIOWrapper__CHUNK_SIZE_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; } -/*[clinic end generated code: output=175e1723a462a722 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b312f2d2e2221580 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index ecc71e552c23f4..6cab295c44611d 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() #if defined(HAVE_WINDOWS_CONSOLE_IO) @@ -246,10 +247,6 @@ _io__WindowsConsoleIO_readinto(winconsoleio *self, PyTypeObject *cls, PyObject * _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument 1", "contiguous buffer", args[0]); - goto exit; - } return_value = _io__WindowsConsoleIO_readinto_impl(self, cls, &buffer); exit: @@ -390,10 +387,6 @@ _io__WindowsConsoleIO_write(winconsoleio *self, PyTypeObject *cls, PyObject *con if (PyObject_GetBuffer(args[0], &b, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", "argument 1", "contiguous buffer", args[0]); - goto exit; - } return_value = _io__WindowsConsoleIO_write_impl(self, cls, &b); exit: @@ -464,4 +457,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=37febc4c96732b3b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=04108fc26b187386 input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index fb416700e22523..8a73ea0365b7a3 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -5,20 +5,23 @@ #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() -#include +#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" /* @@ -35,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" diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 1856b07108bab6..06bc2679e8e227 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -45,6 +45,10 @@ typedef struct { _PyIO_State *module_state; } stringio; +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) +#include "clinic/stringio.c.h" +#undef clinic_state + static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs); #define CHECK_INITIALIZED(self) \ @@ -263,6 +267,7 @@ write_str(stringio *self, PyObject *obj) } /*[clinic input] +@critical_section _io.StringIO.getvalue Retrieve the entire contents of the object. @@ -270,7 +275,7 @@ Retrieve the entire contents of the object. static PyObject * _io_StringIO_getvalue_impl(stringio *self) -/*[clinic end generated code: output=27b6a7bfeaebce01 input=d23cb81d6791cf88]*/ +/*[clinic end generated code: output=27b6a7bfeaebce01 input=fb5dee06b8d467f3]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -281,6 +286,7 @@ _io_StringIO_getvalue_impl(stringio *self) } /*[clinic input] +@critical_section _io.StringIO.tell Tell the current file position. @@ -288,7 +294,7 @@ Tell the current file position. static PyObject * _io_StringIO_tell_impl(stringio *self) -/*[clinic end generated code: output=2e87ac67b116c77b input=ec866ebaff02f405]*/ +/*[clinic end generated code: output=2e87ac67b116c77b input=98a08f3e2dae3550]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -296,6 +302,7 @@ _io_StringIO_tell_impl(stringio *self) } /*[clinic input] +@critical_section _io.StringIO.read size: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -308,7 +315,7 @@ is reached. Return an empty string at EOF. static PyObject * _io_StringIO_read_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=ae8cf6002f71626c input=0921093383dfb92d]*/ +/*[clinic end generated code: output=ae8cf6002f71626c input=9fbef45d8aece8e7]*/ { Py_ssize_t n; Py_UCS4 *output; @@ -368,6 +375,7 @@ _stringio_readline(stringio *self, Py_ssize_t limit) } /*[clinic input] +@critical_section _io.StringIO.readline size: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -379,7 +387,7 @@ Returns an empty string if EOF is hit immediately. static PyObject * _io_StringIO_readline_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=cabd6452f1b7e85d input=a5bd70bf682aa276]*/ +/*[clinic end generated code: output=cabd6452f1b7e85d input=4d14b8495dea1d98]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -427,6 +435,7 @@ stringio_iternext(stringio *self) } /*[clinic input] +@critical_section _io.StringIO.truncate pos as size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None / @@ -440,7 +449,7 @@ Returns the new absolute position. static PyObject * _io_StringIO_truncate_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=eb3aef8e06701365 input=5505cff90ca48b96]*/ +/*[clinic end generated code: output=eb3aef8e06701365 input=461b872dce238452]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -462,6 +471,7 @@ _io_StringIO_truncate_impl(stringio *self, Py_ssize_t size) } /*[clinic input] +@critical_section _io.StringIO.seek pos: Py_ssize_t whence: int = 0 @@ -478,7 +488,7 @@ Returns the new absolute position. static PyObject * _io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence) -/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/ +/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=c75ced09343a00d7]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -515,6 +525,7 @@ _io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence) } /*[clinic input] +@critical_section _io.StringIO.write s as obj: object / @@ -526,8 +537,8 @@ the length of the string. [clinic start generated code]*/ static PyObject * -_io_StringIO_write(stringio *self, PyObject *obj) -/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/ +_io_StringIO_write_impl(stringio *self, PyObject *obj) +/*[clinic end generated code: output=d53b1d841d7db288 input=1561272c0da4651f]*/ { Py_ssize_t size; @@ -547,6 +558,7 @@ _io_StringIO_write(stringio *self, PyObject *obj) } /*[clinic input] +@critical_section _io.StringIO.close Close the IO object. @@ -559,7 +571,7 @@ This method has no effect if the file is already closed. static PyObject * _io_StringIO_close_impl(stringio *self) -/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/ +/*[clinic end generated code: output=04399355cbe518f1 input=305d19aa29cc40b9]*/ { self->closed = 1; /* Free up some memory */ @@ -756,6 +768,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, /* Properties and pseudo-properties */ /*[clinic input] +@critical_section _io.StringIO.readable Returns True if the IO object can be read. @@ -763,7 +776,7 @@ Returns True if the IO object can be read. static PyObject * _io_StringIO_readable_impl(stringio *self) -/*[clinic end generated code: output=b19d44dd8b1ceb99 input=39ce068b224c21ad]*/ +/*[clinic end generated code: output=b19d44dd8b1ceb99 input=6cd2ffd65a8e8763]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -771,6 +784,7 @@ _io_StringIO_readable_impl(stringio *self) } /*[clinic input] +@critical_section _io.StringIO.writable Returns True if the IO object can be written. @@ -778,7 +792,7 @@ Returns True if the IO object can be written. static PyObject * _io_StringIO_writable_impl(stringio *self) -/*[clinic end generated code: output=13e4dd77187074ca input=7a691353aac38835]*/ +/*[clinic end generated code: output=13e4dd77187074ca input=1b3c63dbaa761c69]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -786,6 +800,7 @@ _io_StringIO_writable_impl(stringio *self) } /*[clinic input] +@critical_section _io.StringIO.seekable Returns True if the IO object can be seeked. @@ -793,7 +808,7 @@ Returns True if the IO object can be seeked. static PyObject * _io_StringIO_seekable_impl(stringio *self) -/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/ +/*[clinic end generated code: output=4d20b4641c756879 input=a820fad2cf085fc3]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -812,8 +827,15 @@ _io_StringIO_seekable_impl(stringio *self) supported. */ +/*[clinic input] +@critical_section +_io.StringIO.__getstate__ + +[clinic start generated code]*/ + static PyObject * -stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) +_io_StringIO___getstate___impl(stringio *self) +/*[clinic end generated code: output=780be4a996410199 input=76f27255ef83bb92]*/ { PyObject *initvalue = _io_StringIO_getvalue_impl(self); PyObject *dict; @@ -839,8 +861,17 @@ stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) return state; } +/*[clinic input] +@critical_section +_io.StringIO.__setstate__ + + state: object + / +[clinic start generated code]*/ + static PyObject * -stringio_setstate(stringio *self, PyObject *state) +_io_StringIO___setstate___impl(stringio *self, PyObject *state) +/*[clinic end generated code: output=cb3962bc6d5c5609 input=8a27784b11b82e47]*/ { PyObject *initarg; PyObject *position_obj; @@ -939,36 +970,53 @@ stringio_setstate(stringio *self, PyObject *state) Py_RETURN_NONE; } +/*[clinic input] +@critical_section +@getter +_io.StringIO.closed +[clinic start generated code]*/ static PyObject * -stringio_closed(stringio *self, void *context) +_io_StringIO_closed_get_impl(stringio *self) +/*[clinic end generated code: output=531ddca7954331d6 input=178d2ef24395fd49]*/ { CHECK_INITIALIZED(self); return PyBool_FromLong(self->closed); } +/*[clinic input] +@critical_section +@getter +_io.StringIO.line_buffering +[clinic start generated code]*/ + static PyObject * -stringio_line_buffering(stringio *self, void *context) +_io_StringIO_line_buffering_get_impl(stringio *self) +/*[clinic end generated code: output=360710e0112966ae input=6a7634e7f890745e]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); Py_RETURN_FALSE; } +/*[clinic input] +@critical_section +@getter +_io.StringIO.newlines +[clinic start generated code]*/ + static PyObject * -stringio_newlines(stringio *self, void *context) +_io_StringIO_newlines_get_impl(stringio *self) +/*[clinic end generated code: output=35d7c0b66d7e0160 input=092a14586718244b]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); - if (self->decoder == NULL) + if (self->decoder == NULL) { Py_RETURN_NONE; + } return PyObject_GetAttr(self->decoder, &_Py_ID(newlines)); } -#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) -#include "clinic/stringio.c.h" -#undef clinic_state - static struct PyMethodDef stringio_methods[] = { _IO_STRINGIO_CLOSE_METHODDEF _IO_STRINGIO_GETVALUE_METHODDEF @@ -983,21 +1031,21 @@ static struct PyMethodDef stringio_methods[] = { _IO_STRINGIO_READABLE_METHODDEF _IO_STRINGIO_WRITABLE_METHODDEF - {"__getstate__", (PyCFunction)stringio_getstate, METH_NOARGS}, - {"__setstate__", (PyCFunction)stringio_setstate, METH_O}, + _IO_STRINGIO___GETSTATE___METHODDEF + _IO_STRINGIO___SETSTATE___METHODDEF {NULL, NULL} /* sentinel */ }; static PyGetSetDef stringio_getset[] = { - {"closed", (getter)stringio_closed, NULL, NULL}, - {"newlines", (getter)stringio_newlines, NULL, NULL}, + _IO_STRINGIO_CLOSED_GETSETDEF + _IO_STRINGIO_NEWLINES_GETSETDEF /* (following comments straight off of the original Python wrapper:) XXX Cruft to support the TextIOWrapper API. This would only be meaningful if StringIO supported the buffer attribute. Hopefully, a better solution, than adding these pseudo-attributes, will be found. */ - {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, + _IO_STRINGIO_LINE_BUFFERING_GETSETDEF {NULL} }; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 10ef8a803c50fd..c76d92cdd38b9a 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -7,14 +7,14 @@ */ #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_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() -#include "pycore_pystate.h" // _PyInterpreterState_GET() +#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_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() +#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "_iomodule.h" @@ -1020,15 +1020,10 @@ io_check_errors(PyObject *errors) return 0; } - Py_ssize_t name_length; - const char *name = PyUnicode_AsUTF8AndSize(errors, &name_length); + const char *name = _PyUnicode_AsUTF8NoNUL(errors); if (name == NULL) { return -1; } - if (strlen(name) != (size_t)name_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character in errors"); - return -1; - } PyObject *handler = PyCodec_LookupError(name); if (handler != NULL) { Py_DECREF(handler); @@ -1117,6 +1112,10 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, else if (io_check_errors(errors)) { return -1; } + const char *errors_str = _PyUnicode_AsUTF8NoNUL(errors); + if (errors_str == NULL) { + return -1; + } if (validate_newline(newline) < 0) { return -1; @@ -1189,11 +1188,11 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, /* Build the decoder object */ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); self->state = state; - if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) + if (_textiowrapper_set_decoder(self, codec_info, errors_str) != 0) goto error; /* Build the encoder object */ - if (_textiowrapper_set_encoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) + if (_textiowrapper_set_encoder(self, codec_info, errors_str) != 0) goto error; /* Finished sorting out the codec details */ @@ -1289,35 +1288,46 @@ textiowrapper_change_encoding(textio *self, PyObject *encoding, errors = &_Py_ID(strict); } } + Py_INCREF(errors); + const char *c_encoding = PyUnicode_AsUTF8(encoding); + if (c_encoding == NULL) { + Py_DECREF(encoding); + Py_DECREF(errors); + return -1; + } const char *c_errors = PyUnicode_AsUTF8(errors); if (c_errors == NULL) { Py_DECREF(encoding); + Py_DECREF(errors); return -1; } // Create new encoder & decoder PyObject *codec_info = _PyCodec_LookupTextEncoding( - PyUnicode_AsUTF8(encoding), "codecs.open()"); + c_encoding, "codecs.open()"); if (codec_info == NULL) { Py_DECREF(encoding); + Py_DECREF(errors); return -1; } if (_textiowrapper_set_decoder(self, codec_info, c_errors) != 0 || _textiowrapper_set_encoder(self, codec_info, c_errors) != 0) { Py_DECREF(codec_info); Py_DECREF(encoding); + Py_DECREF(errors); return -1; } Py_DECREF(codec_info); Py_SETREF(self->encoding, encoding); - Py_SETREF(self->errors, Py_NewRef(errors)); + Py_SETREF(self->errors, errors); return _textiowrapper_fix_encoder_state(self); } /*[clinic input] +@critical_section _io.TextIOWrapper.reconfigure * encoding: object = None @@ -1337,12 +1347,32 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, PyObject *errors, PyObject *newline_obj, PyObject *line_buffering_obj, PyObject *write_through_obj) -/*[clinic end generated code: output=52b812ff4b3d4b0f input=671e82136e0f5822]*/ +/*[clinic end generated code: output=52b812ff4b3d4b0f input=dc3bd35ebda702a7]*/ { int line_buffering; int write_through; const char *newline = NULL; + if (encoding != Py_None && !PyUnicode_Check(encoding)) { + PyErr_Format(PyExc_TypeError, + "reconfigure() argument 'encoding' must be str or None, not %s", + Py_TYPE(encoding)->tp_name); + return NULL; + } + if (errors != Py_None && !PyUnicode_Check(errors)) { + PyErr_Format(PyExc_TypeError, + "reconfigure() argument 'errors' must be str or None, not %s", + Py_TYPE(errors)->tp_name); + return NULL; + } + if (newline_obj != NULL && newline_obj != Py_None && + !PyUnicode_Check(newline_obj)) + { + PyErr_Format(PyExc_TypeError, + "reconfigure() argument 'newline' must be str or None, not %s", + Py_TYPE(newline_obj)->tp_name); + return NULL; + } /* Check if something is in the read buffer */ if (self->decoded_chars != NULL) { if (encoding != Py_None || errors != Py_None || newline_obj != NULL) { @@ -1362,9 +1392,12 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, line_buffering = convert_optional_bool(line_buffering_obj, self->line_buffering); + if (line_buffering < 0) { + return NULL; + } write_through = convert_optional_bool(write_through_obj, self->write_through); - if (line_buffering < 0 || write_through < 0) { + if (write_through < 0) { return NULL; } @@ -1499,12 +1532,13 @@ textiowrapper_closed_get(textio *self, void *context); /*[clinic input] +@critical_section _io.TextIOWrapper.detach [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_detach_impl(textio *self) -/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/ +/*[clinic end generated code: output=7ba3715cd032d5f2 input=c908a3b4ef203b0f]*/ { PyObject *buffer; CHECK_ATTACHED(self); @@ -1590,6 +1624,7 @@ _textiowrapper_writeflush(textio *self) } /*[clinic input] +@critical_section _io.TextIOWrapper.write text: unicode / @@ -1597,7 +1632,7 @@ _io.TextIOWrapper.write static PyObject * _io_TextIOWrapper_write_impl(textio *self, PyObject *text) -/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/ +/*[clinic end generated code: output=d2deb0d50771fcec input=73ec95c5c4a3489c]*/ { PyObject *ret; PyObject *b; @@ -1901,6 +1936,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) } /*[clinic input] +@critical_section _io.TextIOWrapper.read size as n: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -1908,7 +1944,7 @@ _io.TextIOWrapper.read static PyObject * _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) -/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/ +/*[clinic end generated code: output=7e651ce6cc6a25a6 input=67d14c5661121377]*/ { PyObject *result = NULL, *chunks = NULL; @@ -2276,6 +2312,7 @@ _textiowrapper_readline(textio *self, Py_ssize_t limit) } /*[clinic input] +@critical_section _io.TextIOWrapper.readline size: Py_ssize_t = -1 / @@ -2283,7 +2320,7 @@ _io.TextIOWrapper.readline static PyObject * _io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size) -/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/ +/*[clinic end generated code: output=344afa98804e8b25 input=b65bab871dc3ddba]*/ { CHECK_ATTACHED(self); return _textiowrapper_readline(self, size); @@ -2422,6 +2459,7 @@ _textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) } /*[clinic input] +@critical_section _io.TextIOWrapper.seek cookie as cookieObj: object Zero or an opaque number returned by tell(). @@ -2446,7 +2484,7 @@ and may raise exceptions. static PyObject * _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) -/*[clinic end generated code: output=0a15679764e2d04d input=0f68adcb02cf2823]*/ +/*[clinic end generated code: output=0a15679764e2d04d input=4bea78698be23d7e]*/ { PyObject *posobj; cookie_type cookie; @@ -2633,6 +2671,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) } /*[clinic input] +@critical_section _io.TextIOWrapper.tell Return the stream position as an opaque number. @@ -2643,7 +2682,7 @@ previous stream position. static PyObject * _io_TextIOWrapper_tell_impl(textio *self) -/*[clinic end generated code: output=4f168c08bf34ad5f input=0852d627d76fb520]*/ +/*[clinic end generated code: output=4f168c08bf34ad5f input=415d6b4e4f8e6e8c]*/ { PyObject *res; PyObject *posobj = NULL; @@ -2869,6 +2908,7 @@ _io_TextIOWrapper_tell_impl(textio *self) } /*[clinic input] +@critical_section _io.TextIOWrapper.truncate pos: object = None / @@ -2876,7 +2916,7 @@ _io.TextIOWrapper.truncate static PyObject * _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) -/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/ +/*[clinic end generated code: output=90ec2afb9bb7745f input=8bddb320834c93ee]*/ { CHECK_ATTACHED(self) @@ -2956,72 +2996,78 @@ textiowrapper_repr(textio *self) /* Inquiries */ /*[clinic input] +@critical_section _io.TextIOWrapper.fileno [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_fileno_impl(textio *self) -/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/ +/*[clinic end generated code: output=21490a4c3da13e6c input=515e1196aceb97ab]*/ { CHECK_ATTACHED(self); return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(fileno)); } /*[clinic input] +@critical_section _io.TextIOWrapper.seekable [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_seekable_impl(textio *self) -/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/ +/*[clinic end generated code: output=ab223dbbcffc0f00 input=71c4c092736c549b]*/ { CHECK_ATTACHED(self); return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(seekable)); } /*[clinic input] +@critical_section _io.TextIOWrapper.readable [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_readable_impl(textio *self) -/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/ +/*[clinic end generated code: output=72ff7ba289a8a91b input=80438d1f01b0a89b]*/ { CHECK_ATTACHED(self); return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(readable)); } /*[clinic input] +@critical_section _io.TextIOWrapper.writable [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_writable_impl(textio *self) -/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/ +/*[clinic end generated code: output=a728c71790d03200 input=9d6c22befb0c340a]*/ { CHECK_ATTACHED(self); return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(writable)); } /*[clinic input] +@critical_section _io.TextIOWrapper.isatty [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_isatty_impl(textio *self) -/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/ +/*[clinic end generated code: output=12be1a35bace882e input=7f83ff04d4d1733d]*/ { CHECK_ATTACHED(self); return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(isatty)); } /*[clinic input] +@critical_section _io.TextIOWrapper.flush [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_flush_impl(textio *self) -/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/ +/*[clinic end generated code: output=59de9165f9c2e4d2 input=3ac3bf521bfed59d]*/ { CHECK_ATTACHED(self); CHECK_CLOSED(self); @@ -3032,12 +3078,13 @@ _io_TextIOWrapper_flush_impl(textio *self) } /*[clinic input] +@critical_section _io.TextIOWrapper.close [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_close_impl(textio *self) -/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/ +/*[clinic end generated code: output=056ccf8b4876e4f4 input=8e12d7079d5ac5c1]*/ { PyObject *res; int r; @@ -3118,21 +3165,41 @@ textiowrapper_iternext(textio *self) } static PyObject * -textiowrapper_name_get(textio *self, void *context) +textiowrapper_name_get_impl(textio *self, void *context) { CHECK_ATTACHED(self); return PyObject_GetAttr(self->buffer, &_Py_ID(name)); } static PyObject * -textiowrapper_closed_get(textio *self, void *context) +textiowrapper_name_get(textio *self, void *context) +{ + PyObject *result = NULL; + Py_BEGIN_CRITICAL_SECTION(self); + result = textiowrapper_name_get_impl(self, context); + Py_END_CRITICAL_SECTION(); + return result; +} + +static PyObject * +textiowrapper_closed_get_impl(textio *self, void *context) { CHECK_ATTACHED(self); return PyObject_GetAttr(self->buffer, &_Py_ID(closed)); } static PyObject * -textiowrapper_newlines_get(textio *self, void *context) +textiowrapper_closed_get(textio *self, void *context) +{ + PyObject *result = NULL; + Py_BEGIN_CRITICAL_SECTION(self); + result = textiowrapper_closed_get_impl(self, context); + Py_END_CRITICAL_SECTION(); + return result; +} + +static PyObject * +textiowrapper_newlines_get_impl(textio *self, void *context) { PyObject *res; CHECK_ATTACHED(self); @@ -3145,29 +3212,63 @@ textiowrapper_newlines_get(textio *self, void *context) } static PyObject * -textiowrapper_errors_get(textio *self, void *context) +textiowrapper_newlines_get(textio *self, void *context) +{ + PyObject *result = NULL; + Py_BEGIN_CRITICAL_SECTION(self); + result = textiowrapper_newlines_get_impl(self, context); + Py_END_CRITICAL_SECTION(); + return result; +} + +static PyObject * +textiowrapper_errors_get_impl(textio *self, void *context) { CHECK_INITIALIZED(self); return Py_NewRef(self->errors); } static PyObject * -textiowrapper_chunk_size_get(textio *self, void *context) +textiowrapper_errors_get(textio *self, void *context) +{ + PyObject *result = NULL; + Py_BEGIN_CRITICAL_SECTION(self); + result = textiowrapper_errors_get_impl(self, context); + Py_END_CRITICAL_SECTION(); + return result; +} + +/*[clinic input] +@critical_section +@getter +_io.TextIOWrapper._CHUNK_SIZE +[clinic start generated code]*/ + +static PyObject * +_io_TextIOWrapper__CHUNK_SIZE_get_impl(textio *self) +/*[clinic end generated code: output=039925cd2df375bc input=e9715b0e06ff0fa6]*/ { CHECK_ATTACHED(self); return PyLong_FromSsize_t(self->chunk_size); } +/*[clinic input] +@critical_section +@setter +_io.TextIOWrapper._CHUNK_SIZE +[clinic start generated code]*/ + static int -textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) +_io_TextIOWrapper__CHUNK_SIZE_set_impl(textio *self, PyObject *value) +/*[clinic end generated code: output=edb86d2db660a5ab input=32fc99861db02a0a]*/ { Py_ssize_t n; CHECK_ATTACHED_INT(self); - if (arg == NULL) { + if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); return -1; } - n = PyNumber_AsSsize_t(arg, PyExc_ValueError); + n = PyNumber_AsSsize_t(value, PyExc_ValueError); if (n == -1 && PyErr_Occurred()) return -1; if (n <= 0) { @@ -3254,8 +3355,7 @@ static PyGetSetDef textiowrapper_getset[] = { */ {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL}, {"errors", (getter)textiowrapper_errors_get, NULL, NULL}, - {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get, - (setter)textiowrapper_chunk_size_set, NULL}, + _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {NULL} }; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 50b8818aad410b..6680488b740cfc 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -134,6 +134,23 @@ char _PyIO_get_console_type(PyObject *path_or_fd) { return m; } +static DWORD +_find_last_utf8_boundary(const char *buf, DWORD len) +{ + /* This function never returns 0, returns the original len instead */ + DWORD count = 1; + if (len == 0 || (buf[len - 1] & 0x80) == 0) { + return len; + } + for (;; count++) { + if (count > 3 || count >= len) { + return len; + } + if ((buf[len - count] & 0xc0) != 0x80) { + return len - count; + } + } +} /*[clinic input] module _io @@ -975,7 +992,7 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, PyTypeObject *cls, { BOOL res = TRUE; wchar_t *wbuf; - DWORD len, wlen, orig_len, n = 0; + DWORD len, wlen, n = 0; HANDLE handle; if (self->fd == -1) @@ -1007,21 +1024,8 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, PyTypeObject *cls, have to reduce and recalculate. */ while (wlen > 32766 / sizeof(wchar_t)) { len /= 2; - orig_len = len; - /* Reduce the length until we hit the final byte of a UTF-8 sequence - * (top bit is unset). Fix for github issue 82052. - */ - while (len > 0 && (((char *)b->buf)[len-1] & 0x80) != 0) - --len; - /* If we hit a length of 0, something has gone wrong. This shouldn't - * be possible, as valid UTF-8 can have at most 3 non-final bytes - * before a final one, and our buffer is way longer than that. - * But to be on the safe side, if we hit this issue we just restore - * the original length and let the console API sort it out. - */ - if (len == 0) { - len = orig_len; - } + /* Fix for github issues gh-110913 and gh-82052. */ + len = _find_last_utf8_boundary(b->buf, len); wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); } Py_END_ALLOW_THREADS diff --git a/Modules/_json.c b/Modules/_json.c index 41495e2012f152..0b1bfe34ad9304 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -24,7 +24,6 @@ typedef struct _PyScannerObject { PyObject *parse_float; PyObject *parse_int; PyObject *parse_constant; - PyObject *memo; } PyScannerObject; static PyMemberDef scanner_members[] = { @@ -70,7 +69,7 @@ ascii_escape_unicode(PyObject *pystr); static PyObject * py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr); static PyObject * -scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); +scan_once_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); static PyObject * _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); static PyObject * @@ -631,7 +630,6 @@ scanner_traverse(PyScannerObject *self, visitproc visit, void *arg) Py_VISIT(self->parse_float); Py_VISIT(self->parse_int); Py_VISIT(self->parse_constant); - Py_VISIT(self->memo); return 0; } @@ -643,12 +641,11 @@ scanner_clear(PyScannerObject *self) Py_CLEAR(self->parse_float); Py_CLEAR(self->parse_int); Py_CLEAR(self->parse_constant); - Py_CLEAR(self->memo); return 0; } static PyObject * -_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +_parse_object_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { /* Read a JSON object from PyUnicode pystr. idx is the index of the first character after the opening curly brace. @@ -693,7 +690,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx); if (key == NULL) goto bail; - memokey = PyDict_SetDefault(s->memo, key, key); + memokey = PyDict_SetDefault(memo, key, key); if (memokey == NULL) { goto bail; } @@ -710,7 +707,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++; /* read any JSON term */ - val = scan_once_unicode(s, pystr, idx, &next_idx); + val = scan_once_unicode(s, memo, pystr, idx, &next_idx); if (val == NULL) goto bail; @@ -774,7 +771,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss } static PyObject * -_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { +_parse_array_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { /* Read a JSON array from PyUnicode pystr. idx is the index of the first character after the opening brace. *next_idx_ptr is a return-by-reference index to the first character after @@ -805,7 +802,7 @@ _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssi while (1) { /* read any JSON term */ - val = scan_once_unicode(s, pystr, idx, &next_idx); + val = scan_once_unicode(s, memo, pystr, idx, &next_idx); if (val == NULL) goto bail; @@ -986,7 +983,7 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ } static PyObject * -scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +scan_once_unicode(PyScannerObject *s, PyObject *memo, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { /* Read one JSON term (of any kind) from PyUnicode pystr. idx is the index of the first character of the term @@ -1022,7 +1019,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ if (_Py_EnterRecursiveCall(" while decoding a JSON object " "from a unicode string")) return NULL; - res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); + res = _parse_object_unicode(s, memo, pystr, idx + 1, next_idx_ptr); _Py_LeaveRecursiveCall(); return res; case '[': @@ -1030,7 +1027,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ if (_Py_EnterRecursiveCall(" while decoding a JSON array " "from a unicode string")) return NULL; - res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); + res = _parse_array_unicode(s, memo, pystr, idx + 1, next_idx_ptr); _Py_LeaveRecursiveCall(); return res; case 'n': @@ -1106,16 +1103,19 @@ scanner_call(PyScannerObject *self, PyObject *args, PyObject *kwds) if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx)) return NULL; - if (PyUnicode_Check(pystr)) { - rval = scan_once_unicode(self, pystr, idx, &next_idx); - } - else { + if (!PyUnicode_Check(pystr)) { PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); return NULL; } - PyDict_Clear(self->memo); + + PyObject *memo = PyDict_New(); + if (memo == NULL) { + return NULL; + } + rval = scan_once_unicode(self, memo, pystr, idx, &next_idx); + Py_DECREF(memo); if (rval == NULL) return NULL; return _build_rval_index_tuple(rval, next_idx); @@ -1137,10 +1137,6 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - s->memo = PyDict_New(); - if (s->memo == NULL) - goto bail; - /* All of these will fail "gracefully" so we don't need to verify them */ strict = PyObject_GetAttrString(ctx, "strict"); if (strict == NULL) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index d23a756ace887d..8f09204097529f 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -5,7 +5,6 @@ #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" @@ -847,7 +846,7 @@ profiler_dealloc(ProfilerObject *op) if (op->flags & POF_ENABLED) { PyThreadState *tstate = _PyThreadState_GET(); if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { - _PyErr_WriteUnraisableMsg("When destroying _lsprof profiler", NULL); + PyErr_FormatUnraisable("Exception ignored when destroying _lsprof profiler"); } } diff --git a/Modules/_multiprocessing/clinic/multiprocessing.c.h b/Modules/_multiprocessing/clinic/multiprocessing.c.h index 0ae0039a666061..6d4f5c2afcfd39 100644 --- a/Modules/_multiprocessing/clinic/multiprocessing.c.h +++ b/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + #if defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_closesocket__doc__, @@ -102,10 +104,6 @@ _multiprocessing_send(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[1], &buf, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buf, 'C')) { - _PyArg_BadArgument("send", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = _multiprocessing_send_impl(module, handle, &buf); exit: @@ -166,4 +164,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=8b91c020d4353cc5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=73b4cb8428d816da input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index 09dfa11da23b86..1b894ea4c67adc 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -2,11 +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_SHM_OPEN) PyDoc_STRVAR(_posixshmem_shm_open__doc__, @@ -16,69 +11,25 @@ PyDoc_STRVAR(_posixshmem_shm_open__doc__, "Open a shared memory object. Returns a file descriptor (integer)."); #define _POSIXSHMEM_SHM_OPEN_METHODDEF \ - {"shm_open", _PyCFunction_CAST(_posixshmem_shm_open), METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_open__doc__}, + {"shm_open", (PyCFunction)(void(*)(void))_posixshmem_shm_open, METH_VARARGS|METH_KEYWORDS, _posixshmem_shm_open__doc__}, static int _posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, int mode); static PyObject * -_posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_posixshmem_shm_open(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 3 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"path", "flags", "mode", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "shm_open", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[3]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + static char *_keywords[] = {"path", "flags", "mode", NULL}; PyObject *path; int flags; int mode = 511; int _return_value; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); - if (!args) { - goto exit; - } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("shm_open", "argument 'path'", "str", args[0]); - goto exit; - } - path = args[0]; - flags = PyLong_AsInt(args[1]); - if (flags == -1 && PyErr_Occurred()) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - mode = PyLong_AsInt(args[2]); - if (mode == -1 && PyErr_Occurred()) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ui|i:shm_open", _keywords, + &path, &flags, &mode)) goto exit; - } -skip_optional_pos: _return_value = _posixshmem_shm_open_impl(module, path, flags, mode); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; @@ -104,52 +55,21 @@ PyDoc_STRVAR(_posixshmem_shm_unlink__doc__, "region."); #define _POSIXSHMEM_SHM_UNLINK_METHODDEF \ - {"shm_unlink", _PyCFunction_CAST(_posixshmem_shm_unlink), METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_unlink__doc__}, + {"shm_unlink", (PyCFunction)(void(*)(void))_posixshmem_shm_unlink, METH_VARARGS|METH_KEYWORDS, _posixshmem_shm_unlink__doc__}, static PyObject * _posixshmem_shm_unlink_impl(PyObject *module, PyObject *path); static PyObject * -_posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_posixshmem_shm_unlink(PyObject *module, 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(path), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "shm_unlink", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; + static char *_keywords[] = {"path", NULL}; PyObject *path; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U:shm_unlink", _keywords, + &path)) goto exit; - } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("shm_unlink", "argument 'path'", "str", args[0]); - goto exit; - } - path = args[0]; return_value = _posixshmem_shm_unlink_impl(module, path); exit: @@ -165,4 +85,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=2f356903a281d857 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=be0661dbed83ea23 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h index a4357376ee1292..7c855113113c20 100644 --- a/Modules/_multiprocessing/clinic/semaphore.c.h +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() #if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) @@ -541,4 +542,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=e8ea65f8cba8e173 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d57992037e6770b6 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/posixshmem.c b/Modules/_multiprocessing/posixshmem.c index debef3267f77d1..425ce10075c156 100644 --- a/Modules/_multiprocessing/posixshmem.c +++ b/Modules/_multiprocessing/posixshmem.c @@ -2,13 +2,21 @@ posixshmem - A Python extension that provides shm_open() and shm_unlink() */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 +#endif + #include -// for shm_open() and shm_unlink() +#include // EINTR #ifdef HAVE_SYS_MMAN_H -#include +# include // shm_open(), shm_unlink() #endif + /*[clinic input] module _posixshmem [clinic start generated code]*/ @@ -40,7 +48,7 @@ _posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, { int fd; int async_err = 0; - const char *name = PyUnicode_AsUTF8(path); + const char *name = PyUnicode_AsUTF8AndSize(path, NULL); if (name == NULL) { return -1; } @@ -79,7 +87,7 @@ _posixshmem_shm_unlink_impl(PyObject *module, PyObject *path) { int rv; int async_err = 0; - const char *name = PyUnicode_AsUTF8(path); + const char *name = PyUnicode_AsUTF8AndSize(path, NULL); if (name == NULL) { return NULL; } diff --git a/Modules/_opcode.c b/Modules/_opcode.c index dac9c019b249e9..93c71377f03a76 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -6,6 +6,7 @@ #include "compile.h" #include "opcode.h" #include "internal/pycore_code.h" +#include "internal/pycore_compile.h" #include "internal/pycore_intrinsics.h" /*[clinic input] @@ -78,7 +79,7 @@ static int _opcode_is_valid_impl(PyObject *module, int opcode) /*[clinic end generated code: output=b0d918ea1d073f65 input=fe23e0aa194ddae0]*/ { - return PyUnstable_OpcodeIsValid(opcode); + return _PyCompile_OpcodeIsValid(opcode); } /*[clinic input] @@ -94,8 +95,8 @@ static int _opcode_has_arg_impl(PyObject *module, int opcode) /*[clinic end generated code: output=7a062d3b2dcc0815 input=93d878ba6361db5f]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasArg(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasArg(opcode); } /*[clinic input] @@ -111,8 +112,8 @@ static int _opcode_has_const_impl(PyObject *module, int opcode) /*[clinic end generated code: output=c646d5027c634120 input=a6999e4cf13f9410]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasConst(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasConst(opcode); } /*[clinic input] @@ -128,8 +129,8 @@ static int _opcode_has_name_impl(PyObject *module, int opcode) /*[clinic end generated code: output=b49a83555c2fa517 input=448aa5e4bcc947ba]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasName(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasName(opcode); } /*[clinic input] @@ -145,8 +146,8 @@ static int _opcode_has_jump_impl(PyObject *module, int opcode) /*[clinic end generated code: output=e9c583c669f1c46a input=35f711274357a0c3]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasJump(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasJump(opcode); } @@ -168,8 +169,8 @@ static int _opcode_has_free_impl(PyObject *module, int opcode) /*[clinic end generated code: output=d81ae4d79af0ee26 input=117dcd5c19c1139b]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasFree(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasFree(opcode); } @@ -186,8 +187,8 @@ static int _opcode_has_local_impl(PyObject *module, int opcode) /*[clinic end generated code: output=da5a8616b7a5097b input=9a798ee24aaef49d]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasLocal(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasLocal(opcode); } /*[clinic input] @@ -203,8 +204,8 @@ static int _opcode_has_exc_impl(PyObject *module, int opcode) /*[clinic end generated code: output=41b68dff0ec82a52 input=db0e4bdb9bf13fa5]*/ { - return PyUnstable_OpcodeIsValid(opcode) && - PyUnstable_OpcodeHasExc(opcode); + return _PyCompile_OpcodeIsValid(opcode) && + _PyCompile_OpcodeHasExc(opcode); } /*[clinic input] @@ -244,8 +245,7 @@ _opcode_get_nb_ops_impl(PyObject *module) } #define ADD_NB_OP(NUM, STR) \ do { \ - PyObject *pair = Py_BuildValue( \ - "NN", PyUnicode_FromString(#NUM), PyUnicode_FromString(STR)); \ + PyObject *pair = Py_BuildValue("ss", #NUM, STR); \ if (pair == NULL) { \ Py_DECREF(list); \ return NULL; \ @@ -310,7 +310,7 @@ _opcode_get_intrinsic1_descs_impl(PyObject *module) return NULL; } for (int i=0; i <= MAX_INTRINSIC_1; i++) { - PyObject *name = PyUnstable_GetUnaryIntrinsicName(i); + PyObject *name = _PyCompile_GetUnaryIntrinsicName(i); if (name == NULL) { Py_DECREF(list); return NULL; @@ -337,7 +337,7 @@ _opcode_get_intrinsic2_descs_impl(PyObject *module) return NULL; } for (int i=0; i <= MAX_INTRINSIC_2; i++) { - PyObject *name = PyUnstable_GetBinaryIntrinsicName(i); + PyObject *name = _PyCompile_GetBinaryIntrinsicName(i); if (name == NULL) { Py_DECREF(list); return NULL; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index a3cf34699ba509..227e5378e42285 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4707,6 +4707,14 @@ Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) Py_VISIT(self->fast_memo); Py_VISIT(self->reducer_override); Py_VISIT(self->buffer_callback); + PyMemoTable *memo = self->memo; + if (memo && memo->mt_table) { + Py_ssize_t i = memo->mt_allocated; + while (--i >= 0) { + Py_VISIT(memo->mt_table[i].me_key); + } + } + return 0; } @@ -7175,6 +7183,13 @@ Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) Py_VISIT(self->stack); Py_VISIT(self->pers_func); Py_VISIT(self->buffers); + PyObject **memo = self->memo; + if (memo) { + Py_ssize_t i = self->memo_size; + while (--i >= 0) { + Py_VISIT(memo[i]); + } + } return 0; } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 2898eedc3e3a8f..d0dd8f064e0395 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -767,8 +767,10 @@ child_exec(char *const exec_array[], #endif #ifdef HAVE_SETGROUPS - if (extra_group_size > 0) + if (extra_group_size >= 0) { + assert((extra_group_size == 0) == (extra_groups == NULL)); POSIX_CALL(setgroups(extra_group_size, extra_groups)); + } #endif /* HAVE_SETGROUPS */ #ifdef HAVE_SETREGID @@ -1022,7 +1024,6 @@ subprocess_fork_exec_impl(PyObject *module, PyObject *process_args, pid_t pid = -1; int need_to_reenable_gc = 0; char *const *argv = NULL, *const *envp = NULL; - Py_ssize_t extra_group_size = 0; int need_after_fork = 0; int saved_errno = 0; int *c_fds_to_keep = NULL; @@ -1103,6 +1104,13 @@ subprocess_fork_exec_impl(PyObject *module, PyObject *process_args, cwd = PyBytes_AsString(cwd_obj2); } + // Special initial value meaning that subprocess API was called with + // extra_groups=None leading to _posixsubprocess.fork_exec(gids=None). + // We use this to differentiate between code desiring a setgroups(0, NULL) + // call vs no call at all. The fast vfork() code path could be used when + // there is no setgroups call. + Py_ssize_t extra_group_size = -2; + if (extra_groups_packed != Py_None) { #ifdef HAVE_SETGROUPS if (!PyList_Check(extra_groups_packed)) { diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index b4bafb375c999d..81a06cdb79a4f2 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -214,6 +214,8 @@ _queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls, PY_TIMEOUT_T microseconds; PyThreadState *tstate = PyThreadState_Get(); + // XXX Use PyThread_ParseTimeoutArg(). + if (block == 0) { /* Non-blocking */ microseconds = 0; diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 18811d03adb451..4403e1d132c057 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -71,15 +71,19 @@ #endif #include "Python.h" -#include "pycore_long.h" // _PyLong_AsByteArray() +#include "pycore_long.h" // _PyLong_NumBits() +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pylifecycle.h" // _PyOS_URandomNonblock() + +#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. */ @@ -171,6 +175,7 @@ genrand_uint32(RandomObject *self) */ /*[clinic input] +@critical_section _random.Random.random self: self(type="RandomObject *") @@ -180,7 +185,7 @@ random() -> x in the interval [0, 1). static PyObject * _random_Random_random_impl(RandomObject *self) -/*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ +/*[clinic end generated code: output=117ff99ee53d755c input=26492e52d26e8b7b]*/ { uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6; return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); @@ -364,6 +369,7 @@ random_seed(RandomObject *self, PyObject *arg) } /*[clinic input] +@critical_section _random.Random.seed self: self(type="RandomObject *") @@ -378,7 +384,7 @@ of the current time and the process identifier. static PyObject * _random_Random_seed_impl(RandomObject *self, PyObject *n) -/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/ +/*[clinic end generated code: output=0fad1e16ba883681 input=46d01d2ba938c7b1]*/ { if (random_seed(self, n) < 0) { return NULL; @@ -387,6 +393,7 @@ _random_Random_seed_impl(RandomObject *self, PyObject *n) } /*[clinic input] +@critical_section _random.Random.getstate self: self(type="RandomObject *") @@ -396,7 +403,7 @@ getstate() -> tuple containing the current state. static PyObject * _random_Random_getstate_impl(RandomObject *self) -/*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/ +/*[clinic end generated code: output=bf6cef0c092c7180 input=b6621f31eb639694]*/ { PyObject *state; PyObject *element; @@ -424,6 +431,7 @@ _random_Random_getstate_impl(RandomObject *self) /*[clinic input] +@critical_section _random.Random.setstate self: self(type="RandomObject *") @@ -434,8 +442,8 @@ setstate(state) -> None. Restores generator state. [clinic start generated code]*/ static PyObject * -_random_Random_setstate(RandomObject *self, PyObject *state) -/*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/ +_random_Random_setstate_impl(RandomObject *self, PyObject *state) +/*[clinic end generated code: output=babfc2c2eac6b027 input=358e898ec07469b7]*/ { int i; unsigned long element; @@ -475,7 +483,7 @@ _random_Random_setstate(RandomObject *self, PyObject *state) } /*[clinic input] - +@critical_section _random.Random.getrandbits self: self(type="RandomObject *") @@ -487,7 +495,7 @@ getrandbits(k) -> x. Generates an int with k random bits. static PyObject * _random_Random_getrandbits_impl(RandomObject *self, int k) -/*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/ +/*[clinic end generated code: output=b402f82a2158887f input=87603cd60f79f730]*/ { int i, words; uint32_t r; diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 6cc09088bdc869..fe82e918677f9a 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -2,6 +2,14 @@ * Helper method for urllib to fetch the proxy configuration settings * using the SystemConfiguration framework. */ + +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 +#endif + #include #include @@ -21,8 +29,7 @@ cfstring_to_pystring(CFStringRef ref) s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8); if (s) { - return PyUnicode_DecodeUTF8( - s, strlen(s), NULL); + return PyUnicode_DecodeUTF8(s, strlen(s), NULL); } else { CFIndex len = CFStringGetLength(ref); @@ -43,8 +50,7 @@ cfstring_to_pystring(CFStringRef ref) PyMem_Free(buf); return NULL; } else { - result = PyUnicode_DecodeUTF8( - buf, strlen(buf), NULL); + result = PyUnicode_DecodeUTF8(buf, strlen(buf), NULL); PyMem_Free(buf); } return result; @@ -84,7 +90,7 @@ get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) if (v == NULL) goto error; r = PyDict_SetItemString(result, "exclude_simple", v); - Py_SETREF(v, NULL); + Py_CLEAR(v); if (r == -1) goto error; anArray = CFDictionaryGetValue(proxyDict, @@ -104,13 +110,11 @@ get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) aString = CFArrayGetValueAtIndex(anArray, i); if (aString == NULL) { - PyTuple_SetItem(v, i, Py_None); - Py_INCREF(Py_None); + PyTuple_SetItem(v, i, Py_NewRef(Py_None)); } else { PyObject* t = cfstring_to_pystring(aString); if (!t) { - PyTuple_SetItem(v, i, Py_None); - Py_INCREF(Py_None); + PyTuple_SetItem(v, i, Py_NewRef(Py_None)); } else { PyTuple_SetItem(v, i, t); } @@ -148,15 +152,13 @@ set_proxy(PyObject* proxies, const char* proto, CFDictionaryRef proxyDict, if (h) { if (aNum) { int32_t port = cfnum_to_int32(aNum); - v = PyUnicode_FromFormat("http://%U:%ld", - h, (long)port); + v = PyUnicode_FromFormat("http://%U:%ld", h, (long)port); } else { v = PyUnicode_FromFormat("http://%U", h); } Py_DECREF(h); if (!v) return -1; - r = PyDict_SetItemString(proxies, proto, - v); + r = PyDict_SetItemString(proxies, proto, v); Py_DECREF(v); return r; } diff --git a/Modules/_sqlite/clinic/_sqlite3.connect.c.h b/Modules/_sqlite/clinic/_sqlite3.connect.c.h index eceb5a7bf23673..1bcda7702c2568 100644 --- a/Modules/_sqlite/clinic/_sqlite3.connect.c.h +++ b/Modules/_sqlite/clinic/_sqlite3.connect.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(pysqlite_connect__doc__, "connect($module, /, database, timeout=5.0, detect_types=0,\n" @@ -27,4 +28,4 @@ PyDoc_STRVAR(pysqlite_connect__doc__, #define PYSQLITE_CONNECT_METHODDEF \ {"connect", _PyCFunction_CAST(pysqlite_connect), METH_FASTCALL|METH_KEYWORDS, pysqlite_connect__doc__}, -/*[clinic end generated code: output=03bd99542e3aec9d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=69b9b00da71c3c0a input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h index e7c60264722f7b..b95ba948aaf97f 100644 --- a/Modules/_sqlite/clinic/blob.c.h +++ b/Modules/_sqlite/clinic/blob.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(blob_close__doc__, "close($self, /)\n" "--\n" @@ -86,10 +88,6 @@ blob_write(pysqlite_Blob *self, PyObject *arg) if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); - goto exit; - } return_value = blob_write_impl(self, &data); exit: @@ -213,4 +211,4 @@ blob_exit(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=8bfd79ab12ac5385 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31abd55660e0c5af input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index fcc657799dfaf0..db5eb77891e52e 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static int pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, @@ -1556,10 +1557,6 @@ deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("deserialize", "argument 1", "contiguous buffer", args[0]); - goto exit; - } } if (!noptargs) { goto skip_optional_kwonly; @@ -1821,4 +1818,4 @@ getconfig(pysqlite_Connection *self, PyObject *arg) #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=166bf41ad5ca1655 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=90b5b9c14261b8d7 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 3cb637bde4ff6c..a13e0d0745b58d 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() static int pysqlite_cursor_init_impl(pysqlite_Cursor *self, @@ -312,4 +313,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=0c52a9cf54d00543 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a8ce095c3c80cf65 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index 49ba7a341ed587..529dc4e281e0eb 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" @@ -207,4 +208,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a14893a7c2eead5e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=457ab0fdbb9e1880 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h index cdf850d01e01a3..e8d1dbf2ba8bc9 100644 --- a/Modules/_sqlite/clinic/row.c.h +++ b/Modules/_sqlite/clinic/row.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + static PyObject * pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, PyObject *data); @@ -54,4 +56,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_row_keys_impl(self); } -/*[clinic end generated code: output=972487d535d2e7d5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=788bf817acc02b8e input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 21bdbc12814698..0a6633972cc5ef 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -35,6 +35,7 @@ #include "util.h" #include "pycore_import.h" // _PyImport_GetModuleAttrString() +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing() #include "pycore_weakref.h" // _PyWeakref_IS_DEAD() @@ -75,16 +76,10 @@ isolation_level_converter(PyObject *str_or_none, const char **result) *result = NULL; } else if (PyUnicode_Check(str_or_none)) { - Py_ssize_t sz; - const char *str = PyUnicode_AsUTF8AndSize(str_or_none, &sz); + const char *str = _PyUnicode_AsUTF8NoNUL(str_or_none); if (str == NULL) { return 0; } - if (strlen(str) != (size_t)sz) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return 0; - } - const char *level = get_isolation_level(str); if (level == NULL) { return 0; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 618ce532b2518d..f95df612328e57 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -721,7 +721,6 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, } else if (PyDict_Check(parameters)) { /* parameters passed as dictionary */ for (i = 1; i <= num_params_needed; i++) { - PyObject *binding_name_obj; Py_BEGIN_ALLOW_THREADS binding_name = sqlite3_bind_parameter_name(self->st, i); Py_END_ALLOW_THREADS @@ -733,17 +732,8 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, } binding_name++; /* skip first char (the colon) */ - binding_name_obj = PyUnicode_FromString(binding_name); - if (!binding_name_obj) { - return; - } - if (PyDict_CheckExact(parameters)) { - PyObject *item = PyDict_GetItemWithError(parameters, binding_name_obj); - current_param = Py_XNewRef(item); - } else { - current_param = PyObject_GetItem(parameters, binding_name_obj); - } - Py_DECREF(binding_name_obj); + PyObject *current_param; + (void)PyMapping_GetOptionalItemString(parameters, binding_name, ¤t_param); if (!current_param) { if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { PyErr_Format(state->ProgrammingError, diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 92f0148bd4c217..f77458d94a8573 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -85,17 +85,16 @@ pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, if (!key) { return NULL; } - adapter = PyDict_GetItemWithError(state->psyco_adapters, key); + if (PyDict_GetItemRef(state->psyco_adapters, key, &adapter) < 0) { + Py_DECREF(key); + return NULL; + } Py_DECREF(key); if (adapter) { - Py_INCREF(adapter); adapted = PyObject_CallOneArg(adapter, obj); Py_DECREF(adapter); return adapted; } - if (PyErr_Occurred()) { - return NULL; - } /* try to have the protocol adapt this object */ if (PyObject_GetOptionalAttr(proto, state->str___adapt__, &adapter) < 0) { diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 1a1943285ce008..14555076a7e79a 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -21,6 +21,10 @@ * 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 "row.h" #include "cursor.h" diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index 1b5e1a710af9db..cd3fbbc720bdf1 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_sre_getcodesize__doc__, "getcodesize($module, /)\n" @@ -1460,4 +1461,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const } return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=46d83927cbafa93a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ad513f31b99505fa input=a9049054013a1b77]*/ diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 07da5da13f70d3..d451974b9cf81e 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -107,9 +107,11 @@ static unsigned int sre_toupper(unsigned int ch) { #if VERBOSE == 0 # define INIT_TRACE(state) +# define DO_TRACE 0 # define TRACE(v) #elif VERBOSE == 1 # define INIT_TRACE(state) int _debug = (state)->debug +# define DO_TRACE (_debug) # define TRACE(v) do { \ if (_debug) { \ printf v; \ @@ -117,6 +119,7 @@ static unsigned int sre_toupper(unsigned int ch) { } while (0) #elif VERBOSE == 2 # define INIT_TRACE(state) +# define DO_TRACE 1 # define TRACE(v) printf v #else # error VERBOSE must be 0, 1 or 2 @@ -1508,6 +1511,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, @@ -2067,8 +2073,6 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) GET_SKIP; GET_ARG; /* 0 for lookahead, width for lookbehind */ code--; /* Back up over arg to simplify math below */ - if (arg & 0x80000000) - FAIL; /* Width too large */ /* Stop 1 before the end; we check the SUCCESS below */ if (_validate_inner(code+1, code+skip-2, groups)) FAIL; diff --git a/Modules/_sre/sre_lib.h b/Modules/_sre/sre_lib.h index 3c805aeeca0974..f5497d9ff2b93f 100644 --- a/Modules/_sre/sre_lib.h +++ b/Modules/_sre/sre_lib.h @@ -373,6 +373,19 @@ SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount) state->lastindex = ctx->lastindex; \ } while (0) +#define LAST_PTR_PUSH() \ + do { \ + TRACE(("push last_ptr: %zd", \ + PTR_TO_INDEX(ctx->u.rep->last_ptr))); \ + DATA_PUSH(&ctx->u.rep->last_ptr); \ + } while (0) +#define LAST_PTR_POP() \ + do { \ + DATA_POP(&ctx->u.rep->last_ptr); \ + TRACE(("pop last_ptr: %zd", \ + PTR_TO_INDEX(ctx->u.rep->last_ptr))); \ + } while (0) + #define RETURN_ERROR(i) do { return i; } while(0) #define RETURN_FAILURE do { ret = 0; goto exit; } while(0) #define RETURN_SUCCESS do { ret = 1; goto exit; } while(0) @@ -449,8 +462,27 @@ do { \ #define DATA_LOOKUP_AT(t,p,pos) \ DATA_STACK_LOOKUP_AT(state,t,p,pos) +#define PTR_TO_INDEX(ptr) \ + ((ptr) ? ((char*)(ptr) - (char*)state->beginning) / state->charsize : -1) + +#if VERBOSE +# define MARK_TRACE(label, lastmark) \ + do if (DO_TRACE) { \ + TRACE(("%s %d marks:", (label), (lastmark)+1)); \ + for (int j = 0; j <= (lastmark); j++) { \ + if (j && (j & 1) == 0) { \ + TRACE((" ")); \ + } \ + TRACE((" %zd", PTR_TO_INDEX(state->mark[j]))); \ + } \ + TRACE(("\n")); \ + } while (0) +#else +# define MARK_TRACE(label, lastmark) +#endif #define MARK_PUSH(lastmark) \ do if (lastmark >= 0) { \ + MARK_TRACE("push", (lastmark)); \ size_t _marks_size = (lastmark+1) * sizeof(void*); \ DATA_STACK_PUSH(state, state->mark, _marks_size); \ } while (0) @@ -458,16 +490,19 @@ do { \ do if (lastmark >= 0) { \ size_t _marks_size = (lastmark+1) * sizeof(void*); \ DATA_STACK_POP(state, state->mark, _marks_size, 1); \ + MARK_TRACE("pop", (lastmark)); \ } while (0) #define MARK_POP_KEEP(lastmark) \ do if (lastmark >= 0) { \ size_t _marks_size = (lastmark+1) * sizeof(void*); \ DATA_STACK_POP(state, state->mark, _marks_size, 0); \ + MARK_TRACE("pop keep", (lastmark)); \ } while (0) #define MARK_POP_DISCARD(lastmark) \ do if (lastmark >= 0) { \ size_t _marks_size = (lastmark+1) * sizeof(void*); \ DATA_STACK_POP_DISCARD(state, _marks_size); \ + MARK_TRACE("pop discard", (lastmark)); \ } while (0) #define JUMP_NONE 0 @@ -591,8 +626,8 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) /* optimization info block */ /* <1=skip> <2=flags> <3=min> ... */ if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) { - TRACE(("reject (got %zd chars, need %zd)\n", - end - ptr, (Py_ssize_t) pattern[3])); + TRACE(("reject (got %tu chars, need %zu)\n", + end - ptr, (size_t) pattern[3])); RETURN_FAILURE; } pattern += pattern[1] + 1; @@ -1150,11 +1185,11 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) LASTMARK_SAVE(); MARK_PUSH(ctx->lastmark); /* zero-width match protection */ - DATA_PUSH(&ctx->u.rep->last_ptr); + LAST_PTR_PUSH(); ctx->u.rep->last_ptr = state->ptr; DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2, ctx->u.rep->pattern+3); - DATA_POP(&ctx->u.rep->last_ptr); + LAST_PTR_POP(); if (ret) { MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); @@ -1235,11 +1270,11 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) ctx->u.rep->count = ctx->count; /* zero-width match protection */ - DATA_PUSH(&ctx->u.rep->last_ptr); + LAST_PTR_PUSH(); ctx->u.rep->last_ptr = state->ptr; DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3, ctx->u.rep->pattern+3); - DATA_POP(&ctx->u.rep->last_ptr); + LAST_PTR_POP(); if (ret) { RETURN_ON_ERROR(ret); RETURN_SUCCESS; @@ -1509,7 +1544,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) /* */ TRACE(("|%p|%p|ASSERT %d\n", pattern, ptr, pattern[1])); - if (ptr - (SRE_CHAR *)state->beginning < (Py_ssize_t)pattern[1]) + if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1]) RETURN_FAILURE; state->ptr = ptr - pattern[1]; DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2); @@ -1522,7 +1557,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) /* */ TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern, ptr, pattern[1])); - if (ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)pattern[1]) { + if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) { state->ptr = ptr - pattern[1]; LASTMARK_SAVE(); if (state->repeat) @@ -1658,9 +1693,9 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) flags = pattern[2]; - if (pattern[3] && end - ptr < (Py_ssize_t)pattern[3]) { - TRACE(("reject (got %u chars, need %u)\n", - (unsigned int)(end - ptr), pattern[3])); + if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) { + TRACE(("reject (got %tu chars, need %zu)\n", + end - ptr, (size_t) pattern[3])); return 0; } if (pattern[3] > 1) { diff --git a/Modules/_ssl.c b/Modules/_ssl.c index cecc3785c7661c..90b600f4b776a3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -301,6 +301,10 @@ typedef struct { BIO *keylog_bio; /* Cached module state, also used in SSLSocket and SSLSession code. */ _sslmodulestate *state; +#ifndef OPENSSL_NO_PSK + PyObject *psk_client_callback; + PyObject *psk_server_callback; +#endif } PySSLContext; typedef struct { @@ -3123,6 +3127,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) self->alpn_protocols = NULL; self->set_sni_cb = NULL; self->state = get_ssl_state(module); +#ifndef OPENSSL_NO_PSK + self->psk_client_callback = NULL; + self->psk_server_callback = NULL; +#endif /* Don't check host name by default */ if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { @@ -3235,6 +3243,10 @@ context_clear(PySSLContext *self) Py_CLEAR(self->set_sni_cb); Py_CLEAR(self->msg_cb); Py_CLEAR(self->keylog_filename); +#ifndef OPENSSL_NO_PSK + Py_CLEAR(self->psk_client_callback); + Py_CLEAR(self->psk_server_callback); +#endif if (self->keylog_bio != NULL) { PySSL_BEGIN_ALLOW_THREADS BIO_free_all(self->keylog_bio); @@ -4133,7 +4145,8 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, if (PyObject_GetBuffer(cadata, &buf, PyBUF_SIMPLE)) { goto error; } - if (!PyBuffer_IsContiguous(&buf, 'C') || buf.ndim > 1) { + assert(PyBuffer_IsContiguous(&buf, 'C')); + if (buf.ndim > 1) { PyBuffer_Release(&buf); PyErr_SetString(PyExc_TypeError, "cadata should be a contiguous buffer with " @@ -4661,6 +4674,238 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) return NULL; } +#ifndef OPENSSL_NO_PSK +static unsigned int psk_client_callback(SSL *s, + const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len) +{ + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject *callback = NULL; + + PySSLSocket *ssl = SSL_get_app_data(s); + if (ssl == NULL || ssl->ctx == NULL) { + goto error; + } + callback = ssl->ctx->psk_client_callback; + if (callback == NULL) { + goto error; + } + + PyObject *hint_str = (hint != NULL && hint[0] != '\0') ? + PyUnicode_DecodeUTF8(hint, strlen(hint), "strict") : + Py_NewRef(Py_None); + if (hint_str == NULL) { + /* The remote side has sent an invalid UTF-8 string + * (breaking the standard), drop the connection without + * raising a decode exception. */ + PyErr_Clear(); + goto error; + } + PyObject *result = PyObject_CallFunctionObjArgs(callback, hint_str, NULL); + Py_DECREF(hint_str); + + if (result == NULL) { + goto error; + } + + const char *psk_; + const char *identity_; + Py_ssize_t psk_len_; + Py_ssize_t identity_len_ = 0; + if (!PyArg_ParseTuple(result, "z#y#", &identity_, &identity_len_, &psk_, &psk_len_)) { + Py_DECREF(result); + goto error; + } + + if (identity_len_ + 1 > max_identity_len || psk_len_ > max_psk_len) { + Py_DECREF(result); + goto error; + } + memcpy(psk, psk_, psk_len_); + if (identity_ != NULL) { + memcpy(identity, identity_, identity_len_); + } + identity[identity_len_] = 0; + + Py_DECREF(result); + + PyGILState_Release(gstate); + return (unsigned int)psk_len_; + +error: + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(callback); + } + PyGILState_Release(gstate); + return 0; +} +#endif + +/*[clinic input] +_ssl._SSLContext.set_psk_client_callback + callback: object + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, + PyObject *callback) +/*[clinic end generated code: output=0aba86f6ed75119e input=7627bae0e5ee7635]*/ +{ +#ifndef OPENSSL_NO_PSK + if (self->protocol == PY_SSL_VERSION_TLS_SERVER) { + _setSSLError(get_state_ctx(self), + "Cannot add PSK client callback to a " + "PROTOCOL_TLS_SERVER context", 0, __FILE__, __LINE__); + return NULL; + } + + SSL_psk_client_cb_func ssl_callback; + if (callback == Py_None) { + callback = NULL; + // Delete the existing callback + ssl_callback = NULL; + } else { + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "callback must be callable"); + return NULL; + } + ssl_callback = psk_client_callback; + } + + Py_XDECREF(self->psk_client_callback); + Py_XINCREF(callback); + + self->psk_client_callback = callback; + SSL_CTX_set_psk_client_callback(self->ctx, ssl_callback); + + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "TLS-PSK is not supported by your OpenSSL version."); + return NULL; +#endif +} + +#ifndef OPENSSL_NO_PSK +static unsigned int psk_server_callback(SSL *s, + const char *identity, + unsigned char *psk, + unsigned int max_psk_len) +{ + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject *callback = NULL; + + PySSLSocket *ssl = SSL_get_app_data(s); + if (ssl == NULL || ssl->ctx == NULL) { + goto error; + } + callback = ssl->ctx->psk_server_callback; + if (callback == NULL) { + goto error; + } + + PyObject *identity_str = (identity != NULL && identity[0] != '\0') ? + PyUnicode_DecodeUTF8(identity, strlen(identity), "strict") : + Py_NewRef(Py_None); + if (identity_str == NULL) { + /* The remote side has sent an invalid UTF-8 string + * (breaking the standard), drop the connection without + * raising a decode exception. */ + PyErr_Clear(); + goto error; + } + PyObject *result = PyObject_CallFunctionObjArgs(callback, identity_str, NULL); + Py_DECREF(identity_str); + + if (result == NULL) { + goto error; + } + + char *psk_; + Py_ssize_t psk_len_; + if (PyBytes_AsStringAndSize(result, &psk_, &psk_len_) < 0) { + Py_DECREF(result); + goto error; + } + + if (psk_len_ > max_psk_len) { + Py_DECREF(result); + goto error; + } + memcpy(psk, psk_, psk_len_); + + Py_DECREF(result); + + PyGILState_Release(gstate); + return (unsigned int)psk_len_; + +error: + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(callback); + } + PyGILState_Release(gstate); + return 0; +} +#endif + +/*[clinic input] +_ssl._SSLContext.set_psk_server_callback + callback: object + identity_hint: str(accept={str, NoneType}) = None + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, + PyObject *callback, + const char *identity_hint) +/*[clinic end generated code: output=1f4d6a4e09a92b03 input=65d4b6022aa85ea3]*/ +{ +#ifndef OPENSSL_NO_PSK + if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { + _setSSLError(get_state_ctx(self), + "Cannot add PSK server callback to a " + "PROTOCOL_TLS_CLIENT context", 0, __FILE__, __LINE__); + return NULL; + } + + SSL_psk_server_cb_func ssl_callback; + if (callback == Py_None) { + callback = NULL; + // Delete the existing callback and hint + ssl_callback = NULL; + identity_hint = NULL; + } else { + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_TypeError, "callback must be callable"); + return NULL; + } + ssl_callback = psk_server_callback; + } + + if (SSL_CTX_use_psk_identity_hint(self->ctx, identity_hint) != 1) { + PyErr_SetString(PyExc_ValueError, "failed to set identity hint"); + return NULL; + } + + Py_XDECREF(self->psk_server_callback); + Py_XINCREF(callback); + + self->psk_server_callback = callback; + SSL_CTX_set_psk_server_callback(self->ctx, ssl_callback); + + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "TLS-PSK is not supported by your OpenSSL version."); + return NULL; +#endif +} + static PyGetSetDef context_getsetlist[] = { {"check_hostname", (getter) get_check_hostname, @@ -4715,6 +4960,8 @@ static struct PyMethodDef context_methods[] = { _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF + _SSL__SSLCONTEXT_SET_PSK_CLIENT_CALLBACK_METHODDEF + _SSL__SSLCONTEXT_SET_PSK_SERVER_CALLBACK_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -5786,52 +6033,44 @@ sslmodule_add_option(PyObject *m, const char *name, uint64_t value) static int sslmodule_init_constants(PyObject *m) { - PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", - PY_SSL_DEFAULT_CIPHER_STRING); - - PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", - PY_SSL_ERROR_ZERO_RETURN); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", - PY_SSL_ERROR_WANT_READ); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", - PY_SSL_ERROR_WANT_WRITE); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", - PY_SSL_ERROR_WANT_X509_LOOKUP); - PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", - PY_SSL_ERROR_SYSCALL); - PyModule_AddIntConstant(m, "SSL_ERROR_SSL", - PY_SSL_ERROR_SSL); - PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", - PY_SSL_ERROR_WANT_CONNECT); + if (PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", + PY_SSL_DEFAULT_CIPHER_STRING) < 0) + { + return -1; + } + +#define ADD_INT_CONST(NAME, VALUE) do { \ + if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \ + return -1; \ + } \ +} while (0) + + ADD_INT_CONST("SSL_ERROR_ZERO_RETURN", PY_SSL_ERROR_ZERO_RETURN); + ADD_INT_CONST("SSL_ERROR_WANT_READ", PY_SSL_ERROR_WANT_READ); + ADD_INT_CONST("SSL_ERROR_WANT_WRITE", PY_SSL_ERROR_WANT_WRITE); + ADD_INT_CONST("SSL_ERROR_WANT_X509_LOOKUP", PY_SSL_ERROR_WANT_X509_LOOKUP); + ADD_INT_CONST("SSL_ERROR_SYSCALL", PY_SSL_ERROR_SYSCALL); + ADD_INT_CONST("SSL_ERROR_SSL", PY_SSL_ERROR_SSL); + ADD_INT_CONST("SSL_ERROR_WANT_CONNECT", PY_SSL_ERROR_WANT_CONNECT); /* non ssl.h errorcodes */ - PyModule_AddIntConstant(m, "SSL_ERROR_EOF", - PY_SSL_ERROR_EOF); - PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", - PY_SSL_ERROR_INVALID_ERROR_CODE); + ADD_INT_CONST("SSL_ERROR_EOF", PY_SSL_ERROR_EOF); + ADD_INT_CONST("SSL_ERROR_INVALID_ERROR_CODE", + PY_SSL_ERROR_INVALID_ERROR_CODE); /* cert requirements */ - PyModule_AddIntConstant(m, "CERT_NONE", - PY_SSL_CERT_NONE); - PyModule_AddIntConstant(m, "CERT_OPTIONAL", - PY_SSL_CERT_OPTIONAL); - PyModule_AddIntConstant(m, "CERT_REQUIRED", - PY_SSL_CERT_REQUIRED); + ADD_INT_CONST("CERT_NONE", PY_SSL_CERT_NONE); + ADD_INT_CONST("CERT_OPTIONAL", PY_SSL_CERT_OPTIONAL); + ADD_INT_CONST("CERT_REQUIRED", PY_SSL_CERT_REQUIRED); /* CRL verification for verification_flags */ - PyModule_AddIntConstant(m, "VERIFY_DEFAULT", - 0); - PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_LEAF", - X509_V_FLAG_CRL_CHECK); - PyModule_AddIntConstant(m, "VERIFY_CRL_CHECK_CHAIN", - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); - PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", - X509_V_FLAG_X509_STRICT); - PyModule_AddIntConstant(m, "VERIFY_ALLOW_PROXY_CERTS", - X509_V_FLAG_ALLOW_PROXY_CERTS); - PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", - X509_V_FLAG_TRUSTED_FIRST); + ADD_INT_CONST("VERIFY_DEFAULT", 0); + ADD_INT_CONST("VERIFY_CRL_CHECK_LEAF", X509_V_FLAG_CRL_CHECK); + ADD_INT_CONST("VERIFY_CRL_CHECK_CHAIN", + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + ADD_INT_CONST("VERIFY_X509_STRICT", X509_V_FLAG_X509_STRICT); + ADD_INT_CONST("VERIFY_ALLOW_PROXY_CERTS", X509_V_FLAG_ALLOW_PROXY_CERTS); + ADD_INT_CONST("VERIFY_X509_TRUSTED_FIRST", X509_V_FLAG_TRUSTED_FIRST); #ifdef X509_V_FLAG_PARTIAL_CHAIN - PyModule_AddIntConstant(m, "VERIFY_X509_PARTIAL_CHAIN", - X509_V_FLAG_PARTIAL_CHAIN); + ADD_INT_CONST("VERIFY_X509_PARTIAL_CHAIN", X509_V_FLAG_PARTIAL_CHAIN); #endif /* Alert Descriptions from ssl.h */ @@ -5839,7 +6078,7 @@ sslmodule_init_constants(PyObject *m) /* http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6 */ #define ADD_AD_CONSTANT(s) \ - PyModule_AddIntConstant(m, "ALERT_DESCRIPTION_"#s, \ + ADD_INT_CONST("ALERT_DESCRIPTION_"#s, \ SSL_AD_##s) ADD_AD_CONSTANT(CLOSE_NOTIFY); @@ -5887,23 +6126,15 @@ sslmodule_init_constants(PyObject *m) /* protocol versions */ #ifndef OPENSSL_NO_SSL3 - PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", - PY_SSL_VERSION_SSL3); + ADD_INT_CONST("PROTOCOL_SSLv3", PY_SSL_VERSION_SSL3); #endif - PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", - PY_SSL_VERSION_TLS); - PyModule_AddIntConstant(m, "PROTOCOL_TLS", - PY_SSL_VERSION_TLS); - PyModule_AddIntConstant(m, "PROTOCOL_TLS_CLIENT", - PY_SSL_VERSION_TLS_CLIENT); - PyModule_AddIntConstant(m, "PROTOCOL_TLS_SERVER", - PY_SSL_VERSION_TLS_SERVER); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", - PY_SSL_VERSION_TLS1); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1", - PY_SSL_VERSION_TLS1_1); - PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2", - PY_SSL_VERSION_TLS1_2); + ADD_INT_CONST("PROTOCOL_SSLv23", PY_SSL_VERSION_TLS); + ADD_INT_CONST("PROTOCOL_TLS", PY_SSL_VERSION_TLS); + ADD_INT_CONST("PROTOCOL_TLS_CLIENT", PY_SSL_VERSION_TLS_CLIENT); + ADD_INT_CONST("PROTOCOL_TLS_SERVER", PY_SSL_VERSION_TLS_SERVER); + ADD_INT_CONST("PROTOCOL_TLSv1", PY_SSL_VERSION_TLS1); + ADD_INT_CONST("PROTOCOL_TLSv1_1", PY_SSL_VERSION_TLS1_1); + ADD_INT_CONST("PROTOCOL_TLSv1_2", PY_SSL_VERSION_TLS1_2); #define ADD_OPTION(NAME, VALUE) if (sslmodule_add_option(m, NAME, (VALUE)) < 0) return -1 @@ -5948,50 +6179,52 @@ sslmodule_init_constants(PyObject *m) ADD_OPTION("OP_ENABLE_KTLS", SSL_OP_ENABLE_KTLS); #endif +#undef ADD_OPTION + #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT - PyModule_AddIntConstant(m, "HOSTFLAG_ALWAYS_CHECK_SUBJECT", - X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); + ADD_INT_CONST("HOSTFLAG_ALWAYS_CHECK_SUBJECT", + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT); #endif #ifdef X509_CHECK_FLAG_NEVER_CHECK_SUBJECT - PyModule_AddIntConstant(m, "HOSTFLAG_NEVER_CHECK_SUBJECT", - X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); + ADD_INT_CONST("HOSTFLAG_NEVER_CHECK_SUBJECT", + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT); #endif #ifdef X509_CHECK_FLAG_NO_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_NO_WILDCARDS", - X509_CHECK_FLAG_NO_WILDCARDS); + ADD_INT_CONST("HOSTFLAG_NO_WILDCARDS", + X509_CHECK_FLAG_NO_WILDCARDS); #endif #ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_NO_PARTIAL_WILDCARDS", - X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); + ADD_INT_CONST("HOSTFLAG_NO_PARTIAL_WILDCARDS", + X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); #endif #ifdef X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS - PyModule_AddIntConstant(m, "HOSTFLAG_MULTI_LABEL_WILDCARDS", - X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); + ADD_INT_CONST("HOSTFLAG_MULTI_LABEL_WILDCARDS", + X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS); #endif #ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS - PyModule_AddIntConstant(m, "HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", - X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); + ADD_INT_CONST("HOSTFLAG_SINGLE_LABEL_SUBDOMAINS", + X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS); #endif /* file types */ - PyModule_AddIntConstant(m, "ENCODING_PEM", PY_SSL_ENCODING_PEM); - PyModule_AddIntConstant(m, "ENCODING_DER", PY_SSL_ENCODING_DER); + ADD_INT_CONST("ENCODING_PEM", PY_SSL_ENCODING_PEM); + ADD_INT_CONST("ENCODING_DER", PY_SSL_ENCODING_DER); /* protocol versions */ - PyModule_AddIntConstant(m, "PROTO_MINIMUM_SUPPORTED", - PY_PROTO_MINIMUM_SUPPORTED); - PyModule_AddIntConstant(m, "PROTO_MAXIMUM_SUPPORTED", - PY_PROTO_MAXIMUM_SUPPORTED); - PyModule_AddIntConstant(m, "PROTO_SSLv3", PY_PROTO_SSLv3); - PyModule_AddIntConstant(m, "PROTO_TLSv1", PY_PROTO_TLSv1); - PyModule_AddIntConstant(m, "PROTO_TLSv1_1", PY_PROTO_TLSv1_1); - PyModule_AddIntConstant(m, "PROTO_TLSv1_2", PY_PROTO_TLSv1_2); - PyModule_AddIntConstant(m, "PROTO_TLSv1_3", PY_PROTO_TLSv1_3); + ADD_INT_CONST("PROTO_MINIMUM_SUPPORTED", PY_PROTO_MINIMUM_SUPPORTED); + ADD_INT_CONST("PROTO_MAXIMUM_SUPPORTED", PY_PROTO_MAXIMUM_SUPPORTED); + ADD_INT_CONST("PROTO_SSLv3", PY_PROTO_SSLv3); + ADD_INT_CONST("PROTO_TLSv1", PY_PROTO_TLSv1); + ADD_INT_CONST("PROTO_TLSv1_1", PY_PROTO_TLSv1_1); + ADD_INT_CONST("PROTO_TLSv1_2", PY_PROTO_TLSv1_2); + ADD_INT_CONST("PROTO_TLSv1_3", PY_PROTO_TLSv1_3); #define addbool(m, key, value) \ do { \ PyObject *bool_obj = (value) ? Py_True : Py_False; \ - PyModule_AddObjectRef((m), (key), bool_obj); \ + if (PyModule_AddObjectRef((m), (key), bool_obj) < 0) { \ + return -1; \ + } \ } while (0) addbool(m, "HAS_SNI", 1); @@ -6032,6 +6265,15 @@ sslmodule_init_constants(PyObject *m) addbool(m, "HAS_TLSv1_3", 0); #endif +#ifdef OPENSSL_NO_PSK + addbool(m, "HAS_PSK", 0); +#else + addbool(m, "HAS_PSK", 1); +#endif + +#undef addbool +#undef ADD_INT_CONST + return 0; } diff --git a/Modules/_ssl/clinic/cert.c.h b/Modules/_ssl/clinic/cert.c.h index db43c88e411139..0748d32291e3c5 100644 --- a/Modules/_ssl/clinic/cert.c.h +++ b/Modules/_ssl/clinic/cert.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_ssl_Certificate_public_bytes__doc__, "public_bytes($self, /, format=Encoding.PEM)\n" @@ -85,4 +86,4 @@ _ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) { return _ssl_Certificate_get_info_impl(self); } -/*[clinic end generated code: output=8e438b54fbebd53e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5b668226f933a677 input=a9049054013a1b77]*/ diff --git a/Modules/_stat.c b/Modules/_stat.c index 3fd951b6fc1022..80f8a92668976b 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -11,6 +11,13 @@ * */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.13 for PyModule_Add() on Windows +#define Py_LIMITED_API 0x030d0000 +#endif + #include "Python.h" #ifdef HAVE_SYS_TYPES_H diff --git a/Modules/_statisticsmodule.c b/Modules/_statisticsmodule.c index 1d5465fbe6d04e..a04a2a779a5d3d 100644 --- a/Modules/_statisticsmodule.c +++ b/Modules/_statisticsmodule.c @@ -1,5 +1,10 @@ /* statistics accelerator C extension: _statistics module. */ +// clinic/_statisticsmodule.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "clinic/_statisticsmodule.c.h" diff --git a/Modules/_struct.c b/Modules/_struct.c index ff1bf4e96c5f21..bd16fa89f18945 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1553,9 +1553,28 @@ prepare_s(PyStructObject *self) return -1; } +static PyObject * +s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *self; + + assert(type != NULL); + allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); + assert(alloc_func != NULL); + + self = alloc_func(type, 0); + if (self != NULL) { + PyStructObject *s = (PyStructObject*)self; + s->s_format = Py_NewRef(Py_None); + s->s_codes = NULL; + s->s_size = -1; + s->s_len = -1; + } + return self; +} + /*[clinic input] -@classmethod -Struct.__new__ +Struct.__init__ format: object @@ -1567,24 +1586,16 @@ the format string. See help(struct) for more on format strings. [clinic start generated code]*/ -static PyObject * -Struct_impl(PyTypeObject *type, PyObject *format) -/*[clinic end generated code: output=49468b044e334308 input=8b91868eb1df0e28]*/ +static int +Struct___init___impl(PyStructObject *self, PyObject *format) +/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ { - allocfunc alloc = PyType_GetSlot(type, Py_tp_alloc); - assert(alloc != NULL); - PyStructObject *self = (PyStructObject *)alloc(type, 0); - - if (self == NULL) { - return NULL; - } + int ret = 0; if (PyUnicode_Check(format)) { format = PyUnicode_AsASCIIString(format); - if (format == NULL) { - Py_DECREF(self); - return NULL; - } + if (format == NULL) + return -1; } else { Py_INCREF(format); @@ -1592,24 +1603,19 @@ Struct_impl(PyTypeObject *type, PyObject *format) if (!PyBytes_Check(format)) { Py_DECREF(format); - Py_DECREF(self); PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be a str or bytes object, " "not %.200s", _PyType_Name(Py_TYPE(format))); - return NULL; + return -1; } - self->s_format = format; + Py_SETREF(self->s_format, format); - if (prepare_s(self) < 0) { - Py_DECREF(self); - return NULL; - } - return (PyObject *)self; + ret = prepare_s(self); + return ret; } - static int s_clear(PyStructObject *s) { @@ -2219,8 +2225,9 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_methods, s_methods}, {Py_tp_members, s_members}, {Py_tp_getset, s_getsetlist}, - {Py_tp_new, Struct}, + {Py_tp_init, Struct___init__}, {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, s_new}, {Py_tp_free, PyObject_GC_Del}, {0, 0}, }; @@ -2250,20 +2257,13 @@ cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) return 1; } - if (state->cache == NULL) { - state->cache = PyDict_New(); - if (state->cache == NULL) - return 0; + if (PyDict_GetItemRef(state->cache, fmt, &s_object) < 0) { + return 0; } - - s_object = PyDict_GetItemWithError(state->cache, fmt); if (s_object != NULL) { - *ptr = (PyStructObject *)Py_NewRef(s_object); + *ptr = (PyStructObject *)s_object; return Py_CLEANUP_SUPPORTED; } - else if (PyErr_Occurred()) { - return 0; - } s_object = PyObject_CallOneArg(state->PyStructType, fmt); if (s_object != NULL) { @@ -2288,7 +2288,7 @@ static PyObject * _clearcache_impl(PyObject *module) /*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ { - Py_CLEAR(get_struct_state(module)->cache); + PyDict_Clear(get_struct_state(module)->cache); Py_RETURN_NONE; } @@ -2512,6 +2512,11 @@ _structmodule_exec(PyObject *m) { _structmodulestate *state = get_struct_state(m); + state->cache = PyDict_New(); + if (state->cache == NULL) { + return -1; + } + state->PyStructType = PyType_FromModuleAndSpec( m, &PyStructType_spec, NULL); if (state->PyStructType == NULL) { diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c new file mode 100644 index 00000000000000..c76b9e6b3ebafa --- /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_GIL_DISABLED + PyObject *py_gil_disabled = _PyLong_GetOne(); +#else + PyObject *py_gil_disabled = _PyLong_GetZero(); +#endif + if (PyDict_SetItemString(config, "Py_GIL_DISABLED", py_gil_disabled) < 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 index 81a3dea4c1dfde..a8ba009eb6a54b 100644 --- a/Modules/_testcapi/abstract.c +++ b/Modules/_testcapi/abstract.c @@ -1,9 +1,35 @@ -#include // ptrdiff_t - #include "parts.h" #include "util.h" +static PyObject * +object_repr(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyObject_Repr(arg); +} + +static PyObject * +object_ascii(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyObject_ASCII(arg); +} + +static PyObject * +object_str(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyObject_Str(arg); +} + +static PyObject * +object_bytes(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyObject_Bytes(arg); +} + static PyObject * object_getattr(PyObject *self, PyObject *args) { @@ -182,6 +208,12 @@ object_delattrstring(PyObject *self, PyObject *args) RETURN_INT(PyObject_DelAttrString(obj, attr_name)); } +static PyObject * +number_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyBool_FromLong(PyNumber_Check(obj)); +} static PyObject * mapping_check(PyObject *self, PyObject *obj) @@ -612,6 +644,11 @@ sequence_tuple(PyObject *self, PyObject *obj) static PyMethodDef test_methods[] = { + {"object_repr", object_repr, METH_O}, + {"object_ascii", object_ascii, METH_O}, + {"object_str", object_str, METH_O}, + {"object_bytes", object_bytes, METH_O}, + {"object_getattr", object_getattr, METH_VARARGS}, {"object_getattrstring", object_getattrstring, METH_VARARGS}, {"object_getoptionalattr", object_getoptionalattr, METH_VARARGS}, @@ -625,6 +662,7 @@ static PyMethodDef test_methods[] = { {"object_delattr", object_delattr, METH_VARARGS}, {"object_delattrstring", object_delattrstring, METH_VARARGS}, + {"number_check", number_check, METH_O}, {"mapping_check", mapping_check, METH_O}, {"mapping_size", mapping_size, METH_O}, {"mapping_length", mapping_length, METH_O}, diff --git a/Modules/_testcapi/bytearray.c b/Modules/_testcapi/bytearray.c new file mode 100644 index 00000000000000..dc47ed2c306f40 --- /dev/null +++ b/Modules/_testcapi/bytearray.c @@ -0,0 +1,123 @@ +#include "parts.h" +#include "util.h" + + +/* Test PyByteArray_Check() */ +static PyObject * +bytearray_check(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyByteArray_Check(obj)); +} + +/* Test PyByteArray_CheckExact() */ +static PyObject * +bytearray_checkexact(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyByteArray_CheckExact(obj)); +} + +/* Test PyByteArray_FromStringAndSize() */ +static PyObject * +bytearray_fromstringandsize(PyObject *Py_UNUSED(module), PyObject *args) +{ + const char *s; + Py_ssize_t bsize; + Py_ssize_t size = -100; + + if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) { + return NULL; + } + + if (size == -100) { + size = bsize; + } + return PyByteArray_FromStringAndSize(s, size); +} + +/* Test PyByteArray_FromObject() */ +static PyObject * +bytearray_fromobject(PyObject *Py_UNUSED(module), PyObject *arg) +{ + NULLABLE(arg); + return PyByteArray_FromObject(arg); +} + +/* Test PyByteArray_Size() */ +static PyObject * +bytearray_size(PyObject *Py_UNUSED(module), PyObject *arg) +{ + NULLABLE(arg); + RETURN_SIZE(PyByteArray_Size(arg)); +} + +/* Test PyUnicode_AsString() */ +static PyObject * +bytearray_asstring(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t buflen; + const char *s; + + if (!PyArg_ParseTuple(args, "On", &obj, &buflen)) + return NULL; + + NULLABLE(obj); + s = PyByteArray_AsString(obj); + if (s == NULL) + return NULL; + + return PyByteArray_FromStringAndSize(s, buflen); +} + +/* Test PyByteArray_Concat() */ +static PyObject * +bytearray_concat(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *left, *right; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + return PyByteArray_Concat(left, right); +} + +/* Test PyByteArray_Resize() */ +static PyObject * +bytearray_resize(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "On", &obj, &size)) + return NULL; + + NULLABLE(obj); + RETURN_INT(PyByteArray_Resize(obj, size)); +} + + +static PyMethodDef test_methods[] = { + {"bytearray_check", bytearray_check, METH_O}, + {"bytearray_checkexact", bytearray_checkexact, METH_O}, + {"bytearray_fromstringandsize", bytearray_fromstringandsize, METH_VARARGS}, + {"bytearray_fromobject", bytearray_fromobject, METH_O}, + {"bytearray_size", bytearray_size, METH_O}, + {"bytearray_asstring", bytearray_asstring, METH_VARARGS}, + {"bytearray_concat", bytearray_concat, METH_VARARGS}, + {"bytearray_resize", bytearray_resize, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_ByteArray(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/bytes.c b/Modules/_testcapi/bytes.c new file mode 100644 index 00000000000000..da10503f6f6856 --- /dev/null +++ b/Modules/_testcapi/bytes.c @@ -0,0 +1,255 @@ +#include "parts.h" +#include "util.h" + + +/* Test PyBytes_Check() */ +static PyObject * +bytes_check(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyBytes_Check(obj)); +} + +/* Test PyBytes_CheckExact() */ +static PyObject * +bytes_checkexact(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyBytes_CheckExact(obj)); +} + +/* Test PyBytes_FromStringAndSize() */ +static PyObject * +bytes_fromstringandsize(PyObject *Py_UNUSED(module), PyObject *args) +{ + const char *s; + Py_ssize_t bsize; + Py_ssize_t size = -100; + + if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) { + return NULL; + } + + if (size == -100) { + size = bsize; + } + return PyBytes_FromStringAndSize(s, size); +} + +/* Test PyBytes_FromString() */ +static PyObject * +bytes_fromstring(PyObject *Py_UNUSED(module), PyObject *arg) +{ + const char *s; + Py_ssize_t size; + + if (!PyArg_Parse(arg, "z#", &s, &size)) { + return NULL; + } + return PyBytes_FromString(s); +} + +/* Test PyBytes_FromObject() */ +static PyObject * +bytes_fromobject(PyObject *Py_UNUSED(module), PyObject *arg) +{ + NULLABLE(arg); + return PyBytes_FromObject(arg); +} + +/* Test PyBytes_Size() */ +static PyObject * +bytes_size(PyObject *Py_UNUSED(module), PyObject *arg) +{ + NULLABLE(arg); + RETURN_SIZE(PyBytes_Size(arg)); +} + +/* Test PyUnicode_AsString() */ +static PyObject * +bytes_asstring(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t buflen; + const char *s; + + if (!PyArg_ParseTuple(args, "On", &obj, &buflen)) + return NULL; + + NULLABLE(obj); + s = PyBytes_AsString(obj); + if (s == NULL) + return NULL; + + return PyBytes_FromStringAndSize(s, buflen); +} + +/* Test PyBytes_AsStringAndSize() */ +static PyObject * +bytes_asstringandsize(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t buflen; + char *s = UNINITIALIZED_PTR; + Py_ssize_t size = UNINITIALIZED_SIZE; + + if (!PyArg_ParseTuple(args, "On", &obj, &buflen)) + return NULL; + + NULLABLE(obj); + if (PyBytes_AsStringAndSize(obj, &s, &size) < 0) { + return NULL; + } + + if (s == NULL) { + return Py_BuildValue("(On)", Py_None, size); + } + else { + return Py_BuildValue("(y#n)", s, buflen, size); + } +} + +static PyObject * +bytes_asstringandsize_null(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t buflen; + char *s = UNINITIALIZED_PTR; + + if (!PyArg_ParseTuple(args, "On", &obj, &buflen)) + return NULL; + + NULLABLE(obj); + if (PyBytes_AsStringAndSize(obj, &s, NULL) < 0) { + return NULL; + } + + if (s == NULL) { + Py_RETURN_NONE; + } + else { + return PyBytes_FromStringAndSize(s, buflen); + } +} + +/* Test PyBytes_Repr() */ +static PyObject * +bytes_repr(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + int smartquotes; + if (!PyArg_ParseTuple(args, "Oi", &obj, &smartquotes)) + return NULL; + + NULLABLE(obj); + return PyBytes_Repr(obj, smartquotes); +} + +/* Test PyBytes_Concat() */ +static PyObject * +bytes_concat(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *left, *right; + int new = 0; + + if (!PyArg_ParseTuple(args, "OO|p", &left, &right, &new)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + if (new) { + assert(left != NULL); + assert(PyBytes_CheckExact(left)); + left = PyBytes_FromStringAndSize(PyBytes_AS_STRING(left), + PyBytes_GET_SIZE(left)); + if (left == NULL) { + return NULL; + } + } + else { + Py_XINCREF(left); + } + PyBytes_Concat(&left, right); + if (left == NULL && !PyErr_Occurred()) { + Py_RETURN_NONE; + } + return left; +} + +/* Test PyBytes_ConcatAndDel() */ +static PyObject * +bytes_concatanddel(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *left, *right; + int new = 0; + + if (!PyArg_ParseTuple(args, "OO|p", &left, &right, &new)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + if (new) { + assert(left != NULL); + assert(PyBytes_CheckExact(left)); + left = PyBytes_FromStringAndSize(PyBytes_AS_STRING(left), + PyBytes_GET_SIZE(left)); + if (left == NULL) { + return NULL; + } + } + else { + Py_XINCREF(left); + } + Py_XINCREF(right); + PyBytes_ConcatAndDel(&left, right); + if (left == NULL && !PyErr_Occurred()) { + Py_RETURN_NONE; + } + return left; +} + +/* Test PyBytes_DecodeEscape() */ +static PyObject * +bytes_decodeescape(PyObject *Py_UNUSED(module), PyObject *args) +{ + const char *s; + Py_ssize_t bsize; + Py_ssize_t size = -100; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "z#|zn", &s, &bsize, &errors, &size)) + return NULL; + + if (size == -100) { + size = bsize; + } + return PyBytes_DecodeEscape(s, size, errors, 0, NULL); +} + + +static PyMethodDef test_methods[] = { + {"bytes_check", bytes_check, METH_O}, + {"bytes_checkexact", bytes_checkexact, METH_O}, + {"bytes_fromstringandsize", bytes_fromstringandsize, METH_VARARGS}, + {"bytes_fromstring", bytes_fromstring, METH_O}, + {"bytes_fromobject", bytes_fromobject, METH_O}, + {"bytes_size", bytes_size, METH_O}, + {"bytes_asstring", bytes_asstring, METH_VARARGS}, + {"bytes_asstringandsize", bytes_asstringandsize, METH_VARARGS}, + {"bytes_asstringandsize_null", bytes_asstringandsize_null, METH_VARARGS}, + {"bytes_repr", bytes_repr, METH_VARARGS}, + {"bytes_concat", bytes_concat, METH_VARARGS}, + {"bytes_concatanddel", bytes_concatanddel, METH_VARARGS}, + {"bytes_decodeescape", bytes_decodeescape, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Bytes(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h index 39b5f8b91a00db..a797444c1a72b9 100644 --- a/Modules/_testcapi/clinic/exceptions.c.h +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_testcapi_err_set_raised__doc__, "err_set_raised($module, exception, /)\n" @@ -455,4 +456,4 @@ _testcapi_unstable_exc_prep_reraise_star(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=ff19512450b3bbdb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0b11ef105030a48e input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/float.c.h b/Modules/_testcapi/clinic/float.c.h index fb0931a0703e11..d5a00c8072da1e 100644 --- a/Modules/_testcapi/clinic/float.c.h +++ b/Modules/_testcapi/clinic/float.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_testcapi_float_pack__doc__, "float_pack($module, size, d, le, /)\n" "--\n" @@ -79,4 +81,4 @@ _testcapi_float_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=50146051f1341cce input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b43dfd3a77fe04ba input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/vectorcall.c.h b/Modules/_testcapi/clinic/vectorcall.c.h index 48688e9ade050a..c6049a438dc8fc 100644 --- a/Modules/_testcapi/clinic/vectorcall.c.h +++ b/Modules/_testcapi/clinic/vectorcall.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_testcapi_pyobject_fastcalldict__doc__, "pyobject_fastcalldict($module, func, func_args, kwargs, /)\n" "--\n" @@ -204,4 +206,4 @@ _testcapi_has_vectorcall_flag(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=0667266b825ec9ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=210ae67caab177ba input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/watchers.c.h b/Modules/_testcapi/clinic/watchers.c.h index fd2ef608334049..ebd71d119fa347 100644 --- a/Modules/_testcapi/clinic/watchers.c.h +++ b/Modules/_testcapi/clinic/watchers.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_testcapi_watch_dict__doc__, "watch_dict($module, watcher_id, dict, /)\n" "--\n" @@ -189,4 +191,4 @@ _testcapi_set_func_kwdefaults_via_capi(PyObject *module, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=5ad5771d6b29dfb9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0e07ce7f295917a5 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/codec.c b/Modules/_testcapi/codec.c new file mode 100644 index 00000000000000..d13f51e20331a1 --- /dev/null +++ b/Modules/_testcapi/codec.c @@ -0,0 +1,17 @@ +#include "parts.h" +#include "util.h" + + +static PyMethodDef test_methods[] = { + {NULL}, +}; + +int +_PyTestCapi_Init_Codec(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0){ + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/complex.c b/Modules/_testcapi/complex.c new file mode 100644 index 00000000000000..4a70217eb90d62 --- /dev/null +++ b/Modules/_testcapi/complex.c @@ -0,0 +1,167 @@ +#include "parts.h" +#include "util.h" + + +static PyObject * +complex_check(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyComplex_Check(obj)); +} + +static PyObject * +complex_checkexact(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyComplex_CheckExact(obj)); +} + +static PyObject * +complex_fromccomplex(PyObject *Py_UNUSED(module), PyObject *obj) +{ + Py_complex complex; + + if (!PyArg_Parse(obj, "D", &complex)) { + return NULL; + } + + return PyComplex_FromCComplex(complex); +} + +static PyObject * +complex_fromdoubles(PyObject *Py_UNUSED(module), PyObject *args) +{ + double real, imag; + + if (!PyArg_ParseTuple(args, "dd", &real, &imag)) { + return NULL; + } + + return PyComplex_FromDoubles(real, imag); +} + +static PyObject * +complex_realasdouble(PyObject *Py_UNUSED(module), PyObject *obj) +{ + double real; + + NULLABLE(obj); + real = PyComplex_RealAsDouble(obj); + + if (real == -1. && PyErr_Occurred()) { + return NULL; + } + + return PyFloat_FromDouble(real); +} + +static PyObject * +complex_imagasdouble(PyObject *Py_UNUSED(module), PyObject *obj) +{ + double imag; + + NULLABLE(obj); + imag = PyComplex_ImagAsDouble(obj); + + if (imag == -1. && PyErr_Occurred()) { + return NULL; + } + + return PyFloat_FromDouble(imag); +} + +static PyObject * +complex_asccomplex(PyObject *Py_UNUSED(module), PyObject *obj) +{ + Py_complex complex; + + NULLABLE(obj); + complex = PyComplex_AsCComplex(obj); + + if (complex.real == -1. && PyErr_Occurred()) { + return NULL; + } + + return PyComplex_FromCComplex(complex); +} + +static PyObject* +_py_c_neg(PyObject *Py_UNUSED(module), PyObject *num) +{ + Py_complex complex; + + complex = PyComplex_AsCComplex(num); + if (complex.real == -1. && PyErr_Occurred()) { + return NULL; + } + + return PyComplex_FromCComplex(_Py_c_neg(complex)); +} + +#define _PY_C_FUNC2(suffix) \ + static PyObject * \ + _py_c_##suffix(PyObject *Py_UNUSED(module), PyObject *args) \ + { \ + Py_complex num, exp, res; \ + \ + if (!PyArg_ParseTuple(args, "DD", &num, &exp)) { \ + return NULL; \ + } \ + \ + errno = 0; \ + res = _Py_c_##suffix(num, exp); \ + return Py_BuildValue("Di", &res, errno); \ + }; + +_PY_C_FUNC2(sum) +_PY_C_FUNC2(diff) +_PY_C_FUNC2(prod) +_PY_C_FUNC2(quot) +_PY_C_FUNC2(pow) + +static PyObject* +_py_c_abs(PyObject *Py_UNUSED(module), PyObject* obj) +{ + Py_complex complex; + double res; + + NULLABLE(obj); + complex = PyComplex_AsCComplex(obj); + + if (complex.real == -1. && PyErr_Occurred()) { + return NULL; + } + + errno = 0; + res = _Py_c_abs(complex); + return Py_BuildValue("di", res, errno); +} + + +static PyMethodDef test_methods[] = { + {"complex_check", complex_check, METH_O}, + {"complex_checkexact", complex_checkexact, METH_O}, + {"complex_fromccomplex", complex_fromccomplex, METH_O}, + {"complex_fromdoubles", complex_fromdoubles, METH_VARARGS}, + {"complex_realasdouble", complex_realasdouble, METH_O}, + {"complex_imagasdouble", complex_imagasdouble, METH_O}, + {"complex_asccomplex", complex_asccomplex, METH_O}, + {"_py_c_sum", _py_c_sum, METH_VARARGS}, + {"_py_c_diff", _py_c_diff, METH_VARARGS}, + {"_py_c_neg", _py_c_neg, METH_O}, + {"_py_c_prod", _py_c_prod, METH_VARARGS}, + {"_py_c_quot", _py_c_quot, METH_VARARGS}, + {"_py_c_pow", _py_c_pow, METH_VARARGS}, + {"_py_c_abs", _py_c_abs, METH_O}, + {NULL}, +}; + +int +_PyTestCapi_Init_Complex(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/dict.c b/Modules/_testcapi/dict.c index 810989fbed85f9..42e056b7d07a31 100644 --- a/Modules/_testcapi/dict.c +++ b/Modules/_testcapi/dict.c @@ -1,5 +1,3 @@ -#include // ptrdiff_t - #include "parts.h" #include "util.h" @@ -333,6 +331,88 @@ dict_mergefromseq2(PyObject *self, PyObject *args) } +static PyObject * +dict_pop(PyObject *self, PyObject *args) +{ + // Test PyDict_Pop(dict, key, &value) + PyObject *dict, *key; + if (!PyArg_ParseTuple(args, "OO", &dict, &key)) { + return NULL; + } + NULLABLE(dict); + NULLABLE(key); + PyObject *result = UNINITIALIZED_PTR; + int res = PyDict_Pop(dict, key, &result); + if (res < 0) { + assert(result == NULL); + return NULL; + } + if (res == 0) { + assert(result == NULL); + result = Py_NewRef(Py_None); + } + else { + assert(result != NULL); + } + return Py_BuildValue("iN", res, result); +} + + +static PyObject * +dict_pop_null(PyObject *self, PyObject *args) +{ + // Test PyDict_Pop(dict, key, NULL) + PyObject *dict, *key; + if (!PyArg_ParseTuple(args, "OO", &dict, &key)) { + return NULL; + } + NULLABLE(dict); + NULLABLE(key); + RETURN_INT(PyDict_Pop(dict, key, NULL)); +} + + +static PyObject * +dict_popstring(PyObject *self, PyObject *args) +{ + PyObject *dict; + const char *key; + Py_ssize_t key_size; + if (!PyArg_ParseTuple(args, "Oz#", &dict, &key, &key_size)) { + return NULL; + } + NULLABLE(dict); + PyObject *result = UNINITIALIZED_PTR; + int res = PyDict_PopString(dict, key, &result); + if (res < 0) { + assert(result == NULL); + return NULL; + } + if (res == 0) { + assert(result == NULL); + result = Py_NewRef(Py_None); + } + else { + assert(result != NULL); + } + return Py_BuildValue("iN", res, result); +} + + +static PyObject * +dict_popstring_null(PyObject *self, PyObject *args) +{ + PyObject *dict; + const char *key; + Py_ssize_t key_size; + if (!PyArg_ParseTuple(args, "Oz#", &dict, &key, &key_size)) { + return NULL; + } + NULLABLE(dict); + RETURN_INT(PyDict_PopString(dict, key, NULL)); +} + + static PyMethodDef test_methods[] = { {"dict_check", dict_check, METH_O}, {"dict_checkexact", dict_checkexact, METH_O}, @@ -360,7 +440,10 @@ static PyMethodDef test_methods[] = { {"dict_merge", dict_merge, METH_VARARGS}, {"dict_update", dict_update, METH_VARARGS}, {"dict_mergefromseq2", dict_mergefromseq2, METH_VARARGS}, - + {"dict_pop", dict_pop, METH_VARARGS}, + {"dict_pop_null", dict_pop_null, METH_VARARGS}, + {"dict_popstring", dict_popstring, METH_VARARGS}, + {"dict_popstring_null", dict_popstring_null, METH_VARARGS}, {NULL}, }; diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c index b54ce0cbb0dd20..42a9915143e6fa 100644 --- a/Modules/_testcapi/exceptions.c +++ b/Modules/_testcapi/exceptions.c @@ -1,3 +1,6 @@ +// clinic/exceptions.c.h uses internal pycore_modsupport.h API +#define PYTESTCAPI_NEED_INTERNAL_API + #include "parts.h" #include "util.h" #include "clinic/exceptions.c.h" @@ -300,6 +303,46 @@ _testcapi_traceback_print_impl(PyObject *module, PyObject *traceback, Py_RETURN_NONE; } +static PyObject * +err_writeunraisable(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *exc, *obj; + if (!PyArg_ParseTuple(args, "OO", &exc, &obj)) { + return NULL; + } + NULLABLE(exc); + NULLABLE(obj); + if (exc) { + PyErr_SetRaisedException(Py_NewRef(exc)); + } + PyErr_WriteUnraisable(obj); + Py_RETURN_NONE; +} + +static PyObject * +err_formatunraisable(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *exc; + const char *fmt; + Py_ssize_t fmtlen; + PyObject *objs[10] = {NULL}; + + if (!PyArg_ParseTuple(args, "Oz#|OOOOOOOOOO", &exc, &fmt, &fmtlen, + &objs[0], &objs[1], &objs[2], &objs[3], &objs[4], + &objs[5], &objs[6], &objs[7], &objs[8], &objs[9])) + { + return NULL; + } + NULLABLE(exc); + if (exc) { + PyErr_SetRaisedException(Py_NewRef(exc)); + } + PyErr_FormatUnraisable(fmt, + objs[0], objs[1], objs[2], objs[3], objs[4], + objs[5], objs[6], objs[7], objs[8], objs[9]); + Py_RETURN_NONE; +} + /*[clinic input] _testcapi.unstable_exc_prep_reraise_star orig: object @@ -344,6 +387,8 @@ static PyTypeObject PyRecursingInfinitelyError_Type = { static PyMethodDef test_methods[] = { {"err_restore", err_restore, METH_VARARGS}, + {"err_writeunraisable", err_writeunraisable, METH_VARARGS}, + {"err_formatunraisable", err_formatunraisable, METH_VARARGS}, _TESTCAPI_ERR_SET_RAISED_METHODDEF _TESTCAPI_EXCEPTION_PRINT_METHODDEF _TESTCAPI_FATAL_ERROR_METHODDEF diff --git a/Modules/_testcapi/file.c b/Modules/_testcapi/file.c new file mode 100644 index 00000000000000..634563f6ea12cb --- /dev/null +++ b/Modules/_testcapi/file.c @@ -0,0 +1,17 @@ +#include "parts.h" +#include "util.h" + + +static PyMethodDef test_methods[] = { + {NULL}, +}; + +int +_PyTestCapi_Init_File(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0){ + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/float.c b/Modules/_testcapi/float.c index cff53fb950fcc6..4fcbaf3bb2aa1e 100644 --- a/Modules/_testcapi/float.c +++ b/Modules/_testcapi/float.c @@ -1,7 +1,76 @@ +// clinic/float.c.h uses internal pycore_modsupport.h API +#define PYTESTCAPI_NEED_INTERNAL_API + #include "parts.h" +#include "util.h" #include "clinic/float.c.h" +static PyObject * +float_check(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyFloat_Check(obj)); +} + +static PyObject * +float_checkexact(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyFloat_CheckExact(obj)); +} + +static PyObject * +float_fromstring(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyFloat_FromString(obj); +} + +static PyObject * +float_fromdouble(PyObject *Py_UNUSED(module), PyObject *obj) +{ + double d; + + if (!PyArg_Parse(obj, "d", &d)) { + return NULL; + } + + return PyFloat_FromDouble(d); +} + +static PyObject * +float_asdouble(PyObject *Py_UNUSED(module), PyObject *obj) +{ + double d; + + NULLABLE(obj); + d = PyFloat_AsDouble(obj); + if (d == -1. && PyErr_Occurred()) { + return NULL; + } + + return PyFloat_FromDouble(d); +} + +static PyObject * +float_getinfo(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(arg)) +{ + return PyFloat_GetInfo(); +} + +static PyObject * +float_getmax(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(arg)) +{ + return PyFloat_FromDouble(PyFloat_GetMax()); +} + +static PyObject * +float_getmin(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(arg)) +{ + return PyFloat_FromDouble(PyFloat_GetMin()); +} + /*[clinic input] module _testcapi [clinic start generated code]*/ @@ -96,6 +165,14 @@ _testcapi_float_unpack_impl(PyObject *module, const char *data, } static PyMethodDef test_methods[] = { + {"float_check", float_check, METH_O}, + {"float_checkexact", float_checkexact, METH_O}, + {"float_fromstring", float_fromstring, METH_O}, + {"float_fromdouble", float_fromdouble, METH_O}, + {"float_asdouble", float_asdouble, METH_O}, + {"float_getinfo", float_getinfo, METH_NOARGS}, + {"float_getmax", float_getmax, METH_NOARGS}, + {"float_getmin", float_getmin, METH_NOARGS}, _TESTCAPI_FLOAT_PACK_METHODDEF _TESTCAPI_FLOAT_UNPACK_METHODDEF {NULL}, diff --git a/Modules/_testcapi/getargs.c b/Modules/_testcapi/getargs.c index 5f4a6dc8ca7672..33e8af7d7bbb39 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,60 @@ 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; + int count = 0; + for (const char *f = sub_format; *f; f++) { + if (Py_ISALNUM(*f)) { + if (strchr("OSUY", *f) == NULL) { + objects_only = 0; + break; + } + count++; + } + } + if (objects_only) { + return_value = PyTuple_New(count); + if (return_value == NULL) { + goto exit; + } + for (Py_ssize_t i = 0; i < count; 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; } @@ -112,32 +142,25 @@ getargs_w_star(PyObject *self, PyObject *args) } static PyObject * -test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) +getargs_empty(PyObject *self, PyObject *args, PyObject *kwargs) { /* Test that formats can begin with '|'. See issue #4720. */ - PyObject *dict = NULL; - static char *kwlist[] = {NULL}; - PyObject *tuple = PyTuple_New(0); - if (!tuple) { - return NULL; - } + assert(PyTuple_CheckExact(args)); + assert(kwargs == NULL || PyDict_CheckExact(kwargs)); + int result; - if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) { - goto done; - } - dict = PyDict_New(); - if (!dict) { - goto done; - } - result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", - kwlist); - done: - Py_DECREF(tuple); - Py_XDECREF(dict); + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) > 0) { + static char *kwlist[] = {NULL}; + result = PyArg_ParseTupleAndKeywords(args, kwargs, "|:getargs_empty", + kwlist); + } + else { + result = PyArg_ParseTuple(args, "|:getargs_empty"); + } if (!result) { return NULL; } - Py_RETURN_NONE; + return PyLong_FromLong(result); } /* Test tuple argument processing */ @@ -328,75 +351,6 @@ getargs_K(PyObject *self, PyObject *args) return PyLong_FromUnsignedLongLong(value); } -/* This function not only tests the 'k' getargs code, but also the - PyLong_AsUnsignedLongMask() function. */ -static PyObject * -test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *num; - unsigned long value; - - tuple = PyTuple_New(1); - if (tuple == NULL) { - return NULL; - } - - /* a number larger than ULONG_MAX even on 64-bit platforms */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) { - return NULL; - } - - value = PyLong_AsUnsignedLongMask(num); - if (value != ULONG_MAX) { - PyErr_SetString(PyExc_AssertionError, - "test_k_code: " - "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); - return NULL; - } - - PyTuple_SET_ITEM(tuple, 0, num); - - value = 0; - if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { - return NULL; - } - if (value != ULONG_MAX) { - PyErr_SetString(PyExc_AssertionError, - "test_k_code: k code returned wrong value for long 0xFFF...FFF"); - return NULL; - } - - Py_DECREF(num); - num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); - if (num == NULL) { - return NULL; - } - - value = PyLong_AsUnsignedLongMask(num); - if (value != (unsigned long)-0x42) { - PyErr_SetString(PyExc_AssertionError, - "test_k_code: " - "PyLong_AsUnsignedLongMask() returned wrong value for long -0xFFF..000042"); - return NULL; - } - - PyTuple_SET_ITEM(tuple, 0, num); - - value = 0; - if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { - return NULL; - } - if (value != (unsigned long)-0x42) { - PyErr_SetString(PyExc_AssertionError, - "test_k_code: k code returned wrong value for long -0xFFF..000042"); - return NULL; - } - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - static PyObject * getargs_f(PyObject *self, PyObject *args) { @@ -677,95 +631,6 @@ getargs_et_hash(PyObject *self, PyObject *args) return result; } -/* Test the L code for PyArg_ParseTuple. This should deliver a long long - for both long and int arguments. The test may leak a little memory if - it fails. -*/ -static PyObject * -test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *num; - long long value; - - tuple = PyTuple_New(1); - if (tuple == NULL) { - return NULL; - } - - num = PyLong_FromLong(42); - if (num == NULL) { - return NULL; - } - - PyTuple_SET_ITEM(tuple, 0, num); - - value = -1; - if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { - return NULL; - } - if (value != 42) { - PyErr_SetString(PyExc_AssertionError, - "test_L_code: L code returned wrong value for long 42"); - return NULL; - } - - Py_DECREF(num); - num = PyLong_FromLong(42); - if (num == NULL) { - return NULL; - } - - PyTuple_SET_ITEM(tuple, 0, num); - - value = -1; - if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { - return NULL; - } - if (value != 42) { - PyErr_SetString(PyExc_AssertionError, - "test_L_code: L code returned wrong value for int 42"); - return NULL; - } - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - -/* Test the s and z codes for PyArg_ParseTuple. -*/ -static PyObject * -test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - /* Unicode strings should be accepted */ - PyObject *tuple = PyTuple_New(1); - if (tuple == NULL) { - return NULL; - } - - PyObject *obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"), - "latin-1", NULL); - if (obj == NULL) { - return NULL; - } - - PyTuple_SET_ITEM(tuple, 0, obj); - - /* These two blocks used to raise a TypeError: - * "argument must be string without null bytes, not str" - */ - char *value; - if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) { - return NULL; - } - - if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) { - return NULL; - } - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - static PyObject * gh_99240_clear_args(PyObject *self, PyObject *args) { @@ -819,6 +684,7 @@ static PyMethodDef test_methods[] = { {"getargs_s_star", getargs_s_star, METH_VARARGS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_w_star", getargs_w_star, METH_VARARGS}, + {"getargs_empty", _PyCFunction_CAST(getargs_empty), METH_VARARGS|METH_KEYWORDS}, {"getargs_y", getargs_y, METH_VARARGS}, {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, {"getargs_y_star", getargs_y_star, METH_VARARGS}, @@ -826,10 +692,6 @@ static PyMethodDef test_methods[] = { {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, {"getargs_z_star", getargs_z_star, METH_VARARGS}, {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, - {"test_L_code", test_L_code, METH_NOARGS}, - {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, - {"test_k_code", test_k_code, METH_NOARGS}, - {"test_s_code", test_s_code, METH_NOARGS}, {"gh_99240_clear_args", gh_99240_clear_args, METH_VARARGS}, {NULL}, }; diff --git a/Modules/_testcapi/hash.c b/Modules/_testcapi/hash.c new file mode 100644 index 00000000000000..aee76787dcddb3 --- /dev/null +++ b/Modules/_testcapi/hash.c @@ -0,0 +1,72 @@ +#include "parts.h" +#include "util.h" + +static PyObject * +hash_getfuncdef(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +{ + // bind PyHash_GetFuncDef() + PyHash_FuncDef *def = PyHash_GetFuncDef(); + + PyObject *types = PyImport_ImportModule("types"); + if (types == NULL) { + return NULL; + } + + PyObject *result = PyObject_CallMethod(types, "SimpleNamespace", NULL); + Py_DECREF(types); + if (result == NULL) { + return NULL; + } + + // ignore PyHash_FuncDef.hash + + PyObject *value = PyUnicode_FromString(def->name); + int res = PyObject_SetAttrString(result, "name", value); + Py_DECREF(value); + if (res < 0) { + return NULL; + } + + value = PyLong_FromLong(def->hash_bits); + res = PyObject_SetAttrString(result, "hash_bits", value); + Py_DECREF(value); + if (res < 0) { + return NULL; + } + + value = PyLong_FromLong(def->seed_bits); + res = PyObject_SetAttrString(result, "seed_bits", value); + Py_DECREF(value); + if (res < 0) { + return NULL; + } + + return result; +} + + +static PyObject * +hash_pointer(PyObject *Py_UNUSED(module), PyObject *arg) +{ + void *ptr = PyLong_AsVoidPtr(arg); + if (ptr == NULL && PyErr_Occurred()) { + return NULL; + } + + Py_hash_t hash = Py_HashPointer(ptr); + Py_BUILD_ASSERT(sizeof(long long) >= sizeof(hash)); + return PyLong_FromLongLong(hash); +} + + +static PyMethodDef test_methods[] = { + {"hash_getfuncdef", hash_getfuncdef, METH_NOARGS}, + {"hash_pointer", hash_pointer, METH_O}, + {NULL}, +}; + +int +_PyTestCapi_Init_Hash(PyObject *m) +{ + return PyModule_AddFunctions(m, test_methods); +} diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c index d14a1763184207..4526583a8059d9 100644 --- a/Modules/_testcapi/heaptype.c +++ b/Modules/_testcapi/heaptype.c @@ -805,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; } @@ -819,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); diff --git a/Modules/_testcapi/heaptype_relative.c b/Modules/_testcapi/heaptype_relative.c index 53dd01d1ed4f80..52bda75736b316 100644 --- a/Modules/_testcapi/heaptype_relative.c +++ b/Modules/_testcapi/heaptype_relative.c @@ -1,4 +1,9 @@ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED #define Py_LIMITED_API 0x030c0000 // 3.12 +#endif + #include "parts.h" #include // max_align_t #include // memset diff --git a/Modules/_testcapi/list.c b/Modules/_testcapi/list.c new file mode 100644 index 00000000000000..10e18699f01bc1 --- /dev/null +++ b/Modules/_testcapi/list.c @@ -0,0 +1,216 @@ +#include "parts.h" +#include "util.h" + +static PyObject * +list_check(PyObject* Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyList_Check(obj)); +} + +static PyObject * +list_check_exact(PyObject* Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyList_CheckExact(obj)); +} + +static PyObject * +list_new(PyObject* Py_UNUSED(module), PyObject *obj) +{ + return PyList_New(PyLong_AsSsize_t(obj)); +} + +static PyObject * +list_size(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyList_Size(obj)); +} + +static PyObject * +list_get_size(PyObject *Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyList_GET_SIZE(obj)); +} + +static PyObject * +list_getitem(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "On", &obj, &i)) { + return NULL; + } + NULLABLE(obj); + return Py_XNewRef(PyList_GetItem(obj, i)); +} + +static PyObject * +list_get_item(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "On", &obj, &i)) { + return NULL; + } + NULLABLE(obj); + return Py_XNewRef(PyList_GET_ITEM(obj, i)); +} + +static PyObject * +list_setitem(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj, *value; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "OnO", &obj, &i, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + RETURN_INT(PyList_SetItem(obj, i, Py_XNewRef(value))); + +} + +static PyObject * +list_set_item(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj, *value; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "OnO", &obj, &i, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + PyList_SET_ITEM(obj, i, Py_XNewRef(value)); + Py_RETURN_NONE; + +} + +static PyObject * +list_insert(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj, *value; + Py_ssize_t where; + if (!PyArg_ParseTuple(args, "OnO", &obj, &where, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + RETURN_INT(PyList_Insert(obj, where, Py_XNewRef(value))); + +} + +static PyObject * +list_append(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj, *value; + if (!PyArg_ParseTuple(args, "OO", &obj, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + RETURN_INT(PyList_Append(obj, value)); +} + +static PyObject * +list_getslice(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj; + Py_ssize_t ilow, ihigh; + if (!PyArg_ParseTuple(args, "Onn", &obj, &ilow, &ihigh)) { + return NULL; + } + NULLABLE(obj); + return PyList_GetSlice(obj, ilow, ihigh); + +} + +static PyObject * +list_setslice(PyObject *Py_UNUSED(module), PyObject *args) +{ + PyObject *obj, *value; + Py_ssize_t ilow, ihigh; + if (!PyArg_ParseTuple(args, "OnnO", &obj, &ilow, &ihigh, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + RETURN_INT(PyList_SetSlice(obj, ilow, ihigh, value)); +} + +static PyObject * +list_sort(PyObject* Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyList_Sort(obj)); +} + +static PyObject * +list_reverse(PyObject* Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyList_Reverse(obj)); +} + +static PyObject * +list_astuple(PyObject* Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + return PyList_AsTuple(obj); +} + + +static PyObject * +list_clear(PyObject* Py_UNUSED(module), PyObject *obj) +{ + NULLABLE(obj); + RETURN_INT(PyList_Clear(obj)); +} + + +static PyObject * +list_extend(PyObject* Py_UNUSED(module), PyObject *args) +{ + PyObject *obj, *arg; + if (!PyArg_ParseTuple(args, "OO", &obj, &arg)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(arg); + RETURN_INT(PyList_Extend(obj, arg)); +} + + +static PyMethodDef test_methods[] = { + {"list_check", list_check, METH_O}, + {"list_check_exact", list_check_exact, METH_O}, + {"list_new", list_new, METH_O}, + {"list_size", list_size, METH_O}, + {"list_get_size", list_get_size, METH_O}, + {"list_getitem", list_getitem, METH_VARARGS}, + {"list_get_item", list_get_item, METH_VARARGS}, + {"list_setitem", list_setitem, METH_VARARGS}, + {"list_set_item", list_set_item, METH_VARARGS}, + {"list_insert", list_insert, METH_VARARGS}, + {"list_append", list_append, METH_VARARGS}, + {"list_getslice", list_getslice, METH_VARARGS}, + {"list_setslice", list_setslice, METH_VARARGS}, + {"list_sort", list_sort, METH_O}, + {"list_reverse", list_reverse, METH_O}, + {"list_astuple", list_astuple, METH_O}, + {"list_clear", list_clear, METH_O}, + {"list_extend", list_extend, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_List(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/long.c b/Modules/_testcapi/long.c index 4362f431fc3f4d..32ad8d32ab8523 100644 --- a/Modules/_testcapi/long.c +++ b/Modules/_testcapi/long.c @@ -3,6 +3,7 @@ #endif #include "parts.h" +#include "util.h" #include "clinic/long.c.h" /*[clinic input] @@ -554,6 +555,69 @@ _testcapi_call_long_compact_api(PyObject *module, PyObject *arg) return Py_BuildValue("in", is_compact, value); } +static PyObject * +pylong_check(PyObject *module, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyLong_Check(obj)); +} + +static PyObject * +pylong_checkexact(PyObject *module, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyLong_CheckExact(obj)); +} + +static PyObject * +pylong_fromdouble(PyObject *module, PyObject *arg) +{ + double value; + if (!PyArg_Parse(arg, "d", &value)) { + return NULL; + } + return PyLong_FromDouble(value); +} + +static PyObject * +pylong_fromstring(PyObject *module, PyObject *args) +{ + const char *str; + Py_ssize_t len; + int base; + char *end = UNINITIALIZED_PTR; + if (!PyArg_ParseTuple(args, "z#i", &str, &len, &base)) { + return NULL; + } + + PyObject *result = PyLong_FromString(str, &end, base); + if (result == NULL) { + // XXX 'end' is not always set. + return NULL; + } + return Py_BuildValue("Nn", result, (Py_ssize_t)(end - str)); +} + +static PyObject * +pylong_fromunicodeobject(PyObject *module, PyObject *args) +{ + PyObject *unicode; + int base; + if (!PyArg_ParseTuple(args, "Oi", &unicode, &base)) { + return NULL; + } + + NULLABLE(unicode); + return PyLong_FromUnicodeObject(unicode, base); +} + +static PyObject * +pylong_fromvoidptr(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + return PyLong_FromVoidPtr((void *)arg); +} + /*[clinic input] _testcapi.PyLong_AsInt arg: object @@ -564,6 +628,7 @@ static PyObject * _testcapi_PyLong_AsInt(PyObject *module, PyObject *arg) /*[clinic end generated code: output=0df9f19de5fa575b input=9561b97105493a67]*/ { + NULLABLE(arg); assert(!PyErr_Occurred()); int value = PyLong_AsInt(arg); if (value == -1 && PyErr_Occurred()) { @@ -572,6 +637,145 @@ _testcapi_PyLong_AsInt(PyObject *module, PyObject *arg) return PyLong_FromLong(value); } +static PyObject * +pylong_aslong(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + long value = PyLong_AsLong(arg); + if (value == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(value); +} + +static PyObject * +pylong_aslongandoverflow(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + int overflow = UNINITIALIZED_INT; + long value = PyLong_AsLongAndOverflow(arg, &overflow); + if (value == -1 && PyErr_Occurred()) { + assert(overflow == -1); + return NULL; + } + return Py_BuildValue("li", value, overflow); +} + +static PyObject * +pylong_asunsignedlong(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + unsigned long value = PyLong_AsUnsignedLong(arg); + if (value == (unsigned long)-1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromUnsignedLong(value); +} + +static PyObject * +pylong_asunsignedlongmask(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + unsigned long value = PyLong_AsUnsignedLongMask(arg); + if (value == (unsigned long)-1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromUnsignedLong(value); +} + +static PyObject * +pylong_aslonglong(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + long long value = PyLong_AsLongLong(arg); + if (value == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLongLong(value); +} + +static PyObject * +pylong_aslonglongandoverflow(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + int overflow = UNINITIALIZED_INT; + long long value = PyLong_AsLongLongAndOverflow(arg, &overflow); + if (value == -1 && PyErr_Occurred()) { + assert(overflow == -1); + return NULL; + } + return Py_BuildValue("Li", value, overflow); +} + +static PyObject * +pylong_asunsignedlonglong(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + unsigned long long value = PyLong_AsUnsignedLongLong(arg); + if (value == (unsigned long long)-1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromUnsignedLongLong(value); +} + +static PyObject * +pylong_asunsignedlonglongmask(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + unsigned long long value = PyLong_AsUnsignedLongLongMask(arg); + if (value == (unsigned long long)-1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromUnsignedLongLong(value); +} + +static PyObject * +pylong_as_ssize_t(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + Py_ssize_t value = PyLong_AsSsize_t(arg); + if (value == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromSsize_t(value); +} + +static PyObject * +pylong_as_size_t(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + size_t value = PyLong_AsSize_t(arg); + if (value == (size_t)-1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromSize_t(value); +} + +static PyObject * +pylong_asdouble(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + double value = PyLong_AsDouble(arg); + if (value == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(value); +} + +static PyObject * +pylong_asvoidptr(PyObject *module, PyObject *arg) +{ + NULLABLE(arg); + void *value = PyLong_AsVoidPtr(arg); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; + } + return Py_NewRef((PyObject *)value); +} + static PyMethodDef test_methods[] = { _TESTCAPI_TEST_LONG_AND_OVERFLOW_METHODDEF _TESTCAPI_TEST_LONG_API_METHODDEF @@ -581,7 +785,25 @@ static PyMethodDef test_methods[] = { _TESTCAPI_TEST_LONG_LONG_AND_OVERFLOW_METHODDEF _TESTCAPI_TEST_LONGLONG_API_METHODDEF _TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF + {"pylong_check", pylong_check, METH_O}, + {"pylong_checkexact", pylong_checkexact, METH_O}, + {"pylong_fromdouble", pylong_fromdouble, METH_O}, + {"pylong_fromstring", pylong_fromstring, METH_VARARGS}, + {"pylong_fromunicodeobject", pylong_fromunicodeobject, METH_VARARGS}, + {"pylong_fromvoidptr", pylong_fromvoidptr, METH_O}, _TESTCAPI_PYLONG_ASINT_METHODDEF + {"pylong_aslong", pylong_aslong, METH_O}, + {"pylong_aslongandoverflow", pylong_aslongandoverflow, METH_O}, + {"pylong_asunsignedlong", pylong_asunsignedlong, METH_O}, + {"pylong_asunsignedlongmask", pylong_asunsignedlongmask, METH_O}, + {"pylong_aslonglong", pylong_aslonglong, METH_O}, + {"pylong_aslonglongandoverflow", pylong_aslonglongandoverflow, METH_O}, + {"pylong_asunsignedlonglong", pylong_asunsignedlonglong, METH_O}, + {"pylong_asunsignedlonglongmask", pylong_asunsignedlonglongmask, METH_O}, + {"pylong_as_ssize_t", pylong_as_ssize_t, METH_O}, + {"pylong_as_size_t", pylong_as_size_t, METH_O}, + {"pylong_asdouble", pylong_asdouble, METH_O}, + {"pylong_asvoidptr", pylong_asvoidptr, METH_O}, {NULL}, }; diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c index ef9234d7f8955f..ab4ad934644c38 100644 --- a/Modules/_testcapi/mem.c +++ b/Modules/_testcapi/mem.c @@ -613,5 +613,14 @@ _PyTestCapi_Init_Mem(PyObject *mod) return -1; } +#ifdef WITH_MIMALLOC + v = Py_True; +#else + v = Py_False; +#endif + if (PyModule_AddObjectRef(mod, "WITH_MIMALLOC", v) < 0) { + return -1; + } + return 0; } diff --git a/Modules/_testcapi/numbers.c b/Modules/_testcapi/numbers.c new file mode 100644 index 00000000000000..6f7fa3fa7a4186 --- /dev/null +++ b/Modules/_testcapi/numbers.c @@ -0,0 +1,16 @@ +#include "parts.h" +#include "util.h" + +static PyMethodDef test_methods[] = { + {NULL}, +}; + +int +_PyTestCapi_Init_Numbers(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h index 24abe54814e611..29817edd69b134 100644 --- a/Modules/_testcapi/parts.h +++ b/Modules/_testcapi/parts.h @@ -4,27 +4,35 @@ // Always enable assertions #undef NDEBUG -// 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 +#ifdef PYTESTCAPI_NEED_INTERNAL_API +# ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +# endif +#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 +#endif #include "Python.h" -#ifdef Py_BUILD_CORE +#if defined(Py_BUILD_CORE) && !defined(PYTESTCAPI_NEED_INTERNAL_API) # 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_ByteArray(PyObject *module); +int _PyTestCapi_Init_Bytes(PyObject *module); int _PyTestCapi_Init_Unicode(PyObject *module); int _PyTestCapi_Init_GetArgs(PyObject *module); int _PyTestCapi_Init_DateTime(PyObject *module); @@ -33,15 +41,24 @@ 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_Complex(PyObject *module); +int _PyTestCapi_Init_Numbers(PyObject *module); int _PyTestCapi_Init_Dict(PyObject *module); +int _PyTestCapi_Init_Set(PyObject *module); +int _PyTestCapi_Init_List(PyObject *module); +int _PyTestCapi_Init_Tuple(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_File(PyObject *module); +int _PyTestCapi_Init_Codec(PyObject *module); int _PyTestCapi_Init_Immortal(PyObject *module); -int _PyTestCapi_Init_GC(PyObject *mod); +int _PyTestCapi_Init_GC(PyObject *module); +int _PyTestCapi_Init_Sys(PyObject *module); +int _PyTestCapi_Init_Hash(PyObject *module); int _PyTestCapi_Init_VectorcallLimited(PyObject *module); int _PyTestCapi_Init_HeaptypeRelative(PyObject *module); diff --git a/Modules/_testcapi/pyatomic.c b/Modules/_testcapi/pyatomic.c index 5aedf687705707..4f72844535ebd6 100644 --- a/Modules/_testcapi/pyatomic.c +++ b/Modules/_testcapi/pyatomic.c @@ -140,6 +140,21 @@ test_atomic_release_acquire(PyObject *self, PyObject *obj) { Py_RETURN_NONE; } +static PyObject * +test_atomic_load_store_int_release_acquire(PyObject *self, PyObject *obj) { \ + int x = 0; + int y = 1; + int z = 2; + assert(_Py_atomic_load_int_acquire(&x) == 0); + _Py_atomic_store_int_release(&x, y); + assert(x == y); + assert(_Py_atomic_load_int_acquire(&x) == y); + _Py_atomic_store_int_release(&x, z); + assert(x == z); + assert(_Py_atomic_load_int_acquire(&x) == z); + Py_RETURN_NONE; +} + // NOTE: all tests should start with "test_atomic_" to be included // in test_pyatomic.py @@ -162,6 +177,7 @@ static PyMethodDef test_methods[] = { 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}, + {"test_atomic_load_store_int_release_acquire", test_atomic_load_store_int_release_acquire, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; 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/sys.c b/Modules/_testcapi/sys.c new file mode 100644 index 00000000000000..aa40e3cd5b9b29 --- /dev/null +++ b/Modules/_testcapi/sys.c @@ -0,0 +1,56 @@ +#include "parts.h" +#include "util.h" + + +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 PyObject * +sys_getxoptions(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(ignored)) +{ + PyObject *result = PySys_GetXOptions(); + return Py_XNewRef(result); +} + + +static PyMethodDef test_methods[] = { + {"sys_getobject", sys_getobject, METH_O}, + {"sys_setobject", sys_setobject, METH_VARARGS}, + {"sys_getxoptions", sys_getxoptions, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Sys(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/tuple.c b/Modules/_testcapi/tuple.c new file mode 100644 index 00000000000000..95dde8c0edadbe --- /dev/null +++ b/Modules/_testcapi/tuple.c @@ -0,0 +1,17 @@ +#include "parts.h" +#include "util.h" + + +static PyMethodDef test_methods[] = { + {NULL}, +}; + +int +_PyTestCapi_Init_Tuple(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0){ + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c index 232b2ad543fca0..a10183dddeca98 100644 --- a/Modules/_testcapi/unicode.c +++ b/Modules/_testcapi/unicode.c @@ -634,7 +634,7 @@ unicode_asutf8andsize(PyObject *self, PyObject *args) NULLABLE(unicode); s = PyUnicode_AsUTF8AndSize(unicode, &size); if (s == NULL) { - assert(size == UNINITIALIZED_SIZE); + assert(size == -1); return NULL; } @@ -1429,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) @@ -2044,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/vectorcall.c b/Modules/_testcapi/vectorcall.c index 2b5110fcba2c91..b30c5e8704c8af 100644 --- a/Modules/_testcapi/vectorcall.c +++ b/Modules/_testcapi/vectorcall.c @@ -1,3 +1,6 @@ +// clinic/vectorcall.c.h uses internal pycore_modsupport.h API +#define PYTESTCAPI_NEED_INTERNAL_API + #include "parts.h" #include "clinic/vectorcall.c.h" diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c index 3e81903098f954..d7b8d33b7f7162 100644 --- a/Modules/_testcapi/vectorcall_limited.c +++ b/Modules/_testcapi/vectorcall_limited.c @@ -1,6 +1,11 @@ /* Test Vectorcall in the limited API */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED #define Py_LIMITED_API 0x030c0000 // 3.12 +#endif + #include "parts.h" #include "clinic/vectorcall_limited.c.h" diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c index 8a264bba4ed6ed..a763ff46a3c290 100644 --- a/Modules/_testcapi/watchers.c +++ b/Modules/_testcapi/watchers.c @@ -1,3 +1,6 @@ +// clinic/watchers.c.h uses internal pycore_modsupport.h API +#define PYTESTCAPI_NEED_INTERNAL_API + #include "parts.h" #include "clinic/watchers.c.h" diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index e09fd8806d2f64..b3ddfae58e6fc0 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -13,6 +13,7 @@ #include "_testcapi/parts.h" #include "frameobject.h" // PyFrame_New() +#include "interpreteridobject.h" // PyInterpreterID_Type #include "marshal.h" // PyMarshal_WriteLongToFile() #include // FLT_MAX @@ -386,6 +387,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) { @@ -534,6 +570,12 @@ static PyType_Spec HeapTypeNameType_Spec = { .slots = HeapTypeNameType_slots, }; +static PyObject * +get_heaptype_for_name(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyType_FromSpec(&HeapTypeNameType_Spec); +} + static PyObject * test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1410,56 +1452,34 @@ run_in_subinterp(PyObject *self, PyObject *args) return PyLong_FromLong(r); } -static void -_xid_capsule_destructor(PyObject *capsule) +static PyObject * +get_interpreterid_type(PyObject *self, PyObject *Py_UNUSED(ignored)) { - _PyCrossInterpreterData *data = \ - (_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL); - if (data != NULL) { - assert(_PyCrossInterpreterData_Release(data) == 0); - PyMem_Free(data); - } + return Py_NewRef(&PyInterpreterID_Type); } static PyObject * -get_crossinterp_data(PyObject *self, PyObject *args) +link_interpreter_refcount(PyObject *self, PyObject *idobj) { - PyObject *obj = NULL; - if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) { - return NULL; - } - - _PyCrossInterpreterData *data = PyMem_NEW(_PyCrossInterpreterData, 1); - if (data == NULL) { - PyErr_NoMemory(); - return NULL; - } - if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { - PyMem_Free(data); + PyInterpreterState *interp = PyInterpreterID_LookUp(idobj); + if (interp == NULL) { + assert(PyErr_Occurred()); return NULL; } - PyObject *capsule = PyCapsule_New(data, NULL, _xid_capsule_destructor); - if (capsule == NULL) { - assert(_PyCrossInterpreterData_Release(data) == 0); - PyMem_Free(data); - } - return capsule; + _PyInterpreterState_RequireIDRef(interp, 1); + Py_RETURN_NONE; } static PyObject * -restore_crossinterp_data(PyObject *self, PyObject *args) +unlink_interpreter_refcount(PyObject *self, PyObject *idobj) { - PyObject *capsule = NULL; - if (!PyArg_ParseTuple(args, "O:restore_crossinterp_data", &capsule)) { - return NULL; - } - - _PyCrossInterpreterData *data = \ - (_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL); - if (data == NULL) { + PyInterpreterState *interp = PyInterpreterID_LookUp(idobj); + if (interp == NULL) { + assert(PyErr_Occurred()); return NULL; } - return _PyCrossInterpreterData_NewObject(data); + _PyInterpreterState_RequireIDRef(interp, 0); + Py_RETURN_NONE; } static PyMethodDef ml; @@ -1988,10 +2008,10 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args) return repr(self) */ static PyObject* -bad_get(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +bad_get(PyObject *module, PyObject *args) { PyObject *self, *obj, *cls; - if (!_PyArg_UnpackStack(args, nargs, "bad_get", 3, 3, &self, &obj, &cls)) { + if (!PyArg_ParseTuple(args, "OOO", &self, &obj, &cls)) { return NULL; } @@ -2458,8 +2478,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() @@ -2923,7 +2943,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; } @@ -3196,35 +3216,6 @@ 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}, @@ -3252,8 +3243,11 @@ 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}, + {"get_heaptype_for_name", get_heaptype_for_name, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS}, {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, {"test_get_type_dict", test_get_type_dict, METH_NOARGS}, @@ -3274,8 +3268,9 @@ 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}, - {"get_crossinterp_data", get_crossinterp_data, METH_VARARGS}, - {"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS}, + {"get_interpreterid_type", get_interpreterid_type, METH_NOARGS}, + {"link_interpreter_refcount", link_interpreter_refcount, METH_O}, + {"unlink_interpreter_refcount", unlink_interpreter_refcount, METH_O}, {"create_cfunction", create_cfunction, METH_NOARGS}, {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS, PyDoc_STR("set_error_class(error_class) -> None")}, @@ -3303,7 +3298,7 @@ static PyMethodDef TestMethods[] = { {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, #endif {"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS}, - {"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL}, + {"bad_get", bad_get, METH_VARARGS}, #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, {"decref_freed_object", decref_freed_object, METH_NOARGS}, @@ -3355,8 +3350,6 @@ 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 */ }; @@ -3923,7 +3916,9 @@ PyInit__testcapi(void) PyModule_AddObject(m, "ULLONG_MAX", PyLong_FromUnsignedLongLong(ULLONG_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN)); + PyModule_AddObject(m, "SIZE_MAX", PyLong_FromSize_t(SIZE_MAX)); PyModule_AddObject(m, "SIZEOF_WCHAR_T", PyLong_FromSsize_t(sizeof(wchar_t))); + PyModule_AddObject(m, "SIZEOF_VOID_P", PyLong_FromSsize_t(sizeof(void*))); PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))); PyModule_AddObject(m, "Py_Version", PyLong_FromUnsignedLong(Py_Version)); Py_INCREF(&PyInstanceMethod_Type); @@ -3954,6 +3949,12 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Abstract(m) < 0) { return NULL; } + if (_PyTestCapi_Init_ByteArray(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Bytes(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Unicode(m) < 0) { return NULL; } @@ -3978,9 +3979,24 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_Float(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Complex(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Numbers(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Dict(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Set(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_List(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Tuple(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Structmember(m) < 0) { return NULL; } @@ -3996,6 +4012,15 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_PyOS(m) < 0) { return NULL; } + if (_PyTestCapi_Init_File(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Codec(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Sys(m) < 0) { + return NULL; + } if (_PyTestCapi_Init_Immortal(m) < 0) { return NULL; } @@ -4011,6 +4036,9 @@ PyInit__testcapi(void) if (_PyTestCapi_Init_HeaptypeRelative(m) < 0) { return NULL; } + if (_PyTestCapi_Init_Hash(m) < 0) { + return NULL; + } PyState_AddModule(m, &_testcapimodule); return m; diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index 2e0535d52641e0..15e0093f15ba1e 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -1128,6 +1128,26 @@ gh_99240_double_free_impl(PyObject *module, char *a, char *b) Py_RETURN_NONE; } +/*[clinic input] +null_or_tuple_for_varargs + + name: object + *constraints: object + covariant: bool = False + +See /~https://github.com/python/cpython/issues/110864 +[clinic start generated code]*/ + +static PyObject * +null_or_tuple_for_varargs_impl(PyObject *module, PyObject *name, + PyObject *constraints, int covariant) +/*[clinic end generated code: output=a785b35421358983 input=c9bce186637956b3]*/ +{ + assert(name != NULL); + assert(constraints != NULL); + PyObject *c = covariant ? Py_True : Py_False; + return pack_arguments_newref(3, name, constraints, c); +} /*[clinic input] _testclinic.clone_f1 as clone_f1 @@ -1843,6 +1863,7 @@ static PyMethodDef tester_methods[] = { GH_32092_KW_PASS_METHODDEF GH_99233_REFCOUNT_METHODDEF GH_99240_DOUBLE_FREE_METHODDEF + NULL_OR_TUPLE_FOR_VARARGS_METHODDEF CLONE_F1_METHODDEF CLONE_F2_METHODDEF CLONE_WITH_CONV_F1_METHODDEF diff --git a/Modules/_testclinic_limited.c b/Modules/_testclinic_limited.c index 4273383816a0dd..ef595be0b626db 100644 --- a/Modules/_testclinic_limited.c +++ b/Modules/_testclinic_limited.c @@ -4,8 +4,12 @@ #undef Py_BUILD_CORE_MODULE #undef Py_BUILD_CORE_BUILTIN +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED // For now, only limited C API 3.13 is supported #define Py_LIMITED_API 0x030d0000 +#endif /* Always enable assertions */ #undef NDEBUG diff --git a/Modules/_testimportmultiple.c b/Modules/_testimportmultiple.c index 1caeb66eb8c858..7e6556ad400cde 100644 --- a/Modules/_testimportmultiple.c +++ b/Modules/_testimportmultiple.c @@ -3,7 +3,14 @@ * file (issue16421). This file defines 3 modules (_testimportmodule, * foo, bar), only the first one is called the same as the compiled file. */ -#include + +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +#define Py_LIMITED_API 0x03020000 +#endif + +#include static struct PyModuleDef _testimportmultiple = { PyModuleDef_HEAD_INIT, @@ -54,4 +61,3 @@ static struct PyModuleDef _barmodule = { PyMODINIT_FUNC PyInit__testimportmultiple_bar(void){ return PyModule_Create(&_barmodule); } - diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index c6b80fffdec16d..7d277df164d3ec 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -27,6 +27,7 @@ #include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_typeobject.h" // _PyType_GetModuleName() #include "interpreteridobject.h" // PyInterpreterID_LookUp() @@ -109,6 +110,14 @@ get_recursion_depth(PyObject *self, PyObject *Py_UNUSED(args)) } +static PyObject* +get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return PyLong_FromLong(tstate->c_recursion_remaining); +} + + static PyObject* test_bswap(PyObject *self, PyObject *Py_UNUSED(args)) { @@ -675,7 +684,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); } @@ -998,6 +1011,32 @@ get_executor(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return (PyObject *)PyUnstable_GetExecutor((PyCodeObject *)code, ioffset); } +static PyObject * +add_executor_dependency(PyObject *self, PyObject *args) +{ + PyObject *exec; + PyObject *obj; + if (!PyArg_ParseTuple(args, "OO", &exec, &obj)) { + return NULL; + } + /* No way to tell in general if exec is an executor, so we only accept + * counting_executor */ + if (strcmp(Py_TYPE(exec)->tp_name, "counting_executor")) { + PyErr_SetString(PyExc_TypeError, "argument must be a counting_executor"); + return NULL; + } + _Py_Executor_DependsOn((_PyExecutorObject *)exec, obj); + Py_RETURN_NONE; +} + +static PyObject * +invalidate_executors(PyObject *self, PyObject *obj) +{ + PyInterpreterState *interp = PyInterpreterState_Get(); + _Py_Executors_InvalidateDependency(interp, obj); + Py_RETURN_NONE; +} + static int _pending_callback(void *arg) { /* we assume the argument is callable object to which we own a reference */ @@ -1436,34 +1475,66 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) } -/*[clinic input] -_testinternalcapi.write_unraisable_exc - exception as exc: object - err_msg: object - obj: object - / -[clinic start generated code]*/ +static PyObject * +get_interpreter_refcount(PyObject *self, PyObject *idobj) +{ + PyInterpreterState *interp = PyInterpreterID_LookUp(idobj); + if (interp == NULL) { + return NULL; + } + return PyLong_FromLongLong(interp->id_refcount); +} + + +static void +_xid_capsule_destructor(PyObject *capsule) +{ + _PyCrossInterpreterData *data = \ + (_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL); + if (data != NULL) { + assert(_PyCrossInterpreterData_Release(data) == 0); + _PyCrossInterpreterData_Free(data); + } +} static PyObject * -_testinternalcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, - PyObject *err_msg, PyObject *obj) -/*[clinic end generated code: output=a0f063cdd04aad83 input=274381b1a3fa5cd6]*/ +get_crossinterp_data(PyObject *self, PyObject *args) { + PyObject *obj = NULL; + if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) { + return NULL; + } - const char *err_msg_utf8; - if (err_msg != Py_None) { - err_msg_utf8 = PyUnicode_AsUTF8(err_msg); - if (err_msg_utf8 == NULL) { - return NULL; - } + _PyCrossInterpreterData *data = _PyCrossInterpreterData_New(); + if (data == NULL) { + return NULL; } - else { - err_msg_utf8 = NULL; + if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { + _PyCrossInterpreterData_Free(data); + return NULL; + } + PyObject *capsule = PyCapsule_New(data, NULL, _xid_capsule_destructor); + if (capsule == NULL) { + assert(_PyCrossInterpreterData_Release(data) == 0); + _PyCrossInterpreterData_Free(data); } + return capsule; +} - PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); - _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); - Py_RETURN_NONE; +static PyObject * +restore_crossinterp_data(PyObject *self, PyObject *args) +{ + PyObject *capsule = NULL; + if (!PyArg_ParseTuple(args, "O:restore_crossinterp_data", &capsule)) { + return NULL; + } + + _PyCrossInterpreterData *data = \ + (_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL); + if (data == NULL) { + return NULL; + } + return _PyCrossInterpreterData_NewObject(data); } @@ -1526,10 +1597,60 @@ _testinternalcapi_test_long_numbits_impl(PyObject *module) Py_RETURN_NONE; } +static PyObject * +compile_perf_trampoline_entry(PyObject *self, PyObject *args) +{ + PyObject *co; + if (!PyArg_ParseTuple(args, "O!", &PyCode_Type, &co)) { + return NULL; + } + int ret = PyUnstable_PerfTrampoline_CompileCode((PyCodeObject *)co); + if (ret != 0) { + PyErr_SetString(PyExc_AssertionError, "Failed to compile trampoline"); + return NULL; + } + return PyLong_FromLong(ret); +} + +static PyObject * +perf_trampoline_set_persist_after_fork(PyObject *self, PyObject *args) +{ + int enable; + if (!PyArg_ParseTuple(args, "i", &enable)) { + return NULL; + } + int ret = PyUnstable_PerfTrampoline_SetPersistAfterFork(enable); + if (ret == 0) { + PyErr_SetString(PyExc_AssertionError, "Failed to set persist_after_fork"); + return NULL; + } + return PyLong_FromLong(ret); +} + + +static PyObject * +get_type_module_name(PyObject *self, PyObject *type) +{ + assert(PyType_Check(type)); + return _PyType_GetModuleName((PyTypeObject *)type); +} + + +#ifdef Py_GIL_DISABLED +static PyObject * +get_py_thread_id(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + uintptr_t tid = _Py_ThreadId(); + Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(tid)); + return PyLong_FromUnsignedLongLong(tid); +} +#endif + static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, + {"get_c_recursion_remaining", get_c_recursion_remaining, METH_NOARGS}, {"test_bswap", test_bswap, METH_NOARGS}, {"test_popcount", test_popcount, METH_NOARGS}, {"test_bit_length", test_bit_length, METH_NOARGS}, @@ -1561,6 +1682,8 @@ static PyMethodDef module_functions[] = { {"get_executor", _PyCFunction_CAST(get_executor), METH_FASTCALL, NULL}, {"get_counter_optimizer", get_counter_optimizer, METH_NOARGS, NULL}, {"get_uop_optimizer", get_uop_optimizer, METH_NOARGS, NULL}, + {"add_executor_dependency", add_executor_dependency, METH_VARARGS, NULL}, + {"invalidate_executors", invalidate_executors, METH_O, NULL}, {"pending_threadfunc", _PyCFunction_CAST(pending_threadfunc), METH_VARARGS | METH_KEYWORDS}, {"pending_identify", pending_identify, METH_VARARGS, NULL}, @@ -1581,8 +1704,16 @@ static PyMethodDef module_functions[] = { {"run_in_subinterp_with_config", _PyCFunction_CAST(run_in_subinterp_with_config), METH_VARARGS | METH_KEYWORDS}, - _TESTINTERNALCAPI_WRITE_UNRAISABLE_EXC_METHODDEF + {"get_interpreter_refcount", get_interpreter_refcount, METH_O}, + {"compile_perf_trampoline_entry", compile_perf_trampoline_entry, METH_VARARGS}, + {"perf_trampoline_set_persist_after_fork", perf_trampoline_set_persist_after_fork, METH_VARARGS}, + {"get_crossinterp_data", get_crossinterp_data, METH_VARARGS}, + {"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS}, _TESTINTERNALCAPI_TEST_LONG_NUMBITS_METHODDEF + {"get_type_module_name", get_type_module_name, METH_O}, +#ifdef Py_GIL_DISABLED + {"py_thread_id", get_py_thread_id, METH_NOARGS}, +#endif {NULL, NULL} /* sentinel */ }; @@ -1598,6 +1729,12 @@ module_exec(PyObject *module) if (_PyTestInternalCapi_Init_PyTime(module) < 0) { return 1; } + if (_PyTestInternalCapi_Init_Set(module) < 0) { + return 1; + } + if (_PyTestInternalCapi_Init_CriticalSection(module) < 0) { + return 1; + } if (PyModule_Add(module, "SIZEOF_PYGC_HEAD", PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { diff --git a/Modules/_testinternalcapi/clinic/test_lock.c.h b/Modules/_testinternalcapi/clinic/test_lock.c.h index 3cbe5ef12c5fa6..86875767343cd2 100644 --- a/Modules/_testinternalcapi/clinic/test_lock.c.h +++ b/Modules/_testinternalcapi/clinic/test_lock.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_testinternalcapi_benchmark_locks__doc__, "benchmark_locks($module, num_threads, use_pymutex=True,\n" @@ -71,4 +72,4 @@ _testinternalcapi_benchmark_locks(PyObject *module, PyObject *const *args, Py_ss exit: return return_value; } -/*[clinic end generated code: output=97c85dff601fed4b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=105105d759c0c271 input=a9049054013a1b77]*/ diff --git a/Modules/_testinternalcapi/parts.h b/Modules/_testinternalcapi/parts.h index bbb8e62ddaf7a2..49a1395f499fc3 100644 --- a/Modules/_testinternalcapi/parts.h +++ b/Modules/_testinternalcapi/parts.h @@ -12,5 +12,7 @@ int _PyTestInternalCapi_Init_Lock(PyObject *module); int _PyTestInternalCapi_Init_PyTime(PyObject *module); +int _PyTestInternalCapi_Init_Set(PyObject *module); +int _PyTestInternalCapi_Init_CriticalSection(PyObject *module); #endif // Py_TESTINTERNALCAPI_PARTS_H 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_critical_sections.c b/Modules/_testinternalcapi/test_critical_sections.c new file mode 100644 index 00000000000000..1f7e311558b27c --- /dev/null +++ b/Modules/_testinternalcapi/test_critical_sections.c @@ -0,0 +1,217 @@ +/* + * C Extension module to test pycore_critical_section.h API. + */ + +#include "parts.h" + +#include "pycore_critical_section.h" + +#ifdef Py_GIL_DISABLED +#define assert_nogil assert +#define assert_gil(x) +#else +#define assert_gil assert +#define assert_nogil(x) +#endif + + +static PyObject * +test_critical_sections(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *d1 = PyDict_New(); + assert(d1 != NULL); + + PyObject *d2 = PyDict_New(); + assert(d2 != NULL); + + // Beginning a critical section should lock the associated object and + // push the critical section onto the thread's stack (in Py_GIL_DISABLED builds). + Py_BEGIN_CRITICAL_SECTION(d1); + assert_nogil(PyMutex_IsLocked(&d1->ob_mutex)); + assert_nogil(_PyCriticalSection_IsActive(PyThreadState_GET()->critical_section)); + assert_gil(PyThreadState_GET()->critical_section == 0); + Py_END_CRITICAL_SECTION(); + assert_nogil(!PyMutex_IsLocked(&d1->ob_mutex)); + + assert_nogil(!PyMutex_IsLocked(&d1->ob_mutex)); + assert_nogil(!PyMutex_IsLocked(&d2->ob_mutex)); + Py_BEGIN_CRITICAL_SECTION2(d1, d2); + assert_nogil(PyMutex_IsLocked(&d1->ob_mutex)); + assert_nogil(PyMutex_IsLocked(&d2->ob_mutex)); + Py_END_CRITICAL_SECTION2(); + assert_nogil(!PyMutex_IsLocked(&d1->ob_mutex)); + assert_nogil(!PyMutex_IsLocked(&d2->ob_mutex)); + + // Passing the same object twice should work (and not deadlock). + assert_nogil(!PyMutex_IsLocked(&d2->ob_mutex)); + Py_BEGIN_CRITICAL_SECTION2(d2, d2); + assert_nogil(PyMutex_IsLocked(&d2->ob_mutex)); + Py_END_CRITICAL_SECTION2(); + assert_nogil(!PyMutex_IsLocked(&d2->ob_mutex)); + + Py_DECREF(d2); + Py_DECREF(d1); + Py_RETURN_NONE; +} + +static void +lock_unlock_object(PyObject *obj, int recurse_depth) +{ + Py_BEGIN_CRITICAL_SECTION(obj); + if (recurse_depth > 0) { + lock_unlock_object(obj, recurse_depth - 1); + } + Py_END_CRITICAL_SECTION(); +} + +static void +lock_unlock_two_objects(PyObject *a, PyObject *b, int recurse_depth) +{ + Py_BEGIN_CRITICAL_SECTION2(a, b); + if (recurse_depth > 0) { + lock_unlock_two_objects(a, b, recurse_depth - 1); + } + Py_END_CRITICAL_SECTION2(); +} + + +// Test that nested critical sections do not deadlock if they attempt to lock +// the same object. +static PyObject * +test_critical_sections_nest(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *a = PyDict_New(); + assert(a != NULL); + PyObject *b = PyDict_New(); + assert(b != NULL); + + // Locking an object recursively with this API should not deadlock. + assert_nogil(!PyMutex_IsLocked(&a->ob_mutex)); + Py_BEGIN_CRITICAL_SECTION(a); + assert_nogil(PyMutex_IsLocked(&a->ob_mutex)); + lock_unlock_object(a, 10); + assert_nogil(PyMutex_IsLocked(&a->ob_mutex)); + Py_END_CRITICAL_SECTION(); + assert_nogil(!PyMutex_IsLocked(&a->ob_mutex)); + + // Same test but with two objects. + Py_BEGIN_CRITICAL_SECTION2(b, a); + lock_unlock_two_objects(a, b, 10); + assert_nogil(PyMutex_IsLocked(&a->ob_mutex)); + assert_nogil(PyMutex_IsLocked(&b->ob_mutex)); + Py_END_CRITICAL_SECTION2(); + + Py_DECREF(b); + Py_DECREF(a); + Py_RETURN_NONE; +} + +// Test that a critical section is suspended by a Py_BEGIN_ALLOW_THREADS and +// resumed by a Py_END_ALLOW_THREADS. +static PyObject * +test_critical_sections_suspend(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *a = PyDict_New(); + assert(a != NULL); + + Py_BEGIN_CRITICAL_SECTION(a); + assert_nogil(PyMutex_IsLocked(&a->ob_mutex)); + + // Py_BEGIN_ALLOW_THREADS should suspend the active critical section + Py_BEGIN_ALLOW_THREADS + assert_nogil(!PyMutex_IsLocked(&a->ob_mutex)); + Py_END_ALLOW_THREADS; + + // After Py_END_ALLOW_THREADS the critical section should be resumed. + assert_nogil(PyMutex_IsLocked(&a->ob_mutex)); + Py_END_CRITICAL_SECTION(); + + Py_DECREF(a); + Py_RETURN_NONE; +} + +struct test_data { + PyObject *obj1; + PyObject *obj2; + PyObject *obj3; + Py_ssize_t countdown; + PyEvent done_event; +}; + +static void +thread_critical_sections(void *arg) +{ + const Py_ssize_t NUM_ITERS = 200; + struct test_data *test_data = arg; + PyGILState_STATE gil = PyGILState_Ensure(); + + for (Py_ssize_t i = 0; i < NUM_ITERS; i++) { + Py_BEGIN_CRITICAL_SECTION(test_data->obj1); + Py_END_CRITICAL_SECTION(); + + Py_BEGIN_CRITICAL_SECTION(test_data->obj2); + lock_unlock_object(test_data->obj1, 1); + Py_END_CRITICAL_SECTION(); + + Py_BEGIN_CRITICAL_SECTION2(test_data->obj3, test_data->obj1); + lock_unlock_object(test_data->obj2, 2); + Py_END_CRITICAL_SECTION2(); + + Py_BEGIN_CRITICAL_SECTION(test_data->obj3); + Py_BEGIN_ALLOW_THREADS + Py_END_ALLOW_THREADS + Py_END_CRITICAL_SECTION(); + } + + PyGILState_Release(gil); + if (_Py_atomic_add_ssize(&test_data->countdown, -1) == 1) { + // last thread to finish sets done_event + _PyEvent_Notify(&test_data->done_event); + } +} + +#ifdef Py_CAN_START_THREADS +static PyObject * +test_critical_sections_threads(PyObject *self, PyObject *Py_UNUSED(args)) +{ + const Py_ssize_t NUM_THREADS = 4; + struct test_data test_data = { + .obj1 = PyDict_New(), + .obj2 = PyDict_New(), + .obj3 = PyDict_New(), + .countdown = NUM_THREADS, + }; + assert(test_data.obj1 != NULL); + assert(test_data.obj2 != NULL); + assert(test_data.obj3 != NULL); + + for (int i = 0; i < NUM_THREADS; i++) { + PyThread_start_new_thread(&thread_critical_sections, &test_data); + } + PyEvent_Wait(&test_data.done_event); + + Py_DECREF(test_data.obj3); + Py_DECREF(test_data.obj2); + Py_DECREF(test_data.obj1); + Py_RETURN_NONE; +} +#endif + +static PyMethodDef test_methods[] = { + {"test_critical_sections", test_critical_sections, METH_NOARGS}, + {"test_critical_sections_nest", test_critical_sections_nest, METH_NOARGS}, + {"test_critical_sections_suspend", test_critical_sections_suspend, METH_NOARGS}, +#ifdef Py_CAN_START_THREADS + {"test_critical_sections_threads", test_critical_sections_threads, METH_NOARGS}, +#endif + {NULL, NULL} /* sentinel */ +}; + +int +_PyTestInternalCapi_Init_CriticalSection(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testinternalcapi/test_lock.c b/Modules/_testinternalcapi/test_lock.c index 33b49dacaa946e..418f71c1441995 100644 --- a/Modules/_testinternalcapi/test_lock.c +++ b/Modules/_testinternalcapi/test_lock.c @@ -75,10 +75,18 @@ test_lock_two_threads(PyObject *self, PyObject *obj) 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 + + // wait up to two seconds for the lock_thread to attempt to lock "m" + int iters = 0; + uint8_t v; + do { + pysleep(10); // allow some time for the other thread to try to lock + v = _Py_atomic_load_uint8_relaxed(&test_data.m.v); + assert(v == 1 || v == 3); + iters++; + } while (v != 3 && iters < 200); + + // both the "locked" and the "has parked" bits should be set assert(test_data.m.v == 3); PyMutex_Unlock(&test_data.m); @@ -333,6 +341,37 @@ test_lock_benchmark(PyObject *module, PyObject *obj) Py_RETURN_NONE; } +static int +init_maybe_fail(void *arg) +{ + int *counter = (int *)arg; + (*counter)++; + if (*counter < 5) { + // failure + return -1; + } + assert(*counter == 5); + return 0; +} + +static PyObject * +test_lock_once(PyObject *self, PyObject *obj) +{ + _PyOnceFlag once = {0}; + int counter = 0; + for (int i = 0; i < 10; i++) { + int res = _PyOnceFlag_CallOnce(&once, init_maybe_fail, &counter); + if (i < 4) { + assert(res == -1); + } + else { + assert(res == 0); + assert(counter == 5); + } + } + 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}, @@ -340,6 +379,7 @@ static PyMethodDef test_methods[] = { {"test_lock_counter_slow", test_lock_counter_slow, METH_NOARGS}, _TESTINTERNALCAPI_BENCHMARK_LOCKS_METHODDEF {"test_lock_benchmark", test_lock_benchmark, METH_NOARGS}, + {"test_lock_once", test_lock_once, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index fdef06168bfc86..21c5f696a4f2ec 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -6,6 +6,7 @@ #endif #include "Python.h" +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_namespace.h" // _PyNamespace_New() /* State for testing module state access from methods */ diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index e77e30dfe5e821..afcf646e3bc19e 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -3,11 +3,8 @@ /* 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() @@ -25,12 +22,13 @@ // Forward declarations static struct PyModuleDef thread_module; - +// Module state typedef struct { PyTypeObject *excepthook_type; PyTypeObject *lock_type; PyTypeObject *local_type; PyTypeObject *local_dummy_type; + PyTypeObject *thread_handle_type; } thread_module_state; static inline thread_module_state* @@ -41,6 +39,145 @@ get_thread_state(PyObject *module) return (thread_module_state *)state; } +// _ThreadHandle type + +typedef struct { + PyObject_HEAD + PyThread_ident_t ident; + PyThread_handle_t handle; + char joinable; +} ThreadHandleObject; + +static ThreadHandleObject* +new_thread_handle(thread_module_state* state) +{ + ThreadHandleObject* self = PyObject_New(ThreadHandleObject, state->thread_handle_type); + if (self == NULL) { + return NULL; + } + self->ident = 0; + self->handle = 0; + self->joinable = 0; + return self; +} + +static void +ThreadHandle_dealloc(ThreadHandleObject *self) +{ + PyObject *tp = (PyObject *) Py_TYPE(self); + if (self->joinable) { + int ret = PyThread_detach_thread(self->handle); + if (ret) { + PyErr_SetString(ThreadError, "Failed detaching thread"); + PyErr_WriteUnraisable(tp); + } + } + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyObject * +ThreadHandle_repr(ThreadHandleObject *self) +{ + return PyUnicode_FromFormat("<%s object: ident=%" PY_FORMAT_THREAD_IDENT_T ">", + Py_TYPE(self)->tp_name, self->ident); +} + +static PyObject * +ThreadHandle_get_ident(ThreadHandleObject *self, void *ignored) +{ + return PyLong_FromUnsignedLongLong(self->ident); +} + + +static PyObject * +ThreadHandle_after_fork_alive(ThreadHandleObject *self, void* ignored) +{ + PyThread_update_thread_after_fork(&self->ident, &self->handle); + Py_RETURN_NONE; +} + +static PyObject * +ThreadHandle_after_fork_dead(ThreadHandleObject *self, void* ignored) +{ + // Disallow calls to detach() and join() as they could crash. + self->joinable = 0; + Py_RETURN_NONE; +} + +static PyObject * +ThreadHandle_detach(ThreadHandleObject *self, void* ignored) +{ + if (!self->joinable) { + PyErr_SetString(PyExc_ValueError, + "the thread is not joinable and thus cannot be detached"); + return NULL; + } + self->joinable = 0; + // This is typically short so no need to release the GIL + int ret = PyThread_detach_thread(self->handle); + if (ret) { + PyErr_SetString(ThreadError, "Failed detaching thread"); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +ThreadHandle_join(ThreadHandleObject *self, void* ignored) +{ + if (!self->joinable) { + PyErr_SetString(PyExc_ValueError, "the thread is not joinable"); + return NULL; + } + if (self->ident == PyThread_get_thread_ident_ex()) { + // PyThread_join_thread() would deadlock or error out. + PyErr_SetString(ThreadError, "Cannot join current thread"); + return NULL; + } + // Before actually joining, we must first mark the thread as non-joinable, + // as joining several times simultaneously or sequentially is undefined behavior. + self->joinable = 0; + int ret; + Py_BEGIN_ALLOW_THREADS + ret = PyThread_join_thread(self->handle); + Py_END_ALLOW_THREADS + if (ret) { + PyErr_SetString(ThreadError, "Failed joining thread"); + return NULL; + } + Py_RETURN_NONE; +} + +static PyGetSetDef ThreadHandle_getsetlist[] = { + {"ident", (getter)ThreadHandle_get_ident, NULL, NULL}, + {0}, +}; + +static PyMethodDef ThreadHandle_methods[] = +{ + {"after_fork_alive", (PyCFunction)ThreadHandle_after_fork_alive, METH_NOARGS}, + {"after_fork_dead", (PyCFunction)ThreadHandle_after_fork_dead, METH_NOARGS}, + {"detach", (PyCFunction)ThreadHandle_detach, METH_NOARGS}, + {"join", (PyCFunction)ThreadHandle_join, METH_NOARGS}, + {0, 0} +}; + +static PyType_Slot ThreadHandle_Type_slots[] = { + {Py_tp_dealloc, (destructor)ThreadHandle_dealloc}, + {Py_tp_repr, (reprfunc)ThreadHandle_repr}, + {Py_tp_getset, ThreadHandle_getsetlist}, + {Py_tp_methods, ThreadHandle_methods}, + {0, 0} +}; + +static PyType_Spec ThreadHandle_Type_spec = { + "_thread._ThreadHandle", + sizeof(ThreadHandleObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + ThreadHandle_Type_slots, +}; /* Lock objects */ @@ -76,57 +213,10 @@ lock_dealloc(lockobject *self) Py_DECREF(tp); } -/* Helper to acquire an interruptible lock with a timeout. If the lock acquire - * is interrupted, signal handlers are run, and if they raise an exception, - * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE - * are returned, depending on whether the lock can be acquired within the - * timeout. - */ -static PyLockStatus +static inline PyLockStatus acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyTime_t endtime = 0; - if (timeout > 0) { - endtime = _PyDeadline_Init(timeout); - } - - PyLockStatus r; - do { - _PyTime_t microseconds; - microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING); - - /* first a simple non-blocking try without releasing the GIL */ - r = PyThread_acquire_lock_timed(lock, 0, 0); - if (r == PY_LOCK_FAILURE && microseconds != 0) { - Py_BEGIN_ALLOW_THREADS - r = PyThread_acquire_lock_timed(lock, microseconds, 1); - Py_END_ALLOW_THREADS - } - - if (r == PY_LOCK_INTR) { - /* Run signal handlers if we were interrupted. Propagate - * exceptions from signal handlers, such as KeyboardInterrupt, by - * passing up PY_LOCK_INTR. */ - if (_PyEval_MakePendingCalls(tstate) < 0) { - return PY_LOCK_INTR; - } - - /* If we're using a timeout, recompute the timeout after processing - * signals, since those can take time. */ - if (timeout > 0) { - timeout = _PyDeadline_Get(endtime); - - /* Check for negative values, since those mean block forever. - */ - if (timeout < 0) { - r = PY_LOCK_FAILURE; - } - } - } - } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */ - - return r; + return PyThread_acquire_lock_timed_with_retries(lock, timeout); } static int @@ -136,14 +226,15 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds, char *kwlist[] = {"blocking", "timeout", NULL}; int blocking = 1; PyObject *timeout_obj = NULL; - const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1); - - *timeout = unset_timeout ; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pO:acquire", kwlist, &blocking, &timeout_obj)) return -1; + // XXX Use PyThread_ParseTimeoutArg(). + + const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1); + *timeout = unset_timeout; + if (timeout_obj && _PyTime_FromSecondsObject(timeout, timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) @@ -156,7 +247,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds, } if (*timeout < 0 && *timeout != unset_timeout) { PyErr_SetString(PyExc_ValueError, - "timeout value must be positive"); + "timeout value must be a non-negative number"); return -1; } if (!blocking) @@ -323,7 +414,7 @@ static PyType_Spec lock_type_spec = { typedef struct { PyObject_HEAD PyThread_type_lock rlock_lock; - unsigned long rlock_owner; + PyThread_ident_t rlock_owner; unsigned long rlock_count; PyObject *in_weakreflist; } rlockobject; @@ -360,13 +451,13 @@ static PyObject * rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) { _PyTime_t timeout; - unsigned long tid; + PyThread_ident_t tid; PyLockStatus r = PY_LOCK_ACQUIRED; if (lock_acquire_parse_args(args, kwds, &timeout) < 0) return NULL; - tid = PyThread_get_thread_ident(); + tid = PyThread_get_thread_ident_ex(); if (self->rlock_count > 0 && tid == self->rlock_owner) { unsigned long count = self->rlock_count + 1; if (count <= self->rlock_count) { @@ -409,7 +500,7 @@ the lock is taken and its internal counter initialized to 1."); static PyObject * rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored)) { - unsigned long tid = PyThread_get_thread_ident(); + PyThread_ident_t tid = PyThread_get_thread_ident_ex(); if (self->rlock_count == 0 || self->rlock_owner != tid) { PyErr_SetString(PyExc_RuntimeError, @@ -438,11 +529,12 @@ to be available for other threads."); static PyObject * rlock_acquire_restore(rlockobject *self, PyObject *args) { - unsigned long owner; + PyThread_ident_t owner; unsigned long count; int r = 1; - if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner)) + if (!PyArg_ParseTuple(args, "(k" Py_PARSE_THREAD_IDENT_T "):_acquire_restore", + &count, &owner)) return NULL; if (!PyThread_acquire_lock(self->rlock_lock, 0)) { @@ -468,7 +560,7 @@ For internal use by `threading.Condition`."); static PyObject * rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored)) { - unsigned long owner; + PyThread_ident_t owner; unsigned long count; if (self->rlock_count == 0) { @@ -482,7 +574,7 @@ rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored)) self->rlock_count = 0; self->rlock_owner = 0; PyThread_release_lock(self->rlock_lock); - return Py_BuildValue("kk", count, owner); + return Py_BuildValue("k" Py_PARSE_THREAD_IDENT_T, count, owner); } PyDoc_STRVAR(rlock_release_save_doc, @@ -493,7 +585,7 @@ For internal use by `threading.Condition`."); static PyObject * rlock_recursion_count(rlockobject *self, PyObject *Py_UNUSED(ignored)) { - unsigned long tid = PyThread_get_thread_ident(); + PyThread_ident_t tid = PyThread_get_thread_ident_ex(); return PyLong_FromUnsignedLong( self->rlock_owner == tid ? self->rlock_count : 0UL); } @@ -506,7 +598,7 @@ For internal use by reentrancy checks."); static PyObject * rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored)) { - unsigned long tid = PyThread_get_thread_ident(); + PyThread_ident_t tid = PyThread_get_thread_ident_ex(); if (self->rlock_count > 0 && self->rlock_owner == tid) { Py_RETURN_TRUE; @@ -542,7 +634,8 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * rlock_repr(rlockobject *self) { - return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>", + return PyUnicode_FromFormat( + "<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%lu at %p>", self->rlock_count ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count, self); @@ -874,11 +967,8 @@ local_clear(localobject *self) HEAD_UNLOCK(runtime); while (tstate) { if (tstate->dict) { - PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None); - if (v != NULL) { - Py_DECREF(v); - } - else { + if (PyDict_Pop(tstate->dict, self->key, NULL) < 0) { + // Silently ignore error PyErr_Clear(); } } @@ -1025,12 +1115,10 @@ local_getattro(localobject *self, PyObject *name) } /* Optimization: just look in dict ourselves */ - PyObject *value = PyDict_GetItemWithError(ldict, name); - if (value != NULL) { - return Py_NewRef(value); - } - if (PyErr_Occurred()) { - return NULL; + PyObject *value; + if (PyDict_GetItemRef(ldict, name, &value) != 0) { + // found or error + return value; } /* Fall back on generic to get __class__ and __dict__ */ @@ -1119,7 +1207,8 @@ thread_run(void *boot_raw) /* SystemExit is ignored silently */ PyErr_Clear(); else { - _PyErr_WriteUnraisableMsg("in thread started by", boot->func); + PyErr_FormatUnraisable( + "Exception ignored in thread started by %R", boot->func); } } else { @@ -1157,10 +1246,66 @@ PyDoc_STRVAR(daemon_threads_allowed_doc, Return True if daemon threads are allowed in the current interpreter,\n\ and False otherwise.\n"); +static int +do_start_new_thread(thread_module_state* state, + PyObject *func, PyObject* args, PyObject* kwargs, + int joinable, + PyThread_ident_t* ident, PyThread_handle_t* handle) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_THREADS)) { + PyErr_SetString(PyExc_RuntimeError, + "thread is not supported for isolated subinterpreters"); + return -1; + } + if (interp->finalizing) { + PyErr_SetString(PyExc_RuntimeError, + "can't create new thread at interpreter shutdown"); + return -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) { + PyErr_NoMemory(); + return -1; + } + boot->tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_THREADING); + if (boot->tstate == NULL) { + PyMem_RawFree(boot); + if (!PyErr_Occurred()) { + PyErr_NoMemory(); + } + return -1; + } + boot->func = Py_NewRef(func); + boot->args = Py_NewRef(args); + boot->kwargs = Py_XNewRef(kwargs); + + int err; + if (joinable) { + err = PyThread_start_joinable_thread(thread_run, (void*) boot, ident, handle); + } else { + *handle = 0; + *ident = PyThread_start_new_thread(thread_run, (void*) boot); + err = (*ident == PYTHREAD_INVALID_THREAD_ID); + } + if (err) { + PyErr_SetString(ThreadError, "can't start new thread"); + PyThreadState_Clear(boot->tstate); + thread_bootstate_free(boot, 1); + return -1; + } + return 0; +} + static PyObject * -thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) +thread_PyThread_start_new_thread(PyObject *module, PyObject *fargs) { PyObject *func, *args, *kwargs = NULL; + thread_module_state *state = get_thread_state(module); if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3, &func, &args, &kwargs)) @@ -1186,57 +1331,73 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) return NULL; } - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_THREADS)) { - PyErr_SetString(PyExc_RuntimeError, - "thread is not supported for isolated subinterpreters"); + PyThread_ident_t ident = 0; + PyThread_handle_t handle; + if (do_start_new_thread(state, func, args, kwargs, /*joinable=*/ 0, + &ident, &handle)) { return NULL; } - if (interp->finalizing) { - PyErr_SetString(PyExc_RuntimeError, - "can't create new thread at interpreter shutdown"); + return PyLong_FromUnsignedLongLong(ident); +} + +PyDoc_STRVAR(start_new_doc, +"start_new_thread(function, args[, kwargs])\n\ +(start_new() is an obsolete synonym)\n\ +\n\ +Start a new thread and return its identifier.\n\ +\n\ +The thread will call the function with positional arguments from the\n\ +tuple args and keyword arguments taken from the optional dictionary\n\ +kwargs. The thread exits when the function returns; the return value\n\ +is ignored. The thread will also exit when the function raises an\n\ +unhandled exception; a stack trace will be printed unless the exception\n\ +is SystemExit.\n"); + +static PyObject * +thread_PyThread_start_joinable_thread(PyObject *module, PyObject *func) +{ + thread_module_state *state = get_thread_state(module); + + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "thread function must be callable"); return NULL; } - // 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->tstate = _PyThreadState_New(interp); - if (boot->tstate == NULL) { - PyMem_RawFree(boot); - if (!PyErr_Occurred()) { - return PyErr_NoMemory(); - } + if (PySys_Audit("_thread.start_joinable_thread", "O", func) < 0) { return NULL; } - boot->func = Py_NewRef(func); - boot->args = Py_NewRef(args); - boot->kwargs = Py_XNewRef(kwargs); - unsigned long ident = PyThread_start_new_thread(thread_run, (void*) boot); - if (ident == PYTHREAD_INVALID_THREAD_ID) { - PyErr_SetString(ThreadError, "can't start new thread"); - PyThreadState_Clear(boot->tstate); - thread_bootstate_free(boot, 1); + PyObject* args = PyTuple_New(0); + if (args == NULL) { + return NULL; + } + ThreadHandleObject* hobj = new_thread_handle(state); + if (hobj == NULL) { + Py_DECREF(args); + return NULL; + } + if (do_start_new_thread(state, func, args, /*kwargs=*/ NULL, /*joinable=*/ 1, + &hobj->ident, &hobj->handle)) { + Py_DECREF(args); + Py_DECREF(hobj); return NULL; } - return PyLong_FromUnsignedLong(ident); + Py_DECREF(args); + hobj->joinable = 1; + return (PyObject*) hobj; } -PyDoc_STRVAR(start_new_doc, -"start_new_thread(function, args[, kwargs])\n\ -(start_new() is an obsolete synonym)\n\ +PyDoc_STRVAR(start_joinable_doc, +"start_joinable_thread(function)\n\ +\n\ +*For internal use only*: start a new thread.\n\ \n\ -Start a new thread and return its identifier. The thread will call the\n\ -function with positional arguments from the tuple args and keyword arguments\n\ -taken from the optional dictionary kwargs. The thread exits when the\n\ -function returns; the return value is ignored. The thread will also exit\n\ -when the function raises an unhandled exception; a stack trace will be\n\ -printed unless the exception is SystemExit.\n"); +Like start_new_thread(), this starts a new thread calling the given function.\n\ +Unlike start_new_thread(), this returns a handle object with methods to join\n\ +or detach the given thread.\n\ +This function is not for third-party code, please use the\n\ +`threading` module instead.\n"); static PyObject * thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) @@ -1296,12 +1457,12 @@ information about locks."); static PyObject * thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored)) { - unsigned long ident = PyThread_get_thread_ident(); + PyThread_ident_t ident = PyThread_get_thread_ident_ex(); if (ident == PYTHREAD_INVALID_THREAD_ID) { PyErr_SetString(ThreadError, "no current thread ident"); return NULL; } - return PyLong_FromUnsignedLong(ident); + return PyLong_FromUnsignedLongLong(ident); } PyDoc_STRVAR(get_ident_doc, @@ -1488,8 +1649,8 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, Py_DECREF(name); } else { - unsigned long ident = PyThread_get_thread_ident(); - PyObject *str = PyUnicode_FromFormat("%lu", ident); + PyThread_ident_t ident = PyThread_get_thread_ident_ex(); + PyObject *str = PyUnicode_FromFormat("%" PY_FORMAT_THREAD_IDENT_T, ident); if (str != NULL) { if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) { Py_DECREF(str); @@ -1605,11 +1766,25 @@ 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}, {"start_new", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, + {"start_joinable_thread", (PyCFunction)thread_PyThread_start_joinable_thread, + METH_O, start_joinable_doc}, {"daemon_threads_allowed", (PyCFunction)thread_daemon_threads_allowed, METH_NOARGS, daemon_threads_allowed_doc}, {"allocate_lock", thread_PyThread_allocate_lock, @@ -1634,8 +1809,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 */ }; @@ -1651,6 +1828,15 @@ thread_module_exec(PyObject *module) // Initialize the C thread library PyThread_init_thread(); + // _ThreadHandle + state->thread_handle_type = (PyTypeObject *)PyType_FromSpec(&ThreadHandle_Type_spec); + if (state->thread_handle_type == NULL) { + return -1; + } + if (PyDict_SetItemString(d, "_ThreadHandle", (PyObject *)state->thread_handle_type) < 0) { + return -1; + } + // Lock state->lock_type = (PyTypeObject *)PyType_FromSpec(&lock_type_spec); if (state->lock_type == NULL) { @@ -1724,6 +1910,7 @@ thread_module_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->lock_type); Py_VISIT(state->local_type); Py_VISIT(state->local_dummy_type); + Py_VISIT(state->thread_handle_type); return 0; } @@ -1735,6 +1922,7 @@ thread_module_clear(PyObject *module) Py_CLEAR(state->lock_type); Py_CLEAR(state->local_type); Py_CLEAR(state->local_dummy_type); + Py_CLEAR(state->thread_handle_type); return 0; } diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index f9a18644945c65..64e752c305aae1 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -1202,7 +1202,7 @@ typedef struct Tkapp_CallEvent { Tcl_Condition *done; } Tkapp_CallEvent; -void +static void Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) { int i; diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c index 2f5be1c5144d83..4b6852c0d0ec73 100644 --- a/Modules/_uuidmodule.c +++ b/Modules/_uuidmodule.c @@ -3,6 +3,13 @@ * DCE compatible Universally Unique Identifier library. */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 +#endif + #include "Python.h" #if defined(HAVE_UUID_H) // AIX, FreeBSD, libuuid with pkgconf diff --git a/Modules/_weakref.c b/Modules/_weakref.c index 4e2862e7467c3d..7225dbc9ce4a1b 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -1,8 +1,7 @@ #include "Python.h" -#include "pycore_dict.h" // _PyDict_DelItemIf() -#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR -#include "pycore_weakref.h" // _PyWeakref_IS_DEAD() - +#include "pycore_dict.h" // _PyDict_DelItemIf() +#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR() +#include "pycore_weakref.h" // _PyWeakref_IS_DEAD() #define GET_WEAKREFS_LISTPTR(o) \ ((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o)) @@ -15,7 +14,7 @@ module _weakref #include "clinic/_weakref.c.h" /*[clinic input] - +@critical_section object _weakref.getweakrefcount -> Py_ssize_t object: object @@ -26,15 +25,14 @@ Return the number of weak references to 'object'. static Py_ssize_t _weakref_getweakrefcount_impl(PyObject *module, PyObject *object) -/*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/ +/*[clinic end generated code: output=301806d59558ff3e input=6535a580f1d0ebdc]*/ { - PyWeakReference **list; - - if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) + if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { return 0; - - list = GET_WEAKREFS_LISTPTR(object); - return _PyWeakref_GetWeakrefCount(*list); + } + PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); + Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); + return count; } @@ -79,6 +77,7 @@ _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, /*[clinic input] +@critical_section object _weakref.getweakrefs object: object / @@ -87,8 +86,8 @@ Return a list of all weak reference objects pointing to 'object'. [clinic start generated code]*/ static PyObject * -_weakref_getweakrefs(PyObject *module, PyObject *object) -/*[clinic end generated code: output=25c7731d8e011824 input=00c6d0e5d3206693]*/ +_weakref_getweakrefs_impl(PyObject *module, PyObject *object) +/*[clinic end generated code: output=5ec268989fb8f035 input=3dea95b8f5b31bbb]*/ { if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { return PyList_New(0); diff --git a/Modules/_winapi.c b/Modules/_winapi.c index cba5468f58801f..b2d3679923995e 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -212,7 +212,7 @@ class DWORD_return_converter(CReturnConverter): self.declare(data) self.err_occurred_if("_return_value == PY_DWORD_MAX", data) data.return_conversion.append( - 'return_value = Py_BuildValue("k", _return_value);\n') + 'return_value = PyLong_FromUnsignedLong(_return_value);\n') class LPVOID_return_converter(CReturnConverter): type = 'LPVOID' @@ -223,7 +223,7 @@ class LPVOID_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = HANDLE_TO_PYNUM(_return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=011ee0c3a2244bfe]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=ef52a757a1830d92]*/ #include "clinic/_winapi.c.h" diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index 6096f88421a73a..4e9b8a82a3f630 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -1,8 +1,21 @@ /* interpreters module */ /* low-level access to interpreter primitives */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "interpreteridobject.h" +#include "pycore_crossinterp.h" // struct _xid +#include "pycore_interp.h" // _PyInterpreterState_LookUpID() + +#ifdef MS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include // SwitchToThread() +#elif defined(HAVE_SCHED_H) +#include // sched_yield() +#endif /* @@ -15,7 +28,7 @@ _globals (static struct globals): next_id; (int64_t) mutex (PyThread_type_lock) head (linked list of struct _channelref *): - id (int64_t) + cid (int64_t) objcount (Py_ssize_t) next (struct _channelref *): ... @@ -29,7 +42,7 @@ _globals (static struct globals): numsendopen (int64_t) numrecvopen (int64_t) send (struct _channelend *): - interp (int64_t) + interpid (int64_t) open (int) next (struct _channelend *) recv (struct _channelend *): @@ -42,7 +55,7 @@ _globals (static struct globals): data (_PyCrossInterpreterData *): data (void *) obj (PyObject *) - interp (int64_t) + interpid (int64_t) new_object (xid_newobjectfunc) free (xid_freefunc) last (struct _channelitem *): @@ -76,6 +89,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) { @@ -140,10 +220,11 @@ 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); + PyTypeObject *cls = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, spec, NULL); if (cls == NULL) { return NULL; } @@ -152,7 +233,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; } @@ -160,45 +241,38 @@ add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared) return cls; } -#define XID_IGNORE_EXC 1 -#define XID_FREE 2 - static int -_release_xid_data(_PyCrossInterpreterData *data, int flags) +wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout) { - 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. */ + PyLockStatus res = PyThread_acquire_lock_timed_with_retries(mutex, timeout); + if (res == PY_LOCK_INTR) { + /* KeyboardInterrupt, etc. */ + assert(PyErr_Occurred()); + return -1; } - if (ignoreexc) { - PyErr_SetRaisedException(exc); + else if (res == PY_LOCK_FAILURE) { + assert(!PyErr_Occurred()); + assert(timeout > 0); + PyErr_SetString(PyExc_TimeoutError, "timed out"); + return -1; } - return res; + assert(res == PY_LOCK_ACQUIRED); + PyThread_release_lock(mutex); + 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 *ChannelInfoType; PyTypeObject *ChannelIDType; /* exceptions */ @@ -218,10 +292,30 @@ 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) { + /* external types */ + Py_VISIT(state->send_channel_type); + Py_VISIT(state->recv_channel_type); + /* heap types */ + Py_VISIT(state->ChannelInfoType); Py_VISIT(state->ChannelIDType); /* exceptions */ @@ -237,7 +331,12 @@ traverse_module_state(module_state *state, visitproc visit, void *arg) static int clear_module_state(module_state *state) { + /* external types */ + Py_CLEAR(state->send_channel_type); + Py_CLEAR(state->recv_channel_type); + /* heap types */ + Py_CLEAR(state->ChannelInfoType); if (state->ChannelIDType != NULL) { (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); } @@ -260,6 +359,7 @@ clear_module_state(module_state *state) #define CHANNEL_BOTH 0 #define CHANNEL_RECV -1 + /* channel errors */ #define ERR_CHANNEL_NOT_FOUND -2 @@ -270,6 +370,7 @@ clear_module_state(module_state *state) #define ERR_CHANNEL_MUTEX_INIT -7 #define ERR_CHANNELS_MUTEX_INIT -8 #define ERR_NO_NEXT_CHANNEL_ID -9 +#define ERR_CHANNEL_CLOSED_WAITING -10 static int exceptions_init(PyObject *mod) @@ -321,6 +422,10 @@ handle_channel_error(int err, PyObject *mod, int64_t cid) PyErr_Format(state->ChannelClosedError, "channel %" PRId64 " is closed", cid); } + else if (err == ERR_CHANNEL_CLOSED_WAITING) { + PyErr_Format(state->ChannelClosedError, + "channel %" PRId64 " has closed", cid); + } else if (err == ERR_CHANNEL_INTERP_CLOSED) { PyErr_Format(state->ChannelClosedError, "channel %" PRId64 " is already closed", cid); @@ -353,37 +458,148 @@ handle_channel_error(int err, PyObject *mod, int64_t cid) return 1; } + /* the channel queue */ +typedef uintptr_t _channelitem_id_t; + +typedef struct wait_info { + PyThread_type_lock mutex; + enum { + WAITING_NO_STATUS = 0, + WAITING_ACQUIRED = 1, + WAITING_RELEASING = 2, + WAITING_RELEASED = 3, + } status; + int received; + _channelitem_id_t itemid; +} _waiting_t; + +static int +_waiting_init(_waiting_t *waiting) +{ + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + PyErr_NoMemory(); + return -1; + } + + *waiting = (_waiting_t){ + .mutex = mutex, + .status = WAITING_NO_STATUS, + }; + return 0; +} + +static void +_waiting_clear(_waiting_t *waiting) +{ + assert(waiting->status != WAITING_ACQUIRED + && waiting->status != WAITING_RELEASING); + if (waiting->mutex != NULL) { + PyThread_free_lock(waiting->mutex); + waiting->mutex = NULL; + } +} + +static _channelitem_id_t +_waiting_get_itemid(_waiting_t *waiting) +{ + return waiting->itemid; +} + +static void +_waiting_acquire(_waiting_t *waiting) +{ + assert(waiting->status == WAITING_NO_STATUS); + PyThread_acquire_lock(waiting->mutex, NOWAIT_LOCK); + waiting->status = WAITING_ACQUIRED; +} + +static void +_waiting_release(_waiting_t *waiting, int received) +{ + assert(waiting->mutex != NULL); + assert(waiting->status == WAITING_ACQUIRED); + assert(!waiting->received); + + waiting->status = WAITING_RELEASING; + PyThread_release_lock(waiting->mutex); + if (waiting->received != received) { + assert(received == 1); + waiting->received = received; + } + waiting->status = WAITING_RELEASED; +} + +static void +_waiting_finish_releasing(_waiting_t *waiting) +{ + while (waiting->status == WAITING_RELEASING) { +#ifdef MS_WINDOWS + SwitchToThread(); +#elif defined(HAVE_SCHED_H) + sched_yield(); +#endif + } +} + struct _channelitem; typedef struct _channelitem { _PyCrossInterpreterData *data; + _waiting_t *waiting; struct _channelitem *next; } _channelitem; -static _channelitem * -_channelitem_new(void) +static inline _channelitem_id_t +_channelitem_ID(_channelitem *item) { - _channelitem *item = GLOBAL_MALLOC(_channelitem); - if (item == NULL) { - PyErr_NoMemory(); - return NULL; + return (_channelitem_id_t)item; +} + +static void +_channelitem_init(_channelitem *item, + _PyCrossInterpreterData *data, _waiting_t *waiting) +{ + *item = (_channelitem){ + .data = data, + .waiting = waiting, + }; + if (waiting != NULL) { + waiting->itemid = _channelitem_ID(item); } - item->data = NULL; - item->next = NULL; - return item; } static void _channelitem_clear(_channelitem *item) { + item->next = NULL; + if (item->data != NULL) { - // It was allocated in _channel_send(). + // It was allocated in channel_send(). (void)_release_xid_data(item->data, XID_IGNORE_EXC & XID_FREE); item->data = NULL; } - item->next = NULL; + + if (item->waiting != NULL) { + if (item->waiting->status == WAITING_ACQUIRED) { + _waiting_release(item->waiting, 0); + } + item->waiting = NULL; + } +} + +static _channelitem * +_channelitem_new(_PyCrossInterpreterData *data, _waiting_t *waiting) +{ + _channelitem *item = GLOBAL_MALLOC(_channelitem); + if (item == NULL) { + PyErr_NoMemory(); + return NULL; + } + _channelitem_init(item, data, waiting); + return item; } static void @@ -403,13 +619,17 @@ _channelitem_free_all(_channelitem *item) } } -static _PyCrossInterpreterData * -_channelitem_popped(_channelitem *item) +static void +_channelitem_popped(_channelitem *item, + _PyCrossInterpreterData **p_data, _waiting_t **p_waiting) { - _PyCrossInterpreterData *data = item->data; + assert(item->waiting == NULL || item->waiting->status == WAITING_ACQUIRED); + *p_data = item->data; + *p_waiting = item->waiting; + // We clear them here, so they won't be released in _channelitem_clear(). item->data = NULL; + item->waiting = NULL; _channelitem_free(item); - return data; } typedef struct _channelqueue { @@ -449,13 +669,13 @@ _channelqueue_free(_channelqueue *queue) } static int -_channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) +_channelqueue_put(_channelqueue *queue, + _PyCrossInterpreterData *data, _waiting_t *waiting) { - _channelitem *item = _channelitem_new(); + _channelitem *item = _channelitem_new(data, waiting); if (item == NULL) { return -1; } - item->data = data; queue->count += 1; if (queue->first == NULL) { @@ -465,15 +685,21 @@ _channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) queue->last->next = item; } queue->last = item; + + if (waiting != NULL) { + _waiting_acquire(waiting); + } + return 0; } -static _PyCrossInterpreterData * -_channelqueue_get(_channelqueue *queue) +static int +_channelqueue_get(_channelqueue *queue, + _PyCrossInterpreterData **p_data, _waiting_t **p_waiting) { _channelitem *item = queue->first; if (item == NULL) { - return NULL; + return ERR_CHANNEL_EMPTY; } queue->first = item->next; if (queue->last == item) { @@ -481,18 +707,84 @@ _channelqueue_get(_channelqueue *queue) } queue->count -= 1; - return _channelitem_popped(item); + _channelitem_popped(item, p_data, p_waiting); + return 0; +} + +static int +_channelqueue_find(_channelqueue *queue, _channelitem_id_t itemid, + _channelitem **p_item, _channelitem **p_prev) +{ + _channelitem *prev = NULL; + _channelitem *item = NULL; + if (queue->first != NULL) { + if (_channelitem_ID(queue->first) == itemid) { + item = queue->first; + } + else { + prev = queue->first; + while (prev->next != NULL) { + if (_channelitem_ID(prev->next) == itemid) { + item = prev->next; + break; + } + prev = prev->next; + } + if (item == NULL) { + prev = NULL; + } + } + } + if (p_item != NULL) { + *p_item = item; + } + if (p_prev != NULL) { + *p_prev = prev; + } + return (item != NULL); +} + +static void +_channelqueue_remove(_channelqueue *queue, _channelitem_id_t itemid, + _PyCrossInterpreterData **p_data, _waiting_t **p_waiting) +{ + _channelitem *prev = NULL; + _channelitem *item = NULL; + int found = _channelqueue_find(queue, itemid, &item, &prev); + if (!found) { + return; + } + + assert(item->waiting != NULL); + assert(!item->waiting->received); + if (prev == NULL) { + assert(queue->first == item); + queue->first = item->next; + } + else { + assert(queue->first != item); + assert(prev->next == item); + prev->next = item->next; + } + item->next = NULL; + + if (queue->last == item) { + queue->last = prev; + } + queue->count -= 1; + + _channelitem_popped(item, p_data, p_waiting); } static void -_channelqueue_drop_interpreter(_channelqueue *queue, int64_t interp) +_channelqueue_clear_interpreter(_channelqueue *queue, int64_t interpid) { _channelitem *prev = NULL; _channelitem *next = queue->first; while (next != NULL) { _channelitem *item = next; next = item->next; - if (item->data->interp == interp) { + if (item->data->interpid == interpid) { if (prev == NULL) { queue->first = item->next; } @@ -508,18 +800,19 @@ _channelqueue_drop_interpreter(_channelqueue *queue, int64_t interp) } } + /* channel-interpreter associations */ struct _channelend; typedef struct _channelend { struct _channelend *next; - int64_t interp; + int64_t interpid; int open; } _channelend; static _channelend * -_channelend_new(int64_t interp) +_channelend_new(int64_t interpid) { _channelend *end = GLOBAL_MALLOC(_channelend); if (end == NULL) { @@ -527,7 +820,7 @@ _channelend_new(int64_t interp) return NULL; } end->next = NULL; - end->interp = interp; + end->interpid = interpid; end->open = 1; return end; } @@ -549,12 +842,12 @@ _channelend_free_all(_channelend *end) } static _channelend * -_channelend_find(_channelend *first, int64_t interp, _channelend **pprev) +_channelend_find(_channelend *first, int64_t interpid, _channelend **pprev) { _channelend *prev = NULL; _channelend *end = first; while (end != NULL) { - if (end->interp == interp) { + if (end->interpid == interpid) { break; } prev = end; @@ -611,10 +904,10 @@ _channelends_free(_channelends *ends) } static _channelend * -_channelends_add(_channelends *ends, _channelend *prev, int64_t interp, +_channelends_add(_channelends *ends, _channelend *prev, int64_t interpid, int send) { - _channelend *end = _channelend_new(interp); + _channelend *end = _channelend_new(interpid); if (end == NULL) { return NULL; } @@ -640,11 +933,11 @@ _channelends_add(_channelends *ends, _channelend *prev, int64_t interp, } static int -_channelends_associate(_channelends *ends, int64_t interp, int send) +_channelends_associate(_channelends *ends, int64_t interpid, int send) { _channelend *prev; _channelend *end = _channelend_find(send ? ends->send : ends->recv, - interp, &prev); + interpid, &prev); if (end != NULL) { if (!end->open) { return ERR_CHANNEL_CLOSED; @@ -652,7 +945,7 @@ _channelends_associate(_channelends *ends, int64_t interp, int send) // already associated return 0; } - if (_channelends_add(ends, prev, interp, send) == NULL) { + if (_channelends_add(ends, prev, interpid, send) == NULL) { return -1; } return 0; @@ -662,16 +955,20 @@ static int _channelends_is_open(_channelends *ends) { if (ends->numsendopen != 0 || ends->numrecvopen != 0) { + // At least one interpreter is still associated with the channel + // (and hasn't been released). return 1; } + // XXX This is wrong if an end can ever be removed. if (ends->send == NULL && ends->recv == NULL) { + // The channel has never had any interpreters associated with it. return 1; } return 0; } static void -_channelends_close_end(_channelends *ends, _channelend *end, int send) +_channelends_release_end(_channelends *ends, _channelend *end, int send) { end->open = 0; if (send) { @@ -683,51 +980,37 @@ _channelends_close_end(_channelends *ends, _channelend *end, int send) } static int -_channelends_close_interpreter(_channelends *ends, int64_t interp, int which) +_channelends_release_interpreter(_channelends *ends, int64_t interpid, int which) { _channelend *prev; _channelend *end; if (which >= 0) { // send/both - end = _channelend_find(ends->send, interp, &prev); + end = _channelend_find(ends->send, interpid, &prev); if (end == NULL) { // never associated so add it - end = _channelends_add(ends, prev, interp, 1); + end = _channelends_add(ends, prev, interpid, 1); if (end == NULL) { return -1; } } - _channelends_close_end(ends, end, 1); + _channelends_release_end(ends, end, 1); } if (which <= 0) { // recv/both - end = _channelend_find(ends->recv, interp, &prev); + end = _channelend_find(ends->recv, interpid, &prev); if (end == NULL) { // never associated so add it - end = _channelends_add(ends, prev, interp, 0); + end = _channelends_add(ends, prev, interpid, 0); if (end == NULL) { return -1; } } - _channelends_close_end(ends, end, 0); + _channelends_release_end(ends, end, 0); } return 0; } static void -_channelends_drop_interpreter(_channelends *ends, int64_t interp) -{ - _channelend *end; - end = _channelend_find(ends->send, interp, NULL); - if (end != NULL) { - _channelends_close_end(ends, end, 1); - } - end = _channelend_find(ends->recv, interp, NULL); - if (end != NULL) { - _channelends_close_end(ends, end, 0); - } -} - -static void -_channelends_close_all(_channelends *ends, int which, int force) +_channelends_release_all(_channelends *ends, int which, int force) { // XXX Handle the ends. // XXX Handle force is True. @@ -735,16 +1018,32 @@ _channelends_close_all(_channelends *ends, int which, int force) // Ensure all the "send"-associated interpreters are closed. _channelend *end; for (end = ends->send; end != NULL; end = end->next) { - _channelends_close_end(ends, end, 1); + _channelends_release_end(ends, end, 1); } // Ensure all the "recv"-associated interpreters are closed. for (end = ends->recv; end != NULL; end = end->next) { - _channelends_close_end(ends, end, 0); + _channelends_release_end(ends, end, 0); } } -/* channels */ +static void +_channelends_clear_interpreter(_channelends *ends, int64_t interpid) +{ + // XXX Actually remove the entries? + _channelend *end; + end = _channelend_find(ends->send, interpid, NULL); + if (end != NULL) { + _channelends_release_end(ends, end, 1); + } + end = _channelend_find(ends->recv, interpid, NULL); + if (end != NULL) { + _channelends_release_end(ends, end, 0); + } +} + + +/* each channel's state */ struct _channel; struct _channel_closing; @@ -757,12 +1056,12 @@ typedef struct _channel { _channelends *ends; int open; struct _channel_closing *closing; -} _PyChannelState; +} _channel_state; -static _PyChannelState * +static _channel_state * _channel_new(PyThread_type_lock mutex) { - _PyChannelState *chan = GLOBAL_MALLOC(_PyChannelState); + _channel_state *chan = GLOBAL_MALLOC(_channel_state); if (chan == NULL) { return NULL; } @@ -784,7 +1083,7 @@ _channel_new(PyThread_type_lock mutex) } static void -_channel_free(_PyChannelState *chan) +_channel_free(_channel_state *chan) { _channel_clear_closing(chan); PyThread_acquire_lock(chan->mutex, WAIT_LOCK); @@ -797,8 +1096,8 @@ _channel_free(_PyChannelState *chan) } static int -_channel_add(_PyChannelState *chan, int64_t interp, - _PyCrossInterpreterData *data) +_channel_add(_channel_state *chan, int64_t interpid, + _PyCrossInterpreterData *data, _waiting_t *waiting) { int res = -1; PyThread_acquire_lock(chan->mutex, WAIT_LOCK); @@ -807,14 +1106,15 @@ _channel_add(_PyChannelState *chan, int64_t interp, res = ERR_CHANNEL_CLOSED; goto done; } - if (_channelends_associate(chan->ends, interp, 1) != 0) { + if (_channelends_associate(chan->ends, interpid, 1) != 0) { res = ERR_CHANNEL_INTERP_CLOSED; goto done; } - if (_channelqueue_put(chan->queue, data) != 0) { + if (_channelqueue_put(chan->queue, data, waiting) != 0) { goto done; } + // Any errors past this point must cause a _waiting_release() call. res = 0; done: @@ -823,8 +1123,8 @@ _channel_add(_PyChannelState *chan, int64_t interp, } static int -_channel_next(_PyChannelState *chan, int64_t interp, - _PyCrossInterpreterData **res) +_channel_next(_channel_state *chan, int64_t interpid, + _PyCrossInterpreterData **p_data, _waiting_t **p_waiting) { int err = 0; PyThread_acquire_lock(chan->mutex, WAIT_LOCK); @@ -833,16 +1133,17 @@ _channel_next(_PyChannelState *chan, int64_t interp, err = ERR_CHANNEL_CLOSED; goto done; } - if (_channelends_associate(chan->ends, interp, 0) != 0) { + if (_channelends_associate(chan->ends, interpid, 0) != 0) { err = ERR_CHANNEL_INTERP_CLOSED; goto done; } - _PyCrossInterpreterData *data = _channelqueue_get(chan->queue); - if (data == NULL && !PyErr_Occurred() && chan->closing != NULL) { + int empty = _channelqueue_get(chan->queue, p_data, p_waiting); + assert(empty == 0 || empty == ERR_CHANNEL_EMPTY); + assert(!PyErr_Occurred()); + if (empty && chan->closing != NULL) { chan->open = 0; } - *res = data; done: PyThread_release_lock(chan->mutex); @@ -852,8 +1153,28 @@ _channel_next(_PyChannelState *chan, int64_t interp, return err; } +static void +_channel_remove(_channel_state *chan, _channelitem_id_t itemid) +{ + _PyCrossInterpreterData *data = NULL; + _waiting_t *waiting = NULL; + + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + _channelqueue_remove(chan->queue, itemid, &data, &waiting); + PyThread_release_lock(chan->mutex); + + (void)_release_xid_data(data, XID_IGNORE_EXC | XID_FREE); + if (waiting != NULL) { + _waiting_release(waiting, 0); + } + + if (chan->queue->count == 0) { + _channel_finish_closing(chan); + } +} + static int -_channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) +_channel_release_interpreter(_channel_state *chan, int64_t interpid, int end) { PyThread_acquire_lock(chan->mutex, WAIT_LOCK); @@ -863,10 +1184,12 @@ _channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) goto done; } - if (_channelends_close_interpreter(chan->ends, interp, end) != 0) { + if (_channelends_release_interpreter(chan->ends, interpid, end) != 0) { goto done; } chan->open = _channelends_is_open(chan->ends); + // XXX Clear the queue if not empty? + // XXX Activate the "closing" mechanism? res = 0; done: @@ -874,20 +1197,8 @@ _channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) return res; } -static void -_channel_drop_interpreter(_PyChannelState *chan, int64_t interp) -{ - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - - _channelqueue_drop_interpreter(chan->queue, interp); - _channelends_drop_interpreter(chan->ends, interp); - chan->open = _channelends_is_open(chan->ends); - - PyThread_release_lock(chan->mutex); -} - static int -_channel_close_all(_PyChannelState *chan, int end, int force) +_channel_release_all(_channel_state *chan, int end, int force) { int res = -1; PyThread_acquire_lock(chan->mutex, WAIT_LOCK); @@ -901,12 +1212,13 @@ _channel_close_all(_PyChannelState *chan, int end, int force) res = ERR_CHANNEL_NOT_EMPTY; goto done; } + // XXX Clear the queue? chan->open = 0; // We *could* also just leave these in place, since we've marked // the channel as closed already. - _channelends_close_all(chan->ends, end, force); + _channelends_release_all(chan->ends, end, force); res = 0; done: @@ -914,25 +1226,39 @@ _channel_close_all(_PyChannelState *chan, int end, int force) return res; } +static void +_channel_clear_interpreter(_channel_state *chan, int64_t interpid) +{ + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + _channelqueue_clear_interpreter(chan->queue, interpid); + _channelends_clear_interpreter(chan->ends, interpid); + chan->open = _channelends_is_open(chan->ends); + + PyThread_release_lock(chan->mutex); +} + + /* the set of channels */ struct _channelref; typedef struct _channelref { - int64_t id; - _PyChannelState *chan; + int64_t cid; + _channel_state *chan; struct _channelref *next; + // The number of ChannelID objects referring to this channel. Py_ssize_t objcount; } _channelref; static _channelref * -_channelref_new(int64_t id, _PyChannelState *chan) +_channelref_new(int64_t cid, _channel_state *chan) { _channelref *ref = GLOBAL_MALLOC(_channelref); if (ref == NULL) { return NULL; } - ref->id = id; + ref->cid = cid; ref->chan = chan; ref->next = NULL; ref->objcount = 0; @@ -942,7 +1268,7 @@ _channelref_new(int64_t id, _PyChannelState *chan) //static void //_channelref_clear(_channelref *ref) //{ -// ref->id = -1; +// ref->cid = -1; // ref->chan = NULL; // ref->next = NULL; // ref->objcount = 0; @@ -959,12 +1285,12 @@ _channelref_free(_channelref *ref) } static _channelref * -_channelref_find(_channelref *first, int64_t id, _channelref **pprev) +_channelref_find(_channelref *first, int64_t cid, _channelref **pprev) { _channelref *prev = NULL; _channelref *ref = first; while (ref != NULL) { - if (ref->id == id) { + if (ref->cid == cid) { break; } prev = ref; @@ -976,6 +1302,7 @@ _channelref_find(_channelref *first, int64_t id, _channelref **pprev) return ref; } + typedef struct _channels { PyThread_type_lock mutex; _channelref *head; @@ -1006,27 +1333,27 @@ _channels_fini(_channels *channels) static int64_t _channels_next_id(_channels *channels) // needs lock { - int64_t id = channels->next_id; - if (id < 0) { + int64_t cid = channels->next_id; + if (cid < 0) { /* overflow */ return -1; } channels->next_id += 1; - return id; + return cid; } static int -_channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex, - _PyChannelState **res) +_channels_lookup(_channels *channels, int64_t cid, PyThread_type_lock *pmutex, + _channel_state **res) { int err = -1; - _PyChannelState *chan = NULL; + _channel_state *chan = NULL; PyThread_acquire_lock(channels->mutex, WAIT_LOCK); if (pmutex != NULL) { *pmutex = NULL; } - _channelref *ref = _channelref_find(channels->head, id, NULL); + _channelref *ref = _channelref_find(channels->head, cid, NULL); if (ref == NULL) { err = ERR_CHANNEL_NOT_FOUND; goto done; @@ -1053,18 +1380,18 @@ _channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex, } static int64_t -_channels_add(_channels *channels, _PyChannelState *chan) +_channels_add(_channels *channels, _channel_state *chan) { int64_t cid = -1; PyThread_acquire_lock(channels->mutex, WAIT_LOCK); // Create a new ref. - int64_t id = _channels_next_id(channels); - if (id < 0) { + int64_t _cid = _channels_next_id(channels); + if (_cid < 0) { cid = ERR_NO_NEXT_CHANNEL_ID; goto done; } - _channelref *ref = _channelref_new(id, chan); + _channelref *ref = _channelref_new(_cid, chan); if (ref == NULL) { goto done; } @@ -1075,17 +1402,17 @@ _channels_add(_channels *channels, _PyChannelState *chan) channels->head = ref; channels->numopen += 1; - cid = id; + cid = _cid; done: PyThread_release_lock(channels->mutex); return cid; } /* forward */ -static int _channel_set_closing(struct _channelref *, PyThread_type_lock); +static int _channel_set_closing(_channelref *, PyThread_type_lock); static int -_channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, +_channels_close(_channels *channels, int64_t cid, _channel_state **pchan, int end, int force) { int res = -1; @@ -1109,7 +1436,7 @@ _channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, goto done; } else { - int err = _channel_close_all(ref->chan, end, force); + int err = _channel_release_all(ref->chan, end, force); if (err != 0) { if (end == CHANNEL_SEND && err == ERR_CHANNEL_NOT_EMPTY) { if (ref->chan->closing != NULL) { @@ -1151,7 +1478,7 @@ _channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, static void _channels_remove_ref(_channels *channels, _channelref *ref, _channelref *prev, - _PyChannelState **pchan) + _channel_state **pchan) { if (ref == channels->head) { channels->head = ref->next; @@ -1168,7 +1495,7 @@ _channels_remove_ref(_channels *channels, _channelref *ref, _channelref *prev, } static int -_channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) +_channels_remove(_channels *channels, int64_t cid, _channel_state **pchan) { int res = -1; PyThread_acquire_lock(channels->mutex, WAIT_LOCK); @@ -1178,7 +1505,7 @@ _channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) } _channelref *prev = NULL; - _channelref *ref = _channelref_find(channels->head, id, &prev); + _channelref *ref = _channelref_find(channels->head, cid, &prev); if (ref == NULL) { res = ERR_CHANNEL_NOT_FOUND; goto done; @@ -1193,12 +1520,12 @@ _channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) } static int -_channels_add_id_object(_channels *channels, int64_t id) +_channels_add_id_object(_channels *channels, int64_t cid) { int res = -1; PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - _channelref *ref = _channelref_find(channels->head, id, NULL); + _channelref *ref = _channelref_find(channels->head, cid, NULL); if (ref == NULL) { res = ERR_CHANNEL_NOT_FOUND; goto done; @@ -1212,12 +1539,12 @@ _channels_add_id_object(_channels *channels, int64_t id) } static void -_channels_drop_id_object(_channels *channels, int64_t id) +_channels_release_cid_object(_channels *channels, int64_t cid) { PyThread_acquire_lock(channels->mutex, WAIT_LOCK); _channelref *prev = NULL; - _channelref *ref = _channelref_find(channels->head, id, &prev); + _channelref *ref = _channelref_find(channels->head, cid, &prev); if (ref == NULL) { // Already destroyed. goto done; @@ -1226,7 +1553,7 @@ _channels_drop_id_object(_channels *channels, int64_t id) // Destroy if no longer used. if (ref->objcount == 0) { - _PyChannelState *chan = NULL; + _channel_state *chan = NULL; _channels_remove_ref(channels, ref, prev, &chan); if (chan != NULL) { _channel_free(chan); @@ -1248,7 +1575,7 @@ _channels_list_all(_channels *channels, int64_t *count) } _channelref *ref = channels->head; for (int64_t i=0; ref != NULL; ref = ref->next, i++) { - ids[i] = ref->id; + ids[i] = ref->cid; } *count = channels->numopen; @@ -1259,29 +1586,30 @@ _channels_list_all(_channels *channels, int64_t *count) } static void -_channels_drop_interpreter(_channels *channels, int64_t interp) +_channels_clear_interpreter(_channels *channels, int64_t interpid) { PyThread_acquire_lock(channels->mutex, WAIT_LOCK); _channelref *ref = channels->head; for (; ref != NULL; ref = ref->next) { if (ref->chan != NULL) { - _channel_drop_interpreter(ref->chan, interp); + _channel_clear_interpreter(ref->chan, interpid); } } PyThread_release_lock(channels->mutex); } + /* support for closing non-empty channels */ struct _channel_closing { - struct _channelref *ref; + _channelref *ref; }; static int -_channel_set_closing(struct _channelref *ref, PyThread_type_lock mutex) { - struct _channel *chan = ref->chan; +_channel_set_closing(_channelref *ref, PyThread_type_lock mutex) { + _channel_state *chan = ref->chan; if (chan == NULL) { // already closed return 0; @@ -1305,7 +1633,7 @@ _channel_set_closing(struct _channelref *ref, PyThread_type_lock mutex) { } static void -_channel_clear_closing(struct _channel *chan) { +_channel_clear_closing(_channel_state *chan) { PyThread_acquire_lock(chan->mutex, WAIT_LOCK); if (chan->closing != NULL) { GLOBAL_FREE(chan->closing); @@ -1315,7 +1643,7 @@ _channel_clear_closing(struct _channel *chan) { } static void -_channel_finish_closing(struct _channel *chan) { +_channel_finish_closing(_channel_state *chan) { struct _channel_closing *closing = chan->closing; if (closing == NULL) { return; @@ -1327,32 +1655,35 @@ _channel_finish_closing(struct _channel *chan) { _channel_free(chan); } + /* "high"-level channel-related functions */ +// Create a new channel. static int64_t -_channel_create(_channels *channels) +channel_create(_channels *channels) { PyThread_type_lock mutex = PyThread_allocate_lock(); if (mutex == NULL) { return ERR_CHANNEL_MUTEX_INIT; } - _PyChannelState *chan = _channel_new(mutex); + _channel_state *chan = _channel_new(mutex); if (chan == NULL) { PyThread_free_lock(mutex); return -1; } - int64_t id = _channels_add(channels, chan); - if (id < 0) { + int64_t cid = _channels_add(channels, chan); + if (cid < 0) { _channel_free(chan); } - return id; + return cid; } +// Completely destroy the channel. static int -_channel_destroy(_channels *channels, int64_t id) +channel_destroy(_channels *channels, int64_t cid) { - _PyChannelState *chan = NULL; - int err = _channels_remove(channels, id, &chan); + _channel_state *chan = NULL; + int err = _channels_remove(channels, cid, &chan); if (err != 0) { return err; } @@ -1362,18 +1693,23 @@ _channel_destroy(_channels *channels, int64_t id) return 0; } +// Push an object onto the channel. +// The current interpreter gets associated with the send end of the channel. +// Optionally request to be notified when it is received. static int -_channel_send(_channels *channels, int64_t id, PyObject *obj) +channel_send(_channels *channels, int64_t cid, PyObject *obj, + _waiting_t *waiting) { PyInterpreterState *interp = _get_current_interp(); if (interp == NULL) { return -1; } + int64_t interpid = PyInterpreterState_GetID(interp); // Look up the channel. PyThread_type_lock mutex = NULL; - _PyChannelState *chan = NULL; - int err = _channels_lookup(channels, id, &mutex, &chan); + _channel_state *chan = NULL; + int err = _channels_lookup(channels, cid, &mutex, &chan); if (err != 0) { return err; } @@ -1398,7 +1734,7 @@ _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, interpid, data, waiting); PyThread_release_lock(mutex); if (res != 0) { // We may chain an exception here: @@ -1410,8 +1746,85 @@ _channel_send(_channels *channels, int64_t id, PyObject *obj) return 0; } +// Basically, un-send an object. +static void +channel_clear_sent(_channels *channels, int64_t cid, _waiting_t *waiting) +{ + // Look up the channel. + PyThread_type_lock mutex = NULL; + _channel_state *chan = NULL; + int err = _channels_lookup(channels, cid, &mutex, &chan); + if (err != 0) { + // The channel was already closed, etc. + assert(waiting->status == WAITING_RELEASED); + return; // Ignore the error. + } + assert(chan != NULL); + // Past this point we are responsible for releasing the mutex. + + _channelitem_id_t itemid = _waiting_get_itemid(waiting); + _channel_remove(chan, itemid); + + PyThread_release_lock(mutex); +} + +// Like channel_send(), but strictly wait for the object to be received. +static int +channel_send_wait(_channels *channels, int64_t cid, PyObject *obj, + PY_TIMEOUT_T timeout) +{ + // We use a stack variable here, so we must ensure that &waiting + // is not held by any channel item at the point this function exits. + _waiting_t waiting; + if (_waiting_init(&waiting) < 0) { + assert(PyErr_Occurred()); + return -1; + } + + /* Queue up the object. */ + int res = channel_send(channels, cid, obj, &waiting); + if (res < 0) { + assert(waiting.status == WAITING_NO_STATUS); + goto finally; + } + + /* Wait until the object is received. */ + if (wait_for_lock(waiting.mutex, timeout) < 0) { + assert(PyErr_Occurred()); + _waiting_finish_releasing(&waiting); + /* The send() call is failing now, so make sure the item + won't be received. */ + channel_clear_sent(channels, cid, &waiting); + assert(waiting.status == WAITING_RELEASED); + if (!waiting.received) { + res = -1; + goto finally; + } + // XXX Emit a warning if not a TimeoutError? + PyErr_Clear(); + } + else { + _waiting_finish_releasing(&waiting); + assert(waiting.status == WAITING_RELEASED); + if (!waiting.received) { + res = ERR_CHANNEL_CLOSED_WAITING; + goto finally; + } + } + + /* success! */ + res = 0; + +finally: + _waiting_clear(&waiting); + return res; +} + +// Pop the next object off the channel. Fail if empty. +// The current interpreter gets associated with the recv end of the channel. +// XXX Support a "wait" mutex? static int -_channel_recv(_channels *channels, int64_t id, PyObject **res) +channel_recv(_channels *channels, int64_t cid, PyObject **res) { int err; *res = NULL; @@ -1424,11 +1837,12 @@ _channel_recv(_channels *channels, int64_t id, PyObject **res) } return 0; } + int64_t interpid = PyInterpreterState_GetID(interp); // Look up the channel. PyThread_type_lock mutex = NULL; - _PyChannelState *chan = NULL; - err = _channels_lookup(channels, id, &mutex, &chan); + _channel_state *chan = NULL; + err = _channels_lookup(channels, cid, &mutex, &chan); if (err != 0) { return err; } @@ -1437,7 +1851,8 @@ _channel_recv(_channels *channels, int64_t id, PyObject **res) // Pop off the next item from the channel. _PyCrossInterpreterData *data = NULL; - err = _channel_next(chan, PyInterpreterState_GetID(interp), &data); + _waiting_t *waiting = NULL; + err = _channel_next(chan, interpid, &data, &waiting); PyThread_release_lock(mutex); if (err != 0) { return err; @@ -1451,57 +1866,77 @@ _channel_recv(_channels *channels, int64_t id, PyObject **res) PyObject *obj = _PyCrossInterpreterData_NewObject(data); if (obj == NULL) { assert(PyErr_Occurred()); - // It was allocated in _channel_send(), so we free it. + // It was allocated in channel_send(), so we free it. (void)_release_xid_data(data, XID_IGNORE_EXC | XID_FREE); + if (waiting != NULL) { + _waiting_release(waiting, 0); + } return -1; } - // It was allocated in _channel_send(), so we free it. + // 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()); Py_DECREF(obj); + if (waiting != NULL) { + _waiting_release(waiting, 0); + } return -1; } + // Notify the sender. + if (waiting != NULL) { + _waiting_release(waiting, 1); + } + *res = obj; return 0; } +// Disallow send/recv for the current interpreter. +// The channel is marked as closed if no other interpreters +// are currently associated. static int -_channel_drop(_channels *channels, int64_t id, int send, int recv) +channel_release(_channels *channels, int64_t cid, int send, int recv) { PyInterpreterState *interp = _get_current_interp(); if (interp == NULL) { return -1; } + int64_t interpid = PyInterpreterState_GetID(interp); // Look up the channel. PyThread_type_lock mutex = NULL; - _PyChannelState *chan = NULL; - int err = _channels_lookup(channels, id, &mutex, &chan); + _channel_state *chan = NULL; + int err = _channels_lookup(channels, cid, &mutex, &chan); if (err != 0) { return err; } // Past this point we are responsible for releasing the mutex. // Close one or both of the two ends. - int res = _channel_close_interpreter(chan, PyInterpreterState_GetID(interp), send-recv); + int res = _channel_release_interpreter(chan, interpid, send-recv); PyThread_release_lock(mutex); return res; } +// Close the channel (for all interpreters). Fail if it's already closed. +// Close immediately if it's empty. Otherwise, disallow sending and +// finally close once empty. Optionally, immediately clear and close it. static int -_channel_close(_channels *channels, int64_t id, int end, int force) +channel_close(_channels *channels, int64_t cid, int end, int force) { - return _channels_close(channels, id, NULL, end, force); + return _channels_close(channels, cid, NULL, end, force); } +// Return true if the identified interpreter is associated +// with the given end of the channel. static int -_channel_is_associated(_channels *channels, int64_t cid, int64_t interp, +channel_is_associated(_channels *channels, int64_t cid, int64_t interpid, int send) { - _PyChannelState *chan = NULL; + _channel_state *chan = NULL; int err = _channels_lookup(channels, cid, NULL, &chan); if (err != 0) { return err; @@ -1511,16 +1946,247 @@ _channel_is_associated(_channels *channels, int64_t cid, int64_t interp, } _channelend *end = _channelend_find(send ? chan->ends->send : chan->ends->recv, - interp, NULL); + interpid, NULL); return (end != NULL && end->open); } + +/* channel info */ + +struct channel_info { + struct { + // 1: closed; -1: closing + int closed; + struct { + Py_ssize_t nsend_only; // not released + Py_ssize_t nsend_only_released; + Py_ssize_t nrecv_only; // not released + Py_ssize_t nrecv_only_released; + Py_ssize_t nboth; // not released + Py_ssize_t nboth_released; + Py_ssize_t nboth_send_released; + Py_ssize_t nboth_recv_released; + } all; + struct { + // 1: associated; -1: released + int send; + int recv; + } cur; + } status; + Py_ssize_t count; +}; + +static int +_channel_get_info(_channels *channels, int64_t cid, struct channel_info *info) +{ + int err = 0; + *info = (struct channel_info){0}; + + // Get the current interpreter. + PyInterpreterState *interp = _get_current_interp(); + if (interp == NULL) { + return -1; + } + Py_ssize_t interpid = PyInterpreterState_GetID(interp); + + // Hold the global lock until we're done. + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + // Find the channel. + _channelref *ref = _channelref_find(channels->head, cid, NULL); + if (ref == NULL) { + err = ERR_CHANNEL_NOT_FOUND; + goto finally; + } + _channel_state *chan = ref->chan; + + // Check if open. + if (chan == NULL) { + info->status.closed = 1; + goto finally; + } + if (!chan->open) { + assert(chan->queue->count == 0); + info->status.closed = 1; + goto finally; + } + if (chan->closing != NULL) { + assert(chan->queue->count > 0); + info->status.closed = -1; + } + else { + info->status.closed = 0; + } + + // Get the number of queued objects. + info->count = chan->queue->count; + + // Get the ends statuses. + assert(info->status.cur.send == 0); + assert(info->status.cur.recv == 0); + _channelend *send = chan->ends->send; + while (send != NULL) { + if (send->interpid == interpid) { + info->status.cur.send = send->open ? 1 : -1; + } + + if (send->open) { + info->status.all.nsend_only += 1; + } + else { + info->status.all.nsend_only_released += 1; + } + send = send->next; + } + _channelend *recv = chan->ends->recv; + while (recv != NULL) { + if (recv->interpid == interpid) { + info->status.cur.recv = recv->open ? 1 : -1; + } + + // XXX This is O(n*n). Why do we have 2 linked lists? + _channelend *send = chan->ends->send; + while (send != NULL) { + if (send->interpid == recv->interpid) { + break; + } + send = send->next; + } + if (send == NULL) { + if (recv->open) { + info->status.all.nrecv_only += 1; + } + else { + info->status.all.nrecv_only_released += 1; + } + } + else { + if (recv->open) { + if (send->open) { + info->status.all.nboth += 1; + info->status.all.nsend_only -= 1; + } + else { + info->status.all.nboth_recv_released += 1; + info->status.all.nsend_only_released -= 1; + } + } + else { + if (send->open) { + info->status.all.nboth_send_released += 1; + info->status.all.nsend_only -= 1; + } + else { + info->status.all.nboth_released += 1; + info->status.all.nsend_only_released -= 1; + } + } + } + recv = recv->next; + } + +finally: + PyThread_release_lock(channels->mutex); + return err; +} + +PyDoc_STRVAR(channel_info_doc, +"ChannelInfo\n\ +\n\ +A named tuple of a channel's state."); + +static PyStructSequence_Field channel_info_fields[] = { + {"open", "both ends are open"}, + {"closing", "send is closed, recv is non-empty"}, + {"closed", "both ends are closed"}, + {"count", "queued objects"}, + + {"num_interp_send", "interpreters bound to the send end"}, + {"num_interp_send_released", + "interpreters bound to the send end and released"}, + + {"num_interp_recv", "interpreters bound to the send end"}, + {"num_interp_recv_released", + "interpreters bound to the send end and released"}, + + {"num_interp_both", "interpreters bound to both ends"}, + {"num_interp_both_released", + "interpreters bound to both ends and released_from_both"}, + {"num_interp_both_send_released", + "interpreters bound to both ends and released_from_the send end"}, + {"num_interp_both_recv_released", + "interpreters bound to both ends and released_from_the recv end"}, + + {"send_associated", "current interpreter is bound to the send end"}, + {"send_released", "current interpreter *was* bound to the send end"}, + {"recv_associated", "current interpreter is bound to the recv end"}, + {"recv_released", "current interpreter *was* bound to the recv end"}, + {0} +}; + +static PyStructSequence_Desc channel_info_desc = { + .name = MODULE_NAME ".ChannelInfo", + .doc = channel_info_doc, + .fields = channel_info_fields, + .n_in_sequence = 8, +}; + +static PyObject * +new_channel_info(PyObject *mod, struct channel_info *info) +{ + module_state *state = get_module_state(mod); + if (state == NULL) { + return NULL; + } + + assert(state->ChannelInfoType != NULL); + PyObject *self = PyStructSequence_New(state->ChannelInfoType); + if (self == NULL) { + return NULL; + } + + int pos = 0; +#define SET_BOOL(val) \ + PyStructSequence_SET_ITEM(self, pos++, \ + Py_NewRef(val ? Py_True : Py_False)) +#define SET_COUNT(val) \ + do { \ + PyObject *obj = PyLong_FromLongLong(val); \ + if (obj == NULL) { \ + Py_CLEAR(info); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(self, pos++, obj); \ + } while(0) + SET_BOOL(info->status.closed == 0); + SET_BOOL(info->status.closed == -1); + SET_BOOL(info->status.closed == 1); + SET_COUNT(info->count); + SET_COUNT(info->status.all.nsend_only); + SET_COUNT(info->status.all.nsend_only_released); + SET_COUNT(info->status.all.nrecv_only); + SET_COUNT(info->status.all.nrecv_only_released); + SET_COUNT(info->status.all.nboth); + SET_COUNT(info->status.all.nboth_released); + SET_COUNT(info->status.all.nboth_send_released); + SET_COUNT(info->status.all.nboth_recv_released); + SET_BOOL(info->status.cur.send == 1); + SET_BOOL(info->status.cur.send == -1); + SET_BOOL(info->status.cur.recv == 1); + SET_BOOL(info->status.cur.recv == -1); +#undef SET_COUNT +#undef SET_BOOL + assert(!PyErr_Occurred()); + return self; +} + + /* ChannelID class */ typedef struct channelid { PyObject_HEAD - int64_t id; + int64_t cid; int end; int resolve; _channels *channels; @@ -1529,17 +2195,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; + cid = ((channelid *)arg)->cid; + end = ((channelid *)arg)->end; } else if (PyIndex_Check(arg)) { cid = PyLong_AsLongLong(arg); @@ -1559,6 +2228,7 @@ channel_id_converter(PyObject *arg, void *ptr) return 0; } data->cid = cid; + data->end = end; return 1; } @@ -1572,7 +2242,7 @@ newchannelid(PyTypeObject *cls, int64_t cid, int end, _channels *channels, if (self == NULL) { return -1; } - self->id = cid; + self->cid = cid; self->end = end; self->resolve = resolve; self->channels = channels; @@ -1600,6 +2270,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, }; @@ -1614,6 +2285,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) { @@ -1621,33 +2293,36 @@ _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; } - PyObject *id = NULL; + PyObject *cidobj = NULL; int err = newchannelid(cls, cid, end, _global_channels(), force, resolve, - (channelid **)&id); + (channelid **)&cidobj); if (handle_channel_error(err, mod, cid)) { - assert(id == NULL); + assert(cidobj == NULL); return NULL; } - assert(id != NULL); - return id; + assert(cidobj != NULL); + return cidobj; } static void channelid_dealloc(PyObject *self) { - int64_t cid = ((channelid *)self)->id; + int64_t cid = ((channelid *)self)->cid; _channels *channels = ((channelid *)self)->channels; PyTypeObject *tp = Py_TYPE(self); @@ -1660,7 +2335,7 @@ channelid_dealloc(PyObject *self) // like we do for _abc._abc_data? Py_DECREF(tp); - _channels_drop_id_object(channels, cid); + _channels_release_cid_object(channels, cid); } static PyObject * @@ -1669,44 +2344,44 @@ channelid_repr(PyObject *self) PyTypeObject *type = Py_TYPE(self); const char *name = _PyType_Name(type); - channelid *cid = (channelid *)self; + channelid *cidobj = (channelid *)self; const char *fmt; - if (cid->end == CHANNEL_SEND) { + if (cidobj->end == CHANNEL_SEND) { fmt = "%s(%" PRId64 ", send=True)"; } - else if (cid->end == CHANNEL_RECV) { + else if (cidobj->end == CHANNEL_RECV) { fmt = "%s(%" PRId64 ", recv=True)"; } else { fmt = "%s(%" PRId64 ")"; } - return PyUnicode_FromFormat(fmt, name, cid->id); + return PyUnicode_FromFormat(fmt, name, cidobj->cid); } static PyObject * channelid_str(PyObject *self) { - channelid *cid = (channelid *)self; - return PyUnicode_FromFormat("%" PRId64 "", cid->id); + channelid *cidobj = (channelid *)self; + return PyUnicode_FromFormat("%" PRId64 "", cidobj->cid); } static PyObject * channelid_int(PyObject *self) { - channelid *cid = (channelid *)self; - return PyLong_FromLongLong(cid->id); + channelid *cidobj = (channelid *)self; + return PyLong_FromLongLong(cidobj->cid); } static Py_hash_t channelid_hash(PyObject *self) { - channelid *cid = (channelid *)self; - PyObject *id = PyLong_FromLongLong(cid->id); - if (id == NULL) { + channelid *cidobj = (channelid *)self; + PyObject *pyid = PyLong_FromLongLong(cidobj->cid); + if (pyid == NULL) { return -1; } - Py_hash_t hash = PyObject_Hash(id); - Py_DECREF(id); + Py_hash_t hash = PyObject_Hash(pyid); + Py_DECREF(pyid); return hash; } @@ -1732,11 +2407,11 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) goto done; } - channelid *cid = (channelid *)self; + channelid *cidobj = (channelid *)self; int equal; if (PyObject_TypeCheck(other, state->ChannelIDType)) { - channelid *othercid = (channelid *)other; - equal = (cid->end == othercid->end) && (cid->id == othercid->id); + channelid *othercidobj = (channelid *)other; + equal = (cidobj->end == othercidobj->end) && (cidobj->cid == othercidobj->cid); } else if (PyLong_Check(other)) { /* Fast path */ @@ -1745,10 +2420,10 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) if (othercid == -1 && PyErr_Occurred()) { goto done; } - equal = !overflow && (othercid >= 0) && (cid->id == othercid); + equal = !overflow && (othercid >= 0) && (cidobj->cid == othercid); } else if (PyNumber_Check(other)) { - PyObject *pyid = PyLong_FromLongLong(cid->id); + PyObject *pyid = PyLong_FromLongLong(cidobj->cid); if (pyid == NULL) { goto done; } @@ -1773,25 +2448,16 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) return res; } +static PyTypeObject * _get_current_channelend_type(int end); + static PyObject * -_channel_from_cid(PyObject *cid, int end) +_channelobj_from_cidobj(PyObject *cidobj, 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_channelend_type(end); if (cls == NULL) { return NULL; } - PyObject *chan = PyObject_CallFunctionObjArgs(cls, cid, NULL); + PyObject *chan = PyObject_CallFunctionObjArgs(cls, cidobj, NULL); Py_DECREF(cls); if (chan == NULL) { return NULL; @@ -1800,7 +2466,7 @@ _channel_from_cid(PyObject *cid, int end) } struct _channelid_xid { - int64_t id; + int64_t cid; int end; int resolve; }; @@ -1822,16 +2488,16 @@ _channelid_from_xid(_PyCrossInterpreterData *data) } // Note that we do not preserve the "resolve" flag. - PyObject *cid = NULL; - int err = newchannelid(state->ChannelIDType, xid->id, xid->end, + PyObject *cidobj = NULL; + int err = newchannelid(state->ChannelIDType, xid->cid, xid->end, _global_channels(), 0, 0, - (channelid **)&cid); + (channelid **)&cidobj); if (err != 0) { - assert(cid == NULL); - (void)handle_channel_error(err, mod, xid->id); + assert(cidobj == NULL); + (void)handle_channel_error(err, mod, xid->cid); goto done; } - assert(cid != NULL); + assert(cidobj != NULL); if (xid->end == 0) { goto done; } @@ -1840,17 +2506,17 @@ _channelid_from_xid(_PyCrossInterpreterData *data) } /* Try returning a high-level channel end but fall back to the ID. */ - PyObject *chan = _channel_from_cid(cid, xid->end); + PyObject *chan = _channelobj_from_cidobj(cidobj, xid->end); if (chan == NULL) { PyErr_Clear(); goto done; } - Py_DECREF(cid); - cid = chan; + Py_DECREF(cidobj); + cidobj = chan; done: Py_DECREF(mod); - return cid; + return cidobj; } static int @@ -1865,7 +2531,7 @@ _channelid_shared(PyThreadState *tstate, PyObject *obj, return -1; } struct _channelid_xid *xid = (struct _channelid_xid *)data->data; - xid->id = ((channelid *)obj)->id; + xid->cid = ((channelid *)obj)->cid; xid->end = ((channelid *)obj)->end; xid->resolve = ((channelid *)obj)->resolve; return 0; @@ -1875,30 +2541,30 @@ static PyObject * channelid_end(PyObject *self, void *end) { int force = 1; - channelid *cid = (channelid *)self; + channelid *cidobj = (channelid *)self; if (end != NULL) { - PyObject *id = NULL; - int err = newchannelid(Py_TYPE(self), cid->id, *(int *)end, - cid->channels, force, cid->resolve, - (channelid **)&id); + PyObject *obj = NULL; + int err = newchannelid(Py_TYPE(self), cidobj->cid, *(int *)end, + cidobj->channels, force, cidobj->resolve, + (channelid **)&obj); if (err != 0) { - assert(id == NULL); + assert(obj == NULL); PyObject *mod = get_module_from_type(Py_TYPE(self)); if (mod == NULL) { return NULL; } - (void)handle_channel_error(err, mod, cid->id); + (void)handle_channel_error(err, mod, cidobj->cid); Py_DECREF(mod); return NULL; } - assert(id != NULL); - return id; + assert(obj != NULL); + return obj; } - if (cid->end == CHANNEL_SEND) { + if (cidobj->end == CHANNEL_SEND) { return PyUnicode_InternFromString("send"); } - if (cid->end == CHANNEL_RECV) { + if (cidobj->end == CHANNEL_RECV) { return PyUnicode_InternFromString("recv"); } return PyUnicode_InternFromString("both"); @@ -1920,7 +2586,7 @@ static PyGetSetDef channelid_getsets[] = { PyDoc_STRVAR(channelid_doc, "A channel ID identifies a channel and may be used as an int."); -static PyType_Slot ChannelIDType_slots[] = { +static PyType_Slot channelid_typeslots[] = { {Py_tp_dealloc, (destructor)channelid_dealloc}, {Py_tp_doc, (void *)channelid_doc}, {Py_tp_repr, (reprfunc)channelid_repr}, @@ -1934,15 +2600,119 @@ static PyType_Slot ChannelIDType_slots[] = { {0, NULL}, }; -static PyType_Spec ChannelIDType_spec = { +static PyType_Spec channelid_typespec = { .name = MODULE_NAME ".ChannelID", .basicsize = sizeof(channelid), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), - .slots = ChannelIDType_slots, + .slots = channelid_typeslots, }; +/* SendChannel and RecvChannel classes */ + +// XXX Use a new __xid__ protocol instead? + +static PyTypeObject * +_get_current_channelend_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) { + // Force the module to be loaded, to register the type. + PyObject *highlevel = PyImport_ImportModule("interpreters.channel"); + if (highlevel == NULL) { + PyErr_Clear(); + highlevel = PyImport_ImportModule("test.support.interpreters.channel"); + 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 * +_channelend_from_xid(_PyCrossInterpreterData *data) +{ + channelid *cidobj = (channelid *)_channelid_from_xid(data); + if (cidobj == NULL) { + return NULL; + } + PyTypeObject *cls = _get_current_channelend_type(cidobj->end); + if (cls == NULL) { + Py_DECREF(cidobj); + return NULL; + } + PyObject *obj = PyObject_CallOneArg((PyObject *)cls, (PyObject *)cidobj); + Py_DECREF(cidobj); + return obj; +} + +static int +_channelend_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 = _channelend_from_xid; + return 0; +} + +static int +set_channelend_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, _channelend_shared, xid_classes)) { + return -1; + } + if (register_xid_class(recv, _channelend_shared, xid_classes)) { + return -1; + } + + return 0; +} + + /* module level code ********************************************************/ /* globals is the process-global state for the module. It holds all @@ -1998,15 +2768,15 @@ clear_interpreter(void *data) } PyInterpreterState *interp = (PyInterpreterState *)data; assert(interp == _get_current_interp()); - int64_t id = PyInterpreterState_GetID(interp); - _channels_drop_interpreter(&_globals.channels, id); + int64_t interpid = PyInterpreterState_GetID(interp); + _channels_clear_interpreter(&_globals.channels, interpid); } static PyObject * -channel_create(PyObject *self, PyObject *Py_UNUSED(ignored)) +channelsmod_create(PyObject *self, PyObject *Py_UNUSED(ignored)) { - int64_t cid = _channel_create(&_globals.channels); + int64_t cid = channel_create(&_globals.channels); if (cid < 0) { (void)handle_channel_error(-1, self, cid); return NULL; @@ -2015,30 +2785,30 @@ channel_create(PyObject *self, PyObject *Py_UNUSED(ignored)) if (state == NULL) { return NULL; } - PyObject *id = NULL; + PyObject *cidobj = NULL; int err = newchannelid(state->ChannelIDType, cid, 0, &_globals.channels, 0, 0, - (channelid **)&id); + (channelid **)&cidobj); if (handle_channel_error(err, self, cid)) { - assert(id == NULL); - err = _channel_destroy(&_globals.channels, cid); + assert(cidobj == NULL); + err = channel_destroy(&_globals.channels, cid); if (handle_channel_error(err, self, cid)) { // XXX issue a warning? } return NULL; } - assert(id != NULL); - assert(((channelid *)id)->channels != NULL); - return id; + assert(cidobj != NULL); + assert(((channelid *)cidobj)->channels != NULL); + return cidobj; } -PyDoc_STRVAR(channel_create_doc, +PyDoc_STRVAR(channelsmod_create_doc, "channel_create() -> cid\n\ \n\ Create a new cross-interpreter channel and return a unique generated ID."); static PyObject * -channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) +channelsmod_destroy(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", NULL}; int64_t cid; @@ -2051,21 +2821,21 @@ channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) } cid = cid_data.cid; - int err = _channel_destroy(&_globals.channels, cid); + int err = channel_destroy(&_globals.channels, cid); if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; } -PyDoc_STRVAR(channel_destroy_doc, +PyDoc_STRVAR(channelsmod_destroy_doc, "channel_destroy(cid)\n\ \n\ Close and finalize the channel. Afterward attempts to use the channel\n\ will behave as though it never existed."); static PyObject * -channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) +channelsmod_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) { int64_t count = 0; int64_t *cids = _channels_list_all(&_globals.channels, &count); @@ -2087,17 +2857,17 @@ channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) } int64_t *cur = cids; for (int64_t i=0; i < count; cur++, i++) { - PyObject *id = NULL; + PyObject *cidobj = NULL; int err = newchannelid(state->ChannelIDType, *cur, 0, &_globals.channels, 0, 0, - (channelid **)&id); + (channelid **)&cidobj); if (handle_channel_error(err, self, *cur)) { - assert(id == NULL); + assert(cidobj == NULL); Py_SETREF(ids, NULL); break; } - assert(id != NULL); - PyList_SET_ITEM(ids, (Py_ssize_t)i, id); + assert(cidobj != NULL); + PyList_SET_ITEM(ids, (Py_ssize_t)i, cidobj); } finally: @@ -2105,13 +2875,13 @@ channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) return ids; } -PyDoc_STRVAR(channel_list_all_doc, +PyDoc_STRVAR(channelsmod_list_all_doc, "channel_list_all() -> [cid]\n\ \n\ Return the list of all IDs for active channels."); static PyObject * -channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) +channelsmod_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "send", NULL}; int64_t cid; /* Channel ID */ @@ -2119,8 +2889,8 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) .module = self, }; int send = 0; /* Send or receive end? */ - int64_t id; - PyObject *ids, *id_obj; + int64_t interpid; + PyObject *ids, *interpid_obj; PyInterpreterState *interp; if (!PyArg_ParseTupleAndKeywords( @@ -2137,20 +2907,20 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) interp = PyInterpreterState_Head(); while (interp != NULL) { - id = PyInterpreterState_GetID(interp); - assert(id >= 0); - int res = _channel_is_associated(&_globals.channels, cid, id, send); + interpid = PyInterpreterState_GetID(interp); + assert(interpid >= 0); + int res = channel_is_associated(&_globals.channels, cid, interpid, send); if (res < 0) { (void)handle_channel_error(res, self, cid); goto except; } if (res) { - id_obj = PyInterpreterState_GetIDObject(interp); - if (id_obj == NULL) { + interpid_obj = PyInterpreterState_GetIDObject(interp); + if (interpid_obj == NULL) { goto except; } - res = PyList_Insert(ids, 0, id_obj); - Py_DECREF(id_obj); + res = PyList_Insert(ids, 0, interpid_obj); + Py_DECREF(interpid_obj); if (res < 0) { goto except; } @@ -2167,7 +2937,7 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) return ids; } -PyDoc_STRVAR(channel_list_interpreters_doc, +PyDoc_STRVAR(channelsmod_list_interpreters_doc, "channel_list_interpreters(cid, *, send) -> [id]\n\ \n\ Return the list of all interpreter IDs associated with an end of the channel.\n\ @@ -2177,34 +2947,100 @@ receive end."); static PyObject * -channel_send(PyObject *self, PyObject *args, PyObject *kwds) +channelsmod_send(PyObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"cid", "obj", NULL}; - int64_t cid; + static char *kwlist[] = {"cid", "obj", "blocking", "timeout", NULL}; 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; + PyObject *timeout_obj = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O|$pO:channel_send", kwlist, + channel_id_converter, &cid_data, &obj, + &blocking, &timeout_obj)) { + return NULL; + } + + int64_t cid = cid_data.cid; + PY_TIMEOUT_T timeout; + if (PyThread_ParseTimeoutArg(timeout_obj, blocking, &timeout) < 0) { + return NULL; + } + + /* Queue up the object. */ + int err = 0; + if (blocking) { + err = channel_send_wait(&_globals.channels, cid, obj, timeout); + } + else { + err = channel_send(&_globals.channels, cid, obj, NULL); + } + if (handle_channel_error(err, self, cid)) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channelsmod_send_doc, +"channel_send(cid, obj, blocking=True)\n\ +\n\ +Add the object's data to the channel's queue.\n\ +By default this waits for the object to be received."); + +static PyObject * +channelsmod_send_buffer(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "obj", "blocking", "timeout", NULL}; + struct channel_id_converter_data cid_data = { + .module = self, + }; + PyObject *obj; + int blocking = 1; + PyObject *timeout_obj = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&O|$pO:channel_send_buffer", kwlist, + channel_id_converter, &cid_data, &obj, + &blocking, &timeout_obj)) { + return NULL; + } + + int64_t cid = cid_data.cid; + PY_TIMEOUT_T timeout; + if (PyThread_ParseTimeoutArg(timeout_obj, blocking, &timeout) < 0) { + return NULL; + } + + PyObject *tempobj = PyMemoryView_FromObject(obj); + if (tempobj == NULL) { return NULL; } - cid = cid_data.cid; - int err = _channel_send(&_globals.channels, cid, obj); + /* Queue up the object. */ + int err = 0; + if (blocking) { + err = channel_send_wait(&_globals.channels, cid, tempobj, timeout); + } + else { + 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_doc, -"channel_send(cid, obj)\n\ +PyDoc_STRVAR(channelsmod_send_buffer_doc, +"channel_send_buffer(cid, obj, blocking=True)\n\ \n\ -Add the object's data to the channel's queue."); +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) +channelsmod_recv(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "default", NULL}; int64_t cid; @@ -2219,7 +3055,7 @@ channel_recv(PyObject *self, PyObject *args, PyObject *kwds) cid = cid_data.cid; PyObject *obj = NULL; - int err = _channel_recv(&_globals.channels, cid, &obj); + int err = channel_recv(&_globals.channels, cid, &obj); if (handle_channel_error(err, self, cid)) { return NULL; } @@ -2236,7 +3072,7 @@ channel_recv(PyObject *self, PyObject *args, PyObject *kwds) return obj; } -PyDoc_STRVAR(channel_recv_doc, +PyDoc_STRVAR(channelsmod_recv_doc, "channel_recv(cid, [default]) -> obj\n\ \n\ Return a new object from the data at the front of the channel's queue.\n\ @@ -2245,7 +3081,7 @@ If there is nothing to receive then raise ChannelEmptyError, unless\n\ a default value is provided. In that case return it."); static PyObject * -channel_close(PyObject *self, PyObject *args, PyObject *kwds) +channelsmod_close(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; int64_t cid; @@ -2263,14 +3099,14 @@ channel_close(PyObject *self, PyObject *args, PyObject *kwds) } cid = cid_data.cid; - int err = _channel_close(&_globals.channels, cid, send-recv, force); + int err = channel_close(&_globals.channels, cid, send-recv, force); if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; } -PyDoc_STRVAR(channel_close_doc, +PyDoc_STRVAR(channelsmod_close_doc, "channel_close(cid, *, send=None, recv=None, force=False)\n\ \n\ Close the channel for all interpreters.\n\ @@ -2298,7 +3134,7 @@ Once the channel's ID has no more ref counts in any interpreter\n\ the channel will be destroyed."); static PyObject * -channel_release(PyObject *self, PyObject *args, PyObject *kwds) +channelsmod_release(PyObject *self, PyObject *args, PyObject *kwds) { // Note that only the current interpreter is affected. static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; @@ -2324,14 +3160,14 @@ channel_release(PyObject *self, PyObject *args, PyObject *kwds) // XXX Handle force is True. // XXX Fix implicit release. - int err = _channel_drop(&_globals.channels, cid, send, recv); + int err = channel_release(&_globals.channels, cid, send, recv); if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; } -PyDoc_STRVAR(channel_release_doc, +PyDoc_STRVAR(channelsmod_release_doc, "channel_release(cid, *, send=None, recv=None, force=True)\n\ \n\ Close the channel for the current interpreter. 'send' and 'recv'\n\ @@ -2339,40 +3175,101 @@ Close the channel for the current interpreter. 'send' and 'recv'\n\ ends are closed. Closing an already closed end is a noop."); static PyObject * -channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds) +channelsmod_get_info(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", NULL}; + struct channel_id_converter_data cid_data = { + .module = self, + }; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&:_get_info", kwlist, + channel_id_converter, &cid_data)) { + return NULL; + } + int64_t cid = cid_data.cid; + + struct channel_info info; + int err = _channel_get_info(&_globals.channels, cid, &info); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + return new_channel_info(self, &info); +} + +PyDoc_STRVAR(channelsmod_get_info_doc, +"get_info(cid)\n\ +\n\ +Return details about the channel."); + +static PyObject * +channelsmod__channel_id(PyObject *self, PyObject *args, PyObject *kwds) { module_state *state = get_module_state(self); if (state == NULL) { return NULL; } PyTypeObject *cls = state->ChannelIDType; + PyObject *mod = get_module_from_owned_type(cls); - if (mod == NULL) { + assert(mod == self); + Py_DECREF(mod); + + return _channelid_new(self, cls, args, kwds); +} + +static PyObject * +channelsmod__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_channelend_types(self, cls_send, cls_recv) < 0) { + return NULL; + } + + Py_RETURN_NONE; } static PyMethodDef module_functions[] = { - {"create", channel_create, - METH_NOARGS, channel_create_doc}, - {"destroy", _PyCFunction_CAST(channel_destroy), - METH_VARARGS | METH_KEYWORDS, channel_destroy_doc}, - {"list_all", channel_list_all, - METH_NOARGS, channel_list_all_doc}, - {"list_interpreters", _PyCFunction_CAST(channel_list_interpreters), - METH_VARARGS | METH_KEYWORDS, channel_list_interpreters_doc}, - {"send", _PyCFunction_CAST(channel_send), - METH_VARARGS | METH_KEYWORDS, channel_send_doc}, - {"recv", _PyCFunction_CAST(channel_recv), - METH_VARARGS | METH_KEYWORDS, channel_recv_doc}, - {"close", _PyCFunction_CAST(channel_close), - METH_VARARGS | METH_KEYWORDS, channel_close_doc}, - {"release", _PyCFunction_CAST(channel_release), - METH_VARARGS | METH_KEYWORDS, channel_release_doc}, - {"_channel_id", _PyCFunction_CAST(channel__channel_id), + {"create", channelsmod_create, + METH_NOARGS, channelsmod_create_doc}, + {"destroy", _PyCFunction_CAST(channelsmod_destroy), + METH_VARARGS | METH_KEYWORDS, channelsmod_destroy_doc}, + {"list_all", channelsmod_list_all, + METH_NOARGS, channelsmod_list_all_doc}, + {"list_interpreters", _PyCFunction_CAST(channelsmod_list_interpreters), + METH_VARARGS | METH_KEYWORDS, channelsmod_list_interpreters_doc}, + {"send", _PyCFunction_CAST(channelsmod_send), + METH_VARARGS | METH_KEYWORDS, channelsmod_send_doc}, + {"send_buffer", _PyCFunction_CAST(channelsmod_send_buffer), + METH_VARARGS | METH_KEYWORDS, channelsmod_send_buffer_doc}, + {"recv", _PyCFunction_CAST(channelsmod_recv), + METH_VARARGS | METH_KEYWORDS, channelsmod_recv_doc}, + {"close", _PyCFunction_CAST(channelsmod_close), + METH_VARARGS | METH_KEYWORDS, channelsmod_close_doc}, + {"release", _PyCFunction_CAST(channelsmod_release), + METH_VARARGS | METH_KEYWORDS, channelsmod_release_doc}, + {"get_info", _PyCFunction_CAST(channelsmod_get_info), + METH_VARARGS | METH_KEYWORDS, channelsmod_get_info_doc}, + {"_channel_id", _PyCFunction_CAST(channelsmod__channel_id), + METH_VARARGS | METH_KEYWORDS, NULL}, + {"_register_end_types", _PyCFunction_CAST(channelsmod__register_end_types), METH_VARARGS | METH_KEYWORDS, NULL}, {NULL, NULL} /* sentinel */ @@ -2391,6 +3288,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) { @@ -2398,25 +3302,33 @@ module_exec(PyObject *mod) } /* Add other types */ - module_state *state = get_module_state(mod); - if (state == NULL) { + + // ChannelInfo + state->ChannelInfoType = PyStructSequence_NewType(&channel_info_desc); + if (state->ChannelInfoType == NULL) { + goto error; + } + if (PyModule_AddType(mod, state->ChannelInfoType) < 0) { goto error; } // ChannelID state->ChannelIDType = add_new_type( - mod, &ChannelIDType_spec, _channelid_shared); + mod, &channelid_typespec, _channelid_shared, xid_classes); if (state->ChannelIDType == NULL) { goto error; } - // Make sure chnnels drop objects owned by this interpreter + /* Make sure chnnels drop objects owned by this interpreter. */ PyInterpreterState *interp = _get_current_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; } @@ -2441,6 +3353,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; } @@ -2450,7 +3367,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/_xxinterpqueuesmodule.c b/Modules/_xxinterpqueuesmodule.c new file mode 100644 index 00000000000000..2cc3a2ac5dc85f --- /dev/null +++ b/Modules/_xxinterpqueuesmodule.c @@ -0,0 +1,1685 @@ +/* interpreters module */ +/* low-level access to interpreter primitives */ + +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" +#include "pycore_crossinterp.h" // struct _xid + + +#define MODULE_NAME "_xxinterpqueues" + + +#define GLOBAL_MALLOC(TYPE) \ + PyMem_RawMalloc(sizeof(TYPE)) +#define GLOBAL_FREE(VAR) \ + PyMem_RawFree(VAR) + + +#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) +{ + // PyInterpreterState_Get() aborts if lookup fails, so don't need + // to check the result for NULL. + return PyInterpreterState_Get(); +} + +static PyObject * +_get_current_module(void) +{ + PyObject *name = PyUnicode_FromString(MODULE_NAME); + if (name == NULL) { + return NULL; + } + PyObject *mod = PyImport_GetModule(name); + Py_DECREF(name); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + return mod; +} + + +struct idarg_int64_converter_data { + // input: + const char *label; + // output: + int64_t id; +}; + +static int +idarg_int64_converter(PyObject *arg, void *ptr) +{ + int64_t id; + struct idarg_int64_converter_data *data = ptr; + + const char *label = data->label; + if (label == NULL) { + label = "ID"; + } + + if (PyIndex_Check(arg)) { + int overflow = 0; + id = PyLong_AsLongLongAndOverflow(arg, &overflow); + if (id == -1 && PyErr_Occurred()) { + return 0; + } + else if (id == -1 && overflow == 1) { + PyErr_Format(PyExc_OverflowError, + "max %s is %lld, got %R", label, INT64_MAX, arg); + return 0; + } + else if (id < 0) { + PyErr_Format(PyExc_ValueError, + "%s must be a non-negative int, got %R", label, arg); + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "%s must be an int, got %.100s", + label, Py_TYPE(arg)->tp_name); + return 0; + } + data->id = id; + return 1; +} + + +/* module state *************************************************************/ + +typedef struct { + /* external types (added at runtime by interpreters module) */ + PyTypeObject *queue_type; + + /* QueueError (and its subclasses) */ + PyObject *QueueError; + PyObject *QueueNotFoundError; + PyObject *QueueEmpty; + PyObject *QueueFull; +} module_state; + +static inline module_state * +get_module_state(PyObject *mod) +{ + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) +{ + /* external types */ + Py_VISIT(state->queue_type); + + /* QueueError */ + Py_VISIT(state->QueueError); + Py_VISIT(state->QueueNotFoundError); + Py_VISIT(state->QueueEmpty); + Py_VISIT(state->QueueFull); + + return 0; +} + +static int +clear_module_state(module_state *state) +{ + /* external types */ + Py_CLEAR(state->queue_type); + + /* QueueError */ + Py_CLEAR(state->QueueError); + Py_CLEAR(state->QueueNotFoundError); + Py_CLEAR(state->QueueEmpty); + Py_CLEAR(state->QueueFull); + + return 0; +} + + +/* error codes **************************************************************/ + +#define ERR_EXCEPTION_RAISED (-1) +// multi-queue errors +#define ERR_QUEUES_ALLOC (-11) +#define ERR_QUEUE_ALLOC (-12) +#define ERR_NO_NEXT_QUEUE_ID (-13) +#define ERR_QUEUE_NOT_FOUND (-14) +// single-queue errors +#define ERR_QUEUE_EMPTY (-21) +#define ERR_QUEUE_FULL (-22) + +static int +resolve_module_errcode(module_state *state, int errcode, int64_t qid, + PyObject **p_exctype, PyObject **p_msgobj) +{ + PyObject *exctype = NULL; + PyObject *msg = NULL; + switch (errcode) { + case ERR_NO_NEXT_QUEUE_ID: + exctype = state->QueueError; + msg = PyUnicode_FromString("ran out of queue IDs"); + break; + case ERR_QUEUE_NOT_FOUND: + exctype = state->QueueNotFoundError; + msg = PyUnicode_FromFormat("queue %" PRId64 " not found", qid); + break; + case ERR_QUEUE_EMPTY: + exctype = state->QueueEmpty; + msg = PyUnicode_FromFormat("queue %" PRId64 " is empty", qid); + break; + case ERR_QUEUE_FULL: + exctype = state->QueueFull; + msg = PyUnicode_FromFormat("queue %" PRId64 " is full", qid); + break; + default: + PyErr_Format(PyExc_ValueError, + "unsupported error code %d", errcode); + return -1; + } + + if (msg == NULL) { + assert(PyErr_Occurred()); + return -1; + } + *p_exctype = exctype; + *p_msgobj = msg; + return 0; +} + + +/* QueueError ***************************************************************/ + +static int +add_exctype(PyObject *mod, PyObject **p_state_field, + const char *qualname, const char *doc, PyObject *base) +{ + const char *dot = strrchr(qualname, '.'); + assert(dot != NULL); + const char *name = dot+1; + assert(*p_state_field == NULL); + assert(!PyObject_HasAttrStringWithError(mod, name)); + PyObject *exctype = PyErr_NewExceptionWithDoc(qualname, doc, base, NULL); + if (exctype == NULL) { + return -1; + } + if (PyModule_AddType(mod, (PyTypeObject *)exctype) < 0) { + Py_DECREF(exctype); + return -1; + } + *p_state_field = exctype; + return 0; +} + +static int +add_QueueError(PyObject *mod) +{ + module_state *state = get_module_state(mod); + +#define PREFIX "test.support.interpreters." +#define ADD_EXCTYPE(NAME, BASE, DOC) \ + if (add_exctype(mod, &state->NAME, PREFIX #NAME, DOC, BASE) < 0) { \ + return -1; \ + } + ADD_EXCTYPE(QueueError, PyExc_RuntimeError, + "Indicates that a queue-related error happened.") + ADD_EXCTYPE(QueueNotFoundError, state->QueueError, NULL) + ADD_EXCTYPE(QueueEmpty, state->QueueError, NULL) + ADD_EXCTYPE(QueueFull, state->QueueError, NULL) +#undef ADD_EXCTYPE +#undef PREFIX + + return 0; +} + +static int +handle_queue_error(int err, PyObject *mod, int64_t qid) +{ + if (err == 0) { + assert(!PyErr_Occurred()); + return 0; + } + assert(err < 0); + assert((err == -1) == (PyErr_Occurred() != NULL)); + + module_state *state; + switch (err) { + case ERR_QUEUE_ALLOC: // fall through + case ERR_QUEUES_ALLOC: + PyErr_NoMemory(); + break; + default: + state = get_module_state(mod); + assert(state->QueueError != NULL); + PyObject *exctype = NULL; + PyObject *msg = NULL; + if (resolve_module_errcode(state, err, qid, &exctype, &msg) < 0) { + return -1; + } + PyObject *exc = PyObject_CallOneArg(exctype, msg); + Py_DECREF(msg); + if (exc == NULL) { + return -1; + } + PyErr_SetObject(exctype, exc); + Py_DECREF(exc); + } + return 1; +} + + +/* the basic queue **********************************************************/ + +struct _queueitem; + +typedef struct _queueitem { + _PyCrossInterpreterData *data; + struct _queueitem *next; +} _queueitem; + +static void +_queueitem_init(_queueitem *item, _PyCrossInterpreterData *data) +{ + *item = (_queueitem){ + .data = data, + }; +} + +static void +_queueitem_clear(_queueitem *item) +{ + item->next = NULL; + + if (item->data != NULL) { + // It was allocated in queue_put(). + (void)_release_xid_data(item->data, XID_IGNORE_EXC & XID_FREE); + item->data = NULL; + } +} + +static _queueitem * +_queueitem_new(_PyCrossInterpreterData *data) +{ + _queueitem *item = GLOBAL_MALLOC(_queueitem); + if (item == NULL) { + PyErr_NoMemory(); + return NULL; + } + _queueitem_init(item, data); + return item; +} + +static void +_queueitem_free(_queueitem *item) +{ + _queueitem_clear(item); + GLOBAL_FREE(item); +} + +static void +_queueitem_free_all(_queueitem *item) +{ + while (item != NULL) { + _queueitem *last = item; + item = item->next; + _queueitem_free(last); + } +} + +static void +_queueitem_popped(_queueitem *item, _PyCrossInterpreterData **p_data) +{ + *p_data = item->data; + // We clear them here, so they won't be released in _queueitem_clear(). + item->data = NULL; + _queueitem_free(item); +} + + +/* the queue */ +typedef struct _queue { + Py_ssize_t num_waiters; // protected by global lock + PyThread_type_lock mutex; + int alive; + struct _queueitems { + Py_ssize_t maxsize; + Py_ssize_t count; + _queueitem *first; + _queueitem *last; + } items; +} _queue; + +static int +_queue_init(_queue *queue, Py_ssize_t maxsize) +{ + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return ERR_QUEUE_ALLOC; + } + *queue = (_queue){ + .mutex = mutex, + .alive = 1, + .items = { + .maxsize = maxsize, + }, + }; + return 0; +} + +static void +_queue_clear(_queue *queue) +{ + assert(!queue->alive); + assert(queue->num_waiters == 0); + _queueitem_free_all(queue->items.first); + assert(queue->mutex != NULL); + PyThread_free_lock(queue->mutex); + *queue = (_queue){0}; +} + +static void +_queue_kill_and_wait(_queue *queue) +{ + // Mark it as dead. + PyThread_acquire_lock(queue->mutex, WAIT_LOCK); + assert(queue->alive); + queue->alive = 0; + PyThread_release_lock(queue->mutex); + + // Wait for all waiters to fail. + while (queue->num_waiters > 0) { + PyThread_acquire_lock(queue->mutex, WAIT_LOCK); + PyThread_release_lock(queue->mutex); + }; +} + +static void +_queue_mark_waiter(_queue *queue, PyThread_type_lock parent_mutex) +{ + if (parent_mutex != NULL) { + PyThread_acquire_lock(parent_mutex, WAIT_LOCK); + queue->num_waiters += 1; + PyThread_release_lock(parent_mutex); + } + else { + // The caller must be holding the parent lock already. + queue->num_waiters += 1; + } +} + +static void +_queue_unmark_waiter(_queue *queue, PyThread_type_lock parent_mutex) +{ + if (parent_mutex != NULL) { + PyThread_acquire_lock(parent_mutex, WAIT_LOCK); + queue->num_waiters -= 1; + PyThread_release_lock(parent_mutex); + } + else { + // The caller must be holding the parent lock already. + queue->num_waiters -= 1; + } +} + +static int +_queue_lock(_queue *queue) +{ + // The queue must be marked as a waiter already. + PyThread_acquire_lock(queue->mutex, WAIT_LOCK); + if (!queue->alive) { + PyThread_release_lock(queue->mutex); + return ERR_QUEUE_NOT_FOUND; + } + return 0; +} + +static void +_queue_unlock(_queue *queue) +{ + PyThread_release_lock(queue->mutex); +} + +static int +_queue_add(_queue *queue, _PyCrossInterpreterData *data) +{ + int err = _queue_lock(queue); + if (err < 0) { + return err; + } + + Py_ssize_t maxsize = queue->items.maxsize; + if (maxsize <= 0) { + maxsize = PY_SSIZE_T_MAX; + } + if (queue->items.count >= maxsize) { + _queue_unlock(queue); + return ERR_QUEUE_FULL; + } + + _queueitem *item = _queueitem_new(data); + if (item == NULL) { + _queue_unlock(queue); + return -1; + } + + queue->items.count += 1; + if (queue->items.first == NULL) { + queue->items.first = item; + } + else { + queue->items.last->next = item; + } + queue->items.last = item; + + _queue_unlock(queue); + return 0; +} + +static int +_queue_next(_queue *queue, _PyCrossInterpreterData **p_data) +{ + int err = _queue_lock(queue); + if (err < 0) { + return err; + } + + assert(queue->items.count >= 0); + _queueitem *item = queue->items.first; + if (item == NULL) { + _queue_unlock(queue); + return ERR_QUEUE_EMPTY; + } + queue->items.first = item->next; + if (queue->items.last == item) { + queue->items.last = NULL; + } + queue->items.count -= 1; + + _queueitem_popped(item, p_data); + + _queue_unlock(queue); + return 0; +} + +static int +_queue_get_maxsize(_queue *queue, Py_ssize_t *p_maxsize) +{ + int err = _queue_lock(queue); + if (err < 0) { + return err; + } + + *p_maxsize = queue->items.maxsize; + + _queue_unlock(queue); + return 0; +} + +static int +_queue_is_full(_queue *queue, int *p_is_full) +{ + int err = _queue_lock(queue); + if (err < 0) { + return err; + } + + assert(queue->items.count <= queue->items.maxsize); + *p_is_full = queue->items.count == queue->items.maxsize; + + _queue_unlock(queue); + return 0; +} + +static int +_queue_get_count(_queue *queue, Py_ssize_t *p_count) +{ + int err = _queue_lock(queue); + if (err < 0) { + return err; + } + + *p_count = queue->items.count; + + _queue_unlock(queue); + return 0; +} + +static void +_queue_clear_interpreter(_queue *queue, int64_t interpid) +{ + int err = _queue_lock(queue); + if (err == ERR_QUEUE_NOT_FOUND) { + // The queue is already destroyed, so there's nothing to clear. + assert(!PyErr_Occurred()); + return; + } + assert(err == 0); // There should be no other errors. + + _queueitem *prev = NULL; + _queueitem *next = queue->items.first; + while (next != NULL) { + _queueitem *item = next; + next = item->next; + if (item->data->interpid == interpid) { + if (prev == NULL) { + queue->items.first = item->next; + } + else { + prev->next = item->next; + } + _queueitem_free(item); + queue->items.count -= 1; + } + else { + prev = item; + } + } + + _queue_unlock(queue); +} + + +/* external queue references ************************************************/ + +struct _queueref; + +typedef struct _queueref { + struct _queueref *next; + int64_t qid; + Py_ssize_t refcount; + _queue *queue; +} _queueref; + +static _queueref * +_queuerefs_find(_queueref *first, int64_t qid, _queueref **pprev) +{ + _queueref *prev = NULL; + _queueref *ref = first; + while (ref != NULL) { + if (ref->qid == qid) { + break; + } + prev = ref; + ref = ref->next; + } + if (pprev != NULL) { + *pprev = prev; + } + return ref; +} + + +/* a collection of queues ***************************************************/ + +typedef struct _queues { + PyThread_type_lock mutex; + _queueref *head; + int64_t count; + int64_t next_id; +} _queues; + +static void +_queues_init(_queues *queues, PyThread_type_lock mutex) +{ + queues->mutex = mutex; + queues->head = NULL; + queues->count = 0; + queues->next_id = 1; +} + +static void +_queues_fini(_queues *queues) +{ + assert(queues->count == 0); + assert(queues->head == NULL); + if (queues->mutex != NULL) { + PyThread_free_lock(queues->mutex); + queues->mutex = NULL; + } +} + +static int64_t +_queues_next_id(_queues *queues) // needs lock +{ + int64_t qid = queues->next_id; + if (qid < 0) { + /* overflow */ + return ERR_NO_NEXT_QUEUE_ID; + } + queues->next_id += 1; + return qid; +} + +static int +_queues_lookup(_queues *queues, int64_t qid, _queue **res) +{ + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + + _queueref *ref = _queuerefs_find(queues->head, qid, NULL); + if (ref == NULL) { + PyThread_release_lock(queues->mutex); + return ERR_QUEUE_NOT_FOUND; + } + assert(ref->queue != NULL); + _queue *queue = ref->queue; + _queue_mark_waiter(queue, NULL); + // The caller must unmark it. + + PyThread_release_lock(queues->mutex); + + *res = queue; + return 0; +} + +static int64_t +_queues_add(_queues *queues, _queue *queue) +{ + int64_t qid = -1; + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + + // Create a new ref. + int64_t _qid = _queues_next_id(queues); + if (_qid < 0) { + goto done; + } + _queueref *ref = GLOBAL_MALLOC(_queueref); + if (ref == NULL) { + qid = ERR_QUEUE_ALLOC; + goto done; + } + *ref = (_queueref){ + .qid = _qid, + .queue = queue, + }; + + // Add it to the list. + // We assume that the queue is a new one (not already in the list). + ref->next = queues->head; + queues->head = ref; + queues->count += 1; + + qid = _qid; +done: + PyThread_release_lock(queues->mutex); + return qid; +} + +static void +_queues_remove_ref(_queues *queues, _queueref *ref, _queueref *prev, + _queue **p_queue) +{ + assert(ref->queue != NULL); + + if (ref == queues->head) { + queues->head = ref->next; + } + else { + prev->next = ref->next; + } + ref->next = NULL; + queues->count -= 1; + + *p_queue = ref->queue; + ref->queue = NULL; + GLOBAL_FREE(ref); +} + +static int +_queues_remove(_queues *queues, int64_t qid, _queue **p_queue) +{ + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + + _queueref *prev = NULL; + _queueref *ref = _queuerefs_find(queues->head, qid, &prev); + if (ref == NULL) { + PyThread_release_lock(queues->mutex); + return ERR_QUEUE_NOT_FOUND; + } + + _queues_remove_ref(queues, ref, prev, p_queue); + PyThread_release_lock(queues->mutex); + + return 0; +} + +static int +_queues_incref(_queues *queues, int64_t qid) +{ + // XXX Track interpreter IDs? + int res = -1; + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + + _queueref *ref = _queuerefs_find(queues->head, qid, NULL); + if (ref == NULL) { + assert(!PyErr_Occurred()); + res = ERR_QUEUE_NOT_FOUND; + goto done; + } + ref->refcount += 1; + + res = 0; +done: + PyThread_release_lock(queues->mutex); + return res; +} + +static void _queue_free(_queue *); + +static void +_queues_decref(_queues *queues, int64_t qid) +{ + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + + _queueref *prev = NULL; + _queueref *ref = _queuerefs_find(queues->head, qid, &prev); + if (ref == NULL) { + assert(!PyErr_Occurred()); + // Already destroyed. + // XXX Warn? + goto finally; + } + assert(ref->refcount > 0); + ref->refcount -= 1; + + // Destroy if no longer used. + assert(ref->queue != NULL); + if (ref->refcount == 0) { + _queue *queue = NULL; + _queues_remove_ref(queues, ref, prev, &queue); + PyThread_release_lock(queues->mutex); + + _queue_kill_and_wait(queue); + _queue_free(queue); + return; + } + +finally: + PyThread_release_lock(queues->mutex); +} + +static int64_t * +_queues_list_all(_queues *queues, int64_t *count) +{ + int64_t *qids = NULL; + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + int64_t *ids = PyMem_NEW(int64_t, (Py_ssize_t)(queues->count)); + if (ids == NULL) { + goto done; + } + _queueref *ref = queues->head; + for (int64_t i=0; ref != NULL; ref = ref->next, i++) { + ids[i] = ref->qid; + } + *count = queues->count; + + qids = ids; +done: + PyThread_release_lock(queues->mutex); + return qids; +} + +static void +_queues_clear_interpreter(_queues *queues, int64_t interpid) +{ + PyThread_acquire_lock(queues->mutex, WAIT_LOCK); + + _queueref *ref = queues->head; + for (; ref != NULL; ref = ref->next) { + assert(ref->queue != NULL); + _queue_clear_interpreter(ref->queue, interpid); + } + + PyThread_release_lock(queues->mutex); +} + + +/* "high"-level queue-related functions *************************************/ + +static void +_queue_free(_queue *queue) +{ + _queue_clear(queue); + GLOBAL_FREE(queue); +} + +// Create a new queue. +static int64_t +queue_create(_queues *queues, Py_ssize_t maxsize) +{ + _queue *queue = GLOBAL_MALLOC(_queue); + if (queue == NULL) { + return ERR_QUEUE_ALLOC; + } + int err = _queue_init(queue, maxsize); + if (err < 0) { + GLOBAL_FREE(queue); + return (int64_t)err; + } + int64_t qid = _queues_add(queues, queue); + if (qid < 0) { + _queue_clear(queue); + GLOBAL_FREE(queue); + } + return qid; +} + +// Completely destroy the queue. +static int +queue_destroy(_queues *queues, int64_t qid) +{ + _queue *queue = NULL; + int err = _queues_remove(queues, qid, &queue); + if (err < 0) { + return err; + } + _queue_kill_and_wait(queue); + _queue_free(queue); + return 0; +} + +// Push an object onto the queue. +static int +queue_put(_queues *queues, int64_t qid, PyObject *obj) +{ + // Look up the queue. + _queue *queue = NULL; + int err = _queues_lookup(queues, qid, &queue); + if (err != 0) { + return err; + } + assert(queue != NULL); + + // Convert the object to cross-interpreter data. + _PyCrossInterpreterData *data = GLOBAL_MALLOC(_PyCrossInterpreterData); + if (data == NULL) { + _queue_unmark_waiter(queue, queues->mutex); + return -1; + } + if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { + _queue_unmark_waiter(queue, queues->mutex); + GLOBAL_FREE(data); + return -1; + } + + // Add the data to the queue. + int res = _queue_add(queue, data); + _queue_unmark_waiter(queue, queues->mutex); + if (res != 0) { + // We may chain an exception here: + (void)_release_xid_data(data, 0); + GLOBAL_FREE(data); + return res; + } + + return 0; +} + +// Pop the next object off the queue. Fail if empty. +// XXX Support a "wait" mutex? +static int +queue_get(_queues *queues, int64_t qid, PyObject **res) +{ + int err; + *res = NULL; + + // Look up the queue. + _queue *queue = NULL; + err = _queues_lookup(queues, qid, &queue); + if (err != 0) { + return err; + } + // Past this point we are responsible for releasing the mutex. + assert(queue != NULL); + + // Pop off the next item from the queue. + _PyCrossInterpreterData *data = NULL; + err = _queue_next(queue, &data); + _queue_unmark_waiter(queue, queues->mutex); + if (err != 0) { + return err; + } + else if (data == NULL) { + assert(!PyErr_Occurred()); + return 0; + } + + // Convert the data back to an object. + PyObject *obj = _PyCrossInterpreterData_NewObject(data); + if (obj == NULL) { + assert(PyErr_Occurred()); + // It was allocated in queue_put(), so we free it. + (void)_release_xid_data(data, XID_IGNORE_EXC | XID_FREE); + return -1; + } + // It was allocated in queue_put(), 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()); + Py_DECREF(obj); + return -1; + } + + *res = obj; + return 0; +} + +static int +queue_get_maxsize(_queues *queues, int64_t qid, Py_ssize_t *p_maxsize) +{ + _queue *queue = NULL; + int err = _queues_lookup(queues, qid, &queue); + if (err < 0) { + return err; + } + err = _queue_get_maxsize(queue, p_maxsize); + _queue_unmark_waiter(queue, queues->mutex); + return err; +} + +static int +queue_is_full(_queues *queues, int64_t qid, int *p_is_full) +{ + _queue *queue = NULL; + int err = _queues_lookup(queues, qid, &queue); + if (err < 0) { + return err; + } + err = _queue_is_full(queue, p_is_full); + _queue_unmark_waiter(queue, queues->mutex); + return err; +} + +static int +queue_get_count(_queues *queues, int64_t qid, Py_ssize_t *p_count) +{ + _queue *queue = NULL; + int err = _queues_lookup(queues, qid, &queue); + if (err < 0) { + return err; + } + err = _queue_get_count(queue, p_count); + _queue_unmark_waiter(queue, queues->mutex); + return err; +} + + +/* external Queue objects ***************************************************/ + +static int _queueobj_shared(PyThreadState *, + PyObject *, _PyCrossInterpreterData *); + +static int +set_external_queue_type(PyObject *module, PyTypeObject *queue_type) +{ + module_state *state = get_module_state(module); + + if (state->queue_type != NULL) { + PyErr_SetString(PyExc_TypeError, "already registered"); + return -1; + } + state->queue_type = (PyTypeObject *)Py_NewRef(queue_type); + + if (_PyCrossInterpreterData_RegisterClass(queue_type, _queueobj_shared) < 0) { + return -1; + } + + return 0; +} + +static PyTypeObject * +get_external_queue_type(PyObject *module) +{ + module_state *state = get_module_state(module); + + PyTypeObject *cls = state->queue_type; + if (cls == NULL) { + // Force the module to be loaded, to register the type. + PyObject *highlevel = PyImport_ImportModule("interpreters.queue"); + if (highlevel == NULL) { + PyErr_Clear(); + highlevel = PyImport_ImportModule("test.support.interpreters.queue"); + if (highlevel == NULL) { + return NULL; + } + } + Py_DECREF(highlevel); + cls = state->queue_type; + assert(cls != NULL); + } + return cls; +} + + +// XXX Use a new __xid__ protocol instead? + +struct _queueid_xid { + int64_t qid; +}; + +static _queues * _get_global_queues(void); + +static void * +_queueid_xid_new(int64_t qid) +{ + _queues *queues = _get_global_queues(); + if (_queues_incref(queues, qid) < 0) { + return NULL; + } + + struct _queueid_xid *data = PyMem_RawMalloc(sizeof(struct _queueid_xid)); + if (data == NULL) { + _queues_incref(queues, qid); + return NULL; + } + data->qid = qid; + return (void *)data; +} + +static void +_queueid_xid_free(void *data) +{ + int64_t qid = ((struct _queueid_xid *)data)->qid; + PyMem_RawFree(data); + _queues *queues = _get_global_queues(); + _queues_decref(queues, qid); +} + +static PyObject * +_queueobj_from_xid(_PyCrossInterpreterData *data) +{ + int64_t qid = *(int64_t *)data->data; + PyObject *qidobj = PyLong_FromLongLong(qid); + if (qidobj == NULL) { + return NULL; + } + + PyObject *mod = _get_current_module(); + if (mod == NULL) { + // XXX import it? + PyErr_SetString(PyExc_RuntimeError, + MODULE_NAME " module not imported yet"); + return NULL; + } + + PyTypeObject *cls = get_external_queue_type(mod); + Py_DECREF(mod); + if (cls == NULL) { + Py_DECREF(qidobj); + return NULL; + } + PyObject *obj = PyObject_CallOneArg((PyObject *)cls, (PyObject *)qidobj); + Py_DECREF(qidobj); + return obj; +} + +static int +_queueobj_shared(PyThreadState *tstate, PyObject *queueobj, + _PyCrossInterpreterData *data) +{ + PyObject *qidobj = PyObject_GetAttrString(queueobj, "_id"); + if (qidobj == NULL) { + return -1; + } + struct idarg_int64_converter_data converted = { + .label = "queue ID", + }; + int res = idarg_int64_converter(qidobj, &converted); + Py_DECREF(qidobj); + if (!res) { + assert(PyErr_Occurred()); + return -1; + } + + void *raw = _queueid_xid_new(converted.id); + if (raw == NULL) { + Py_DECREF(qidobj); + return -1; + } + _PyCrossInterpreterData_Init(data, tstate->interp, raw, NULL, + _queueobj_from_xid); + Py_DECREF(qidobj); + data->free = _queueid_xid_free; + return 0; +} + + +/* module level code ********************************************************/ + +/* globals is the process-global state for the module. It holds all + the data that we need to share between interpreters, so it cannot + hold PyObject values. */ +static struct globals { + int module_count; + _queues queues; +} _globals = {0}; + +static int +_globals_init(void) +{ + // XXX This isn't thread-safe. + _globals.module_count++; + if (_globals.module_count > 1) { + // Already initialized. + return 0; + } + + assert(_globals.queues.mutex == NULL); + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return ERR_QUEUES_ALLOC; + } + _queues_init(&_globals.queues, mutex); + return 0; +} + +static void +_globals_fini(void) +{ + // XXX This isn't thread-safe. + _globals.module_count--; + if (_globals.module_count > 0) { + return; + } + + _queues_fini(&_globals.queues); +} + +static _queues * +_get_global_queues(void) +{ + return &_globals.queues; +} + + +static void +clear_interpreter(void *data) +{ + if (_globals.module_count == 0) { + return; + } + PyInterpreterState *interp = (PyInterpreterState *)data; + assert(interp == _get_current_interp()); + int64_t interpid = PyInterpreterState_GetID(interp); + _queues_clear_interpreter(&_globals.queues, interpid); +} + + +typedef struct idarg_int64_converter_data qidarg_converter_data; + +static int +qidarg_converter(PyObject *arg, void *ptr) +{ + qidarg_converter_data *data = ptr; + if (data->label == NULL) { + data->label = "queue ID"; + } + return idarg_int64_converter(arg, ptr); +} + + +static PyObject * +queuesmod_create(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"maxsize", NULL}; + Py_ssize_t maxsize = -1; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|n:create", kwlist, + &maxsize)) { + return NULL; + } + + int64_t qid = queue_create(&_globals.queues, maxsize); + if (qid < 0) { + (void)handle_queue_error((int)qid, self, qid); + return NULL; + } + + PyObject *qidobj = PyLong_FromLongLong(qid); + if (qidobj == NULL) { + PyObject *exc = PyErr_GetRaisedException(); + int err = queue_destroy(&_globals.queues, qid); + if (handle_queue_error(err, self, qid)) { + // XXX issue a warning? + PyErr_Clear(); + } + PyErr_SetRaisedException(exc); + return NULL; + } + + return qidobj; +} + +PyDoc_STRVAR(queuesmod_create_doc, +"create() -> qid\n\ +\n\ +Create a new cross-interpreter queue and return its unique generated ID.\n\ +It is a new reference as though bind() had been called on the queue."); + +static PyObject * +queuesmod_destroy(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", NULL}; + qidarg_converter_data qidarg; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:destroy", kwlist, + qidarg_converter, &qidarg)) { + return NULL; + } + int64_t qid = qidarg.id; + + int err = queue_destroy(&_globals.queues, qid); + if (handle_queue_error(err, self, qid)) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(queuesmod_destroy_doc, +"destroy(qid)\n\ +\n\ +Clear and destroy the queue. Afterward attempts to use the queue\n\ +will behave as though it never existed."); + +static PyObject * +queuesmod_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + int64_t count = 0; + int64_t *qids = _queues_list_all(&_globals.queues, &count); + if (qids == NULL) { + if (count == 0) { + return PyList_New(0); + } + return NULL; + } + PyObject *ids = PyList_New((Py_ssize_t)count); + if (ids == NULL) { + goto finally; + } + int64_t *cur = qids; + for (int64_t i=0; i < count; cur++, i++) { + PyObject *qidobj = PyLong_FromLongLong(*cur); + if (qidobj == NULL) { + Py_SETREF(ids, NULL); + break; + } + PyList_SET_ITEM(ids, (Py_ssize_t)i, qidobj); + } + +finally: + PyMem_Free(qids); + return ids; +} + +PyDoc_STRVAR(queuesmod_list_all_doc, +"list_all() -> [qid]\n\ +\n\ +Return the list of IDs for all queues."); + +static PyObject * +queuesmod_put(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", "obj", NULL}; + qidarg_converter_data qidarg; + PyObject *obj; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:put", kwlist, + qidarg_converter, &qidarg, &obj)) { + return NULL; + } + int64_t qid = qidarg.id; + + /* Queue up the object. */ + int err = queue_put(&_globals.queues, qid, obj); + if (handle_queue_error(err, self, qid)) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(queuesmod_put_doc, +"put(qid, obj)\n\ +\n\ +Add the object's data to the queue."); + +static PyObject * +queuesmod_get(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", "default", NULL}; + qidarg_converter_data qidarg; + PyObject *dflt = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O:get", kwlist, + qidarg_converter, &qidarg, &dflt)) { + return NULL; + } + int64_t qid = qidarg.id; + + PyObject *obj = NULL; + int err = queue_get(&_globals.queues, qid, &obj); + if (err == ERR_QUEUE_EMPTY && dflt != NULL) { + assert(obj == NULL); + obj = Py_NewRef(dflt); + } + else if (handle_queue_error(err, self, qid)) { + return NULL; + } + return obj; +} + +PyDoc_STRVAR(queuesmod_get_doc, +"get(qid, [default]) -> obj\n\ +\n\ +Return a new object from the data at the front of the queue.\n\ +\n\ +If there is nothing to receive then raise QueueEmpty, unless\n\ +a default value is provided. In that case return it."); + +static PyObject * +queuesmod_bind(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", NULL}; + qidarg_converter_data qidarg; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:bind", kwlist, + qidarg_converter, &qidarg)) { + return NULL; + } + int64_t qid = qidarg.id; + + // XXX Check module state if bound already. + + int err = _queues_incref(&_globals.queues, qid); + if (handle_queue_error(err, self, qid)) { + return NULL; + } + + // XXX Update module state. + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(queuesmod_bind_doc, +"bind(qid)\n\ +\n\ +Take a reference to the identified queue.\n\ +The queue is not destroyed until there are no references left."); + +static PyObject * +queuesmod_release(PyObject *self, PyObject *args, PyObject *kwds) +{ + // Note that only the current interpreter is affected. + static char *kwlist[] = {"qid", NULL}; + qidarg_converter_data qidarg; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&:release", kwlist, + qidarg_converter, &qidarg)) { + return NULL; + } + int64_t qid = qidarg.id; + + // XXX Check module state if bound already. + // XXX Update module state. + + _queues_decref(&_globals.queues, qid); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(queuesmod_release_doc, +"release(qid)\n\ +\n\ +Release a reference to the queue.\n\ +The queue is destroyed once there are no references left."); + +static PyObject * +queuesmod_get_maxsize(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", NULL}; + qidarg_converter_data qidarg; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&:get_maxsize", kwlist, + qidarg_converter, &qidarg)) { + return NULL; + } + int64_t qid = qidarg.id; + + Py_ssize_t maxsize = -1; + int err = queue_get_maxsize(&_globals.queues, qid, &maxsize); + if (handle_queue_error(err, self, qid)) { + return NULL; + } + return PyLong_FromLongLong(maxsize); +} + +PyDoc_STRVAR(queuesmod_get_maxsize_doc, +"get_maxsize(qid)\n\ +\n\ +Return the maximum number of items in the queue."); + +static PyObject * +queuesmod_is_full(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", NULL}; + qidarg_converter_data qidarg; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&:is_full", kwlist, + qidarg_converter, &qidarg)) { + return NULL; + } + int64_t qid = qidarg.id; + + int is_full; + int err = queue_is_full(&_globals.queues, qid, &is_full); + if (handle_queue_error(err, self, qid)) { + return NULL; + } + if (is_full) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(queuesmod_is_full_doc, +"is_full(qid)\n\ +\n\ +Return true if the queue has a maxsize and has reached it."); + +static PyObject * +queuesmod_get_count(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"qid", NULL}; + qidarg_converter_data qidarg; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&:get_count", kwlist, + qidarg_converter, &qidarg)) { + return NULL; + } + int64_t qid = qidarg.id; + + Py_ssize_t count = -1; + int err = queue_get_count(&_globals.queues, qid, &count); + if (handle_queue_error(err, self, qid)) { + return NULL; + } + assert(count >= 0); + return PyLong_FromSsize_t(count); +} + +PyDoc_STRVAR(queuesmod_get_count_doc, +"get_count(qid)\n\ +\n\ +Return the number of items in the queue."); + +static PyObject * +queuesmod__register_queue_type(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"queuetype", NULL}; + PyObject *queuetype; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O:_register_queue_type", kwlist, + &queuetype)) { + return NULL; + } + if (!PyType_Check(queuetype)) { + PyErr_SetString(PyExc_TypeError, "expected a type for 'queuetype'"); + return NULL; + } + PyTypeObject *cls_queue = (PyTypeObject *)queuetype; + + if (set_external_queue_type(self, cls_queue) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +static PyMethodDef module_functions[] = { + {"create", _PyCFunction_CAST(queuesmod_create), + METH_VARARGS | METH_KEYWORDS, queuesmod_create_doc}, + {"destroy", _PyCFunction_CAST(queuesmod_destroy), + METH_VARARGS | METH_KEYWORDS, queuesmod_destroy_doc}, + {"list_all", queuesmod_list_all, + METH_NOARGS, queuesmod_list_all_doc}, + {"put", _PyCFunction_CAST(queuesmod_put), + METH_VARARGS | METH_KEYWORDS, queuesmod_put_doc}, + {"get", _PyCFunction_CAST(queuesmod_get), + METH_VARARGS | METH_KEYWORDS, queuesmod_get_doc}, + {"bind", _PyCFunction_CAST(queuesmod_bind), + METH_VARARGS | METH_KEYWORDS, queuesmod_bind_doc}, + {"release", _PyCFunction_CAST(queuesmod_release), + METH_VARARGS | METH_KEYWORDS, queuesmod_release_doc}, + {"get_maxsize", _PyCFunction_CAST(queuesmod_get_maxsize), + METH_VARARGS | METH_KEYWORDS, queuesmod_get_maxsize_doc}, + {"is_full", _PyCFunction_CAST(queuesmod_is_full), + METH_VARARGS | METH_KEYWORDS, queuesmod_is_full_doc}, + {"get_count", _PyCFunction_CAST(queuesmod_get_count), + METH_VARARGS | METH_KEYWORDS, queuesmod_get_count_doc}, + {"_register_queue_type", _PyCFunction_CAST(queuesmod__register_queue_type), + METH_VARARGS | METH_KEYWORDS, NULL}, + + {NULL, NULL} /* sentinel */ +}; + + +/* initialization function */ + +PyDoc_STRVAR(module_doc, +"This module provides primitive operations to manage Python interpreters.\n\ +The 'interpreters' module provides a more convenient interface."); + +static int +module_exec(PyObject *mod) +{ + if (_globals_init() != 0) { + return -1; + } + + /* Add exception types */ + if (add_QueueError(mod) < 0) { + goto error; + } + + /* Make sure queues drop objects owned by this interpreter. */ + PyInterpreterState *interp = _get_current_interp(); + PyUnstable_AtExit(interp, clear_interpreter, (void *)interp); + + return 0; + +error: + _globals_fini(); + return -1; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) +{ + module_state *state = get_module_state(mod); + traverse_module_state(state, visit, arg); + return 0; +} + +static int +module_clear(PyObject *mod) +{ + module_state *state = get_module_state(mod); + + if (state->queue_type != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->queue_type); + } + + // Now we clear the module state. + clear_module_state(state); + return 0; +} + +static void +module_free(void *mod) +{ + module_state *state = get_module_state(mod); + + // Now we clear the module state. + clear_module_state(state); + + _globals_fini(); +} + +static struct PyModuleDef moduledef = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = module_doc, + .m_size = sizeof(module_state), + .m_methods = module_functions, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; + +PyMODINIT_FUNC +PyInit__xxinterpqueues(void) +{ + return PyModuleDef_Init(&moduledef); +} diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 1ddf64909bf18a..4e9e13457a9eb3 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -6,487 +6,498 @@ #endif #include "Python.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_crossinterp.h" // struct _xid +#include "pycore_interp.h" // _PyInterpreterState_IDIncref() #include "pycore_initconfig.h" // _PyErr_SetFromPyStatus() -#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() +#include "pycore_long.h" // _PyLong_IsNegative() +#include "pycore_modsupport.h" // _PyArg_BadArgument() +#include "pycore_pybuffer.h" // _PyBuffer_ReleaseInInterpreterAndRawFree() +#include "pycore_pyerrors.h" // _Py_excinfo +#include "pycore_pystate.h" // _PyInterpreterState_SetRunningMain() + #include "interpreteridobject.h" +#include "marshal.h" // PyMarshal_ReadObjectFromString() #define MODULE_NAME "_xxsubinterpreters" -static const char * -_copy_raw_string(PyObject *strobj) +static PyInterpreterState * +_get_current_interp(void) { - const char *str = PyUnicode_AsUTF8(strobj); - if (str == NULL) { - return NULL; + // PyInterpreterState_Get() aborts if lookup fails, so don't need + // to check the result for NULL. + return PyInterpreterState_Get(); +} + +static int64_t +pylong_to_interpid(PyObject *idobj) +{ + assert(PyLong_CheckExact(idobj)); + + if (_PyLong_IsNegative((PyLongObject *)idobj)) { + PyErr_Format(PyExc_ValueError, + "interpreter ID must be a non-negative int, got %R", + idobj); + return -1; } - char *copied = PyMem_RawMalloc(strlen(str)+1); - if (copied == NULL) { - PyErr_NoMemory(); - return NULL; + + int overflow; + long long id = PyLong_AsLongLongAndOverflow(idobj, &overflow); + if (id == -1) { + if (!overflow) { + assert(PyErr_Occurred()); + return -1; + } + assert(!PyErr_Occurred()); + // For now, we don't worry about if LLONG_MAX < INT64_MAX. + goto bad_id; + } +#if LLONG_MAX > INT64_MAX + if (id > INT64_MAX) { + goto bad_id; } - strcpy(copied, str); - return copied; +#endif + return (int64_t)id; + +bad_id: + PyErr_Format(PyExc_RuntimeError, + "unrecognized interpreter ID %O", idobj); + return -1; +} + +static int64_t +convert_interpid_obj(PyObject *arg) +{ + int64_t id = -1; + if (_PyIndex_Check(arg)) { + PyObject *idobj = PyNumber_Long(arg); + if (idobj == NULL) { + return -1; + } + id = pylong_to_interpid(idobj); + Py_DECREF(idobj); + if (id < 0) { + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "interpreter ID must be an int, got %.100s", + Py_TYPE(arg)->tp_name); + return -1; + } + return id; } static PyInterpreterState * -_get_current_interp(void) +look_up_interp(PyObject *arg) { - // PyInterpreterState_Get() aborts if lookup fails, so don't need - // to check the result for NULL. - return PyInterpreterState_Get(); + int64_t id = convert_interpid_obj(arg); + if (id < 0) { + return NULL; + } + return _PyInterpreterState_LookUpID(id); +} + + +static PyObject * +interpid_to_pylong(int64_t id) +{ + assert(id < LLONG_MAX); + return PyLong_FromLongLong(id); } static PyObject * -add_new_exception(PyObject *mod, const char *name, PyObject *base) +get_interpid_obj(PyInterpreterState *interp) { - assert(!PyObject_HasAttrStringWithError(mod, name)); - PyObject *exctype = PyErr_NewException(name, base, NULL); - if (exctype == NULL) { + if (_PyInterpreterState_IDInitref(interp) != 0) { return NULL; - } - int res = PyModule_AddType(mod, (PyTypeObject *)exctype); - if (res < 0) { - Py_DECREF(exctype); + }; + int64_t id = PyInterpreterState_GetID(interp); + if (id < 0) { return NULL; } - return exctype; + return interpid_to_pylong(id); } -#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \ - add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE) - -static int -_release_xid_data(_PyCrossInterpreterData *data) +static PyObject * +_get_current_module(void) { - PyObject *exc = PyErr_GetRaisedException(); - int res = _PyCrossInterpreterData_Release(data); - if (res < 0) { - /* The owning interpreter is already destroyed. */ - _PyCrossInterpreterData_Clear(NULL, data); - // XXX Emit a warning? - PyErr_Clear(); + PyObject *name = PyUnicode_FromString(MODULE_NAME); + if (name == NULL) { + return NULL; } - PyErr_SetRaisedException(exc); - return res; + PyObject *mod = PyImport_GetModule(name); + Py_DECREF(name); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + return mod; } -/* module state *************************************************************/ +/* Cross-interpreter Buffer Views *******************************************/ + +// XXX Release when the original interpreter is destroyed. typedef struct { - /* exceptions */ - PyObject *RunFailedError; -} module_state; + PyObject_HEAD + Py_buffer *view; + int64_t interpid; +} XIBufferViewObject; -static inline module_state * -get_module_state(PyObject *mod) +static PyObject * +xibufferview_from_xid(PyTypeObject *cls, _PyCrossInterpreterData *data) { - assert(mod != NULL); - module_state *state = PyModule_GetState(mod); - assert(state != NULL); - return state; + assert(data->data != NULL); + assert(data->obj == NULL); + assert(data->interpid >= 0); + XIBufferViewObject *self = PyObject_Malloc(sizeof(XIBufferViewObject)); + if (self == NULL) { + return NULL; + } + PyObject_Init((PyObject *)self, cls); + self->view = (Py_buffer *)data->data; + self->interpid = data->interpid; + return (PyObject *)self; } -static int -traverse_module_state(module_state *state, visitproc visit, void *arg) +static void +xibufferview_dealloc(XIBufferViewObject *self) { - /* exceptions */ - Py_VISIT(state->RunFailedError); + PyInterpreterState *interp = _PyInterpreterState_LookUpID(self->interpid); + /* If the interpreter is no longer alive then we have problems, + since other objects may be using the buffer still. */ + assert(interp != NULL); - return 0; + 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 -clear_module_state(module_state *state) +xibufferview_getbuf(XIBufferViewObject *self, Py_buffer *view, int flags) { - /* exceptions */ - Py_CLEAR(state->RunFailedError); - + /* 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}, +}; -/* data-sharing-specific code ***********************************************/ - -struct _sharednsitem { - const char *name; - _PyCrossInterpreterData data; +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, }; -static void _sharednsitem_clear(struct _sharednsitem *); // forward -static int -_sharednsitem_init(struct _sharednsitem *item, PyObject *key, PyObject *value) +static PyTypeObject * _get_current_xibufferview_type(void); + +static PyObject * +_memoryview_from_xid(_PyCrossInterpreterData *data) { - item->name = _copy_raw_string(key); - if (item->name == NULL) { - return -1; + PyTypeObject *cls = _get_current_xibufferview_type(); + if (cls == NULL) { + return NULL; } - if (_PyObject_GetCrossInterpreterData(value, &item->data) != 0) { - _sharednsitem_clear(item); - return -1; + PyObject *obj = xibufferview_from_xid(cls, data); + if (obj == NULL) { + return NULL; } - return 0; + return PyMemoryView_FromObject(obj); } -static void -_sharednsitem_clear(struct _sharednsitem *item) +static int +_memoryview_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - if (item->name != NULL) { - PyMem_RawFree((void *)item->name); - item->name = NULL; + Py_buffer *view = PyMem_RawMalloc(sizeof(Py_buffer)); + if (view == NULL) { + return -1; } - (void)_release_xid_data(&item->data); + 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 -_sharednsitem_apply(struct _sharednsitem *item, PyObject *ns) +register_memoryview_xid(PyObject *mod, PyTypeObject **p_state) { - PyObject *name = PyUnicode_FromString(item->name); - if (name == NULL) { + // XIBufferView + assert(*p_state == NULL); + PyTypeObject *cls = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &XIBufferViewType_spec, NULL); + if (cls == NULL) { return -1; } - PyObject *value = _PyCrossInterpreterData_NewObject(&item->data); - if (value == NULL) { - Py_DECREF(name); + if (PyModule_AddType(mod, cls) < 0) { + Py_DECREF(cls); return -1; } - int res = PyDict_SetItem(ns, name, value); - Py_DECREF(name); - Py_DECREF(value); - return res; + *p_state = cls; + + // Register XID for the builtin memoryview type. + if (_PyCrossInterpreterData_RegisterClass( + &PyMemoryView_Type, _memoryview_shared) < 0) { + return -1; + } + // We don't ever bother un-registering memoryview. + + return 0; } -typedef struct _sharedns { - Py_ssize_t len; - struct _sharednsitem* items; -} _sharedns; -static _sharedns * -_sharedns_new(Py_ssize_t len) + +/* module state *************************************************************/ + +typedef struct { + int _notused; + + /* heap types */ + PyTypeObject *XIBufferViewType; +} module_state; + +static inline module_state * +get_module_state(PyObject *mod) { - _sharedns *shared = PyMem_RawCalloc(sizeof(_sharedns), 1); - if (shared == NULL) { - PyErr_NoMemory(); - return NULL; - } - shared->len = len; - shared->items = PyMem_RawCalloc(sizeof(struct _sharednsitem), len); - if (shared->items == NULL) { - PyErr_NoMemory(); - PyMem_RawFree(shared); - return NULL; - } - return shared; + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; } -static void -_sharedns_free(_sharedns *shared) +static module_state * +_get_current_module_state(void) { - for (Py_ssize_t i=0; i < shared->len; i++) { - _sharednsitem_clear(&shared->items[i]); + PyObject *mod = _get_current_module(); + if (mod == NULL) { + // XXX import it? + PyErr_SetString(PyExc_RuntimeError, + MODULE_NAME " module not imported yet"); + return NULL; } - PyMem_RawFree(shared->items); - PyMem_RawFree(shared); + module_state *state = get_module_state(mod); + Py_DECREF(mod); + return state; } -static _sharedns * -_get_shared_ns(PyObject *shareable) +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) { - if (shareable == NULL || shareable == Py_None) { - return NULL; - } - Py_ssize_t len = PyDict_Size(shareable); - if (len == 0) { - return NULL; - } + /* heap types */ + Py_VISIT(state->XIBufferViewType); - _sharedns *shared = _sharedns_new(len); - if (shared == NULL) { - return NULL; - } - Py_ssize_t pos = 0; - for (Py_ssize_t i=0; i < len; i++) { - PyObject *key, *value; - if (PyDict_Next(shareable, &pos, &key, &value) == 0) { - break; - } - if (_sharednsitem_init(&shared->items[i], key, value) != 0) { - break; - } - } - if (PyErr_Occurred()) { - _sharedns_free(shared); - return NULL; - } - return shared; + return 0; } static int -_sharedns_apply(_sharedns *shared, PyObject *ns) +clear_module_state(module_state *state) { - for (Py_ssize_t i=0; i < shared->len; i++) { - if (_sharednsitem_apply(&shared->items[i], ns) != 0) { - return -1; - } - } + /* heap types */ + Py_CLEAR(state->XIBufferViewType); + return 0; } -// Ultimately we'd like to preserve enough information about the -// exception and traceback that we could re-constitute (or at least -// simulate, a la traceback.TracebackException), and even chain, a copy -// of the exception in the calling interpreter. -typedef struct _sharedexception { - const char *name; - const char *msg; -} _sharedexception; +static PyTypeObject * +_get_current_xibufferview_type(void) +{ + module_state *state = _get_current_module_state(); + if (state == NULL) { + return NULL; + } + return state->XIBufferViewType; +} + -static const struct _sharedexception no_exception = { - .name = NULL, - .msg = NULL, -}; +/* Python code **************************************************************/ -static void -_sharedexception_clear(_sharedexception *exc) +static const char * +check_code_str(PyUnicodeObject *text) { - if (exc->name != NULL) { - PyMem_RawFree((void *)exc->name); - } - if (exc->msg != NULL) { - PyMem_RawFree((void *)exc->msg); + assert(text != NULL); + if (PyUnicode_GET_LENGTH(text) == 0) { + return "too short"; } + + // XXX Verify that it parses? + + return NULL; } static const char * -_sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) +check_code_object(PyCodeObject *code) { - 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"; - goto error; + 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"; } - sharedexc->name = _copy_raw_string(nameobj); - Py_DECREF(nameobj); - if (sharedexc->name == NULL) { - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - failure = "out of memory copying exception type name"; - } else { - failure = "unable to encode and copy exception type name"; - } - goto error; + if (code->co_ncellvars > 0) { + return "closures not supported"; } + // We trust that no code objects under co_consts have unbound cell vars. - if (exc != NULL) { - PyObject *msgobj = PyUnicode_FromFormat("%S", exc); - if (msgobj == NULL) { - failure = "unable to format exception message"; - goto error; - } - sharedexc->msg = _copy_raw_string(msgobj); - Py_DECREF(msgobj); - if (sharedexc->msg == NULL) { - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - failure = "out of memory copying exception message"; - } else { - failure = "unable to encode and copy exception message"; - } - goto error; - } + 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; - -error: - assert(failure != NULL); - PyErr_Clear(); - _sharedexception_clear(sharedexc); - *sharedexc = no_exception; - return failure; } -static void -_sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) +#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) { - if (exc->name != NULL) { - if (exc->msg != NULL) { - PyErr_Format(wrapperclass, "%s: %s", exc->name, exc->msg); + 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; } - else { - PyErr_SetString(wrapperclass, exc->name); + if (strlen(codestr) != (size_t)len) { + PyErr_SetString(PyExc_ValueError, + "source code string cannot contain null bytes"); + return NULL; } - } - else if (exc->msg != NULL) { - PyErr_SetString(wrapperclass, exc->msg); + flags = RUN_TEXT; } else { - PyErr_SetNone(wrapperclass); - } -} - + assert(PyCode_Check(arg) + && (check_code_object((PyCodeObject *)arg) == NULL)); + flags = RUN_CODE; -/* interpreter-specific code ************************************************/ - -static int -exceptions_init(PyObject *mod) -{ - module_state *state = get_module_state(mod); - if (state == NULL) { - return -1; + // 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); } -#define ADD(NAME, BASE) \ - do { \ - assert(state->NAME == NULL); \ - state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \ - if (state->NAME == NULL) { \ - return -1; \ - } \ - } while (0) - - // An uncaught exception came out of interp_run_string(). - ADD(RunFailedError, PyExc_RuntimeError); -#undef ADD - - return 0; + *flags_p = flags; + *bytes_p = bytes_obj; + *len_p = len; + return codestr; } -static int -_is_running(PyInterpreterState *interp) -{ - 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->current_frame; - if (frame == NULL) { - return 0; - } - return 1; -} -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; - } - return 0; -} +/* interpreter-specific code ************************************************/ static int -_run_script(PyInterpreterState *interp, const char *codestr, - _sharedns *shared, _sharedexception *sharedexc) +_run_script(PyObject *ns, const char *codestr, Py_ssize_t codestrlen, int flags) { - PyObject *excval = NULL; - PyObject *main_mod = PyUnstable_InterpreterState_GetMainModule(interp); - if (main_mod == NULL) { - goto error; - } - PyObject *ns = PyModule_GetDict(main_mod); // borrowed - Py_DECREF(main_mod); - if (ns == NULL) { - goto error; - } - Py_INCREF(ns); - - // Apply the cross-interpreter data. - if (shared != NULL) { - if (_sharedns_apply(shared, ns) != 0) { - Py_DECREF(ns); - goto error; + 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); } } - - // Run the string (see PyRun_SimpleStringFlags). - PyObject *result = PyRun_StringFlags(codestr, Py_file_input, ns, ns, NULL); - Py_DECREF(ns); - if (result == NULL) { - goto error; - } else { - Py_DECREF(result); // We throw away the result. + Py_UNREACHABLE(); } - - *sharedexc = no_exception; - return 0; - -error: - excval = PyErr_GetRaisedException(); - const char *failure = _sharedexception_bind(excval, sharedexc); - if (failure != NULL) { - fprintf(stderr, - "RunFailedError: script raised an uncaught exception (%s)", - failure); - PyErr_Clear(); + if (result == NULL) { + return -1; } - Py_XDECREF(excval); - assert(!PyErr_Occurred()); - return -1; + Py_DECREF(result); // We throw away the result. + return 0; } static int -_run_script_in_interpreter(PyObject *mod, PyInterpreterState *interp, - const char *codestr, PyObject *shareables) +_run_in_interpreter(PyInterpreterState *interp, + const char *codestr, Py_ssize_t codestrlen, + PyObject *shareables, int flags, + PyObject **p_excinfo) { - if (_ensure_not_running(interp) < 0) { - return -1; - } - module_state *state = get_module_state(mod); - - _sharedns *shared = _get_shared_ns(shareables); - if (shared == NULL && PyErr_Occurred()) { + assert(!PyErr_Occurred()); + _PyXI_session session = {0}; + + // Prep and switch interpreters. + if (_PyXI_Enter(&session, interp, shareables) < 0) { + assert(!PyErr_Occurred()); + PyObject *excinfo = _PyXI_ApplyError(session.error); + if (excinfo != NULL) { + *p_excinfo = excinfo; + } + assert(PyErr_Occurred()); return -1; } - // Switch to interpreter. - PyThreadState *save_tstate = NULL; - if (interp != PyInterpreterState_Get()) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - // XXX Possible GILState issues? - save_tstate = PyThreadState_Swap(tstate); - } - // Run the script. - _sharedexception exc = {NULL, NULL}; - int result = _run_script(interp, codestr, shared, &exc); + int res = _run_script(session.main_ns, codestr, codestrlen, flags); - // Switch back. - if (save_tstate != NULL) { - PyThreadState_Swap(save_tstate); - } + // Clean up and switch back. + _PyXI_Exit(&session); // Propagate any exception out to the caller. - if (exc.name != NULL) { - assert(state != NULL); - _sharedexception_apply(&exc, state->RunFailedError); - } - else if (result != 0) { - // We were unable to allocate a shared exception. - PyErr_NoMemory(); + assert(!PyErr_Occurred()); + if (res < 0) { + PyObject *excinfo = _PyXI_ApplyCapturedException(&session); + if (excinfo != NULL) { + *p_excinfo = excinfo; + } } - - if (shared != NULL) { - _sharedns_free(shared); + else { + assert(!_PyXI_HasCapturedException(&session)); } - return result; + return res; } @@ -509,6 +520,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); @@ -524,8 +536,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 = get_interpid_obj(interp); if (idobj == NULL) { // XXX Possible GILState issues? save_tstate = PyThreadState_Swap(tstate); @@ -533,6 +546,12 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) PyThreadState_Swap(save_tstate); return NULL; } + + PyThreadState_Swap(tstate); + PyThreadState_Clear(tstate); + PyThreadState_Swap(save_tstate); + PyThreadState_Delete(tstate); + _PyInterpreterState_RequireIDRef(interp, 1); return idobj; } @@ -540,7 +559,9 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) PyDoc_STRVAR(create_doc, "create() -> ID\n\ \n\ -Create a new interpreter and return a unique generated ID."); +Create a new interpreter and return a unique generated ID.\n\ +\n\ +The caller is responsible for destroying the interpreter before exiting."); static PyObject * @@ -555,7 +576,7 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) } // Look up the interpreter. - PyInterpreterState *interp = PyInterpreterID_LookUp(id); + PyInterpreterState *interp = look_up_interp(id); if (interp == NULL) { return NULL; } @@ -574,12 +595,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); @@ -610,7 +633,7 @@ interp_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) interp = PyInterpreterState_Head(); while (interp != NULL) { - id = PyInterpreterState_GetIDObject(interp); + id = get_interpid_obj(interp); if (id == NULL) { Py_DECREF(ids); return NULL; @@ -642,7 +665,7 @@ interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored)) if (interp == NULL) { return NULL; } - return PyInterpreterState_GetIDObject(interp); + return get_interpid_obj(interp); } PyDoc_STRVAR(get_current_doc, @@ -656,7 +679,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 PyLong_FromLongLong(id); } PyDoc_STRVAR(get_main_doc, @@ -664,16 +687,13 @@ PyDoc_STRVAR(get_main_doc, \n\ Return the ID of main interpreter."); - static PyObject * -interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) +interp_set___main___attrs(PyObject *self, PyObject *args) { - static char *kwlist[] = {"id", "script", "shared", NULL}; - PyObject *id, *code; - PyObject *shared = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "OU|O:run_string", kwlist, - &id, &code, &shared)) { + PyObject *id, *updates; + if (!PyArg_ParseTuple(args, "OO:" MODULE_NAME ".set___main___attrs", + &id, &updates)) + { return NULL; } @@ -683,31 +703,276 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } + // Check the updates. + if (updates != Py_None) { + Py_ssize_t size = PyObject_Size(updates); + if (size < 0) { + return NULL; + } + if (size == 0) { + PyErr_SetString(PyExc_ValueError, + "arg 2 must be a non-empty mapping"); + return NULL; + } + } + + _PyXI_session session = {0}; + + // Prep and switch interpreters, including apply the updates. + if (_PyXI_Enter(&session, interp, updates) < 0) { + if (!PyErr_Occurred()) { + _PyXI_ApplyCapturedException(&session); + assert(PyErr_Occurred()); + } + else { + assert(!_PyXI_HasCapturedException(&session)); + } + return NULL; + } + + // Clean up and switch back. + _PyXI_Exit(&session); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(set___main___attrs_doc, +"set___main___attrs(id, ns)\n\ +\n\ +Bind the given attributes in the interpreter's __main__ module."); + +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, + PyObject **p_excinfo) +{ + // Look up the interpreter. + PyInterpreterState *interp = look_up_interp(id_arg); + if (interp == NULL) { + return -1; + } + // Extract code. - Py_ssize_t size; - const char *codestr = PyUnicode_AsUTF8AndSize(code, &size); + 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(interp, codestr, codestrlen, + shared_arg, flags, p_excinfo); + Py_XDECREF(bytes_obj); + if (res < 0) { + return -1; + } + + return 0; +} + +static PyObject * +interp_exec(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "code", "shared", NULL}; + PyObject *id, *code; + PyObject *shared = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "OO|O:" MODULE_NAME ".exec", kwlist, + &id, &code, &shared)) { return NULL; } - if (strlen(codestr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, - "source code string cannot contain null bytes"); + + 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; } - // Run the code in the interpreter. - if (_run_script_in_interpreter(self, interp, codestr, shared) != 0) { + PyObject *excinfo = NULL; + int res = _interp_exec(self, id, code, shared, &excinfo); + Py_DECREF(code); + if (res < 0) { + assert((excinfo == NULL) != (PyErr_Occurred() == NULL)); + return excinfo; + } + 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; + } + + script = (PyObject *)convert_script_arg(script, MODULE_NAME ".exec", + "argument 2", "a string"); + if (script == NULL) { return NULL; } + + PyObject *excinfo = NULL; + int res = _interp_exec(self, id, script, shared, &excinfo); + Py_DECREF(script); + if (res < 0) { + assert((excinfo == NULL) != (PyErr_Occurred() == NULL)); + return excinfo; + } 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; + } + + PyObject *excinfo = NULL; + int res = _interp_exec(self, id, (PyObject *)code, shared, &excinfo); + Py_DECREF(code); + if (res < 0) { + assert((excinfo == NULL) != (PyErr_Occurred() == NULL)); + return excinfo; + } + 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 * @@ -744,15 +1009,11 @@ interp_is_running(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - PyInterpreterState *interp = PyInterpreterID_LookUp(id); + PyInterpreterState *interp = look_up_interp(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; @@ -763,6 +1024,50 @@ PyDoc_STRVAR(is_running_doc, \n\ Return whether or not the identified interpreter is running."); + +static PyObject * +interp_incref(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", NULL}; + PyObject *id; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O:_incref", kwlist, &id)) { + return NULL; + } + + PyInterpreterState *interp = look_up_interp(id); + if (interp == NULL) { + return NULL; + } + if (_PyInterpreterState_IDInitref(interp) < 0) { + return NULL; + } + _PyInterpreterState_IDIncref(interp); + + Py_RETURN_NONE; +} + + +static PyObject * +interp_decref(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", NULL}; + PyObject *id; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O:_incref", kwlist, &id)) { + return NULL; + } + + PyInterpreterState *interp = look_up_interp(id); + if (interp == NULL) { + return NULL; + } + _PyInterpreterState_IDDecref(interp); + + Py_RETURN_NONE; +} + + static PyMethodDef module_functions[] = { {"create", _PyCFunction_CAST(interp_create), METH_VARARGS | METH_KEYWORDS, create_doc}, @@ -777,12 +1082,23 @@ 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}, + {"set___main___attrs", _PyCFunction_CAST(interp_set___main___attrs), + METH_VARARGS, set___main___attrs_doc}, {"is_shareable", _PyCFunction_CAST(object_is_shareable), METH_VARARGS | METH_KEYWORDS, is_shareable_doc}, + {"_incref", _PyCFunction_CAST(interp_incref), + METH_VARARGS | METH_KEYWORDS, NULL}, + {"_decref", _PyCFunction_CAST(interp_decref), + METH_VARARGS | METH_KEYWORDS, NULL}, + {NULL, NULL} /* sentinel */ }; @@ -796,13 +1112,17 @@ The 'interpreters' module provides a more convenient interface."); static int module_exec(PyObject *mod) { - /* Add exception types */ - if (exceptions_init(mod) != 0) { + module_state *state = get_module_state(mod); + + // exceptions + if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterError) < 0) { + goto error; + } + if (PyModule_AddType(mod, (PyTypeObject *)PyExc_InterpreterNotFoundError) < 0) { goto error; } - // PyInterpreterID - if (PyModule_AddType(mod, &PyInterpreterID_Type) < 0) { + if (register_memoryview_xid(mod, &state->XIBufferViewType) < 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/dictionaries/fuzz_elementtree_parsewhole.dict b/Modules/_xxtestfuzz/dictionaries/fuzz_elementtree_parsewhole.dict new file mode 100644 index 00000000000000..e1b58cdb248238 --- /dev/null +++ b/Modules/_xxtestfuzz/dictionaries/fuzz_elementtree_parsewhole.dict @@ -0,0 +1,134 @@ +tok_1="<" +tok_2=">" +tok_3="/" +tok_4="" +tok_6="" +tok_7="version" +tok_8="encoding" +tok_9="UTF-8" +tok_9a="UTF-16" +tok_9b="ASCII" +tok_9c="LATIN-1" +tok_9d="UTF-32" +tok_9e="UTF-7" +tok_10="\"" +tok_11="&" +tok_11a="&#" +tok_11b=";" +tok_12="'" +tok_13="" +tok_14="" +tag_doctype="" +tag_open_close="" +tag_open_exclamation="" +tag_xml_q="" + +encoding_utf="UTF-" +encoding_iso1="ISO-8859" +encoding_iso3="ISO-10646-UCS" +encoding_iso5="ISO-LATIN-1" +encoding_jis="SHIFT_JIS" +encoding_utf7="UTF-7" +encoding_utf16le="UTF-16BE" +encoding_utf16le="UTF-16LE" +encoding_ascii="US-ASCII" +encoding_latin1="latin1" diff --git a/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict b/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict new file mode 100644 index 00000000000000..c6a44d946284ef --- /dev/null +++ b/Modules/_xxtestfuzz/dictionaries/fuzz_pycompile.dict @@ -0,0 +1,165 @@ +# bits of syntax +"( " +") " +"[ " +"] " +": " +", " +"; " +"{ " +"} " + +# operators +"+ " +"- " +"* " +"** " +"/ " +"// " +"| " +"& " +"< " +"> " +"= " +". " +"% " +"` " +"^ " +"~ " +"@ " +"== " +"!= " +"<> " +"<< " +"<= " +">= " +">> " +"+= " +"-= " +"*= " +"** " +"/= " +"//= " +"|= " +"%= " +"&= " +"^= " +"<<= " +">>= " +"**= " +":= " +"@= " + +# whitespace +" " +":\\n " + +# type signatures and functions +"-> " +": List[int]" +": Dict[int, str]" + +"# type:" +"# type: List[int]" +"# type: Dict[int, str]" + +", *" +", /" +", *args" +", **kwargs" +", x=42" + + +# literals +"0x0a" +"0b0000" +"42" +"0o70" +"42j" +"42.01" +"-5" +"+42e-3" +"0_0_0" +"1e1_0" +".1_4" + +"{}" + +# variable names +"x" +"y" + +# strings +"r'x'" + +"b'x'" + +"rb\"x\"" + +"br\"x\"" + +"f'{x + 5}'" +"f\"{x + 5}\"" + +"'''" +"\"\"\"" + +"\\u" +"\\x" + +# keywords +"def " +"del " +"pass " +"break " +"continue " +"return " +"raise " +"from " +"import " +".. " +"... " +"__future__ " +"as " +"global " +"nonlocal " +"assert " +"print " +"if " +"elif " +"else: " +"while " +"try: " +"except " +"finally: " +"with " +"lambda " +"or " +"and " +"not " +"None " +"__peg_parser__" +"True " +"False " +"yield " +"async " +"await " +"for " +"in " +"is " +"class " + +# shebangs and encodings +"#!" +"# coding:" +"# coding=" +"# coding: latin-1" +"# coding=latin-1" +"# coding: utf-8" +"# coding=utf-8" +"# coding: ascii" +"# coding=ascii" +"# coding: cp860" +"# coding=cp860" +"# coding: gbk" +"# coding=gbk" diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nComment.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nComment.xml new file mode 100644 index 00000000000000..e95aa302d04fdb --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nComment.xml @@ -0,0 +1,4 @@ + + true + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nDefault.xml new file mode 100644 index 00000000000000..c1364142cc59bf --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nDefault.xml @@ -0,0 +1,3 @@ + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefix.xml new file mode 100644 index 00000000000000..fb233b42b1334f --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefix.xml @@ -0,0 +1,4 @@ + + sequential + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefixQname.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefixQname.xml new file mode 100644 index 00000000000000..23188eedbc2451 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefixQname.xml @@ -0,0 +1,7 @@ + + sequential + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefixQnameXpathElem.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefixQnameXpathElem.xml new file mode 100644 index 00000000000000..626fc48f410fa0 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nPrefixQnameXpathElem.xml @@ -0,0 +1,8 @@ + + sequential + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQname.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQname.xml new file mode 100644 index 00000000000000..919e5903f5ce6e --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQname.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQnameElem.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQnameElem.xml new file mode 100644 index 00000000000000..0321f8061952e6 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQnameElem.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQnameXpathElem.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQnameXpathElem.xml new file mode 100644 index 00000000000000..c4890bc8b01d5e --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nQnameXpathElem.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nTrim.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nTrim.xml new file mode 100644 index 00000000000000..ccb9cf65db7235 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/c14nTrim.xml @@ -0,0 +1,4 @@ + + true + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/expat224_utf8_bug.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/expat224_utf8_bug.xml new file mode 100644 index 00000000000000..d66a8e6b50f93b --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/expat224_utf8_bug.xml @@ -0,0 +1,2 @@ + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N1.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N1.xml new file mode 100644 index 00000000000000..ed450c7341d382 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N1.xml @@ -0,0 +1,14 @@ + + + + + + +Hello, world! + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N2.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N2.xml new file mode 100644 index 00000000000000..74eeea147c3791 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N2.xml @@ -0,0 +1,11 @@ + + + A B + + A + + B + A B + C + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N3.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N3.xml new file mode 100644 index 00000000000000..fea78213f1ae69 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N3.xml @@ -0,0 +1,18 @@ +]> + + + + + + + + + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N4.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N4.xml new file mode 100644 index 00000000000000..909a847435b86c --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N4.xml @@ -0,0 +1,13 @@ + + +]> + + First line Second line + 2 + "0" && value<"10" ?"valid":"error"]]> + valid + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N5.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N5.xml new file mode 100644 index 00000000000000..501161bad5187f --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N5.xml @@ -0,0 +1,12 @@ + + + + + +]> + + &ent1;, &ent2;! + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N6.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N6.xml new file mode 100644 index 00000000000000..31e2071867257c --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inC14N6.xml @@ -0,0 +1,2 @@ + +© diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsContent.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsContent.xml new file mode 100644 index 00000000000000..b9924660ba6da3 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsContent.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsDefault.xml new file mode 100644 index 00000000000000..3e0d323bad27c2 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsDefault.xml @@ -0,0 +1,3 @@ + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsPushdown.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsPushdown.xml new file mode 100644 index 00000000000000..daa67d83f15914 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsPushdown.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsRedecl.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsRedecl.xml new file mode 100644 index 00000000000000..10bd97beda3baa --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsRedecl.xml @@ -0,0 +1,3 @@ + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsSort.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsSort.xml new file mode 100644 index 00000000000000..8e9fc01c647b24 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsSort.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsSuperfluous.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsSuperfluous.xml new file mode 100644 index 00000000000000..f77720f7b0b09d --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsSuperfluous.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsXml.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsXml.xml new file mode 100644 index 00000000000000..7520cf3fb9eb28 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/inNsXml.xml @@ -0,0 +1,3 @@ + + data + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N1_c14nComment.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N1_c14nComment.xml new file mode 100644 index 00000000000000..d98d16840c6bcc --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N1_c14nComment.xml @@ -0,0 +1,6 @@ + +Hello, world! + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N1_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N1_c14nDefault.xml new file mode 100644 index 00000000000000..af9a9770578e9d --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N1_c14nDefault.xml @@ -0,0 +1,4 @@ + +Hello, world! + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N2_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N2_c14nDefault.xml new file mode 100644 index 00000000000000..2afa15ccb36382 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N2_c14nDefault.xml @@ -0,0 +1,11 @@ + + + A B + + A + + B + A B + C + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N2_c14nTrim.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N2_c14nTrim.xml new file mode 100644 index 00000000000000..7a1dc32946bce3 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N2_c14nTrim.xml @@ -0,0 +1 @@ +A BABA BC \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nDefault.xml new file mode 100644 index 00000000000000..662e108aa8a1e4 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nDefault.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nPrefix.xml new file mode 100644 index 00000000000000..041e1ec8ebe59a --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nPrefix.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nTrim.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nTrim.xml new file mode 100644 index 00000000000000..4f35ad9662df3b --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N3_c14nTrim.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N4_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N4_c14nDefault.xml new file mode 100644 index 00000000000000..243d0e61f2e94f --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N4_c14nDefault.xml @@ -0,0 +1,10 @@ + + First line +Second line + 2 + value>"0" && value<"10" ?"valid":"error" + valid + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N4_c14nTrim.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N4_c14nTrim.xml new file mode 100644 index 00000000000000..24d83ba8ab0012 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N4_c14nTrim.xml @@ -0,0 +1,2 @@ +First line +Second line2value>"0" && value<"10" ?"valid":"error"valid \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N5_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N5_c14nDefault.xml new file mode 100644 index 00000000000000..c232e740aee4a7 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N5_c14nDefault.xml @@ -0,0 +1,3 @@ + + Hello, world! + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N5_c14nTrim.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N5_c14nTrim.xml new file mode 100644 index 00000000000000..3fa84b1e986014 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N5_c14nTrim.xml @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N6_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N6_c14nDefault.xml new file mode 100644 index 00000000000000..0be38f98cb1398 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inC14N6_c14nDefault.xml @@ -0,0 +1 @@ +© \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nDefault.xml new file mode 100644 index 00000000000000..62d7e004a44034 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nDefault.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nPrefixQnameXpathElem.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nPrefixQnameXpathElem.xml new file mode 100644 index 00000000000000..20e1c2e9d6dfb4 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nPrefixQnameXpathElem.xml @@ -0,0 +1,4 @@ + + n1:string + /n3:body/child::n2:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nQnameElem.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nQnameElem.xml new file mode 100644 index 00000000000000..db8680daa033d7 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nQnameElem.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nQnameXpathElem.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nQnameXpathElem.xml new file mode 100644 index 00000000000000..df3b21579fac5e --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsContent_c14nQnameXpathElem.xml @@ -0,0 +1,4 @@ + + xsd:string + /soap-env:body/child::b:foo[@att1 != "c:val" and @att2 != 'xsd:string'] + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsDefault_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsDefault_c14nDefault.xml new file mode 100644 index 00000000000000..674b076dd6d9a6 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsDefault_c14nDefault.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsDefault_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsDefault_c14nPrefix.xml new file mode 100644 index 00000000000000..83edaae91e7423 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsDefault_c14nPrefix.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsPushdown_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsPushdown_c14nDefault.xml new file mode 100644 index 00000000000000..fa4f21b5d0af55 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsPushdown_c14nDefault.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsPushdown_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsPushdown_c14nPrefix.xml new file mode 100644 index 00000000000000..6d579200c9dc8c --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsPushdown_c14nPrefix.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsRedecl_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsRedecl_c14nDefault.xml new file mode 100644 index 00000000000000..ba37f925103c70 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsRedecl_c14nDefault.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsRedecl_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsRedecl_c14nPrefix.xml new file mode 100644 index 00000000000000..af3bb2d6f062cd --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsRedecl_c14nPrefix.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSort_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSort_c14nDefault.xml new file mode 100644 index 00000000000000..8a92c5c61c2c2c --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSort_c14nDefault.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSort_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSort_c14nPrefix.xml new file mode 100644 index 00000000000000..8d44c84fe5d307 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSort_c14nPrefix.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSuperfluous_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSuperfluous_c14nDefault.xml new file mode 100644 index 00000000000000..6bb862d763d737 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSuperfluous_c14nDefault.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSuperfluous_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSuperfluous_c14nPrefix.xml new file mode 100644 index 00000000000000..700a16d42a7746 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsSuperfluous_c14nPrefix.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nDefault.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nDefault.xml new file mode 100644 index 00000000000000..1689f3bf423dc5 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nDefault.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nPrefix.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nPrefix.xml new file mode 100644 index 00000000000000..38508a47f6b904 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nPrefix.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nPrefixQname.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nPrefixQname.xml new file mode 100644 index 00000000000000..867980f82bfa59 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nPrefixQname.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nQname.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nQname.xml new file mode 100644 index 00000000000000..0300f9d562db30 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/out_inNsXml_c14nQname.xml @@ -0,0 +1,3 @@ + + data + \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/simple-ns.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/simple-ns.xml new file mode 100644 index 00000000000000..f1f34b2e29c73e --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/simple-ns.xml @@ -0,0 +1,7 @@ + + + + text + texttail + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/simple.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/simple.xml new file mode 100644 index 00000000000000..b88c2c7e69a088 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/simple.xml @@ -0,0 +1,6 @@ + + + text + texttail + + diff --git a/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/test.xml b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/test.xml new file mode 100644 index 00000000000000..92136da76d3581 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_elementtree_parsewhole_corpus/test.xml @@ -0,0 +1,115 @@ + + +Introduction to XSL +

Introduction to XSL

+ + + +
+

Overview +

+
    + +
  • 1.Intro
  • + +
  • 2.History
  • + +
  • 3.XSL Basics
  • + +
  • Lunch
  • + +
  • 4.An XML Data Model
  • + +
  • 5.XSL Patterns
  • + +
  • 6.XSL Templates
  • + +
  • 7.XSL Formatting Model +
  • + +
+ + + + + + +
+

Intro

+
    + +
  • Who am I?
  • + +
  • Who are you?
  • + +
  • Why are we here? +
  • + +
+ + + + + + +
+

History: XML and SGML

+
    + +
  • XML is a subset of SGML.
  • + +
  • SGML allows the separation of abstract content from formatting.
  • + +
  • Also one of XML's primary virtues (in the doc publishing domain). +
  • + +
+ + + + + + +
+

History: What are stylesheets?

+
    + +
  • Stylesheets specify the formatting of SGML/XML documents.
  • + +
  • Stylesheets put the "style" back into documents.
  • + +
  • New York Times content+NYT Stylesheet = NYT paper +
  • + +
+ + + + + + +
+

History: FOSI

+
    + +
  • FOSI: "Formatted Output Specification Instance" +
      +
    • MIL-STD-28001 +
    • + +
    • FOSI's are SGML documents +
    • + +
    • A stylesheet for another document +
    • +
  • + +
  • Obsolete but implemented... +
  • + +
+ + +� + + diff --git a/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input1.py b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input1.py new file mode 100644 index 00000000000000..c43994dda29eed --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input1.py @@ -0,0 +1,7 @@ +from __future__ import annotations + +def test() -> None: + x: list[int] = [] + x: dict[int, str] = {} + x: set[bytes] = {} + print(5 + 42 * 3, x) diff --git a/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input2.py b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input2.py new file mode 100644 index 00000000000000..7be326e95be0eb --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input2.py @@ -0,0 +1,5 @@ +class Foo(metaclass=42): + __slots__ = ['x'] + pass + +foo = Foo() diff --git a/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input3.py b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input3.py new file mode 100644 index 00000000000000..9bc3a45ebe75da --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input3.py @@ -0,0 +1,6 @@ +def evens(): + i = 0 + while True: + i += 1 + if i % 2 == 0: + yield i diff --git a/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input4.py b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input4.py new file mode 100644 index 00000000000000..490de90fb97b39 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input4.py @@ -0,0 +1,3 @@ +async def hello(name: str): + await name + print(name) diff --git a/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input5.py b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input5.py new file mode 100644 index 00000000000000..4cfcfe590ebc95 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input5.py @@ -0,0 +1,7 @@ +try: + eval('importer exporter... really long matches') +except SyntaxError: + print("nothing to see here") +finally: + print("all done here") + raise diff --git a/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input6.py b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input6.py new file mode 100644 index 00000000000000..d8e59ade503a8c --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_pycompile_corpus/input6.py @@ -0,0 +1,8 @@ +"""Some module docstring""" +import sys + +def main(): + print("Hello world!", file=sys.stderr) + +if __name__ == '__main__': + main() diff --git a/Modules/_xxtestfuzz/fuzz_tests.txt b/Modules/_xxtestfuzz/fuzz_tests.txt index 4e046ecf6d898c..ea6f982eefc9da 100644 --- a/Modules/_xxtestfuzz/fuzz_tests.txt +++ b/Modules/_xxtestfuzz/fuzz_tests.txt @@ -7,3 +7,5 @@ fuzz_sre_match fuzz_csv_reader fuzz_struct_unpack fuzz_ast_literal_eval +fuzz_elementtree_parsewhole +fuzz_pycompile diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 816ba09c8fd7de..e133b4d3c44480 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -439,6 +439,125 @@ static int fuzz_ast_literal_eval(const char* data, size_t size) { return 0; } +#define MAX_ELEMENTTREE_PARSEWHOLE_TEST_SIZE 0x100000 +PyObject* xmlparser_type = NULL; +PyObject* bytesio_type = NULL; +/* Called by LLVMFuzzerTestOneInput for initialization */ +static int init_elementtree_parsewhole(void) { + PyObject* elementtree_module = PyImport_ImportModule("_elementtree"); + if (elementtree_module == NULL) { + return 0; + } + xmlparser_type = PyObject_GetAttrString(elementtree_module, "XMLParser"); + Py_DECREF(elementtree_module); + if (xmlparser_type == NULL) { + return 0; + } + + + PyObject* io_module = PyImport_ImportModule("io"); + if (io_module == NULL) { + return 0; + } + bytesio_type = PyObject_GetAttrString(io_module, "BytesIO"); + Py_DECREF(io_module); + if (bytesio_type == NULL) { + return 0; + } + + return 1; +} +/* Fuzz _elementtree.XMLParser._parse_whole(x) */ +static int fuzz_elementtree_parsewhole(const char* data, size_t size) { + if (size > MAX_ELEMENTTREE_PARSEWHOLE_TEST_SIZE) { + return 0; + } + + PyObject *input = PyObject_CallFunction(bytesio_type, "y#", data, (Py_ssize_t)size); + if (input == NULL) { + assert(PyErr_Occurred()); + PyErr_Print(); + abort(); + } + + PyObject *xmlparser_instance = PyObject_CallObject(xmlparser_type, NULL); + if (xmlparser_instance == NULL) { + assert(PyErr_Occurred()); + PyErr_Print(); + abort(); + } + + PyObject *result = PyObject_CallMethod(xmlparser_instance, "_parse_whole", "O", input); + if (result == NULL) { + /* Ignore exception here, which can be caused by invalid XML input */ + PyErr_Clear(); + } else { + Py_DECREF(result); + } + + Py_DECREF(xmlparser_instance); + Py_DECREF(input); + + return 0; +} + +#define MAX_PYCOMPILE_TEST_SIZE 16384 +static char pycompile_scratch[MAX_PYCOMPILE_TEST_SIZE]; + +static const int start_vals[] = {Py_eval_input, Py_single_input, Py_file_input}; +const size_t NUM_START_VALS = sizeof(start_vals) / sizeof(start_vals[0]); + +static const int optimize_vals[] = {-1, 0, 1, 2}; +const size_t NUM_OPTIMIZE_VALS = sizeof(optimize_vals) / sizeof(optimize_vals[0]); + +/* Fuzz `PyCompileStringExFlags` using a variety of input parameters. + * That function is essentially behind the `compile` builtin */ +static int fuzz_pycompile(const char* data, size_t size) { + // Ignore overly-large inputs, and account for a NUL terminator + if (size > MAX_PYCOMPILE_TEST_SIZE - 1) { + return 0; + } + + // Need 2 bytes for parameter selection + if (size < 2) { + return 0; + } + + // Use first byte to determine element of `start_vals` to use + unsigned char start_idx = (unsigned char) data[0]; + int start = start_vals[start_idx % NUM_START_VALS]; + + // Use second byte to determine element of `optimize_vals` to use + unsigned char optimize_idx = (unsigned char) data[1]; + int optimize = optimize_vals[optimize_idx % NUM_OPTIMIZE_VALS]; + + // Create a NUL-terminated C string from the remaining input + memcpy(pycompile_scratch, data + 2, size - 2); + // Put a NUL terminator just after the copied data. (Space was reserved already.) + pycompile_scratch[size - 2] = '\0'; + + // XXX: instead of always using NULL for the `flags` value to + // `Py_CompileStringExFlags`, there are many flags that conditionally + // change parser behavior: + // + // #define PyCF_TYPE_COMMENTS 0x1000 + // #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 + // #define PyCF_ONLY_AST 0x0400 + // + // It would be good to test various combinations of these, too. + PyCompilerFlags *flags = NULL; + + PyObject *result = Py_CompileStringExFlags(pycompile_scratch, "", start, flags, optimize); + if (result == NULL) { + /* compilation failed, most likely from a syntax error */ + PyErr_Clear(); + } else { + Py_DECREF(result); + } + + return 0; +} + /* Run fuzzer and abort on failure. */ static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* , size_t)) { int rv = fuzzer((const char*) data, size); @@ -569,6 +688,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { } rv |= _run_fuzz(data, size, fuzz_ast_literal_eval); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_elementtree_parsewhole) + static int ELEMENTTREE_PARSEWHOLE_INITIALIZED = 0; + if (!ELEMENTTREE_PARSEWHOLE_INITIALIZED && !init_elementtree_parsewhole()) { + PyErr_Print(); + abort(); + } else { + ELEMENTTREE_PARSEWHOLE_INITIALIZED = 1; + } + + rv |= _run_fuzz(data, size, fuzz_elementtree_parsewhole); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_pycompile) + rv |= _run_fuzz(data, size, fuzz_pycompile); #endif return rv; } diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index eb4e522465181f..77644c3155bc33 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -61,21 +61,21 @@ struct TransitionRuleType { typedef struct { TransitionRuleType base; - uint8_t month; - uint8_t week; - uint8_t day; - int8_t hour; - int8_t minute; - int8_t second; + uint8_t month; /* 1 - 12 */ + uint8_t week; /* 1 - 5 */ + uint8_t day; /* 0 - 6 */ + int16_t hour; /* -167 - 167, RFC 8536 §3.3.1 */ + int8_t minute; /* signed 2 digits */ + int8_t second; /* signed 2 digits */ } CalendarRule; typedef struct { TransitionRuleType base; - uint8_t julian; - unsigned int day; - int8_t hour; - int8_t minute; - int8_t second; + uint8_t julian; /* 0, 1 */ + uint16_t day; /* 0 - 365 */ + int16_t hour; /* -167 - 167, RFC 8536 §3.3.1 */ + int8_t minute; /* signed 2 digits */ + int8_t second; /* signed 2 digits */ } DayRule; struct StrongCacheNode { @@ -133,15 +133,14 @@ ts_to_local(size_t *trans_idx, int64_t *trans_utc, long *utcoff, static int parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out); -static Py_ssize_t -parse_abbr(const char *const p, PyObject **abbr); -static Py_ssize_t -parse_tz_delta(const char *const p, long *total_seconds); -static Py_ssize_t -parse_transition_time(const char *const p, int8_t *hour, int8_t *minute, - int8_t *second); -static Py_ssize_t -parse_transition_rule(const char *const p, TransitionRuleType **out); +static int +parse_abbr(const char **p, PyObject **abbr); +static int +parse_tz_delta(const char **p, long *total_seconds); +static int +parse_transition_time(const char **p, int *hour, int *minute, int *second); +static int +parse_transition_rule(const char **p, TransitionRuleType **out); static _ttinfo * find_tzrule_ttinfo(_tzrule *rule, int64_t ts, unsigned char fold, int year); @@ -421,7 +420,7 @@ zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyTypeObject *cls, return NULL; } - file_repr = PyUnicode_FromFormat("%R", file_obj); + file_repr = PyObject_Repr(file_obj); if (file_repr == NULL) { goto error; } @@ -817,7 +816,7 @@ zoneinfo_ZoneInfo__unpickle_impl(PyTypeObject *type, PyTypeObject *cls, /*[clinic end generated code: output=556712fc709deecb input=6ac8c73eed3de316]*/ { if (from_cache) { - PyObject *val_args = Py_BuildValue("(O)", key); + PyObject *val_args = PyTuple_Pack(1, key); if (val_args == NULL) { return NULL; } @@ -1327,14 +1326,14 @@ calendarrule_year_to_timestamp(TransitionRuleType *base_self, int year) } int64_t ordinal = ymd_to_ord(year, self->month, month_day) - EPOCHORDINAL; - return ((ordinal * 86400) + (int64_t)(self->hour * 3600) + - (int64_t)(self->minute * 60) + (int64_t)(self->second)); + return ordinal * 86400 + (int64_t)self->hour * 3600 + + (int64_t)self->minute * 60 + self->second; } /* Constructor for CalendarRule. */ int -calendarrule_new(uint8_t month, uint8_t week, uint8_t day, int8_t hour, - int8_t minute, int8_t second, CalendarRule *out) +calendarrule_new(int month, int week, int day, int hour, + int minute, int second, CalendarRule *out) { // These bounds come from the POSIX standard, which describes an Mm.n.d // rule as: @@ -1343,33 +1342,36 @@ calendarrule_new(uint8_t month, uint8_t week, uint8_t day, int8_t hour, // 5, 1 <= m <= 12, where week 5 means "the last d day in month m" which // may occur in either the fourth or the fifth week). Week 1 is the first // week in which the d'th day occurs. Day zero is Sunday. - if (month <= 0 || month > 12) { - PyErr_Format(PyExc_ValueError, "Month must be in (0, 12]"); + if (month < 1 || month > 12) { + PyErr_Format(PyExc_ValueError, "Month must be in [1, 12]"); return -1; } - if (week <= 0 || week > 5) { - PyErr_Format(PyExc_ValueError, "Week must be in (0, 5]"); + if (week < 1 || week > 5) { + PyErr_Format(PyExc_ValueError, "Week must be in [1, 5]"); return -1; } - // If the 'day' parameter type is changed to a signed type, - // "day < 0" check must be added. - if (/* day < 0 || */ day > 6) { + if (day < 0 || day > 6) { PyErr_Format(PyExc_ValueError, "Day must be in [0, 6]"); return -1; } + if (hour < -167 || hour > 167) { + PyErr_Format(PyExc_ValueError, "Hour must be in [0, 167]"); + return -1; + } + TransitionRuleType base = {&calendarrule_year_to_timestamp}; CalendarRule new_offset = { .base = base, - .month = month, - .week = week, - .day = day, - .hour = hour, - .minute = minute, - .second = second, + .month = (uint8_t)month, + .week = (uint8_t)week, + .day = (uint8_t)day, + .hour = (int16_t)hour, + .minute = (int8_t)minute, + .second = (int8_t)second, }; *out = new_offset; @@ -1409,40 +1411,45 @@ dayrule_year_to_timestamp(TransitionRuleType *base_self, int year) // always transitions on a given calendar day (other than February 29th), // you would use a Julian day, e.g. J91 always refers to April 1st and J365 // always refers to December 31st. - unsigned int day = self->day; + uint16_t day = self->day; if (self->julian && day >= 59 && is_leap_year(year)) { day += 1; } - return ((days_before_year + day) * 86400) + (self->hour * 3600) + - (self->minute * 60) + self->second; + return (days_before_year + day) * 86400 + (int64_t)self->hour * 3600 + + (int64_t)self->minute * 60 + self->second; } /* Constructor for DayRule. */ static int -dayrule_new(uint8_t julian, unsigned int day, int8_t hour, int8_t minute, - int8_t second, DayRule *out) +dayrule_new(int julian, int day, int hour, int minute, + int second, DayRule *out) { // The POSIX standard specifies that Julian days must be in the range (1 <= // n <= 365) and that non-Julian (they call it "0-based Julian") days must // be in the range (0 <= n <= 365). if (day < julian || day > 365) { - PyErr_Format(PyExc_ValueError, "day must be in [%u, 365], not: %u", + PyErr_Format(PyExc_ValueError, "day must be in [%d, 365], not: %d", julian, day); return -1; } + if (hour < -167 || hour > 167) { + PyErr_Format(PyExc_ValueError, "Hour must be in [0, 167]"); + return -1; + } + TransitionRuleType base = { &dayrule_year_to_timestamp, }; DayRule tmp = { .base = base, - .julian = julian, - .day = day, - .hour = hour, - .minute = minute, - .second = second, + .julian = (uint8_t)julian, + .day = (int16_t)day, + .hour = (int16_t)hour, + .minute = (int8_t)minute, + .second = (int8_t)second, }; *out = tmp; @@ -1599,21 +1606,18 @@ parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) const char *p = tz_str; // Read the `std` abbreviation, which must be at least 3 characters long. - Py_ssize_t num_chars = parse_abbr(p, &std_abbr); - if (num_chars < 1) { - PyErr_Format(PyExc_ValueError, "Invalid STD format in %R", tz_str_obj); + if (parse_abbr(&p, &std_abbr)) { + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, "Invalid STD format in %R", tz_str_obj); + } goto error; } - p += num_chars; - // Now read the STD offset, which is required - num_chars = parse_tz_delta(p, &std_offset); - if (num_chars < 0) { + if (parse_tz_delta(&p, &std_offset)) { PyErr_Format(PyExc_ValueError, "Invalid STD offset in %R", tz_str_obj); goto error; } - p += num_chars; // If the string ends here, there is no DST, otherwise we must parse the // DST abbreviation and start and end dates and times. @@ -1621,12 +1625,12 @@ parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) goto complete; } - num_chars = parse_abbr(p, &dst_abbr); - if (num_chars < 1) { - PyErr_Format(PyExc_ValueError, "Invalid DST format in %R", tz_str_obj); + if (parse_abbr(&p, &dst_abbr)) { + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_ValueError, "Invalid DST format in %R", tz_str_obj); + } goto error; } - p += num_chars; if (*p == ',') { // From the POSIX standard: @@ -1636,14 +1640,11 @@ parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) dst_offset = std_offset + 3600; } else { - num_chars = parse_tz_delta(p, &dst_offset); - if (num_chars < 0) { + if (parse_tz_delta(&p, &dst_offset)) { PyErr_Format(PyExc_ValueError, "Invalid DST offset in %R", tz_str_obj); goto error; } - - p += num_chars; } TransitionRuleType **transitions[2] = {&start, &end}; @@ -1656,14 +1657,12 @@ parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) } p++; - num_chars = parse_transition_rule(p, transitions[i]); - if (num_chars < 0) { + if (parse_transition_rule(&p, transitions[i])) { PyErr_Format(PyExc_ValueError, "Malformed transition rule in TZ string: %R", tz_str_obj); goto error; } - p += num_chars; } if (*p != '\0') { @@ -1698,21 +1697,25 @@ parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) } static int -parse_uint(const char *const p, uint8_t *value) +parse_digits(const char **p, int min, int max, int *value) { - if (!Py_ISDIGIT(*p)) { - return -1; + assert(max <= 3); + *value = 0; + for (int i = 0; i < max; i++, (*p)++) { + if (!Py_ISDIGIT(**p)) { + return (i < min) ? -1 : 0; + } + *value *= 10; + *value += (**p) - '0'; } - - *value = (*p) - '0'; return 0; } /* Parse the STD and DST abbreviations from a TZ string. */ -static Py_ssize_t -parse_abbr(const char *const p, PyObject **abbr) +static int +parse_abbr(const char **p, PyObject **abbr) { - const char *ptr = p; + const char *ptr = *p; const char *str_start; const char *str_end; @@ -1741,7 +1744,7 @@ parse_abbr(const char *const p, PyObject **abbr) ptr++; } else { - str_start = p; + str_start = ptr; // From the POSIX standard: // // In the unquoted form, all characters in these fields shall be @@ -1751,6 +1754,9 @@ parse_abbr(const char *const p, PyObject **abbr) ptr++; } str_end = ptr; + if (str_end == str_start) { + return -1; + } } *abbr = PyUnicode_FromStringAndSize(str_start, str_end - str_start); @@ -1758,12 +1764,13 @@ parse_abbr(const char *const p, PyObject **abbr) return -1; } - return ptr - p; + *p = ptr; + return 0; } /* Parse a UTC offset from a TZ str. */ -static Py_ssize_t -parse_tz_delta(const char *const p, long *total_seconds) +static int +parse_tz_delta(const char **p, long *total_seconds) { // From the POSIX spec: // @@ -1778,75 +1785,30 @@ parse_tz_delta(const char *const p, long *total_seconds) // The POSIX spec says that the values for `hour` must be between 0 and 24 // hours, but RFC 8536 §3.3.1 specifies that the hours part of the // transition times may be signed and range from -167 to 167. - long sign = -1; - long hours = 0; - long minutes = 0; - long seconds = 0; - - const char *ptr = p; - char buff = *ptr; - if (buff == '-' || buff == '+') { - // Negative numbers correspond to *positive* offsets, from the spec: - // - // If preceded by a '-', the timezone shall be east of the Prime - // Meridian; otherwise, it shall be west (which may be indicated by - // an optional preceding '+' ). - if (buff == '-') { - sign = 1; - } - - ptr++; - } - - // The hour can be 1 or 2 numeric characters - for (size_t i = 0; i < 2; ++i) { - buff = *ptr; - if (!Py_ISDIGIT(buff)) { - if (i == 0) { - return -1; - } - else { - break; - } - } + int hours = 0; + int minutes = 0; + int seconds = 0; - hours *= 10; - hours += buff - '0'; - ptr++; - } - - if (hours > 24 || hours < 0) { + if (parse_transition_time(p, &hours, &minutes, &seconds)) { return -1; } - // Minutes and seconds always of the format ":dd" - long *outputs[2] = {&minutes, &seconds}; - for (size_t i = 0; i < 2; ++i) { - if (*ptr != ':') { - goto complete; - } - ptr++; - - for (size_t j = 0; j < 2; ++j) { - buff = *ptr; - if (!Py_ISDIGIT(buff)) { - return -1; - } - *(outputs[i]) *= 10; - *(outputs[i]) += buff - '0'; - ptr++; - } + if (hours > 24 || hours < -24) { + return -1; } -complete: - *total_seconds = sign * ((hours * 3600) + (minutes * 60) + seconds); - - return ptr - p; + // Negative numbers correspond to *positive* offsets, from the spec: + // + // If preceded by a '-', the timezone shall be east of the Prime + // Meridian; otherwise, it shall be west (which may be indicated by + // an optional preceding '+' ). + *total_seconds = -((hours * 3600L) + (minutes * 60) + seconds); + return 0; } /* Parse the date portion of a transition rule. */ -static Py_ssize_t -parse_transition_rule(const char *const p, TransitionRuleType **out) +static int +parse_transition_rule(const char **p, TransitionRuleType **out) { // The full transition rule indicates when to change back and forth between // STD and DST, and has the form: @@ -1858,10 +1820,10 @@ parse_transition_rule(const char *const p, TransitionRuleType **out) // does not include the ',' at the end of the first rule. // // The POSIX spec states that if *time* is not given, the default is 02:00. - const char *ptr = p; - int8_t hour = 2; - int8_t minute = 0; - int8_t second = 0; + const char *ptr = *p; + int hour = 2; + int minute = 0; + int second = 0; // Rules come in one of three flavors: // @@ -1870,44 +1832,30 @@ parse_transition_rule(const char *const p, TransitionRuleType **out) // 3. Mm.n.d: Specifying by month, week and day-of-week. if (*ptr == 'M') { - uint8_t month, week, day; + int month, week, day; ptr++; - if (parse_uint(ptr, &month)) { + + if (parse_digits(&ptr, 1, 2, &month)) { return -1; } - ptr++; - if (*ptr != '.') { - uint8_t tmp; - if (parse_uint(ptr, &tmp)) { - return -1; - } - - month *= 10; - month += tmp; - ptr++; + if (*ptr++ != '.') { + return -1; } - - uint8_t *values[2] = {&week, &day}; - for (size_t i = 0; i < 2; ++i) { - if (*ptr != '.') { - return -1; - } - ptr++; - - if (parse_uint(ptr, values[i])) { - return -1; - } - ptr++; + if (parse_digits(&ptr, 1, 1, &week)) { + return -1; + } + if (*ptr++ != '.') { + return -1; + } + if (parse_digits(&ptr, 1, 1, &day)) { + return -1; } if (*ptr == '/') { ptr++; - Py_ssize_t num_chars = - parse_transition_time(ptr, &hour, &minute, &second); - if (num_chars < 0) { + if (parse_transition_time(&ptr, &hour, &minute, &second)) { return -1; } - ptr += num_chars; } CalendarRule *rv = PyMem_Calloc(1, sizeof(CalendarRule)); @@ -1923,33 +1871,22 @@ parse_transition_rule(const char *const p, TransitionRuleType **out) *out = (TransitionRuleType *)rv; } else { - uint8_t julian = 0; - unsigned int day = 0; + int julian = 0; + int day = 0; if (*ptr == 'J') { julian = 1; ptr++; } - for (size_t i = 0; i < 3; ++i) { - if (!Py_ISDIGIT(*ptr)) { - if (i == 0) { - return -1; - } - break; - } - day *= 10; - day += (*ptr) - '0'; - ptr++; + if (parse_digits(&ptr, 1, 3, &day)) { + return -1; } if (*ptr == '/') { ptr++; - Py_ssize_t num_chars = - parse_transition_time(ptr, &hour, &minute, &second); - if (num_chars < 0) { + if (parse_transition_time(&ptr, &hour, &minute, &second)) { return -1; } - ptr += num_chars; } DayRule *rv = PyMem_Calloc(1, sizeof(DayRule)); @@ -1964,13 +1901,13 @@ parse_transition_rule(const char *const p, TransitionRuleType **out) *out = (TransitionRuleType *)rv; } - return ptr - p; + *p = ptr; + return 0; } /* Parse the time portion of a transition rule (e.g. following an /) */ -static Py_ssize_t -parse_transition_time(const char *const p, int8_t *hour, int8_t *minute, - int8_t *second) +static int +parse_transition_time(const char **p, int *hour, int *minute, int *second) { // From the spec: // @@ -1982,12 +1919,9 @@ parse_transition_time(const char *const p, int8_t *hour, int8_t *minute, // h[h][:mm[:ss]] // // RFC 8536 also allows transition times to be signed and to range from - // -167 to +167, but the current version only supports [0, 99]. - // - // TODO: Support the full range of transition hours. - int8_t *components[3] = {hour, minute, second}; - const char *ptr = p; - int8_t sign = 1; + // -167 to +167. + const char *ptr = *p; + int sign = 1; if (*ptr == '-' || *ptr == '+') { if (*ptr == '-') { @@ -1996,32 +1930,31 @@ parse_transition_time(const char *const p, int8_t *hour, int8_t *minute, ptr++; } - for (size_t i = 0; i < 3; ++i) { - if (i > 0) { - if (*ptr != ':') { - break; - } - ptr++; + // The hour can be 1 to 3 numeric characters + if (parse_digits(&ptr, 1, 3, hour)) { + return -1; + } + *hour *= sign; + + // Minutes and seconds always of the format ":dd" + if (*ptr == ':') { + ptr++; + if (parse_digits(&ptr, 2, 2, minute)) { + return -1; } + *minute *= sign; - uint8_t buff = 0; - for (size_t j = 0; j < 2; j++) { - if (!Py_ISDIGIT(*ptr)) { - if (i == 0 && j > 0) { - break; - } + if (*ptr == ':') { + ptr++; + if (parse_digits(&ptr, 2, 2, second)) { return -1; } - - buff *= 10; - buff += (*ptr) - '0'; - ptr++; + *second *= sign; } - - *(components[i]) = sign * buff; } - return ptr - p; + *p = ptr; + return 0; } /* Constructor for a _tzrule. @@ -2376,8 +2309,8 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts) } } - *local_ts = (int64_t)(ord - EPOCHORDINAL) * 86400 + - (int64_t)(hour * 3600 + minute * 60 + second); + *local_ts = (int64_t)(ord - EPOCHORDINAL) * 86400L + + (int64_t)(hour * 3600L + minute * 60 + second); return 0; } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 309a36919f3465..b97ade6126fa08 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -11,7 +11,7 @@ #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_modsupport.h" // _PyArg_NoKeywords() #include "pycore_moduleobject.h" // _PyModule_GetState() #include // offsetof() diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index 57e2ea67450453..b6f1bcbca67916 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -10,7 +10,6 @@ #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 /* ===================================================================== */ @@ -137,7 +136,8 @@ atexit_callfuncs(struct atexit_state *state) PyObject* the_func = Py_NewRef(cb->func); PyObject *res = PyObject_Call(cb->func, cb->args, cb->kwargs); if (res == NULL) { - _PyErr_WriteUnraisableMsg("in atexit callback", the_func); + PyErr_FormatUnraisable( + "Exception ignored in atexit callback %R", the_func); } else { Py_DECREF(res); diff --git a/Modules/binascii.c b/Modules/binascii.c index a87a2ef2e89927..86493241a1fb7e 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -185,13 +185,7 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf) "not '%.100s'", Py_TYPE(arg)->tp_name); return 0; } - if (!PyBuffer_IsContiguous(buf, 'C')) { - PyErr_Format(PyExc_TypeError, - "argument should be a contiguous buffer, " - "not '%.100s'", Py_TYPE(arg)->tp_name); - PyBuffer_Release(buf); - return 0; - } + assert(PyBuffer_IsContiguous(buf, 'C')); return Py_CLEANUP_SUPPORTED; } @@ -776,12 +770,20 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) Py_BEGIN_ALLOW_THREADS /* Avoid truncation of length for very large buffers. crc32() takes - length as an unsigned int, which may be narrower than Py_ssize_t. */ - while ((size_t)len > UINT_MAX) { - crc = crc32(crc, buf, UINT_MAX); - buf += (size_t) UINT_MAX; - len -= (size_t) UINT_MAX; + length as an unsigned int, which may be narrower than Py_ssize_t. + We further limit size due to bugs in Apple's macOS zlib. + See /~https://github.com/python/cpython/issues/105967 + */ +#define ZLIB_CRC_CHUNK_SIZE 0x40000000 +#if ZLIB_CRC_CHUNK_SIZE > INT_MAX +# error "unsupported less than 32-bit platform?" +#endif + while ((size_t)len > ZLIB_CRC_CHUNK_SIZE) { + crc = crc32(crc, buf, ZLIB_CRC_CHUNK_SIZE); + buf += (size_t) ZLIB_CRC_CHUNK_SIZE; + len -= (size_t) ZLIB_CRC_CHUNK_SIZE; } +#undef ZLIB_CRC_CHUNK_SIZE crc = crc32(crc, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c index 86bb73b982a551..e8835ad0909633 100644 --- a/Modules/cjkcodecs/_codecs_iso2022.c +++ b/Modules/cjkcodecs/_codecs_iso2022.c @@ -207,8 +207,9 @@ ENCODER(iso2022) encoded = MAP_UNMAPPABLE; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { + Py_UCS4 buf[2] = {c, 0}; Py_ssize_t length = 1; - encoded = dsg->encoder(codec, &c, &length); + encoded = dsg->encoder(codec, buf, &length); if (encoded == MAP_MULTIPLE_AVAIL) { /* this implementation won't work for pair * of non-bmp characters. */ @@ -217,9 +218,11 @@ ENCODER(iso2022) return MBERR_TOOFEW; length = -1; } - else + else { + buf[1] = INCHAR2; length = 2; - encoded = dsg->encoder(codec, &c, &length); + } + encoded = dsg->encoder(codec, buf, &length); if (encoded != MAP_UNMAPPABLE) { insize = length; break; diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 0b73a7059eb584..305ade17b1f1aa 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, "encode($self, /, input, errors=None)\n" @@ -153,10 +154,6 @@ _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *cons if (PyObject_GetBuffer(args[0], &input, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&input, 'C')) { - _PyArg_BadArgument("decode", "argument 'input'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -373,10 +370,6 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb if (PyObject_GetBuffer(args[0], &input, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&input, 'C')) { - _PyArg_BadArgument("decode", "argument 'input'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -689,4 +682,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=1ee928e7a85e9d34 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=219a363662d2fbff input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 7c1da9004549a6..5d3c16a98423ba 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -9,7 +9,6 @@ #endif #include "Python.h" -#include "pycore_long.h" // _PyLong_FromByteArray() #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" diff --git a/Modules/clinic/_abc.c.h b/Modules/clinic/_abc.c.h index 8d3832e1b83d2d..04681fa2206a2a 100644 --- a/Modules/clinic/_abc.c.h +++ b/Modules/clinic/_abc.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_abc__reset_registry__doc__, "_reset_registry($module, self, /)\n" "--\n" @@ -159,4 +161,4 @@ _abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _abc_get_cache_token_impl(module); } -/*[clinic end generated code: output=babb3ce445fa9b21 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1989b6716c950e17 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 74dd06461e6e27..d941c280a4300b 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_asyncio_Future___init____doc__, "Future(*, loop=None)\n" @@ -1486,4 +1487,4 @@ _asyncio_current_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=1b7658bfab7024f3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f3864d8e2af7635f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h index 5553b05acbf521..9955d0edb2699f 100644 --- a/Modules/clinic/_bisectmodule.c.h +++ b/Modules/clinic/_bisectmodule.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_bisect_bisect_right__doc__, "bisect_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" @@ -433,4 +434,4 @@ _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=43ece163c3e972df input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4af5bd405149bf5f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 29f5d3a68e06ae..de7b3993596446 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_BadArgument() PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, "compress($self, data, /)\n" @@ -34,10 +35,6 @@ _bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *arg) if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); - goto exit; - } return_value = _bz2_BZ2Compressor_compress_impl(self, &data); exit: @@ -180,10 +177,6 @@ _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -241,4 +234,4 @@ _bz2_BZ2Decompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=3dfc8436fa8eaefb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8daa62f47cc4853d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index bf9bd4a61f5ce4..12fea806ab5209 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_BadArgument() PyDoc_STRVAR(_codecs_register__doc__, "register($module, search_function, /)\n" @@ -302,10 +303,6 @@ _codecs_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("escape_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } } if (nargs < 2) { goto skip_optional; @@ -421,10 +418,6 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_7_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -491,10 +484,6 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_8_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -561,10 +550,6 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -631,10 +616,6 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_le_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -701,10 +682,6 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_be_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -773,10 +750,6 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_16_ex_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -850,10 +823,6 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -920,10 +889,6 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_le_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -990,10 +955,6 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_be_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1062,10 +1023,6 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("utf_32_ex_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1148,10 +1105,6 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("unicode_escape_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } } if (nargs < 2) { goto skip_optional; @@ -1228,10 +1181,6 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("raw_unicode_escape_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } } if (nargs < 2) { goto skip_optional; @@ -1298,10 +1247,6 @@ _codecs_latin_1_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("latin_1_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1360,10 +1305,6 @@ _codecs_ascii_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("ascii_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1423,10 +1364,6 @@ _codecs_charmap_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("charmap_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1492,10 +1429,6 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("mbcs_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1566,10 +1499,6 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("oem_decode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1645,10 +1574,6 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[1], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("code_page_decode", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (nargs < 3) { goto skip_optional; } @@ -1725,10 +1650,6 @@ _codecs_readbuffer_encode(PyObject *module, PyObject *const *args, Py_ssize_t na if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("readbuffer_encode", "argument 1", "contiguous buffer", args[0]); - goto exit; - } } if (nargs < 2) { goto skip_optional; @@ -2817,4 +2738,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=3473564544f10403 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d8d9e372f7ccba35 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index a375b87261ce2d..591ab50c76a8e8 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_collections__count_elements__doc__, "_count_elements($module, mapping, iterable, /)\n" @@ -71,4 +72,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b01ddb9fdecc4a2d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c896a72f8c45930d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_csv.c.h b/Modules/clinic/_csv.c.h index 86ed0efd79028e..2442bdcde5679f 100644 --- a/Modules/clinic/_csv.c.h +++ b/Modules/clinic/_csv.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_csv_list_dialects__doc__, "list_dialects($module, /)\n" @@ -205,4 +206,4 @@ _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=4704d708f5745e91 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9ec59717f5414d8b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index a8c32c6aa3fc10..7945d93b5433f7 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() + PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "bottom($self, /)\n" "--\n" @@ -416,4 +418,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=dd302cb9afc42f40 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=636beecf71d96ff1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index ecc3c059d03c90..f7e0aaf7b23649 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_curses_window_addch__doc__, "addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" @@ -3162,7 +3163,7 @@ PyDoc_STRVAR(_curses_napms__doc__, #define _CURSES_NAPMS_METHODDEF \ {"napms", (PyCFunction)_curses_napms, METH_O, _curses_napms__doc__}, -static PyObject * +static int _curses_napms_impl(PyObject *module, int ms); static PyObject * @@ -3170,12 +3171,17 @@ _curses_napms(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; int ms; + int _return_value; ms = PyLong_AsInt(arg); if (ms == -1 && PyErr_Occurred()) { goto exit; } - return_value = _curses_napms_impl(module, ms); + _return_value = _curses_napms_impl(module, ms); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); exit: return return_value; @@ -4312,4 +4318,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=839faafb638935ea input=a9049054013a1b77]*/ +/*[clinic end generated code: output=96887782374f070a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 177a37e486e24d..1ee50fc2a13762 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, "fromtimestamp($type, timestamp, /)\n" @@ -145,4 +146,4 @@ datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=e422c25b1c28f38b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=562813dd3e164794 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index a76b8b30eded39..5a4aba2825e03a 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() + PyDoc_STRVAR(_dbm_dbm_close__doc__, "close($self, /)\n" "--\n" @@ -216,4 +218,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=972d221f9da819d3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=96fdd4bd7bd256c5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 3477257f9d2cf2..02375c8a61e73e 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_elementtree_Element_append__doc__, "append($self, subelement, /)\n" @@ -1218,4 +1219,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=20d1869da79a43d7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8fdaa17d3262800a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h index 25a3e5b0da60a8..e98984dc4d3a09 100644 --- a/Modules/clinic/_functoolsmodule.c.h +++ b/Modules/clinic/_functoolsmodule.c.h @@ -6,6 +6,8 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_functools_cmp_to_key__doc__, "cmp_to_key($module, /, mycmp)\n" @@ -80,7 +82,13 @@ _functools__lru_cache_wrapper_cache_info_impl(PyObject *self); static PyObject * _functools__lru_cache_wrapper_cache_info(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return _functools__lru_cache_wrapper_cache_info_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _functools__lru_cache_wrapper_cache_info_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_functools__lru_cache_wrapper_cache_clear__doc__, @@ -98,6 +106,12 @@ _functools__lru_cache_wrapper_cache_clear_impl(PyObject *self); static PyObject * _functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) { - return _functools__lru_cache_wrapper_cache_clear_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _functools__lru_cache_wrapper_cache_clear_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } -/*[clinic end generated code: output=de9cf85e85167f43 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=755265bb6d5ea751 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index e9138bbf0430c5..c7164e519d0e7d 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_gdbm_gdbm_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -338,4 +340,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=84f30c7fff0eadac input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c5ee922363d5a81f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index e41f608bde5011..58650dff288444 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(EVP_copy__doc__, "copy($self, /)\n" @@ -1289,17 +1290,9 @@ pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (PyObject_GetBuffer(args[1], &password, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&password, 'C')) { - _PyArg_BadArgument("pbkdf2_hmac", "argument 'password'", "contiguous buffer", args[1]); - goto exit; - } if (PyObject_GetBuffer(args[2], &salt, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("pbkdf2_hmac", "argument 'salt'", "contiguous buffer", args[2]); - goto exit; - } iterations = PyLong_AsLong(args[3]); if (iterations == -1 && PyErr_Occurred()) { goto exit; @@ -1387,10 +1380,6 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (PyObject_GetBuffer(args[0], &password, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&password, 'C')) { - _PyArg_BadArgument("scrypt", "argument 'password'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_kwonly; } @@ -1398,10 +1387,6 @@ _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (PyObject_GetBuffer(args[1], &salt, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&salt, 'C')) { - _PyArg_BadArgument("scrypt", "argument 'salt'", "contiguous buffer", args[1]); - goto exit; - } if (!--noptargs) { goto skip_optional_kwonly; } @@ -1521,17 +1506,9 @@ _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("hmac_digest", "argument 'key'", "contiguous buffer", args[0]); - goto exit; - } if (PyObject_GetBuffer(args[1], &msg, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&msg, 'C')) { - _PyArg_BadArgument("hmac_digest", "argument 'msg'", "contiguous buffer", args[1]); - goto exit; - } digest = args[2]; return_value = _hashlib_hmac_singleshot_impl(module, &key, &msg, digest); @@ -1603,10 +1580,6 @@ _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO if (PyObject_GetBuffer(args[0], &key, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&key, 'C')) { - _PyArg_BadArgument("hmac_new", "argument 'key'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -1851,4 +1824,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=75413752099f2dec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7eddeb3d6ccdeec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_heapqmodule.c.h b/Modules/clinic/_heapqmodule.c.h index 8d73b5b48d6a0e..9046307990773b 100644 --- a/Modules/clinic/_heapqmodule.c.h +++ b/Modules/clinic/_heapqmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_heapq_heappush__doc__, "heappush($module, heap, item, /)\n" "--\n" @@ -265,4 +267,4 @@ _heapq__heapify_max(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9a22715a8bf0c91d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=05f2afdf3bc54c9d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_localemodule.c.h b/Modules/clinic/_localemodule.c.h index efbb9f709958cd..5e0880b0d0bb4c 100644 --- a/Modules/clinic/_localemodule.c.h +++ b/Modules/clinic/_localemodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_locale_setlocale__doc__, "setlocale($module, category, locale=, /)\n" "--\n" @@ -593,4 +595,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=3abe7fade999eff6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=034a3c219466d207 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index 528b48384f0bcb..51fab5eab3f7dc 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_BadArgument() PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, "compress($self, data, /)\n" @@ -34,10 +35,6 @@ _lzma_LZMACompressor_compress(Compressor *self, PyObject *arg) if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", "argument", "contiguous buffer", arg); - goto exit; - } return_value = _lzma_LZMACompressor_compress_impl(self, &data); exit: @@ -138,10 +135,6 @@ _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -324,10 +317,6 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz if (PyObject_GetBuffer(args[1], &encoded_props, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&encoded_props, 'C')) { - _PyArg_BadArgument("_decode_filter_properties", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props); exit: @@ -338,4 +327,4 @@ _lzma__decode_filter_properties(PyObject *module, PyObject *const *args, Py_ssiz return return_value; } -/*[clinic end generated code: output=eadc9ee7a11a06f5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5e79c05ace76dc96 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index 4b9a70d2ba9852..c7fd0f9f8a7420 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_opcode_stack_effect__doc__, "stack_effect($module, opcode, oparg=None, /, *, jump=None)\n" @@ -667,4 +668,4 @@ _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]*/ +/*[clinic end generated code: output=a1052bb1deffb7f2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_operator.c.h b/Modules/clinic/_operator.c.h index 06bde243b4e85b..08615d690922a1 100644 --- a/Modules/clinic/_operator.c.h +++ b/Modules/clinic/_operator.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_operator_truth__doc__, "truth($module, a, /)\n" @@ -1488,4 +1489,4 @@ _operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=9658aca50a9ad991 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ddbba2cd943571eb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 5df40d62827754..932ace190e6059 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, "clear_memo($self, /)\n" @@ -1033,4 +1034,4 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=57c209a12264146d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7f0564b5fb5410a8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_posixsubprocess.c.h b/Modules/clinic/_posixsubprocess.c.h index 83048a385d319c..dd7644de6b7534 100644 --- a/Modules/clinic/_posixsubprocess.c.h +++ b/Modules/clinic/_posixsubprocess.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + 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" @@ -153,4 +155,4 @@ subprocess_fork_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a83b11467169b97b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48555f5965a871be input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 8d4df14ae3b009..8e2a430835e35f 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_NoKeywords() PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" @@ -330,4 +331,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=5c326e4c1f2a1ad7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=457310b20cb61cf8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_randommodule.c.h b/Modules/clinic/_randommodule.c.h index 008b531d832c5a..6193acac67e7ac 100644 --- a/Modules/clinic/_randommodule.c.h +++ b/Modules/clinic/_randommodule.c.h @@ -2,6 +2,9 @@ preserve [clinic start generated code]*/ +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_random_Random_random__doc__, "random($self, /)\n" "--\n" @@ -17,7 +20,13 @@ _random_Random_random_impl(RandomObject *self); static PyObject * _random_Random_random(RandomObject *self, PyObject *Py_UNUSED(ignored)) { - return _random_Random_random_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _random_Random_random_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_random_Random_seed__doc__, @@ -49,7 +58,9 @@ _random_Random_seed(RandomObject *self, PyObject *const *args, Py_ssize_t nargs) } n = args[0]; skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _random_Random_seed_impl(self, n); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -70,7 +81,13 @@ _random_Random_getstate_impl(RandomObject *self); static PyObject * _random_Random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) { - return _random_Random_getstate_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _random_Random_getstate_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_random_Random_setstate__doc__, @@ -82,6 +99,21 @@ PyDoc_STRVAR(_random_Random_setstate__doc__, #define _RANDOM_RANDOM_SETSTATE_METHODDEF \ {"setstate", (PyCFunction)_random_Random_setstate, METH_O, _random_Random_setstate__doc__}, +static PyObject * +_random_Random_setstate_impl(RandomObject *self, PyObject *state); + +static PyObject * +_random_Random_setstate(RandomObject *self, PyObject *state) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _random_Random_setstate_impl(self, state); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_random_Random_getrandbits__doc__, "getrandbits($self, k, /)\n" "--\n" @@ -104,9 +136,11 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) if (k == -1 && PyErr_Occurred()) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _random_Random_getrandbits_impl(self, k); + Py_END_CRITICAL_SECTION(); exit: return return_value; } -/*[clinic end generated code: output=5e7e05d756a7e1c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bf49ece1d341b1b6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 5f8ae29180a4fa..19c0f619b92f45 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, "do_handshake($self, /)\n" @@ -236,10 +237,6 @@ _ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); - goto exit; - } return_value = _ssl__SSLSocket_write_impl(self, &b); exit: @@ -529,10 +526,6 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&protos, 'C')) { - _PyArg_BadArgument("_set_alpn_protocols", "argument", "contiguous buffer", arg); - goto exit; - } return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); exit: @@ -1021,6 +1014,141 @@ _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssiz return return_value; } +PyDoc_STRVAR(_ssl__SSLContext_set_psk_client_callback__doc__, +"set_psk_client_callback($self, /, callback)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_PSK_CLIENT_CALLBACK_METHODDEF \ + {"set_psk_client_callback", _PyCFunction_CAST(_ssl__SSLContext_set_psk_client_callback), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_set_psk_client_callback__doc__}, + +static PyObject * +_ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, + PyObject *callback); + +static PyObject * +_ssl__SSLContext_set_psk_client_callback(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"callback", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_psk_client_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *callback; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + callback = args[0]; + return_value = _ssl__SSLContext_set_psk_client_callback_impl(self, callback); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext_set_psk_server_callback__doc__, +"set_psk_server_callback($self, /, callback, identity_hint=None)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT_SET_PSK_SERVER_CALLBACK_METHODDEF \ + {"set_psk_server_callback", _PyCFunction_CAST(_ssl__SSLContext_set_psk_server_callback), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_set_psk_server_callback__doc__}, + +static PyObject * +_ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, + PyObject *callback, + const char *identity_hint); + +static PyObject * +_ssl__SSLContext_set_psk_server_callback(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 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(callback), &_Py_ID(identity_hint), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"callback", "identity_hint", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_psk_server_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *callback; + const char *identity_hint = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + callback = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1] == Py_None) { + identity_hint = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t identity_hint_length; + identity_hint = PyUnicode_AsUTF8AndSize(args[1], &identity_hint_length); + if (identity_hint == NULL) { + goto exit; + } + if (strlen(identity_hint) != (size_t)identity_hint_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("set_psk_server_callback", "argument 'identity_hint'", "str or None", args[1]); + goto exit; + } +skip_optional_pos: + return_value = _ssl__SSLContext_set_psk_server_callback_impl(self, callback, identity_hint); + +exit: + return return_value; +} + static PyObject * _ssl_MemoryBIO_impl(PyTypeObject *type); @@ -1107,10 +1235,6 @@ _ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); - goto exit; - } return_value = _ssl_MemoryBIO_write_impl(self, &b); exit: @@ -1179,10 +1303,6 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &view, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&view, 'C')) { - _PyArg_BadArgument("RAND_add", "argument 1", "contiguous buffer", args[0]); - goto exit; - } } if (PyFloat_CheckExact(args[1])) { entropy = PyFloat_AS_DOUBLE(args[1]); @@ -1542,4 +1662,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=a47d575abe0aceb6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6342ea0062ab16c7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h index 03543e41af7f5a..653a2138aaad70 100644 --- a/Modules/clinic/_statisticsmodule.c.h +++ b/Modules/clinic/_statisticsmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_statistics__normal_dist_inv_cdf__doc__, "_normal_dist_inv_cdf($module, p, mu, sigma, /)\n" "--\n" @@ -65,4 +67,4 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi exit: return return_value; } -/*[clinic end generated code: output=b807a8243e7801e6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e7cead17f9f3e19f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index 8c468e6e7205e6..1a07532bdd75ad 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -7,8 +7,9 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() -PyDoc_STRVAR(Struct__doc__, +PyDoc_STRVAR(Struct___init____doc__, "Struct(format)\n" "--\n" "\n" @@ -19,13 +20,13 @@ PyDoc_STRVAR(Struct__doc__, "\n" "See help(struct) for more on format strings."); -static PyObject * -Struct_impl(PyTypeObject *type, PyObject *format); +static int +Struct___init___impl(PyStructObject *self, PyObject *format); -static PyObject * -Struct(PyTypeObject *type, PyObject *args, PyObject *kwargs) +static int +Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *return_value = NULL; + int return_value = -1; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) #define NUM_KEYWORDS 1 @@ -61,7 +62,7 @@ Struct(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } format = fastargs[0]; - return_value = Struct_impl(type, format); + return_value = Struct___init___impl((PyStructObject *)self, format); exit: return return_value; @@ -93,10 +94,6 @@ Struct_unpack(PyStructObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack", "argument", "contiguous buffer", arg); - goto exit; - } return_value = Struct_unpack_impl(self, &buffer); exit: @@ -169,10 +166,6 @@ Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs if (PyObject_GetBuffer(args[0], &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack_from", "argument 'buffer'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -299,10 +292,6 @@ unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = unpack_impl(module, s_object, &buffer); exit: @@ -378,10 +367,6 @@ unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("unpack_from", "argument 'buffer'", "contiguous buffer", args[1]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -451,4 +436,4 @@ iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -/*[clinic end generated code: output=5c1bc384ff87df1f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=67bd299e5d72fee0 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 ba3aeca49e26eb..fea30e778381de 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -7,6 +7,7 @@ preserve #endif #include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_long.h" // _PyLong_UnsignedShort_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_runtime.h" // _Py_ID() PyDoc_STRVAR(test_empty_function__doc__, @@ -2813,6 +2814,76 @@ gh_99240_double_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } +PyDoc_STRVAR(null_or_tuple_for_varargs__doc__, +"null_or_tuple_for_varargs($module, /, name, *constraints,\n" +" covariant=False)\n" +"--\n" +"\n" +"See /~https://github.com/python/cpython/issues/110864"); + +#define NULL_OR_TUPLE_FOR_VARARGS_METHODDEF \ + {"null_or_tuple_for_varargs", _PyCFunction_CAST(null_or_tuple_for_varargs), METH_FASTCALL|METH_KEYWORDS, null_or_tuple_for_varargs__doc__}, + +static PyObject * +null_or_tuple_for_varargs_impl(PyObject *module, PyObject *name, + PyObject *constraints, int covariant); + +static PyObject * +null_or_tuple_for_varargs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(covariant), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "covariant", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "null_or_tuple_for_varargs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *name; + PyObject *constraints = NULL; + int covariant = 0; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + name = args[0]; + constraints = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + covariant = PyObject_IsTrue(args[2]); + if (covariant < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = null_or_tuple_for_varargs_impl(module, name, constraints, covariant); + +exit: + Py_XDECREF(constraints); + return return_value; +} + PyDoc_STRVAR(clone_f1__doc__, "clone_f1($module, /, path)\n" "--\n" @@ -3070,4 +3141,4 @@ clone_with_conv_f2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py exit: return return_value; } -/*[clinic end generated code: output=c2a69a08ffdfc466 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=90743ac900d60f9f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic_depr.c.h b/Modules/clinic/_testclinic_depr.c.h index 36ff55bc002939..732c3810408399 100644 --- a/Modules/clinic/_testclinic_depr.c.h +++ b/Modules/clinic/_testclinic_depr.c.h @@ -7,6 +7,7 @@ preserve #endif #include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_long.h" // _PyLong_UnsignedShort_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_runtime.h" // _Py_ID() PyDoc_STRVAR(depr_star_new__doc__, @@ -2392,4 +2393,4 @@ depr_multi(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=689b1e2d0872e413 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2c19d1804ba6e53b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testinternalcapi.c.h b/Modules/clinic/_testinternalcapi.c.h index c1b42672e13d53..cba2a943d03456 100644 --- a/Modules/clinic/_testinternalcapi.c.h +++ b/Modules/clinic/_testinternalcapi.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_testinternalcapi_compiler_cleandoc__doc__, "compiler_cleandoc($module, /, doc)\n" @@ -265,38 +266,6 @@ _testinternalcapi_assemble_code_object(PyObject *module, PyObject *const *args, return return_value; } -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" @@ -313,4 +282,4 @@ _testinternalcapi_test_long_numbits(PyObject *module, PyObject *Py_UNUSED(ignore { return _testinternalcapi_test_long_numbits_impl(module); } -/*[clinic end generated code: output=59144f59957627bd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=679bf53bbae20085 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index a96d20bf33ea03..c0a00954c16cbe 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_testmultiphase_StateAccessType_get_defining_module__doc__, "get_defining_module($self, /)\n" @@ -161,4 +162,4 @@ _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObj } return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=db1fdd15244ee59c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d8c262af27b3b98d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index fcfc406238808b..188bcc773cfc41 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_BadArgument() + PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, "eval($self, script, /)\n" "--\n" @@ -859,4 +861,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=bcd9cdc8f6bdcfae input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d447501ec5aa9447 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tracemalloc.c.h b/Modules/clinic/_tracemalloc.c.h index c07ad797d6295b..1d100247423991 100644 --- a/Modules/clinic/_tracemalloc.c.h +++ b/Modules/clinic/_tracemalloc.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, "is_tracing($module, /)\n" "--\n" @@ -212,4 +214,4 @@ _tracemalloc_reset_peak(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _tracemalloc_reset_peak_impl(module); } -/*[clinic end generated code: output=ad7d1fae89f2bdaa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9d4d884b156c2ddb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index 541cba75e6813c..550b6c4d71a015 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -2,6 +2,9 @@ preserve [clinic start generated code]*/ +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_weakref_getweakrefcount__doc__, "getweakrefcount($module, object, /)\n" "--\n" @@ -20,7 +23,9 @@ _weakref_getweakrefcount(PyObject *module, PyObject *object) PyObject *return_value = NULL; Py_ssize_t _return_value; + Py_BEGIN_CRITICAL_SECTION(object); _return_value = _weakref_getweakrefcount_impl(module, object); + Py_END_CRITICAL_SECTION(); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -74,6 +79,21 @@ PyDoc_STRVAR(_weakref_getweakrefs__doc__, #define _WEAKREF_GETWEAKREFS_METHODDEF \ {"getweakrefs", (PyCFunction)_weakref_getweakrefs, METH_O, _weakref_getweakrefs__doc__}, +static PyObject * +_weakref_getweakrefs_impl(PyObject *module, PyObject *object); + +static PyObject * +_weakref_getweakrefs(PyObject *module, PyObject *object) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(object); + return_value = _weakref_getweakrefs_impl(module, object); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_weakref_proxy__doc__, "proxy($module, object, callback=None, /)\n" "--\n" @@ -110,4 +130,4 @@ _weakref_proxy(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=f4be6b8177fbceb8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d5d30707212a9870 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 2d02789689769b..5d99caae9d52af 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_long.h" // _PyLong_Size_t_Converter() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, "GetOverlappedResult($self, wait, /)\n" @@ -704,7 +705,7 @@ _winapi_GetExitCodeProcess(PyObject *module, PyObject *arg) if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { goto exit; } - return_value = Py_BuildValue("k", _return_value); + return_value = PyLong_FromUnsignedLong(_return_value); exit: return return_value; @@ -731,7 +732,7 @@ _winapi_GetLastError(PyObject *module, PyObject *Py_UNUSED(ignored)) if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { goto exit; } - return_value = Py_BuildValue("k", _return_value); + return_value = PyLong_FromUnsignedLong(_return_value); exit: return return_value; @@ -1796,7 +1797,7 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if ((_return_value == PY_DWORD_MAX) && PyErr_Occurred()) { goto exit; } - return_value = Py_BuildValue("k", _return_value); + return_value = PyLong_FromUnsignedLong(_return_value); exit: return return_value; @@ -1970,4 +1971,4 @@ _winapi_CopyFile2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO return return_value; } -/*[clinic end generated code: output=025b2c56d469c899 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3084c671239bbed4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_zoneinfo.c.h b/Modules/clinic/_zoneinfo.c.h index 6691d39deb7c24..9905b6425e2f79 100644 --- a/Modules/clinic/_zoneinfo.c.h +++ b/Modules/clinic/_zoneinfo.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(zoneinfo_ZoneInfo_from_file__doc__, "from_file($type, file_obj, /, key=None)\n" @@ -371,4 +372,4 @@ zoneinfo_ZoneInfo__unpickle(PyTypeObject *type, PyTypeObject *cls, PyObject *con exit: return return_value; } -/*[clinic end generated code: output=a5384f79d49a593b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2a15f32fdd2ab6cd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 2a874b8c830609..dbce0313541649 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(array_array___copy____doc__, "__copy__($self, /)\n" @@ -441,10 +442,6 @@ array_array_frombytes(arrayobject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("frombytes", "argument", "contiguous buffer", arg); - goto exit; - } return_value = array_array_frombytes_impl(self, &buffer); exit: @@ -670,4 +667,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=8595b1906b5a6552 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bf086c01e7e482bf input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index d80decf145bfdc..1adca415dfee12 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(binascii_a2b_uu__doc__, "a2b_uu($module, data, /)\n" @@ -91,10 +92,6 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_uu", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_kwonly; } @@ -242,10 +239,6 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_base64", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_kwonly; } @@ -290,10 +283,6 @@ binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("crc_hqx", "argument 1", "contiguous buffer", args[0]); - goto exit; - } crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); if (crc == (unsigned int)-1 && PyErr_Occurred()) { goto exit; @@ -335,10 +324,6 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("crc32", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -434,10 +419,6 @@ binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_hex", "argument 'data'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -527,10 +508,6 @@ binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("hexlify", "argument 'data'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -754,10 +731,6 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_qp", "argument 'data'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -794,4 +767,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=acc9419209dfd568 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=968767b663ed889d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index a665ac3c1c4994..b709204af1d959 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(cmath_acos__doc__, "acos($module, z, /)\n" @@ -981,4 +982,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=96a5c4ae198dd5bf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=364093af55bfe53f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index 83e882bbbaf184..5dc2fc068d0f7e 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(fcntl_fcntl__doc__, "fcntl($module, fd, cmd, arg=0, /)\n" @@ -245,4 +246,4 @@ fcntl_lockf(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=4d4fac195494faec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=732e33ba92042031 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 40448404877e3e..ad4469350447cb 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(gc_enable__doc__, "enable($module, /)\n" @@ -424,4 +425,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=63093e7724b94a37 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c345e7b4ce6085a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index e6c9cccfce4a76..1da061f3fd8eb1 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(grp_getgrgid__doc__, "getgrgid($module, /, id)\n" @@ -145,4 +146,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=d4bdad9b26fb8558 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f7011384604d38d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index 74cd3ddc3c9a86..fa2c5e0e922387 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(batched_new__doc__, "batched(iterable, n)\n" @@ -913,4 +914,4 @@ itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=95bb863274717bd9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=782fe7e30733779b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index bfce397be77c8b..ca14c03f16f706 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(math_ceil__doc__, "ceil($module, x, /)\n" @@ -949,4 +950,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=da62cea7eb3dc8bc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6b2eeaed8d8a76d5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 6087a0f9c25c1a..7d4d3108dab9b6 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(MD5Type_copy__doc__, "copy($self, /)\n" @@ -147,4 +148,4 @@ _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=943d42b9d17d9a5b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bfadda44914804a8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 9a71e25aa557a4..8b285e4a8f0a72 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_long.h" // _PyLong_UnsignedLong_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, "CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" @@ -623,10 +624,6 @@ _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *arg if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bufobj, 'C')) { - _PyArg_BadArgument("ReadFileInto", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj); exit: @@ -714,10 +711,6 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bufobj, 'C')) { - _PyArg_BadArgument("WSARecvInto", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { goto exit; } @@ -762,10 +755,6 @@ _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bufobj, 'C')) { - _PyArg_BadArgument("WriteFile", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj); exit: @@ -808,10 +797,6 @@ _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bufobj, 'C')) { - _PyArg_BadArgument("WSASend", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { goto exit; } @@ -1137,10 +1122,6 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bufobj, 'C')) { - _PyArg_BadArgument("WSASendTo", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { goto exit; } @@ -1238,10 +1219,6 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bufobj, 'C')) { - _PyArg_BadArgument("WSARecvFromInto", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (!_PyLong_UnsignedLong_Converter(args[2], &size)) { goto exit; } @@ -1262,4 +1239,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=31bcc780209593a2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=958cbddbcc355f47 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index e77a31b947f45e..9d6cd337f4a2f4 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -9,6 +9,7 @@ preserve #include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() #include "pycore_long.h" // _PyLong_UnsignedInt_Converter() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(os_stat__doc__, "stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" @@ -1848,6 +1849,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" @@ -5962,8 +5997,6 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #endif /* defined(HAVE_SYMLINK) */ -#if defined(HAVE_TIMES) - PyDoc_STRVAR(os_times__doc__, "times($module, /)\n" "--\n" @@ -5986,7 +6019,375 @@ os_times(PyObject *module, PyObject *Py_UNUSED(ignored)) return os_times_impl(module); } -#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) @@ -6803,10 +7204,6 @@ os_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[1], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("write", "argument 2", "contiguous buffer", args[1]); - goto exit; - } _return_value = os_write_impl(module, fd, &data); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; @@ -7405,10 +7802,6 @@ os_pwrite(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("pwrite", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (!Py_off_t_converter(args[2], &offset)) { goto exit; } @@ -8161,7 +8554,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #endif /* (defined HAVE_TRUNCATE || defined MS_WINDOWS) */ -#if (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)) +#if (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) && !defined(__wasi__)) PyDoc_STRVAR(os_posix_fallocate__doc__, "posix_fallocate($module, fd, offset, length, /)\n" @@ -8206,7 +8599,7 @@ os_posix_fallocate(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)) */ +#endif /* (defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) && !defined(__wasi__)) */ #if (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) @@ -9847,10 +10240,6 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (PyObject_GetBuffer(args[2], &value, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&value, 'C')) { - _PyArg_BadArgument("setxattr", "argument 'value'", "contiguous buffer", args[2]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -10425,11 +10814,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__}, @@ -11369,6 +11756,28 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #endif /* (defined(WIFEXITED) || defined(MS_WINDOWS)) */ +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__supports_virtual_terminal__doc__, +"_supports_virtual_terminal($module, /)\n" +"--\n" +"\n" +"Checks if virtual terminal is supported in windows"); + +#define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF \ + {"_supports_virtual_terminal", (PyCFunction)os__supports_virtual_terminal, METH_NOARGS, os__supports_virtual_terminal__doc__}, + +static PyObject * +os__supports_virtual_terminal_impl(PyObject *module); + +static PyObject * +os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os__supports_virtual_terminal_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + #ifndef OS_TTYNAME_METHODDEF #define OS_TTYNAME_METHODDEF #endif /* !defined(OS_TTYNAME_METHODDEF) */ @@ -11453,6 +11862,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) */ @@ -11721,9 +12134,25 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #define OS_SYMLINK_METHODDEF #endif /* !defined(OS_SYMLINK_METHODDEF) */ -#ifndef OS_TIMES_METHODDEF - #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 @@ -11988,4 +12417,8 @@ 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=51aa26bc6a41e1da input=a9049054013a1b77]*/ + +#ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF + #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF +#endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ +/*[clinic end generated code: output=ff0ec3371de19904 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index 0e8aa5e6a9f470..43d4825031c7e6 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_BadArgument() + PyDoc_STRVAR(pwd_getpwuid__doc__, "getpwuid($module, uidobj, /)\n" "--\n" @@ -71,4 +73,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=211c7a2516899b91 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a8fb12939ff4ea3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index 21b09110d00853..a5b93e68598204 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "Parse($self, data, isfinal=False, /)\n" @@ -497,4 +498,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=ac398d94833e802d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48c4296e43777df4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h index e5a784a5f79e5a..1c616d60f097cc 100644 --- a/Modules/clinic/readline.c.h +++ b/Modules/clinic/readline.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(readline_parse_and_bind__doc__, "parse_and_bind($module, string, /)\n" "--\n" @@ -682,4 +684,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=790ed2ba01babb60 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=358ab465285c7949 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/resource.c.h b/Modules/clinic/resource.c.h index 0ac272af25d154..9eda7de27532a1 100644 --- a/Modules/clinic/resource.c.h +++ b/Modules/clinic/resource.c.h @@ -66,7 +66,7 @@ PyDoc_STRVAR(resource_setrlimit__doc__, "\n"); #define RESOURCE_SETRLIMIT_METHODDEF \ - {"setrlimit", _PyCFunction_CAST(resource_setrlimit), METH_FASTCALL, resource_setrlimit__doc__}, + {"setrlimit", (PyCFunction)(void(*)(void))resource_setrlimit, METH_FASTCALL, resource_setrlimit__doc__}, static PyObject * resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits); @@ -78,7 +78,8 @@ resource_setrlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int resource; PyObject *limits; - if (!_PyArg_CheckPositional("setrlimit", nargs, 2, 2)) { + if (nargs != 2) { + PyErr_Format(PyExc_TypeError, "setrlimit expected 2 arguments, got %zd", nargs); goto exit; } resource = PyLong_AsInt(args[0]); @@ -100,7 +101,7 @@ PyDoc_STRVAR(resource_prlimit__doc__, "\n"); #define RESOURCE_PRLIMIT_METHODDEF \ - {"prlimit", _PyCFunction_CAST(resource_prlimit), METH_FASTCALL, resource_prlimit__doc__}, + {"prlimit", (PyCFunction)(void(*)(void))resource_prlimit, METH_FASTCALL, resource_prlimit__doc__}, static PyObject * resource_prlimit_impl(PyObject *module, pid_t pid, int resource, @@ -114,7 +115,12 @@ resource_prlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int resource; PyObject *limits = Py_None; - if (!_PyArg_CheckPositional("prlimit", nargs, 2, 3)) { + if (nargs < 2) { + PyErr_Format(PyExc_TypeError, "prlimit expected at least 2 arguments, got %zd", nargs); + goto exit; + } + if (nargs > 3) { + PyErr_Format(PyExc_TypeError, "prlimit expected at most 3 arguments, got %zd", nargs); goto exit; } pid = PyLong_AsPid(args[0]); @@ -172,4 +178,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=2376b9a3f03777aa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e45883ace510414a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index 282196b8f88973..67e76d4c89f59a 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -8,6 +8,7 @@ preserve #endif #include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() #include "pycore_long.h" // _PyLong_UnsignedShort_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(select_select__doc__, "select($module, rlist, wlist, xlist, timeout=None, /)\n" @@ -1310,4 +1311,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=35cd4aa7b6802838 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4c2dcb31cb17c2c6 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index fa4ec8bb51e787..ee391656fb67c3 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(SHA1Type_copy__doc__, "copy($self, /)\n" @@ -147,4 +148,4 @@ _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * exit: return return_value; } -/*[clinic end generated code: output=7efbe42154a7a7f8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=41fc7579213b57b4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha2module.c.h b/Modules/clinic/sha2module.c.h index 9fb8bf7de876fa..ec31d5545be4c1 100644 --- a/Modules/clinic/sha2module.c.h +++ b/Modules/clinic/sha2module.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(SHA256Type_copy__doc__, "copy($self, /)\n" @@ -436,4 +437,4 @@ _sha2_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=1242ccc50bcefe98 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1482d9de086e45c4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h index fd65462d62c195..738e9589503900 100644 --- a/Modules/clinic/sha3module.c.h +++ b/Modules/clinic/sha3module.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_long.h" // _PyLong_UnsignedLong_Converter() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(py_sha3_new__doc__, "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n" @@ -193,4 +194,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=0888aed37ef39984 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a8e76a880d1421ec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 5e8957a4be780d..bc33e066654364 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(signal_default_int_handler__doc__, "default_int_handler($module, signalnum, frame, /)\n" "--\n" @@ -699,4 +701,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=ef4c2ad1a2443063 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a9928cb2dc75b5f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h index c62050160f1117..3f4056efff2fec 100644 --- a/Modules/clinic/socketmodule.c.h +++ b/Modules/clinic/socketmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static int sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, @@ -90,4 +91,172 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=1b68ae94d6cbeeb1 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_socket_socket_ntohs__doc__, +"ntohs($self, x, /)\n" +"--\n" +"\n" +"Convert a 16-bit unsigned integer from network to host byte order."); + +#define _SOCKET_SOCKET_NTOHS_METHODDEF \ + {"ntohs", (PyCFunction)_socket_socket_ntohs, METH_O, _socket_socket_ntohs__doc__}, + +static PyObject * +_socket_socket_ntohs_impl(PySocketSockObject *self, int x); + +static PyObject * +_socket_socket_ntohs(PySocketSockObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int x; + + x = PyLong_AsInt(arg); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _socket_socket_ntohs_impl(self, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_socket_socket_htons__doc__, +"htons($self, x, /)\n" +"--\n" +"\n" +"Convert a 16-bit unsigned integer from host to network byte order."); + +#define _SOCKET_SOCKET_HTONS_METHODDEF \ + {"htons", (PyCFunction)_socket_socket_htons, METH_O, _socket_socket_htons__doc__}, + +static PyObject * +_socket_socket_htons_impl(PySocketSockObject *self, int x); + +static PyObject * +_socket_socket_htons(PySocketSockObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int x; + + x = PyLong_AsInt(arg); + if (x == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _socket_socket_htons_impl(self, x); + +exit: + return return_value; +} + +PyDoc_STRVAR(_socket_socket_inet_aton__doc__, +"inet_aton($self, ip_addr, /)\n" +"--\n" +"\n" +"Convert an IP address in string format (123.45.67.89) to the 32-bit packed binary format used in low-level network functions."); + +#define _SOCKET_SOCKET_INET_ATON_METHODDEF \ + {"inet_aton", (PyCFunction)_socket_socket_inet_aton, METH_O, _socket_socket_inet_aton__doc__}, + +static PyObject * +_socket_socket_inet_aton_impl(PySocketSockObject *self, const char *ip_addr); + +static PyObject * +_socket_socket_inet_aton(PySocketSockObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *ip_addr; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("inet_aton", "argument", "str", arg); + goto exit; + } + Py_ssize_t ip_addr_length; + ip_addr = PyUnicode_AsUTF8AndSize(arg, &ip_addr_length); + if (ip_addr == NULL) { + goto exit; + } + if (strlen(ip_addr) != (size_t)ip_addr_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _socket_socket_inet_aton_impl(self, ip_addr); + +exit: + return return_value; +} + +#if defined(HAVE_INET_NTOA) + +PyDoc_STRVAR(_socket_socket_inet_ntoa__doc__, +"inet_ntoa($self, packed_ip, /)\n" +"--\n" +"\n" +"Convert an IP address from 32-bit packed binary format to string format."); + +#define _SOCKET_SOCKET_INET_NTOA_METHODDEF \ + {"inet_ntoa", (PyCFunction)_socket_socket_inet_ntoa, METH_O, _socket_socket_inet_ntoa__doc__}, + +static PyObject * +_socket_socket_inet_ntoa_impl(PySocketSockObject *self, Py_buffer *packed_ip); + +static PyObject * +_socket_socket_inet_ntoa(PySocketSockObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer packed_ip = {NULL, NULL}; + + if (PyObject_GetBuffer(arg, &packed_ip, PyBUF_SIMPLE) != 0) { + goto exit; + } + return_value = _socket_socket_inet_ntoa_impl(self, &packed_ip); + +exit: + /* Cleanup for packed_ip */ + if (packed_ip.obj) { + PyBuffer_Release(&packed_ip); + } + + return return_value; +} + +#endif /* defined(HAVE_INET_NTOA) */ + +#if (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) + +PyDoc_STRVAR(_socket_socket_if_nametoindex__doc__, +"if_nametoindex($self, oname, /)\n" +"--\n" +"\n" +"Returns the interface index corresponding to the interface name if_name."); + +#define _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF \ + {"if_nametoindex", (PyCFunction)_socket_socket_if_nametoindex, METH_O, _socket_socket_if_nametoindex__doc__}, + +static PyObject * +_socket_socket_if_nametoindex_impl(PySocketSockObject *self, PyObject *oname); + +static PyObject * +_socket_socket_if_nametoindex(PySocketSockObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *oname; + + if (!PyUnicode_FSConverter(arg, &oname)) { + goto exit; + } + return_value = _socket_socket_if_nametoindex_impl(self, oname); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS)) */ + +#ifndef _SOCKET_SOCKET_INET_NTOA_METHODDEF + #define _SOCKET_SOCKET_INET_NTOA_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_INET_NTOA_METHODDEF) */ + +#ifndef _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF + #define _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF +#endif /* !defined(_SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF) */ +/*[clinic end generated code: output=eb37b5d88a1e4661 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 2cd08f81782007..2ecd3afc00d2be 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_symtable_symtable__doc__, "symtable($module, source, filename, startstr, /)\n" "--\n" @@ -48,4 +50,4 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3f7ccf535d750238 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=931964a76a72f850 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/syslogmodule.c.h b/Modules/clinic/syslogmodule.c.h index f0c6f2a871d042..58b0ea57b065b3 100644 --- a/Modules/clinic/syslogmodule.c.h +++ b/Modules/clinic/syslogmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(syslog_openlog__doc__, "openlog($module, /, ident=, logoption=0,\n" @@ -250,4 +251,4 @@ syslog_LOG_UPTO(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=68942dad7fb3872e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=86ca2fd84b2da98e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h index 78828e57d73077..1c340681e5862f 100644 --- a/Modules/clinic/termios.c.h +++ b/Modules/clinic/termios.c.h @@ -3,6 +3,7 @@ preserve [clinic start generated code]*/ #include "pycore_fileutils.h" // _PyLong_FileDescriptor_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(termios_tcgetattr__doc__, "tcgetattr($module, fd, /)\n" @@ -288,4 +289,4 @@ termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=daecc8ebc8fe29f5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f31382658135c774 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/timemodule.c.h b/Modules/clinic/timemodule.c.h new file mode 100644 index 00000000000000..bbc0748f9a9c0d --- /dev/null +++ b/Modules/clinic/timemodule.c.h @@ -0,0 +1,74 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(HAVE_CLOCK_GETTIME) + +PyDoc_STRVAR(time_clock_gettime__doc__, +"clock_gettime($module, clk_id, /)\n" +"--\n" +"\n" +"Return the time of the specified clock clk_id as a float."); + +#define TIME_CLOCK_GETTIME_METHODDEF \ + {"clock_gettime", (PyCFunction)time_clock_gettime, METH_O, time_clock_gettime__doc__}, + +static PyObject * +time_clock_gettime_impl(PyObject *module, clockid_t clk_id); + +static PyObject * +time_clock_gettime(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + clockid_t clk_id; + + if (!time_clockid_converter(arg, &clk_id)) { + goto exit; + } + return_value = time_clock_gettime_impl(module, clk_id); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CLOCK_GETTIME) */ + +#if defined(HAVE_CLOCK_GETTIME) + +PyDoc_STRVAR(time_clock_gettime_ns__doc__, +"clock_gettime_ns($module, clk_id, /)\n" +"--\n" +"\n" +"Return the time of the specified clock clk_id as nanoseconds (int)."); + +#define TIME_CLOCK_GETTIME_NS_METHODDEF \ + {"clock_gettime_ns", (PyCFunction)time_clock_gettime_ns, METH_O, time_clock_gettime_ns__doc__}, + +static PyObject * +time_clock_gettime_ns_impl(PyObject *module, clockid_t clk_id); + +static PyObject * +time_clock_gettime_ns(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + clockid_t clk_id; + + if (!time_clockid_converter(arg, &clk_id)) { + goto exit; + } + return_value = time_clock_gettime_ns_impl(module, clk_id); + +exit: + return return_value; +} + +#endif /* defined(HAVE_CLOCK_GETTIME) */ + +#ifndef TIME_CLOCK_GETTIME_METHODDEF + #define TIME_CLOCK_GETTIME_METHODDEF +#endif /* !defined(TIME_CLOCK_GETTIME_METHODDEF) */ + +#ifndef TIME_CLOCK_GETTIME_NS_METHODDEF + #define TIME_CLOCK_GETTIME_NS_METHODDEF +#endif /* !defined(TIME_CLOCK_GETTIME_NS_METHODDEF) */ +/*[clinic end generated code: output=b589a2132aa9df47 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index 74362c6a6857b7..739f498f1d2672 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "decimal($self, chr, default=, /)\n" "--\n" @@ -517,4 +519,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=ca10ded25747d182 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea30f89007b2bfff input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index 895215307974f7..6b09abe309bf48 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(zlib_compress__doc__, "compress($module, data, /, level=Z_DEFAULT_COMPRESSION, wbits=MAX_WBITS)\n" @@ -69,10 +70,6 @@ zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -163,10 +160,6 @@ zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -333,10 +326,6 @@ zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (PyObject_GetBuffer(args[5], &zdict, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&zdict, 'C')) { - _PyArg_BadArgument("compressobj", "argument 'zdict'", "contiguous buffer", args[5]); - goto exit; - } skip_optional_pos: return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict); @@ -472,10 +461,6 @@ zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *arg if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("compress", "argument 1", "contiguous buffer", args[0]); - goto exit; - } return_value = zlib_Compress_compress_impl(self, cls, &data); exit: @@ -552,10 +537,6 @@ zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -964,10 +945,6 @@ zlib_ZlibDecompressor_decompress(ZlibDecompressor *self, PyObject *const *args, if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); - goto exit; - } if (!noptargs) { goto skip_optional_pos; } @@ -1025,10 +1002,6 @@ zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("adler32", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1079,10 +1052,6 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("crc32", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (nargs < 2) { goto skip_optional; } @@ -1129,4 +1098,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=6d90c72ba2dd04c5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6dd97dc851c39031 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/errnomodule.c b/Modules/errnomodule.c index 301ad8313bc512..1100e9f6094352 100644 --- a/Modules/errnomodule.c +++ b/Modules/errnomodule.c @@ -1,41 +1,49 @@ - /* Errno module */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 +#endif + #include "Python.h" +#include // EPIPE /* Windows socket errors (WSA*) */ #ifdef MS_WINDOWS -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -/* The following constants were added to errno.h in VS2010 but have - preferred WSA equivalents. */ -#undef EADDRINUSE -#undef EADDRNOTAVAIL -#undef EAFNOSUPPORT -#undef EALREADY -#undef ECONNABORTED -#undef ECONNREFUSED -#undef ECONNRESET -#undef EDESTADDRREQ -#undef EHOSTUNREACH -#undef EINPROGRESS -#undef EISCONN -#undef ELOOP -#undef EMSGSIZE -#undef ENETDOWN -#undef ENETRESET -#undef ENETUNREACH -#undef ENOBUFS -#undef ENOPROTOOPT -#undef ENOTCONN -#undef ENOTSOCK -#undef EOPNOTSUPP -#undef EPROTONOSUPPORT -#undef EPROTOTYPE -#undef ETIMEDOUT -#undef EWOULDBLOCK +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + + // The following constants were added to errno.h in VS2010 but have + // preferred WSA equivalents. +# undef EADDRINUSE +# undef EADDRNOTAVAIL +# undef EAFNOSUPPORT +# undef EALREADY +# undef ECONNABORTED +# undef ECONNREFUSED +# undef ECONNRESET +# undef EDESTADDRREQ +# undef EHOSTUNREACH +# undef EINPROGRESS +# undef EISCONN +# undef ELOOP +# undef EMSGSIZE +# undef ENETDOWN +# undef ENETRESET +# undef ENETUNREACH +# undef ENOBUFS +# undef ENOPROTOOPT +# undef ENOTCONN +# undef ENOTSOCK +# undef EOPNOTSUPP +# undef EPROTONOSUPPORT +# undef EPROTOTYPE +# undef ETIMEDOUT +# undef EWOULDBLOCK #endif /* diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 4b6bf68be07202..a2e3c2300b3ce8 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -6,8 +6,10 @@ #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 @@ -16,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) @@ -24,6 +26,7 @@ # include // getauxval() #endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 632cabdf4bcfbd..2d1f381e622226 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -24,6 +24,7 @@ */ #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" @@ -73,6 +74,20 @@ module gc #define AS_GC(op) _Py_AS_GC(op) #define FROM_GC(gc) _Py_FROM_GC(gc) +// Automatically choose the generation that needs collecting. +#define GENERATION_AUTO (-1) + +typedef enum { + // GC was triggered by heap allocation + _Py_GC_REASON_HEAP, + + // GC was called during shutdown + _Py_GC_REASON_SHUTDOWN, + + // GC was called by gc.collect() or PyGC_Collect() + _Py_GC_REASON_MANUAL +} _PyGC_Reason; + static inline int gc_is_collecting(PyGC_Head *g) @@ -490,15 +505,16 @@ subtract_refs(PyGC_Head *containers) PyObject *op = FROM_GC(gc); traverse = Py_TYPE(op)->tp_traverse; (void) traverse(op, - (visitproc)visit_decref, + visit_decref, op); } } /* A traversal callback for move_unreachable. */ static int -visit_reachable(PyObject *op, PyGC_Head *reachable) +visit_reachable(PyObject *op, void *arg) { + PyGC_Head *reachable = arg; OBJECT_STAT_INC(object_visits); if (!_PyObject_IS_GC(op)) { return 0; @@ -602,7 +618,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) // NOTE: visit_reachable may change gc->_gc_next when // young->_gc_prev == gc. Don't do gc = GC_NEXT(gc) before! (void) traverse(op, - (visitproc)visit_reachable, + visit_reachable, (void *)young); // relink gc_prev to prev element. _PyGCHead_SET_PREV(gc, prev); @@ -725,8 +741,9 @@ clear_unreachable_mask(PyGC_Head *unreachable) /* A traversal callback for move_legacy_finalizer_reachable. */ static int -visit_move(PyObject *op, PyGC_Head *tolist) +visit_move(PyObject *op, void *arg) { + PyGC_Head *tolist = arg; OBJECT_STAT_INC(object_visits); if (_PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); @@ -750,7 +767,7 @@ move_legacy_finalizer_reachable(PyGC_Head *finalizers) /* Note that the finalizers list may grow during this. */ traverse = Py_TYPE(FROM_GC(gc))->tp_traverse; (void) traverse(FROM_GC(gc), - (visitproc)visit_move, + visit_move, (void *)finalizers); } } @@ -1031,8 +1048,8 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, Py_INCREF(op); (void) clear(op); if (_PyErr_Occurred(tstate)) { - _PyErr_WriteUnraisableMsg("in tp_clear of", - (PyObject*)Py_TYPE(op)); + PyErr_FormatUnraisable("Exception ignored in tp_clear of %s", + Py_TYPE(op)->tp_name); } Py_DECREF(op); } @@ -1191,19 +1208,122 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable, gc_list_merge(resurrected, old_generation); } + +/* Invoke progress callbacks to notify clients that garbage collection + * is starting or stopping + */ +static void +invoke_gc_callback(PyThreadState *tstate, const char *phase, + int generation, Py_ssize_t collected, + Py_ssize_t uncollectable) +{ + assert(!_PyErr_Occurred(tstate)); + + /* we may get called very early */ + GCState *gcstate = &tstate->interp->gc; + if (gcstate->callbacks == NULL) { + return; + } + + /* The local variable cannot be rebound, check it for sanity */ + assert(PyList_CheckExact(gcstate->callbacks)); + PyObject *info = NULL; + if (PyList_GET_SIZE(gcstate->callbacks) != 0) { + info = Py_BuildValue("{sisnsn}", + "generation", generation, + "collected", collected, + "uncollectable", uncollectable); + if (info == NULL) { + PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks"); + return; + } + } + + PyObject *phase_obj = PyUnicode_FromString(phase); + if (phase_obj == NULL) { + Py_XDECREF(info); + PyErr_FormatUnraisable("Exception ignored on invoking gc callbacks"); + return; + } + + PyObject *stack[] = {phase_obj, info}; + for (Py_ssize_t i=0; icallbacks); i++) { + PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); + Py_INCREF(cb); /* make sure cb doesn't go away */ + r = PyObject_Vectorcall(cb, stack, 2, NULL); + if (r == NULL) { + PyErr_WriteUnraisable(cb); + } + else { + Py_DECREF(r); + } + Py_DECREF(cb); + } + Py_DECREF(phase_obj); + Py_XDECREF(info); + assert(!_PyErr_Occurred(tstate)); +} + + +/* Find the oldest generation (highest numbered) where the count + * exceeds the threshold. Objects in the that generation and + * generations younger than it will be collected. */ +static int +gc_select_generation(GCState *gcstate) +{ + for (int i = NUM_GENERATIONS-1; i >= 0; i--) { + if (gcstate->generations[i].count > gcstate->generations[i].threshold) { + /* Avoid quadratic performance degradation in number + of tracked objects (see also issue #4074): + + To limit the cost of garbage collection, there are two strategies; + - make each collection faster, e.g. by scanning fewer objects + - do less collections + This heuristic is about the latter strategy. + + In addition to the various configurable thresholds, we only trigger a + full collection if the ratio + + long_lived_pending / long_lived_total + + is above a given value (hardwired to 25%). + + The reason is that, while "non-full" collections (i.e., collections of + the young and middle generations) will always examine roughly the same + number of objects -- determined by the aforementioned thresholds --, + the cost of a full collection is proportional to the total number of + long-lived objects, which is virtually unbounded. + + Indeed, it has been remarked that doing a full collection every + of object creations entails a dramatic performance + degradation in workloads which consist in creating and storing lots of + long-lived objects (e.g. building a large list of GC-tracked objects would + show quadratic performance, instead of linear as expected: see issue #4074). + + Using the above ratio, instead, yields amortized linear performance in + the total number of objects (the effect of which can be summarized + thusly: "each full garbage collection is more and more costly as the + number of objects grows, but we do fewer and fewer of them"). + + This heuristic was suggested by Martin von Löwis on python-dev in + June 2008. His original analysis and proposal can be found at: + http://mail.python.org/pipermail/python-dev/2008-June/080579.html + */ + if (i == NUM_GENERATIONS - 1 + && gcstate->long_lived_pending < gcstate->long_lived_total / 4) + continue; + return i; + } + } + return -1; +} + + /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t -gc_collect_main(PyThreadState *tstate, int generation, - Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, - int nofail) +gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason) { - 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 */ @@ -1220,6 +1340,36 @@ gc_collect_main(PyThreadState *tstate, int generation, assert(gcstate->garbage != NULL); assert(!_PyErr_Occurred(tstate)); + int expected = 0; + if (!_Py_atomic_compare_exchange_int(&gcstate->collecting, &expected, 1)) { + // Don't start a garbage collection if one is already in progress. + return 0; + } + + if (generation == GENERATION_AUTO) { + // Select the oldest generation that needs collecting. We will collect + // objects from that generation and all generations younger than it. + generation = gc_select_generation(gcstate); + if (generation < 0) { + // No generation needs to be collected. + _Py_atomic_store_int(&gcstate->collecting, 0); + return 0; + } + } + + assert(generation >= 0 && generation < NUM_GENERATIONS); + +#ifdef Py_STATS + if (_Py_stats) { + _Py_stats->object_stats.object_visits = 0; + } +#endif + GC_STAT_ADD(generation, collections, 1); + + if (reason != _Py_GC_REASON_SHUTDOWN) { + invoke_gc_callback(tstate, "start", generation, 0, 0); + } + if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); show_stats_each_generations(gcstate); @@ -1339,22 +1489,15 @@ gc_collect_main(PyThreadState *tstate, int generation, } if (_PyErr_Occurred(tstate)) { - if (nofail) { + if (reason == _Py_GC_REASON_SHUTDOWN) { _PyErr_Clear(tstate); } else { - _PyErr_WriteUnraisableMsg("in garbage collection", NULL); + PyErr_FormatUnraisable("Exception ignored in garbage collection"); } } /* Update stats */ - if (n_collected) { - *n_collected = m; - } - if (n_uncollectable) { - *n_uncollectable = n; - } - struct gc_generation_stats *stats = &gcstate->generation_stats[generation]; stats->collections++; stats->collected += m; @@ -1373,134 +1516,13 @@ gc_collect_main(PyThreadState *tstate, int generation, PyDTrace_GC_DONE(n + m); } - assert(!_PyErr_Occurred(tstate)); - return n + m; -} - -/* Invoke progress callbacks to notify clients that garbage collection - * is starting or stopping - */ -static void -invoke_gc_callback(PyThreadState *tstate, const char *phase, - int generation, Py_ssize_t collected, - Py_ssize_t uncollectable) -{ - assert(!_PyErr_Occurred(tstate)); - - /* we may get called very early */ - GCState *gcstate = &tstate->interp->gc; - if (gcstate->callbacks == NULL) { - return; - } - - /* The local variable cannot be rebound, check it for sanity */ - assert(PyList_CheckExact(gcstate->callbacks)); - PyObject *info = NULL; - if (PyList_GET_SIZE(gcstate->callbacks) != 0) { - info = Py_BuildValue("{sisnsn}", - "generation", generation, - "collected", collected, - "uncollectable", uncollectable); - if (info == NULL) { - PyErr_WriteUnraisable(NULL); - return; - } + if (reason != _Py_GC_REASON_SHUTDOWN) { + invoke_gc_callback(tstate, "stop", generation, m, n); } - PyObject *phase_obj = PyUnicode_FromString(phase); - if (phase_obj == NULL) { - Py_XDECREF(info); - PyErr_WriteUnraisable(NULL); - return; - } - - PyObject *stack[] = {phase_obj, info}; - for (Py_ssize_t i=0; icallbacks); i++) { - PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); - Py_INCREF(cb); /* make sure cb doesn't go away */ - r = PyObject_Vectorcall(cb, stack, 2, NULL); - if (r == NULL) { - PyErr_WriteUnraisable(cb); - } - else { - Py_DECREF(r); - } - Py_DECREF(cb); - } - Py_DECREF(phase_obj); - Py_XDECREF(info); - assert(!_PyErr_Occurred(tstate)); -} - -/* Perform garbage collection of a generation and invoke - * progress callbacks. - */ -static Py_ssize_t -gc_collect_with_callback(PyThreadState *tstate, int generation) -{ - assert(!_PyErr_Occurred(tstate)); - Py_ssize_t result, collected, uncollectable; - invoke_gc_callback(tstate, "start", generation, 0, 0); - result = gc_collect_main(tstate, generation, &collected, &uncollectable, 0); - invoke_gc_callback(tstate, "stop", generation, collected, uncollectable); assert(!_PyErr_Occurred(tstate)); - return result; -} - -static Py_ssize_t -gc_collect_generations(PyThreadState *tstate) -{ - GCState *gcstate = &tstate->interp->gc; - /* Find the oldest generation (highest numbered) where the count - * exceeds the threshold. Objects in the that generation and - * generations younger than it will be collected. */ - Py_ssize_t n = 0; - for (int i = NUM_GENERATIONS-1; i >= 0; i--) { - if (gcstate->generations[i].count > gcstate->generations[i].threshold) { - /* Avoid quadratic performance degradation in number - of tracked objects (see also issue #4074): - - To limit the cost of garbage collection, there are two strategies; - - make each collection faster, e.g. by scanning fewer objects - - do less collections - This heuristic is about the latter strategy. - - In addition to the various configurable thresholds, we only trigger a - full collection if the ratio - - long_lived_pending / long_lived_total - - is above a given value (hardwired to 25%). - - The reason is that, while "non-full" collections (i.e., collections of - the young and middle generations) will always examine roughly the same - number of objects -- determined by the aforementioned thresholds --, - the cost of a full collection is proportional to the total number of - long-lived objects, which is virtually unbounded. - - Indeed, it has been remarked that doing a full collection every - of object creations entails a dramatic performance - degradation in workloads which consist in creating and storing lots of - long-lived objects (e.g. building a large list of GC-tracked objects would - show quadratic performance, instead of linear as expected: see issue #4074). - - Using the above ratio, instead, yields amortized linear performance in - the total number of objects (the effect of which can be summarized - thusly: "each full garbage collection is more and more costly as the - number of objects grows, but we do fewer and fewer of them"). - - This heuristic was suggested by Martin von Löwis on python-dev in - June 2008. His original analysis and proposal can be found at: - http://mail.python.org/pipermail/python-dev/2008-June/080579.html - */ - if (i == NUM_GENERATIONS - 1 - && gcstate->long_lived_pending < gcstate->long_lived_total / 4) - continue; - n = gc_collect_with_callback(tstate, i); - break; - } - } - return n; + _Py_atomic_store_int(&gcstate->collecting, 0); + return n + m; } #include "clinic/gcmodule.c.h" @@ -1571,18 +1593,7 @@ gc_collect_impl(PyObject *module, int generation) return -1; } - GCState *gcstate = &tstate->interp->gc; - Py_ssize_t n; - if (gcstate->collecting) { - /* already collecting, don't do anything */ - n = 0; - } - else { - gcstate->collecting = 1; - n = gc_collect_with_callback(tstate, generation); - gcstate->collecting = 0; - } - return n; + return gc_collect_main(tstate, generation, _Py_GC_REASON_MANUAL); } /*[clinic input] @@ -1683,8 +1694,9 @@ gc_get_count_impl(PyObject *module) } static int -referrersvisit(PyObject* obj, PyObject *objs) +referrersvisit(PyObject* obj, void *arg) { + PyObject *objs = arg; Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(objs); i++) if (PyTuple_GET_ITEM(objs, i) == obj) @@ -1703,7 +1715,7 @@ gc_referrers_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist) traverse = Py_TYPE(obj)->tp_traverse; if (obj == objs || obj == resultlist) continue; - if (traverse(obj, (visitproc)referrersvisit, objs)) { + if (traverse(obj, referrersvisit, objs)) { if (PyList_Append(resultlist, obj) < 0) return 0; /* error */ } @@ -1739,8 +1751,9 @@ gc_get_referrers(PyObject *self, PyObject *args) /* Append obj to list; return true if error (out of memory), false if OK. */ static int -referentsvisit(PyObject *obj, PyObject *list) +referentsvisit(PyObject *obj, void *arg) { + PyObject *list = arg; return PyList_Append(list, obj) < 0; } @@ -1769,7 +1782,7 @@ gc_get_referents(PyObject *self, PyObject *args) traverse = Py_TYPE(obj)->tp_traverse; if (! traverse) continue; - if (traverse(obj, (visitproc)referentsvisit, result)) { + if (traverse(obj, referentsvisit, result)) { Py_DECREF(result); return NULL; } @@ -2119,17 +2132,9 @@ PyGC_Collect(void) } Py_ssize_t n; - if (gcstate->collecting) { - /* already collecting, don't do anything */ - n = 0; - } - else { - gcstate->collecting = 1; - PyObject *exc = _PyErr_GetRaisedException(tstate); - n = gc_collect_with_callback(tstate, NUM_GENERATIONS - 1); - _PyErr_SetRaisedException(tstate, exc); - gcstate->collecting = 0; - } + PyObject *exc = _PyErr_GetRaisedException(tstate); + n = gc_collect_main(tstate, NUM_GENERATIONS - 1, _Py_GC_REASON_MANUAL); + _PyErr_SetRaisedException(tstate, exc); return n; } @@ -2143,16 +2148,7 @@ _PyGC_CollectNoFail(PyThreadState *tstate) during interpreter shutdown (and then never finish it). See http://bugs.python.org/issue8713#msg195178 for an example. */ - GCState *gcstate = &tstate->interp->gc; - if (gcstate->collecting) { - return 0; - } - - Py_ssize_t n; - gcstate->collecting = 1; - n = gc_collect_main(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1); - gcstate->collecting = 0; - return n; + return gc_collect_main(tstate, NUM_GENERATIONS - 1, _Py_GC_REASON_SHUTDOWN); } void @@ -2270,15 +2266,7 @@ PyObject_IS_GC(PyObject *obj) void _Py_ScheduleGC(PyInterpreterState *interp) { - GCState *gcstate = &interp->gc; - if (gcstate->collecting == 1) { - return; - } - struct _ceval_state *ceval = &interp->ceval; - if (!_Py_atomic_load_relaxed(&ceval->gc_scheduled)) { - _Py_atomic_store_relaxed(&ceval->gc_scheduled, 1); - _Py_atomic_store_relaxed(&ceval->eval_breaker, 1); - } + _Py_set_eval_breaker_bit(interp, _PY_GC_SCHEDULED_BIT, 1); } void @@ -2295,7 +2283,7 @@ _PyObject_GC_Link(PyObject *op) if (gcstate->generations[0].count > gcstate->generations[0].threshold && gcstate->enabled && gcstate->generations[0].threshold && - !gcstate->collecting && + !_Py_atomic_load_int_relaxed(&gcstate->collecting) && !_PyErr_Occurred(tstate)) { _Py_ScheduleGC(tstate->interp); @@ -2305,10 +2293,7 @@ _PyObject_GC_Link(PyObject *op) void _Py_RunGC(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->gc; - gcstate->collecting = 1; - gc_collect_generations(tstate); - gcstate->collecting = 0; + gc_collect_main(tstate, GENERATION_AUTO, _Py_GC_REASON_HEAP); } static PyObject * @@ -2399,14 +2384,16 @@ PyObject_GC_Del(void *op) size_t presize = _PyType_PreHeaderSize(((PyObject *)op)->ob_type); PyGC_Head *g = AS_GC(op); if (_PyObject_GC_IS_TRACKED(op)) { + gc_list_remove(g); #ifdef Py_DEBUG + PyObject *exc = PyErr_GetRaisedException(); if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, "gc", NULL, "Object of type %s is not untracked before destruction", ((PyObject*)op)->ob_type->tp_name)) { PyErr_WriteUnraisable(NULL); } + PyErr_SetRaisedException(exc); #endif - gc_list_remove(g); } GCState *gcstate = get_gc_state(); if (gcstate->generations[0].count > 0) { diff --git a/Modules/getpath.c b/Modules/getpath.c index 3b926cac0d3f24..6c1078b8914522 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -4,8 +4,8 @@ #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 @@ -17,6 +17,7 @@ #endif #ifdef __APPLE__ +# include # include #endif @@ -768,16 +769,11 @@ library_to_dict(PyObject *dict, const char *key) which is in the framework, not relative to the executable, which may be outside of the framework. Except when we're in the build directory... */ - NSSymbol symbol = NSLookupAndBindSymbol("_Py_Initialize"); - if (symbol != NULL) { - NSModule pythonModule = NSModuleForSymbol(symbol); - if (pythonModule != NULL) { - /* Use dylib functions to find out where the framework was loaded from */ - const char *path = NSLibraryNameForModule(pythonModule); - if (path) { - strncpy(modPath, path, MAXPATHLEN); - modPathInitialized = 1; - } + Dl_info pythonInfo; + if (dladdr(&Py_Initialize, &pythonInfo)) { + if (pythonInfo.dli_fname) { + strncpy(modPath, pythonInfo.dli_fname, MAXPATHLEN); + modPathInitialized = 1; } } } @@ -821,7 +817,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"); } @@ -910,7 +906,7 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) ) { Py_DECREF(co); Py_DECREF(dict); - _PyErr_WriteUnraisableMsg("error evaluating initial values", NULL); + PyErr_FormatUnraisable("Exception ignored in preparing getpath"); return PyStatus_Error("error evaluating initial values"); } @@ -919,13 +915,13 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) if (!r) { Py_DECREF(dict); - _PyErr_WriteUnraisableMsg("error evaluating path", NULL); + PyErr_FormatUnraisable("Exception ignored in running getpath"); return PyStatus_Error("error evaluating path"); } Py_DECREF(r); if (_PyConfig_FromDict(config, configDict) < 0) { - _PyErr_WriteUnraisableMsg("reading getpath results", NULL); + PyErr_FormatUnraisable("Exception ignored in reading getpath results"); Py_DECREF(dict); return PyStatus_Error("error getting getpath results"); } diff --git a/Modules/getpath.py b/Modules/getpath.py index 9913fcba497d30..1410ffdbed8c70 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -229,17 +229,16 @@ def search_up(prefix, *landmarks, test=isfile): pythonpath = config.get('module_search_paths') pythonpath_was_set = config.get('module_search_paths_set') +stdlib_dir = config.get('stdlib_dir') +stdlib_dir_was_set_in_config = bool(stdlib_dir) real_executable_dir = None -stdlib_dir = None platstdlib_dir = None # ****************************************************************************** # CALCULATE program_name # ****************************************************************************** -program_name_was_set = bool(program_name) - if not program_name: try: program_name = config.get('orig_argv', [])[0] @@ -509,11 +508,12 @@ def search_up(prefix, *landmarks, test=isfile): build_stdlib_prefix = build_prefix else: build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS) - # Always use the build prefix for stdlib - if build_stdlib_prefix: - stdlib_dir = joinpath(build_stdlib_prefix, 'Lib') - else: - stdlib_dir = joinpath(build_prefix, 'Lib') + # Use the build prefix for stdlib when not explicitly set + if not stdlib_dir_was_set_in_config: + if build_stdlib_prefix: + stdlib_dir = joinpath(build_stdlib_prefix, 'Lib') + else: + stdlib_dir = joinpath(build_prefix, 'Lib') # Only use the build prefix for prefix if it hasn't already been set if not prefix: prefix = build_stdlib_prefix @@ -545,8 +545,9 @@ def search_up(prefix, *landmarks, test=isfile): prefix, had_delim, exec_prefix = home.partition(DELIM) if not had_delim: exec_prefix = prefix - # Reset the standard library directory if it was already set - stdlib_dir = None + # Reset the standard library directory if it was not explicitly set + if not stdlib_dir_was_set_in_config: + stdlib_dir = None # First try to detect prefix by looking alongside our runtime library, if known @@ -562,7 +563,8 @@ def search_up(prefix, *landmarks, test=isfile): if STDLIB_SUBDIR and STDLIB_LANDMARKS and not prefix: if any(isfile(joinpath(library_dir, f)) for f in STDLIB_LANDMARKS): prefix = library_dir - stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) + if not stdlib_dir_was_set_in_config: + stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) # Detect prefix by looking for zip file @@ -573,7 +575,7 @@ def search_up(prefix, *landmarks, test=isfile): prefix = executable_dir else: prefix = search_up(executable_dir, ZIP_LANDMARK) - if prefix: + if prefix and not stdlib_dir_was_set_in_config: stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) if not isdir(stdlib_dir): stdlib_dir = None diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 20e83de84e8340..9756f1c2fb15b1 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -1,6 +1,11 @@ /* UNIX group file access module */ +// clinic/grpmodule.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "posixmodule.h" diff --git a/Modules/hashlib.h b/Modules/hashlib.h index a8bad9dd87a939..7105e68af7b806 100644 --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -1,5 +1,7 @@ /* Common code for use by all hashlib related modules. */ +#include "pycore_lock.h" // PyMutex + /* * Given a PyObject* obj, fill in the Py_buffer* viewp with the result * of PyObject_GetBuffer. Sets an exception and issues the erraction @@ -48,18 +50,28 @@ #include "pythread.h" #define ENTER_HASHLIB(obj) \ - if ((obj)->lock) { \ - if (!PyThread_acquire_lock((obj)->lock, 0)) { \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock((obj)->lock, 1); \ - Py_END_ALLOW_THREADS \ - } \ + if ((obj)->use_mutex) { \ + PyMutex_Lock(&(obj)->mutex); \ } #define LEAVE_HASHLIB(obj) \ - if ((obj)->lock) { \ - PyThread_release_lock((obj)->lock); \ + if ((obj)->use_mutex) { \ + PyMutex_Unlock(&(obj)->mutex); \ } +#ifdef Py_GIL_DISABLED +#define HASHLIB_INIT_MUTEX(obj) \ + do { \ + (obj)->mutex = (PyMutex){0}; \ + (obj)->use_mutex = true; \ + } while (0) +#else +#define HASHLIB_INIT_MUTEX(obj) \ + do { \ + (obj)->mutex = (PyMutex){0}; \ + (obj)->use_mutex = false; \ + } while (0) +#endif + /* TODO(gpshead): We should make this a module or class attribute * to allow the user to optimize based on the platform they're using. */ #define HASHLIB_GIL_MINSIZE 2048 diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 4ed34aa5bde827..ab99fa4d873bf5 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -330,21 +330,30 @@ pairwise_next(pairwiseobject *po) return NULL; } if (old == NULL) { - po->old = old = (*Py_TYPE(it)->tp_iternext)(it); + old = (*Py_TYPE(it)->tp_iternext)(it); + Py_XSETREF(po->old, old); if (old == NULL) { Py_CLEAR(po->it); return NULL; } + it = po->it; + if (it == NULL) { + Py_CLEAR(po->old); + return NULL; + } } + Py_INCREF(old); new = (*Py_TYPE(it)->tp_iternext)(it); if (new == NULL) { Py_CLEAR(po->it); Py_CLEAR(po->old); + Py_DECREF(old); return NULL; } /* Future optimization: Reuse the result tuple as we do in enumerate() */ result = PyTuple_Pack(2, old, new); - Py_SETREF(po->old, new); + Py_XSETREF(po->old, new); + Py_DECREF(old); return result; } diff --git a/Modules/main.c b/Modules/main.c index 05bedff050699f..df2ce550245088 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -249,7 +249,7 @@ pymain_run_command(wchar_t *command) PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags |= PyCF_IGNORE_COOKIE; - ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), &cf); + ret = _PyRun_SimpleStringFlagsWithName(PyBytes_AsString(bytes), "", &cf); Py_DECREF(bytes); return (ret != 0); @@ -556,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 @@ -571,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); } @@ -617,6 +638,7 @@ pymain_run_python(int *exitcode) *exitcode = pymain_exit_err_print(); done: + _PyInterpreterState_SetNotRunningMain(interp); Py_XDECREF(main_importer_path); } diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 2d896e7fe333a4..6cd61e9ab75424 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1125,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) { @@ -1136,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)); } @@ -1196,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) { @@ -2830,7 +2832,7 @@ math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q) PyErr_Clear(); goto finalize_flt_path; } - } else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(q_i))) { + } else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(p_i))) { flt_q = PyFloat_AS_DOUBLE(q_i); flt_p = PyLong_AsDouble(p_i); if (flt_p == -1.0 && PyErr_Occurred()) { diff --git a/Modules/md5module.c b/Modules/md5module.c index 5463effb507de6..7d2b3275f213fd 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -15,14 +15,13 @@ */ /* MD5 objects */ + #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif #include "Python.h" #include "hashlib.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() /*[clinic input] module _md5 @@ -50,8 +49,8 @@ typedef long long MD5_INT64; /* 64-bit integer */ typedef struct { PyObject_HEAD // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; Hacl_Streaming_MD5_state *hash_state; } MD5object; @@ -74,7 +73,11 @@ static MD5object * newMD5object(MD5State * st) { MD5object *md5 = (MD5object *)PyObject_GC_New(MD5object, st->md5_type); - md5->lock = NULL; + if (!md5) { + return NULL; + } + HASHLIB_INIT_MUTEX(md5); + PyObject_GC_Track(md5); return md5; } @@ -91,10 +94,7 @@ static void MD5_dealloc(MD5object *ptr) { Hacl_Streaming_MD5_legacy_free(ptr->hash_state); - if (ptr->lock != NULL) { - PyThread_free_lock(ptr->lock); - } - PyTypeObject *tp = Py_TYPE(ptr); + PyTypeObject *tp = Py_TYPE((PyObject*)ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); Py_DECREF(tp); @@ -115,7 +115,7 @@ static PyObject * MD5Type_copy_impl(MD5object *self, PyTypeObject *cls) /*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ { - MD5State *st = _PyType_GetModuleState(cls); + MD5State *st = PyType_GetModuleState(cls); MD5object *newobj; if ((newobj = newMD5object(st))==NULL) @@ -158,7 +158,16 @@ MD5Type_hexdigest_impl(MD5object *self) ENTER_HASHLIB(self); Hacl_Streaming_MD5_legacy_finish(self->hash_state, digest); LEAVE_HASHLIB(self); - return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); + + const char *hexdigits = "0123456789abcdef"; + char digest_hex[MD5_DIGESTSIZE * 2]; + char *str = digest_hex; + for (size_t i=0; i < MD5_DIGESTSIZE; i++) { + unsigned char byte = digest[i]; + *str++ = hexdigits[byte >> 4]; + *str++ = hexdigits[byte & 0x0f]; + } + return PyUnicode_FromStringAndSize(digest_hex, sizeof(digest_hex)); } static void update(Hacl_Streaming_MD5_state *state, uint8_t *buf, Py_ssize_t len) { @@ -189,14 +198,14 @@ MD5Type_update(MD5object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); update(self->hash_state, buf.buf, buf.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { update(self->hash_state, buf.buf, buf.len); diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index d11200a4042551..66ed0b8efb775c 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -171,7 +171,7 @@ mmap_object_dealloc(mmap_object *m_obj) } static PyObject * -mmap_close_method(mmap_object *self, PyObject *unused) +mmap_close_method(mmap_object *self, PyObject *Py_UNUSED(ignored)) { if (self->exports > 0) { PyErr_SetString(PyExc_BufferError, "cannot close "\ @@ -260,7 +260,7 @@ do { \ static PyObject * mmap_read_byte_method(mmap_object *self, - PyObject *unused) + PyObject *Py_UNUSED(ignored)) { CHECK_VALID(NULL); if (self->pos >= self->size) { @@ -272,7 +272,7 @@ mmap_read_byte_method(mmap_object *self, static PyObject * mmap_read_line_method(mmap_object *self, - PyObject *unused) + PyObject *Py_UNUSED(ignored)) { Py_ssize_t remaining; char *start, *eol; @@ -460,7 +460,7 @@ mmap_write_byte_method(mmap_object *self, static PyObject * mmap_size_method(mmap_object *self, - PyObject *unused) + PyObject *Py_UNUSED(ignored)) { CHECK_VALID(NULL); @@ -657,7 +657,7 @@ mmap_resize_method(mmap_object *self, } static PyObject * -mmap_tell_method(mmap_object *self, PyObject *unused) +mmap_tell_method(mmap_object *self, PyObject *Py_UNUSED(ignored)) { CHECK_VALID(NULL); return PyLong_FromSize_t(self->pos); @@ -729,7 +729,7 @@ mmap_seek_method(mmap_object *self, PyObject *args) if (where > self->size || where < 0) goto onoutofrange; self->pos = where; - Py_RETURN_NONE; + return PyLong_FromSsize_t(self->pos); } onoutofrange: @@ -737,6 +737,12 @@ mmap_seek_method(mmap_object *self, PyObject *args) return NULL; } +static PyObject * +mmap_seekable_method(mmap_object *self, PyObject *Py_UNUSED(ignored)) +{ + Py_RETURN_TRUE; +} + static PyObject * mmap_move_method(mmap_object *self, PyObject *args) { @@ -835,7 +841,7 @@ mmap__repr__method(PyObject *self) #ifdef MS_WINDOWS static PyObject * -mmap__sizeof__method(mmap_object *self, void *unused) +mmap__sizeof__method(mmap_object *self, void *Py_UNUSED(ignored)) { size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->tagname) { @@ -905,6 +911,7 @@ static struct PyMethodDef mmap_object_methods[] = { {"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS}, {"resize", (PyCFunction) mmap_resize_method, METH_VARARGS}, {"seek", (PyCFunction) mmap_seek_method, METH_VARARGS}, + {"seekable", (PyCFunction) mmap_seekable_method, METH_NOARGS}, {"size", (PyCFunction) mmap_size_method, METH_NOARGS}, {"tell", (PyCFunction) mmap_tell_method, METH_NOARGS}, {"write", (PyCFunction) mmap_write_method, METH_VARARGS}, diff --git a/Modules/overlapped.c b/Modules/overlapped.c index e23db22dadb18b..fd40e91d0f50c4 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -599,8 +599,7 @@ _overlapped_FormatMessage_impl(PyObject *module, DWORD code) if (n) { while (iswspace(lpMsgBuf[n-1])) --n; - lpMsgBuf[n] = L'\0'; - res = Py_BuildValue("u", lpMsgBuf); + res = PyUnicode_FromWideChar(lpMsgBuf, n); } else { res = PyUnicode_FromFormat("unknown error code %u", code); } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d7d3e365d2c553..ddbb4cd43babfc 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -24,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) @@ -37,7 +41,6 @@ # endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ #endif - #ifndef MS_WINDOWS # include "posixmodule.h" #else @@ -285,17 +288,19 @@ corresponding Unix manual entries for more information on calls."); # include #endif -#ifdef HAVE_COPY_FILE_RANGE -# include // copy_file_range() -#endif - #if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) # undef HAVE_SCHED_SETAFFINITY #endif -#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. +#if defined(HAVE_SYS_XATTR_H) +# if defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) +# define USE_XATTRS +# include // Needed for XATTR_SIZE_MAX on musl libc. +# endif +# if defined(__CYGWIN__) +# define USE_XATTRS +# include // Needed for XATTR_SIZE_MAX and XATTR_LIST_MAX. +# endif #endif #ifdef USE_XATTRS @@ -551,6 +556,11 @@ extern char *ctermid_r(char *); # include #endif +/* timerfd_create() */ +#ifdef HAVE_SYS_TIMERFD_H +# include +#endif + #ifdef _Py_MEMORY_SANITIZER # include #endif @@ -1020,6 +1030,10 @@ typedef struct { PyObject *struct_rusage; #endif PyObject *st_mode; +#ifndef MS_WINDOWS + // times() clock frequency in hertz; used by os.times() + long ticks_per_second; +#endif } _posixstate; @@ -4810,6 +4824,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 @@ -8134,39 +8179,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; @@ -8178,12 +8229,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 */ @@ -9939,8 +9990,6 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, #endif /* HAVE_SYMLINK */ - - static PyStructSequence_Field times_result_fields[] = { {"user", "user time"}, {"system", "system time"}, @@ -9966,12 +10015,6 @@ static PyStructSequence_Desc times_result_desc = { 5 }; -#ifdef MS_WINDOWS -#define HAVE_TIMES /* mandatory, for the method table */ -#endif - -#ifdef HAVE_TIMES - static PyObject * build_times_result(PyObject *module, double user, double system, double children_user, double children_system, @@ -10017,8 +10060,8 @@ All fields are floating point numbers. static PyObject * os_times_impl(PyObject *module) /*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/ -#ifdef MS_WINDOWS { +#ifdef MS_WINDOWS FILETIME create, exit, kernel, user; HANDLE hProc; hProc = GetCurrentProcess(); @@ -10036,29 +10079,248 @@ os_times_impl(PyObject *module) (double)0, (double)0, (double)0); -} #else /* MS_WINDOWS */ -{ - struct tms t; - clock_t c; + _posixstate *state = get_posix_state(module); + long ticks_per_second = state->ticks_per_second; + + struct tms process; + clock_t elapsed; errno = 0; - c = times(&t); - if (c == (clock_t) -1) { + elapsed = times(&process); + if (elapsed == (clock_t) -1) { return posix_error(); } - assert(_PyRuntime.time.ticks_per_second_initialized); -#define ticks_per_second _PyRuntime.time.ticks_per_second + return build_times_result(module, - (double)t.tms_utime / ticks_per_second, - (double)t.tms_stime / ticks_per_second, - (double)t.tms_cutime / ticks_per_second, - (double)t.tms_cstime / ticks_per_second, - (double)c / ticks_per_second); -#undef ticks_per_second -} + (double)process.tms_utime / ticks_per_second, + (double)process.tms_stime / ticks_per_second, + (double)process.tms_cutime / ticks_per_second, + (double)process.tms_cstime / ticks_per_second, + (double)elapsed / ticks_per_second); #endif /* MS_WINDOWS */ -#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] @@ -11014,9 +11276,9 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, done: #if !defined(HAVE_LARGEFILE_SUPPORT) - return Py_BuildValue("l", sbytes); + return PyLong_FromLong(sbytes); #else - return Py_BuildValue("L", sbytes); + return PyLong_FromLongLong(sbytes); #endif #else @@ -11029,7 +11291,7 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) return (!async_err) ? posix_error() : NULL; - return Py_BuildValue("n", ret); + return PyLong_FromSsize_t(ret); } #endif off_t offset; @@ -11050,7 +11312,7 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, return (!async_err) ? posix_error() : NULL; if (offset >= st.st_size) { - return Py_BuildValue("i", 0); + return PyLong_FromLong(0); } // On illumos specifically sendfile() may perform a partial write but @@ -11076,7 +11338,7 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) return (!async_err) ? posix_error() : NULL; - return Py_BuildValue("n", ret); + return PyLong_FromSsize_t(ret); #endif } #endif /* HAVE_SENDFILE */ @@ -11897,7 +12159,10 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) #endif -#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) +/* GH-111804: Due to posix_fallocate() not having consistent semantics across + OSs, support was dropped in WASI preview2. */ +#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) && \ + !defined(__wasi__) /*[clinic input] os.posix_fallocate @@ -11935,7 +12200,7 @@ os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, errno = result; return posix_error(); } -#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */ +#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG && !defined(__wasi__) */ #if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) @@ -12009,7 +12274,6 @@ win32_putenv(PyObject *name, PyObject *value) } Py_ssize_t size; - /* PyUnicode_AsWideCharString() rejects embedded null characters */ wchar_t *env = PyUnicode_AsWideCharString(unicode, &size); Py_DECREF(unicode); @@ -12023,6 +12287,12 @@ win32_putenv(PyObject *name, PyObject *value) PyMem_Free(env); return NULL; } + if (wcslen(env) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + PyMem_Free(env); + return NULL; + } /* _wputenv() and SetEnvironmentVariableW() update the environment in the Process Environment Block (PEB). _wputenv() also updates CRT 'environ' @@ -14330,48 +14600,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); } @@ -14534,6 +14813,7 @@ typedef struct { #ifdef MS_WINDOWS struct _Py_stat_struct win32_lstat; uint64_t win32_file_index; + uint64_t win32_file_index_high; int got_file_index; #else /* POSIX */ #ifdef HAVE_DIRENT_D_TYPE @@ -14863,11 +15143,10 @@ os_DirEntry_inode_impl(DirEntry *self) } self->win32_file_index = stat.st_ino; + self->win32_file_index_high = stat.st_ino_high; self->got_file_index = 1; } - static_assert(sizeof(unsigned long long) >= sizeof(self->win32_file_index), - "DirEntry.win32_file_index is larger than unsigned long long"); - return PyLong_FromUnsignedLongLong(self->win32_file_index); + return _pystat_l128_from_l64_l64(self->win32_file_index, self->win32_file_index_high); #else /* POSIX */ static_assert(sizeof(unsigned long long) >= sizeof(self->d_ino), "DirEntry.d_ino is larger than unsigned long long"); @@ -15794,6 +16073,26 @@ os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj) } #endif +#if defined(MS_WINDOWS) +/*[clinic input] +os._supports_virtual_terminal + +Checks if virtual terminal is supported in windows +[clinic start generated code]*/ + +static PyObject * +os__supports_virtual_terminal_impl(PyObject *module) +/*[clinic end generated code: output=bd0556a6d9d99fe6 input=0752c98e5d321542]*/ +{ + DWORD mode = 0; + HANDLE handle = GetStdHandle(STD_ERROR_HANDLE); + if (!GetConsoleMode(handle, &mode)) { + Py_RETURN_FALSE; + } + return PyBool_FromLong(mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING); +} +#endif + static PyMethodDef posix_methods[] = { @@ -15951,6 +16250,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 @@ -15986,12 +16286,19 @@ 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 OS__PATH_ISFILE_METHODDEF OS__PATH_ISLINK_METHODDEF OS__PATH_EXISTS_METHODDEF + + OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -16301,6 +16608,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; @@ -16699,6 +17019,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 @@ -16971,6 +17295,15 @@ posixmodule_exec(PyObject *m) Py_DECREF(unicode); } +#ifndef MS_WINDOWS + if (_Py_GetTicksPerSecond(&state->ticks_per_second) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "cannot read ticks_per_second"); + return -1; + } + assert(state->ticks_per_second >= 1); +#endif + return PyModule_Add(m, "_have_functions", list); } diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index bd24523eac830b..9d95309dbb7aa6 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -240,19 +240,12 @@ string_intern(xmlparseobject *self, const char* str) return result; if (!self->intern) return result; - value = PyDict_GetItemWithError(self->intern, result); - if (!value) { - if (!PyErr_Occurred() && - PyDict_SetItem(self->intern, result, result) == 0) - { - return result; - } - else { - Py_DECREF(result); - return NULL; - } + if (PyDict_GetItemRef(self->intern, result, &value) == 0 && + PyDict_SetItem(self->intern, result, result) == 0) + { + return result; } - Py_INCREF(value); + assert((value != NULL) == !PyErr_Occurred()); Py_DECREF(result); return value; } @@ -895,7 +888,7 @@ static PyObject * pyexpat_xmlparser_GetBase_impl(xmlparseobject *self) /*[clinic end generated code: output=2886cb21f9a8739a input=918d71c38009620e]*/ { - return Py_BuildValue("z", XML_GetBase(self->itself)); + return conv_string_to_unicode(XML_GetBase(self->itself)); } /*[clinic input] @@ -1585,7 +1578,7 @@ static PyObject * pyexpat_ErrorString_impl(PyObject *module, long code) /*[clinic end generated code: output=2feae50d166f2174 input=cc67de010d9e62b3]*/ { - return Py_BuildValue("z", XML_ErrorString((int)code)); + return conv_string_to_unicode(XML_ErrorString((int)code)); } /* List of methods defined in the module */ diff --git a/Modules/readline.c b/Modules/readline.c index 4b473023c6e524..e29051c37f8827 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -147,8 +147,19 @@ readline_free(void *m) static PyModuleDef readlinemodule; -#define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule))) - +static inline readlinestate* +get_hook_module_state(void) +{ + PyObject *mod = PyState_FindModule(&readlinemodule); + if (mod == NULL){ + PyErr_Clear(); + return NULL; + } + Py_INCREF(mod); + readlinestate *state = get_readline_state(mod); + Py_DECREF(mod); + return state; +} /* Convert to/from multibyte C strings */ @@ -438,15 +449,16 @@ readline_set_completion_display_matches_hook_impl(PyObject *module, PyObject *function) /*[clinic end generated code: output=516e5cb8db75a328 input=4f0bfd5ab0179a26]*/ { + readlinestate *state = get_readline_state(module); PyObject *result = set_hook("completion_display_matches_hook", - &readlinestate_global->completion_display_matches_hook, + &state->completion_display_matches_hook, function); #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK /* We cannot set this hook globally, since it replaces the default completion display. */ rl_completion_display_matches_hook = - readlinestate_global->completion_display_matches_hook ? -#if defined(_RL_FUNCTION_TYPEDEF) + state->completion_display_matches_hook ? +#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; @@ -472,7 +484,8 @@ static PyObject * readline_set_startup_hook_impl(PyObject *module, PyObject *function) /*[clinic end generated code: output=02cd0e0c4fa082ad input=7783b4334b26d16d]*/ { - return set_hook("startup_hook", &readlinestate_global->startup_hook, + readlinestate *state = get_readline_state(module); + return set_hook("startup_hook", &state->startup_hook, function); } @@ -497,7 +510,8 @@ static PyObject * readline_set_pre_input_hook_impl(PyObject *module, PyObject *function) /*[clinic end generated code: output=fe1a96505096f464 input=4f3eaeaf7ce1fdbe]*/ { - return set_hook("pre_input_hook", &readlinestate_global->pre_input_hook, + readlinestate *state = get_readline_state(module); + return set_hook("pre_input_hook", &state->pre_input_hook, function); } #endif @@ -530,7 +544,8 @@ static PyObject * readline_get_begidx_impl(PyObject *module) /*[clinic end generated code: output=362616ee8ed1b2b1 input=e083b81c8eb4bac3]*/ { - return Py_NewRef(readlinestate_global->begidx); + readlinestate *state = get_readline_state(module); + return Py_NewRef(state->begidx); } /* Get the ending index for the scope of the tab-completion */ @@ -545,7 +560,8 @@ static PyObject * readline_get_endidx_impl(PyObject *module) /*[clinic end generated code: output=7f763350b12d7517 input=d4c7e34a625fd770]*/ { - return Py_NewRef(readlinestate_global->endidx); + readlinestate *state = get_readline_state(module); + return Py_NewRef(state->endidx); } /* Set the tab-completion word-delimiters that readline uses */ @@ -576,6 +592,13 @@ readline_set_completer_delims(PyObject *module, PyObject *string) if (break_chars) { free(completer_word_break_characters); completer_word_break_characters = break_chars; +#ifdef WITH_EDITLINE + rl_basic_word_break_characters = break_chars; +#else + if (using_libedit_emulation) { + rl_basic_word_break_characters = break_chars; + } +#endif rl_completer_word_break_characters = break_chars; Py_RETURN_NONE; } @@ -772,7 +795,8 @@ static PyObject * readline_set_completer_impl(PyObject *module, PyObject *function) /*[clinic end generated code: output=171a2a60f81d3204 input=51e81e13118eb877]*/ { - return set_hook("completer", &readlinestate_global->completer, function); + readlinestate *state = get_readline_state(module); + return set_hook("completer", &state->completer, function); } /*[clinic input] @@ -785,10 +809,11 @@ static PyObject * readline_get_completer_impl(PyObject *module) /*[clinic end generated code: output=6e6bbd8226d14475 input=6457522e56d70d13]*/ { - if (readlinestate_global->completer == NULL) { + readlinestate *state = get_readline_state(module); + if (state->completer == NULL) { Py_RETURN_NONE; } - return Py_NewRef(readlinestate_global->completer); + return Py_NewRef(state->completer); } /* Private function to get current length of history. XXX It may be @@ -1018,15 +1043,18 @@ 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) +on_startup_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) #endif { int r; PyGILState_STATE gilstate = PyGILState_Ensure(); - r = on_hook(readlinestate_global->startup_hook); + readlinestate *state = get_hook_module_state(); + if (state == NULL) { + PyGILState_Release(gilstate); + return -1; + } + r = on_hook(state->startup_hook); PyGILState_Release(gilstate); return r; } @@ -1035,15 +1063,18 @@ 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) +on_pre_input_hook(const char *Py_UNUSED(text), int Py_UNUSED(state)) #endif { int r; PyGILState_STATE gilstate = PyGILState_Ensure(); - r = on_hook(readlinestate_global->pre_input_hook); + readlinestate *state = get_hook_module_state(); + if (state == NULL) { + PyGILState_Release(gilstate); + return -1; + } + r = on_hook(state->pre_input_hook); PyGILState_Release(gilstate); return r; } @@ -1060,6 +1091,11 @@ on_completion_display_matches_hook(char **matches, int i; PyObject *sub, *m=NULL, *s=NULL, *r=NULL; PyGILState_STATE gilstate = PyGILState_Ensure(); + readlinestate *state = get_hook_module_state(); + if (state == NULL) { + PyGILState_Release(gilstate); + return; + } m = PyList_New(num_matches); if (m == NULL) goto error; @@ -1070,7 +1106,7 @@ on_completion_display_matches_hook(char **matches, PyList_SET_ITEM(m, i, s); } sub = decode(matches[0]); - r = PyObject_CallFunction(readlinestate_global->completion_display_matches_hook, + r = PyObject_CallFunction(state->completion_display_matches_hook, "NNi", sub, m, max_length); m=NULL; @@ -1118,12 +1154,17 @@ static char * on_completion(const char *text, int state) { char *result = NULL; - if (readlinestate_global->completer != NULL) { + PyGILState_STATE gilstate = PyGILState_Ensure(); + readlinestate *module_state = get_hook_module_state(); + if (module_state == NULL) { + PyGILState_Release(gilstate); + return NULL; + } + if (module_state->completer != NULL) { PyObject *r = NULL, *t; - PyGILState_STATE gilstate = PyGILState_Ensure(); rl_attempted_completion_over = 1; t = decode(text); - r = PyObject_CallFunction(readlinestate_global->completer, "Ni", t, state); + r = PyObject_CallFunction(module_state->completer, "Ni", t, state); if (r == NULL) goto error; if (r == Py_None) { @@ -1145,6 +1186,7 @@ on_completion(const char *text, int state) PyGILState_Release(gilstate); return result; } + PyGILState_Release(gilstate); return result; } @@ -1160,6 +1202,7 @@ flex_complete(const char *text, int start, int end) size_t start_size, end_size; wchar_t *s; PyGILState_STATE gilstate = PyGILState_Ensure(); + readlinestate *state = get_hook_module_state(); #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER rl_completion_append_character ='\0'; #endif @@ -1187,10 +1230,12 @@ flex_complete(const char *text, int start, int end) end = start + (int)end_size; done: - Py_XDECREF(readlinestate_global->begidx); - Py_XDECREF(readlinestate_global->endidx); - readlinestate_global->begidx = PyLong_FromLong((long) start); - readlinestate_global->endidx = PyLong_FromLong((long) end); + if (state) { + Py_XDECREF(state->begidx); + Py_XDECREF(state->endidx); + state->begidx = PyLong_FromLong((long) start); + state->endidx = PyLong_FromLong((long) end); + } result = completion_matches((char *)text, *on_completion); PyGILState_Release(gilstate); return result; @@ -1267,6 +1312,15 @@ setup_readline(readlinestate *mod_state) completer_word_break_characters = strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?"); /* All nonalphanums except '.' */ +#ifdef WITH_EDITLINE + // libedit uses rl_basic_word_break_characters instead of + // rl_completer_word_break_characters as complete delimiter + rl_basic_word_break_characters = completer_word_break_characters; +#else + if (using_libedit_emulation) { + rl_basic_word_break_characters = completer_word_break_characters; + } +#endif rl_completer_word_break_characters = completer_word_break_characters; mod_state->begidx = PyLong_FromLong(0L); @@ -1480,6 +1534,7 @@ static struct PyModuleDef readlinemodule = { PyMODINIT_FUNC PyInit_readline(void) { + const char *backend = "readline"; PyObject *m; readlinestate *mod_state; @@ -1487,8 +1542,10 @@ PyInit_readline(void) using_libedit_emulation = 1; } - if (using_libedit_emulation) + if (using_libedit_emulation) { readlinemodule.m_doc = doc_module_le; + backend = "editline"; + } m = PyModule_Create(&readlinemodule); @@ -1510,13 +1567,22 @@ PyInit_readline(void) goto error; } + if (PyModule_AddStringConstant(m, "backend", backend) < 0) { + goto error; + } + mod_state = (readlinestate *) PyModule_GetState(m); + if (mod_state == NULL){ + goto error; + } PyOS_ReadlineFunctionPointer = call_readline; if (setup_readline(mod_state) < 0) { PyErr_NoMemory(); goto error; } - + if (PyErr_Occurred()){ + goto error; + } return m; error: diff --git a/Modules/resource.c b/Modules/resource.c index d65509ec3436a2..19020b8cc1b6db 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -1,3 +1,10 @@ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.13 for PySys_Audit() +#define Py_LIMITED_API 0x030d0000 +#endif + #include "Python.h" #include // errno #include @@ -116,24 +123,24 @@ resource_getrusage_impl(PyObject *module, int who) if (!result) return NULL; - PyStructSequence_SET_ITEM(result, 0, + PyStructSequence_SetItem(result, 0, PyFloat_FromDouble(doubletime(ru.ru_utime))); - PyStructSequence_SET_ITEM(result, 1, + PyStructSequence_SetItem(result, 1, PyFloat_FromDouble(doubletime(ru.ru_stime))); - PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss)); - PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss)); - PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss)); - PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss)); - PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt)); - PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt)); - PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap)); - PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock)); - PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock)); - PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd)); - PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv)); - PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals)); - PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw)); - PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw)); + PyStructSequence_SetItem(result, 2, PyLong_FromLong(ru.ru_maxrss)); + PyStructSequence_SetItem(result, 3, PyLong_FromLong(ru.ru_ixrss)); + PyStructSequence_SetItem(result, 4, PyLong_FromLong(ru.ru_idrss)); + PyStructSequence_SetItem(result, 5, PyLong_FromLong(ru.ru_isrss)); + PyStructSequence_SetItem(result, 6, PyLong_FromLong(ru.ru_minflt)); + PyStructSequence_SetItem(result, 7, PyLong_FromLong(ru.ru_majflt)); + PyStructSequence_SetItem(result, 8, PyLong_FromLong(ru.ru_nswap)); + PyStructSequence_SetItem(result, 9, PyLong_FromLong(ru.ru_inblock)); + PyStructSequence_SetItem(result, 10, PyLong_FromLong(ru.ru_oublock)); + PyStructSequence_SetItem(result, 11, PyLong_FromLong(ru.ru_msgsnd)); + PyStructSequence_SetItem(result, 12, PyLong_FromLong(ru.ru_msgrcv)); + PyStructSequence_SetItem(result, 13, PyLong_FromLong(ru.ru_nsignals)); + PyStructSequence_SetItem(result, 14, PyLong_FromLong(ru.ru_nvcsw)); + PyStructSequence_SetItem(result, 15, PyLong_FromLong(ru.ru_nivcsw)); if (PyErr_Occurred()) { Py_DECREF(result); @@ -153,13 +160,13 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out) /* Here limits is a borrowed reference */ return -1; - if (PyTuple_GET_SIZE(limits) != 2) { + if (PyTuple_Size(limits) != 2) { PyErr_SetString(PyExc_ValueError, "expected a tuple of 2 integers"); goto error; } - curobj = PyTuple_GET_ITEM(limits, 0); - maxobj = PyTuple_GET_ITEM(limits, 1); + curobj = PyTuple_GetItem(limits, 0); // borrowed + maxobj = PyTuple_GetItem(limits, 1); // borrowed #if !defined(HAVE_LARGEFILE_SUPPORT) rl_out->rlim_cur = PyLong_AsLong(curobj); if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index c56e682b21e2a1..1dbde3e9e6ca5d 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -14,8 +14,10 @@ #include "Python.h" #include "pycore_fileutils.h" // _Py_set_inheritable() +#include "pycore_import.h" // _PyImport_GetModuleAttrString() #include "pycore_time.h" // _PyTime_t +#include #include // offsetof() #ifndef MS_WINDOWS # include // close() @@ -75,13 +77,26 @@ extern void bzero(void *, int); # define POLLPRI 0 #endif +#ifdef HAVE_KQUEUE +// Linked list to track kqueue objects with an open fd, so +// that we can invalidate them at fork; +typedef struct _kqueue_list_item { + struct kqueue_queue_Object *obj; + struct _kqueue_list_item *next; +} _kqueue_list_item, *_kqueue_list; +#endif + typedef struct { PyObject *close; PyTypeObject *poll_Type; PyTypeObject *devpoll_Type; PyTypeObject *pyEpoll_Type; +#ifdef HAVE_KQUEUE PyTypeObject *kqueue_event_Type; PyTypeObject *kqueue_queue_Type; + _kqueue_list kqueue_open_list; + bool kqueue_tracking_initialized; +#endif } _selectstate; static struct PyModuleDef selectmodule; @@ -1754,7 +1769,7 @@ typedef struct { #define kqueue_event_Check(op, state) (PyObject_TypeCheck((op), state->kqueue_event_Type)) -typedef struct { +typedef struct kqueue_queue_Object { PyObject_HEAD SOCKET kqfd; /* kqueue control fd */ } kqueue_queue_Object; @@ -1940,6 +1955,107 @@ kqueue_queue_err_closed(void) return NULL; } +static PyObject* +kqueue_tracking_after_fork(PyObject *module) { + _selectstate *state = get_select_state(module); + _kqueue_list_item *item = state->kqueue_open_list; + state->kqueue_open_list = NULL; + while (item) { + // Safety: we hold the GIL, and references are removed from this list + // before the object is deallocated. + kqueue_queue_Object *obj = item->obj; + assert(obj->kqfd != -1); + obj->kqfd = -1; + _kqueue_list_item *next = item->next; + PyMem_Free(item); + item = next; + } + Py_RETURN_NONE; +} + +static PyMethodDef kqueue_tracking_after_fork_def = { + "kqueue_tracking_after_fork", (PyCFunction)kqueue_tracking_after_fork, + METH_NOARGS, "Invalidate open select.kqueue objects after fork." +}; + +static void +kqueue_tracking_init(PyObject *module) { + _selectstate *state = get_select_state(module); + assert(state->kqueue_open_list == NULL); + // Register a callback to invalidate kqueues with open fds after fork. + PyObject *register_at_fork = NULL, *cb = NULL, *args = NULL, + *kwargs = NULL, *result = NULL; + register_at_fork = _PyImport_GetModuleAttrString("posix", + "register_at_fork"); + if (register_at_fork == NULL) { + goto finally; + } + cb = PyCFunction_New(&kqueue_tracking_after_fork_def, module); + if (cb == NULL) { + goto finally; + } + args = PyTuple_New(0); + assert(args != NULL); + kwargs = Py_BuildValue("{sO}", "after_in_child", cb); + if (kwargs == NULL) { + goto finally; + } + result = PyObject_Call(register_at_fork, args, kwargs); + +finally: + if (PyErr_Occurred()) { + // There are a few reasons registration can fail, especially if someone + // touched posix.register_at_fork. But everything else still works so + // instead of raising we issue a warning and move along. + PyObject *exc = PyErr_GetRaisedException(); + PyObject *exctype = (PyObject*)Py_TYPE(exc); + PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "An exception of type %S was raised while registering an " + "after-fork handler for select.kqueue objects: %S", exctype, exc); + Py_DECREF(exc); + } + Py_XDECREF(register_at_fork); + Py_XDECREF(cb); + Py_XDECREF(args); + Py_XDECREF(kwargs); + Py_XDECREF(result); + state->kqueue_tracking_initialized = true; +} + +static int +kqueue_tracking_add(_selectstate *state, kqueue_queue_Object *self) { + if (!state->kqueue_tracking_initialized) { + kqueue_tracking_init(PyType_GetModule(Py_TYPE(self))); + } + assert(self->kqfd >= 0); + _kqueue_list_item *item = PyMem_New(_kqueue_list_item, 1); + if (item == NULL) { + PyErr_NoMemory(); + return -1; + } + item->obj = self; + item->next = state->kqueue_open_list; + state->kqueue_open_list = item; + return 0; +} + +static void +kqueue_tracking_remove(_selectstate *state, kqueue_queue_Object *self) { + _kqueue_list *listptr = &state->kqueue_open_list; + while (*listptr != NULL) { + _kqueue_list_item *item = *listptr; + if (item->obj == self) { + *listptr = item->next; + PyMem_Free(item); + return; + } + listptr = &item->next; + } + // The item should be in the list when we remove it, + // and it should only be removed once at close time. + assert(0); +} + static int kqueue_queue_internal_close(kqueue_queue_Object *self) { @@ -1947,6 +2063,8 @@ kqueue_queue_internal_close(kqueue_queue_Object *self) if (self->kqfd >= 0) { int kqfd = self->kqfd; self->kqfd = -1; + _selectstate *state = _selectstate_by_type(Py_TYPE(self)); + kqueue_tracking_remove(state, self); Py_BEGIN_ALLOW_THREADS if (close(kqfd) < 0) save_errno = errno; @@ -1987,6 +2105,13 @@ newKqueue_Object(PyTypeObject *type, SOCKET fd) return NULL; } } + + _selectstate *state = _selectstate_by_type(type); + if (kqueue_tracking_add(state, self) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *)self; } @@ -2017,13 +2142,11 @@ select_kqueue_impl(PyTypeObject *type) } static void -kqueue_queue_dealloc(kqueue_queue_Object *self) +kqueue_queue_finalize(kqueue_queue_Object *self) { - PyTypeObject* type = Py_TYPE(self); + PyObject* error = PyErr_GetRaisedException(); kqueue_queue_internal_close(self); - freefunc kqueue_free = PyType_GetSlot(type, Py_tp_free); - kqueue_free((PyObject *)self); - Py_DECREF((PyObject *)type); + PyErr_SetRaisedException(error); } /*[clinic input] @@ -2357,11 +2480,11 @@ static PyMethodDef kqueue_queue_methods[] = { }; static PyType_Slot kqueue_queue_Type_slots[] = { - {Py_tp_dealloc, kqueue_queue_dealloc}, {Py_tp_doc, (void*)select_kqueue__doc__}, {Py_tp_getset, kqueue_queue_getsetlist}, {Py_tp_methods, kqueue_queue_methods}, {Py_tp_new, select_kqueue}, + {Py_tp_finalize, kqueue_queue_finalize}, {0, 0}, }; @@ -2406,8 +2529,11 @@ _select_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->poll_Type); Py_VISIT(state->devpoll_Type); Py_VISIT(state->pyEpoll_Type); +#ifdef HAVE_KQUEUE Py_VISIT(state->kqueue_event_Type); Py_VISIT(state->kqueue_queue_Type); + // state->kqueue_open_list only holds borrowed refs +#endif return 0; } @@ -2420,8 +2546,10 @@ _select_clear(PyObject *module) Py_CLEAR(state->poll_Type); Py_CLEAR(state->devpoll_Type); Py_CLEAR(state->pyEpoll_Type); +#ifdef HAVE_KQUEUE Py_CLEAR(state->kqueue_event_Type); Py_CLEAR(state->kqueue_queue_Type); +#endif return 0; } @@ -2444,12 +2572,18 @@ _select_exec(PyObject *m) return -1; } +#define ADD_INT(VAL) do { \ + if (PyModule_AddIntConstant((m), #VAL, (VAL)) < 0) { \ + return -1; \ + } \ +} while (0) + #ifdef PIPE_BUF #ifdef HAVE_BROKEN_PIPE_BUF #undef PIPE_BUF #define PIPE_BUF 512 #endif - PyModule_AddIntMacro(m, PIPE_BUF); + ADD_INT(PIPE_BUF); #endif #if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) @@ -2468,31 +2602,31 @@ _select_exec(PyObject *m) return -1; } - PyModule_AddIntMacro(m, POLLIN); - PyModule_AddIntMacro(m, POLLPRI); - PyModule_AddIntMacro(m, POLLOUT); - PyModule_AddIntMacro(m, POLLERR); - PyModule_AddIntMacro(m, POLLHUP); - PyModule_AddIntMacro(m, POLLNVAL); + ADD_INT(POLLIN); + ADD_INT(POLLPRI); + ADD_INT(POLLOUT); + ADD_INT(POLLERR); + ADD_INT(POLLHUP); + ADD_INT(POLLNVAL); #ifdef POLLRDNORM - PyModule_AddIntMacro(m, POLLRDNORM); + ADD_INT(POLLRDNORM); #endif #ifdef POLLRDBAND - PyModule_AddIntMacro(m, POLLRDBAND); + ADD_INT(POLLRDBAND); #endif #ifdef POLLWRNORM - PyModule_AddIntMacro(m, POLLWRNORM); + ADD_INT(POLLWRNORM); #endif #ifdef POLLWRBAND - PyModule_AddIntMacro(m, POLLWRBAND); + ADD_INT(POLLWRBAND); #endif #ifdef POLLMSG - PyModule_AddIntMacro(m, POLLMSG); + ADD_INT(POLLMSG); #endif #ifdef POLLRDHUP /* Kernel 2.6.17+ */ - PyModule_AddIntMacro(m, POLLRDHUP); + ADD_INT(POLLRDHUP); #endif } #endif /* HAVE_POLL */ @@ -2515,46 +2649,57 @@ _select_exec(PyObject *m) return -1; } - PyModule_AddIntMacro(m, EPOLLIN); - PyModule_AddIntMacro(m, EPOLLOUT); - PyModule_AddIntMacro(m, EPOLLPRI); - PyModule_AddIntMacro(m, EPOLLERR); - PyModule_AddIntMacro(m, EPOLLHUP); + ADD_INT(EPOLLIN); + ADD_INT(EPOLLOUT); + ADD_INT(EPOLLPRI); + ADD_INT(EPOLLERR); + ADD_INT(EPOLLHUP); #ifdef EPOLLRDHUP /* Kernel 2.6.17 */ - PyModule_AddIntMacro(m, EPOLLRDHUP); + ADD_INT(EPOLLRDHUP); #endif - PyModule_AddIntMacro(m, EPOLLET); + ADD_INT(EPOLLET); #ifdef EPOLLONESHOT /* Kernel 2.6.2+ */ - PyModule_AddIntMacro(m, EPOLLONESHOT); + ADD_INT(EPOLLONESHOT); #endif #ifdef EPOLLEXCLUSIVE - PyModule_AddIntMacro(m, EPOLLEXCLUSIVE); + ADD_INT(EPOLLEXCLUSIVE); #endif #ifdef EPOLLRDNORM - PyModule_AddIntMacro(m, EPOLLRDNORM); + ADD_INT(EPOLLRDNORM); #endif #ifdef EPOLLRDBAND - PyModule_AddIntMacro(m, EPOLLRDBAND); + ADD_INT(EPOLLRDBAND); #endif #ifdef EPOLLWRNORM - PyModule_AddIntMacro(m, EPOLLWRNORM); + ADD_INT(EPOLLWRNORM); #endif #ifdef EPOLLWRBAND - PyModule_AddIntMacro(m, EPOLLWRBAND); + ADD_INT(EPOLLWRBAND); #endif #ifdef EPOLLMSG - PyModule_AddIntMacro(m, EPOLLMSG); + ADD_INT(EPOLLMSG); #endif #ifdef EPOLL_CLOEXEC - PyModule_AddIntMacro(m, EPOLL_CLOEXEC); + ADD_INT(EPOLL_CLOEXEC); #endif #endif /* HAVE_EPOLL */ +#undef ADD_INT + +#define ADD_INT_CONST(NAME, VAL) \ + do { \ + if (PyModule_AddIntConstant(m, NAME, VAL) < 0) { \ + return -1; \ + } \ + } while (0) + #ifdef HAVE_KQUEUE + state->kqueue_open_list = NULL; + state->kqueue_event_Type = (PyTypeObject *)PyType_FromModuleAndSpec( m, &kqueue_event_Type_spec, NULL); if (state->kqueue_event_Type == NULL) { @@ -2574,80 +2719,83 @@ _select_exec(PyObject *m) } /* event filters */ - PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ); - PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE); + ADD_INT_CONST("KQ_FILTER_READ", EVFILT_READ); + ADD_INT_CONST("KQ_FILTER_WRITE", EVFILT_WRITE); #ifdef EVFILT_AIO - PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO); + ADD_INT_CONST("KQ_FILTER_AIO", EVFILT_AIO); #endif #ifdef EVFILT_VNODE - PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE); + ADD_INT_CONST("KQ_FILTER_VNODE", EVFILT_VNODE); #endif #ifdef EVFILT_PROC - PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC); + ADD_INT_CONST("KQ_FILTER_PROC", EVFILT_PROC); #endif #ifdef EVFILT_NETDEV - PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV); + ADD_INT_CONST("KQ_FILTER_NETDEV", EVFILT_NETDEV); #endif #ifdef EVFILT_SIGNAL - PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL); + ADD_INT_CONST("KQ_FILTER_SIGNAL", EVFILT_SIGNAL); #endif - PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER); + ADD_INT_CONST("KQ_FILTER_TIMER", EVFILT_TIMER); /* event flags */ - PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD); - PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE); - PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE); - PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE); - PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT); - PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR); + ADD_INT_CONST("KQ_EV_ADD", EV_ADD); + ADD_INT_CONST("KQ_EV_DELETE", EV_DELETE); + ADD_INT_CONST("KQ_EV_ENABLE", EV_ENABLE); + ADD_INT_CONST("KQ_EV_DISABLE", EV_DISABLE); + ADD_INT_CONST("KQ_EV_ONESHOT", EV_ONESHOT); + ADD_INT_CONST("KQ_EV_CLEAR", EV_CLEAR); #ifdef EV_SYSFLAGS - PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS); + ADD_INT_CONST("KQ_EV_SYSFLAGS", EV_SYSFLAGS); #endif #ifdef EV_FLAG1 - PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1); + ADD_INT_CONST("KQ_EV_FLAG1", EV_FLAG1); #endif - PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF); - PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR); + ADD_INT_CONST("KQ_EV_EOF", EV_EOF); + ADD_INT_CONST("KQ_EV_ERROR", EV_ERROR); /* READ WRITE filter flag */ #ifdef NOTE_LOWAT - PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT); + ADD_INT_CONST("KQ_NOTE_LOWAT", NOTE_LOWAT); #endif /* VNODE filter flags */ #ifdef EVFILT_VNODE - PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE); - PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE); - PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND); - PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB); - PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK); - PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME); - PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE); + ADD_INT_CONST("KQ_NOTE_DELETE", NOTE_DELETE); + ADD_INT_CONST("KQ_NOTE_WRITE", NOTE_WRITE); + ADD_INT_CONST("KQ_NOTE_EXTEND", NOTE_EXTEND); + ADD_INT_CONST("KQ_NOTE_ATTRIB", NOTE_ATTRIB); + ADD_INT_CONST("KQ_NOTE_LINK", NOTE_LINK); + ADD_INT_CONST("KQ_NOTE_RENAME", NOTE_RENAME); + ADD_INT_CONST("KQ_NOTE_REVOKE", NOTE_REVOKE); #endif /* PROC filter flags */ #ifdef EVFILT_PROC - PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT); - PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK); - PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC); - PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK); - PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK); - - PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK); - PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD); - PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR); + ADD_INT_CONST("KQ_NOTE_EXIT", NOTE_EXIT); + ADD_INT_CONST("KQ_NOTE_FORK", NOTE_FORK); + ADD_INT_CONST("KQ_NOTE_EXEC", NOTE_EXEC); + ADD_INT_CONST("KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK); + ADD_INT_CONST("KQ_NOTE_PDATAMASK", NOTE_PDATAMASK); + + ADD_INT_CONST("KQ_NOTE_TRACK", NOTE_TRACK); + ADD_INT_CONST("KQ_NOTE_CHILD", NOTE_CHILD); + ADD_INT_CONST("KQ_NOTE_TRACKERR", NOTE_TRACKERR); #endif /* NETDEV filter flags */ #ifdef EVFILT_NETDEV - PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP); - PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN); - PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV); + ADD_INT_CONST("KQ_NOTE_LINKUP", NOTE_LINKUP); + ADD_INT_CONST("KQ_NOTE_LINKDOWN", NOTE_LINKDOWN); + ADD_INT_CONST("KQ_NOTE_LINKINV", NOTE_LINKINV); #endif #endif /* HAVE_KQUEUE */ + +#undef ADD_INT_CONST + return 0; } diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 3fd53123229ac4..eda6b5608d52f7 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -49,7 +49,8 @@ typedef long long SHA1_INT64; /* 64-bit integer */ typedef struct { PyObject_HEAD // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. + bool use_mutex; + PyMutex mutex; PyThread_type_lock lock; Hacl_Streaming_SHA1_state *hash_state; } SHA1object; @@ -76,7 +77,8 @@ newSHA1object(SHA1State *st) if (sha == NULL) { return NULL; } - sha->lock = NULL; + HASHLIB_INIT_MUTEX(sha); + PyObject_GC_Track(sha); return sha; } @@ -94,9 +96,6 @@ static void SHA1_dealloc(SHA1object *ptr) { Hacl_Streaming_SHA1_legacy_free(ptr->hash_state); - if (ptr->lock != NULL) { - PyThread_free_lock(ptr->lock); - } PyTypeObject *tp = Py_TYPE(ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -192,14 +191,14 @@ SHA1Type_update(SHA1object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); update(self->hash_state, buf.buf, buf.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { update(self->hash_state, buf.buf, buf.len); diff --git a/Modules/sha2module.c b/Modules/sha2module.c index 6ad1ff2e05bfd8..968493ba51b50d 100644 --- a/Modules/sha2module.c +++ b/Modules/sha2module.c @@ -53,8 +53,8 @@ typedef struct { PyObject_HEAD int digestsize; // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; Hacl_Streaming_SHA2_state_sha2_256 *state; } SHA256object; @@ -62,8 +62,8 @@ typedef struct { PyObject_HEAD int digestsize; // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; Hacl_Streaming_SHA2_state_sha2_512 *state; } SHA512object; @@ -106,7 +106,8 @@ newSHA224object(sha2_state *state) if (!sha) { return NULL; } - sha->lock = NULL; + HASHLIB_INIT_MUTEX(sha); + PyObject_GC_Track(sha); return sha; } @@ -119,7 +120,8 @@ newSHA256object(sha2_state *state) if (!sha) { return NULL; } - sha->lock = NULL; + HASHLIB_INIT_MUTEX(sha); + PyObject_GC_Track(sha); return sha; } @@ -132,7 +134,8 @@ newSHA384object(sha2_state *state) if (!sha) { return NULL; } - sha->lock = NULL; + HASHLIB_INIT_MUTEX(sha); + PyObject_GC_Track(sha); return sha; } @@ -145,7 +148,8 @@ newSHA512object(sha2_state *state) if (!sha) { return NULL; } - sha->lock = NULL; + HASHLIB_INIT_MUTEX(sha); + PyObject_GC_Track(sha); return sha; } @@ -163,9 +167,6 @@ static void SHA256_dealloc(SHA256object *ptr) { Hacl_Streaming_SHA2_free_256(ptr->state); - if (ptr->lock != NULL) { - PyThread_free_lock(ptr->lock); - } PyTypeObject *tp = Py_TYPE(ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -176,9 +177,6 @@ static void SHA512_dealloc(SHA512object *ptr) { Hacl_Streaming_SHA2_free_512(ptr->state); - if (ptr->lock != NULL) { - PyThread_free_lock(ptr->lock); - } PyTypeObject *tp = Py_TYPE(ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -376,14 +374,14 @@ SHA256Type_update(SHA256object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); update_256(self->state, buf.buf, buf.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { update_256(self->state, buf.buf, buf.len); @@ -410,14 +408,14 @@ SHA512Type_update(SHA512object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); update_512(self->state, buf.buf, buf.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { update_512(self->state, buf.buf, buf.len); diff --git a/Modules/sha3module.c b/Modules/sha3module.c index 558d2005cff617..d9d2f6c385a68b 100644 --- a/Modules/sha3module.c +++ b/Modules/sha3module.c @@ -61,8 +61,8 @@ class _sha3.shake_256 "SHA3object *" "&SHAKE256type" typedef struct { PyObject_HEAD // Prevents undefined behavior via multiple threads entering the C API. - // The lock will be NULL before threaded access has been enabled. - PyThread_type_lock lock; + bool use_mutex; + PyMutex mutex; Hacl_Streaming_Keccak_state *hash_state; } SHA3object; @@ -76,7 +76,8 @@ newSHA3object(PyTypeObject *type) if (newobj == NULL) { return NULL; } - newobj->lock = NULL; + HASHLIB_INIT_MUTEX(newobj); + return newobj; } @@ -169,9 +170,6 @@ static void SHA3_dealloc(SHA3object *self) { Hacl_Streaming_Keccak_free(self->hash_state); - if (self->lock != NULL) { - PyThread_free_lock(self->lock); - } PyTypeObject *tp = Py_TYPE(self); PyObject_Free(self); Py_DECREF(tp); @@ -257,19 +255,22 @@ _sha3_sha3_224_update(SHA3object *self, PyObject *data) /*[clinic end generated code: output=d3223352286ed357 input=a887f54dcc4ae227]*/ { Py_buffer buf; + GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); + + if (!self->use_mutex && buf.len >= HASHLIB_GIL_MINSIZE) { + self->use_mutex = true; } - if (self->lock != NULL) { + if (self->use_mutex) { Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + PyMutex_Lock(&self->mutex); sha3_update(self->hash_state, buf.buf, buf.len); - PyThread_release_lock(self->lock); + PyMutex_Unlock(&self->mutex); Py_END_ALLOW_THREADS } else { sha3_update(self->hash_state, buf.buf, buf.len); } + PyBuffer_Release(&buf); Py_RETURN_NONE; } diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 8d6556727b3a5a..394a997b20c06d 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 @@ -22,6 +21,9 @@ # include "socketmodule.h" // SOCKET_T #endif +#ifdef HAVE_UNISTD_H +# include // alarm() +#endif #ifdef MS_WINDOWS # ifdef HAVE_PROCESS_H # include @@ -124,13 +126,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); } @@ -240,8 +244,7 @@ report_wakeup_write_error(void *data) errno = (int) (intptr_t) data; PyObject *exc = PyErr_GetRaisedException(); PyErr_SetFromErrno(PyExc_OSError); - _PyErr_WriteUnraisableMsg("when trying to write to the signal wakeup fd", - NULL); + PyErr_FormatUnraisable("Exception ignored when trying to write to the signal wakeup fd"); PyErr_SetRaisedException(exc); errno = save_errno; return 0; @@ -258,7 +261,7 @@ report_wakeup_send_error(void* data) recognizes the error codes used by both GetLastError() and WSAGetLastError */ PyErr_SetExcFromWindowsErr(PyExc_OSError, send_errno); - _PyErr_WriteUnraisableMsg("when trying to send to the signal wakeup fd", NULL); + PyErr_FormatUnraisable("Exception ignored when trying to send to the signal wakeup fd"); PyErr_SetRaisedException(exc); return 0; } @@ -267,11 +270,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 +318,7 @@ trip_signal(int sig_num) _PyEval_AddPendingCall(interp, report_wakeup_send_error, (void *)(intptr_t) last_error, - 1); + _Py_PENDING_MAINTHREADONLY); } } } @@ -335,7 +338,7 @@ trip_signal(int sig_num) _PyEval_AddPendingCall(interp, report_wakeup_write_error, (void *)(intptr_t)errno, - 1); + _Py_PENDING_MAINTHREADONLY); } } } @@ -656,7 +659,7 @@ signal_strsignal_impl(PyObject *module, int signalnum) Py_RETURN_NONE; #endif - return Py_BuildValue("s", res); + return PyUnicode_FromString(res); } #ifdef HAVE_SIGINTERRUPT @@ -1731,7 +1734,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 +1770,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 +1788,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 +1806,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 +1860,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 +1978,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 +2000,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 +2022,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 90592ffc152fc1..0a0e0e78656f76 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -107,7 +107,6 @@ Local naming conventions: #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 @@ -393,16 +392,10 @@ remove_unusable_flags(PyObject *m) break; } else { - PyObject *flag_name = PyUnicode_FromString(win_runtime_flags[i].flag_name); - if (flag_name == NULL) { + if (PyDict_PopString(dict, win_runtime_flags[i].flag_name, + NULL) < 0) { return -1; } - PyObject *v = _PyDict_Pop(dict, flag_name, Py_None); - Py_DECREF(flag_name); - if (v == NULL) { - return -1; - } - Py_DECREF(v); } } return 0; @@ -5652,8 +5645,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 @@ -6332,14 +6326,18 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET."); #endif /* HAVE_SOCKETPAIR */ +/*[clinic input] +_socket.socket.ntohs + x: int + / + +Convert a 16-bit unsigned integer from network to host byte order. +[clinic start generated code]*/ + static PyObject * -socket_ntohs(PyObject *self, PyObject *args) +_socket_socket_ntohs_impl(PySocketSockObject *self, int x) +/*[clinic end generated code: output=a828a61a9fb205b2 input=9a79cb3a71652147]*/ { - int x; - - if (!PyArg_ParseTuple(args, "i:ntohs", &x)) { - return NULL; - } if (x < 0) { PyErr_SetString(PyExc_OverflowError, "ntohs: can't convert negative Python int to C " @@ -6355,11 +6353,6 @@ socket_ntohs(PyObject *self, PyObject *args) return PyLong_FromUnsignedLong(ntohs((unsigned short)x)); } -PyDoc_STRVAR(ntohs_doc, -"ntohs(integer) -> integer\n\ -\n\ -Convert a 16-bit unsigned integer from network to host byte order."); - static PyObject * socket_ntohl(PyObject *self, PyObject *arg) @@ -6395,14 +6388,18 @@ PyDoc_STRVAR(ntohl_doc, Convert a 32-bit integer from network to host byte order."); +/*[clinic input] +_socket.socket.htons + x: int + / + +Convert a 16-bit unsigned integer from host to network byte order. +[clinic start generated code]*/ + static PyObject * -socket_htons(PyObject *self, PyObject *args) +_socket_socket_htons_impl(PySocketSockObject *self, int x) +/*[clinic end generated code: output=d785ee692312da47 input=053252d8416f4337]*/ { - int x; - - if (!PyArg_ParseTuple(args, "i:htons", &x)) { - return NULL; - } if (x < 0) { PyErr_SetString(PyExc_OverflowError, "htons: can't convert negative Python int to C " @@ -6418,11 +6415,6 @@ socket_htons(PyObject *self, PyObject *args) return PyLong_FromUnsignedLong(htons((unsigned short)x)); } -PyDoc_STRVAR(htons_doc, -"htons(integer) -> integer\n\ -\n\ -Convert a 16-bit unsigned integer from host to network byte order."); - static PyObject * socket_htonl(PyObject *self, PyObject *arg) @@ -6459,14 +6451,17 @@ Convert a 32-bit integer from host to network byte order."); /* socket.inet_aton() and socket.inet_ntoa() functions. */ -PyDoc_STRVAR(inet_aton_doc, -"inet_aton(string) -> bytes giving packed 32-bit IP representation\n\ -\n\ -Convert an IP address in string format (123.45.67.89) to the 32-bit packed\n\ -binary format used in low-level network functions."); +/*[clinic input] +_socket.socket.inet_aton + ip_addr: str + / -static PyObject* -socket_inet_aton(PyObject *self, PyObject *args) +Convert an IP address in string format (123.45.67.89) to the 32-bit packed binary format used in low-level network functions. +[clinic start generated code]*/ + +static PyObject * +_socket_socket_inet_aton_impl(PySocketSockObject *self, const char *ip_addr) +/*[clinic end generated code: output=5bfe11a255423d8c input=a120e20cb52b9488]*/ { #ifdef HAVE_INET_ATON struct in_addr buf; @@ -6479,11 +6474,6 @@ socket_inet_aton(PyObject *self, PyObject *args) /* Have to use inet_addr() instead */ unsigned int packed_addr; #endif - const char *ip_addr; - - if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr)) - return NULL; - #ifdef HAVE_INET_ATON @@ -6532,30 +6522,29 @@ socket_inet_aton(PyObject *self, PyObject *args) } #ifdef HAVE_INET_NTOA -PyDoc_STRVAR(inet_ntoa_doc, -"inet_ntoa(packed_ip) -> ip_address_string\n\ -\n\ -Convert an IP address from 32-bit packed binary format to string format"); +/*[clinic input] +_socket.socket.inet_ntoa + packed_ip: Py_buffer + / -static PyObject* -socket_inet_ntoa(PyObject *self, PyObject *args) +Convert an IP address from 32-bit packed binary format to string format. +[clinic start generated code]*/ + +static PyObject * +_socket_socket_inet_ntoa_impl(PySocketSockObject *self, Py_buffer *packed_ip) +/*[clinic end generated code: output=b671880a3f62461b input=95c2c4a1b2ee957c]*/ { - Py_buffer packed_ip; struct in_addr packed_addr; - if (!PyArg_ParseTuple(args, "y*:inet_ntoa", &packed_ip)) { - return NULL; - } - - if (packed_ip.len != sizeof(packed_addr)) { + if (packed_ip->len != sizeof(packed_addr)) { PyErr_SetString(PyExc_OSError, "packed IP wrong length for inet_ntoa"); - PyBuffer_Release(&packed_ip); + PyBuffer_Release(packed_ip); return NULL; } - memcpy(&packed_addr, packed_ip.buf, packed_ip.len); - PyBuffer_Release(&packed_ip); + memcpy(&packed_addr, packed_ip->buf, packed_ip->len); + PyBuffer_Release(packed_ip); SUPPRESS_DEPRECATED_CALL return PyUnicode_FromString(inet_ntoa(packed_addr)); @@ -7049,18 +7038,23 @@ PyDoc_STRVAR(if_nameindex_doc, \n\ Returns a list of network interface information (index, name) tuples."); +/*[clinic input] +_socket.socket.if_nametoindex + oname: object(converter="PyUnicode_FSConverter") + / + +Returns the interface index corresponding to the interface name if_name. +[clinic start generated code]*/ + static PyObject * -socket_if_nametoindex(PyObject *self, PyObject *args) +_socket_socket_if_nametoindex_impl(PySocketSockObject *self, PyObject *oname) +/*[clinic end generated code: output=f7fc00511a309a8e input=662688054482cd46]*/ { - PyObject *oname; #ifdef MS_WINDOWS NET_IFINDEX index; #else unsigned long index; #endif - if (!PyArg_ParseTuple(args, "O&:if_nametoindex", - PyUnicode_FSConverter, &oname)) - return NULL; index = if_nametoindex(PyBytes_AS_STRING(oname)); Py_DECREF(oname); @@ -7073,25 +7067,27 @@ socket_if_nametoindex(PyObject *self, PyObject *args) return PyLong_FromUnsignedLong(index); } -PyDoc_STRVAR(if_nametoindex_doc, -"if_nametoindex(if_name)\n\ -\n\ -Returns the interface index corresponding to the interface name if_name."); static PyObject * socket_if_indextoname(PyObject *self, PyObject *arg) { + unsigned long index_long = PyLong_AsUnsignedLong(arg); + if (index_long == (unsigned long) -1 && PyErr_Occurred()) { + return NULL; + } + #ifdef MS_WINDOWS - NET_IFINDEX index; + NET_IFINDEX index = (NET_IFINDEX)index_long; #else - unsigned long index; + unsigned int index = (unsigned int)index_long; #endif - char name[IF_NAMESIZE + 1]; - index = PyLong_AsUnsignedLong(arg); - if (index == (unsigned long) -1) + if ((unsigned long)index != index_long) { + PyErr_SetString(PyExc_OverflowError, "index is too large"); return NULL; + } + char name[IF_NAMESIZE + 1]; if (if_indextoname(index, name) == NULL) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -7215,19 +7211,15 @@ static PyMethodDef socket_methods[] = { {"socketpair", socket_socketpair, METH_VARARGS, socketpair_doc}, #endif - {"ntohs", socket_ntohs, - METH_VARARGS, ntohs_doc}, + _SOCKET_SOCKET_NTOHS_METHODDEF {"ntohl", socket_ntohl, METH_O, ntohl_doc}, - {"htons", socket_htons, - METH_VARARGS, htons_doc}, + _SOCKET_SOCKET_HTONS_METHODDEF {"htonl", socket_htonl, METH_O, htonl_doc}, - {"inet_aton", socket_inet_aton, - METH_VARARGS, inet_aton_doc}, + _SOCKET_SOCKET_INET_ATON_METHODDEF #ifdef HAVE_INET_NTOA - {"inet_ntoa", socket_inet_ntoa, - METH_VARARGS, inet_ntoa_doc}, + _SOCKET_SOCKET_INET_NTOA_METHODDEF #endif #ifdef HAVE_INET_PTON {"inet_pton", socket_inet_pton, @@ -7250,8 +7242,7 @@ static PyMethodDef socket_methods[] = { #if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) {"if_nameindex", socket_if_nameindex, METH_NOARGS, if_nameindex_doc}, - {"if_nametoindex", socket_if_nametoindex, - METH_VARARGS, if_nametoindex_doc}, + _SOCKET_SOCKET_IF_NAMETOINDEX_METHODDEF {"if_indextoname", socket_if_indextoname, METH_O, if_indextoname_doc}, #endif @@ -7722,10 +7713,10 @@ socket_exec(PyObject *m) /* FreeBSD divert(4) */ #ifdef PF_DIVERT - PyModule_AddIntMacro(m, PF_DIVERT); + ADD_INT_MACRO(m, PF_DIVERT); #endif #ifdef AF_DIVERT - PyModule_AddIntMacro(m, AF_DIVERT); + ADD_INT_MACRO(m, AF_DIVERT); #endif #ifdef AF_PACKET @@ -8818,6 +8809,9 @@ socket_exec(PyObject *m) #ifdef NI_DGRAM ADD_INT_MACRO(m, NI_DGRAM); #endif +#ifdef NI_IDN + ADD_INT_MACRO(m, NI_IDN); +#endif /* shutdown() parameters */ #ifdef SHUT_RD diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 6db8de9c491dd9..62c7816f891ee2 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -49,6 +49,11 @@ Revision history: /* syslog module */ +// clinic/syslogmodule.c.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "osdefs.h" // SEP @@ -401,6 +406,30 @@ syslog_exec(PyObject *module) ADD_INT_MACRO(module, LOG_AUTHPRIV); #endif +#ifdef LOG_FTP + ADD_INT_MACRO(module, LOG_FTP); +#endif + +#ifdef LOG_NETINFO + ADD_INT_MACRO(module, LOG_NETINFO); +#endif + +#ifdef LOG_REMOTEAUTH + ADD_INT_MACRO(module, LOG_REMOTEAUTH); +#endif + +#ifdef LOG_INSTALL + ADD_INT_MACRO(module, LOG_INSTALL); +#endif + +#ifdef LOG_RAS + ADD_INT_MACRO(module, LOG_RAS); +#endif + +#ifdef LOG_LAUNCHD + ADD_INT_MACRO(module, LOG_LAUNCHD); +#endif + return 0; } diff --git a/Modules/termios.c b/Modules/termios.c index c779a757e4fa9b..c4f0fd9d50044a 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -120,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 @@ -128,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; + } + if (PyList_SetItem(cc, VMIN, v) < 0) { goto err; - PyList_SetItem(cc, VMIN, v); + } 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); @@ -197,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", @@ -222,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"); @@ -674,6 +702,9 @@ static struct constant { #ifdef IMAXBEL {"IMAXBEL", IMAXBEL}, #endif +#ifdef IUTF8 + {"IUTF8", IUTF8}, +#endif /* struct termios.c_oflag constants */ {"OPOST", OPOST}, @@ -698,6 +729,12 @@ static struct constant { #ifdef OFDEL {"OFDEL", OFDEL}, #endif +#ifdef OXTABS + {"OXTABS", OXTABS}, +#endif +#ifdef ONOEOT + {"ONOEOT", ONOEOT}, +#endif #ifdef NLDLY {"NLDLY", NLDLY}, #endif @@ -724,6 +761,12 @@ static struct constant { #ifdef NL1 {"NL1", NL1}, #endif +#ifdef NL2 + {"NL2", NL2}, +#endif +#ifdef NL3 + {"NL3", NL3}, +#endif #ifdef CR0 {"CR0", CR0}, #endif @@ -771,6 +814,9 @@ static struct constant { #endif /* struct termios.c_cflag constants */ +#ifdef CIGNORE + {"CIGNORE", CIGNORE}, +#endif {"CSIZE", CSIZE}, {"CSTOPB", CSTOPB}, {"CREAD", CREAD}, @@ -785,6 +831,25 @@ static struct constant { {"CRTSCTS", (long)CRTSCTS}, #endif +#ifdef CRTS_IFLOW + {"CRTS_IFLOW", CRTS_IFLOW}, +#endif +#ifdef CDTR_IFLOW + {"CDTR_IFLOW", CDTR_IFLOW}, +#endif +#ifdef CDSR_OFLOW + {"CDSR_OFLOW", CDSR_OFLOW}, +#endif +#ifdef CCTS_OFLOW + {"CCTS_OFLOW", CCTS_OFLOW}, +#endif +#ifdef CCAR_OFLOW + {"CCAR_OFLOW", CCAR_OFLOW}, +#endif +#ifdef MDMBUF + {"MDMBUF", MDMBUF}, +#endif + /* struct termios.c_cflag-related values (character size) */ {"CS5", CS5}, {"CS6", CS6}, @@ -792,6 +857,9 @@ static struct constant { {"CS8", CS8}, /* struct termios.c_lflag constants */ +#ifdef ALTWERASE + {"ALTWERASE", ALTWERASE}, +#endif {"ISIG", ISIG}, {"ICANON", ICANON}, #ifdef XCASE @@ -812,6 +880,9 @@ static struct constant { #endif #ifdef FLUSHO {"FLUSHO", FLUSHO}, +#endif +#ifdef NOKERNINFO + {"NOKERNINFO", NOKERNINFO}, #endif {"NOFLSH", NOFLSH}, {"TOSTOP", TOSTOP}, @@ -819,6 +890,9 @@ static struct constant { {"PENDIN", PENDIN}, #endif {"IEXTEN", IEXTEN}, +#ifdef EXTPROC + {"EXTPROC", EXTPROC}, +#endif /* indexes into the control chars array returned by tcgetattr() */ {"VINTR", VINTR}, @@ -827,6 +901,9 @@ static struct constant { {"VKILL", VKILL}, {"VEOF", VEOF}, {"VTIME", VTIME}, +#ifdef VSTATUS + {"VSTATUS", VSTATUS}, +#endif {"VMIN", VMIN}, #ifdef VSWTC /* The #defines above ensure that if either is defined, both are, @@ -837,6 +914,9 @@ static struct constant { {"VSTART", VSTART}, {"VSTOP", VSTOP}, {"VSUSP", VSUSP}, +#ifdef VDSUSP + {"VDSUSP", VDSUSP}, +#endif {"VEOL", VEOL}, #ifdef VREPRINT {"VREPRINT", VREPRINT}, @@ -855,6 +935,18 @@ static struct constant { #endif +#ifdef B7200 + {"B7200", B7200}, +#endif +#ifdef B14400 + {"B14400", B14400}, +#endif +#ifdef B28800 + {"B28800", B28800}, +#endif +#ifdef B76800 + {"B76800", B76800}, +#endif #ifdef B460800 {"B460800", B460800}, #endif diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 6a872a285d289b..b3fe175d9b184a 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -63,54 +63,10 @@ #define SEC_TO_NS (1000 * 1000 * 1000) -#if defined(HAVE_TIMES) || defined(HAVE_CLOCK) -static int -check_ticks_per_second(long tps, const char *context) -{ - /* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) - cannot overflow. */ - if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) { - PyErr_Format(PyExc_OverflowError, "%s is too large", context); - return -1; - } - return 0; -} -#endif /* HAVE_TIMES || HAVE_CLOCK */ - -#ifdef HAVE_TIMES - -# define ticks_per_second _PyRuntime.time.ticks_per_second - -static void -ensure_ticks_per_second(void) -{ - if (_PyRuntime.time.ticks_per_second_initialized) { - return; - } - _PyRuntime.time.ticks_per_second_initialized = 1; -# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - ticks_per_second = sysconf(_SC_CLK_TCK); - if (ticks_per_second < 1) { - ticks_per_second = -1; - } -# elif defined(HZ) - ticks_per_second = HZ; -# else - ticks_per_second = 60; /* magic fallback value; may be bogus */ -# endif -} - -#endif /* HAVE_TIMES */ - - -PyStatus -_PyTime_Init(void) -{ -#ifdef HAVE_TIMES - ensure_ticks_per_second(); -#endif - return PyStatus_Ok(); -} +/*[clinic input] +module time +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a668a08771581f36]*/ /* Forward declarations */ @@ -119,6 +75,14 @@ static int pysleep(_PyTime_t timeout); typedef struct { PyTypeObject *struct_time_type; +#ifdef HAVE_TIMES + // times() clock frequency in hertz + _PyTimeFraction times_base; +#endif +#ifdef HAVE_CLOCK + // clock() frequency in hertz + _PyTimeFraction clock_base; +#endif } time_module_state; static inline time_module_state* @@ -178,7 +142,7 @@ PyDoc_STRVAR(time_ns_doc, \n\ Return the current time in nanoseconds since the Epoch."); -#if defined(HAVE_CLOCK) +#ifdef HAVE_CLOCK #ifndef CLOCKS_PER_SEC # ifdef CLK_TCK @@ -189,15 +153,13 @@ Return the current time in nanoseconds since the Epoch."); #endif static int -_PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +py_clock(time_module_state *state, _PyTime_t *tp, _Py_clock_info_t *info) { - if (check_ticks_per_second(CLOCKS_PER_SEC, "CLOCKS_PER_SEC") < 0) { - return -1; - } + _PyTimeFraction *base = &state->clock_base; if (info) { info->implementation = "clock()"; - info->resolution = 1.0 / (double)CLOCKS_PER_SEC; + info->resolution = _PyTimeFraction_Resolution(base); info->monotonic = 1; info->adjustable = 0; } @@ -209,7 +171,7 @@ _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) "or its value cannot be represented"); return -1; } - _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)CLOCKS_PER_SEC); + _PyTime_t ns = _PyTimeFraction_Mul(ticks, base); *tp = _PyTime_FromNanoseconds(ns); return 0; } @@ -227,23 +189,52 @@ _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #pragma clang diagnostic ignored "-Wunguarded-availability" #endif -static PyObject * -time_clock_gettime(PyObject *self, PyObject *args) +static int +time_clockid_converter(PyObject *obj, clockid_t *p) { - int ret; - struct timespec tp; - -#if defined(_AIX) && (SIZEOF_LONG == 8) - long clk_id; - if (!PyArg_ParseTuple(args, "l:clock_gettime", &clk_id)) { +#ifdef _AIX + long long clk_id = PyLong_AsLongLong(obj); #else - int clk_id; - if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { + int clk_id = PyLong_AsInt(obj); #endif - return NULL; + if (clk_id == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "clk_id should be integer, not %s", + _PyType_Name(Py_TYPE(obj))); + return 0; } - ret = clock_gettime((clockid_t)clk_id, &tp); + // Make sure that we picked the right type (check sizes type) + Py_BUILD_ASSERT(sizeof(clk_id) == sizeof(*p)); + *p = (clockid_t)clk_id; + return 1; +} + +/*[python input] + +class clockid_t_converter(CConverter): + type = "clockid_t" + converter = 'time_clockid_converter' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=53867111501f46c8]*/ + + +/*[clinic input] +time.clock_gettime + + clk_id: clockid_t + / + +Return the time of the specified clock clk_id as a float. +[clinic start generated code]*/ + +static PyObject * +time_clock_gettime_impl(PyObject *module, clockid_t clk_id) +/*[clinic end generated code: output=832b9ebc03328020 input=7e89fcc42ca15e5d]*/ +{ + struct timespec tp; + int ret = clock_gettime(clk_id, &tp); if (ret != 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -251,38 +242,32 @@ time_clock_gettime(PyObject *self, PyObject *args) return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); } -PyDoc_STRVAR(clock_gettime_doc, -"clock_gettime(clk_id) -> float\n\ -\n\ -Return the time of the specified clock clk_id."); +/*[clinic input] +time.clock_gettime_ns + + clk_id: clockid_t + / + +Return the time of the specified clock clk_id as nanoseconds (int). +[clinic start generated code]*/ static PyObject * -time_clock_gettime_ns(PyObject *self, PyObject *args) +time_clock_gettime_ns_impl(PyObject *module, clockid_t clk_id) +/*[clinic end generated code: output=4a045c3a36e60044 input=aabc248db8c8e3e5]*/ { - int ret; - int clk_id; struct timespec ts; - _PyTime_t t; - - if (!PyArg_ParseTuple(args, "i:clock_gettime", &clk_id)) { - return NULL; - } - - ret = clock_gettime((clockid_t)clk_id, &ts); + int ret = clock_gettime(clk_id, &ts); if (ret != 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } + + _PyTime_t t; if (_PyTime_FromTimespec(&t, &ts) < 0) { return NULL; } return _PyTime_AsNanosecondsObject(t); } - -PyDoc_STRVAR(clock_gettime_ns_doc, -"clock_gettime_ns(clk_id) -> int\n\ -\n\ -Return the time of the specified clock clk_id as nanoseconds."); #endif /* HAVE_CLOCK_GETTIME */ #ifdef HAVE_CLOCK_SETTIME @@ -1248,8 +1233,38 @@ PyDoc_STRVAR(perf_counter_ns_doc, \n\ Performance counter for benchmarking as nanoseconds."); + +#ifdef HAVE_TIMES static int -_PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +process_time_times(time_module_state *state, _PyTime_t *tp, + _Py_clock_info_t *info) +{ + _PyTimeFraction *base = &state->times_base; + + struct tms process; + if (times(&process) == (clock_t)-1) { + return 0; + } + + if (info) { + info->implementation = "times()"; + info->resolution = _PyTimeFraction_Resolution(base); + info->monotonic = 1; + info->adjustable = 0; + } + + _PyTime_t ns; + ns = _PyTimeFraction_Mul(process.tms_utime, base); + ns += _PyTimeFraction_Mul(process.tms_stime, base); + *tp = _PyTime_FromNanoseconds(ns); + return 1; +} +#endif + + +static int +py_process_time(time_module_state *state, _PyTime_t *tp, + _Py_clock_info_t *info) { #if defined(MS_WINDOWS) HANDLE process; @@ -1352,41 +1367,27 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) /* times() */ #ifdef HAVE_TIMES - struct tms t; - - if (times(&t) != (clock_t)-1) { - assert(_PyRuntime.time.ticks_per_second_initialized); - if (check_ticks_per_second(ticks_per_second, "_SC_CLK_TCK") < 0) { - return -1; - } - if (ticks_per_second != -1) { - if (info) { - info->implementation = "times()"; - info->monotonic = 1; - info->adjustable = 0; - info->resolution = 1.0 / (double)ticks_per_second; - } - - _PyTime_t ns; - ns = _PyTime_MulDiv(t.tms_utime, SEC_TO_NS, ticks_per_second); - ns += _PyTime_MulDiv(t.tms_stime, SEC_TO_NS, ticks_per_second); - *tp = _PyTime_FromNanoseconds(ns); - return 0; - } + int res = process_time_times(state, tp, info); + if (res < 0) { + return -1; + } + if (res == 1) { + return 0; } + // times() failed, ignore failure #endif - /* clock */ - /* Currently, Python 3 requires clock() to build: see issue #22624 */ - return _PyTime_GetClockWithInfo(tp, info); + /* clock(). Python 3 requires clock() to build (see gh-66814) */ + return py_clock(state, tp, info); #endif } static PyObject * -time_process_time(PyObject *self, PyObject *unused) +time_process_time(PyObject *module, PyObject *unused) { + time_module_state *state = get_time_state(module); _PyTime_t t; - if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { + if (py_process_time(state, &t, NULL) < 0) { return NULL; } return _PyFloat_FromPyTime(t); @@ -1398,10 +1399,11 @@ PyDoc_STRVAR(process_time_doc, Process time for profiling: sum of the kernel and user-space CPU time."); static PyObject * -time_process_time_ns(PyObject *self, PyObject *unused) +time_process_time_ns(PyObject *module, PyObject *unused) { + time_module_state *state = get_time_state(module); _PyTime_t t; - if (_PyTime_GetProcessTimeWithInfo(&t, NULL) < 0) { + if (py_process_time(state, &t, NULL) < 0) { return NULL; } return _PyTime_AsNanosecondsObject(t); @@ -1588,7 +1590,7 @@ sum of the kernel and user-space CPU time."); static PyObject * -time_get_clock_info(PyObject *self, PyObject *args) +time_get_clock_info(PyObject *module, PyObject *args) { char *name; _Py_clock_info_t info; @@ -1627,7 +1629,8 @@ time_get_clock_info(PyObject *self, PyObject *args) } } else if (strcmp(name, "process_time") == 0) { - if (_PyTime_GetProcessTimeWithInfo(&t, &info) < 0) { + time_module_state *state = get_time_state(module); + if (py_process_time(state, &t, &info) < 0) { return NULL; } } @@ -1740,6 +1743,12 @@ get_gmtoff(time_t t, struct tm *p) static int init_timezone(PyObject *m) { +#define ADD_INT(NAME, VALUE) do { \ + if (PyModule_AddIntConstant(m, NAME, VALUE) < 0) { \ + return -1; \ + } \ +} while (0) + assert(!PyErr_Occurred()); /* This code moved from PyInit_time wholesale to allow calling it from @@ -1763,13 +1772,13 @@ init_timezone(PyObject *m) #if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) tzset(); #endif - PyModule_AddIntConstant(m, "timezone", _Py_timezone); + ADD_INT("timezone", _Py_timezone); #ifdef HAVE_ALTZONE - PyModule_AddIntConstant(m, "altzone", altzone); + ADD_INT("altzone", altzone); #else - PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600); + ADD_INT("altzone", _Py_timezone-3600); #endif - PyModule_AddIntConstant(m, "daylight", _Py_daylight); + ADD_INT("daylight", _Py_daylight); #ifdef MS_WINDOWS TIME_ZONE_INFORMATION tzinfo = {0}; GetTimeZoneInformation(&tzinfo); @@ -1828,20 +1837,21 @@ init_timezone(PyObject *m) PyObject *tzname_obj; if (janzone < julyzone) { /* DST is reversed in the southern hemisphere */ - PyModule_AddIntConstant(m, "timezone", julyzone); - PyModule_AddIntConstant(m, "altzone", janzone); - PyModule_AddIntConstant(m, "daylight", janzone != julyzone); + ADD_INT("timezone", julyzone); + ADD_INT("altzone", janzone); + ADD_INT("daylight", janzone != julyzone); tzname_obj = Py_BuildValue("(zz)", julyname, janname); } else { - PyModule_AddIntConstant(m, "timezone", janzone); - PyModule_AddIntConstant(m, "altzone", julyzone); - PyModule_AddIntConstant(m, "daylight", janzone != julyzone); + ADD_INT("timezone", janzone); + ADD_INT("altzone", julyzone); + ADD_INT("daylight", janzone != julyzone); tzname_obj = Py_BuildValue("(zz)", janname, julyname); } if (PyModule_Add(m, "tzname", tzname_obj) < 0) { return -1; } #endif // !HAVE_DECL_TZNAME +#undef ADD_INT if (PyErr_Occurred()) { return -1; @@ -1850,12 +1860,16 @@ init_timezone(PyObject *m) } +// Include Argument Clinic code after defining converters such as +// time_clockid_converter(). +#include "clinic/timemodule.c.h" + static PyMethodDef time_methods[] = { {"time", time_time, METH_NOARGS, time_doc}, {"time_ns", time_time_ns, METH_NOARGS, time_ns_doc}, #ifdef HAVE_CLOCK_GETTIME - {"clock_gettime", time_clock_gettime, METH_VARARGS, clock_gettime_doc}, - {"clock_gettime_ns",time_clock_gettime_ns, METH_VARARGS, clock_gettime_ns_doc}, + TIME_CLOCK_GETTIME_METHODDEF + TIME_CLOCK_GETTIME_NS_METHODDEF #endif #ifdef HAVE_CLOCK_SETTIME {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, @@ -2076,6 +2090,28 @@ time_exec(PyObject *module) } #endif +#ifdef HAVE_TIMES + long ticks_per_second; + if (_Py_GetTicksPerSecond(&ticks_per_second) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "cannot read ticks_per_second"); + return -1; + } + if (_PyTimeFraction_Set(&state->times_base, SEC_TO_NS, + ticks_per_second) < 0) { + PyErr_Format(PyExc_OverflowError, "ticks_per_second is too large"); + return -1; + } +#endif + +#ifdef HAVE_CLOCK + if (_PyTimeFraction_Set(&state->clock_base, SEC_TO_NS, + CLOCKS_PER_SEC) < 0) { + PyErr_Format(PyExc_OverflowError, "CLOCKS_PER_SEC is too large"); + return -1; + } +#endif + return 0; } diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 875a9c18c4e340..6ae35b9372b830 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -977,21 +977,6 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, /* -------------------------------------------------------------------- */ /* database code (cut and pasted from the unidb package) */ -static unsigned long -_gethash(const char *s, int len, int scale) -{ - int i; - unsigned long h = 0; - unsigned long ix; - for (i = 0; i < len; i++) { - h = (h * scale) + (unsigned char) Py_TOUPPER(s[i]); - ix = h & 0xff000000; - if (ix) - h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff; - } - return h; -} - static const char * const hangul_syllables[][3] = { { "G", "A", "" }, { "GG", "AE", "G" }, @@ -1046,6 +1031,247 @@ is_unified_ideograph(Py_UCS4 code) #define IS_NAMED_SEQ(cp) ((cp >= named_sequences_start) && \ (cp < named_sequences_end)) + +// DAWG decoding functions + +static unsigned int +_dawg_decode_varint_unsigned(unsigned int index, unsigned int* result) +{ + unsigned int res = 0; + unsigned int shift = 0; + for (;;) { + unsigned char byte = packed_name_dawg[index]; + res |= (byte & 0x7f) << shift; + index++; + shift += 7; + if (!(byte & 0x80)) { + *result = res; + return index; + } + } +} + +static int +_dawg_match_edge(const char* name, unsigned int namelen, unsigned int size, + unsigned int label_offset, unsigned int namepos) +{ + // This returns 1 if the edge matched, 0 if it didn't (but further edges + // could match) and -1 if the name cannot match at all. + if (size > 1 && namepos + size > namelen) { + return 0; + } + for (unsigned int i = 0; i < size; i++) { + if (packed_name_dawg[label_offset + i] != Py_TOUPPER(name[namepos + i])) { + if (i > 0) { + return -1; // cannot match at all + } + return 0; + } + } + return 1; +} + +// reading DAWG node information: +// a node is encoded by a varint. The lowest bit of that int is set if the node +// is a final, accepting state. The higher bits of that int represent the +// number of names that are encoded by the sub-DAWG started by this node. It's +// used to compute the position of a name. +// +// the starting node of the DAWG is at position 0. +// +// the varint representing a node is followed by the node's edges, the encoding +// is described below + + +static unsigned int +_dawg_decode_node(unsigned int node_offset, bool* final) +{ + unsigned int num; + node_offset = _dawg_decode_varint_unsigned(node_offset, &num); + *final = num & 1; + return node_offset; +} + +static bool +_dawg_node_is_final(unsigned int node_offset) +{ + unsigned int num; + _dawg_decode_varint_unsigned(node_offset, &num); + return num & 1; +} + +static unsigned int +_dawg_node_descendant_count(unsigned int node_offset) +{ + unsigned int num; + _dawg_decode_varint_unsigned(node_offset, &num); + return num >> 1; +} + + +// reading DAWG edge information: +// a DAWG edge is comprised of the following information: +// (1) the size of the label of the string attached to the edge +// (2) the characters of that edge +// (3) the target node +// (4) whether the edge is the last edge in the list of edges following a node +// +// this information is encoded in a compact form as follows: +// +// +---------+-----------------+--------------+-------------------- +// | varint | size (if != 1) | label chars | ... next edge ... +// +---------+-----------------+--------------+-------------------- +// +// - first comes a varint +// - the lowest bit of that varint is whether the edge is final (4) +// - the second lowest bit of that varint is true if the size of +// the length of the label is 1 (1) +// - the rest of the varint is an offset that can be used to compute +// the offset of the target node of that edge (3) +// - if the size is not 1, the first varint is followed by a +// character encoding the number of characters of the label (1) +// (unicode character names aren't larger than 256 bytes, therefore each +// edge label can be at most 256 chars, but is usually smaller) +// - the next size bytes are the characters of the label (2) +// +// the offset of the target node is computed as follows: the number in the +// upper bits of the varint needs to be added to the offset of the target node +// of the previous edge. For the first edge, where there is no previous target +// node, the offset of the first edge is used. +// The intuition here is that edges going out from a node often lead to nodes +// that are close by, leading to small offsets from the current node and thus +// fewer bytes. +// +// There is a special case: if a final node has no outgoing edges, it has to be +// followed by a 0 byte to indicate that there are no edges (because the end of +// the edge list is normally indicated in a bit in the edge encoding). This is +// indicated by _dawg_decode_edge returning -1 + + +static int +_dawg_decode_edge(bool is_first_edge, unsigned int prev_target_node_offset, + unsigned int edge_offset, unsigned int* size, + unsigned int* label_offset, unsigned int* target_node_offset) +{ + unsigned int num; + edge_offset = _dawg_decode_varint_unsigned(edge_offset, &num); + if (num == 0 && is_first_edge) { + return -1; // trying to decode past a final node without outgoing edges + } + bool last_edge = num & 1; + num >>= 1; + bool len_is_one = num & 1; + num >>= 1; + *target_node_offset = prev_target_node_offset + num; + if (len_is_one) { + *size = 1; + } else { + *size = packed_name_dawg[edge_offset++]; + } + *label_offset = edge_offset; + return last_edge; +} + +static int +_lookup_dawg_packed(const char* name, unsigned int namelen) +{ + unsigned int stringpos = 0; + unsigned int node_offset = 0; + unsigned int result = 0; // this is the number of final nodes that we skipped to match name + while (stringpos < namelen) { + bool final; + unsigned int edge_offset = _dawg_decode_node(node_offset, &final); + unsigned int prev_target_node_offset = edge_offset; + bool is_first_edge = true; + for (;;) { + unsigned int size; + unsigned int label_offset, target_node_offset; + int last_edge = _dawg_decode_edge( + is_first_edge, prev_target_node_offset, edge_offset, + &size, &label_offset, &target_node_offset); + if (last_edge == -1) { + return -1; + } + is_first_edge = false; + prev_target_node_offset = target_node_offset; + int matched = _dawg_match_edge(name, namelen, size, label_offset, stringpos); + if (matched == -1) { + return -1; + } + if (matched) { + if (final) + result += 1; + stringpos += size; + node_offset = target_node_offset; + break; + } + if (last_edge) { + return -1; + } + result += _dawg_node_descendant_count(target_node_offset); + edge_offset = label_offset + size; + } + } + if (_dawg_node_is_final(node_offset)) { + return result; + } + return -1; +} + +static int +_inverse_dawg_lookup(char* buffer, unsigned int buflen, unsigned int pos) +{ + unsigned int node_offset = 0; + unsigned int bufpos = 0; + for (;;) { + bool final; + unsigned int edge_offset = _dawg_decode_node(node_offset, &final); + + if (final) { + if (pos == 0) { + if (bufpos + 1 == buflen) { + return 0; + } + buffer[bufpos] = '\0'; + return 1; + } + pos--; + } + unsigned int prev_target_node_offset = edge_offset; + bool is_first_edge = true; + for (;;) { + unsigned int size; + unsigned int label_offset, target_node_offset; + int last_edge = _dawg_decode_edge( + is_first_edge, prev_target_node_offset, edge_offset, + &size, &label_offset, &target_node_offset); + if (last_edge == -1) { + return 0; + } + is_first_edge = false; + prev_target_node_offset = target_node_offset; + + unsigned int descendant_count = _dawg_node_descendant_count(target_node_offset); + if (pos < descendant_count) { + if (bufpos + size >= buflen) { + return 0; // buffer overflow + } + for (unsigned int i = 0; i < size; i++) { + buffer[bufpos++] = packed_name_dawg[label_offset++]; + } + node_offset = target_node_offset; + break; + } else if (!last_edge) { + pos -= descendant_count; + edge_offset = label_offset + size; + } else { + return 0; + } + } + } +} + + static int _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, int with_alias_and_seq) @@ -1054,9 +1280,6 @@ _getucname(PyObject *self, * If with_alias_and_seq is 1, check for names in the Private Use Area 15 * that we are using for aliases and named sequences. */ int offset; - int i; - int word; - const unsigned char* w; if (code >= 0x110000) return 0; @@ -1107,45 +1330,15 @@ _getucname(PyObject *self, return 1; } - /* get offset into phrasebook */ - offset = phrasebook_offset1[(code>>phrasebook_shift)]; - offset = phrasebook_offset2[(offset<>DAWG_CODEPOINT_TO_POS_SHIFT)]; + offset = dawg_codepoint_to_pos_index2[(offset<= 0) { - word = (word << 8) + phrasebook[offset+1]; - offset += 2; - } else - word = phrasebook[offset++]; - if (i) { - if (i > buflen) - return 0; /* buffer overflow */ - buffer[i++] = ' '; - } - /* copy word string from lexicon. the last character in the - word has bit 7 set. the last word in a string ends with - 0x80 */ - w = lexicon + lexicon_offset[word]; - while (*w < 128) { - if (i >= buflen) - return 0; /* buffer overflow */ - buffer[i++] = *w++; - } - if (i >= buflen) - return 0; /* buffer overflow */ - buffer[i++] = *w & 127; - if (*w == 128) - break; /* end of word */ - } - - return 1; + assert(buflen >= 0); + return _inverse_dawg_lookup(buffer, Py_SAFE_DOWNCAST(buflen, int, unsigned int), offset); } static int @@ -1157,21 +1350,6 @@ capi_getucname(Py_UCS4 code, } -static int -_cmpname(PyObject *self, int code, const char* name, int namelen) -{ - /* check if code corresponds to the given name */ - int i; - char buffer[NAME_MAXLEN+1]; - if (!_getucname(self, code, buffer, NAME_MAXLEN, 1)) - return 0; - for (i = 0; i < namelen; i++) { - if (Py_TOUPPER(name[i]) != buffer[i]) - return 0; - } - return buffer[namelen] == '\0'; -} - static void find_syllable(const char *str, int *len, int *pos, int count, int column) { @@ -1193,31 +1371,25 @@ find_syllable(const char *str, int *len, int *pos, int count, int column) } static int -_check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) +_check_alias_and_seq(Py_UCS4* code, int with_named_seq) { /* check if named sequences are allowed */ - if (!with_named_seq && IS_NAMED_SEQ(cp)) + if (!with_named_seq && IS_NAMED_SEQ(*code)) return 0; /* if the code point is in the PUA range that we use for aliases, * convert it to obtain the right code point */ - if (IS_ALIAS(cp)) - *code = name_aliases[cp-aliases_start]; - else - *code = cp; + if (IS_ALIAS(*code)) + *code = name_aliases[*code-aliases_start]; return 1; } + static int -_getcode(PyObject* self, - const char* name, int namelen, Py_UCS4* code, int with_named_seq) +_getcode(const char* name, int namelen, Py_UCS4* code) { /* Return the code point associated with the given name. - * Named aliases are resolved too (unless self != NULL (i.e. we are using - * 3.2.0)). If with_named_seq is 1, returns the PUA code point that we are - * using for the named sequence, and the caller must then convert it. */ - unsigned int h, v; - unsigned int mask = code_size-1; - unsigned int i, incr; + * Named aliases are not resolved, they are returned as a code point in the + * PUA */ /* Check for hangul syllables. */ if (strncmp(name, "HANGUL SYLLABLE ", 16) == 0) { @@ -1240,6 +1412,7 @@ _getcode(PyObject* self, /* Check for unified ideographs. */ if (strncmp(name, "CJK UNIFIED IDEOGRAPH-", 22) == 0) { /* Four or five hexdigits must follow. */ + unsigned int v; v = 0; name += 22; namelen -= 22; @@ -1261,41 +1434,24 @@ _getcode(PyObject* self, return 1; } - /* the following is the same as python's dictionary lookup, with - only minor changes. see the makeunicodedata script for more - details */ - - h = (unsigned int) _gethash(name, namelen, code_magic); - i = (~h) & mask; - v = code_hash[i]; - if (!v) + assert(namelen >= 0); + int position = _lookup_dawg_packed(name, Py_SAFE_DOWNCAST(namelen, int, unsigned int)); + if (position < 0) { return 0; - if (_cmpname(self, v, name, namelen)) { - return _check_alias_and_seq(v, code, with_named_seq); - } - incr = (h ^ (h >> 3)) & mask; - if (!incr) - incr = mask; - for (;;) { - i = (i + incr) & mask; - v = code_hash[i]; - if (!v) - return 0; - if (_cmpname(self, v, name, namelen)) { - return _check_alias_and_seq(v, code, with_named_seq); - } - incr = incr << 1; - if (incr > mask) - incr = incr ^ code_poly; } + *code = dawg_pos_to_codepoint[position]; + return 1; } + static int capi_getcode(const char* name, int namelen, Py_UCS4* code, int with_named_seq) { - return _getcode(NULL, name, namelen, code, with_named_seq); - + if (!_getcode(name, namelen, code)) { + return 0; + } + return _check_alias_and_seq(code, with_named_seq); } static void @@ -1388,10 +1544,17 @@ unicodedata_UCD_lookup_impl(PyObject *self, const char *name, return NULL; } - if (!_getcode(self, name, (int)name_length, &code, 1)) { + if (!_getcode(name, (int)name_length, &code)) { PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); return NULL; } + if (UCD_Check(self)) { + /* in 3.2.0 there are no aliases and named sequences */ + if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) { + PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); + return 0; + } + } /* check if code is in the PUA range that we use for named sequences and convert it */ if (IS_NAMED_SEQ(code)) { @@ -1400,6 +1563,9 @@ unicodedata_UCD_lookup_impl(PyObject *self, const char *name, named_sequences[index].seq, named_sequences[index].seqlen); } + if (IS_ALIAS(code)) { + code = name_aliases[code-aliases_start]; + } return PyUnicode_FromOrdinal(code); } diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index ed4b0eea9a6c59..3e210863448b78 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -1,4 +1,4 @@ -/* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ +/* this file was generated by ./Tools/unicode/makeunicodedata.py 3.3 */ #define UNIDATA_VERSION "15.1.0" /* a list of unique database records */ diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index 1116905308177d..4fe60ad5ed4452 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -1,30130 +1,17171 @@ -/* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ +/* this file was generated by ./Tools/unicode/makeunicodedata.py 3.3 */ #define NAME_MAXLEN 256 -/* lexicon */ -static const unsigned char lexicon[] = { - 76, 69, 84, 84, 69, 210, 83, 77, 65, 76, 204, 83, 73, 71, 206, 87, 73, - 84, 200, 83, 89, 76, 76, 65, 66, 76, 197, 67, 65, 80, 73, 84, 65, 204, - 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 76, 65, 84, 73, 206, 65, 82, 65, - 66, 73, 195, 67, 85, 78, 69, 73, 70, 79, 82, 205, 89, 201, 67, 74, 203, - 77, 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 69, 71, 89, 80, 84, 73, - 65, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 217, 83, 89, 77, - 66, 79, 204, 68, 73, 71, 73, 212, 86, 79, 87, 69, 204, 84, 65, 78, 71, - 85, 212, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, 89, - 76, 76, 65, 66, 73, 67, 211, 65, 78, 196, 83, 73, 71, 78, 87, 82, 73, 84, - 73, 78, 199, 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 83, 67, 82, 73, - 80, 212, 66, 79, 76, 196, 65, 78, 65, 84, 79, 76, 73, 65, 206, 72, 65, - 78, 71, 85, 204, 78, 85, 77, 66, 69, 210, 76, 73, 78, 69, 65, 210, 67, - 79, 77, 66, 73, 78, 73, 78, 199, 76, 73, 71, 65, 84, 85, 82, 197, 71, 82, - 69, 69, 203, 69, 84, 72, 73, 79, 80, 73, 195, 77, 85, 83, 73, 67, 65, - 204, 67, 89, 82, 73, 76, 76, 73, 195, 70, 79, 210, 75, 72, 73, 84, 65, - 206, 193, 73, 84, 65, 76, 73, 195, 84, 65, 77, 73, 204, 76, 69, 70, 212, - 78, 85, 83, 72, 213, 67, 73, 82, 67, 76, 69, 196, 82, 65, 68, 73, 67, 65, - 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, 198, 82, 73, 71, 72, 212, 83, - 81, 85, 65, 82, 197, 77, 79, 68, 73, 70, 73, 69, 210, 70, 73, 78, 65, - 204, 84, 65, 201, 68, 79, 85, 66, 76, 197, 83, 73, 71, 78, 128, 65, 82, - 82, 79, 87, 128, 65, 66, 79, 86, 69, 128, 86, 65, 201, 66, 69, 76, 79, - 87, 128, 72, 69, 78, 84, 65, 73, 71, 65, 78, 193, 66, 76, 65, 67, 203, - 87, 72, 73, 84, 197, 65, 82, 82, 79, 215, 65, 128, 85, 128, 86, 65, 82, - 73, 65, 84, 73, 79, 206, 73, 128, 66, 82, 65, 73, 76, 76, 197, 80, 65, - 84, 84, 69, 82, 206, 75, 65, 84, 65, 75, 65, 78, 193, 66, 89, 90, 65, 78, - 84, 73, 78, 197, 79, 128, 68, 79, 212, 73, 83, 79, 76, 65, 84, 69, 196, - 77, 65, 82, 75, 128, 194, 79, 198, 77, 89, 65, 78, 77, 65, 210, 86, 69, - 82, 84, 73, 67, 65, 204, 77, 73, 68, 68, 76, 197, 75, 65, 78, 71, 88, - 201, 75, 73, 75, 65, 75, 85, 201, 77, 69, 78, 68, 197, 84, 73, 66, 69, - 84, 65, 206, 77, 65, 82, 203, 72, 69, 65, 86, 217, 73, 78, 73, 84, 73, - 65, 204, 72, 77, 79, 78, 199, 79, 78, 197, 77, 69, 69, 205, 65, 66, 79, - 86, 197, 67, 79, 80, 84, 73, 195, 75, 72, 77, 69, 210, 82, 73, 71, 72, - 84, 87, 65, 82, 68, 211, 90, 78, 65, 77, 69, 78, 78, 217, 67, 65, 82, 82, - 73, 69, 210, 89, 69, 200, 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 71, - 69, 79, 82, 71, 73, 65, 206, 72, 79, 79, 75, 128, 67, 72, 69, 82, 79, 75, - 69, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 84, 87, 207, 83, 84, 82, - 79, 75, 69, 128, 79, 78, 69, 128, 80, 76, 85, 211, 84, 87, 79, 128, 76, - 79, 87, 69, 210, 66, 79, 216, 83, 81, 85, 65, 82, 69, 196, 83, 89, 77, - 66, 79, 76, 128, 80, 72, 65, 83, 69, 45, 197, 84, 72, 82, 69, 197, 85, - 80, 80, 69, 210, 86, 79, 67, 65, 76, 73, 195, 76, 69, 70, 84, 87, 65, 82, - 68, 211, 84, 207, 67, 79, 78, 83, 79, 78, 65, 78, 212, 77, 73, 65, 207, - 68, 82, 65, 87, 73, 78, 71, 211, 84, 73, 76, 197, 68, 85, 80, 76, 79, 89, - 65, 206, 74, 79, 78, 71, 83, 69, 79, 78, 199, 80, 65, 82, 69, 78, 84, 72, - 69, 83, 73, 90, 69, 196, 84, 72, 65, 205, 71, 79, 78, 68, 201, 76, 79, - 215, 65, 76, 69, 198, 72, 65, 76, 198, 85, 208, 70, 79, 85, 82, 128, 71, - 76, 65, 71, 79, 76, 73, 84, 73, 195, 72, 69, 66, 82, 69, 215, 72, 73, 71, - 200, 84, 72, 82, 69, 69, 128, 79, 86, 69, 210, 72, 65, 128, 73, 78, 68, - 69, 216, 77, 65, 76, 65, 89, 65, 76, 65, 205, 83, 73, 89, 65, 209, 68, - 79, 87, 206, 80, 65, 72, 65, 87, 200, 67, 72, 79, 83, 69, 79, 78, 199, - 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, - 65, 45, 49, 128, 87, 193, 87, 48, 50, 53, 128, 87, 48, 50, 52, 65, 128, - 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, 48, 50, 50, 128, 87, 48, - 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, 57, 128, 87, 48, 49, 56, - 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, 65, 128, 87, 48, 49, 55, - 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, 87, 48, 49, 52, 65, 128, - 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, 48, 49, 50, 128, 87, 48, - 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, 49, 48, 128, 87, 48, 48, - 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, 56, 128, 87, 48, 48, 55, - 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, 87, 48, 48, 52, 128, 87, - 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, 48, 48, 50, 128, 87, 48, - 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 90, 128, 86, 89, 88, 128, 86, - 89, 84, 128, 86, 89, 83, 79, 75, 79, 128, 86, 89, 83, 79, 75, 207, 86, - 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, 89, 128, 86, 88, - 128, 86, 87, 74, 128, 86, 87, 65, 128, 86, 87, 128, 86, 85, 88, 128, 86, - 85, 85, 128, 86, 85, 84, 128, 86, 85, 82, 88, 128, 86, 85, 82, 128, 86, - 85, 80, 128, 86, 85, 76, 71, 65, 210, 86, 85, 76, 67, 65, 78, 85, 83, - 128, 86, 85, 69, 81, 128, 86, 84, 83, 128, 86, 84, 128, 86, 83, 57, 57, - 128, 86, 83, 57, 56, 128, 86, 83, 57, 55, 128, 86, 83, 57, 54, 128, 86, - 83, 57, 53, 128, 86, 83, 57, 52, 128, 86, 83, 57, 51, 128, 86, 83, 57, - 50, 128, 86, 83, 57, 49, 128, 86, 83, 57, 48, 128, 86, 83, 57, 128, 86, - 83, 56, 57, 128, 86, 83, 56, 56, 128, 86, 83, 56, 55, 128, 86, 83, 56, - 54, 128, 86, 83, 56, 53, 128, 86, 83, 56, 52, 128, 86, 83, 56, 51, 128, - 86, 83, 56, 50, 128, 86, 83, 56, 49, 128, 86, 83, 56, 48, 128, 86, 83, - 56, 128, 86, 83, 55, 57, 128, 86, 83, 55, 56, 128, 86, 83, 55, 55, 128, - 86, 83, 55, 54, 128, 86, 83, 55, 53, 128, 86, 83, 55, 52, 128, 86, 83, - 55, 51, 128, 86, 83, 55, 50, 128, 86, 83, 55, 49, 128, 86, 83, 55, 48, - 128, 86, 83, 55, 128, 86, 83, 54, 57, 128, 86, 83, 54, 56, 128, 86, 83, - 54, 55, 128, 86, 83, 54, 54, 128, 86, 83, 54, 53, 128, 86, 83, 54, 52, - 128, 86, 83, 54, 51, 128, 86, 83, 54, 50, 128, 86, 83, 54, 49, 128, 86, - 83, 54, 48, 128, 86, 83, 54, 128, 86, 83, 53, 57, 128, 86, 83, 53, 56, - 128, 86, 83, 53, 55, 128, 86, 83, 53, 54, 128, 86, 83, 53, 53, 128, 86, - 83, 53, 52, 128, 86, 83, 53, 51, 128, 86, 83, 53, 50, 128, 86, 83, 53, - 49, 128, 86, 83, 53, 48, 128, 86, 83, 53, 128, 86, 83, 52, 57, 128, 86, - 83, 52, 56, 128, 86, 83, 52, 55, 128, 86, 83, 52, 54, 128, 86, 83, 52, - 53, 128, 86, 83, 52, 52, 128, 86, 83, 52, 51, 128, 86, 83, 52, 50, 128, - 86, 83, 52, 49, 128, 86, 83, 52, 48, 128, 86, 83, 52, 128, 86, 83, 51, - 57, 128, 86, 83, 51, 56, 128, 86, 83, 51, 55, 128, 86, 83, 51, 54, 128, - 86, 83, 51, 53, 128, 86, 83, 51, 52, 128, 86, 83, 51, 51, 128, 86, 83, - 51, 50, 128, 86, 83, 51, 49, 128, 86, 83, 51, 48, 128, 86, 83, 51, 128, - 86, 83, 50, 57, 128, 86, 83, 50, 56, 128, 86, 83, 50, 55, 128, 86, 83, - 50, 54, 128, 86, 83, 50, 53, 54, 128, 86, 83, 50, 53, 53, 128, 86, 83, - 50, 53, 52, 128, 86, 83, 50, 53, 51, 128, 86, 83, 50, 53, 50, 128, 86, - 83, 50, 53, 49, 128, 86, 83, 50, 53, 48, 128, 86, 83, 50, 53, 128, 86, - 83, 50, 52, 57, 128, 86, 83, 50, 52, 56, 128, 86, 83, 50, 52, 55, 128, - 86, 83, 50, 52, 54, 128, 86, 83, 50, 52, 53, 128, 86, 83, 50, 52, 52, - 128, 86, 83, 50, 52, 51, 128, 86, 83, 50, 52, 50, 128, 86, 83, 50, 52, - 49, 128, 86, 83, 50, 52, 48, 128, 86, 83, 50, 52, 128, 86, 83, 50, 51, - 57, 128, 86, 83, 50, 51, 56, 128, 86, 83, 50, 51, 55, 128, 86, 83, 50, - 51, 54, 128, 86, 83, 50, 51, 53, 128, 86, 83, 50, 51, 52, 128, 86, 83, - 50, 51, 51, 128, 86, 83, 50, 51, 50, 128, 86, 83, 50, 51, 49, 128, 86, - 83, 50, 51, 48, 128, 86, 83, 50, 51, 128, 86, 83, 50, 50, 57, 128, 86, - 83, 50, 50, 56, 128, 86, 83, 50, 50, 55, 128, 86, 83, 50, 50, 54, 128, - 86, 83, 50, 50, 53, 128, 86, 83, 50, 50, 52, 128, 86, 83, 50, 50, 51, - 128, 86, 83, 50, 50, 50, 128, 86, 83, 50, 50, 49, 128, 86, 83, 50, 50, - 48, 128, 86, 83, 50, 50, 128, 86, 83, 50, 49, 57, 128, 86, 83, 50, 49, - 56, 128, 86, 83, 50, 49, 55, 128, 86, 83, 50, 49, 54, 128, 86, 83, 50, - 49, 53, 128, 86, 83, 50, 49, 52, 128, 86, 83, 50, 49, 51, 128, 86, 83, - 50, 49, 50, 128, 86, 83, 50, 49, 49, 128, 86, 83, 50, 49, 48, 128, 86, - 83, 50, 49, 128, 86, 83, 50, 48, 57, 128, 86, 83, 50, 48, 56, 128, 86, - 83, 50, 48, 55, 128, 86, 83, 50, 48, 54, 128, 86, 83, 50, 48, 53, 128, - 86, 83, 50, 48, 52, 128, 86, 83, 50, 48, 51, 128, 86, 83, 50, 48, 50, - 128, 86, 83, 50, 48, 49, 128, 86, 83, 50, 48, 48, 128, 86, 83, 50, 48, - 128, 86, 83, 50, 128, 86, 83, 49, 57, 57, 128, 86, 83, 49, 57, 56, 128, - 86, 83, 49, 57, 55, 128, 86, 83, 49, 57, 54, 128, 86, 83, 49, 57, 53, - 128, 86, 83, 49, 57, 52, 128, 86, 83, 49, 57, 51, 128, 86, 83, 49, 57, - 50, 128, 86, 83, 49, 57, 49, 128, 86, 83, 49, 57, 48, 128, 86, 83, 49, - 57, 128, 86, 83, 49, 56, 57, 128, 86, 83, 49, 56, 56, 128, 86, 83, 49, - 56, 55, 128, 86, 83, 49, 56, 54, 128, 86, 83, 49, 56, 53, 128, 86, 83, - 49, 56, 52, 128, 86, 83, 49, 56, 51, 128, 86, 83, 49, 56, 50, 128, 86, - 83, 49, 56, 49, 128, 86, 83, 49, 56, 48, 128, 86, 83, 49, 56, 128, 86, - 83, 49, 55, 57, 128, 86, 83, 49, 55, 56, 128, 86, 83, 49, 55, 55, 128, - 86, 83, 49, 55, 54, 128, 86, 83, 49, 55, 53, 128, 86, 83, 49, 55, 52, - 128, 86, 83, 49, 55, 51, 128, 86, 83, 49, 55, 50, 128, 86, 83, 49, 55, - 49, 128, 86, 83, 49, 55, 48, 128, 86, 83, 49, 55, 128, 86, 83, 49, 54, - 57, 128, 86, 83, 49, 54, 56, 128, 86, 83, 49, 54, 55, 128, 86, 83, 49, - 54, 54, 128, 86, 83, 49, 54, 53, 128, 86, 83, 49, 54, 52, 128, 86, 83, - 49, 54, 51, 128, 86, 83, 49, 54, 50, 128, 86, 83, 49, 54, 49, 128, 86, - 83, 49, 54, 48, 128, 86, 83, 49, 54, 128, 86, 83, 49, 53, 57, 128, 86, - 83, 49, 53, 56, 128, 86, 83, 49, 53, 55, 128, 86, 83, 49, 53, 54, 128, - 86, 83, 49, 53, 53, 128, 86, 83, 49, 53, 52, 128, 86, 83, 49, 53, 51, - 128, 86, 83, 49, 53, 50, 128, 86, 83, 49, 53, 49, 128, 86, 83, 49, 53, - 48, 128, 86, 83, 49, 53, 128, 86, 83, 49, 52, 57, 128, 86, 83, 49, 52, - 56, 128, 86, 83, 49, 52, 55, 128, 86, 83, 49, 52, 54, 128, 86, 83, 49, - 52, 53, 128, 86, 83, 49, 52, 52, 128, 86, 83, 49, 52, 51, 128, 86, 83, - 49, 52, 50, 128, 86, 83, 49, 52, 49, 128, 86, 83, 49, 52, 48, 128, 86, - 83, 49, 52, 128, 86, 83, 49, 51, 57, 128, 86, 83, 49, 51, 56, 128, 86, - 83, 49, 51, 55, 128, 86, 83, 49, 51, 54, 128, 86, 83, 49, 51, 53, 128, - 86, 83, 49, 51, 52, 128, 86, 83, 49, 51, 51, 128, 86, 83, 49, 51, 50, - 128, 86, 83, 49, 51, 49, 128, 86, 83, 49, 51, 48, 128, 86, 83, 49, 51, - 128, 86, 83, 49, 50, 57, 128, 86, 83, 49, 50, 56, 128, 86, 83, 49, 50, - 55, 128, 86, 83, 49, 50, 54, 128, 86, 83, 49, 50, 53, 128, 86, 83, 49, - 50, 52, 128, 86, 83, 49, 50, 51, 128, 86, 83, 49, 50, 50, 128, 86, 83, - 49, 50, 49, 128, 86, 83, 49, 50, 48, 128, 86, 83, 49, 50, 128, 86, 83, - 49, 49, 57, 128, 86, 83, 49, 49, 56, 128, 86, 83, 49, 49, 55, 128, 86, - 83, 49, 49, 54, 128, 86, 83, 49, 49, 53, 128, 86, 83, 49, 49, 52, 128, - 86, 83, 49, 49, 51, 128, 86, 83, 49, 49, 50, 128, 86, 83, 49, 49, 49, - 128, 86, 83, 49, 49, 48, 128, 86, 83, 49, 49, 128, 86, 83, 49, 48, 57, - 128, 86, 83, 49, 48, 56, 128, 86, 83, 49, 48, 55, 128, 86, 83, 49, 48, - 54, 128, 86, 83, 49, 48, 53, 128, 86, 83, 49, 48, 52, 128, 86, 83, 49, - 48, 51, 128, 86, 83, 49, 48, 50, 128, 86, 83, 49, 48, 49, 128, 86, 83, - 49, 48, 48, 128, 86, 83, 49, 48, 128, 86, 83, 49, 128, 86, 83, 128, 86, - 82, 65, 75, 72, 73, 89, 193, 86, 82, 65, 67, 72, 89, 128, 86, 81, 128, - 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73, 69, 210, 86, - 79, 87, 128, 86, 79, 85, 128, 86, 79, 84, 128, 86, 79, 211, 86, 79, 80, - 128, 86, 79, 79, 73, 128, 86, 79, 79, 128, 86, 79, 77, 73, 84, 73, 78, - 71, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, 86, 79, 76, 84, 65, - 71, 197, 86, 79, 76, 76, 69, 89, 66, 65, 76, 76, 128, 86, 79, 76, 67, 65, - 78, 79, 128, 86, 79, 76, 65, 80, 85, 203, 86, 79, 73, 68, 69, 196, 86, - 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, 73, 67, 69, 76, 69, - 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 68, 128, 86, 79, 67, 65, 76, - 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, - 89, 79, 128, 86, 73, 88, 128, 86, 73, 84, 82, 73, 79, 76, 45, 50, 128, - 86, 73, 84, 82, 73, 79, 76, 128, 86, 73, 84, 72, 75, 85, 81, 201, 86, 73, - 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, 73, 84, 128, 86, - 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, 71, 65, 89, 65, - 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, 71, 193, 86, - 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, 82, 71, 65, - 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, 79, 76, 73, - 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, 69, 71, 65, - 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, 69, 71, 65, - 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, 86, 73, 78, 128, 86, 73, 76, - 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 71, 73, 78, 84, 73, 76, 69, - 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, 73, 69, 87, - 69, 82, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, 78, 65, 77, - 69, 83, 197, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, 69, 80, 128, - 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, 74, 128, 86, - 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, 68, 69, 207, - 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, 66, 82, 65, 84, - 73, 79, 206, 86, 72, 65, 128, 86, 70, 65, 128, 86, 69, 89, 90, 128, 86, - 69, 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, 88, 128, 86, 69, - 85, 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, 69, 85, 65, 69, - 128, 86, 69, 83, 84, 65, 128, 86, 69, 83, 84, 128, 86, 69, 83, 83, 69, - 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, 65, 76, 76, 89, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, - 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 52, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 51, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, - 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 53, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 52, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, - 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 54, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 53, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, - 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 48, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 54, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, - 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 49, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 48, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, - 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 50, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 49, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, - 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 51, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 50, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, - 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 52, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 51, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, 86, 69, 82, - 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, 86, 69, 82, 71, 69, 128, - 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, 82, 128, 86, 69, 80, - 128, 86, 69, 78, 68, 128, 86, 69, 76, 73, 128, 86, 69, 73, 76, 128, 86, - 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, 69, 69, - 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, 86, 67, - 128, 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, 86, 128, - 86, 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, 84, 128, - 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, 65, 82, 89, - 211, 86, 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, 128, 86, - 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, 73, 193, - 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, 82, 65, 65, - 75, 65, 78, 128, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, 128, 86, - 65, 78, 69, 128, 86, 65, 77, 80, 73, 82, 69, 128, 86, 65, 77, 65, 71, 79, - 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, 72, 193, 86, - 65, 76, 76, 69, 89, 128, 86, 65, 75, 65, 73, 89, 65, 82, 65, 65, 128, 86, - 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, 86, 65, 200, 86, 65, 65, - 86, 85, 128, 86, 65, 65, 128, 86, 193, 86, 48, 52, 48, 65, 128, 86, 48, - 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, 86, 48, 51, 55, - 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, 48, 51, 53, 128, - 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, 51, 51, 128, 86, - 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, 49, 128, 86, 48, - 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, 65, 128, 86, 48, - 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, 128, 86, 48, 50, - 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, 48, 50, 52, 128, - 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, 50, 50, 128, 86, - 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, 48, 75, 128, 86, - 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, 50, 48, 72, 128, - 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, 48, 50, 48, 69, - 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, 86, 48, 50, 48, - 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, 86, 48, 49, 57, - 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, 49, 54, 128, 86, - 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, 128, 86, 48, 49, - 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, 128, 86, 48, 49, - 49, 68, 128, 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, - 49, 49, 65, 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, - 57, 128, 86, 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, - 65, 128, 86, 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, - 86, 48, 48, 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, - 48, 48, 50, 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, - 48, 48, 49, 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, - 86, 48, 48, 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, - 128, 86, 48, 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, - 90, 72, 65, 75, 75, 85, 128, 85, 90, 51, 128, 85, 90, 179, 85, 90, 128, - 85, 89, 71, 72, 85, 210, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, - 87, 85, 128, 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, - 85, 85, 51, 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, - 73, 128, 85, 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, - 128, 85, 83, 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, - 83, 72, 50, 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, - 69, 45, 50, 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, - 85, 82, 85, 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, - 85, 68, 193, 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, - 78, 69, 128, 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, - 83, 128, 85, 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, - 85, 80, 87, 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, - 65, 82, 68, 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, - 85, 80, 83, 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 83, - 73, 68, 69, 45, 68, 79, 87, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, - 69, 82, 128, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, 128, 85, 80, 45, - 80, 79, 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, 79, 71, 128, 85, - 78, 78, 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, - 78, 128, 85, 78, 75, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, - 73, 84, 89, 128, 85, 78, 73, 84, 69, 196, 85, 78, 73, 84, 128, 85, 78, - 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, 70, - 79, 82, 77, 128, 85, 78, 73, 70, 73, 69, 196, 85, 78, 73, 67, 79, 82, - 206, 85, 78, 69, 86, 69, 206, 85, 78, 68, 207, 85, 78, 68, 69, 82, 84, - 73, 69, 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, 69, 82, 68, - 79, 84, 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, 69, 82, - 128, 85, 78, 68, 69, 210, 85, 78, 67, 73, 193, 85, 78, 67, 69, 82, 84, - 65, 73, 78, 84, 217, 85, 78, 66, 76, 69, 78, 68, 69, 196, 85, 78, 65, 83, - 80, 73, 82, 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, - 83, 69, 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, - 205, 85, 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, - 193, 85, 77, 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, - 73, 65, 206, 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, - 85, 73, 90, 128, 85, 73, 88, 128, 85, 73, 85, 90, 128, 85, 73, 85, 88, - 128, 85, 73, 85, 81, 128, 85, 73, 85, 67, 128, 85, 73, 81, 128, 85, 73, - 76, 76, 69, 65, 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 73, 67, 128, - 85, 72, 68, 128, 85, 71, 65, 82, 73, 84, 73, 195, 85, 69, 90, 128, 85, - 69, 89, 128, 85, 69, 88, 128, 85, 69, 78, 128, 85, 69, 73, 128, 85, 69, - 69, 128, 85, 69, 67, 128, 85, 69, 65, 128, 85, 68, 85, 71, 128, 85, 68, - 65, 84, 84, 65, 128, 85, 68, 65, 84, 84, 193, 85, 68, 65, 82, 75, 65, - 128, 85, 68, 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 66, 85, 70, 73, - 76, 73, 128, 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, 65, 77, 65, - 128, 85, 66, 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, 85, 65, 128, - 85, 178, 85, 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, 52, 48, 128, - 85, 48, 51, 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, 128, 85, 48, - 51, 54, 128, 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, 48, 51, 51, - 128, 85, 48, 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, 51, 49, 128, - 85, 48, 51, 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, 57, 128, 85, - 48, 50, 56, 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, 85, 48, 50, - 53, 128, 85, 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, 48, 50, 51, - 128, 85, 48, 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, 48, 128, 85, - 48, 49, 57, 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, 85, 48, 49, - 54, 128, 85, 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, 49, 51, 128, - 85, 48, 49, 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, 128, 85, 48, - 48, 57, 128, 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, 48, 48, 54, - 66, 128, 85, 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, 48, 48, 53, - 128, 85, 48, 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, 50, 128, 85, - 48, 48, 49, 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, 45, 73, 45, 73, - 128, 85, 45, 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 128, - 85, 45, 53, 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, 79, 128, - 84, 90, 73, 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, 69, 128, - 84, 90, 65, 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, 84, 89, - 80, 69, 45, 183, 84, 89, 80, 69, 45, 54, 128, 84, 89, 80, 69, 45, 182, - 84, 89, 80, 69, 45, 53, 128, 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, - 52, 128, 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, 51, 128, 84, 89, - 80, 69, 45, 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 49, 45, 50, - 128, 84, 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, 84, 89, - 73, 128, 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, 84, 88, - 87, 86, 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 88, 65, 128, - 84, 87, 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, - 73, 82, 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, - 69, 65, 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 79, 45, 67, 73, 82, - 67, 76, 197, 84, 87, 73, 83, 84, 73, 78, 71, 128, 84, 87, 73, 83, 84, 69, - 196, 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, - 84, 87, 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 207, 84, 87, 69, 78, - 84, 89, 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, 45, 83, 73, - 88, 128, 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, 84, 87, 69, - 78, 84, 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 78, 73, 78, - 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, 87, 69, 78, - 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, - 197, 84, 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, - 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 128, 84, 87, - 69, 78, 84, 217, 84, 87, 69, 78, 84, 73, 69, 84, 72, 83, 128, 84, 87, 69, - 78, 84, 73, 69, 84, 72, 128, 84, 87, 69, 76, 86, 69, 45, 84, 72, 73, 82, - 84, 89, 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, 76, 86, 197, 84, - 87, 69, 76, 70, 84, 72, 83, 128, 84, 87, 69, 76, 70, 84, 72, 128, 84, 87, - 69, 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, 86, 82, 73, 68, 79, - 128, 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, 69, 68, 79, 128, 84, - 85, 88, 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, - 89, 128, 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, 128, 84, - 85, 82, 88, 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, 128, 84, - 85, 82, 79, 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, - 206, 84, 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, - 75, 69, 89, 128, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, - 210, 84, 85, 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, - 85, 79, 84, 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, - 89, 128, 84, 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 66, 76, 69, 210, - 84, 85, 77, 65, 69, 128, 84, 85, 77, 128, 84, 85, 205, 84, 85, 76, 73, - 80, 128, 84, 85, 75, 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, - 85, 71, 82, 73, 203, 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 66, - 69, 128, 84, 85, 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, - 128, 84, 85, 65, 69, 128, 84, 85, 45, 84, 79, 128, 84, 85, 45, 52, 128, - 84, 85, 45, 51, 128, 84, 85, 45, 50, 128, 84, 85, 45, 49, 128, 84, 213, - 84, 84, 85, 85, 128, 84, 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, - 65, 65, 71, 128, 84, 84, 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, - 65, 128, 84, 84, 83, 85, 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, - 84, 84, 83, 69, 69, 128, 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, - 84, 79, 79, 128, 84, 84, 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, - 69, 128, 84, 84, 72, 85, 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, - 128, 84, 84, 72, 73, 128, 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, - 84, 84, 72, 65, 65, 128, 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, - 84, 84, 69, 72, 69, 200, 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, - 69, 69, 128, 84, 84, 65, 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, - 84, 84, 65, 73, 128, 84, 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, - 69, 128, 84, 83, 87, 66, 128, 84, 83, 87, 65, 128, 84, 83, 86, 128, 84, - 83, 83, 69, 128, 84, 83, 83, 65, 128, 84, 83, 79, 214, 84, 83, 73, 85, - 128, 84, 83, 72, 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, - 72, 79, 79, 203, 84, 83, 72, 79, 79, 74, 128, 84, 83, 72, 69, 83, 128, - 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, 199, 84, 83, 72, 69, 69, 74, - 128, 84, 83, 72, 69, 128, 84, 83, 72, 65, 194, 84, 83, 72, 65, 128, 84, - 83, 69, 82, 69, 128, 84, 83, 69, 69, 66, 128, 84, 83, 65, 84, 193, 84, - 83, 65, 68, 73, 128, 84, 83, 65, 68, 201, 84, 83, 65, 66, 128, 84, 83, - 65, 65, 68, 73, 89, 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 82, 89, - 66, 76, 73, 79, 206, 84, 82, 89, 65, 83, 79, 83, 84, 82, 69, 76, 78, 65, - 89, 65, 128, 84, 82, 89, 65, 83, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, - 128, 84, 82, 89, 65, 83, 79, 71, 76, 65, 83, 78, 65, 89, 65, 128, 84, 82, - 89, 65, 83, 75, 65, 128, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, - 128, 84, 82, 85, 78, 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, - 128, 84, 82, 85, 77, 80, 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, - 84, 82, 85, 77, 80, 45, 55, 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, - 85, 77, 80, 45, 53, 128, 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, - 80, 45, 51, 128, 84, 82, 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, - 45, 50, 48, 128, 84, 82, 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, - 49, 57, 128, 84, 82, 85, 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, - 49, 55, 128, 84, 82, 85, 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, - 49, 53, 128, 84, 82, 85, 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, - 49, 51, 128, 84, 82, 85, 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, - 49, 49, 128, 84, 82, 85, 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, - 49, 128, 84, 82, 85, 69, 128, 84, 82, 85, 197, 84, 82, 85, 67, 75, 128, - 84, 82, 79, 80, 73, 67, 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, - 77, 73, 75, 79, 83, 89, 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, - 79, 80, 83, 73, 70, 73, 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, - 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, - 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, - 76, 89, 71, 73, 83, 77, 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, - 128, 84, 82, 79, 76, 76, 69, 89, 128, 84, 82, 79, 76, 76, 128, 84, 82, - 79, 75, 85, 84, 65, 83, 84, 201, 84, 82, 79, 69, 90, 69, 78, 73, 65, 206, - 84, 82, 73, 85, 77, 80, 72, 128, 84, 82, 73, 84, 79, 211, 84, 82, 73, 84, - 73, 77, 79, 82, 73, 79, 78, 128, 84, 82, 73, 83, 73, 77, 79, 85, 128, 84, - 82, 73, 83, 69, 77, 69, 128, 84, 82, 73, 80, 79, 68, 128, 84, 82, 73, 80, - 76, 73, 128, 84, 82, 73, 80, 76, 69, 128, 84, 82, 73, 80, 76, 197, 84, - 82, 73, 79, 206, 84, 82, 73, 76, 76, 73, 79, 78, 83, 128, 84, 82, 73, 76, - 76, 128, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, 65, 77, 77, - 79, 211, 84, 82, 73, 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, 71, 79, 78, - 128, 84, 82, 73, 70, 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, 79, 76, 73, - 65, 84, 197, 84, 82, 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, 69, 78, - 212, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, 85, 76, - 65, 210, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, 84, 82, - 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, 65, 78, - 71, 76, 69, 128, 84, 82, 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, 128, - 84, 82, 73, 128, 84, 82, 69, 83, 86, 69, 84, 76, 89, 128, 84, 82, 69, 83, - 86, 69, 84, 76, 79, 128, 84, 82, 69, 83, 86, 69, 84, 76, 65, 89, 65, 128, - 84, 82, 69, 83, 73, 76, 76, 79, 128, 84, 82, 69, 78, 68, 128, 84, 82, 69, - 78, 196, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, 82, 69, 77, 79, 76, - 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 69, - 128, 84, 82, 69, 197, 84, 82, 69, 68, 69, 67, 73, 76, 69, 128, 84, 82, - 69, 65, 68, 73, 78, 71, 128, 84, 82, 65, 89, 128, 84, 82, 65, 86, 69, 76, - 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 82, 65, 86, 69, 76, 45, 70, - 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 82, 65, 80, 69, 90, 73, 85, 77, - 128, 84, 82, 65, 80, 128, 84, 82, 65, 78, 83, 86, 69, 82, 83, 65, 204, - 84, 82, 65, 78, 83, 80, 79, 83, 73, 84, 73, 79, 206, 84, 82, 65, 78, 83, - 80, 76, 85, 84, 79, 128, 84, 82, 65, 78, 83, 77, 73, 212, 84, 82, 65, 78, - 83, 77, 73, 83, 83, 73, 79, 78, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, - 73, 79, 206, 84, 82, 65, 77, 87, 65, 89, 128, 84, 82, 65, 77, 128, 84, - 82, 65, 205, 84, 82, 65, 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, - 73, 76, 73, 78, 199, 84, 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, - 73, 195, 84, 82, 65, 68, 73, 84, 73, 79, 78, 65, 204, 84, 82, 65, 68, - 197, 84, 82, 65, 67, 84, 79, 82, 128, 84, 82, 65, 67, 75, 66, 65, 76, 76, - 128, 84, 82, 65, 67, 75, 128, 84, 82, 65, 128, 84, 82, 128, 84, 79, 89, - 79, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, 128, 84, 79, 87, 65, - 82, 68, 211, 84, 79, 86, 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, - 85, 67, 72, 84, 79, 78, 197, 84, 79, 85, 67, 72, 73, 78, 199, 84, 79, 85, - 67, 72, 69, 211, 84, 79, 85, 67, 200, 84, 79, 84, 207, 84, 79, 84, 65, - 204, 84, 79, 84, 128, 84, 79, 83, 128, 84, 79, 82, 84, 79, 73, 83, 197, - 84, 79, 82, 83, 79, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 79, 82, - 83, 79, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 79, 82, 83, 79, - 128, 84, 79, 82, 78, 65, 68, 79, 128, 84, 79, 82, 67, 85, 76, 85, 83, - 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, 128, 84, 79, - 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, 73, 71, 72, 84, - 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, 72, 66, 82, 85, - 83, 72, 128, 84, 79, 79, 84, 72, 128, 84, 79, 79, 78, 128, 84, 79, 79, - 76, 66, 79, 88, 128, 84, 79, 78, 79, 83, 128, 84, 79, 78, 71, 85, 69, - 128, 84, 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, 79, 78, 69, 45, - 86, 128, 84, 79, 78, 69, 45, 83, 128, 84, 79, 78, 69, 45, 77, 128, 84, - 79, 78, 69, 45, 74, 128, 84, 79, 78, 69, 45, 71, 128, 84, 79, 78, 69, 45, - 68, 128, 84, 79, 78, 69, 45, 66, 128, 84, 79, 78, 69, 45, 56, 128, 84, - 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, 128, 84, 79, 78, 69, 45, - 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, 51, 128, 84, - 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, 128, 84, 79, 78, 69, - 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, 84, 79, 77, 65, 84, - 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, 207, 84, 79, 73, - 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, 68, 207, - 84, 79, 67, 72, 75, 65, 128, 84, 79, 65, 78, 68, 65, 75, 72, 73, 65, 84, - 128, 84, 79, 65, 128, 84, 79, 45, 82, 65, 128, 84, 79, 45, 54, 128, 84, - 79, 45, 53, 128, 84, 79, 45, 52, 128, 84, 79, 45, 51, 128, 84, 79, 45, - 50, 128, 84, 79, 45, 49, 128, 84, 78, 128, 84, 76, 86, 128, 84, 76, 85, - 128, 84, 76, 73, 128, 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, 69, 128, - 84, 76, 72, 85, 128, 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, 128, 84, - 76, 72, 73, 128, 84, 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, 84, 76, - 72, 65, 128, 84, 76, 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, 128, 84, - 73, 88, 128, 84, 73, 87, 82, 128, 84, 73, 87, 78, 128, 84, 73, 87, 65, - 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, 73, 84, 76, 79, 128, 84, 73, - 84, 76, 207, 84, 73, 84, 193, 84, 73, 84, 128, 84, 73, 82, 89, 65, 75, - 128, 84, 73, 82, 84, 193, 84, 73, 82, 79, 78, 73, 65, 206, 84, 73, 82, - 72, 85, 84, 193, 84, 73, 82, 69, 196, 84, 73, 82, 128, 84, 73, 210, 84, - 73, 80, 80, 73, 128, 84, 73, 80, 69, 72, 65, 128, 84, 73, 80, 128, 84, - 73, 208, 84, 73, 78, 89, 128, 84, 73, 78, 217, 84, 73, 78, 78, 69, 128, - 84, 73, 78, 67, 84, 85, 82, 69, 128, 84, 73, 78, 65, 71, 77, 65, 128, 84, - 73, 77, 69, 83, 128, 84, 73, 77, 69, 210, 84, 73, 77, 69, 128, 84, 73, - 76, 84, 73, 78, 71, 128, 84, 73, 76, 84, 73, 78, 199, 84, 73, 76, 84, - 128, 84, 73, 76, 69, 83, 128, 84, 73, 76, 68, 69, 128, 84, 73, 76, 68, - 197, 84, 73, 76, 128, 84, 73, 204, 84, 73, 75, 72, 89, 128, 84, 73, 75, - 72, 65, 89, 65, 128, 84, 73, 75, 72, 65, 89, 193, 84, 73, 75, 69, 85, 84, - 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, 75, 69, 85, 84, 45, 83, 73, - 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 83, - 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 69, 85, 76, 128, 84, - 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 84, 73, 75, 69, 85, 84, - 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, 85, 84, 45, 75, 73, 89, 69, - 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, 73, 69, 85, 67, 128, 84, 73, - 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, 72, 128, 84, 73, 75, 69, 85, - 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, 71, 72, 84, 76, 89, 45, 67, 76, - 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, 73, 71, 69, 82, 128, 84, 73, - 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, 200, 84, 73, 69, 88, 128, 84, - 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, 75, 69, 84, 83, 128, 84, 73, - 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, 84, 73, 65, - 82, 65, 128, 84, 73, 50, 128, 84, 73, 45, 55, 128, 84, 73, 45, 54, 128, - 84, 73, 45, 53, 128, 84, 73, 45, 52, 128, 84, 73, 45, 51, 128, 84, 73, - 45, 50, 128, 84, 73, 45, 49, 128, 84, 72, 90, 128, 84, 72, 89, 79, 79, - 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, 73, 73, - 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, 65, 65, - 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, 73, 83, - 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, 84, 79, - 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, 69, - 210, 84, 72, 85, 77, 66, 211, 84, 72, 85, 77, 66, 128, 84, 72, 82, 79, - 87, 73, 78, 199, 84, 72, 82, 79, 85, 71, 72, 128, 84, 72, 82, 79, 85, 71, - 200, 84, 72, 82, 69, 69, 45, 84, 72, 73, 82, 84, 89, 128, 84, 72, 82, 69, - 69, 45, 81, 85, 65, 82, 84, 69, 210, 84, 72, 82, 69, 69, 45, 80, 69, 82, - 45, 69, 205, 84, 72, 82, 69, 69, 45, 76, 73, 78, 197, 84, 72, 82, 69, 69, - 45, 76, 69, 71, 71, 69, 196, 84, 72, 82, 69, 69, 45, 72, 85, 78, 68, 82, - 69, 68, 45, 65, 78, 68, 45, 84, 87, 69, 78, 84, 73, 69, 84, 72, 128, 84, - 72, 82, 69, 69, 45, 69, 205, 84, 72, 82, 69, 69, 45, 68, 79, 212, 84, 72, - 82, 69, 69, 45, 196, 84, 72, 82, 69, 69, 45, 67, 73, 82, 67, 76, 197, 84, - 72, 82, 69, 65, 68, 128, 84, 72, 79, 85, 83, 65, 78, 68, 83, 128, 84, 72, - 79, 85, 83, 65, 78, 68, 211, 84, 72, 79, 85, 83, 65, 78, 196, 84, 72, 79, - 85, 71, 72, 212, 84, 72, 79, 85, 128, 84, 72, 79, 82, 78, 128, 84, 72, - 79, 82, 206, 84, 72, 79, 78, 71, 128, 84, 72, 79, 78, 199, 84, 72, 79, - 77, 128, 84, 72, 79, 74, 128, 84, 72, 79, 65, 128, 84, 72, 207, 84, 72, - 73, 85, 84, 72, 128, 84, 72, 73, 84, 65, 128, 84, 72, 73, 82, 84, 89, 45, - 83, 69, 67, 79, 78, 68, 128, 84, 72, 73, 82, 84, 89, 45, 83, 69, 67, 79, - 78, 196, 84, 72, 73, 82, 84, 89, 45, 79, 78, 69, 128, 84, 72, 73, 82, 84, - 89, 45, 70, 73, 86, 197, 84, 72, 73, 82, 84, 217, 84, 72, 73, 82, 84, 69, - 69, 78, 128, 84, 72, 73, 82, 84, 69, 69, 206, 84, 72, 73, 82, 68, 83, - 128, 84, 72, 73, 82, 68, 211, 84, 72, 73, 82, 68, 45, 83, 84, 65, 71, - 197, 84, 72, 73, 82, 68, 128, 84, 72, 73, 82, 196, 84, 72, 73, 78, 75, - 73, 78, 199, 84, 72, 73, 78, 71, 128, 84, 72, 73, 73, 128, 84, 72, 73, - 71, 72, 128, 84, 72, 73, 69, 85, 84, 200, 84, 72, 73, 67, 203, 84, 72, - 73, 65, 66, 128, 84, 72, 69, 89, 128, 84, 72, 69, 84, 72, 69, 128, 84, - 72, 69, 84, 72, 128, 84, 72, 69, 84, 65, 128, 84, 72, 69, 84, 193, 84, - 72, 69, 83, 80, 73, 65, 206, 84, 72, 69, 83, 69, 79, 83, 128, 84, 72, 69, - 83, 69, 79, 211, 84, 72, 69, 211, 84, 72, 69, 82, 77, 79, 77, 69, 84, 69, - 82, 128, 84, 72, 69, 82, 77, 79, 68, 89, 78, 65, 77, 73, 67, 128, 84, 72, - 69, 82, 69, 70, 79, 82, 69, 128, 84, 72, 69, 82, 197, 84, 72, 69, 206, - 84, 72, 69, 77, 65, 84, 73, 83, 77, 79, 211, 84, 72, 69, 77, 65, 128, 84, - 72, 69, 77, 193, 84, 72, 69, 72, 128, 84, 72, 69, 200, 84, 72, 69, 65, - 128, 84, 72, 197, 84, 72, 65, 87, 128, 84, 72, 65, 78, 84, 72, 65, 75, - 72, 65, 84, 128, 84, 72, 65, 78, 78, 65, 128, 84, 72, 65, 78, 128, 84, - 72, 65, 206, 84, 72, 65, 77, 69, 68, 72, 128, 84, 72, 65, 76, 128, 84, - 72, 65, 204, 84, 72, 65, 74, 128, 84, 72, 65, 201, 84, 72, 65, 72, 65, - 78, 128, 84, 72, 65, 65, 78, 193, 84, 72, 65, 65, 76, 85, 128, 84, 72, - 45, 67, 82, 69, 197, 84, 69, 88, 84, 128, 84, 69, 88, 212, 84, 69, 88, - 128, 84, 69, 86, 73, 82, 128, 84, 69, 85, 84, 69, 85, 88, 128, 84, 69, - 85, 84, 69, 85, 87, 69, 78, 128, 84, 69, 85, 84, 128, 84, 69, 85, 78, - 128, 84, 69, 85, 65, 69, 81, 128, 84, 69, 85, 65, 69, 78, 128, 84, 69, - 85, 128, 84, 69, 84, 82, 65, 83, 73, 77, 79, 85, 128, 84, 69, 84, 82, 65, - 83, 69, 77, 69, 128, 84, 69, 84, 82, 65, 80, 76, 73, 128, 84, 69, 84, 82, - 65, 71, 82, 65, 205, 84, 69, 84, 82, 65, 70, 79, 78, 73, 65, 83, 128, 84, - 69, 84, 72, 128, 84, 69, 84, 200, 84, 69, 84, 65, 82, 84, 79, 211, 84, - 69, 84, 65, 82, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 69, 84, 128, 84, - 69, 212, 84, 69, 83, 212, 84, 69, 83, 83, 69, 82, 65, 128, 84, 69, 83, - 83, 69, 82, 193, 84, 69, 83, 83, 65, 82, 79, 206, 84, 69, 83, 200, 84, - 69, 82, 77, 73, 78, 65, 84, 79, 82, 128, 84, 69, 82, 77, 73, 78, 65, 204, - 84, 69, 80, 128, 84, 69, 78, 85, 84, 79, 128, 84, 69, 78, 85, 128, 84, - 69, 78, 213, 84, 69, 78, 84, 72, 128, 84, 69, 78, 84, 128, 84, 69, 78, - 83, 69, 128, 84, 69, 78, 83, 197, 84, 69, 78, 83, 128, 84, 69, 78, 211, - 84, 69, 78, 78, 73, 211, 84, 69, 78, 71, 197, 84, 69, 78, 45, 84, 72, 73, - 82, 84, 89, 128, 84, 69, 78, 128, 84, 69, 206, 84, 69, 77, 80, 85, 211, - 84, 69, 77, 80, 76, 69, 128, 84, 69, 76, 85, 71, 213, 84, 69, 76, 85, - 128, 84, 69, 76, 79, 85, 211, 84, 69, 76, 76, 69, 210, 84, 69, 76, 73, - 83, 72, 193, 84, 69, 76, 69, 86, 73, 83, 73, 79, 78, 128, 84, 69, 76, 69, - 83, 67, 79, 80, 69, 128, 84, 69, 76, 69, 80, 72, 79, 78, 69, 128, 84, 69, - 76, 69, 80, 72, 79, 78, 197, 84, 69, 76, 69, 73, 65, 128, 84, 69, 76, 69, - 71, 82, 65, 80, 200, 84, 69, 75, 128, 84, 69, 73, 87, 83, 128, 84, 69, - 71, 69, 72, 128, 84, 69, 69, 84, 72, 128, 84, 69, 69, 84, 200, 84, 69, - 69, 78, 83, 128, 84, 69, 69, 69, 69, 128, 84, 69, 197, 84, 69, 68, 85, - 78, 71, 128, 84, 69, 68, 68, 217, 84, 69, 65, 82, 83, 128, 84, 69, 65, - 82, 211, 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, 80, 79, 75, 69, 196, 84, - 69, 65, 82, 68, 82, 79, 80, 45, 83, 72, 65, 78, 75, 69, 196, 84, 69, 65, - 82, 68, 82, 79, 80, 45, 66, 65, 82, 66, 69, 196, 84, 69, 65, 82, 45, 79, - 70, 198, 84, 69, 65, 82, 128, 84, 69, 65, 80, 79, 84, 128, 84, 69, 65, - 67, 85, 208, 84, 69, 65, 128, 84, 69, 45, 85, 128, 84, 69, 45, 57, 128, - 84, 69, 45, 56, 128, 84, 69, 45, 55, 128, 84, 69, 45, 54, 128, 84, 69, - 45, 53, 128, 84, 69, 45, 52, 128, 84, 69, 45, 51, 128, 84, 69, 45, 50, - 128, 84, 69, 45, 49, 128, 84, 67, 72, 69, 72, 69, 72, 128, 84, 67, 72, - 69, 72, 69, 200, 84, 67, 72, 69, 72, 128, 84, 67, 72, 69, 200, 84, 67, - 72, 69, 128, 84, 195, 84, 65, 89, 128, 84, 65, 88, 73, 128, 84, 65, 88, - 128, 84, 65, 87, 69, 76, 76, 69, 77, 69, 212, 84, 65, 87, 65, 128, 84, - 65, 87, 128, 84, 65, 215, 84, 65, 86, 73, 89, 65, 78, 73, 128, 84, 65, - 86, 128, 84, 65, 214, 84, 65, 85, 82, 85, 83, 128, 84, 65, 85, 77, 128, - 84, 65, 213, 84, 65, 84, 87, 69, 69, 76, 128, 84, 65, 84, 87, 69, 69, - 204, 84, 65, 84, 84, 79, 79, 69, 196, 84, 65, 84, 128, 84, 65, 83, 83, - 73, 128, 84, 65, 83, 72, 69, 69, 76, 128, 84, 65, 83, 128, 84, 65, 82, - 85, 78, 71, 128, 84, 65, 82, 84, 65, 82, 45, 50, 128, 84, 65, 82, 84, 65, - 82, 128, 84, 65, 82, 71, 69, 84, 128, 84, 65, 81, 128, 84, 65, 80, 69, - 82, 128, 84, 65, 80, 197, 84, 65, 80, 128, 84, 65, 79, 128, 84, 65, 78, - 78, 69, 196, 84, 65, 78, 71, 83, 193, 84, 65, 78, 71, 69, 82, 73, 78, 69, - 128, 84, 65, 78, 71, 69, 78, 84, 128, 84, 65, 78, 71, 69, 78, 212, 84, - 65, 78, 199, 84, 65, 78, 65, 66, 65, 84, 193, 84, 65, 78, 65, 128, 84, - 65, 78, 128, 84, 65, 77, 73, 78, 71, 128, 84, 65, 77, 65, 206, 84, 65, - 77, 65, 76, 69, 128, 84, 65, 77, 128, 84, 65, 76, 76, 217, 84, 65, 76, - 76, 128, 84, 65, 76, 204, 84, 65, 76, 73, 78, 71, 128, 84, 65, 76, 73, - 78, 199, 84, 65, 76, 69, 78, 84, 83, 128, 84, 65, 76, 69, 78, 212, 84, - 65, 75, 82, 201, 84, 65, 75, 72, 65, 76, 76, 85, 83, 128, 84, 65, 75, 69, - 79, 85, 212, 84, 65, 75, 69, 128, 84, 65, 75, 52, 128, 84, 65, 75, 180, - 84, 65, 75, 128, 84, 65, 73, 83, 89, 79, 85, 128, 84, 65, 73, 76, 76, 69, - 83, 211, 84, 65, 73, 76, 128, 84, 65, 73, 204, 84, 65, 72, 65, 76, 65, - 128, 84, 65, 72, 128, 84, 65, 200, 84, 65, 71, 66, 65, 78, 87, 193, 84, - 65, 71, 65, 76, 79, 199, 84, 65, 71, 128, 84, 65, 199, 84, 65, 69, 206, - 84, 65, 67, 79, 128, 84, 65, 67, 75, 128, 84, 65, 67, 203, 84, 65, 66, - 85, 76, 65, 84, 73, 79, 78, 128, 84, 65, 66, 85, 76, 65, 84, 73, 79, 206, - 84, 65, 66, 83, 128, 84, 65, 66, 76, 69, 128, 84, 65, 66, 76, 197, 84, - 65, 66, 65, 65, 82, 65, 75, 193, 84, 65, 66, 128, 84, 65, 194, 84, 65, - 65, 83, 72, 65, 69, 128, 84, 65, 65, 81, 128, 84, 65, 65, 77, 128, 84, - 65, 65, 76, 85, 74, 193, 84, 65, 65, 73, 128, 84, 65, 65, 70, 128, 84, - 65, 50, 128, 84, 65, 45, 82, 79, 76, 128, 84, 65, 45, 52, 128, 84, 65, - 45, 51, 128, 84, 65, 45, 50, 128, 84, 65, 45, 49, 128, 84, 48, 51, 54, - 128, 84, 48, 51, 53, 128, 84, 48, 51, 52, 128, 84, 48, 51, 51, 65, 128, - 84, 48, 51, 51, 128, 84, 48, 51, 50, 65, 128, 84, 48, 51, 50, 128, 84, - 48, 51, 49, 128, 84, 48, 51, 48, 128, 84, 48, 50, 57, 128, 84, 48, 50, - 56, 128, 84, 48, 50, 55, 128, 84, 48, 50, 54, 128, 84, 48, 50, 53, 128, - 84, 48, 50, 52, 128, 84, 48, 50, 51, 128, 84, 48, 50, 50, 128, 84, 48, - 50, 49, 128, 84, 48, 50, 48, 128, 84, 48, 49, 57, 128, 84, 48, 49, 56, - 128, 84, 48, 49, 55, 128, 84, 48, 49, 54, 65, 128, 84, 48, 49, 54, 128, - 84, 48, 49, 53, 128, 84, 48, 49, 52, 128, 84, 48, 49, 51, 128, 84, 48, - 49, 50, 128, 84, 48, 49, 49, 65, 128, 84, 48, 49, 49, 128, 84, 48, 49, - 48, 128, 84, 48, 48, 57, 65, 128, 84, 48, 48, 57, 128, 84, 48, 48, 56, - 65, 128, 84, 48, 48, 56, 128, 84, 48, 48, 55, 65, 128, 84, 48, 48, 55, - 128, 84, 48, 48, 54, 128, 84, 48, 48, 53, 128, 84, 48, 48, 52, 128, 84, - 48, 48, 51, 65, 128, 84, 48, 48, 51, 128, 84, 48, 48, 50, 128, 84, 48, - 48, 49, 128, 84, 45, 83, 72, 73, 82, 84, 128, 84, 45, 82, 69, 88, 128, - 83, 90, 90, 128, 83, 90, 87, 71, 128, 83, 90, 87, 65, 128, 83, 90, 85, - 128, 83, 90, 79, 128, 83, 90, 73, 128, 83, 90, 69, 69, 128, 83, 90, 69, - 128, 83, 90, 65, 65, 128, 83, 90, 65, 128, 83, 90, 128, 83, 89, 88, 128, - 83, 89, 84, 128, 83, 89, 83, 84, 69, 205, 83, 89, 82, 88, 128, 83, 89, - 82, 77, 65, 84, 73, 75, 73, 128, 83, 89, 82, 77, 65, 128, 83, 89, 82, 73, - 78, 71, 69, 128, 83, 89, 82, 73, 65, 195, 83, 89, 82, 128, 83, 89, 80, - 128, 83, 89, 79, 85, 87, 65, 128, 83, 89, 78, 69, 86, 77, 65, 128, 83, - 89, 78, 68, 69, 83, 77, 79, 211, 83, 89, 78, 67, 72, 82, 79, 78, 79, 85, - 211, 83, 89, 78, 65, 71, 79, 71, 85, 69, 128, 83, 89, 78, 65, 71, 77, - 193, 83, 89, 78, 65, 70, 73, 128, 83, 89, 78, 128, 83, 89, 77, 77, 69, - 84, 82, 89, 128, 83, 89, 77, 77, 69, 84, 82, 73, 195, 83, 89, 77, 66, 79, - 76, 83, 128, 83, 89, 77, 66, 79, 76, 211, 83, 89, 77, 66, 79, 76, 45, 57, - 128, 83, 89, 77, 66, 79, 76, 45, 56, 128, 83, 89, 77, 66, 79, 76, 45, 55, - 128, 83, 89, 77, 66, 79, 76, 45, 54, 128, 83, 89, 77, 66, 79, 76, 45, 53, - 52, 128, 83, 89, 77, 66, 79, 76, 45, 53, 51, 128, 83, 89, 77, 66, 79, 76, - 45, 53, 50, 128, 83, 89, 77, 66, 79, 76, 45, 53, 49, 128, 83, 89, 77, 66, - 79, 76, 45, 53, 48, 128, 83, 89, 77, 66, 79, 76, 45, 53, 128, 83, 89, 77, - 66, 79, 76, 45, 52, 57, 128, 83, 89, 77, 66, 79, 76, 45, 52, 56, 128, 83, - 89, 77, 66, 79, 76, 45, 52, 55, 128, 83, 89, 77, 66, 79, 76, 45, 52, 53, - 128, 83, 89, 77, 66, 79, 76, 45, 52, 51, 128, 83, 89, 77, 66, 79, 76, 45, - 52, 50, 128, 83, 89, 77, 66, 79, 76, 45, 52, 48, 128, 83, 89, 77, 66, 79, - 76, 45, 52, 128, 83, 89, 77, 66, 79, 76, 45, 51, 57, 128, 83, 89, 77, 66, - 79, 76, 45, 51, 56, 128, 83, 89, 77, 66, 79, 76, 45, 51, 55, 128, 83, 89, - 77, 66, 79, 76, 45, 51, 54, 128, 83, 89, 77, 66, 79, 76, 45, 51, 50, 128, - 83, 89, 77, 66, 79, 76, 45, 51, 48, 128, 83, 89, 77, 66, 79, 76, 45, 51, - 128, 83, 89, 77, 66, 79, 76, 45, 50, 57, 128, 83, 89, 77, 66, 79, 76, 45, - 50, 55, 128, 83, 89, 77, 66, 79, 76, 45, 50, 54, 128, 83, 89, 77, 66, 79, - 76, 45, 50, 53, 128, 83, 89, 77, 66, 79, 76, 45, 50, 52, 128, 83, 89, 77, - 66, 79, 76, 45, 50, 51, 128, 83, 89, 77, 66, 79, 76, 45, 50, 50, 128, 83, - 89, 77, 66, 79, 76, 45, 50, 49, 128, 83, 89, 77, 66, 79, 76, 45, 50, 48, - 128, 83, 89, 77, 66, 79, 76, 45, 50, 128, 83, 89, 77, 66, 79, 76, 45, 49, - 57, 128, 83, 89, 77, 66, 79, 76, 45, 49, 56, 128, 83, 89, 77, 66, 79, 76, - 45, 49, 55, 128, 83, 89, 77, 66, 79, 76, 45, 49, 54, 128, 83, 89, 77, 66, - 79, 76, 45, 49, 53, 128, 83, 89, 77, 66, 79, 76, 45, 49, 52, 128, 83, 89, - 77, 66, 79, 76, 45, 49, 51, 128, 83, 89, 77, 66, 79, 76, 45, 49, 50, 128, - 83, 89, 77, 66, 79, 76, 45, 49, 49, 128, 83, 89, 77, 66, 79, 76, 45, 49, - 48, 128, 83, 89, 77, 66, 79, 76, 45, 49, 128, 83, 89, 76, 79, 84, 201, - 83, 89, 73, 128, 83, 89, 128, 83, 87, 90, 128, 83, 87, 85, 78, 199, 83, - 87, 79, 82, 68, 83, 128, 83, 87, 79, 82, 68, 128, 83, 87, 79, 79, 128, - 83, 87, 79, 128, 83, 87, 73, 82, 204, 83, 87, 73, 77, 83, 85, 73, 84, - 128, 83, 87, 73, 77, 77, 73, 78, 71, 128, 83, 87, 73, 77, 77, 69, 82, - 128, 83, 87, 73, 73, 128, 83, 87, 73, 128, 83, 87, 71, 128, 83, 87, 69, - 69, 84, 128, 83, 87, 69, 69, 212, 83, 87, 69, 65, 84, 128, 83, 87, 69, - 65, 212, 83, 87, 65, 83, 200, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, - 87, 65, 78, 128, 83, 87, 65, 65, 128, 83, 87, 128, 83, 86, 65, 83, 84, - 201, 83, 86, 65, 82, 73, 84, 65, 128, 83, 86, 65, 82, 73, 84, 193, 83, - 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, 85, 72, 128, 83, 85, 84, 82, - 193, 83, 85, 84, 128, 83, 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 85, - 83, 72, 73, 128, 83, 85, 82, 89, 65, 128, 83, 85, 82, 88, 128, 83, 85, - 82, 82, 79, 85, 78, 68, 128, 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, 82, - 70, 69, 82, 128, 83, 85, 82, 70, 65, 67, 197, 83, 85, 82, 69, 128, 83, - 85, 82, 65, 78, 71, 128, 83, 85, 82, 57, 128, 83, 85, 82, 128, 83, 85, - 210, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, 86, - 73, 83, 69, 128, 83, 85, 80, 69, 82, 86, 73, 76, 76, 65, 73, 78, 128, 83, - 85, 80, 69, 82, 83, 69, 84, 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, 85, - 80, 69, 82, 83, 67, 82, 73, 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, 79, - 83, 69, 196, 83, 85, 80, 69, 82, 72, 69, 82, 79, 128, 83, 85, 80, 69, 82, - 70, 73, 88, 69, 196, 83, 85, 80, 69, 210, 83, 85, 80, 128, 83, 85, 79, - 88, 128, 83, 85, 79, 80, 128, 83, 85, 79, 128, 83, 85, 78, 83, 69, 212, - 83, 85, 78, 82, 73, 83, 69, 128, 83, 85, 78, 82, 73, 83, 197, 83, 85, 78, - 71, 76, 65, 83, 83, 69, 83, 128, 83, 85, 78, 71, 128, 83, 85, 78, 70, 76, - 79, 87, 69, 82, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, 78, - 128, 83, 85, 206, 83, 85, 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, - 73, 79, 78, 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, - 72, 128, 83, 85, 77, 128, 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, - 78, 128, 83, 85, 75, 85, 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, - 85, 73, 84, 65, 66, 76, 69, 128, 83, 85, 73, 212, 83, 85, 72, 85, 82, - 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, - 75, 73, 78, 199, 83, 85, 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, - 67, 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, - 67, 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, - 84, 128, 83, 85, 66, 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, - 72, 69, 83, 72, 73, 199, 83, 72, 69, 83, 72, 50, 128, 83, 72, 69, 83, 72, - 128, 83, 72, 69, 83, 200, 83, 72, 69, 81, 69, 204, 83, 72, 69, 80, 128, - 83, 72, 69, 78, 128, 83, 72, 69, 76, 76, 128, 83, 72, 69, 76, 204, 83, - 72, 69, 76, 70, 128, 83, 72, 69, 73, 128, 83, 72, 69, 71, 57, 128, 83, - 72, 69, 69, 80, 128, 83, 72, 69, 69, 78, 85, 128, 83, 72, 69, 69, 78, - 128, 83, 72, 69, 69, 206, 83, 72, 69, 69, 128, 83, 72, 69, 45, 71, 79, - 65, 84, 128, 83, 72, 197, 83, 72, 67, 72, 79, 79, 73, 128, 83, 72, 67, - 72, 65, 128, 83, 72, 65, 89, 128, 83, 72, 65, 88, 128, 83, 72, 65, 86, - 73, 89, 65, 78, 73, 128, 83, 72, 65, 86, 73, 65, 206, 83, 72, 65, 86, 69, - 196, 83, 72, 65, 85, 128, 83, 72, 65, 84, 128, 83, 72, 65, 82, 85, 128, - 83, 72, 65, 82, 213, 83, 72, 65, 82, 80, 128, 83, 72, 65, 82, 208, 83, - 72, 65, 82, 75, 128, 83, 72, 65, 82, 65, 68, 193, 83, 72, 65, 82, 65, - 128, 83, 72, 65, 82, 50, 128, 83, 72, 65, 82, 178, 83, 72, 65, 80, 73, - 78, 71, 128, 83, 72, 65, 80, 69, 83, 128, 83, 72, 65, 80, 197, 83, 72, - 65, 80, 128, 83, 72, 65, 78, 71, 128, 83, 72, 65, 78, 128, 83, 72, 65, - 206, 83, 72, 65, 77, 82, 79, 67, 75, 128, 83, 72, 65, 76, 83, 72, 69, 76, - 69, 84, 128, 83, 72, 65, 76, 76, 79, 215, 83, 72, 65, 75, 84, 73, 128, - 83, 72, 65, 75, 73, 78, 71, 128, 83, 72, 65, 75, 73, 78, 199, 83, 72, 65, - 75, 69, 82, 128, 83, 72, 65, 75, 128, 83, 72, 65, 73, 128, 83, 72, 65, - 70, 84, 128, 83, 72, 65, 70, 212, 83, 72, 65, 68, 79, 87, 69, 196, 83, - 72, 65, 68, 69, 196, 83, 72, 65, 68, 69, 128, 83, 72, 65, 68, 197, 83, - 72, 65, 68, 68, 65, 128, 83, 72, 65, 68, 68, 193, 83, 72, 65, 68, 128, - 83, 72, 65, 196, 83, 72, 65, 66, 54, 128, 83, 72, 65, 65, 128, 83, 72, - 65, 54, 128, 83, 72, 65, 182, 83, 72, 65, 51, 128, 83, 72, 65, 179, 83, - 71, 82, 193, 83, 71, 79, 210, 83, 71, 67, 128, 83, 71, 65, 215, 83, 71, - 65, 194, 83, 71, 128, 83, 69, 89, 75, 128, 83, 69, 88, 84, 85, 76, 193, - 83, 69, 88, 84, 73, 76, 69, 128, 83, 69, 88, 84, 65, 78, 84, 45, 54, 128, - 83, 69, 88, 84, 65, 78, 84, 45, 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 53, 128, 83, 69, 88, 84, 65, 78, 84, 45, 52, 54, 128, 83, 69, 88, 84, - 65, 78, 84, 45, 52, 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 52, 53, - 128, 83, 69, 88, 84, 65, 78, 84, 45, 52, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 51, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 51, 53, 54, 128, 83, 69, - 88, 84, 65, 78, 84, 45, 51, 53, 128, 83, 69, 88, 84, 65, 78, 84, 45, 51, - 52, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 51, 52, 53, 54, 128, 83, 69, - 88, 84, 65, 78, 84, 45, 51, 52, 53, 128, 83, 69, 88, 84, 65, 78, 84, 45, - 51, 52, 128, 83, 69, 88, 84, 65, 78, 84, 45, 51, 128, 83, 69, 88, 84, 65, - 78, 84, 45, 50, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 50, 53, 54, 128, - 83, 69, 88, 84, 65, 78, 84, 45, 50, 53, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 50, 52, 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 50, 52, 53, 128, - 83, 69, 88, 84, 65, 78, 84, 45, 50, 52, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 50, 51, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 50, 51, 53, 54, 128, - 83, 69, 88, 84, 65, 78, 84, 45, 50, 51, 53, 128, 83, 69, 88, 84, 65, 78, - 84, 45, 50, 51, 52, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 50, 51, 52, - 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 50, 51, 52, 53, 128, 83, 69, - 88, 84, 65, 78, 84, 45, 50, 51, 52, 128, 83, 69, 88, 84, 65, 78, 84, 45, - 50, 51, 128, 83, 69, 88, 84, 65, 78, 84, 45, 50, 128, 83, 69, 88, 84, 65, - 78, 84, 45, 49, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 53, 54, 128, - 83, 69, 88, 84, 65, 78, 84, 45, 49, 53, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 49, 52, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 52, 53, 54, 128, - 83, 69, 88, 84, 65, 78, 84, 45, 49, 52, 53, 128, 83, 69, 88, 84, 65, 78, - 84, 45, 49, 52, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 51, 54, 128, 83, - 69, 88, 84, 65, 78, 84, 45, 49, 51, 53, 54, 128, 83, 69, 88, 84, 65, 78, - 84, 45, 49, 51, 52, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 51, 52, - 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 51, 52, 53, 128, 83, 69, - 88, 84, 65, 78, 84, 45, 49, 51, 52, 128, 83, 69, 88, 84, 65, 78, 84, 45, - 49, 51, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, 54, 128, 83, 69, 88, - 84, 65, 78, 84, 45, 49, 50, 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, - 49, 50, 53, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, 52, 54, 128, 83, - 69, 88, 84, 65, 78, 84, 45, 49, 50, 52, 53, 54, 128, 83, 69, 88, 84, 65, - 78, 84, 45, 49, 50, 52, 53, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, - 52, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, 51, 54, 128, 83, 69, 88, - 84, 65, 78, 84, 45, 49, 50, 51, 53, 54, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 49, 50, 51, 53, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, 51, 52, - 54, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, 51, 52, 53, 128, 83, 69, - 88, 84, 65, 78, 84, 45, 49, 50, 51, 52, 128, 83, 69, 88, 84, 65, 78, 84, - 45, 49, 50, 51, 128, 83, 69, 88, 84, 65, 78, 84, 45, 49, 50, 128, 83, 69, - 88, 84, 65, 78, 84, 45, 49, 128, 83, 69, 88, 84, 65, 78, 211, 83, 69, 87, - 73, 78, 199, 83, 69, 86, 69, 82, 65, 78, 67, 69, 128, 83, 69, 86, 69, 78, - 84, 89, 128, 83, 69, 86, 69, 78, 84, 217, 83, 69, 86, 69, 78, 84, 72, - 128, 83, 69, 86, 69, 78, 84, 69, 69, 78, 128, 83, 69, 86, 69, 78, 84, 69, - 69, 206, 83, 69, 86, 69, 78, 45, 84, 72, 73, 82, 84, 89, 128, 83, 69, 86, - 69, 206, 83, 69, 85, 88, 128, 83, 69, 85, 78, 89, 65, 77, 128, 83, 69, - 85, 65, 69, 81, 128, 83, 69, 84, 70, 79, 78, 128, 83, 69, 83, 84, 69, 82, - 84, 73, 85, 211, 83, 69, 83, 81, 85, 73, 81, 85, 65, 68, 82, 65, 84, 69, - 128, 83, 69, 83, 65, 77, 197, 83, 69, 82, 86, 73, 67, 197, 83, 69, 82, - 73, 79, 85, 211, 83, 69, 82, 73, 70, 83, 128, 83, 69, 82, 73, 70, 211, - 83, 69, 82, 73, 70, 128, 83, 69, 81, 85, 69, 78, 84, 73, 65, 76, 128, 83, - 69, 81, 85, 69, 78, 67, 197, 83, 69, 80, 84, 85, 80, 76, 197, 83, 69, 80, - 84, 69, 77, 66, 69, 82, 128, 83, 69, 80, 65, 82, 65, 84, 79, 82, 128, 83, - 69, 80, 65, 82, 65, 84, 79, 210, 83, 69, 80, 65, 82, 65, 84, 69, 196, 83, - 69, 78, 84, 79, 128, 83, 69, 78, 84, 73, 128, 83, 69, 78, 84, 65, 71, 79, - 78, 128, 83, 69, 77, 85, 78, 67, 73, 193, 83, 69, 77, 75, 65, 84, 72, - 128, 83, 69, 77, 75, 128, 83, 69, 77, 73, 86, 79, 87, 69, 204, 83, 69, - 77, 73, 83, 79, 70, 212, 83, 69, 77, 73, 83, 69, 88, 84, 73, 76, 69, 128, - 83, 69, 77, 73, 77, 73, 78, 73, 77, 193, 83, 69, 77, 73, 68, 73, 82, 69, - 67, 212, 83, 69, 77, 73, 67, 79, 76, 79, 78, 128, 83, 69, 77, 73, 67, 79, - 76, 79, 206, 83, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 210, 83, 69, 77, - 73, 67, 73, 82, 67, 76, 197, 83, 69, 77, 73, 66, 82, 69, 86, 73, 211, 83, - 69, 77, 73, 45, 86, 79, 73, 67, 69, 196, 83, 69, 76, 70, 73, 69, 128, 83, - 69, 76, 70, 128, 83, 69, 76, 69, 78, 65, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 57, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 56, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 57, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 53, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 57, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 50, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 55, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 56, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 52, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 56, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 49, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 56, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 57, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 55, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 54, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 55, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 51, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 55, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 48, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, - 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 56, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, - 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 53, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 54, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, - 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 50, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, - 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 56, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 55, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 53, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 52, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 50, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 49, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 57, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 55, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 54, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 52, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 51, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 49, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 48, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 57, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 54, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 51, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 48, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 56, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 54, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 53, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, - 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 50, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 57, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, - 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 54, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 52, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 51, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 50, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, - 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 55, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 54, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, - 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 51, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 50, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 50, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 48, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, - 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 55, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 50, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 50, 50, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 52, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 51, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 48, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 50, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 56, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 55, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 52, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 51, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, - 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 48, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 56, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 55, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 48, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, - 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 52, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 48, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 49, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 48, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 57, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 57, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 54, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 57, 53, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 51, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 50, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 55, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 54, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 51, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 50, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, - 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 55, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 55, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 54, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, - 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 51, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 55, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 48, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, - 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 55, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 54, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 52, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 51, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 48, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 56, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 55, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 52, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 49, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 48, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 56, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 52, 55, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 53, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 52, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 49, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 48, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 57, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 56, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 51, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 53, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 52, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, - 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 49, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 57, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 56, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, - 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 53, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 50, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 49, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 57, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 54, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 53, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 50, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 49, 49, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 57, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 48, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 48, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 54, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 48, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 51, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 50, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 48, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 48, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 128, - 83, 69, 76, 69, 67, 84, 79, 210, 83, 69, 76, 69, 67, 84, 69, 196, 83, 69, - 73, 83, 77, 65, 128, 83, 69, 73, 83, 77, 193, 83, 69, 72, 128, 83, 69, - 71, 79, 76, 128, 83, 69, 71, 78, 79, 128, 83, 69, 71, 77, 69, 78, 84, 69, - 196, 83, 69, 71, 77, 69, 78, 84, 128, 83, 69, 69, 86, 128, 83, 69, 69, - 78, 85, 128, 83, 69, 69, 78, 128, 83, 69, 69, 206, 83, 69, 69, 68, 76, - 73, 78, 71, 128, 83, 69, 69, 45, 78, 79, 45, 69, 86, 73, 204, 83, 69, 68, - 78, 65, 128, 83, 69, 67, 84, 79, 82, 128, 83, 69, 67, 84, 73, 79, 78, - 128, 83, 69, 67, 84, 73, 79, 206, 83, 69, 67, 82, 69, 84, 128, 83, 69, - 67, 65, 78, 84, 128, 83, 69, 66, 65, 84, 66, 69, 73, 212, 83, 69, 65, 84, - 128, 83, 69, 65, 76, 128, 83, 69, 65, 71, 85, 76, 204, 83, 69, 45, 53, - 128, 83, 69, 45, 52, 128, 83, 69, 45, 51, 128, 83, 68, 79, 78, 199, 83, - 68, 128, 83, 67, 87, 65, 128, 83, 67, 82, 85, 80, 76, 69, 128, 83, 67, - 82, 79, 76, 76, 128, 83, 67, 82, 73, 80, 84, 128, 83, 67, 82, 69, 87, 68, - 82, 73, 86, 69, 82, 128, 83, 67, 82, 69, 69, 78, 128, 83, 67, 82, 69, 69, - 206, 83, 67, 82, 69, 65, 77, 73, 78, 199, 83, 67, 79, 84, 211, 83, 67, - 79, 82, 80, 73, 85, 83, 128, 83, 67, 79, 82, 80, 73, 79, 78, 128, 83, 67, - 79, 82, 69, 128, 83, 67, 79, 79, 84, 69, 82, 128, 83, 67, 73, 83, 83, 79, - 82, 83, 128, 83, 67, 73, 128, 83, 67, 72, 87, 65, 128, 83, 67, 72, 87, - 193, 83, 67, 72, 82, 79, 69, 68, 69, 82, 128, 83, 67, 72, 79, 79, 76, - 128, 83, 67, 72, 79, 79, 204, 83, 67, 72, 79, 76, 65, 82, 128, 83, 67, - 72, 69, 77, 193, 83, 67, 69, 80, 84, 69, 210, 83, 67, 65, 82, 70, 128, - 83, 67, 65, 78, 68, 73, 67, 85, 83, 128, 83, 67, 65, 78, 68, 73, 67, 85, - 211, 83, 67, 65, 206, 83, 67, 65, 76, 69, 83, 128, 83, 66, 85, 194, 83, - 66, 82, 85, 204, 83, 65, 89, 73, 83, 201, 83, 65, 89, 65, 78, 78, 65, - 128, 83, 65, 89, 128, 83, 65, 88, 79, 80, 72, 79, 78, 69, 128, 83, 65, - 88, 73, 77, 65, 84, 65, 128, 83, 65, 87, 65, 78, 128, 83, 65, 87, 128, - 83, 65, 86, 79, 85, 82, 73, 78, 199, 83, 65, 85, 82, 79, 80, 79, 68, 128, - 83, 65, 85, 82, 65, 83, 72, 84, 82, 193, 83, 65, 85, 73, 76, 128, 83, 65, - 85, 67, 69, 82, 128, 83, 65, 84, 85, 82, 78, 128, 83, 65, 84, 75, 65, 65, - 78, 75, 85, 85, 128, 83, 65, 84, 75, 65, 65, 78, 128, 83, 65, 84, 69, 76, - 76, 73, 84, 69, 128, 83, 65, 84, 69, 76, 76, 73, 84, 197, 83, 65, 84, 67, - 72, 69, 76, 128, 83, 65, 84, 65, 78, 71, 65, 128, 83, 65, 83, 72, 128, - 83, 65, 83, 65, 75, 128, 83, 65, 82, 73, 128, 83, 65, 82, 193, 83, 65, - 82, 128, 83, 65, 81, 128, 83, 65, 80, 65, 128, 83, 65, 78, 89, 79, 79, - 71, 193, 83, 65, 78, 89, 65, 75, 193, 83, 65, 78, 84, 73, 73, 77, 85, - 128, 83, 65, 78, 83, 75, 82, 73, 212, 83, 65, 78, 78, 89, 65, 128, 83, - 65, 78, 71, 65, 50, 128, 83, 65, 78, 68, 87, 73, 67, 72, 128, 83, 65, 78, - 68, 72, 201, 83, 65, 78, 68, 65, 76, 128, 83, 65, 78, 65, 72, 128, 83, - 65, 78, 128, 83, 65, 77, 89, 79, 203, 83, 65, 77, 86, 65, 84, 128, 83, - 65, 77, 80, 73, 128, 83, 65, 77, 80, 72, 65, 79, 128, 83, 65, 77, 75, 65, - 128, 83, 65, 77, 69, 75, 72, 128, 83, 65, 77, 69, 75, 200, 83, 65, 77, - 66, 65, 128, 83, 65, 77, 65, 82, 73, 84, 65, 206, 83, 65, 77, 128, 83, - 65, 76, 85, 84, 73, 78, 199, 83, 65, 76, 84, 73, 82, 69, 128, 83, 65, 76, - 84, 73, 82, 197, 83, 65, 76, 84, 73, 76, 76, 79, 128, 83, 65, 76, 84, 45, - 50, 128, 83, 65, 76, 84, 128, 83, 65, 76, 212, 83, 65, 76, 76, 65, 76, - 76, 65, 72, 213, 83, 65, 76, 76, 65, 76, 76, 65, 72, 79, 213, 83, 65, 76, - 76, 65, 76, 76, 65, 65, 72, 213, 83, 65, 76, 76, 193, 83, 65, 76, 65, - 205, 83, 65, 76, 65, 68, 128, 83, 65, 76, 65, 65, 77, 85, 72, 213, 83, - 65, 76, 65, 128, 83, 65, 76, 45, 65, 77, 77, 79, 78, 73, 65, 67, 128, 83, - 65, 76, 128, 83, 65, 75, 84, 65, 128, 83, 65, 75, 79, 84, 128, 83, 65, - 75, 73, 78, 128, 83, 65, 75, 72, 193, 83, 65, 75, 69, 85, 65, 69, 128, - 83, 65, 75, 197, 83, 65, 74, 68, 65, 72, 128, 83, 65, 73, 76, 66, 79, 65, - 84, 128, 83, 65, 73, 76, 128, 83, 65, 73, 75, 85, 82, 85, 128, 83, 65, - 72, 128, 83, 65, 71, 73, 84, 84, 65, 82, 73, 85, 83, 128, 83, 65, 71, 65, - 128, 83, 65, 71, 128, 83, 65, 199, 83, 65, 70, 72, 65, 128, 83, 65, 70, - 69, 84, 217, 83, 65, 68, 72, 69, 128, 83, 65, 68, 72, 197, 83, 65, 68, - 69, 128, 83, 65, 68, 128, 83, 65, 196, 83, 65, 67, 82, 73, 70, 73, 67, - 73, 65, 204, 83, 65, 65, 73, 128, 83, 65, 65, 68, 72, 85, 128, 83, 65, - 45, 73, 128, 83, 65, 45, 56, 128, 83, 65, 45, 55, 128, 83, 65, 45, 54, - 128, 83, 65, 45, 53, 128, 83, 65, 45, 52, 128, 83, 65, 45, 51, 128, 83, - 65, 45, 50, 128, 83, 65, 45, 49, 128, 83, 48, 52, 54, 128, 83, 48, 52, - 53, 128, 83, 48, 52, 52, 128, 83, 48, 52, 51, 128, 83, 48, 52, 50, 128, - 83, 48, 52, 49, 128, 83, 48, 52, 48, 128, 83, 48, 51, 57, 128, 83, 48, - 51, 56, 128, 83, 48, 51, 55, 128, 83, 48, 51, 54, 128, 83, 48, 51, 53, - 65, 128, 83, 48, 51, 53, 128, 83, 48, 51, 52, 128, 83, 48, 51, 51, 128, - 83, 48, 51, 50, 128, 83, 48, 51, 49, 128, 83, 48, 51, 48, 128, 83, 48, - 50, 57, 128, 83, 48, 50, 56, 128, 83, 48, 50, 55, 128, 83, 48, 50, 54, - 66, 128, 83, 48, 50, 54, 65, 128, 83, 48, 50, 54, 128, 83, 48, 50, 53, - 128, 83, 48, 50, 52, 128, 83, 48, 50, 51, 128, 83, 48, 50, 50, 128, 83, - 48, 50, 49, 128, 83, 48, 50, 48, 128, 83, 48, 49, 57, 128, 83, 48, 49, - 56, 128, 83, 48, 49, 55, 65, 128, 83, 48, 49, 55, 128, 83, 48, 49, 54, - 128, 83, 48, 49, 53, 128, 83, 48, 49, 52, 66, 128, 83, 48, 49, 52, 65, - 128, 83, 48, 49, 52, 128, 83, 48, 49, 51, 128, 83, 48, 49, 50, 128, 83, - 48, 49, 49, 128, 83, 48, 49, 48, 128, 83, 48, 48, 57, 128, 83, 48, 48, - 56, 128, 83, 48, 48, 55, 128, 83, 48, 48, 54, 65, 128, 83, 48, 48, 54, - 128, 83, 48, 48, 53, 128, 83, 48, 48, 52, 128, 83, 48, 48, 51, 128, 83, - 48, 48, 50, 65, 128, 83, 48, 48, 50, 128, 83, 48, 48, 49, 128, 83, 45, - 87, 128, 83, 45, 83, 72, 65, 80, 69, 196, 82, 89, 89, 128, 82, 89, 88, - 128, 82, 89, 84, 128, 82, 89, 82, 88, 128, 82, 89, 82, 128, 82, 89, 80, - 128, 82, 87, 79, 79, 128, 82, 87, 79, 128, 82, 87, 73, 73, 128, 82, 87, - 73, 128, 82, 87, 69, 69, 128, 82, 87, 69, 128, 82, 87, 65, 72, 65, 128, - 82, 87, 65, 65, 128, 82, 87, 65, 128, 82, 85, 88, 128, 82, 85, 85, 66, - 85, 82, 85, 128, 82, 85, 85, 128, 82, 85, 84, 128, 82, 85, 83, 83, 73, - 65, 206, 82, 85, 83, 73, 128, 82, 85, 82, 88, 128, 82, 85, 82, 128, 82, - 85, 80, 73, 73, 128, 82, 85, 80, 69, 197, 82, 85, 80, 128, 82, 85, 79, - 88, 128, 82, 85, 79, 80, 128, 82, 85, 79, 128, 82, 85, 78, 79, 85, 84, - 128, 82, 85, 78, 78, 73, 78, 199, 82, 85, 78, 78, 69, 82, 128, 82, 85, - 78, 73, 195, 82, 85, 78, 128, 82, 85, 77, 201, 82, 85, 77, 65, 201, 82, - 85, 77, 128, 82, 85, 205, 82, 85, 76, 69, 82, 128, 82, 85, 76, 69, 45, - 68, 69, 76, 65, 89, 69, 68, 128, 82, 85, 76, 69, 128, 82, 85, 76, 65, 73, - 128, 82, 85, 75, 75, 65, 75, 72, 65, 128, 82, 85, 73, 83, 128, 82, 85, - 71, 66, 217, 82, 85, 68, 73, 77, 69, 78, 84, 193, 82, 85, 66, 76, 197, - 82, 85, 194, 82, 85, 65, 128, 82, 85, 45, 54, 128, 82, 85, 45, 53, 128, - 82, 85, 45, 52, 128, 82, 85, 45, 51, 128, 82, 85, 45, 50, 128, 82, 85, - 45, 49, 128, 82, 84, 72, 65, 78, 199, 82, 84, 69, 128, 82, 84, 65, 71, - 83, 128, 82, 84, 65, 71, 211, 82, 82, 89, 88, 128, 82, 82, 89, 84, 128, - 82, 82, 89, 82, 88, 128, 82, 82, 89, 82, 128, 82, 82, 89, 80, 128, 82, - 82, 85, 88, 128, 82, 82, 85, 85, 128, 82, 82, 85, 84, 128, 82, 82, 85, - 82, 88, 128, 82, 82, 85, 82, 128, 82, 82, 85, 80, 128, 82, 82, 85, 79, - 88, 128, 82, 82, 85, 79, 128, 82, 82, 85, 128, 82, 82, 82, 65, 128, 82, - 82, 79, 88, 128, 82, 82, 79, 84, 128, 82, 82, 79, 80, 128, 82, 82, 79, - 79, 128, 82, 82, 79, 128, 82, 82, 73, 73, 128, 82, 82, 73, 128, 82, 82, - 69, 88, 128, 82, 82, 69, 84, 128, 82, 82, 69, 80, 128, 82, 82, 69, 72, - 128, 82, 82, 69, 200, 82, 82, 69, 69, 128, 82, 82, 69, 128, 82, 82, 65, - 88, 128, 82, 82, 65, 85, 128, 82, 82, 65, 73, 128, 82, 82, 65, 65, 128, - 82, 79, 87, 66, 79, 65, 84, 128, 82, 79, 85, 78, 68, 69, 196, 82, 79, 85, - 78, 68, 45, 84, 73, 80, 80, 69, 196, 82, 79, 84, 85, 78, 68, 65, 128, 82, - 79, 84, 65, 84, 73, 79, 78, 83, 128, 82, 79, 84, 65, 84, 73, 79, 78, 45, - 87, 65, 76, 76, 80, 76, 65, 78, 197, 82, 79, 84, 65, 84, 73, 79, 78, 45, - 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 82, 79, 84, 65, 84, 73, 79, 78, - 128, 82, 79, 84, 65, 84, 73, 79, 206, 82, 79, 84, 65, 84, 69, 196, 82, - 79, 83, 72, 128, 82, 79, 83, 69, 84, 84, 69, 128, 82, 79, 83, 69, 128, - 82, 79, 79, 84, 128, 82, 79, 79, 83, 84, 69, 82, 128, 82, 79, 79, 77, - 128, 82, 79, 79, 75, 128, 82, 79, 79, 203, 82, 79, 79, 70, 128, 82, 79, - 77, 65, 78, 73, 65, 206, 82, 79, 77, 65, 206, 82, 79, 77, 128, 82, 79, - 76, 76, 73, 78, 199, 82, 79, 76, 76, 69, 210, 82, 79, 76, 76, 69, 68, 45, - 85, 208, 82, 79, 76, 204, 82, 79, 72, 73, 78, 71, 89, 193, 82, 79, 71, - 79, 77, 128, 82, 79, 71, 128, 82, 79, 196, 82, 79, 67, 75, 69, 84, 128, - 82, 79, 67, 203, 82, 79, 67, 128, 82, 79, 66, 79, 212, 82, 79, 66, 65, - 84, 128, 82, 79, 65, 83, 84, 69, 196, 82, 79, 65, 82, 128, 82, 79, 65, - 128, 82, 79, 45, 54, 128, 82, 79, 45, 53, 128, 82, 79, 45, 52, 128, 82, - 79, 45, 51, 128, 82, 79, 45, 50, 128, 82, 79, 45, 49, 128, 82, 78, 89, - 73, 78, 199, 82, 78, 79, 79, 78, 128, 82, 78, 79, 79, 206, 82, 78, 65, - 205, 82, 77, 84, 128, 82, 76, 79, 128, 82, 76, 77, 128, 82, 76, 73, 128, - 82, 76, 69, 128, 82, 74, 69, 211, 82, 74, 69, 128, 82, 74, 197, 82, 73, - 84, 85, 65, 76, 128, 82, 73, 84, 84, 79, 82, 85, 128, 82, 73, 84, 83, 73, - 128, 82, 73, 83, 73, 78, 199, 82, 73, 83, 72, 128, 82, 73, 82, 65, 128, - 82, 73, 80, 80, 76, 197, 82, 73, 80, 128, 82, 73, 78, 71, 211, 82, 73, - 78, 71, 73, 78, 199, 82, 73, 78, 71, 69, 196, 82, 73, 78, 70, 79, 82, 90, - 65, 78, 68, 79, 128, 82, 73, 206, 82, 73, 77, 71, 66, 65, 128, 82, 73, - 77, 128, 82, 73, 75, 82, 73, 75, 128, 82, 73, 71, 86, 69, 68, 73, 195, - 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 128, 82, 73, 71, 72, 84, 72, 65, - 78, 196, 82, 73, 71, 72, 84, 45, 84, 79, 45, 76, 69, 70, 212, 82, 73, 71, - 72, 84, 45, 83, 73, 68, 197, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 79, - 87, 69, 196, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 69, 196, 82, 73, 71, - 72, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 82, 73, 71, 72, 84, 45, 76, - 73, 71, 72, 84, 69, 196, 82, 73, 71, 72, 84, 45, 72, 65, 78, 68, 69, 196, - 82, 73, 71, 72, 84, 45, 72, 65, 78, 196, 82, 73, 71, 72, 84, 45, 70, 65, - 67, 73, 78, 199, 82, 73, 70, 76, 69, 128, 82, 73, 69, 85, 76, 45, 89, 69, - 83, 73, 69, 85, 78, 71, 128, 82, 73, 69, 85, 76, 45, 89, 69, 79, 82, 73, - 78, 72, 73, 69, 85, 72, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, - 45, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, - 45, 84, 73, 75, 69, 85, 84, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, - 76, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 84, 72, 73, - 69, 85, 84, 72, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 84, 73, - 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 83, 73, - 79, 83, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, - 80, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, - 75, 128, 82, 73, 69, 85, 76, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, - 45, 80, 73, 69, 85, 80, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, - 76, 45, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, - 45, 80, 73, 69, 85, 80, 45, 80, 72, 73, 69, 85, 80, 72, 128, 82, 73, 69, - 85, 76, 45, 80, 73, 69, 85, 80, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, - 85, 76, 45, 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 80, 72, 73, - 69, 85, 80, 72, 128, 82, 73, 69, 85, 76, 45, 80, 65, 78, 83, 73, 79, 83, - 128, 82, 73, 69, 85, 76, 45, 78, 73, 69, 85, 78, 128, 82, 73, 69, 85, 76, - 45, 77, 73, 69, 85, 77, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, - 77, 73, 69, 85, 77, 45, 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, - 45, 77, 73, 69, 85, 77, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, - 45, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 45, 75, 73, 89, 69, 79, - 75, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 75, 73, 89, 69, 79, - 75, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, 75, 73, 89, 69, - 79, 75, 128, 82, 73, 69, 85, 76, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, - 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 72, 73, 69, 85, 72, 128, 82, - 73, 69, 85, 76, 45, 67, 73, 69, 85, 67, 128, 82, 73, 69, 85, 204, 82, 73, - 69, 76, 128, 82, 73, 69, 69, 128, 82, 73, 67, 75, 83, 72, 65, 87, 128, - 82, 73, 67, 69, 77, 128, 82, 73, 67, 69, 128, 82, 73, 67, 197, 82, 73, - 66, 66, 79, 78, 128, 82, 73, 66, 66, 79, 206, 82, 73, 65, 204, 82, 73, - 45, 55, 128, 82, 73, 45, 54, 128, 82, 73, 45, 53, 128, 82, 73, 45, 52, - 128, 82, 73, 45, 51, 128, 82, 73, 45, 50, 128, 82, 73, 45, 49, 128, 82, - 72, 79, 84, 73, 195, 82, 72, 79, 128, 82, 72, 207, 82, 72, 73, 78, 79, - 67, 69, 82, 79, 83, 128, 82, 72, 65, 128, 82, 72, 128, 82, 71, 89, 73, - 78, 71, 83, 128, 82, 71, 89, 65, 78, 128, 82, 71, 89, 193, 82, 69, 86, - 79, 76, 86, 73, 78, 199, 82, 69, 86, 79, 76, 85, 84, 73, 79, 78, 128, 82, - 69, 86, 77, 65, 128, 82, 69, 86, 73, 65, 128, 82, 69, 86, 69, 82, 83, 69, - 68, 45, 83, 67, 72, 87, 65, 128, 82, 69, 86, 69, 82, 83, 69, 68, 128, 82, - 69, 86, 69, 82, 83, 69, 196, 82, 69, 86, 69, 82, 83, 197, 82, 69, 85, 88, - 128, 82, 69, 85, 128, 82, 69, 84, 85, 82, 78, 128, 82, 69, 84, 85, 82, - 206, 82, 69, 84, 82, 79, 70, 76, 69, 216, 82, 69, 84, 82, 69, 65, 84, - 128, 82, 69, 84, 79, 82, 84, 128, 82, 69, 83, 85, 80, 73, 78, 85, 83, - 128, 82, 69, 83, 84, 82, 79, 79, 77, 128, 82, 69, 83, 84, 82, 73, 67, 84, - 69, 196, 82, 69, 83, 84, 128, 82, 69, 83, 80, 79, 78, 83, 69, 128, 82, - 69, 83, 79, 85, 82, 67, 69, 128, 82, 69, 83, 79, 76, 85, 84, 73, 79, 78, - 128, 82, 69, 83, 73, 83, 84, 65, 78, 67, 69, 128, 82, 69, 83, 73, 68, 69, - 78, 67, 69, 128, 82, 69, 83, 72, 45, 65, 89, 73, 78, 45, 68, 65, 76, 69, - 84, 72, 128, 82, 69, 83, 72, 45, 65, 89, 73, 78, 128, 82, 69, 83, 200, - 82, 69, 82, 69, 78, 71, 71, 65, 78, 128, 82, 69, 82, 69, 75, 65, 78, 128, - 82, 69, 80, 82, 69, 83, 69, 78, 84, 128, 82, 69, 80, 76, 65, 67, 69, 77, - 69, 78, 212, 82, 69, 80, 72, 65, 128, 82, 69, 80, 72, 128, 82, 69, 80, - 69, 84, 73, 84, 73, 79, 206, 82, 69, 80, 69, 65, 84, 69, 196, 82, 69, 80, - 69, 65, 84, 128, 82, 69, 80, 69, 65, 212, 82, 69, 80, 65, 89, 65, 128, - 82, 69, 80, 65, 128, 82, 69, 80, 193, 82, 69, 78, 84, 79, 71, 69, 78, - 128, 82, 69, 78, 128, 82, 69, 206, 82, 69, 77, 85, 128, 82, 69, 77, 73, - 78, 68, 69, 210, 82, 69, 77, 69, 68, 89, 128, 82, 69, 76, 73, 71, 73, 79, - 78, 128, 82, 69, 76, 73, 69, 86, 69, 196, 82, 69, 76, 69, 65, 83, 69, - 128, 82, 69, 76, 65, 88, 69, 68, 128, 82, 69, 76, 65, 84, 73, 79, 78, 65, - 204, 82, 69, 76, 65, 84, 73, 79, 78, 128, 82, 69, 76, 65, 65, 128, 82, - 69, 74, 65, 78, 199, 82, 69, 73, 87, 65, 128, 82, 69, 73, 196, 82, 69, - 73, 128, 82, 69, 71, 85, 76, 85, 83, 45, 52, 128, 82, 69, 71, 85, 76, 85, - 83, 45, 51, 128, 82, 69, 71, 85, 76, 85, 83, 45, 50, 128, 82, 69, 71, 85, - 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, 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, - 69, 82, 83, 79, 78, 128, 80, 69, 82, 83, 79, 206, 80, 69, 82, 83, 73, 65, - 206, 80, 69, 82, 83, 69, 86, 69, 82, 73, 78, 199, 80, 69, 82, 80, 69, 78, - 68, 73, 67, 85, 76, 65, 82, 128, 80, 69, 82, 80, 69, 78, 68, 73, 67, 85, - 76, 65, 210, 80, 69, 82, 78, 73, 206, 80, 69, 82, 77, 73, 84, 84, 69, - 196, 80, 69, 82, 77, 73, 195, 80, 69, 82, 77, 65, 78, 69, 78, 212, 80, - 69, 82, 73, 83, 80, 79, 77, 69, 78, 73, 128, 80, 69, 82, 73, 83, 80, 79, - 77, 69, 78, 201, 80, 69, 82, 70, 79, 82, 77, 73, 78, 199, 80, 69, 82, 70, - 69, 67, 84, 85, 205, 80, 69, 82, 70, 69, 67, 84, 65, 128, 80, 69, 82, 70, - 69, 67, 84, 193, 80, 69, 82, 69, 86, 79, 68, 75, 65, 128, 80, 69, 82, 69, - 86, 79, 68, 75, 193, 80, 69, 82, 67, 85, 83, 83, 73, 86, 69, 128, 80, 69, - 82, 67, 69, 78, 212, 80, 69, 80, 80, 69, 82, 128, 80, 69, 80, 69, 84, - 128, 80, 69, 80, 69, 212, 80, 69, 79, 82, 84, 200, 80, 69, 79, 80, 76, - 69, 128, 80, 69, 79, 80, 76, 197, 80, 69, 78, 84, 65, 84, 72, 76, 79, 78, - 128, 80, 69, 78, 84, 65, 83, 69, 77, 69, 128, 80, 69, 78, 84, 65, 71, 82, - 65, 77, 128, 80, 69, 78, 84, 65, 71, 79, 78, 128, 80, 69, 78, 83, 85, - 128, 80, 69, 78, 83, 73, 86, 197, 80, 69, 78, 78, 217, 80, 69, 78, 78, - 65, 78, 84, 128, 80, 69, 78, 73, 72, 73, 128, 80, 69, 78, 71, 85, 73, 78, - 128, 80, 69, 78, 71, 75, 65, 76, 128, 80, 69, 78, 69, 84, 82, 65, 84, 73, - 79, 78, 128, 80, 69, 78, 67, 73, 76, 128, 80, 69, 206, 80, 69, 76, 65, - 83, 84, 79, 78, 128, 80, 69, 76, 65, 83, 84, 79, 206, 80, 69, 73, 84, 72, - 128, 80, 69, 72, 69, 72, 128, 80, 69, 72, 69, 200, 80, 69, 72, 128, 80, - 69, 200, 80, 69, 69, 90, 73, 128, 80, 69, 69, 83, 72, 73, 128, 80, 69, - 69, 80, 128, 80, 69, 69, 77, 128, 80, 69, 69, 75, 73, 78, 199, 80, 69, - 69, 73, 128, 80, 69, 69, 128, 80, 69, 68, 69, 83, 84, 82, 73, 65, 78, 83, - 128, 80, 69, 68, 69, 83, 84, 82, 73, 65, 78, 128, 80, 69, 68, 69, 83, 84, - 65, 76, 128, 80, 69, 68, 69, 83, 84, 65, 204, 80, 69, 68, 65, 204, 80, - 69, 65, 78, 85, 84, 83, 128, 80, 69, 65, 75, 211, 80, 69, 65, 67, 79, 67, - 75, 128, 80, 69, 65, 67, 72, 128, 80, 69, 65, 67, 69, 128, 80, 69, 65, - 67, 197, 80, 69, 193, 80, 68, 73, 128, 80, 68, 70, 128, 80, 68, 128, 80, - 67, 128, 80, 65, 90, 69, 82, 128, 80, 65, 89, 69, 82, 79, 75, 128, 80, - 65, 89, 65, 78, 78, 65, 128, 80, 65, 89, 128, 80, 65, 88, 128, 80, 65, - 87, 78, 128, 80, 65, 87, 206, 80, 65, 215, 80, 65, 86, 73, 89, 65, 78, - 73, 128, 80, 65, 85, 83, 197, 80, 65, 85, 75, 128, 80, 65, 85, 128, 80, - 65, 213, 80, 65, 84, 84, 217, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, - 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 65, 84, 72, 65, 75, 75, 85, 128, - 80, 65, 84, 200, 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, 72, 128, 80, - 65, 84, 128, 80, 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, 79, 82, 212, - 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, 45, 79, 85, - 84, 80, 85, 212, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 68, - 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 77, 66, 65, - 78, 71, 128, 80, 65, 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, 83, 69, - 196, 80, 65, 83, 72, 84, 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, - 83, 69, 81, 128, 80, 65, 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, - 128, 80, 65, 82, 84, 217, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, - 80, 65, 82, 84, 73, 65, 76, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, - 80, 65, 82, 84, 73, 65, 204, 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, - 212, 80, 65, 82, 82, 79, 84, 128, 80, 65, 82, 75, 128, 80, 65, 82, 73, - 67, 72, 79, 78, 128, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 206, - 80, 65, 82, 69, 82, 69, 78, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, - 83, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 80, 65, 82, 69, 78, - 84, 72, 69, 83, 69, 211, 80, 65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 65, - 82, 65, 76, 76, 69, 76, 79, 71, 82, 65, 77, 128, 80, 65, 82, 65, 76, 76, - 69, 76, 128, 80, 65, 82, 65, 76, 76, 69, 204, 80, 65, 82, 65, 75, 76, 73, - 84, 73, 75, 73, 128, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 201, 80, 65, - 82, 65, 75, 76, 73, 84, 128, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, - 80, 65, 82, 65, 71, 82, 65, 80, 72, 85, 211, 80, 65, 82, 65, 71, 82, 65, - 80, 72, 79, 83, 128, 80, 65, 82, 65, 71, 82, 65, 80, 72, 128, 80, 65, 82, - 65, 71, 82, 65, 80, 200, 80, 65, 82, 65, 67, 72, 85, 84, 69, 128, 80, 65, - 82, 65, 128, 80, 65, 82, 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, - 80, 69, 82, 67, 76, 73, 80, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, - 128, 80, 65, 80, 69, 82, 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, - 65, 208, 80, 65, 207, 80, 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, - 73, 75, 85, 128, 80, 65, 78, 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, - 78, 71, 71, 65, 128, 80, 65, 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, - 73, 128, 80, 65, 78, 84, 201, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, 69, - 85, 80, 128, 80, 65, 78, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, - 78, 80, 73, 69, 85, 80, 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, 128, - 80, 65, 78, 79, 76, 79, 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, 68, - 128, 80, 65, 78, 71, 82, 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, 79, - 76, 65, 84, 128, 80, 65, 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, 76, - 65, 89, 65, 82, 128, 80, 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, 75, - 65, 84, 128, 80, 65, 78, 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, 128, - 80, 65, 78, 69, 85, 76, 69, 85, 78, 71, 128, 80, 65, 78, 68, 193, 80, 65, - 78, 67, 65, 75, 69, 83, 128, 80, 65, 78, 65, 77, 128, 80, 65, 78, 65, 69, - 76, 65, 69, 78, 71, 128, 80, 65, 78, 128, 80, 65, 206, 80, 65, 77, 85, - 78, 71, 75, 65, 72, 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 77, - 83, 72, 65, 69, 128, 80, 65, 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, 77, - 73, 78, 71, 75, 65, 76, 128, 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, 77, - 69, 78, 69, 78, 71, 128, 80, 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, 68, - 193, 80, 65, 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, 80, - 65, 76, 79, 67, 72, 75, 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, 80, - 65, 76, 77, 211, 80, 65, 76, 77, 128, 80, 65, 76, 205, 80, 65, 76, 76, - 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 75, 65, 128, - 80, 65, 76, 201, 80, 65, 76, 69, 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, - 199, 80, 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, - 76, 73, 90, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, - 75, 80, 65, 203, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, - 84, 72, 82, 65, 128, 80, 65, 73, 82, 69, 196, 80, 65, 73, 78, 84, 66, 82, - 85, 83, 72, 128, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, - 72, 128, 80, 65, 71, 79, 68, 65, 128, 80, 65, 71, 69, 83, 128, 80, 65, - 71, 69, 82, 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, 68, 68, - 76, 197, 80, 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, - 80, 65, 67, 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, - 65, 84, 85, 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, - 77, 128, 80, 65, 65, 82, 65, 69, 128, 80, 65, 65, 77, 128, 80, 65, 65, - 73, 128, 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 65, 65, 128, 80, - 50, 128, 80, 48, 49, 49, 128, 80, 48, 49, 48, 128, 80, 48, 48, 57, 128, - 80, 48, 48, 56, 128, 80, 48, 48, 55, 128, 80, 48, 48, 54, 128, 80, 48, - 48, 53, 128, 80, 48, 48, 52, 128, 80, 48, 48, 51, 65, 128, 80, 48, 48, - 51, 128, 80, 48, 48, 50, 128, 80, 48, 48, 49, 65, 128, 80, 48, 48, 49, - 128, 79, 90, 128, 79, 89, 83, 84, 69, 82, 128, 79, 89, 82, 65, 78, 73, - 83, 77, 193, 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, - 73, 193, 79, 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 87, 76, 128, - 79, 86, 69, 82, 83, 84, 82, 85, 67, 203, 79, 86, 69, 82, 82, 73, 68, 69, - 128, 79, 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, - 128, 79, 86, 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 217, 79, - 86, 69, 82, 76, 65, 80, 80, 73, 78, 199, 79, 86, 69, 82, 76, 65, 80, 128, - 79, 86, 69, 82, 76, 65, 73, 68, 128, 79, 86, 69, 82, 76, 65, 73, 196, 79, - 86, 69, 82, 72, 69, 65, 84, 69, 196, 79, 86, 69, 82, 66, 65, 82, 128, 79, - 86, 65, 76, 128, 79, 86, 65, 204, 79, 85, 84, 76, 73, 78, 69, 196, 79, - 85, 84, 76, 73, 78, 69, 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, - 216, 79, 85, 78, 75, 73, 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, - 197, 79, 84, 85, 128, 79, 84, 84, 79, 77, 65, 206, 79, 84, 84, 69, 82, - 128, 79, 84, 84, 65, 86, 193, 79, 84, 84, 128, 79, 84, 83, 69, 67, 72, - 75, 65, 128, 79, 84, 72, 69, 82, 211, 79, 84, 72, 69, 210, 79, 84, 72, - 65, 76, 65, 206, 79, 84, 72, 65, 76, 128, 79, 83, 79, 75, 65, 128, 79, - 83, 79, 75, 193, 79, 83, 77, 65, 78, 89, 193, 79, 83, 67, 128, 79, 83, - 65, 71, 197, 79, 82, 84, 72, 79, 71, 79, 78, 65, 204, 79, 82, 84, 72, 79, - 68, 79, 216, 79, 82, 78, 65, 84, 197, 79, 82, 78, 65, 77, 69, 78, 84, 83, - 128, 79, 82, 78, 65, 77, 69, 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, - 212, 79, 82, 75, 72, 79, 206, 79, 82, 73, 89, 193, 79, 82, 73, 71, 73, - 78, 65, 204, 79, 82, 73, 71, 73, 78, 128, 79, 82, 69, 45, 50, 128, 79, - 82, 68, 73, 78, 65, 204, 79, 82, 68, 69, 210, 79, 82, 67, 85, 83, 128, - 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, 71, 85, 84, 65, 78, 128, 79, - 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, 206, 79, 80, 84, 73, 67, 65, - 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, - 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, 78, 199, 79, 80, 80, 79, 83, - 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, 128, 79, 80, 69, 82, 65, 84, - 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, 210, 79, 80, 69, 82, 65, 84, 73, - 78, 199, 79, 80, 69, 78, 73, 78, 199, 79, 80, 69, 78, 45, 80, 128, 79, - 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, 69, 196, 79, 80, 69, 78, 45, 79, - 128, 79, 80, 69, 78, 45, 207, 79, 80, 69, 78, 45, 72, 69, 65, 68, 69, - 196, 79, 80, 69, 78, 45, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, 80, - 85, 212, 79, 80, 69, 78, 128, 79, 80, 69, 206, 79, 79, 90, 69, 128, 79, - 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, 85, 128, 79, - 79, 72, 128, 79, 79, 69, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, - 79, 78, 85, 128, 79, 78, 83, 85, 128, 79, 78, 78, 128, 79, 78, 75, 65, - 82, 128, 79, 78, 73, 79, 78, 128, 79, 78, 69, 83, 69, 76, 70, 128, 79, - 78, 69, 45, 87, 65, 217, 79, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 79, - 78, 69, 45, 80, 73, 69, 67, 197, 79, 78, 69, 45, 76, 73, 78, 197, 79, 78, - 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, 83, 73, 88, 84, - 73, 69, 84, 72, 128, 79, 78, 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, - 128, 79, 78, 45, 79, 70, 198, 79, 77, 73, 83, 83, 73, 79, 206, 79, 77, - 73, 67, 82, 79, 78, 128, 79, 77, 73, 67, 82, 79, 206, 79, 77, 69, 84, - 128, 79, 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, 79, 77, 65, 76, 79, - 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, 206, 79, 76, 68, - 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, 65, 82, 193, 79, - 74, 79, 68, 128, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, - 79, 73, 78, 128, 79, 73, 76, 128, 79, 73, 204, 79, 72, 77, 128, 79, 72, - 205, 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, 71, 79, 78, - 69, 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, 128, 79, 70, - 70, 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, 128, 79, 69, - 89, 128, 79, 69, 82, 128, 79, 69, 75, 128, 79, 69, 69, 128, 79, 68, 69, - 78, 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, 85, 83, 128, - 79, 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, 67, 84, 65, 71, - 79, 78, 65, 204, 79, 67, 84, 65, 71, 79, 78, 128, 79, 67, 210, 79, 67, - 76, 79, 67, 75, 128, 79, 67, 72, 75, 79, 77, 128, 79, 67, 67, 85, 76, 84, - 65, 84, 73, 79, 78, 128, 79, 67, 67, 76, 85, 83, 73, 79, 78, 128, 79, 66, - 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 79, 66, 83, 69, 82, 86, 69, 210, - 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, 70, 73, 76, 73, 128, - 79, 66, 76, 73, 81, 85, 197, 79, 66, 76, 65, 75, 79, 128, 79, 66, 76, 65, - 67, 72, 75, 79, 128, 79, 66, 74, 69, 67, 212, 79, 66, 69, 76, 85, 83, - 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, 65, 89, 128, 79, 65, - 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, 79, 193, 79, 48, 53, - 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, 65, 128, 79, 48, 53, - 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, 79, 48, 52, 55, 128, - 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, 52, 52, 128, 79, 48, - 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, 128, 79, 48, 52, 48, - 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, 48, 51, 55, 128, 79, - 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, 48, 51, 54, 66, 128, - 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, 48, 51, 53, 128, 79, - 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, 51, 51, 128, 79, 48, - 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, 65, 128, 79, 48, 51, - 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, 128, 79, 48, 50, 56, - 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, 48, 50, 53, 65, 128, - 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, 48, 50, 52, 128, 79, - 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, 49, 128, 79, 48, 50, - 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, 65, 128, 79, 48, 49, - 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, 79, 48, 49, 54, 128, - 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, 49, 51, 128, 79, 48, - 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, 67, 128, 79, 48, 49, - 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, 48, 128, 79, 48, 48, - 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, 79, 48, 48, 54, 70, - 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, 128, 79, 48, 48, 54, - 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, 65, 128, 79, 48, 48, - 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, 128, 79, 48, 48, 52, - 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, 48, 48, 49, 65, 128, - 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, 79, 45, 73, 128, 79, - 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, 128, 78, 90, 89, 82, - 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, 78, 90, 89, 128, 78, - 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, 85, 82, 128, 78, 90, - 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, 88, 128, 78, 90, 85, - 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, 79, 88, 128, 78, 90, - 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, 128, 78, 90, 73, 80, - 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, 128, 78, 90, 73, 69, - 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, 69, 85, 77, 128, 78, - 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, 128, 78, 90, 65, 81, - 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, 193, 78, 89, 87, 65, - 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, 89, 85, 84, 128, 78, - 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, 85, 79, 80, 128, 78, - 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, 85, 69, 128, 78, 89, 85, - 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, 78, 89, 79, 80, 128, 78, - 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, 79, 65, 128, 78, 89, 79, - 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, 78, 89, 73, 84, 128, 78, - 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, 78, 89, 73, 80, 128, 78, - 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, 128, 78, 89, 73, 73, 128, - 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, 78, 89, 73, 69, 80, - 128, 78, 89, 73, 69, 128, 78, 89, 73, 65, 75, 69, 78, 199, 78, 89, 73, - 128, 78, 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, 128, 78, 89, 69, - 212, 78, 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, 69, 200, 78, 89, - 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, 65, 128, 78, 89, - 65, 85, 128, 78, 89, 65, 74, 128, 78, 89, 65, 73, 128, 78, 89, 65, 72, - 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, 128, 78, 87, 79, - 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, 73, 128, 78, 87, - 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, 128, 78, 86, 128, - 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, 78, 85, 84, 73, - 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, 82, 88, 128, 78, - 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, 85, 79, 80, 128, - 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, 85, 218, 78, 85, - 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, 65, 86, 73, 203, - 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, 78, 85, 77, 69, - 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, 77, 66, 69, 82, - 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, 78, 85, 76, 76, - 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, 65, 128, 78, 85, - 75, 84, 193, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, 78, 85, 66, 73, - 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, 85, 49, 177, 78, - 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, 85, 48, 50, 49, - 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, 78, 85, 48, 49, - 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, 128, 78, 85, - 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, 52, 128, 78, - 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, 49, 49, 65, - 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, 78, 85, 48, - 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, 128, 78, 85, - 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, 53, 128, 78, - 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, 48, 50, 128, - 78, 85, 48, 48, 49, 128, 78, 85, 45, 51, 128, 78, 85, 45, 50, 128, 78, - 85, 45, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, 88, 65, 128, 78, 84, - 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, 84, 213, 78, - 84, 83, 65, 85, 128, 78, 84, 83, 65, 128, 78, 84, 79, 81, 80, 69, 78, - 128, 78, 84, 79, 71, 128, 78, 84, 79, 199, 78, 84, 73, 69, 197, 78, 84, - 72, 65, 85, 128, 78, 84, 69, 85, 78, 71, 66, 65, 128, 78, 84, 69, 85, 77, - 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, 128, 78, 84, 65, 80, 128, 78, - 84, 65, 208, 78, 84, 65, 65, 128, 78, 84, 65, 128, 78, 83, 85, 79, 212, - 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, 77, 128, 78, 83, - 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, 83, 73, 69, 69, - 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, 83, 72, 85, 79, - 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, 128, 78, 83, - 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, 128, 78, 83, - 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, 128, 78, 82, - 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, 78, 82, 89, - 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, 88, 128, 78, - 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, 128, 78, 82, - 85, 80, 128, 78, 82, 85, 65, 128, 78, 82, 85, 128, 78, 82, 79, 88, 128, - 78, 82, 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, 78, 82, 69, - 84, 128, 78, 82, 69, 211, 78, 82, 69, 80, 128, 78, 82, 69, 128, 78, 82, - 65, 88, 128, 78, 82, 65, 84, 128, 78, 82, 65, 80, 128, 78, 82, 65, 128, - 78, 81, 73, 71, 128, 78, 81, 65, 128, 78, 80, 76, 65, 128, 78, 80, 65, - 128, 78, 79, 90, 72, 75, 65, 128, 78, 79, 89, 128, 78, 79, 88, 128, 78, - 79, 87, 67, 128, 78, 79, 86, 73, 76, 69, 128, 78, 79, 86, 69, 77, 66, 69, - 82, 128, 78, 79, 84, 84, 79, 128, 78, 79, 84, 69, 83, 128, 78, 79, 84, - 69, 72, 69, 65, 68, 128, 78, 79, 84, 69, 72, 69, 65, 196, 78, 79, 84, 69, - 66, 79, 79, 75, 128, 78, 79, 84, 69, 66, 79, 79, 203, 78, 79, 84, 69, - 128, 78, 79, 84, 197, 78, 79, 84, 67, 72, 69, 196, 78, 79, 84, 67, 72, - 128, 78, 79, 84, 65, 84, 73, 79, 206, 78, 79, 84, 128, 78, 79, 212, 78, - 79, 83, 69, 128, 78, 79, 83, 197, 78, 79, 82, 84, 72, 87, 69, 83, 212, - 78, 79, 82, 84, 72, 69, 82, 206, 78, 79, 82, 84, 72, 69, 65, 83, 84, 45, - 80, 79, 73, 78, 84, 73, 78, 199, 78, 79, 82, 77, 65, 204, 78, 79, 82, 68, - 73, 195, 78, 79, 210, 78, 79, 80, 128, 78, 79, 79, 78, 85, 128, 78, 79, - 79, 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, 128, 78, 79, 78, 45, 80, - 79, 84, 65, 66, 76, 197, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82, 128, 78, - 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 78, 79, 78, 128, 78, 79, 77, - 73, 83, 77, 193, 78, 79, 77, 73, 78, 65, 204, 78, 79, 75, 72, 85, 75, - 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, 79, 45, 66, 82, 69, 65, - 203, 78, 79, 45, 53, 128, 78, 79, 45, 52, 128, 78, 79, 45, 51, 128, 78, - 79, 45, 50, 128, 78, 79, 45, 49, 128, 78, 78, 85, 85, 128, 78, 78, 85, - 128, 78, 78, 79, 79, 128, 78, 78, 78, 85, 85, 128, 78, 78, 78, 85, 128, - 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, 78, 78, 78, 73, 73, 128, - 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, 78, 78, 78, 69, 128, 78, - 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, 78, 78, 78, 65, 65, 128, - 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, 72, 65, 128, 78, 78, 71, - 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, 73, 73, 128, 78, 78, 71, - 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 65, 128, 78, 78, 71, 128, - 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, 65, 85, 128, 78, 76, 48, - 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, 48, 49, 56, 128, 78, 76, - 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, 78, 76, 48, 49, 54, 128, - 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, 128, 78, 76, 48, 49, 51, - 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, 49, 128, 78, 76, 48, 49, - 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, 48, 56, 128, 78, 76, 48, - 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, 48, 48, 53, 65, 128, 78, - 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, 78, 76, 48, 48, 51, 128, - 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, 128, 78, 76, 128, 78, 75, - 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, 73, 128, 78, 75, 65, 85, - 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 75, 65, 128, 78, 74, 89, 88, - 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, 128, 78, 74, 89, 82, 128, - 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, 85, 88, 128, 78, 74, 85, - 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, 81, 65, 128, 78, 74, 85, - 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 69, - 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, 128, 78, 74, 79, 88, 128, - 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, 74, 79, 79, 128, 78, 74, - 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, 128, 78, 74, 73, 80, 128, - 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 80, - 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, 128, 78, 74, 73, 128, 78, - 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, 85, 84, 128, 78, 74, 69, - 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, 77, 128, 78, 74, 69, 69, - 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, 197, 78, 74, 69, 128, 78, - 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, 65, 69, 77, 76, 73, 128, - 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, 78, 73, 90, 75, 207, 78, - 73, 88, 128, 78, 73, 84, 82, 69, 128, 78, 73, 83, 65, 71, 128, 78, 73, - 82, 85, 71, 85, 128, 78, 73, 80, 128, 78, 73, 78, 84, 72, 128, 78, 73, - 78, 74, 65, 128, 78, 73, 78, 69, 84, 89, 128, 78, 73, 78, 69, 84, 217, - 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, 69, 84, 69, 69, 206, 78, - 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, 73, 78, 69, 45, 76, 73, - 75, 197, 78, 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, - 65, 178, 78, 73, 78, 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, - 205, 78, 73, 75, 79, 76, 83, 66, 85, 82, 199, 78, 73, 75, 72, 65, 72, 73, - 84, 128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, - 72, 83, 72, 86, 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, - 78, 73, 71, 73, 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, - 71, 72, 212, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, - 128, 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, - 78, 45, 84, 72, 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, - 79, 83, 128, 78, 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, - 85, 78, 45, 80, 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, - 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, - 78, 73, 69, 85, 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, - 67, 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, - 72, 128, 78, 73, 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, - 73, 66, 128, 78, 73, 65, 128, 78, 73, 50, 128, 78, 73, 45, 84, 69, 128, - 78, 73, 45, 55, 128, 78, 73, 45, 54, 128, 78, 73, 45, 53, 128, 78, 73, - 45, 52, 128, 78, 73, 45, 51, 128, 78, 73, 45, 50, 128, 78, 73, 45, 49, - 128, 78, 72, 85, 69, 128, 78, 72, 74, 65, 128, 78, 72, 65, 89, 128, 78, - 72, 128, 78, 71, 89, 69, 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, - 78, 71, 85, 79, 88, 128, 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, - 78, 71, 85, 65, 78, 128, 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, - 128, 78, 71, 79, 88, 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, - 79, 84, 128, 78, 71, 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, - 128, 78, 71, 79, 77, 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, - 78, 71, 207, 78, 71, 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, - 128, 78, 71, 75, 85, 80, 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, - 77, 128, 78, 71, 75, 85, 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, - 197, 78, 71, 75, 73, 78, 68, 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, - 75, 69, 85, 88, 128, 78, 71, 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, - 65, 69, 81, 128, 78, 71, 75, 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, - 128, 78, 71, 75, 65, 80, 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, - 75, 65, 128, 78, 71, 73, 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, - 73, 69, 128, 78, 71, 72, 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, - 71, 71, 85, 82, 65, 69, 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, - 81, 128, 78, 71, 71, 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, - 71, 85, 79, 77, 128, 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, - 128, 78, 71, 71, 85, 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, - 206, 78, 71, 71, 85, 65, 128, 78, 71, 71, 85, 128, 78, 71, 71, 79, 79, - 128, 78, 71, 71, 79, 128, 78, 71, 71, 73, 128, 78, 71, 71, 69, 85, 88, - 128, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 71, 71, 69, 85, 65, 69, - 128, 78, 71, 71, 69, 213, 78, 71, 71, 69, 78, 128, 78, 71, 71, 69, 69, - 84, 128, 78, 71, 71, 69, 69, 69, 69, 128, 78, 71, 71, 69, 69, 128, 78, - 71, 71, 69, 128, 78, 71, 71, 65, 80, 128, 78, 71, 71, 65, 65, 77, 65, 69, - 128, 78, 71, 71, 65, 65, 77, 128, 78, 71, 71, 65, 65, 128, 78, 71, 71, - 128, 78, 71, 69, 88, 128, 78, 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, - 69, 80, 128, 78, 71, 69, 78, 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, - 68, 65, 76, 128, 78, 71, 65, 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, - 84, 128, 78, 71, 65, 211, 78, 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, - 71, 65, 78, 71, 85, 128, 78, 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, - 71, 65, 72, 128, 78, 71, 65, 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, - 69, 88, 212, 78, 69, 88, 128, 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, - 78, 69, 87, 76, 73, 78, 69, 128, 78, 69, 87, 76, 73, 78, 197, 78, 69, 87, - 193, 78, 69, 87, 128, 78, 69, 215, 78, 69, 85, 84, 82, 65, 76, 128, 78, - 69, 85, 84, 82, 65, 204, 78, 69, 85, 84, 69, 82, 128, 78, 69, 84, 87, 79, - 82, 75, 69, 196, 78, 69, 212, 78, 69, 83, 84, 73, 78, 199, 78, 69, 83, - 84, 69, 196, 78, 69, 83, 84, 128, 78, 69, 83, 212, 78, 69, 83, 83, 85, - 83, 128, 78, 69, 82, 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, - 84, 85, 78, 69, 128, 78, 69, 80, 84, 85, 78, 197, 78, 69, 80, 79, 83, 84, - 79, 89, 65, 78, 78, 65, 89, 65, 128, 78, 69, 80, 128, 78, 69, 79, 128, - 78, 69, 207, 78, 69, 78, 79, 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, - 69, 78, 128, 78, 69, 77, 75, 65, 128, 78, 69, 76, 128, 78, 69, 73, 84, - 72, 69, 210, 78, 69, 71, 65, 84, 73, 86, 197, 78, 69, 71, 65, 84, 73, 79, - 206, 78, 69, 71, 65, 84, 69, 196, 78, 69, 69, 68, 76, 69, 128, 78, 69, - 67, 75, 84, 73, 69, 128, 78, 69, 67, 75, 128, 78, 69, 66, 69, 78, 83, 84, - 73, 77, 77, 69, 128, 78, 69, 45, 75, 79, 128, 78, 68, 85, 88, 128, 78, - 68, 85, 84, 128, 78, 68, 85, 82, 88, 128, 78, 68, 85, 82, 128, 78, 68, - 85, 80, 128, 78, 68, 85, 78, 128, 78, 68, 213, 78, 68, 79, 88, 128, 78, - 68, 79, 84, 128, 78, 68, 79, 80, 128, 78, 68, 79, 79, 128, 78, 68, 79, - 78, 128, 78, 68, 79, 77, 66, 85, 128, 78, 68, 79, 76, 197, 78, 68, 73, - 88, 128, 78, 68, 73, 84, 128, 78, 68, 73, 81, 128, 78, 68, 73, 80, 128, - 78, 68, 73, 69, 88, 128, 78, 68, 73, 69, 128, 78, 68, 73, 68, 65, 128, - 78, 68, 73, 65, 81, 128, 78, 68, 69, 88, 128, 78, 68, 69, 85, 88, 128, - 78, 68, 69, 85, 84, 128, 78, 68, 69, 85, 65, 69, 82, 69, 69, 128, 78, 68, - 69, 80, 128, 78, 68, 69, 69, 128, 78, 68, 69, 128, 78, 68, 65, 88, 128, - 78, 68, 65, 84, 128, 78, 68, 65, 80, 128, 78, 68, 65, 77, 128, 78, 68, - 65, 65, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 68, 65, 65, 128, 78, 68, - 65, 193, 78, 67, 72, 65, 85, 128, 78, 67, 65, 128, 78, 66, 89, 88, 128, - 78, 66, 89, 84, 128, 78, 66, 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, - 66, 89, 80, 128, 78, 66, 89, 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, - 128, 78, 66, 85, 82, 88, 128, 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, - 78, 66, 85, 128, 78, 66, 79, 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, - 80, 128, 78, 66, 79, 128, 78, 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, - 66, 73, 80, 128, 78, 66, 73, 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, - 66, 73, 69, 128, 78, 66, 73, 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, - 78, 66, 65, 84, 128, 78, 66, 65, 80, 128, 78, 66, 65, 128, 78, 65, 90, - 65, 210, 78, 65, 89, 65, 78, 78, 65, 128, 78, 65, 89, 128, 78, 65, 88, - 73, 65, 206, 78, 65, 88, 128, 78, 65, 85, 84, 72, 83, 128, 78, 65, 85, - 83, 69, 65, 84, 69, 196, 78, 65, 85, 68, 73, 218, 78, 65, 84, 85, 82, 65, - 204, 78, 65, 84, 84, 73, 76, 73, 203, 78, 65, 84, 73, 79, 78, 65, 204, - 78, 65, 83, 75, 65, 80, 201, 78, 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, - 73, 90, 69, 196, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 78, 128, 78, - 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 206, 78, 65, 83, 65, 204, 78, 65, - 82, 82, 79, 215, 78, 65, 82, 128, 78, 65, 81, 128, 78, 65, 79, 211, 78, - 65, 78, 83, 65, 78, 65, 81, 128, 78, 65, 78, 71, 77, 79, 78, 84, 72, 79, - 128, 78, 65, 78, 68, 73, 78, 65, 71, 65, 82, 201, 78, 65, 78, 68, 128, - 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, 78, 65, 77, 197, 78, 65, 77, - 50, 128, 78, 65, 75, 65, 65, 82, 193, 78, 65, 75, 128, 78, 65, 73, 82, - 193, 78, 65, 73, 204, 78, 65, 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, - 65, 71, 65, 128, 78, 65, 71, 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, - 69, 128, 78, 65, 66, 76, 65, 128, 78, 65, 66, 65, 84, 65, 69, 65, 206, - 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, - 89, 65, 89, 65, 128, 78, 65, 65, 73, 128, 78, 65, 193, 78, 65, 52, 128, - 78, 65, 50, 128, 78, 65, 45, 57, 128, 78, 65, 45, 56, 128, 78, 65, 45, - 55, 128, 78, 65, 45, 54, 128, 78, 65, 45, 53, 128, 78, 65, 45, 52, 128, - 78, 65, 45, 51, 128, 78, 65, 45, 50, 128, 78, 65, 45, 49, 128, 78, 48, - 52, 50, 128, 78, 48, 52, 49, 128, 78, 48, 52, 48, 128, 78, 48, 51, 57, - 128, 78, 48, 51, 56, 128, 78, 48, 51, 55, 65, 128, 78, 48, 51, 55, 128, - 78, 48, 51, 54, 128, 78, 48, 51, 53, 65, 128, 78, 48, 51, 53, 128, 78, - 48, 51, 52, 65, 128, 78, 48, 51, 52, 128, 78, 48, 51, 51, 65, 128, 78, - 48, 51, 51, 128, 78, 48, 51, 50, 128, 78, 48, 51, 49, 128, 78, 48, 51, - 48, 128, 78, 48, 50, 57, 128, 78, 48, 50, 56, 128, 78, 48, 50, 55, 128, - 78, 48, 50, 54, 128, 78, 48, 50, 53, 65, 128, 78, 48, 50, 53, 128, 78, - 48, 50, 52, 128, 78, 48, 50, 51, 128, 78, 48, 50, 50, 128, 78, 48, 50, - 49, 128, 78, 48, 50, 48, 128, 78, 48, 49, 57, 128, 78, 48, 49, 56, 66, - 128, 78, 48, 49, 56, 65, 128, 78, 48, 49, 56, 128, 78, 48, 49, 55, 128, - 78, 48, 49, 54, 128, 78, 48, 49, 53, 128, 78, 48, 49, 52, 128, 78, 48, - 49, 51, 128, 78, 48, 49, 50, 128, 78, 48, 49, 49, 128, 78, 48, 49, 48, - 128, 78, 48, 48, 57, 128, 78, 48, 48, 56, 128, 78, 48, 48, 55, 128, 78, - 48, 48, 54, 128, 78, 48, 48, 53, 128, 78, 48, 48, 52, 128, 78, 48, 48, - 51, 128, 78, 48, 48, 50, 128, 78, 48, 48, 49, 128, 78, 45, 77, 85, 45, - 77, 79, 45, 50, 128, 78, 45, 77, 85, 45, 77, 79, 45, 49, 128, 78, 45, 67, - 82, 69, 197, 78, 45, 65, 82, 217, 77, 90, 128, 77, 89, 88, 128, 77, 89, - 84, 128, 77, 89, 83, 76, 73, 84, 69, 128, 77, 89, 80, 128, 77, 89, 65, - 128, 77, 89, 193, 77, 87, 79, 79, 128, 77, 87, 79, 128, 77, 87, 73, 73, - 128, 77, 87, 73, 128, 77, 87, 69, 69, 128, 77, 87, 69, 128, 77, 87, 65, - 65, 128, 77, 87, 65, 128, 77, 87, 128, 77, 215, 77, 86, 83, 128, 77, 86, - 79, 80, 128, 77, 86, 73, 128, 77, 86, 69, 85, 65, 69, 78, 71, 65, 77, - 128, 77, 86, 128, 77, 214, 77, 85, 88, 128, 77, 85, 85, 86, 85, 90, 72, - 65, 75, 75, 85, 128, 77, 85, 85, 83, 73, 75, 65, 84, 79, 65, 78, 128, 77, - 85, 85, 82, 68, 72, 65, 74, 193, 77, 85, 85, 128, 77, 85, 84, 72, 65, 76, - 73, 89, 65, 128, 77, 85, 84, 128, 77, 85, 83, 73, 67, 128, 77, 85, 83, - 73, 195, 77, 85, 83, 72, 82, 79, 79, 77, 128, 77, 85, 83, 72, 51, 128, - 77, 85, 83, 72, 179, 77, 85, 83, 72, 128, 77, 85, 83, 200, 77, 85, 83, - 128, 77, 85, 82, 88, 128, 77, 85, 82, 71, 85, 50, 128, 77, 85, 82, 69, - 128, 77, 85, 82, 68, 65, 128, 77, 85, 82, 68, 193, 77, 85, 82, 128, 77, - 85, 81, 68, 65, 77, 128, 77, 85, 80, 128, 77, 85, 79, 88, 128, 77, 85, - 79, 84, 128, 77, 85, 79, 80, 128, 77, 85, 79, 77, 65, 69, 128, 77, 85, - 79, 128, 77, 85, 78, 83, 85, 66, 128, 77, 85, 78, 68, 65, 82, 201, 77, - 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, 76, 84, 73, 83, 69, 84, - 128, 77, 85, 76, 84, 73, 83, 69, 212, 77, 85, 76, 84, 73, 80, 76, 73, 67, - 65, 84, 73, 79, 78, 128, 77, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, - 79, 206, 77, 85, 76, 84, 73, 80, 76, 69, 128, 77, 85, 76, 84, 73, 80, 76, - 197, 77, 85, 76, 84, 73, 79, 67, 85, 76, 65, 210, 77, 85, 76, 84, 73, 77, - 65, 80, 128, 77, 85, 76, 84, 201, 77, 85, 76, 84, 65, 78, 201, 77, 85, - 75, 80, 72, 82, 69, 78, 71, 128, 77, 85, 75, 75, 85, 82, 85, 78, 73, 128, - 77, 85, 73, 78, 128, 77, 85, 72, 79, 82, 128, 77, 85, 71, 83, 128, 77, - 85, 71, 128, 77, 85, 199, 77, 85, 69, 78, 128, 77, 85, 69, 128, 77, 85, - 67, 72, 128, 77, 85, 67, 200, 77, 85, 67, 65, 65, 68, 128, 77, 85, 65, - 83, 128, 77, 85, 65, 78, 128, 77, 85, 65, 69, 128, 77, 85, 45, 71, 65, - 65, 72, 76, 65, 193, 77, 85, 45, 52, 128, 77, 85, 45, 51, 128, 77, 85, - 45, 50, 128, 77, 85, 45, 49, 128, 77, 213, 77, 84, 65, 86, 82, 85, 76, - 201, 77, 83, 128, 77, 82, 207, 77, 82, 65, 67, 72, 78, 89, 128, 77, 82, - 65, 67, 72, 78, 79, 84, 73, 75, 72, 65, 89, 65, 128, 77, 82, 65, 67, 72, - 78, 79, 128, 77, 82, 65, 67, 72, 78, 65, 89, 65, 128, 77, 210, 77, 81, - 128, 77, 80, 65, 128, 77, 79, 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, - 86, 73, 197, 77, 79, 86, 69, 211, 77, 79, 86, 69, 77, 69, 78, 84, 45, 87, - 65, 76, 76, 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 72, - 73, 78, 71, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 70, 76, 79, 79, 82, - 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 68, 73, 65, 71, - 79, 78, 65, 204, 77, 79, 86, 69, 77, 69, 78, 84, 128, 77, 79, 86, 69, 77, - 69, 78, 212, 77, 79, 86, 69, 196, 77, 79, 86, 69, 128, 77, 79, 85, 84, - 72, 128, 77, 79, 85, 83, 69, 128, 77, 79, 85, 83, 197, 77, 79, 85, 78, - 84, 65, 73, 78, 83, 128, 77, 79, 85, 78, 84, 65, 73, 78, 128, 77, 79, 85, - 78, 84, 65, 73, 206, 77, 79, 85, 78, 212, 77, 79, 85, 78, 68, 128, 77, - 79, 85, 78, 196, 77, 79, 84, 79, 82, 87, 65, 89, 128, 77, 79, 84, 79, 82, - 73, 90, 69, 196, 77, 79, 84, 79, 82, 67, 89, 67, 76, 69, 128, 77, 79, 84, - 79, 210, 77, 79, 84, 72, 69, 82, 128, 77, 79, 84, 72, 69, 210, 77, 79, - 84, 128, 77, 79, 83, 81, 85, 73, 84, 79, 128, 77, 79, 83, 81, 85, 69, - 128, 77, 79, 82, 84, 85, 85, 77, 128, 77, 79, 82, 84, 65, 82, 128, 77, - 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, 77, 79, 82, 78, 73, 78, - 71, 128, 77, 79, 80, 128, 77, 79, 79, 83, 69, 45, 67, 82, 69, 197, 77, - 79, 79, 83, 69, 128, 77, 79, 79, 78, 128, 77, 79, 79, 206, 77, 79, 79, - 77, 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, 79, 68, - 128, 77, 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, 69, 78, - 128, 77, 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, 83, 84, - 69, 82, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, 79, 83, - 80, 65, 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, 79, 71, - 82, 65, 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, 79, 78, - 79, 71, 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, - 78, 79, 67, 85, 76, 65, 210, 77, 79, 78, 79, 67, 76, 69, 128, 77, 79, 78, - 75, 69, 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, 77, 79, - 78, 71, 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 89, 45, 77, 79, 85, - 84, 200, 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, 79, 76, - 128, 77, 79, 75, 72, 65, 83, 83, 65, 83, 128, 77, 79, 72, 65, 77, 77, 65, - 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 73, 70, 73, 69, 82, 45, 57, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 56, 128, 77, 79, 68, 73, 70, 73, - 69, 82, 45, 55, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 54, 128, 77, 79, - 68, 73, 70, 73, 69, 82, 45, 53, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, - 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 51, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 50, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 54, 128, - 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 53, 128, 77, 79, 68, 73, 70, 73, - 69, 82, 45, 49, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 51, 128, - 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 50, 128, 77, 79, 68, 73, 70, 73, - 69, 82, 45, 49, 49, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 48, 128, - 77, 79, 68, 73, 70, 73, 69, 82, 128, 77, 79, 68, 201, 77, 79, 68, 69, 83, - 84, 89, 128, 77, 79, 68, 69, 82, 206, 77, 79, 68, 69, 77, 128, 77, 79, - 68, 69, 76, 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, 128, 77, - 79, 66, 73, 76, 197, 77, 79, 65, 128, 77, 79, 45, 54, 128, 77, 79, 45, - 53, 128, 77, 79, 45, 52, 128, 77, 79, 45, 51, 128, 77, 207, 77, 78, 89, - 65, 205, 77, 78, 65, 83, 128, 77, 77, 83, 80, 128, 77, 77, 128, 77, 205, - 77, 76, 65, 128, 77, 76, 128, 77, 75, 80, 65, 82, 65, 209, 77, 73, 88, - 128, 77, 73, 84, 128, 77, 73, 83, 82, 65, 128, 77, 73, 82, 82, 79, 82, - 128, 77, 73, 82, 82, 79, 210, 77, 73, 82, 73, 66, 65, 65, 82, 85, 128, - 77, 73, 82, 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, 73, - 78, 89, 128, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, 73, - 78, 85, 83, 128, 77, 73, 78, 78, 65, 206, 77, 73, 78, 73, 83, 84, 69, 82, - 128, 77, 73, 78, 73, 77, 73, 90, 69, 128, 77, 73, 78, 73, 77, 65, 128, - 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, 83, 128, 77, - 73, 78, 68, 85, 128, 77, 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, - 76, 73, 79, 78, 83, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, 73, 76, 76, - 69, 84, 128, 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, 76, 75, 217, - 77, 73, 76, 75, 128, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, - 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, - 73, 128, 77, 73, 73, 78, 128, 77, 73, 73, 77, 128, 77, 73, 73, 128, 77, - 73, 199, 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, - 84, 128, 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, - 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, - 73, 69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, - 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, - 69, 85, 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, - 77, 73, 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, - 67, 73, 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, - 72, 128, 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, - 77, 73, 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, - 87, 69, 76, 83, 200, 77, 73, 68, 68, 76, 69, 128, 77, 73, 68, 45, 76, 69, - 86, 69, 204, 77, 73, 68, 45, 72, 69, 73, 71, 72, 212, 77, 73, 196, 77, - 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, 73, 67, 82, 79, 80, 72, 79, - 78, 69, 128, 77, 73, 67, 82, 79, 66, 69, 128, 77, 73, 67, 82, 207, 77, - 73, 67, 210, 77, 73, 45, 55, 128, 77, 73, 45, 54, 128, 77, 73, 45, 53, - 128, 77, 73, 45, 52, 128, 77, 73, 45, 51, 128, 77, 73, 45, 50, 128, 77, - 73, 45, 49, 128, 77, 72, 90, 128, 77, 72, 65, 128, 77, 72, 128, 77, 71, - 85, 88, 128, 77, 71, 85, 84, 128, 77, 71, 85, 82, 88, 128, 77, 71, 85, - 82, 128, 77, 71, 85, 80, 128, 77, 71, 85, 79, 88, 128, 77, 71, 85, 79, - 80, 128, 77, 71, 85, 79, 128, 77, 71, 85, 128, 77, 71, 79, 88, 128, 77, - 71, 79, 84, 128, 77, 71, 79, 80, 128, 77, 71, 79, 128, 77, 71, 207, 77, - 71, 73, 69, 88, 128, 77, 71, 73, 69, 128, 77, 71, 69, 88, 128, 77, 71, - 69, 80, 128, 77, 71, 69, 128, 77, 71, 66, 85, 128, 77, 71, 66, 79, 79, - 128, 77, 71, 66, 79, 70, 85, 77, 128, 77, 71, 66, 79, 128, 77, 71, 66, - 73, 128, 77, 71, 66, 69, 85, 78, 128, 77, 71, 66, 69, 78, 128, 77, 71, - 66, 69, 69, 128, 77, 71, 66, 69, 128, 77, 71, 66, 65, 83, 65, 81, 128, - 77, 71, 66, 65, 83, 65, 128, 77, 71, 65, 88, 128, 77, 71, 65, 84, 128, - 77, 71, 65, 80, 128, 77, 71, 65, 128, 77, 71, 128, 77, 70, 79, 78, 128, - 77, 70, 79, 206, 77, 70, 79, 128, 77, 70, 73, 89, 65, 81, 128, 77, 70, - 73, 69, 69, 128, 77, 70, 69, 85, 84, 128, 77, 70, 69, 85, 81, 128, 77, - 70, 69, 85, 65, 69, 128, 77, 70, 65, 65, 128, 77, 69, 90, 90, 79, 128, - 77, 69, 88, 128, 77, 69, 85, 212, 77, 69, 85, 81, 128, 77, 69, 85, 78, - 74, 79, 77, 78, 68, 69, 85, 81, 128, 77, 69, 85, 78, 128, 77, 69, 84, 82, - 79, 128, 77, 69, 84, 82, 73, 67, 65, 204, 77, 69, 84, 82, 73, 65, 128, - 77, 69, 84, 82, 69, 84, 69, 211, 77, 69, 84, 79, 66, 69, 76, 85, 83, 128, - 77, 69, 84, 69, 75, 128, 77, 69, 84, 69, 71, 128, 77, 69, 84, 65, 76, - 128, 77, 69, 84, 193, 77, 69, 83, 83, 69, 78, 73, 65, 206, 77, 69, 83, - 83, 65, 71, 69, 128, 77, 69, 83, 83, 65, 71, 197, 77, 69, 83, 79, 128, - 77, 69, 83, 73, 128, 77, 69, 83, 72, 128, 77, 69, 82, 80, 69, 82, 83, 79, - 78, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 82, 75, 72, 193, 77, 69, - 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, 128, 77, 69, 82, 71, 69, - 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 82, 67, 85, 82, 217, 77, - 69, 78, 79, 82, 65, 200, 77, 69, 78, 79, 69, 128, 77, 69, 78, 68, 85, 84, - 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, 77, 69, 77, 66, 69, 82, 83, - 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, 77, 69, 77, 66, 69, 210, - 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, 128, 77, 69, 205, 77, - 69, 76, 84, 73, 78, 199, 77, 69, 76, 79, 68, 73, 195, 77, 69, 76, 73, 75, - 128, 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, 128, 77, 69, - 71, 65, 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, 128, 77, 69, 69, - 84, 79, 82, 85, 128, 77, 69, 69, 84, 69, 201, 77, 69, 69, 84, 128, 77, - 69, 69, 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, 202, 77, 69, 69, - 69, 69, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, 73, 85, 205, 77, - 69, 68, 73, 69, 86, 65, 204, 77, 69, 68, 73, 67, 73, 78, 69, 128, 77, 69, - 68, 73, 67, 65, 204, 77, 69, 68, 73, 65, 204, 77, 69, 68, 69, 70, 65, 73, - 68, 82, 73, 206, 77, 69, 68, 65, 76, 128, 77, 69, 67, 72, 73, 75, 128, - 77, 69, 67, 72, 73, 203, 77, 69, 67, 72, 65, 78, 73, 67, 65, 204, 77, 69, - 65, 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, 69, 196, 77, 69, - 65, 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, 77, 69, 45, 77, 65, - 128, 77, 69, 45, 50, 128, 77, 69, 45, 49, 128, 77, 68, 85, 206, 77, 196, - 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 67, 128, 77, 195, 77, 66, 85, - 85, 128, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, 128, 77, 66, 85, 69, - 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, 69, 128, 77, 66, 79, - 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, 66, 73, 212, 77, 66, - 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, 66, 69, 85, 88, 128, - 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, 128, 77, 66, 69, 82, 65, - 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, 75, 69, 69, 84, 128, 77, - 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, 81, 128, 77, 66, 65, 78, - 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, 77, 66, 65, 65, 75, 69, 84, - 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, 77, 66, 193, 77, 66, 52, 128, - 77, 66, 51, 128, 77, 66, 50, 128, 77, 65, 89, 69, 203, 77, 65, 89, 65, - 78, 78, 65, 128, 77, 65, 89, 65, 206, 77, 65, 89, 128, 77, 65, 88, 73, - 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, 128, 77, 65, 88, 128, 77, - 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, 77, 65, 84, 82, 73, 88, - 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, 65, 84, 128, 77, 65, - 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, 83, 83, 65, 71, 69, - 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, 77, 65, 83, 203, 77, - 65, 83, 72, 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, 128, 77, 65, 83, 67, - 85, 76, 73, 78, 197, 77, 65, 83, 65, 82, 65, 205, 77, 65, 82, 89, 128, - 77, 65, 82, 87, 65, 82, 201, 77, 65, 82, 85, 75, 85, 128, 77, 65, 82, 84, - 89, 82, 73, 193, 77, 65, 82, 84, 73, 65, 204, 77, 65, 82, 82, 89, 73, 78, - 199, 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, 82, 65, 84, 65, 78, - 128, 77, 65, 82, 75, 211, 77, 65, 82, 75, 69, 82, 128, 77, 65, 82, 75, - 45, 52, 128, 77, 65, 82, 75, 45, 51, 128, 77, 65, 82, 75, 45, 50, 128, - 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 69, 128, 77, 65, 82, 67, 72, 69, - 206, 77, 65, 82, 67, 72, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, - 67, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, 82, 67, - 65, 83, 73, 84, 69, 128, 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 66, - 85, 84, 193, 77, 65, 82, 65, 67, 65, 83, 128, 77, 65, 82, 128, 77, 65, - 81, 65, 70, 128, 77, 65, 81, 128, 77, 65, 80, 76, 197, 77, 65, 80, 73, - 81, 128, 77, 65, 208, 77, 65, 79, 128, 77, 65, 78, 85, 65, 204, 77, 65, - 78, 84, 69, 76, 80, 73, 69, 67, 197, 77, 65, 78, 83, 89, 79, 78, 128, 77, - 65, 78, 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, 218, 77, 65, 78, 78, 65, - 128, 77, 65, 78, 73, 67, 72, 65, 69, 65, 206, 77, 65, 78, 71, 79, 128, - 77, 65, 78, 71, 65, 76, 65, 77, 128, 77, 65, 78, 68, 65, 82, 73, 78, 128, - 77, 65, 78, 68, 65, 73, 76, 73, 78, 199, 77, 65, 78, 68, 65, 73, 195, 77, - 65, 78, 67, 72, 213, 77, 65, 78, 65, 212, 77, 65, 78, 65, 67, 76, 69, 83, - 128, 77, 65, 77, 77, 79, 84, 72, 128, 77, 65, 76, 84, 69, 83, 197, 77, - 65, 76, 207, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 197, 77, 65, - 76, 65, 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, 65, 75, 83, 85, - 82, 193, 77, 65, 75, 69, 77, 65, 75, 69, 128, 77, 65, 75, 65, 83, 65, - 210, 77, 65, 73, 90, 69, 128, 77, 65, 73, 89, 65, 77, 79, 75, 128, 77, - 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 73, 82, 85, 128, 77, 65, 73, - 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, 65, 73, 128, 77, 65, 73, 76, - 66, 79, 216, 77, 65, 73, 75, 85, 82, 79, 128, 77, 65, 73, 68, 69, 78, - 128, 77, 65, 73, 128, 77, 65, 72, 74, 79, 78, 199, 77, 65, 72, 72, 65, - 128, 77, 65, 72, 65, 80, 82, 65, 78, 65, 128, 77, 65, 72, 65, 80, 65, 75, - 72, 128, 77, 65, 72, 65, 74, 65, 78, 201, 77, 65, 72, 65, 65, 80, 82, 65, - 65, 78, 193, 77, 65, 72, 128, 77, 65, 71, 78, 73, 70, 89, 73, 78, 199, - 77, 65, 71, 78, 69, 84, 128, 77, 65, 71, 73, 195, 77, 65, 71, 69, 128, - 77, 65, 69, 83, 73, 128, 77, 65, 69, 78, 89, 73, 128, 77, 65, 69, 78, 74, - 69, 84, 128, 77, 65, 69, 77, 86, 69, 85, 88, 128, 77, 65, 69, 77, 75, 80, - 69, 78, 128, 77, 65, 69, 77, 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, - 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, 65, 128, 77, 65, 69, 77, - 128, 77, 65, 69, 76, 69, 69, 128, 77, 65, 69, 75, 69, 85, 80, 128, 77, - 65, 68, 89, 65, 128, 77, 65, 68, 85, 128, 77, 65, 68, 68, 65, 72, 128, - 77, 65, 68, 68, 65, 200, 77, 65, 68, 68, 65, 128, 77, 65, 68, 68, 193, - 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, 86, 69, 128, 77, 65, 67, 82, 79, - 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 65, 67, 85, - 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, 77, 65, 67, 82, 79, 206, 77, - 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, 89, 65, 65, 128, 77, 65, 65, - 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, 77, 65, 45, 55, 128, 77, 65, - 45, 54, 128, 77, 65, 45, 53, 128, 77, 65, 45, 52, 128, 77, 65, 45, 51, - 128, 77, 65, 45, 50, 128, 77, 65, 45, 49, 128, 77, 49, 57, 183, 77, 49, - 57, 182, 77, 49, 57, 181, 77, 49, 57, 180, 77, 49, 57, 179, 77, 49, 57, - 178, 77, 49, 57, 177, 77, 49, 57, 176, 77, 49, 56, 185, 77, 49, 56, 184, - 77, 49, 56, 183, 77, 49, 56, 182, 77, 49, 56, 181, 77, 49, 56, 180, 77, - 49, 56, 179, 77, 49, 56, 178, 77, 49, 56, 177, 77, 49, 56, 176, 77, 49, - 55, 185, 77, 49, 55, 184, 77, 49, 55, 183, 77, 49, 55, 182, 77, 49, 55, - 181, 77, 49, 55, 180, 77, 49, 55, 179, 77, 49, 55, 178, 77, 49, 55, 177, - 77, 49, 55, 176, 77, 49, 54, 185, 77, 49, 54, 184, 77, 49, 54, 183, 77, - 49, 54, 182, 77, 49, 54, 181, 77, 49, 54, 180, 77, 49, 54, 179, 77, 49, - 54, 178, 77, 49, 54, 177, 77, 49, 54, 176, 77, 49, 53, 185, 77, 49, 53, - 184, 77, 49, 53, 183, 77, 49, 53, 182, 77, 49, 53, 181, 77, 49, 53, 180, - 77, 49, 53, 179, 77, 49, 53, 178, 77, 49, 53, 177, 77, 49, 53, 176, 77, - 49, 52, 185, 77, 49, 52, 184, 77, 49, 52, 183, 77, 49, 52, 182, 77, 49, - 52, 181, 77, 49, 52, 180, 77, 49, 52, 179, 77, 49, 52, 178, 77, 49, 52, - 177, 77, 49, 52, 176, 77, 49, 51, 185, 77, 49, 51, 184, 77, 49, 51, 183, - 77, 49, 51, 182, 77, 49, 51, 181, 77, 49, 51, 180, 77, 49, 51, 179, 77, - 49, 51, 178, 77, 49, 51, 177, 77, 49, 51, 176, 77, 49, 50, 185, 77, 49, - 50, 184, 77, 49, 50, 183, 77, 49, 50, 182, 77, 49, 50, 181, 77, 49, 50, - 180, 77, 49, 50, 179, 77, 49, 50, 178, 77, 49, 50, 177, 77, 49, 50, 176, - 77, 49, 49, 185, 77, 49, 49, 184, 77, 49, 49, 183, 77, 49, 49, 182, 77, - 49, 49, 181, 77, 49, 49, 180, 77, 49, 49, 179, 77, 49, 49, 178, 77, 49, - 49, 177, 77, 49, 49, 176, 77, 49, 48, 185, 77, 49, 48, 184, 77, 49, 48, - 183, 77, 49, 48, 182, 77, 49, 48, 181, 77, 49, 48, 180, 77, 49, 48, 179, - 77, 49, 48, 178, 77, 49, 48, 177, 77, 49, 48, 176, 77, 48, 57, 185, 77, - 48, 57, 184, 77, 48, 57, 183, 77, 48, 57, 182, 77, 48, 57, 181, 77, 48, - 57, 180, 77, 48, 57, 179, 77, 48, 57, 178, 77, 48, 57, 177, 77, 48, 57, - 176, 77, 48, 56, 185, 77, 48, 56, 184, 77, 48, 56, 183, 77, 48, 56, 182, - 77, 48, 56, 181, 77, 48, 56, 180, 77, 48, 56, 179, 77, 48, 56, 178, 77, - 48, 56, 177, 77, 48, 56, 176, 77, 48, 55, 185, 77, 48, 55, 184, 77, 48, - 55, 183, 77, 48, 55, 182, 77, 48, 55, 181, 77, 48, 55, 180, 77, 48, 55, - 179, 77, 48, 55, 178, 77, 48, 55, 177, 77, 48, 55, 176, 77, 48, 54, 185, - 77, 48, 54, 184, 77, 48, 54, 183, 77, 48, 54, 182, 77, 48, 54, 181, 77, - 48, 54, 180, 77, 48, 54, 179, 77, 48, 54, 178, 77, 48, 54, 177, 77, 48, - 54, 176, 77, 48, 53, 185, 77, 48, 53, 184, 77, 48, 53, 183, 77, 48, 53, - 182, 77, 48, 53, 181, 77, 48, 53, 180, 77, 48, 53, 179, 77, 48, 53, 178, - 77, 48, 53, 177, 77, 48, 53, 176, 77, 48, 52, 185, 77, 48, 52, 184, 77, - 48, 52, 183, 77, 48, 52, 182, 77, 48, 52, 181, 77, 48, 52, 52, 128, 77, - 48, 52, 180, 77, 48, 52, 51, 128, 77, 48, 52, 179, 77, 48, 52, 50, 128, - 77, 48, 52, 178, 77, 48, 52, 49, 128, 77, 48, 52, 177, 77, 48, 52, 48, - 65, 128, 77, 48, 52, 48, 128, 77, 48, 52, 176, 77, 48, 51, 57, 128, 77, - 48, 51, 185, 77, 48, 51, 56, 128, 77, 48, 51, 184, 77, 48, 51, 55, 128, - 77, 48, 51, 183, 77, 48, 51, 54, 128, 77, 48, 51, 182, 77, 48, 51, 53, - 128, 77, 48, 51, 181, 77, 48, 51, 52, 128, 77, 48, 51, 180, 77, 48, 51, - 51, 66, 128, 77, 48, 51, 51, 65, 128, 77, 48, 51, 51, 128, 77, 48, 51, - 179, 77, 48, 51, 50, 128, 77, 48, 51, 178, 77, 48, 51, 49, 65, 128, 77, - 48, 51, 49, 128, 77, 48, 51, 177, 77, 48, 51, 48, 128, 77, 48, 51, 176, - 77, 48, 50, 57, 128, 77, 48, 50, 185, 77, 48, 50, 56, 65, 128, 77, 48, - 50, 56, 128, 77, 48, 50, 184, 77, 48, 50, 55, 128, 77, 48, 50, 183, 77, - 48, 50, 54, 128, 77, 48, 50, 182, 77, 48, 50, 53, 128, 77, 48, 50, 181, - 77, 48, 50, 52, 65, 128, 77, 48, 50, 52, 128, 77, 48, 50, 180, 77, 48, - 50, 51, 128, 77, 48, 50, 179, 77, 48, 50, 50, 65, 128, 77, 48, 50, 50, - 128, 77, 48, 50, 178, 77, 48, 50, 49, 128, 77, 48, 50, 177, 77, 48, 50, - 48, 128, 77, 48, 50, 176, 77, 48, 49, 57, 128, 77, 48, 49, 185, 77, 48, - 49, 56, 128, 77, 48, 49, 184, 77, 48, 49, 55, 65, 128, 77, 48, 49, 55, - 128, 77, 48, 49, 183, 77, 48, 49, 54, 65, 128, 77, 48, 49, 54, 128, 77, - 48, 49, 182, 77, 48, 49, 53, 65, 128, 77, 48, 49, 53, 128, 77, 48, 49, - 181, 77, 48, 49, 52, 128, 77, 48, 49, 180, 77, 48, 49, 51, 128, 77, 48, - 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, 49, 50, 71, 128, 77, 48, 49, - 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, 48, 49, 50, 68, 128, 77, 48, - 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, 77, 48, 49, 50, 65, 128, 77, - 48, 49, 50, 128, 77, 48, 49, 178, 77, 48, 49, 49, 128, 77, 48, 49, 177, - 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, 128, 77, 48, 49, 176, 77, 48, - 48, 57, 128, 77, 48, 48, 185, 77, 48, 48, 56, 128, 77, 48, 48, 184, 77, - 48, 48, 55, 128, 77, 48, 48, 183, 77, 48, 48, 54, 128, 77, 48, 48, 182, - 77, 48, 48, 53, 128, 77, 48, 48, 181, 77, 48, 48, 52, 128, 77, 48, 48, - 180, 77, 48, 48, 51, 65, 128, 77, 48, 48, 51, 128, 77, 48, 48, 179, 77, - 48, 48, 50, 128, 77, 48, 48, 178, 77, 48, 48, 49, 66, 128, 77, 48, 48, - 49, 65, 128, 77, 48, 48, 49, 128, 77, 48, 48, 177, 76, 218, 76, 89, 89, - 128, 76, 89, 88, 128, 76, 89, 84, 128, 76, 89, 82, 88, 128, 76, 89, 82, - 128, 76, 89, 80, 128, 76, 89, 73, 84, 128, 76, 89, 73, 78, 199, 76, 89, - 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, 76, 88, 128, 76, 87, 79, 79, - 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, 76, 87, 73, 128, 76, 87, 69, - 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, 76, 85, 88, 128, 76, 85, 85, - 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, 76, 85, 80, 128, 76, 85, 79, - 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, 80, 128, 76, 85, 79, 128, 76, - 85, 78, 71, 83, 73, 128, 76, 85, 78, 71, 83, 128, 76, 85, 78, 65, 84, - 197, 76, 85, 78, 65, 210, 76, 85, 205, 76, 85, 76, 128, 76, 85, 73, 83, - 128, 76, 85, 72, 85, 82, 128, 76, 85, 72, 128, 76, 85, 200, 76, 85, 71, - 71, 65, 71, 69, 128, 76, 85, 71, 65, 76, 128, 76, 85, 71, 65, 204, 76, - 85, 69, 128, 76, 85, 197, 76, 85, 66, 128, 76, 85, 65, 69, 80, 128, 76, - 85, 51, 128, 76, 85, 50, 128, 76, 85, 178, 76, 82, 79, 128, 76, 82, 77, - 128, 76, 82, 73, 128, 76, 82, 69, 128, 76, 79, 90, 69, 78, 71, 69, 128, - 76, 79, 90, 69, 78, 71, 197, 76, 79, 88, 128, 76, 79, 87, 69, 82, 69, - 196, 76, 79, 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, 79, 87, - 45, 77, 73, 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, 79, 87, - 45, 185, 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, 68, 83, - 80, 69, 65, 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, 85, 83, - 128, 76, 79, 84, 85, 211, 76, 79, 84, 73, 79, 206, 76, 79, 84, 128, 76, - 79, 83, 212, 76, 79, 83, 83, 76, 69, 83, 83, 128, 76, 79, 82, 82, 89, - 128, 76, 79, 82, 82, 65, 73, 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, - 128, 76, 79, 79, 84, 128, 76, 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, - 76, 79, 79, 208, 76, 79, 79, 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, - 76, 79, 78, 83, 85, 77, 128, 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, - 193, 76, 79, 78, 71, 45, 76, 69, 71, 71, 69, 196, 76, 79, 78, 71, 45, 66, - 82, 65, 78, 67, 72, 45, 89, 82, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, - 67, 72, 45, 83, 79, 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, - 79, 83, 211, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, - 210, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, - 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, - 77, 65, 69, 128, 76, 79, 77, 75, 65, 128, 76, 79, 77, 128, 76, 79, 205, - 76, 79, 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, 128, 76, 79, 71, - 210, 76, 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, 71, 82, 65, 205, - 76, 79, 71, 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, 128, 76, 79, 67, 79, - 77, 79, 84, 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, 71, 45, 83, 72, 73, - 70, 212, 76, 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 67, 65, 84, 73, 79, - 78, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, - 78, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, - 79, 78, 128, 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, 66, 83, 84, 69, 82, - 128, 76, 79, 65, 128, 76, 78, 128, 76, 76, 85, 85, 128, 76, 76, 79, 79, - 128, 76, 76, 76, 85, 85, 128, 76, 76, 76, 85, 128, 76, 76, 76, 79, 79, - 128, 76, 76, 76, 79, 128, 76, 76, 76, 73, 73, 128, 76, 76, 76, 73, 128, - 76, 76, 76, 69, 69, 128, 76, 76, 76, 69, 128, 76, 76, 76, 65, 85, 128, - 76, 76, 76, 65, 73, 128, 76, 76, 76, 65, 65, 128, 76, 76, 76, 65, 128, - 76, 76, 76, 128, 76, 76, 72, 65, 128, 76, 76, 65, 77, 65, 128, 76, 74, - 85, 68, 73, 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 90, 65, - 82, 68, 128, 76, 73, 88, 128, 76, 73, 87, 78, 128, 76, 73, 86, 82, 197, - 76, 73, 84, 84, 76, 69, 128, 76, 73, 84, 84, 76, 197, 76, 73, 84, 84, 69, - 210, 76, 73, 84, 82, 193, 76, 73, 84, 200, 76, 73, 83, 213, 76, 73, 83, - 128, 76, 73, 82, 193, 76, 73, 81, 85, 73, 68, 128, 76, 73, 81, 85, 73, - 196, 76, 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, 128, 76, 73, 80, - 211, 76, 73, 208, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 75, 69, 196, - 76, 73, 78, 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, - 76, 73, 78, 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, - 128, 76, 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, - 77, 77, 85, 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, - 128, 76, 73, 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, - 84, 65, 84, 73, 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, - 128, 76, 73, 77, 66, 213, 76, 73, 77, 66, 211, 76, 73, 77, 194, 76, 73, - 76, 89, 128, 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, 73, 71, - 72, 84, 78, 73, 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, 78, 199, 76, 73, - 71, 72, 84, 72, 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, 128, 76, 73, 71, - 65, 84, 73, 78, 199, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, 128, - 76, 73, 69, 88, 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, 73, - 69, 69, 128, 76, 73, 69, 128, 76, 73, 68, 128, 76, 73, 67, 75, 73, 78, - 199, 76, 73, 66, 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, 73, - 65, 66, 73, 76, 73, 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, 89, - 65, 78, 73, 128, 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, 76, - 69, 90, 72, 128, 76, 69, 90, 200, 76, 69, 88, 128, 76, 69, 86, 73, 84, - 65, 84, 73, 78, 71, 128, 76, 69, 86, 69, 76, 45, 51, 128, 76, 69, 86, 69, - 76, 45, 50, 128, 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, - 69, 85, 65, 69, 77, 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, - 69, 82, 83, 128, 76, 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, - 83, 69, 210, 76, 69, 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, - 84, 72, 65, 206, 76, 69, 83, 72, 128, 76, 69, 80, 67, 72, 193, 76, 69, - 80, 128, 76, 69, 79, 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, - 84, 73, 67, 85, 76, 65, 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, - 211, 76, 69, 78, 71, 84, 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 72, - 45, 55, 128, 76, 69, 78, 71, 84, 72, 45, 54, 128, 76, 69, 78, 71, 84, 72, - 45, 53, 128, 76, 69, 78, 71, 84, 72, 45, 52, 128, 76, 69, 78, 71, 84, 72, - 45, 51, 128, 76, 69, 78, 71, 84, 72, 45, 50, 128, 76, 69, 78, 71, 84, 72, - 45, 49, 128, 76, 69, 78, 71, 84, 200, 76, 69, 78, 71, 65, 128, 76, 69, - 78, 71, 193, 76, 69, 77, 79, 78, 128, 76, 69, 77, 79, 73, 128, 76, 69, - 76, 69, 84, 128, 76, 69, 76, 69, 212, 76, 69, 203, 76, 69, 73, 77, 77, - 65, 128, 76, 69, 73, 77, 77, 193, 76, 69, 73, 128, 76, 69, 71, 83, 128, - 76, 69, 71, 73, 79, 78, 128, 76, 69, 71, 69, 84, 79, 211, 76, 69, 71, - 128, 76, 69, 199, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, 70, - 84, 45, 84, 79, 45, 82, 73, 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, 69, - 205, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, 65, - 68, 69, 196, 76, 69, 70, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, 69, - 70, 84, 45, 76, 73, 71, 72, 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, - 68, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, - 65, 67, 73, 78, 199, 76, 69, 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, - 128, 76, 69, 69, 75, 128, 76, 69, 69, 69, 69, 128, 76, 69, 68, 71, 69, - 82, 128, 76, 69, 65, 84, 72, 69, 82, 128, 76, 69, 65, 78, 73, 78, 199, - 76, 69, 65, 70, 217, 76, 69, 65, 70, 128, 76, 69, 65, 198, 76, 69, 65, - 68, 69, 82, 128, 76, 69, 65, 196, 76, 68, 65, 78, 128, 76, 68, 50, 128, - 76, 67, 201, 76, 67, 197, 76, 65, 90, 217, 76, 65, 89, 65, 78, 78, 65, - 128, 76, 65, 88, 128, 76, 65, 87, 128, 76, 65, 215, 76, 65, 85, 76, 65, - 128, 76, 65, 85, 75, 65, 218, 76, 65, 85, 74, 128, 76, 65, 85, 71, 72, - 73, 78, 71, 128, 76, 65, 84, 73, 78, 65, 84, 197, 76, 65, 84, 73, 75, - 128, 76, 65, 84, 69, 82, 65, 204, 76, 65, 84, 197, 76, 65, 83, 212, 76, - 65, 82, 89, 78, 71, 69, 65, 204, 76, 65, 82, 201, 76, 65, 82, 71, 69, 83, - 84, 128, 76, 65, 82, 71, 69, 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, - 71, 197, 76, 65, 81, 128, 76, 65, 80, 65, 81, 128, 76, 65, 207, 76, 65, - 78, 84, 69, 82, 78, 128, 76, 65, 78, 84, 65, 78, 71, 128, 76, 65, 78, 71, - 85, 65, 71, 197, 76, 65, 78, 69, 83, 128, 76, 65, 78, 196, 76, 65, 78, - 128, 76, 65, 77, 80, 128, 76, 65, 77, 69, 68, 72, 128, 76, 65, 77, 69, - 68, 128, 76, 65, 77, 69, 196, 76, 65, 77, 69, 128, 76, 65, 77, 197, 76, - 65, 77, 68, 65, 128, 76, 65, 77, 68, 128, 76, 65, 77, 66, 68, 193, 76, - 65, 77, 65, 68, 72, 128, 76, 65, 76, 128, 76, 65, 204, 76, 65, 75, 75, - 72, 65, 78, 71, 89, 65, 79, 128, 76, 65, 75, 72, 65, 78, 128, 76, 65, 75, - 72, 128, 76, 65, 75, 200, 76, 65, 75, 45, 55, 52, 57, 128, 76, 65, 75, - 45, 55, 50, 52, 128, 76, 65, 75, 45, 54, 54, 56, 128, 76, 65, 75, 45, 54, - 52, 56, 128, 76, 65, 75, 45, 54, 52, 184, 76, 65, 75, 45, 54, 51, 54, - 128, 76, 65, 75, 45, 54, 49, 55, 128, 76, 65, 75, 45, 54, 49, 183, 76, - 65, 75, 45, 54, 48, 56, 128, 76, 65, 75, 45, 53, 53, 48, 128, 76, 65, 75, - 45, 52, 57, 53, 128, 76, 65, 75, 45, 52, 57, 51, 128, 76, 65, 75, 45, 52, - 57, 50, 128, 76, 65, 75, 45, 52, 57, 48, 128, 76, 65, 75, 45, 52, 56, 51, - 128, 76, 65, 75, 45, 52, 55, 48, 128, 76, 65, 75, 45, 52, 53, 55, 128, - 76, 65, 75, 45, 52, 53, 48, 128, 76, 65, 75, 45, 52, 52, 57, 128, 76, 65, - 75, 45, 52, 52, 185, 76, 65, 75, 45, 52, 52, 49, 128, 76, 65, 75, 45, 51, - 57, 48, 128, 76, 65, 75, 45, 51, 56, 52, 128, 76, 65, 75, 45, 51, 56, 51, - 128, 76, 65, 75, 45, 51, 52, 56, 128, 76, 65, 75, 45, 51, 52, 55, 128, - 76, 65, 75, 45, 51, 52, 51, 128, 76, 65, 75, 45, 50, 54, 54, 128, 76, 65, - 75, 45, 50, 54, 53, 128, 76, 65, 75, 45, 50, 51, 56, 128, 76, 65, 75, 45, - 50, 50, 56, 128, 76, 65, 75, 45, 50, 50, 53, 128, 76, 65, 75, 45, 50, 50, - 48, 128, 76, 65, 75, 45, 50, 49, 57, 128, 76, 65, 75, 45, 50, 49, 48, - 128, 76, 65, 75, 45, 49, 52, 50, 128, 76, 65, 75, 45, 49, 51, 48, 128, - 76, 65, 75, 45, 48, 57, 50, 128, 76, 65, 75, 45, 48, 56, 49, 128, 76, 65, - 75, 45, 48, 56, 177, 76, 65, 75, 45, 48, 56, 48, 128, 76, 65, 75, 45, 48, - 55, 185, 76, 65, 75, 45, 48, 54, 50, 128, 76, 65, 75, 45, 48, 53, 49, - 128, 76, 65, 75, 45, 48, 53, 48, 128, 76, 65, 75, 45, 48, 51, 48, 128, - 76, 65, 75, 45, 48, 50, 53, 128, 76, 65, 75, 45, 48, 50, 49, 128, 76, 65, - 75, 45, 48, 50, 48, 128, 76, 65, 75, 45, 48, 48, 51, 128, 76, 65, 74, 65, - 78, 89, 65, 76, 65, 78, 128, 76, 65, 73, 78, 199, 76, 65, 201, 76, 65, - 72, 83, 72, 85, 128, 76, 65, 72, 128, 76, 65, 71, 85, 83, 128, 76, 65, - 71, 213, 76, 65, 71, 65, 82, 128, 76, 65, 71, 65, 210, 76, 65, 71, 65, - 66, 128, 76, 65, 71, 65, 194, 76, 65, 69, 86, 128, 76, 65, 69, 128, 76, - 65, 68, 217, 76, 65, 68, 68, 69, 82, 128, 76, 65, 67, 82, 79, 83, 83, - 197, 76, 65, 67, 75, 128, 76, 65, 67, 65, 128, 76, 65, 66, 79, 85, 82, - 73, 78, 71, 128, 76, 65, 66, 79, 82, 128, 76, 65, 66, 73, 65, 76, 73, 90, - 65, 84, 73, 79, 206, 76, 65, 66, 73, 65, 204, 76, 65, 66, 69, 76, 128, - 76, 65, 66, 65, 84, 128, 76, 65, 194, 76, 65, 65, 78, 65, 69, 128, 76, - 65, 65, 78, 128, 76, 65, 65, 77, 85, 128, 76, 65, 65, 73, 128, 76, 54, - 128, 76, 52, 128, 76, 51, 128, 76, 50, 128, 76, 48, 48, 54, 65, 128, 76, - 48, 48, 50, 65, 128, 76, 45, 84, 89, 80, 197, 76, 45, 83, 72, 65, 80, 69, - 196, 75, 89, 85, 82, 73, 73, 128, 75, 89, 85, 128, 75, 89, 79, 128, 75, - 89, 76, 73, 83, 77, 65, 128, 75, 89, 73, 128, 75, 89, 69, 128, 75, 89, - 65, 84, 72, 79, 211, 75, 89, 65, 65, 128, 75, 89, 65, 128, 75, 88, 87, - 73, 128, 75, 88, 87, 69, 69, 128, 75, 88, 87, 69, 128, 75, 88, 87, 65, - 65, 128, 75, 88, 87, 65, 128, 75, 88, 85, 128, 75, 88, 79, 128, 75, 88, - 73, 128, 75, 88, 69, 69, 128, 75, 88, 69, 128, 75, 88, 65, 65, 128, 75, - 88, 65, 128, 75, 87, 86, 128, 75, 87, 85, 51, 49, 56, 128, 75, 87, 79, - 79, 128, 75, 87, 79, 128, 75, 87, 77, 128, 75, 87, 73, 73, 128, 75, 87, - 73, 128, 75, 87, 69, 69, 128, 75, 87, 69, 128, 75, 87, 66, 128, 75, 87, - 65, 89, 128, 75, 87, 65, 69, 84, 128, 75, 87, 65, 65, 128, 75, 86, 65, - 128, 75, 86, 128, 75, 85, 90, 72, 73, 128, 75, 85, 88, 128, 75, 85, 86, - 128, 75, 85, 85, 72, 128, 75, 85, 84, 128, 75, 85, 83, 77, 65, 128, 75, - 85, 83, 72, 85, 50, 128, 75, 85, 83, 72, 85, 178, 75, 85, 82, 88, 128, - 75, 85, 82, 85, 90, 69, 73, 82, 79, 128, 75, 85, 82, 84, 128, 75, 85, 82, - 79, 79, 78, 69, 128, 75, 85, 82, 128, 75, 85, 210, 75, 85, 81, 128, 75, - 85, 80, 78, 65, 89, 65, 128, 75, 85, 79, 88, 128, 75, 85, 79, 80, 128, - 75, 85, 79, 208, 75, 85, 79, 77, 128, 75, 85, 79, 128, 75, 85, 78, 71, - 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, 128, 75, 85, 76, 128, 75, - 85, 204, 75, 85, 71, 128, 75, 85, 70, 73, 83, 77, 65, 128, 75, 85, 69, - 84, 128, 75, 85, 66, 128, 75, 85, 65, 86, 128, 75, 85, 65, 66, 128, 75, - 85, 65, 128, 75, 85, 55, 128, 75, 85, 52, 128, 75, 85, 180, 75, 85, 51, - 128, 75, 85, 179, 75, 85, 45, 55, 128, 75, 85, 45, 54, 128, 75, 85, 45, - 53, 128, 75, 85, 45, 52, 128, 75, 85, 45, 51, 128, 75, 85, 45, 50, 128, - 75, 85, 45, 49, 128, 75, 84, 128, 75, 83, 83, 85, 85, 128, 75, 83, 83, - 85, 128, 75, 83, 83, 79, 79, 128, 75, 83, 83, 79, 128, 75, 83, 83, 73, - 73, 128, 75, 83, 83, 73, 128, 75, 83, 83, 69, 69, 128, 75, 83, 83, 69, - 128, 75, 83, 83, 65, 85, 128, 75, 83, 83, 65, 73, 128, 75, 83, 83, 65, - 65, 128, 75, 83, 83, 65, 128, 75, 83, 83, 128, 75, 83, 73, 128, 75, 82, - 89, 90, 72, 69, 86, 65, 89, 65, 128, 75, 82, 89, 90, 72, 69, 77, 128, 75, - 82, 89, 90, 72, 69, 205, 75, 82, 89, 90, 72, 128, 75, 82, 89, 90, 200, - 75, 82, 89, 85, 75, 79, 86, 65, 89, 65, 128, 75, 82, 89, 85, 75, 79, 86, - 65, 89, 193, 75, 82, 89, 85, 75, 128, 75, 82, 89, 85, 203, 75, 82, 79, - 78, 79, 83, 128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, - 77, 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, - 75, 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, - 128, 75, 82, 65, 84, 73, 77, 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, - 75, 80, 79, 79, 128, 75, 80, 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, - 88, 128, 75, 80, 69, 69, 128, 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, - 128, 75, 80, 65, 78, 128, 75, 80, 65, 72, 128, 75, 80, 65, 128, 75, 80, - 128, 75, 79, 88, 128, 75, 79, 86, 85, 85, 128, 75, 79, 86, 128, 75, 79, - 84, 79, 128, 75, 79, 82, 85, 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, - 128, 75, 79, 82, 79, 78, 128, 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, - 78, 73, 195, 75, 79, 81, 78, 68, 79, 78, 128, 75, 79, 80, 80, 65, 128, - 75, 79, 80, 128, 75, 79, 79, 86, 128, 75, 79, 79, 80, 79, 128, 75, 79, - 79, 77, 85, 85, 84, 128, 75, 79, 79, 66, 128, 75, 79, 79, 128, 75, 79, - 78, 84, 69, 86, 77, 65, 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, - 201, 75, 79, 77, 66, 85, 86, 65, 128, 75, 79, 77, 66, 85, 86, 193, 75, - 79, 77, 66, 213, 75, 79, 75, 79, 128, 75, 79, 75, 69, 128, 75, 79, 75, - 128, 75, 79, 203, 75, 79, 73, 78, 73, 128, 75, 79, 73, 128, 75, 79, 201, - 75, 79, 72, 128, 75, 79, 71, 72, 79, 77, 128, 75, 79, 69, 84, 128, 75, - 79, 66, 89, 76, 65, 128, 75, 79, 66, 128, 75, 79, 65, 76, 65, 128, 75, - 79, 65, 128, 75, 79, 45, 75, 73, 128, 75, 79, 45, 51, 128, 75, 79, 45, - 50, 128, 75, 79, 45, 49, 128, 75, 78, 85, 67, 75, 76, 69, 83, 128, 75, - 78, 85, 67, 75, 76, 69, 128, 75, 78, 79, 84, 128, 75, 78, 79, 66, 83, - 128, 75, 78, 73, 71, 72, 84, 45, 82, 79, 79, 75, 128, 75, 78, 73, 71, 72, - 84, 45, 81, 85, 69, 69, 78, 128, 75, 78, 73, 71, 72, 84, 45, 66, 73, 83, - 72, 79, 80, 128, 75, 78, 73, 71, 72, 84, 128, 75, 78, 73, 71, 72, 212, - 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, 197, 75, 78, 69, 69, 76, 73, 78, - 199, 75, 77, 128, 75, 205, 75, 76, 89, 85, 67, 72, 69, 86, 79, 89, 128, - 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, - 69, 86, 65, 89, 193, 75, 76, 89, 85, 67, 72, 69, 80, 79, 86, 79, 68, 78, - 89, 128, 75, 76, 89, 85, 67, 72, 69, 80, 79, 86, 79, 68, 78, 65, 89, 65, - 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, - 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, 80, 79, 83, 84, 79, 89, - 65, 78, 78, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, 128, 75, 76, 73, 84, - 79, 78, 128, 75, 76, 65, 83, 77, 65, 128, 75, 76, 65, 83, 77, 193, 75, - 76, 65, 128, 75, 76, 128, 75, 75, 79, 128, 75, 75, 73, 128, 75, 75, 69, - 69, 128, 75, 75, 69, 128, 75, 75, 65, 128, 75, 75, 128, 75, 74, 69, 128, - 75, 73, 89, 69, 79, 75, 45, 84, 73, 75, 69, 85, 84, 128, 75, 73, 89, 69, - 79, 75, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 75, 73, 89, - 69, 79, 75, 45, 82, 73, 69, 85, 76, 128, 75, 73, 89, 69, 79, 75, 45, 80, - 73, 69, 85, 80, 128, 75, 73, 89, 69, 79, 75, 45, 78, 73, 69, 85, 78, 128, - 75, 73, 89, 69, 79, 75, 45, 75, 72, 73, 69, 85, 75, 72, 128, 75, 73, 89, - 69, 79, 75, 45, 67, 72, 73, 69, 85, 67, 72, 128, 75, 73, 89, 69, 79, 203, - 75, 73, 88, 128, 75, 73, 87, 73, 70, 82, 85, 73, 84, 128, 75, 73, 87, - 128, 75, 73, 86, 128, 75, 73, 84, 69, 128, 75, 73, 84, 128, 75, 73, 83, - 83, 73, 78, 199, 75, 73, 83, 83, 128, 75, 73, 83, 211, 75, 73, 83, 73, - 77, 53, 128, 75, 73, 83, 73, 77, 181, 75, 73, 83, 72, 128, 75, 73, 83, - 65, 76, 128, 75, 73, 82, 79, 87, 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, - 69, 69, 84, 79, 82, 85, 128, 75, 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, - 75, 73, 82, 79, 128, 75, 73, 82, 71, 72, 73, 218, 75, 73, 81, 128, 75, - 73, 80, 128, 75, 73, 208, 75, 73, 78, 83, 72, 73, 80, 128, 75, 73, 78, - 78, 193, 75, 73, 78, 68, 69, 82, 71, 65, 82, 84, 69, 78, 128, 75, 73, 77, - 79, 78, 79, 128, 75, 73, 76, 76, 69, 82, 128, 75, 73, 73, 90, 72, 128, - 75, 73, 73, 128, 75, 73, 72, 128, 75, 73, 69, 88, 128, 75, 73, 69, 86, - 65, 206, 75, 73, 69, 80, 128, 75, 73, 69, 69, 77, 128, 75, 73, 69, 128, - 75, 73, 68, 128, 75, 73, 196, 75, 73, 67, 75, 128, 75, 73, 66, 128, 75, - 73, 65, 86, 128, 75, 73, 65, 66, 128, 75, 73, 45, 56, 128, 75, 73, 45, - 55, 128, 75, 73, 45, 54, 128, 75, 73, 45, 53, 128, 75, 73, 45, 52, 128, - 75, 73, 45, 51, 128, 75, 73, 45, 50, 128, 75, 73, 45, 49, 128, 75, 72, - 90, 128, 75, 72, 87, 65, 73, 128, 75, 72, 85, 69, 78, 45, 76, 85, 197, - 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, 87, 65, 68, 201, 75, 72, 85, 68, - 65, 77, 128, 75, 72, 85, 65, 84, 128, 75, 72, 79, 85, 128, 75, 72, 79, - 212, 75, 72, 79, 78, 78, 65, 128, 75, 72, 79, 78, 128, 75, 72, 79, 77, - 85, 84, 128, 75, 72, 79, 75, 72, 76, 79, 205, 75, 72, 79, 74, 75, 201, - 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, 213, 75, 72, 73, 84, 128, 75, - 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, 85, 75, 200, 75, 72, 73, 128, - 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, 72, 65, 128, 75, 72, 69, 84, - 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, 69, 128, 75, 72, 69, 128, 75, - 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, 72, 84, 72, 201, 75, 72, 65, 82, - 128, 75, 72, 65, 80, 72, 128, 75, 72, 65, 78, 199, 75, 72, 65, 78, 68, - 65, 128, 75, 72, 65, 78, 68, 193, 75, 72, 65, 77, 84, 201, 75, 72, 65, - 77, 73, 76, 79, 128, 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, 75, 72, 65, - 73, 128, 75, 72, 65, 72, 128, 75, 72, 65, 200, 75, 72, 65, 70, 128, 75, - 72, 65, 66, 128, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, 65, - 80, 128, 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, 128, - 75, 69, 89, 66, 79, 65, 82, 196, 75, 69, 88, 128, 75, 69, 86, 128, 75, - 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, 80, 128, - 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, 75, 69, 85, - 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, 68, 65, - 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, 85, 78, - 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, 69, 83, - 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, 69, 78, - 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, 75, 69, - 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, 75, 69, - 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, 69, 77, - 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, 69, 78, - 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, 206, 75, - 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, 69, 70, - 85, 76, 65, 128, 75, 69, 69, 86, 128, 75, 69, 69, 83, 85, 128, 75, 69, - 69, 80, 73, 78, 199, 75, 69, 69, 78, 71, 128, 75, 69, 69, 66, 128, 75, - 69, 66, 128, 75, 69, 65, 65, 69, 128, 75, 67, 65, 76, 128, 75, 66, 128, - 75, 65, 90, 65, 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, 89, 65, - 200, 75, 65, 88, 128, 75, 65, 87, 86, 128, 75, 65, 87, 73, 128, 75, 65, - 87, 201, 75, 65, 87, 66, 128, 75, 65, 86, 89, 75, 65, 128, 75, 65, 86, - 89, 75, 193, 75, 65, 86, 128, 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, - 128, 75, 65, 85, 206, 75, 65, 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, - 84, 72, 73, 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, - 86, 65, 83, 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, - 78, 65, 45, 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, - 78, 128, 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, - 65, 83, 82, 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, - 75, 65, 83, 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, - 65, 82, 79, 82, 73, 73, 128, 75, 65, 82, 79, 82, 65, 78, 128, 75, 65, 82, - 79, 82, 128, 75, 65, 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, 84, - 84, 79, 128, 75, 65, 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, - 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, - 82, 73, 69, 85, 76, 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, - 85, 80, 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, - 75, 65, 80, 80, 65, 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, 75, - 65, 80, 72, 128, 75, 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, 65, - 208, 75, 65, 78, 84, 65, 74, 193, 75, 65, 78, 78, 65, 68, 193, 75, 65, - 78, 71, 65, 82, 79, 79, 128, 75, 65, 78, 71, 128, 75, 65, 78, 199, 75, - 65, 78, 65, 75, 79, 128, 75, 65, 77, 52, 128, 75, 65, 77, 50, 128, 75, - 65, 77, 128, 75, 65, 75, 84, 79, 86, 73, 203, 75, 65, 75, 79, 128, 75, - 65, 75, 65, 66, 65, 84, 128, 75, 65, 75, 128, 75, 65, 203, 75, 65, 73, - 86, 128, 75, 65, 73, 84, 72, 201, 75, 65, 73, 82, 73, 128, 75, 65, 73, - 66, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, 70, 65, 128, 75, 65, 70, - 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, 68, 181, 75, 65, 68, 52, - 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, 65, 68, 50, 128, 75, 65, - 68, 128, 75, 65, 67, 72, 75, 65, 128, 75, 65, 66, 193, 75, 65, 66, 128, - 75, 65, 65, 86, 128, 75, 65, 65, 73, 128, 75, 65, 65, 70, 85, 128, 75, - 65, 65, 70, 128, 75, 65, 65, 67, 85, 128, 75, 65, 65, 66, 65, 128, 75, - 65, 65, 66, 128, 75, 65, 50, 128, 75, 65, 178, 75, 65, 45, 75, 69, 128, - 75, 65, 45, 57, 128, 75, 65, 45, 56, 128, 75, 65, 45, 55, 128, 75, 65, - 45, 54, 128, 75, 65, 45, 53, 128, 75, 65, 45, 52, 128, 75, 65, 45, 51, - 128, 75, 65, 45, 50, 128, 75, 65, 45, 49, 49, 128, 75, 65, 45, 49, 48, - 128, 75, 65, 45, 49, 128, 75, 48, 48, 56, 128, 75, 48, 48, 55, 128, 75, - 48, 48, 54, 128, 75, 48, 48, 53, 128, 75, 48, 48, 52, 128, 75, 48, 48, - 51, 128, 75, 48, 48, 50, 128, 75, 48, 48, 49, 128, 74, 87, 65, 128, 74, - 85, 85, 128, 74, 85, 84, 128, 74, 85, 83, 84, 73, 70, 73, 67, 65, 84, 73, - 79, 78, 128, 74, 85, 80, 73, 84, 69, 82, 128, 74, 85, 79, 84, 128, 74, - 85, 79, 80, 128, 74, 85, 78, 79, 128, 74, 85, 78, 71, 83, 69, 79, 78, - 199, 74, 85, 78, 69, 128, 74, 85, 76, 89, 128, 74, 85, 71, 71, 76, 73, - 78, 71, 128, 74, 85, 69, 85, 73, 128, 74, 85, 68, 85, 76, 128, 74, 85, - 68, 71, 69, 128, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 74, - 79, 89, 83, 84, 73, 67, 75, 128, 74, 79, 89, 79, 85, 211, 74, 79, 89, - 128, 74, 79, 86, 69, 128, 74, 79, 212, 74, 79, 78, 71, 128, 74, 79, 78, - 193, 74, 79, 75, 69, 82, 128, 74, 79, 73, 78, 84, 83, 128, 74, 79, 73, - 78, 69, 68, 128, 74, 79, 73, 78, 128, 74, 79, 65, 128, 74, 78, 89, 65, - 128, 74, 74, 89, 88, 128, 74, 74, 89, 84, 128, 74, 74, 89, 80, 128, 74, - 74, 89, 128, 74, 74, 85, 88, 128, 74, 74, 85, 84, 128, 74, 74, 85, 82, - 88, 128, 74, 74, 85, 82, 128, 74, 74, 85, 80, 128, 74, 74, 85, 79, 88, - 128, 74, 74, 85, 79, 80, 128, 74, 74, 85, 79, 128, 74, 74, 85, 128, 74, - 74, 79, 88, 128, 74, 74, 79, 84, 128, 74, 74, 79, 80, 128, 74, 74, 79, - 128, 74, 74, 73, 88, 128, 74, 74, 73, 84, 128, 74, 74, 73, 80, 128, 74, - 74, 73, 69, 88, 128, 74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 80, 128, - 74, 74, 73, 69, 128, 74, 74, 73, 128, 74, 74, 69, 69, 128, 74, 74, 69, - 128, 74, 74, 65, 128, 74, 73, 76, 128, 74, 73, 73, 77, 128, 74, 73, 73, - 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, 74, 73, 71, 83, 65, - 215, 74, 73, 65, 128, 74, 72, 79, 88, 128, 74, 72, 79, 128, 74, 72, 69, - 72, 128, 74, 72, 65, 89, 73, 78, 128, 74, 72, 65, 78, 128, 74, 72, 65, - 77, 128, 74, 72, 65, 65, 128, 74, 72, 65, 128, 74, 69, 85, 128, 74, 69, - 82, 85, 83, 65, 76, 69, 77, 128, 74, 69, 82, 65, 206, 74, 69, 82, 65, - 128, 74, 69, 82, 128, 74, 69, 76, 76, 89, 70, 73, 83, 72, 128, 74, 69, - 72, 128, 74, 69, 200, 74, 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, - 128, 74, 69, 69, 205, 74, 69, 65, 78, 83, 128, 74, 65, 89, 78, 128, 74, - 65, 89, 73, 78, 128, 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 87, 128, - 74, 65, 86, 73, 89, 65, 78, 73, 128, 74, 65, 86, 65, 78, 69, 83, 197, 74, - 65, 85, 128, 74, 65, 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, 74, 65, - 80, 65, 78, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, 65, 74, - 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 74, 65, 76, 76, 128, 74, 65, 73, - 206, 74, 65, 73, 128, 74, 65, 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, - 75, 83, 128, 74, 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, 69, 82, 78, 128, - 74, 65, 67, 203, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 73, 90, - 72, 73, 84, 83, 65, 128, 73, 90, 72, 73, 84, 83, 193, 73, 90, 72, 69, - 128, 73, 90, 65, 75, 65, 89, 193, 73, 89, 69, 75, 128, 73, 89, 65, 78, - 78, 65, 128, 73, 85, 74, 65, 128, 73, 84, 211, 73, 84, 69, 82, 65, 84, - 73, 79, 206, 73, 84, 69, 77, 128, 73, 83, 83, 72, 65, 82, 128, 73, 83, - 79, 83, 67, 69, 76, 69, 211, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, - 83, 79, 76, 65, 84, 69, 128, 73, 83, 76, 65, 78, 68, 128, 73, 83, 72, 77, - 65, 65, 77, 128, 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, 65, 75, - 73, 193, 73, 83, 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, 78, 78, - 65, 128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, 45, 67, - 79, 80, 80, 69, 210, 73, 82, 79, 78, 128, 73, 82, 66, 128, 73, 79, 84, - 73, 70, 73, 69, 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, - 73, 79, 84, 193, 73, 79, 82, 128, 73, 79, 78, 71, 128, 73, 79, 68, 72, - 65, 68, 72, 128, 73, 78, 86, 73, 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, - 84, 69, 68, 128, 73, 78, 86, 69, 82, 84, 69, 196, 73, 78, 86, 69, 82, 84, - 69, 66, 82, 65, 84, 69, 128, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, - 79, 68, 85, 67, 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, - 89, 76, 76, 65, 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, - 78, 128, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, - 82, 83, 69, 67, 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, - 71, 128, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 199, 73, 78, 84, 69, 82, - 80, 79, 76, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, - 196, 73, 78, 84, 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, 84, 69, 82, 76, - 65, 67, 69, 196, 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, 84, 69, 82, 69, - 83, 212, 73, 78, 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, 73, 78, 84, 69, - 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, - 206, 73, 78, 84, 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, 71, 82, 65, - 204, 73, 78, 83, 85, 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, - 65, 204, 73, 78, 83, 73, 68, 69, 128, 73, 78, 83, 73, 68, 197, 73, 78, - 83, 69, 82, 84, 73, 79, 206, 73, 78, 83, 69, 82, 212, 73, 78, 83, 69, 67, - 84, 128, 73, 78, 83, 67, 82, 73, 80, 84, 73, 79, 78, 65, 204, 73, 78, 80, - 85, 212, 73, 78, 78, 79, 67, 69, 78, 67, 69, 128, 73, 78, 78, 78, 128, - 73, 78, 78, 69, 82, 128, 73, 78, 78, 69, 210, 73, 78, 78, 128, 73, 78, - 73, 78, 71, 85, 128, 73, 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, - 78, 212, 73, 78, 72, 65, 76, 69, 128, 73, 78, 71, 87, 65, 90, 128, 73, - 78, 70, 79, 82, 77, 65, 84, 73, 79, 206, 73, 78, 70, 76, 85, 69, 78, 67, - 69, 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 73, 78, 70, 73, 78, 73, 84, - 217, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73, 78, 68, 73, 82, 69, 67, - 212, 73, 78, 68, 73, 67, 84, 73, 79, 206, 73, 78, 68, 73, 67, 65, 84, 79, - 82, 128, 73, 78, 68, 73, 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, - 78, 68, 73, 65, 206, 73, 78, 68, 69, 88, 128, 73, 78, 68, 69, 80, 69, 78, - 68, 69, 78, 212, 73, 78, 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, 67, 82, - 69, 65, 83, 69, 211, 73, 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, 67, 82, - 69, 65, 83, 197, 73, 78, 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67, 79, - 77, 73, 78, 199, 73, 78, 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 72, - 128, 73, 78, 66, 79, 216, 73, 78, 65, 80, 128, 73, 78, 45, 65, 76, 65, - 70, 128, 73, 77, 80, 69, 82, 73, 65, 204, 73, 77, 80, 69, 82, 70, 69, 67, - 84, 85, 205, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 128, 73, 77, 80, 69, - 82, 70, 69, 67, 84, 193, 73, 77, 78, 128, 73, 77, 73, 83, 69, 79, 211, - 73, 77, 73, 78, 51, 128, 73, 77, 73, 78, 128, 73, 77, 73, 206, 73, 77, - 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 77, 73, 70, 84, 72, 79, 82, 65, - 128, 73, 77, 73, 70, 79, 78, 79, 78, 128, 73, 77, 73, 68, 73, 65, 82, 71, - 79, 78, 128, 73, 77, 65, 71, 197, 73, 77, 65, 65, 76, 65, 128, 73, 76, - 85, 89, 65, 78, 78, 65, 128, 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, - 78, 78, 65, 128, 73, 76, 85, 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, - 73, 76, 73, 77, 77, 85, 51, 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, - 77, 77, 213, 73, 76, 50, 128, 73, 75, 73, 82, 128, 73, 75, 65, 82, 65, - 128, 73, 75, 65, 82, 193, 73, 74, 128, 73, 73, 89, 65, 78, 78, 65, 128, - 73, 71, 73, 128, 73, 71, 201, 73, 71, 71, 87, 83, 128, 73, 70, 73, 78, - 128, 73, 69, 85, 78, 71, 45, 84, 73, 75, 69, 85, 84, 128, 73, 69, 85, 78, - 71, 45, 84, 72, 73, 69, 85, 84, 72, 128, 73, 69, 85, 78, 71, 45, 82, 73, - 69, 85, 76, 128, 73, 69, 85, 78, 71, 45, 80, 73, 69, 85, 80, 128, 73, 69, - 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, 73, 69, 85, 78, 71, 45, - 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85, 67, - 72, 128, 73, 69, 85, 78, 199, 73, 68, 76, 69, 128, 73, 68, 73, 77, 128, - 73, 68, 73, 205, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, - 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 57, 49, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, - 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 68, 55, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 67, 65, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, - 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 54, 68, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 51, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, - 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 69, 56, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 50, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, - 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 57, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 53, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, - 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 52, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 70, 56, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, - 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 57, 49, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 56, 70, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, - 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 51, 67, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 68, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, - 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 65, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 56, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 66, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 50, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 66, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 50, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 66, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 65, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 50, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 200, 73, 68, 69, 78, 84, 73, - 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68, 69, 78, 84, 73, 70, 73, 67, - 65, 84, 73, 79, 206, 73, 68, 69, 78, 84, 73, 67, 65, 204, 73, 68, 68, - 128, 73, 67, 79, 78, 128, 73, 67, 72, 79, 85, 128, 73, 67, 72, 79, 83, - 128, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 73, 67, 72, 65, 68, 73, 78, - 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 66, 73, 70, - 73, 76, 73, 128, 73, 65, 85, 68, 65, 128, 73, 48, 49, 53, 128, 73, 48, - 49, 52, 128, 73, 48, 49, 51, 128, 73, 48, 49, 50, 128, 73, 48, 49, 49, - 65, 128, 73, 48, 49, 49, 128, 73, 48, 49, 48, 65, 128, 73, 48, 49, 48, - 128, 73, 48, 48, 57, 65, 128, 73, 48, 48, 57, 128, 73, 48, 48, 56, 128, - 73, 48, 48, 55, 128, 73, 48, 48, 54, 128, 73, 48, 48, 53, 65, 128, 73, - 48, 48, 53, 128, 73, 48, 48, 52, 128, 73, 48, 48, 51, 128, 73, 48, 48, - 50, 128, 73, 48, 48, 49, 128, 73, 45, 89, 85, 128, 73, 45, 89, 79, 128, - 73, 45, 89, 69, 79, 128, 73, 45, 89, 69, 128, 73, 45, 89, 65, 69, 128, - 73, 45, 89, 65, 45, 79, 128, 73, 45, 89, 65, 128, 73, 45, 79, 45, 73, - 128, 73, 45, 79, 128, 73, 45, 69, 85, 128, 73, 45, 66, 69, 65, 77, 128, - 73, 45, 65, 82, 65, 69, 65, 128, 73, 45, 65, 128, 72, 90, 90, 90, 71, - 128, 72, 90, 90, 90, 128, 72, 90, 90, 80, 128, 72, 90, 90, 128, 72, 90, - 87, 71, 128, 72, 90, 87, 128, 72, 90, 84, 128, 72, 90, 71, 128, 72, 89, - 83, 84, 69, 82, 69, 83, 73, 211, 72, 89, 80, 79, 68, 73, 65, 83, 84, 79, - 76, 69, 128, 72, 89, 80, 72, 69, 78, 65, 84, 73, 79, 206, 72, 89, 80, 72, - 69, 78, 45, 77, 73, 78, 85, 83, 128, 72, 89, 80, 72, 69, 78, 128, 72, 89, - 80, 72, 69, 206, 72, 89, 71, 73, 69, 73, 65, 128, 72, 89, 71, 73, 69, 65, - 128, 72, 89, 65, 67, 73, 78, 84, 72, 128, 72, 88, 87, 71, 128, 72, 88, - 85, 79, 88, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, - 88, 85, 79, 128, 72, 88, 79, 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, - 80, 128, 72, 88, 79, 128, 72, 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, - 88, 73, 80, 128, 72, 88, 73, 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, - 88, 73, 69, 80, 128, 72, 88, 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, - 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, - 88, 65, 84, 128, 72, 88, 65, 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, - 72, 87, 65, 73, 82, 128, 72, 87, 65, 72, 128, 72, 85, 86, 65, 128, 72, - 85, 83, 72, 69, 196, 72, 85, 83, 72, 128, 72, 85, 82, 65, 78, 128, 72, - 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 83, 128, 72, 85, 78, 68, 82, - 69, 68, 211, 72, 85, 78, 68, 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, - 196, 72, 85, 78, 128, 72, 85, 77, 208, 72, 85, 77, 65, 78, 128, 72, 85, - 77, 65, 206, 72, 85, 76, 50, 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, - 71, 71, 73, 78, 71, 128, 72, 85, 71, 71, 73, 78, 199, 72, 85, 66, 50, - 128, 72, 85, 66, 178, 72, 85, 66, 128, 72, 85, 65, 82, 65, 68, 68, 79, - 128, 72, 85, 65, 78, 128, 72, 85, 45, 51, 128, 72, 85, 45, 50, 128, 72, - 85, 45, 49, 128, 72, 84, 84, 65, 128, 72, 84, 83, 128, 72, 84, 74, 128, - 72, 82, 89, 86, 78, 73, 193, 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, - 80, 128, 72, 79, 85, 83, 197, 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, - 72, 79, 85, 82, 71, 76, 65, 83, 211, 72, 79, 85, 82, 128, 72, 79, 85, - 210, 72, 79, 84, 69, 76, 128, 72, 79, 84, 65, 128, 72, 79, 83, 80, 73, - 84, 65, 76, 128, 72, 79, 82, 83, 69, 128, 72, 79, 82, 83, 197, 72, 79, - 82, 82, 128, 72, 79, 82, 78, 83, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 76, 89, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 54, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 53, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 53, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 53, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 53, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, - 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, - 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, - 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 51, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 51, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 51, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 51, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 50, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, - 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, - 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, - 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 48, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 48, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 48, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 48, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 48, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, - 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, - 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 204, 72, 79, 82, 73, 128, 72, 79, 82, 193, 72, 79, - 79, 85, 128, 72, 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, - 78, 128, 72, 79, 79, 75, 69, 68, 128, 72, 79, 79, 75, 69, 196, 72, 79, - 78, 69, 89, 66, 69, 69, 128, 72, 79, 78, 69, 217, 72, 79, 77, 79, 84, 72, - 69, 84, 73, 67, 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 79, 76, - 79, 128, 72, 79, 76, 76, 79, 215, 72, 79, 76, 69, 128, 72, 79, 76, 68, - 73, 78, 199, 72, 79, 76, 65, 77, 128, 72, 79, 76, 65, 205, 72, 79, 75, - 65, 128, 72, 79, 67, 75, 69, 217, 72, 79, 67, 72, 79, 128, 72, 79, 45, - 56, 128, 72, 79, 45, 55, 128, 72, 79, 45, 54, 128, 72, 79, 45, 53, 128, - 72, 79, 45, 52, 128, 72, 79, 45, 51, 128, 72, 79, 45, 50, 128, 72, 79, - 45, 49, 128, 72, 78, 85, 84, 128, 72, 78, 85, 79, 88, 128, 72, 78, 85, - 79, 128, 72, 78, 85, 66, 128, 72, 78, 79, 88, 128, 72, 78, 79, 84, 128, - 72, 78, 79, 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, 72, 78, - 73, 80, 128, 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, 72, 78, - 73, 69, 80, 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, 69, 88, - 128, 72, 78, 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, 72, 78, - 65, 85, 128, 72, 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, 65, 128, - 72, 77, 89, 88, 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, 128, 72, - 77, 89, 80, 128, 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, 85, 84, - 128, 72, 77, 85, 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, 80, 128, - 72, 77, 85, 79, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, 79, 128, - 72, 77, 85, 128, 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, 77, 79, - 80, 128, 72, 77, 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, 128, 72, - 77, 73, 80, 128, 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, 128, 72, - 77, 73, 69, 128, 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, 88, 128, - 72, 77, 65, 84, 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, 76, 89, - 88, 128, 72, 76, 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, 89, 82, - 128, 72, 76, 89, 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, 72, 76, - 85, 84, 128, 72, 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, 76, 85, - 80, 128, 72, 76, 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, - 79, 128, 72, 76, 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, 128, 72, - 76, 79, 128, 72, 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, 73, 80, - 128, 72, 76, 73, 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, 73, 69, - 128, 72, 76, 73, 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, 72, 76, - 69, 128, 72, 76, 65, 88, 128, 72, 76, 65, 85, 128, 72, 76, 65, 84, 128, - 72, 76, 65, 80, 128, 72, 76, 65, 128, 72, 76, 128, 72, 75, 128, 72, 73, - 90, 66, 128, 72, 73, 89, 79, 128, 72, 73, 84, 84, 73, 78, 199, 72, 73, - 83, 84, 79, 82, 73, 195, 72, 73, 82, 73, 81, 128, 72, 73, 80, 80, 79, 80, - 79, 84, 65, 77, 85, 83, 128, 72, 73, 78, 71, 69, 68, 128, 72, 73, 78, 71, - 69, 196, 72, 73, 78, 71, 69, 128, 72, 73, 78, 68, 213, 72, 73, 75, 73, - 78, 199, 72, 73, 71, 72, 45, 83, 80, 69, 69, 196, 72, 73, 71, 72, 45, 82, - 69, 86, 69, 82, 83, 69, 68, 45, 185, 72, 73, 71, 72, 45, 76, 79, 215, 72, - 73, 71, 72, 45, 72, 69, 69, 76, 69, 196, 72, 73, 69, 88, 128, 72, 73, 69, - 85, 72, 45, 83, 73, 79, 83, 128, 72, 73, 69, 85, 72, 45, 82, 73, 69, 85, - 76, 128, 72, 73, 69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, - 72, 45, 78, 73, 69, 85, 78, 128, 72, 73, 69, 85, 72, 45, 77, 73, 69, 85, - 77, 128, 72, 73, 69, 85, 200, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, - 195, 72, 73, 68, 73, 78, 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, - 128, 72, 73, 66, 73, 83, 67, 85, 83, 128, 72, 73, 45, 82, 69, 83, 128, - 72, 73, 45, 55, 128, 72, 73, 45, 54, 128, 72, 73, 45, 53, 128, 72, 73, - 45, 52, 128, 72, 73, 45, 51, 128, 72, 73, 45, 50, 128, 72, 73, 45, 49, - 128, 72, 72, 89, 85, 128, 72, 72, 89, 79, 128, 72, 72, 89, 73, 128, 72, - 72, 89, 69, 69, 128, 72, 72, 89, 69, 128, 72, 72, 89, 65, 65, 128, 72, - 72, 89, 65, 128, 72, 72, 87, 73, 128, 72, 72, 87, 69, 69, 128, 72, 72, - 87, 69, 128, 72, 72, 87, 65, 128, 72, 72, 85, 128, 72, 72, 73, 128, 72, - 72, 69, 69, 128, 72, 72, 69, 128, 72, 72, 65, 65, 128, 72, 71, 128, 72, - 69, 89, 84, 128, 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, - 65, 205, 72, 69, 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, 85, 128, - 72, 69, 82, 85, 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, - 73, 79, 78, 73, 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, 82, 69, - 128, 72, 69, 82, 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 78, 71, - 128, 72, 69, 78, 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, 84, 128, - 72, 69, 76, 77, 69, 212, 72, 69, 76, 205, 72, 69, 76, 76, 83, 67, 72, 82, - 69, 73, 66, 69, 210, 72, 69, 76, 73, 88, 128, 72, 69, 76, 73, 67, 79, 80, - 84, 69, 82, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, - 69, 73, 128, 72, 69, 73, 71, 72, 84, 128, 72, 69, 69, 73, 128, 72, 69, - 68, 71, 69, 72, 79, 71, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, - 78, 76, 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, - 69, 65, 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, - 72, 69, 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 73, 78, - 199, 72, 69, 65, 82, 45, 78, 79, 45, 69, 86, 73, 204, 72, 69, 65, 68, 83, - 84, 82, 79, 75, 69, 128, 72, 69, 65, 68, 83, 84, 79, 78, 69, 128, 72, 69, - 65, 68, 83, 84, 79, 78, 197, 72, 69, 65, 68, 83, 67, 65, 82, 70, 128, 72, - 69, 65, 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, 68, 73, 78, 71, 128, 72, - 69, 65, 68, 45, 66, 65, 78, 68, 65, 71, 69, 128, 72, 69, 45, 55, 128, 72, - 69, 45, 54, 128, 72, 69, 45, 53, 128, 72, 69, 45, 52, 128, 72, 69, 45, - 51, 128, 72, 69, 45, 50, 128, 72, 69, 45, 49, 128, 72, 68, 82, 128, 72, - 67, 128, 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, 65, 83, - 193, 72, 65, 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, 128, 72, 65, 86, - 69, 128, 72, 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 85, 77, - 69, 65, 128, 72, 65, 213, 72, 65, 84, 82, 65, 206, 72, 65, 84, 72, 73, - 128, 72, 65, 84, 69, 128, 72, 65, 84, 67, 72, 73, 78, 199, 72, 65, 84, - 65, 198, 72, 65, 83, 69, 210, 72, 65, 83, 65, 78, 84, 65, 128, 72, 65, - 82, 80, 79, 79, 78, 128, 72, 65, 82, 80, 79, 79, 206, 72, 65, 82, 77, 79, - 78, 73, 67, 128, 72, 65, 82, 75, 76, 69, 65, 206, 72, 65, 82, 68, 78, 69, - 83, 83, 128, 72, 65, 82, 196, 72, 65, 82, 66, 65, 72, 65, 89, 128, 72, - 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, 72, 65, 78, 73, 70, 201, - 72, 65, 78, 71, 90, 72, 79, 213, 72, 65, 78, 68, 83, 72, 65, 75, 69, 128, - 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, 211, 72, 65, 78, 68, 76, 69, 83, - 128, 72, 65, 78, 68, 76, 69, 128, 72, 65, 78, 68, 66, 65, 76, 76, 128, - 72, 65, 78, 68, 66, 65, 71, 128, 72, 65, 78, 68, 45, 79, 86, 65, 76, 128, - 72, 65, 78, 68, 45, 79, 86, 65, 204, 72, 65, 78, 68, 45, 72, 79, 79, 75, - 128, 72, 65, 78, 68, 45, 72, 79, 79, 203, 72, 65, 78, 68, 45, 72, 73, 78, - 71, 69, 128, 72, 65, 78, 68, 45, 72, 73, 78, 71, 197, 72, 65, 78, 68, 45, - 70, 76, 65, 84, 128, 72, 65, 78, 68, 45, 70, 76, 65, 212, 72, 65, 78, 68, - 45, 70, 73, 83, 84, 128, 72, 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, - 69, 128, 72, 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, 197, 72, 65, 78, - 68, 45, 67, 85, 80, 128, 72, 65, 78, 68, 45, 67, 85, 208, 72, 65, 78, 68, - 45, 67, 76, 65, 87, 128, 72, 65, 78, 68, 45, 67, 76, 65, 215, 72, 65, 78, - 68, 45, 67, 73, 82, 67, 76, 69, 128, 72, 65, 78, 68, 45, 67, 73, 82, 67, - 76, 197, 72, 65, 78, 68, 45, 65, 78, 71, 76, 69, 128, 72, 65, 78, 68, 45, - 65, 78, 71, 76, 197, 72, 65, 78, 68, 128, 72, 65, 78, 45, 65, 75, 65, 84, - 128, 72, 65, 77, 90, 65, 128, 72, 65, 77, 90, 193, 72, 65, 77, 83, 84, - 69, 210, 72, 65, 77, 83, 65, 128, 72, 65, 77, 77, 69, 82, 128, 72, 65, - 77, 77, 69, 210, 72, 65, 77, 66, 85, 82, 71, 69, 82, 128, 72, 65, 76, 81, - 65, 128, 72, 65, 76, 79, 128, 72, 65, 76, 70, 45, 67, 73, 82, 67, 76, - 197, 72, 65, 76, 70, 45, 50, 128, 72, 65, 76, 70, 45, 49, 128, 72, 65, - 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, 76, 65, 78, 84, 65, - 128, 72, 65, 73, 84, 85, 128, 72, 65, 73, 211, 72, 65, 73, 82, 67, 85, - 84, 128, 72, 65, 71, 76, 65, 218, 72, 65, 71, 76, 128, 72, 65, 70, 85, - 75, 72, 65, 128, 72, 65, 70, 85, 75, 72, 128, 72, 65, 69, 71, 204, 72, - 65, 68, 69, 83, 128, 72, 65, 65, 82, 85, 128, 72, 65, 65, 77, 128, 72, - 65, 193, 72, 65, 45, 72, 65, 128, 72, 65, 45, 57, 128, 72, 65, 45, 56, - 128, 72, 65, 45, 55, 128, 72, 65, 45, 54, 128, 72, 65, 45, 53, 128, 72, - 65, 45, 52, 128, 72, 65, 45, 51, 128, 72, 65, 45, 50, 128, 72, 65, 45, - 49, 49, 128, 72, 65, 45, 49, 48, 128, 72, 65, 45, 49, 128, 72, 48, 48, - 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, 54, 65, 128, 72, 48, 48, 54, - 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, 128, 72, 48, 48, 51, 128, 72, - 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, 45, 84, 89, 80, 197, 71, 89, - 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, 128, 71, 89, 73, 128, 71, 89, - 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, 83, 128, 71, 89, 65, 65, 128, - 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, 128, 71, 87, 73, 128, 71, 87, - 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, 65, 128, 71, 87, 65, 128, 71, - 87, 128, 71, 86, 65, 78, 71, 128, 71, 86, 128, 71, 85, 82, 85, 83, 72, - 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, 77, 85, 75, 72, 201, 71, 85, - 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, 65, 71, 197, 71, 85, 82, 55, - 128, 71, 85, 78, 85, 128, 71, 85, 78, 213, 71, 85, 78, 74, 65, 76, 193, - 71, 85, 205, 71, 85, 76, 128, 71, 85, 74, 65, 82, 65, 84, 201, 71, 85, - 73, 84, 65, 82, 128, 71, 85, 73, 68, 197, 71, 85, 199, 71, 85, 69, 73, - 128, 71, 85, 69, 72, 128, 71, 85, 69, 200, 71, 85, 68, 128, 71, 85, 196, - 71, 85, 65, 82, 68, 83, 77, 65, 78, 128, 71, 85, 65, 82, 68, 69, 68, 78, - 69, 83, 83, 128, 71, 85, 65, 82, 68, 69, 196, 71, 85, 65, 82, 68, 128, - 71, 85, 65, 82, 65, 78, 201, 71, 85, 193, 71, 85, 178, 71, 84, 69, 210, - 71, 83, 85, 77, 128, 71, 83, 85, 205, 71, 82, 213, 71, 82, 79, 87, 73, - 78, 199, 71, 82, 79, 85, 78, 68, 128, 71, 82, 79, 78, 84, 72, 73, 83, 77, - 65, 84, 65, 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, - 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, 68, 78, 65, 89, 193, 71, 82, 79, - 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, 128, 71, 82, 79, 77, 79, - 75, 82, 89, 90, 72, 69, 86, 65, 89, 193, 71, 82, 79, 77, 78, 65, 89, 65, - 128, 71, 82, 79, 77, 78, 65, 89, 193, 71, 82, 73, 78, 78, 73, 78, 199, - 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, 69, 217, 71, 82, 69, 71, 79, - 82, 73, 65, 206, 71, 82, 69, 69, 78, 128, 71, 82, 69, 69, 206, 71, 82, - 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, - 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 206, 71, 82, 69, - 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, 86, 69, 89, 65, 82, - 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 71, 82, 65, 86, - 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, 128, 71, 82, 65, 86, - 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, 83, 128, 71, 82, 65, - 83, 211, 71, 82, 65, 83, 208, 71, 82, 65, 80, 72, 69, 77, 197, 71, 82, - 65, 80, 69, 83, 128, 71, 82, 65, 78, 84, 72, 193, 71, 82, 65, 77, 77, - 193, 71, 82, 65, 73, 78, 128, 71, 82, 65, 70, 128, 71, 82, 65, 68, 85, - 65, 84, 73, 79, 206, 71, 82, 65, 68, 85, 65, 76, 128, 71, 82, 65, 67, 69, - 128, 71, 82, 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, 73, - 75, 79, 206, 71, 79, 82, 84, 128, 71, 79, 82, 73, 76, 76, 65, 128, 71, - 79, 82, 71, 79, 84, 69, 82, 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, 84, - 72, 69, 84, 79, 78, 128, 71, 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, - 128, 71, 79, 82, 65, 90, 68, 207, 71, 79, 82, 65, 128, 71, 79, 79, 83, - 69, 128, 71, 79, 79, 196, 71, 79, 78, 71, 71, 79, 78, 71, 128, 71, 79, - 76, 85, 66, 67, 72, 73, 203, 71, 79, 76, 70, 69, 82, 128, 71, 79, 76, 68, - 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, 71, 79, 71, 71, 76, 69, 83, - 128, 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, 76, 128, 71, 79, 65, 204, - 71, 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, 78, 65, 86, 73, 89, 65, 78, - 73, 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, 79, 86, 69, 83, 128, 71, - 76, 79, 86, 69, 128, 71, 76, 79, 84, 84, 65, 204, 71, 76, 79, 66, 197, - 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, 69, 73, 67, 200, 71, 76, 65, - 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, 74, 69, 128, 71, 73, 88, 128, - 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, 73, 83, 200, 71, 73, 83, 65, - 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 73, 82, 76, 211, 71, 73, - 82, 76, 128, 71, 73, 82, 65, 70, 70, 197, 71, 73, 82, 51, 128, 71, 73, - 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, 178, 71, 73, 80, 128, 71, 73, - 78, 73, 73, 128, 71, 73, 78, 71, 69, 210, 71, 73, 77, 69, 76, 45, 72, 69, - 84, 72, 128, 71, 73, 77, 69, 76, 128, 71, 73, 77, 69, 204, 71, 73, 77, - 128, 71, 73, 71, 65, 128, 71, 73, 71, 128, 71, 73, 70, 212, 71, 73, 69, - 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, 79, 85, 211, 71, 73, - 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, 90, 128, 71, 72, 87, - 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, 78, 78, 193, 71, 72, - 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, 128, 71, 72, 79, 128, - 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, 71, 72, 72, 65, 128, 71, - 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, 71, 72, 69, 85, 78, 128, - 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, 71, 72, 69, 85, 71, 72, - 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, 128, 71, 72, 69, 85, 65, - 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, 128, 71, 72, 69, 69, - 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, 78, 128, 71, 72, 65, - 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, 78, 128, 71, 72, 65, - 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, 65, 73, 78, 85, - 128, 71, 72, 65, 73, 78, 128, 71, 72, 65, 73, 206, 71, 72, 65, 68, 128, - 71, 72, 65, 65, 77, 65, 69, 128, 71, 72, 65, 65, 128, 71, 71, 87, 73, - 128, 71, 71, 87, 69, 69, 128, 71, 71, 87, 69, 128, 71, 71, 87, 65, 65, - 128, 71, 71, 87, 65, 128, 71, 71, 85, 88, 128, 71, 71, 85, 84, 128, 71, - 71, 85, 82, 88, 128, 71, 71, 85, 82, 128, 71, 71, 85, 79, 88, 128, 71, - 71, 85, 79, 84, 128, 71, 71, 85, 79, 80, 128, 71, 71, 85, 79, 128, 71, - 71, 79, 88, 128, 71, 71, 79, 84, 128, 71, 71, 79, 80, 128, 71, 71, 73, - 88, 128, 71, 71, 73, 84, 128, 71, 71, 73, 69, 88, 128, 71, 71, 73, 69, - 80, 128, 71, 71, 73, 69, 128, 71, 71, 69, 88, 128, 71, 71, 69, 84, 128, - 71, 71, 69, 80, 128, 71, 71, 65, 88, 128, 71, 71, 65, 84, 128, 71, 69, - 84, 193, 71, 69, 83, 84, 85, 82, 69, 128, 71, 69, 83, 72, 85, 128, 71, - 69, 83, 72, 84, 73, 78, 128, 71, 69, 83, 72, 84, 73, 206, 71, 69, 83, 72, - 50, 128, 71, 69, 82, 83, 72, 65, 89, 73, 77, 128, 71, 69, 82, 77, 65, - 206, 71, 69, 82, 69, 83, 72, 128, 71, 69, 82, 69, 83, 200, 71, 69, 79, - 77, 69, 84, 82, 73, 67, 65, 76, 76, 217, 71, 69, 79, 77, 69, 84, 82, 73, - 195, 71, 69, 78, 84, 76, 197, 71, 69, 78, 73, 84, 73, 86, 69, 128, 71, - 69, 78, 73, 75, 201, 71, 69, 78, 73, 69, 128, 71, 69, 78, 69, 82, 73, - 195, 71, 69, 78, 69, 82, 65, 76, 128, 71, 69, 77, 73, 78, 73, 128, 71, - 69, 77, 73, 78, 65, 84, 73, 79, 206, 71, 69, 77, 73, 78, 65, 84, 197, 71, - 69, 205, 71, 69, 69, 77, 128, 71, 69, 68, 79, 76, 65, 128, 71, 69, 68, - 69, 128, 71, 69, 66, 207, 71, 69, 66, 193, 71, 69, 65, 82, 128, 71, 69, - 65, 210, 71, 69, 50, 50, 128, 71, 68, 65, 78, 128, 71, 67, 73, 71, 128, - 71, 67, 65, 206, 71, 66, 79, 78, 128, 71, 66, 73, 69, 197, 71, 66, 69, - 85, 88, 128, 71, 66, 69, 84, 128, 71, 66, 65, 89, 73, 128, 71, 66, 65, - 75, 85, 82, 85, 78, 69, 78, 128, 71, 66, 128, 71, 65, 89, 65, 78, 85, 75, - 73, 84, 84, 65, 128, 71, 65, 89, 65, 78, 78, 65, 128, 71, 65, 89, 128, - 71, 65, 85, 78, 84, 76, 69, 84, 128, 71, 65, 84, 72, 69, 82, 73, 78, 71, - 128, 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 65, 84, 69, 128, 71, 65, - 83, 72, 65, 78, 128, 71, 65, 82, 83, 72, 85, 78, 73, 128, 71, 65, 82, 79, - 78, 128, 71, 65, 82, 77, 69, 78, 84, 128, 71, 65, 82, 76, 73, 67, 128, - 71, 65, 82, 68, 69, 78, 128, 71, 65, 82, 51, 128, 71, 65, 80, 80, 69, - 196, 71, 65, 208, 71, 65, 78, 77, 65, 128, 71, 65, 78, 71, 73, 65, 128, - 71, 65, 78, 68, 193, 71, 65, 78, 50, 128, 71, 65, 78, 178, 71, 65, 77, - 77, 65, 128, 71, 65, 77, 76, 65, 128, 71, 65, 77, 76, 128, 71, 65, 77, - 69, 128, 71, 65, 77, 197, 71, 65, 77, 65, 78, 128, 71, 65, 77, 65, 76, - 128, 71, 65, 77, 65, 204, 71, 65, 76, 201, 71, 65, 71, 128, 71, 65, 70, - 128, 71, 65, 198, 71, 65, 69, 84, 84, 65, 45, 80, 73, 76, 76, 65, 128, - 71, 65, 68, 79, 76, 128, 71, 65, 68, 128, 71, 65, 196, 71, 65, 66, 65, - 128, 71, 65, 66, 193, 71, 65, 65, 70, 85, 128, 71, 65, 178, 71, 48, 53, - 52, 128, 71, 48, 53, 51, 128, 71, 48, 53, 50, 128, 71, 48, 53, 49, 128, - 71, 48, 53, 48, 128, 71, 48, 52, 57, 128, 71, 48, 52, 56, 128, 71, 48, - 52, 55, 128, 71, 48, 52, 54, 128, 71, 48, 52, 53, 65, 128, 71, 48, 52, - 53, 128, 71, 48, 52, 52, 128, 71, 48, 52, 51, 65, 128, 71, 48, 52, 51, - 128, 71, 48, 52, 50, 128, 71, 48, 52, 49, 128, 71, 48, 52, 48, 128, 71, - 48, 51, 57, 128, 71, 48, 51, 56, 128, 71, 48, 51, 55, 65, 128, 71, 48, - 51, 55, 128, 71, 48, 51, 54, 65, 128, 71, 48, 51, 54, 128, 71, 48, 51, - 53, 128, 71, 48, 51, 52, 128, 71, 48, 51, 51, 128, 71, 48, 51, 50, 128, - 71, 48, 51, 49, 128, 71, 48, 51, 48, 128, 71, 48, 50, 57, 128, 71, 48, - 50, 56, 128, 71, 48, 50, 55, 128, 71, 48, 50, 54, 65, 128, 71, 48, 50, - 54, 128, 71, 48, 50, 53, 128, 71, 48, 50, 52, 128, 71, 48, 50, 51, 128, - 71, 48, 50, 50, 128, 71, 48, 50, 49, 128, 71, 48, 50, 48, 65, 128, 71, - 48, 50, 48, 128, 71, 48, 49, 57, 128, 71, 48, 49, 56, 128, 71, 48, 49, - 55, 128, 71, 48, 49, 54, 128, 71, 48, 49, 53, 128, 71, 48, 49, 52, 128, - 71, 48, 49, 51, 128, 71, 48, 49, 50, 128, 71, 48, 49, 49, 65, 128, 71, - 48, 49, 49, 128, 71, 48, 49, 48, 128, 71, 48, 48, 57, 128, 71, 48, 48, - 56, 128, 71, 48, 48, 55, 66, 128, 71, 48, 48, 55, 65, 128, 71, 48, 48, - 55, 128, 71, 48, 48, 54, 65, 128, 71, 48, 48, 54, 128, 71, 48, 48, 53, - 128, 71, 48, 48, 52, 128, 71, 48, 48, 51, 128, 71, 48, 48, 50, 128, 71, - 48, 48, 49, 128, 70, 89, 88, 128, 70, 89, 84, 128, 70, 89, 80, 128, 70, - 89, 65, 128, 70, 87, 73, 128, 70, 87, 69, 69, 128, 70, 87, 69, 128, 70, - 87, 65, 65, 128, 70, 87, 65, 128, 70, 86, 83, 52, 128, 70, 86, 83, 51, - 128, 70, 86, 83, 50, 128, 70, 86, 83, 49, 128, 70, 85, 88, 128, 70, 85, - 84, 128, 70, 85, 83, 69, 128, 70, 85, 83, 193, 70, 85, 82, 88, 128, 70, - 85, 80, 128, 70, 85, 78, 69, 82, 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, - 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 87, 73, 68, - 84, 200, 70, 85, 76, 76, 78, 69, 83, 83, 128, 70, 85, 76, 204, 70, 85, - 74, 73, 128, 70, 85, 69, 84, 128, 70, 85, 69, 204, 70, 85, 69, 128, 70, - 85, 65, 128, 70, 84, 72, 79, 82, 193, 70, 83, 73, 128, 70, 82, 79, 87, - 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, 73, 78, 199, 70, 82, 79, 87, 78, - 128, 70, 82, 79, 87, 206, 70, 82, 79, 78, 84, 45, 84, 73, 76, 84, 69, - 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, 70, 82, 79, 78, - 212, 70, 82, 79, 205, 70, 82, 79, 71, 128, 70, 82, 79, 199, 70, 82, 73, - 84, 85, 128, 70, 82, 73, 69, 83, 128, 70, 82, 73, 69, 196, 70, 82, 73, - 67, 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, 66, 79, 65, 82, 68, 128, 70, - 82, 69, 78, 67, 200, 70, 82, 69, 69, 90, 73, 78, 199, 70, 82, 69, 69, - 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, 70, 82, 65, 78, 195, 70, - 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, 128, 70, 82, 65, 77, 197, - 70, 82, 65, 75, 84, 85, 210, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 82, - 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, 84, 73, 79, 206, 70, 79, 88, - 128, 70, 79, 216, 70, 79, 85, 82, 84, 69, 69, 78, 128, 70, 79, 85, 82, - 84, 69, 69, 206, 70, 79, 85, 82, 45, 84, 72, 73, 82, 84, 89, 128, 70, 79, - 85, 82, 45, 83, 84, 82, 73, 78, 199, 70, 79, 85, 82, 45, 80, 69, 82, 45, - 69, 205, 70, 79, 85, 82, 45, 76, 73, 78, 197, 70, 79, 85, 210, 70, 79, - 85, 78, 84, 65, 73, 78, 128, 70, 79, 85, 78, 84, 65, 73, 206, 70, 79, 83, - 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, 82, 68, 128, 70, 79, 82, - 87, 65, 82, 196, 70, 79, 82, 84, 89, 45, 70, 73, 86, 197, 70, 79, 82, 84, - 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, 84, 85, 78, 69, 128, 70, 79, - 82, 84, 85, 78, 197, 70, 79, 82, 84, 73, 69, 84, 72, 128, 70, 79, 82, 84, - 69, 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 69, 69, 128, 70, 79, 82, - 77, 69, 197, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, - 65, 212, 70, 79, 82, 75, 69, 196, 70, 79, 82, 69, 72, 69, 65, 196, 70, - 79, 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, 80, 128, 70, - 79, 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, 73, 78, 84, - 83, 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, 65, 76, 76, - 128, 70, 79, 79, 84, 128, 70, 79, 79, 76, 128, 70, 79, 79, 68, 128, 70, - 79, 79, 128, 70, 79, 78, 212, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, - 78, 68, 85, 69, 128, 70, 79, 77, 128, 70, 79, 76, 76, 89, 128, 70, 79, - 76, 76, 79, 87, 73, 78, 71, 128, 70, 79, 76, 68, 73, 78, 199, 70, 79, 76, - 68, 69, 82, 128, 70, 79, 76, 68, 69, 196, 70, 79, 71, 71, 89, 128, 70, - 79, 71, 128, 70, 207, 70, 77, 128, 70, 76, 89, 73, 78, 199, 70, 76, 89, - 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, 71, 128, 70, 76, 85, 84, 84, 69, - 82, 73, 78, 199, 70, 76, 85, 84, 69, 128, 70, 76, 85, 83, 72, 69, 196, - 70, 76, 79, 87, 73, 78, 199, 70, 76, 79, 87, 69, 82, 83, 128, 70, 76, 79, - 87, 69, 210, 70, 76, 79, 85, 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, - 84, 69, 128, 70, 76, 79, 82, 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, - 79, 79, 82, 128, 70, 76, 79, 79, 210, 70, 76, 73, 80, 128, 70, 76, 73, - 71, 72, 84, 128, 70, 76, 73, 67, 203, 70, 76, 69, 88, 85, 83, 128, 70, - 76, 69, 88, 69, 196, 70, 76, 69, 88, 128, 70, 76, 69, 85, 82, 79, 78, - 128, 70, 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, 70, 76, 65, 84, - 84, 69, 78, 69, 196, 70, 76, 65, 84, 78, 69, 83, 83, 128, 70, 76, 65, 84, - 66, 82, 69, 65, 68, 128, 70, 76, 65, 83, 72, 128, 70, 76, 65, 77, 73, 78, - 71, 79, 128, 70, 76, 65, 77, 69, 128, 70, 76, 65, 71, 83, 128, 70, 76, - 65, 71, 45, 53, 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, 45, 51, - 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 49, 128, 70, 76, - 65, 71, 128, 70, 76, 65, 199, 70, 76, 65, 128, 70, 76, 128, 70, 73, 88, - 69, 68, 45, 70, 79, 82, 205, 70, 73, 88, 128, 70, 73, 86, 69, 45, 84, 72, - 73, 82, 84, 89, 128, 70, 73, 86, 69, 45, 76, 73, 78, 197, 70, 73, 86, 69, - 45, 76, 73, 75, 197, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, 203, 70, 73, - 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, 73, 83, 72, - 73, 78, 199, 70, 73, 83, 72, 72, 79, 79, 75, 128, 70, 73, 83, 72, 72, 79, - 79, 203, 70, 73, 83, 72, 69, 89, 69, 128, 70, 73, 83, 200, 70, 73, 82, - 83, 212, 70, 73, 82, 73, 128, 70, 73, 82, 69, 87, 79, 82, 75, 83, 128, - 70, 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, 69, 67, 82, 65, 67, 75, 69, - 82, 128, 70, 73, 82, 69, 128, 70, 73, 82, 197, 70, 73, 80, 128, 70, 73, - 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, 83, 128, 70, 73, 78, 71, 69, 82, - 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 73, 78, 71, 69, - 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, 80, 79, 83, 212, 70, 73, 78, 71, - 69, 82, 128, 70, 73, 78, 71, 69, 210, 70, 73, 78, 65, 78, 67, 73, 65, 76, - 128, 70, 73, 78, 65, 76, 128, 70, 73, 76, 205, 70, 73, 76, 76, 69, 82, - 45, 50, 128, 70, 73, 76, 76, 69, 82, 45, 49, 128, 70, 73, 76, 76, 69, 82, - 128, 70, 73, 76, 76, 69, 196, 70, 73, 76, 76, 128, 70, 73, 76, 204, 70, - 73, 76, 197, 70, 73, 73, 128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, - 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, - 73, 71, 85, 82, 69, 128, 70, 73, 71, 85, 82, 197, 70, 73, 71, 72, 84, - 128, 70, 73, 70, 84, 89, 128, 70, 73, 70, 84, 217, 70, 73, 70, 84, 72, - 83, 128, 70, 73, 70, 84, 72, 128, 70, 73, 70, 84, 69, 69, 78, 128, 70, - 73, 70, 84, 69, 69, 206, 70, 73, 69, 76, 68, 128, 70, 73, 69, 76, 196, - 70, 72, 84, 79, 82, 193, 70, 70, 76, 128, 70, 70, 73, 128, 70, 69, 85, - 88, 128, 70, 69, 85, 70, 69, 85, 65, 69, 84, 128, 70, 69, 84, 72, 128, - 70, 69, 83, 84, 73, 86, 65, 76, 128, 70, 69, 82, 82, 89, 128, 70, 69, 82, - 82, 73, 211, 70, 69, 82, 77, 65, 84, 65, 128, 70, 69, 82, 77, 65, 84, - 193, 70, 69, 79, 200, 70, 69, 78, 199, 70, 69, 78, 67, 69, 82, 128, 70, - 69, 78, 67, 69, 128, 70, 69, 77, 73, 78, 73, 78, 197, 70, 69, 77, 65, 76, - 69, 128, 70, 69, 77, 65, 76, 197, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, - 128, 70, 69, 73, 128, 70, 69, 72, 213, 70, 69, 72, 128, 70, 69, 200, 70, - 69, 69, 78, 71, 128, 70, 69, 69, 77, 128, 70, 69, 69, 68, 128, 70, 69, - 69, 196, 70, 69, 69, 128, 70, 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, - 65, 84, 72, 69, 82, 128, 70, 69, 65, 84, 72, 69, 210, 70, 69, 65, 82, 78, - 128, 70, 69, 65, 82, 70, 85, 204, 70, 69, 65, 82, 128, 70, 65, 89, 65, - 78, 78, 65, 128, 70, 65, 89, 128, 70, 65, 88, 128, 70, 65, 216, 70, 65, - 84, 73, 71, 85, 69, 128, 70, 65, 84, 72, 69, 82, 128, 70, 65, 84, 72, 69, - 210, 70, 65, 84, 72, 65, 84, 65, 78, 128, 70, 65, 84, 72, 65, 84, 65, - 206, 70, 65, 84, 72, 65, 128, 70, 65, 84, 72, 193, 70, 65, 84, 128, 70, - 65, 83, 84, 128, 70, 65, 82, 83, 201, 70, 65, 82, 128, 70, 65, 81, 128, - 70, 65, 80, 128, 70, 65, 78, 71, 128, 70, 65, 78, 69, 82, 79, 83, 73, - 211, 70, 65, 78, 128, 70, 65, 77, 73, 76, 89, 128, 70, 65, 77, 128, 70, - 65, 76, 76, 69, 206, 70, 65, 76, 65, 70, 69, 76, 128, 70, 65, 74, 128, - 70, 65, 73, 82, 89, 128, 70, 65, 73, 76, 85, 82, 69, 128, 70, 65, 73, 72, - 85, 128, 70, 65, 73, 66, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, - 128, 70, 65, 67, 84, 79, 82, 89, 128, 70, 65, 67, 84, 79, 210, 70, 65, - 67, 83, 73, 77, 73, 76, 197, 70, 65, 67, 73, 78, 71, 83, 128, 70, 65, 67, - 69, 45, 54, 128, 70, 65, 67, 69, 45, 53, 128, 70, 65, 67, 69, 45, 52, - 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, 67, 69, 45, 50, 128, 70, 65, - 67, 69, 45, 49, 128, 70, 65, 65, 77, 65, 69, 128, 70, 65, 65, 73, 128, - 70, 65, 65, 70, 85, 128, 70, 48, 53, 51, 128, 70, 48, 53, 50, 128, 70, - 48, 53, 49, 67, 128, 70, 48, 53, 49, 66, 128, 70, 48, 53, 49, 65, 128, - 70, 48, 53, 49, 128, 70, 48, 53, 48, 128, 70, 48, 52, 57, 128, 70, 48, - 52, 56, 128, 70, 48, 52, 55, 65, 128, 70, 48, 52, 55, 128, 70, 48, 52, - 54, 65, 128, 70, 48, 52, 54, 128, 70, 48, 52, 53, 65, 128, 70, 48, 52, - 53, 128, 70, 48, 52, 52, 128, 70, 48, 52, 51, 128, 70, 48, 52, 50, 128, - 70, 48, 52, 49, 128, 70, 48, 52, 48, 128, 70, 48, 51, 57, 128, 70, 48, - 51, 56, 65, 128, 70, 48, 51, 56, 128, 70, 48, 51, 55, 65, 128, 70, 48, - 51, 55, 128, 70, 48, 51, 54, 128, 70, 48, 51, 53, 128, 70, 48, 51, 52, - 128, 70, 48, 51, 51, 128, 70, 48, 51, 50, 128, 70, 48, 51, 49, 65, 128, - 70, 48, 51, 49, 128, 70, 48, 51, 48, 128, 70, 48, 50, 57, 128, 70, 48, - 50, 56, 128, 70, 48, 50, 55, 128, 70, 48, 50, 54, 128, 70, 48, 50, 53, - 128, 70, 48, 50, 52, 128, 70, 48, 50, 51, 128, 70, 48, 50, 50, 128, 70, - 48, 50, 49, 65, 128, 70, 48, 50, 49, 128, 70, 48, 50, 48, 128, 70, 48, - 49, 57, 128, 70, 48, 49, 56, 128, 70, 48, 49, 55, 128, 70, 48, 49, 54, - 128, 70, 48, 49, 53, 128, 70, 48, 49, 52, 128, 70, 48, 49, 51, 65, 128, - 70, 48, 49, 51, 128, 70, 48, 49, 50, 128, 70, 48, 49, 49, 128, 70, 48, - 49, 48, 128, 70, 48, 48, 57, 128, 70, 48, 48, 56, 128, 70, 48, 48, 55, - 128, 70, 48, 48, 54, 128, 70, 48, 48, 53, 128, 70, 48, 48, 52, 128, 70, - 48, 48, 51, 128, 70, 48, 48, 50, 128, 70, 48, 48, 49, 65, 128, 70, 48, - 48, 49, 128, 69, 90, 83, 128, 69, 90, 69, 78, 128, 69, 90, 69, 206, 69, - 89, 89, 89, 128, 69, 89, 69, 83, 128, 69, 89, 69, 211, 69, 89, 69, 76, - 65, 83, 72, 69, 211, 69, 89, 69, 71, 76, 65, 83, 83, 69, 83, 128, 69, 89, - 69, 71, 65, 90, 69, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 69, 89, 69, - 71, 65, 90, 69, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 69, 89, 69, - 66, 82, 79, 87, 211, 69, 89, 69, 66, 82, 79, 215, 69, 89, 197, 69, 89, - 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, 65, 78, 78, 65, 128, 69, 88, 84, - 82, 69, 77, 69, 76, 217, 69, 88, 84, 82, 65, 84, 69, 82, 82, 69, 83, 84, - 82, 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, 79, 215, 69, 88, 84, 82, 65, - 45, 72, 73, 71, 200, 69, 88, 84, 82, 193, 69, 88, 84, 73, 78, 71, 85, 73, - 83, 72, 69, 82, 128, 69, 88, 84, 69, 78, 83, 73, 79, 78, 128, 69, 88, 84, - 69, 78, 68, 69, 68, 128, 69, 88, 84, 69, 78, 68, 69, 196, 69, 88, 80, 82, - 69, 83, 83, 73, 79, 78, 76, 69, 83, 211, 69, 88, 80, 79, 78, 69, 78, 212, - 69, 88, 80, 76, 79, 68, 73, 78, 199, 69, 88, 79, 128, 69, 88, 207, 69, - 88, 73, 83, 84, 83, 128, 69, 88, 73, 83, 84, 128, 69, 88, 72, 65, 85, 83, - 84, 73, 79, 78, 128, 69, 88, 72, 65, 76, 69, 128, 69, 88, 67, 76, 65, 77, - 65, 84, 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 206, 69, - 88, 67, 73, 84, 69, 77, 69, 78, 84, 128, 69, 88, 67, 72, 65, 78, 71, 69, - 128, 69, 88, 67, 69, 83, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, - 128, 69, 87, 69, 128, 69, 86, 69, 82, 217, 69, 86, 69, 82, 71, 82, 69, - 69, 206, 69, 86, 69, 78, 73, 78, 71, 128, 69, 85, 82, 79, 80, 69, 65, - 206, 69, 85, 82, 79, 80, 69, 45, 65, 70, 82, 73, 67, 65, 128, 69, 85, 82, - 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 69, 85, 82, 207, 69, 85, 76, 69, - 210, 69, 85, 45, 85, 128, 69, 85, 45, 79, 128, 69, 85, 45, 69, 85, 128, - 69, 85, 45, 69, 79, 128, 69, 85, 45, 69, 128, 69, 85, 45, 65, 128, 69, - 84, 88, 128, 69, 84, 84, 128, 69, 84, 78, 65, 72, 84, 65, 128, 69, 84, - 72, 69, 204, 69, 84, 69, 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, 89, - 128, 69, 84, 69, 82, 78, 73, 84, 217, 69, 84, 66, 128, 69, 83, 90, 128, - 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 83, 84, 73, 77, 65, 84, 69, 83, - 128, 69, 83, 84, 73, 77, 65, 84, 69, 196, 69, 83, 72, 69, 51, 128, 69, - 83, 72, 50, 49, 128, 69, 83, 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, - 128, 69, 83, 67, 128, 69, 83, 65, 128, 69, 83, 45, 84, 69, 128, 69, 83, - 45, 51, 128, 69, 83, 45, 50, 128, 69, 83, 45, 49, 128, 69, 82, 82, 79, - 82, 45, 66, 65, 82, 82, 69, 196, 69, 82, 82, 128, 69, 82, 73, 211, 69, - 82, 73, 78, 50, 128, 69, 82, 73, 78, 178, 69, 82, 71, 128, 69, 82, 65, - 83, 197, 69, 81, 85, 73, 86, 65, 76, 69, 78, 212, 69, 81, 85, 73, 76, 65, - 84, 69, 82, 65, 204, 69, 81, 85, 73, 72, 79, 80, 80, 69, 82, 128, 69, 81, - 85, 73, 72, 79, 80, 80, 69, 210, 69, 81, 85, 73, 68, 128, 69, 81, 85, 73, - 65, 78, 71, 85, 76, 65, 210, 69, 81, 85, 65, 76, 83, 128, 69, 81, 85, 65, - 76, 211, 69, 81, 85, 65, 76, 128, 69, 81, 85, 65, 204, 69, 80, 83, 73, - 76, 79, 78, 128, 69, 80, 83, 73, 76, 79, 206, 69, 80, 79, 67, 72, 128, - 69, 80, 73, 71, 82, 65, 80, 72, 73, 195, 69, 80, 73, 68, 65, 85, 82, 69, - 65, 206, 69, 80, 69, 78, 84, 72, 69, 84, 73, 195, 69, 80, 69, 71, 69, 82, - 77, 65, 128, 69, 80, 65, 67, 212, 69, 79, 84, 128, 69, 79, 77, 128, 69, - 79, 76, 72, 88, 128, 69, 79, 76, 128, 69, 79, 72, 128, 69, 78, 89, 128, - 69, 78, 86, 69, 76, 79, 80, 69, 128, 69, 78, 86, 69, 76, 79, 80, 197, 69, - 78, 85, 77, 69, 82, 65, 84, 73, 79, 206, 69, 78, 84, 82, 89, 45, 50, 128, - 69, 78, 84, 82, 89, 45, 49, 128, 69, 78, 84, 82, 89, 128, 69, 78, 84, 82, - 217, 69, 78, 84, 72, 85, 83, 73, 65, 83, 77, 128, 69, 78, 84, 69, 82, 80, - 82, 73, 83, 69, 128, 69, 78, 84, 69, 82, 73, 78, 199, 69, 78, 84, 69, 82, - 128, 69, 78, 84, 69, 210, 69, 78, 84, 45, 83, 72, 65, 80, 69, 196, 69, - 78, 81, 85, 73, 82, 89, 128, 69, 78, 81, 128, 69, 78, 79, 211, 69, 78, - 78, 73, 128, 69, 78, 78, 128, 69, 78, 76, 65, 82, 71, 69, 77, 69, 78, 84, - 128, 69, 78, 71, 73, 78, 69, 128, 69, 78, 68, 79, 70, 79, 78, 79, 78, - 128, 69, 78, 68, 73, 78, 199, 69, 78, 68, 69, 80, 128, 69, 78, 68, 69, - 65, 86, 79, 85, 82, 128, 69, 78, 67, 79, 85, 78, 84, 69, 82, 83, 128, 69, - 78, 67, 76, 79, 83, 85, 82, 69, 83, 128, 69, 78, 67, 76, 79, 83, 85, 82, - 69, 128, 69, 78, 67, 76, 79, 83, 73, 78, 199, 69, 78, 67, 128, 69, 78, - 65, 82, 88, 73, 211, 69, 78, 65, 82, 77, 79, 78, 73, 79, 211, 69, 77, 80, - 84, 217, 69, 77, 80, 72, 65, 84, 73, 195, 69, 77, 80, 72, 65, 83, 73, - 211, 69, 77, 79, 74, 201, 69, 77, 66, 82, 79, 73, 68, 69, 82, 89, 128, - 69, 77, 66, 76, 69, 77, 128, 69, 77, 66, 69, 76, 76, 73, 83, 72, 77, 69, - 78, 84, 128, 69, 77, 66, 69, 68, 68, 73, 78, 71, 128, 69, 76, 89, 77, 65, - 73, 195, 69, 76, 89, 128, 69, 76, 84, 128, 69, 76, 76, 73, 80, 84, 73, - 195, 69, 76, 76, 73, 80, 83, 73, 83, 128, 69, 76, 76, 73, 80, 83, 69, - 128, 69, 76, 73, 70, 73, 128, 69, 76, 73, 70, 128, 69, 76, 69, 86, 69, - 78, 45, 84, 72, 73, 82, 84, 89, 128, 69, 76, 69, 86, 69, 78, 128, 69, 76, - 69, 86, 69, 206, 69, 76, 69, 86, 65, 84, 85, 211, 69, 76, 69, 86, 65, 84, - 79, 82, 128, 69, 76, 69, 80, 72, 65, 78, 84, 128, 69, 76, 69, 77, 69, 78, - 212, 69, 76, 69, 67, 84, 82, 79, 78, 73, 67, 83, 128, 69, 76, 69, 67, 84, - 82, 73, 67, 65, 204, 69, 76, 69, 67, 84, 82, 73, 195, 69, 76, 66, 65, 83, - 65, 206, 69, 76, 65, 77, 73, 84, 69, 128, 69, 76, 65, 77, 73, 84, 197, - 69, 76, 65, 70, 82, 79, 78, 128, 69, 75, 83, 84, 82, 69, 80, 84, 79, 78, - 128, 69, 75, 83, 128, 69, 75, 70, 79, 78, 73, 84, 73, 75, 79, 78, 128, - 69, 75, 65, 82, 65, 128, 69, 75, 65, 77, 128, 69, 74, 69, 67, 212, 69, - 73, 83, 128, 69, 73, 71, 72, 84, 89, 128, 69, 73, 71, 72, 84, 217, 69, - 73, 71, 72, 84, 73, 69, 84, 72, 83, 128, 69, 73, 71, 72, 84, 73, 69, 84, - 72, 128, 69, 73, 71, 72, 84, 72, 83, 128, 69, 73, 71, 72, 84, 72, 211, - 69, 73, 71, 72, 84, 72, 128, 69, 73, 71, 72, 84, 69, 69, 78, 128, 69, 73, - 71, 72, 84, 69, 69, 206, 69, 73, 71, 72, 84, 45, 84, 72, 73, 82, 84, 89, - 128, 69, 73, 69, 128, 69, 72, 87, 65, 218, 69, 72, 84, 83, 65, 128, 69, - 72, 84, 65, 128, 69, 72, 80, 65, 128, 69, 72, 75, 65, 128, 69, 72, 67, - 72, 65, 128, 69, 71, 89, 80, 84, 79, 76, 79, 71, 73, 67, 65, 204, 69, 71, - 89, 128, 69, 71, 73, 82, 128, 69, 71, 71, 83, 128, 69, 71, 71, 128, 69, - 69, 89, 65, 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, 72, 128, - 69, 69, 66, 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, 73, 65, - 204, 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 67, 76, - 73, 80, 83, 69, 128, 69, 66, 69, 70, 73, 76, 73, 128, 69, 65, 83, 84, 69, - 82, 206, 69, 65, 83, 84, 128, 69, 65, 83, 212, 69, 65, 82, 84, 72, 76, - 217, 69, 65, 82, 84, 72, 128, 69, 65, 82, 84, 200, 69, 65, 82, 76, 217, - 69, 65, 77, 72, 65, 78, 67, 72, 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, - 69, 65, 68, 72, 65, 68, 72, 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, - 178, 69, 48, 51, 56, 128, 69, 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, - 48, 51, 52, 65, 128, 69, 48, 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, - 51, 50, 128, 69, 48, 51, 49, 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, - 128, 69, 48, 50, 56, 65, 128, 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, - 69, 48, 50, 54, 128, 69, 48, 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, - 50, 51, 128, 69, 48, 50, 50, 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, - 65, 128, 69, 48, 50, 48, 128, 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, - 69, 48, 49, 55, 65, 128, 69, 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, - 69, 48, 49, 54, 128, 69, 48, 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, - 49, 51, 128, 69, 48, 49, 50, 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, - 128, 69, 48, 48, 57, 65, 128, 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, - 128, 69, 48, 48, 56, 128, 69, 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, - 48, 48, 53, 128, 69, 48, 48, 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, - 50, 128, 69, 48, 48, 49, 128, 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, - 69, 128, 68, 90, 90, 69, 128, 68, 90, 90, 65, 128, 68, 90, 89, 73, 128, - 68, 90, 89, 65, 89, 128, 68, 90, 87, 69, 128, 68, 90, 85, 128, 68, 90, - 79, 128, 68, 90, 74, 69, 128, 68, 90, 73, 84, 65, 128, 68, 90, 73, 128, - 68, 90, 72, 79, 73, 128, 68, 90, 72, 69, 128, 68, 90, 72, 65, 128, 68, - 90, 69, 76, 79, 128, 68, 90, 69, 69, 128, 68, 90, 69, 128, 68, 90, 65, - 89, 128, 68, 90, 65, 65, 128, 68, 90, 65, 128, 68, 90, 128, 68, 218, 68, - 89, 79, 128, 68, 89, 207, 68, 89, 78, 65, 77, 73, 195, 68, 89, 69, 72, - 128, 68, 89, 69, 200, 68, 89, 65, 78, 128, 68, 87, 79, 128, 68, 87, 69, - 128, 68, 87, 65, 128, 68, 86, 85, 77, 89, 193, 68, 86, 79, 69, 84, 79, - 67, 72, 73, 69, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, - 79, 68, 78, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, - 79, 86, 79, 68, 78, 65, 89, 193, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, - 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, - 76, 78, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 65, 89, 193, - 68, 86, 73, 83, 86, 65, 82, 65, 128, 68, 86, 68, 128, 68, 86, 193, 68, - 86, 128, 68, 85, 84, 73, 69, 83, 128, 68, 85, 83, 75, 128, 68, 85, 83, - 72, 69, 78, 78, 65, 128, 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, - 50, 128, 68, 85, 80, 79, 78, 68, 73, 85, 211, 68, 85, 79, 88, 128, 68, - 85, 79, 128, 68, 85, 78, 52, 128, 68, 85, 78, 51, 128, 68, 85, 78, 179, - 68, 85, 77, 80, 76, 73, 78, 71, 128, 68, 85, 77, 128, 68, 85, 204, 68, - 85, 72, 128, 68, 85, 71, 85, 68, 128, 68, 85, 199, 68, 85, 68, 65, 128, - 68, 85, 67, 75, 128, 68, 85, 66, 50, 128, 68, 85, 66, 128, 68, 85, 194, - 68, 82, 89, 128, 68, 82, 217, 68, 82, 85, 77, 83, 84, 73, 67, 75, 83, - 128, 68, 82, 85, 77, 128, 68, 82, 85, 205, 68, 82, 79, 80, 83, 128, 68, - 82, 79, 80, 76, 69, 84, 128, 68, 82, 79, 80, 45, 83, 72, 65, 68, 79, 87, - 69, 196, 68, 82, 79, 208, 68, 82, 79, 79, 76, 73, 78, 199, 68, 82, 79, - 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, 69, 128, 68, 82, 73, 86, 197, - 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, 68, 82, 69, 83, 83, 128, 68, - 82, 69, 65, 77, 217, 68, 82, 65, 85, 71, 72, 84, 211, 68, 82, 65, 77, - 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, 128, 68, 82, 65, 71, 79, - 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, 65, 67, 72, 77, 65, 83, - 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, 67, 72, 77, 193, 68, - 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, 87, 65, 82, 68, 211, - 68, 79, 87, 78, 87, 65, 82, 196, 68, 79, 87, 78, 83, 67, 65, 76, 73, 78, - 199, 68, 79, 87, 78, 45, 80, 79, 73, 78, 84, 73, 78, 199, 68, 79, 87, 78, - 128, 68, 79, 86, 69, 128, 68, 79, 86, 197, 68, 79, 85, 71, 72, 78, 85, - 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, 69, 196, 68, 79, - 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 68, 79, 85, 66, 76, 69, 45, - 76, 73, 78, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 197, 68, 79, - 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, 76, 69, 128, 68, - 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, 45, 78, 128, 68, - 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, 128, 68, 79, 84, - 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, 83, 45, 55, 56, - 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, 56, 128, 68, - 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128, 68, 79, - 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, - 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, 84, 83, 45, 53, - 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, - 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, - 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, 52, 55, 56, - 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56, - 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, - 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 53, 56, - 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, - 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 52, - 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, 79, 84, - 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83, - 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 51, 55, - 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56, - 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 54, - 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, 53, 56, - 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, - 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 51, - 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 55, 128, 68, 79, 84, - 83, 45, 51, 53, 54, 128, 68, 79, 84, 83, 45, 51, 53, 128, 68, 79, 84, 83, - 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, 79, 84, - 83, 45, 51, 52, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 128, 68, 79, - 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 54, 55, - 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, 52, 53, - 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, - 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 56, 128, 68, 79, - 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, - 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, - 51, 52, 53, 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, 45, 51, - 128, 68, 79, 84, 83, 45, 50, 56, 128, 68, 79, 84, 83, 45, 50, 55, 56, - 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, - 128, 68, 79, 84, 83, 45, 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 54, - 55, 128, 68, 79, 84, 83, 45, 50, 54, 128, 68, 79, 84, 83, 45, 50, 53, 56, - 128, 68, 79, 84, 83, 45, 50, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, - 55, 128, 68, 79, 84, 83, 45, 50, 53, 54, 56, 128, 68, 79, 84, 83, 45, 50, - 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, 54, 55, 128, 68, 79, 84, - 83, 45, 50, 53, 54, 128, 68, 79, 84, 83, 45, 50, 53, 128, 68, 79, 84, 83, - 45, 50, 52, 56, 128, 68, 79, 84, 83, 45, 50, 52, 55, 56, 128, 68, 79, 84, - 83, 45, 50, 52, 55, 128, 68, 79, 84, 83, 45, 50, 52, 54, 56, 128, 68, 79, - 84, 83, 45, 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 52, 54, 55, - 128, 68, 79, 84, 83, 45, 50, 52, 54, 128, 68, 79, 84, 83, 45, 50, 52, 53, - 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, - 50, 52, 53, 55, 128, 68, 79, 84, 83, 45, 50, 52, 53, 54, 56, 128, 68, 79, - 84, 83, 45, 50, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 52, 53, - 54, 55, 128, 68, 79, 84, 83, 45, 50, 52, 53, 54, 128, 68, 79, 84, 83, 45, - 50, 52, 53, 128, 68, 79, 84, 83, 45, 50, 52, 128, 68, 79, 84, 83, 45, 50, - 51, 56, 128, 68, 79, 84, 83, 45, 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, - 50, 51, 55, 128, 68, 79, 84, 83, 45, 50, 51, 54, 56, 128, 68, 79, 84, 83, - 45, 50, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 54, 55, 128, 68, - 79, 84, 83, 45, 50, 51, 54, 128, 68, 79, 84, 83, 45, 50, 51, 53, 56, 128, - 68, 79, 84, 83, 45, 50, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, - 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 56, 128, 68, 79, 84, 83, - 45, 50, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 55, - 128, 68, 79, 84, 83, 45, 50, 51, 53, 54, 128, 68, 79, 84, 83, 45, 50, 51, - 53, 128, 68, 79, 84, 83, 45, 50, 51, 52, 56, 128, 68, 79, 84, 83, 45, 50, - 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 55, 128, 68, 79, 84, - 83, 45, 50, 51, 52, 54, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 55, - 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, - 50, 51, 52, 54, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 56, 128, 68, 79, - 84, 83, 45, 50, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, - 53, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 54, 56, 128, 68, 79, 84, - 83, 45, 50, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 51, 52, - 53, 54, 55, 128, 68, 79, 84, 83, 45, 50, 51, 52, 53, 54, 128, 68, 79, 84, - 83, 45, 50, 51, 52, 53, 128, 68, 79, 84, 83, 45, 50, 51, 52, 128, 68, 79, - 84, 83, 45, 50, 51, 128, 68, 79, 84, 83, 45, 50, 128, 68, 79, 84, 83, 45, - 49, 56, 128, 68, 79, 84, 83, 45, 49, 55, 56, 128, 68, 79, 84, 83, 45, 49, - 55, 128, 68, 79, 84, 83, 45, 49, 54, 56, 128, 68, 79, 84, 83, 45, 49, 54, - 55, 56, 128, 68, 79, 84, 83, 45, 49, 54, 55, 128, 68, 79, 84, 83, 45, 49, - 54, 128, 68, 79, 84, 83, 45, 49, 53, 56, 128, 68, 79, 84, 83, 45, 49, 53, - 55, 56, 128, 68, 79, 84, 83, 45, 49, 53, 55, 128, 68, 79, 84, 83, 45, 49, - 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 53, 54, 55, 56, 128, 68, 79, 84, - 83, 45, 49, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 53, 54, 128, 68, 79, - 84, 83, 45, 49, 53, 128, 68, 79, 84, 83, 45, 49, 52, 56, 128, 68, 79, 84, - 83, 45, 49, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 55, 128, 68, 79, - 84, 83, 45, 49, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, 52, 54, 55, 56, - 128, 68, 79, 84, 83, 45, 49, 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 52, - 54, 128, 68, 79, 84, 83, 45, 49, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, - 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 55, 128, 68, 79, 84, - 83, 45, 49, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 54, 55, - 56, 128, 68, 79, 84, 83, 45, 49, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, - 49, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 52, 53, 128, 68, 79, 84, 83, - 45, 49, 52, 128, 68, 79, 84, 83, 45, 49, 51, 56, 128, 68, 79, 84, 83, 45, - 49, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 55, 128, 68, 79, 84, 83, - 45, 49, 51, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 54, 55, 56, 128, 68, - 79, 84, 83, 45, 49, 51, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 54, 128, - 68, 79, 84, 83, 45, 49, 51, 53, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, - 55, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 55, 128, 68, 79, 84, 83, 45, - 49, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 53, 54, 55, 56, 128, - 68, 79, 84, 83, 45, 49, 51, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, - 53, 54, 128, 68, 79, 84, 83, 45, 49, 51, 53, 128, 68, 79, 84, 83, 45, 49, - 51, 52, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 55, 56, 128, 68, 79, 84, - 83, 45, 49, 51, 52, 55, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 56, 128, - 68, 79, 84, 83, 45, 49, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, - 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 51, 52, 54, 128, 68, 79, 84, - 83, 45, 49, 51, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 55, - 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, - 49, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 54, 55, - 56, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 54, 55, 128, 68, 79, 84, 83, - 45, 49, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, 49, 51, 52, 53, 128, 68, - 79, 84, 83, 45, 49, 51, 52, 128, 68, 79, 84, 83, 45, 49, 51, 128, 68, 79, - 84, 83, 45, 49, 50, 56, 128, 68, 79, 84, 83, 45, 49, 50, 55, 56, 128, 68, - 79, 84, 83, 45, 49, 50, 55, 128, 68, 79, 84, 83, 45, 49, 50, 54, 56, 128, - 68, 79, 84, 83, 45, 49, 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, - 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 54, 128, 68, 79, 84, 83, 45, 49, - 50, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, 53, 55, 56, 128, 68, 79, 84, - 83, 45, 49, 50, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 53, 54, 56, 128, - 68, 79, 84, 83, 45, 49, 50, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, - 50, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 53, 54, 128, 68, 79, 84, - 83, 45, 49, 50, 53, 128, 68, 79, 84, 83, 45, 49, 50, 52, 56, 128, 68, 79, - 84, 83, 45, 49, 50, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 55, - 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 56, 128, 68, 79, 84, 83, 45, 49, - 50, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 54, 55, 128, 68, - 79, 84, 83, 45, 49, 50, 52, 54, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, - 56, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 55, 56, 128, 68, 79, 84, 83, - 45, 49, 50, 52, 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, 56, - 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, - 45, 49, 50, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 54, - 128, 68, 79, 84, 83, 45, 49, 50, 52, 53, 128, 68, 79, 84, 83, 45, 49, 50, - 52, 128, 68, 79, 84, 83, 45, 49, 50, 51, 56, 128, 68, 79, 84, 83, 45, 49, - 50, 51, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 55, 128, 68, 79, 84, - 83, 45, 49, 50, 51, 54, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 55, - 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 54, 55, 128, 68, 79, 84, 83, 45, - 49, 50, 51, 54, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 56, 128, 68, 79, - 84, 83, 45, 49, 50, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, - 53, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 56, 128, 68, 79, 84, - 83, 45, 49, 50, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, - 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 53, 54, 128, 68, 79, 84, - 83, 45, 49, 50, 51, 53, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 56, 128, - 68, 79, 84, 83, 45, 49, 50, 51, 52, 55, 56, 128, 68, 79, 84, 83, 45, 49, - 50, 51, 52, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 56, 128, 68, - 79, 84, 83, 45, 49, 50, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, - 50, 51, 52, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 54, 128, 68, - 79, 84, 83, 45, 49, 50, 51, 52, 53, 56, 128, 68, 79, 84, 83, 45, 49, 50, - 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 55, 128, - 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, - 49, 50, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, - 53, 54, 55, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, 53, 54, 128, 68, 79, - 84, 83, 45, 49, 50, 51, 52, 53, 128, 68, 79, 84, 83, 45, 49, 50, 51, 52, - 128, 68, 79, 84, 83, 45, 49, 50, 51, 128, 68, 79, 84, 83, 45, 49, 50, - 128, 68, 79, 84, 83, 45, 49, 128, 68, 79, 84, 83, 128, 68, 79, 84, 76, - 69, 83, 211, 68, 79, 82, 85, 128, 68, 79, 82, 79, 77, 197, 68, 79, 79, - 82, 128, 68, 79, 79, 78, 71, 128, 68, 79, 78, 75, 69, 89, 128, 68, 79, - 78, 71, 128, 68, 79, 77, 73, 78, 207, 68, 79, 77, 65, 73, 206, 68, 79, - 76, 80, 72, 73, 78, 128, 68, 79, 76, 76, 83, 128, 68, 79, 76, 76, 65, - 210, 68, 79, 76, 73, 85, 77, 128, 68, 79, 75, 77, 65, 73, 128, 68, 79, - 73, 84, 128, 68, 79, 73, 78, 199, 68, 79, 73, 128, 68, 79, 71, 82, 193, - 68, 79, 71, 128, 68, 79, 199, 68, 79, 69, 211, 68, 79, 68, 79, 128, 68, - 79, 68, 69, 75, 65, 84, 65, 128, 68, 79, 67, 85, 77, 69, 78, 84, 128, 68, - 79, 67, 85, 77, 69, 78, 212, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, - 65, 83, 72, 77, 69, 69, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, - 68, 79, 65, 128, 68, 79, 45, 79, 128, 68, 78, 193, 68, 77, 128, 68, 205, - 68, 76, 85, 128, 68, 76, 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, - 128, 68, 76, 72, 65, 128, 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, - 128, 68, 75, 65, 82, 128, 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, - 68, 74, 69, 82, 86, 128, 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, - 90, 217, 68, 73, 89, 193, 68, 73, 86, 79, 82, 67, 197, 68, 73, 86, 73, - 83, 73, 79, 78, 128, 68, 73, 86, 73, 83, 73, 79, 206, 68, 73, 86, 73, 78, - 199, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, 69, - 83, 128, 68, 73, 86, 73, 68, 69, 82, 83, 128, 68, 73, 86, 73, 68, 69, 82, - 128, 68, 73, 86, 73, 68, 69, 196, 68, 73, 86, 73, 68, 69, 128, 68, 73, - 86, 73, 68, 197, 68, 73, 86, 69, 211, 68, 73, 86, 69, 82, 71, 69, 78, 67, - 69, 128, 68, 73, 84, 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, - 128, 68, 73, 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, - 76, 76, 128, 68, 73, 83, 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, - 79, 76, 86, 69, 128, 68, 73, 83, 80, 85, 84, 69, 196, 68, 73, 83, 80, 69, - 82, 83, 73, 79, 78, 128, 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, - 128, 68, 73, 83, 72, 128, 68, 73, 83, 71, 85, 73, 83, 69, 196, 68, 73, - 83, 67, 79, 78, 84, 73, 78, 85, 79, 85, 211, 68, 73, 83, 195, 68, 73, 83, - 65, 80, 80, 79, 73, 78, 84, 69, 196, 68, 73, 83, 65, 66, 76, 69, 196, 68, - 73, 82, 71, 193, 68, 73, 82, 69, 67, 84, 76, 217, 68, 73, 82, 69, 67, 84, - 73, 79, 78, 65, 204, 68, 73, 82, 69, 67, 84, 73, 79, 206, 68, 73, 80, 84, - 69, 128, 68, 73, 80, 80, 69, 82, 128, 68, 73, 80, 76, 79, 85, 78, 128, - 68, 73, 80, 76, 73, 128, 68, 73, 80, 76, 201, 68, 73, 78, 71, 66, 65, - 212, 68, 73, 206, 68, 73, 77, 77, 73, 78, 71, 128, 68, 73, 77, 73, 78, - 85, 84, 73, 79, 78, 45, 51, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, - 45, 50, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 49, 128, 68, 73, - 77, 73, 78, 73, 83, 72, 77, 69, 78, 84, 128, 68, 73, 77, 73, 68, 73, 193, - 68, 73, 77, 69, 78, 83, 73, 79, 78, 65, 204, 68, 73, 77, 69, 78, 83, 73, - 79, 206, 68, 73, 77, 50, 128, 68, 73, 77, 178, 68, 73, 76, 128, 68, 73, - 71, 82, 65, 80, 72, 128, 68, 73, 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, - 77, 77, 79, 211, 68, 73, 71, 82, 65, 77, 77, 193, 68, 73, 71, 82, 65, - 205, 68, 73, 71, 79, 82, 71, 79, 78, 128, 68, 73, 71, 79, 82, 71, 79, - 206, 68, 73, 71, 73, 84, 83, 128, 68, 73, 71, 65, 77, 77, 65, 128, 68, - 73, 71, 193, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 70, 79, 78, 73, - 65, 83, 128, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 73, 70, 70, 73, - 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, - 65, 76, 128, 68, 73, 70, 70, 69, 82, 69, 78, 67, 197, 68, 73, 70, 65, 84, - 128, 68, 73, 69, 83, 73, 83, 128, 68, 73, 69, 83, 73, 211, 68, 73, 69, - 83, 69, 204, 68, 73, 69, 80, 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, - 65, 84, 79, 78, 79, 206, 68, 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, - 83, 84, 79, 76, 201, 68, 73, 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, - 79, 78, 68, 128, 68, 73, 65, 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, - 210, 68, 73, 65, 76, 89, 84, 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, - 75, 193, 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, - 76, 128, 68, 73, 65, 69, 82, 69, 83, 73, 90, 69, 196, 68, 73, 65, 69, 82, - 69, 83, 73, 83, 45, 82, 73, 78, 71, 128, 68, 73, 65, 69, 82, 69, 83, 73, - 83, 128, 68, 73, 65, 69, 82, 69, 83, 73, 211, 68, 72, 79, 85, 128, 68, - 72, 79, 79, 128, 68, 72, 79, 128, 68, 72, 73, 73, 128, 68, 72, 72, 85, - 128, 68, 72, 72, 79, 79, 128, 68, 72, 72, 79, 128, 68, 72, 72, 73, 128, - 68, 72, 72, 69, 69, 128, 68, 72, 72, 69, 128, 68, 72, 72, 65, 128, 68, - 72, 69, 69, 128, 68, 72, 65, 82, 77, 65, 128, 68, 72, 65, 77, 69, 68, 72, - 128, 68, 72, 65, 76, 69, 84, 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, - 68, 72, 65, 76, 128, 68, 72, 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, - 128, 68, 72, 65, 65, 128, 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, - 84, 69, 82, 79, 213, 68, 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, - 128, 68, 69, 86, 73, 67, 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, - 128, 68, 69, 85, 78, 71, 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, - 203, 68, 69, 83, 73, 71, 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, - 82, 84, 128, 68, 69, 83, 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, - 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, - 78, 199, 68, 69, 83, 67, 69, 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, - 72, 73, 68, 69, 84, 128, 68, 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, - 67, 212, 68, 69, 82, 66, 73, 84, 83, 65, 128, 68, 69, 80, 84, 72, 128, - 68, 69, 80, 65, 82, 84, 85, 82, 69, 128, 68, 69, 80, 65, 82, 84, 77, 69, - 78, 212, 68, 69, 80, 65, 82, 84, 73, 78, 199, 68, 69, 78, 84, 73, 83, 84, - 82, 217, 68, 69, 78, 84, 65, 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, - 82, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, 69, - 78, 128, 68, 69, 78, 71, 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, 73, - 85, 211, 68, 69, 77, 69, 83, 84, 86, 69, 78, 78, 217, 68, 69, 76, 84, 65, - 128, 68, 69, 76, 84, 193, 68, 69, 76, 84, 128, 68, 69, 76, 80, 72, 73, - 195, 68, 69, 76, 73, 86, 69, 82, 217, 68, 69, 76, 73, 86, 69, 82, 65, 78, - 67, 69, 128, 68, 69, 76, 73, 77, 73, 84, 69, 82, 128, 68, 69, 76, 73, 77, - 73, 84, 69, 210, 68, 69, 76, 73, 67, 73, 79, 85, 211, 68, 69, 76, 69, 84, - 73, 79, 206, 68, 69, 76, 69, 84, 69, 128, 68, 69, 76, 69, 84, 197, 68, - 69, 75, 65, 128, 68, 69, 75, 128, 68, 69, 73, 128, 68, 69, 72, 73, 128, - 68, 69, 71, 82, 69, 69, 83, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, - 78, 73, 84, 73, 79, 78, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, - 83, 211, 68, 69, 69, 82, 128, 68, 69, 69, 80, 76, 89, 128, 68, 69, 69, - 76, 128, 68, 69, 67, 82, 69, 83, 67, 69, 78, 68, 79, 128, 68, 69, 67, 82, - 69, 65, 83, 69, 128, 68, 69, 67, 82, 69, 65, 83, 197, 68, 69, 67, 79, 82, - 65, 84, 73, 86, 197, 68, 69, 67, 79, 82, 65, 84, 73, 79, 78, 128, 68, 69, - 67, 73, 83, 73, 86, 69, 78, 69, 83, 83, 128, 68, 69, 67, 73, 77, 65, 204, - 68, 69, 67, 73, 68, 85, 79, 85, 211, 68, 69, 67, 69, 77, 66, 69, 82, 128, - 68, 69, 67, 65, 89, 69, 68, 128, 68, 69, 66, 73, 212, 68, 69, 65, 84, 72, - 128, 68, 69, 65, 198, 68, 69, 65, 68, 128, 68, 68, 87, 65, 128, 68, 68, - 85, 88, 128, 68, 68, 85, 84, 128, 68, 68, 85, 82, 88, 128, 68, 68, 85, - 82, 128, 68, 68, 85, 80, 128, 68, 68, 85, 79, 88, 128, 68, 68, 85, 79, - 80, 128, 68, 68, 85, 79, 128, 68, 68, 85, 128, 68, 68, 79, 88, 128, 68, - 68, 79, 84, 128, 68, 68, 79, 80, 128, 68, 68, 79, 65, 128, 68, 68, 73, - 88, 128, 68, 68, 73, 84, 128, 68, 68, 73, 80, 128, 68, 68, 73, 69, 88, - 128, 68, 68, 73, 69, 80, 128, 68, 68, 73, 69, 128, 68, 68, 73, 128, 68, - 68, 72, 85, 128, 68, 68, 72, 79, 128, 68, 68, 72, 69, 69, 128, 68, 68, - 72, 69, 128, 68, 68, 72, 65, 65, 128, 68, 68, 72, 65, 128, 68, 68, 69, - 88, 128, 68, 68, 69, 80, 128, 68, 68, 69, 69, 128, 68, 68, 69, 128, 68, - 68, 68, 72, 65, 128, 68, 68, 68, 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, - 128, 68, 68, 65, 88, 128, 68, 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, - 68, 65, 76, 128, 68, 68, 65, 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, - 65, 72, 65, 204, 68, 68, 65, 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, - 128, 68, 67, 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, - 68, 194, 68, 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, - 87, 66, 128, 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, - 128, 68, 65, 84, 197, 68, 65, 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, - 65, 83, 72, 69, 196, 68, 65, 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, - 69, 73, 65, 128, 68, 65, 82, 84, 128, 68, 65, 82, 75, 69, 78, 73, 78, 71, - 128, 68, 65, 82, 75, 69, 78, 73, 78, 199, 68, 65, 82, 203, 68, 65, 82, - 71, 65, 128, 68, 65, 82, 65, 52, 128, 68, 65, 82, 65, 51, 128, 68, 65, - 82, 128, 68, 65, 80, 45, 80, 82, 65, 205, 68, 65, 80, 45, 80, 73, 201, - 68, 65, 80, 45, 77, 85, 79, 217, 68, 65, 80, 45, 66, 85, 79, 206, 68, 65, - 80, 45, 66, 69, 201, 68, 65, 208, 68, 65, 78, 84, 65, 89, 65, 76, 65, 78, - 128, 68, 65, 78, 84, 65, 74, 193, 68, 65, 78, 71, 79, 128, 68, 65, 78, - 71, 128, 68, 65, 78, 199, 68, 65, 78, 68, 65, 128, 68, 65, 78, 67, 73, - 78, 71, 128, 68, 65, 78, 67, 69, 82, 128, 68, 65, 77, 80, 128, 68, 65, - 77, 208, 68, 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 77, 77, 65, 84, 65, - 206, 68, 65, 77, 77, 65, 128, 68, 65, 77, 77, 193, 68, 65, 77, 65, 82, - 85, 128, 68, 65, 77, 65, 71, 69, 68, 128, 68, 65, 77, 65, 71, 69, 196, - 68, 65, 76, 69, 84, 72, 45, 82, 69, 83, 72, 128, 68, 65, 76, 69, 84, 128, - 68, 65, 76, 69, 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, - 128, 68, 65, 76, 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, - 128, 68, 65, 73, 78, 71, 128, 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, - 85, 83, 72, 45, 50, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, - 71, 83, 128, 68, 65, 71, 71, 69, 82, 128, 68, 65, 71, 71, 69, 210, 68, - 65, 71, 69, 83, 72, 128, 68, 65, 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, - 73, 78, 78, 65, 128, 68, 65, 71, 65, 218, 68, 65, 71, 65, 76, 71, 65, - 128, 68, 65, 71, 51, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, 68, 65, - 69, 199, 68, 65, 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, 68, 65, - 65, 76, 73, 128, 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, - 68, 48, 54, 55, 71, 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, - 128, 68, 48, 54, 55, 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, - 66, 128, 68, 48, 54, 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, - 128, 68, 48, 54, 53, 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, - 48, 54, 50, 128, 68, 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, - 57, 128, 68, 48, 53, 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, - 68, 48, 53, 53, 128, 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, - 48, 53, 51, 128, 68, 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, - 53, 49, 128, 68, 48, 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, - 53, 48, 71, 128, 68, 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, - 48, 53, 48, 68, 128, 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, - 68, 48, 53, 48, 65, 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, - 48, 52, 56, 65, 128, 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, - 52, 54, 65, 128, 68, 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, - 52, 128, 68, 48, 52, 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, - 68, 48, 52, 48, 128, 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, - 51, 55, 128, 68, 48, 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, - 65, 128, 68, 48, 51, 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, - 68, 48, 51, 49, 65, 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, - 48, 50, 57, 128, 68, 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, - 50, 55, 128, 68, 48, 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, - 128, 68, 48, 50, 51, 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, - 48, 50, 48, 128, 68, 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, - 55, 128, 68, 48, 49, 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, - 68, 48, 49, 51, 128, 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, - 49, 48, 128, 68, 48, 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, - 56, 128, 68, 48, 48, 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, - 68, 48, 48, 52, 128, 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, - 48, 49, 128, 67, 89, 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, - 89, 82, 69, 78, 65, 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 79, 45, 77, - 73, 78, 79, 65, 206, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, 82, 85, - 83, 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, 84, 89, - 128, 67, 89, 67, 76, 79, 78, 69, 128, 67, 89, 65, 89, 128, 67, 89, 65, - 87, 128, 67, 89, 65, 128, 67, 87, 79, 79, 128, 67, 87, 79, 128, 67, 87, - 73, 73, 128, 67, 87, 73, 128, 67, 87, 69, 79, 82, 84, 72, 128, 67, 87, - 69, 128, 67, 87, 65, 65, 128, 67, 85, 88, 128, 67, 85, 85, 128, 67, 85, - 212, 67, 85, 83, 84, 79, 77, 83, 128, 67, 85, 83, 84, 79, 77, 69, 210, - 67, 85, 83, 84, 65, 82, 68, 128, 67, 85, 83, 80, 128, 67, 85, 82, 88, - 128, 67, 85, 82, 86, 73, 78, 199, 67, 85, 82, 86, 69, 68, 128, 67, 85, - 82, 86, 69, 196, 67, 85, 82, 86, 69, 128, 67, 85, 82, 86, 197, 67, 85, - 82, 83, 73, 86, 197, 67, 85, 82, 82, 217, 67, 85, 82, 82, 69, 78, 84, - 128, 67, 85, 82, 82, 69, 78, 212, 67, 85, 82, 76, 217, 67, 85, 82, 76, - 73, 78, 199, 67, 85, 82, 76, 69, 196, 67, 85, 82, 76, 128, 67, 85, 82, - 128, 67, 85, 80, 80, 69, 68, 128, 67, 85, 80, 80, 69, 196, 67, 85, 80, - 73, 68, 79, 128, 67, 85, 80, 67, 65, 75, 69, 128, 67, 85, 79, 88, 128, - 67, 85, 79, 80, 128, 67, 85, 79, 128, 67, 85, 205, 67, 85, 76, 84, 73, - 86, 65, 84, 73, 79, 206, 67, 85, 67, 85, 77, 66, 69, 82, 128, 67, 85, 66, - 69, 68, 128, 67, 85, 66, 69, 128, 67, 85, 66, 197, 67, 85, 65, 84, 82, - 73, 76, 76, 79, 128, 67, 85, 65, 84, 82, 73, 76, 76, 207, 67, 85, 65, - 205, 67, 83, 73, 128, 67, 82, 89, 83, 84, 65, 204, 67, 82, 89, 80, 84, - 79, 71, 82, 65, 77, 77, 73, 195, 67, 82, 89, 73, 78, 199, 67, 82, 85, 90, - 69, 73, 82, 207, 67, 82, 85, 84, 67, 72, 128, 67, 82, 85, 67, 73, 70, 79, - 82, 205, 67, 82, 85, 67, 73, 66, 76, 69, 45, 53, 128, 67, 82, 85, 67, 73, - 66, 76, 69, 45, 52, 128, 67, 82, 85, 67, 73, 66, 76, 69, 45, 51, 128, 67, - 82, 85, 67, 73, 66, 76, 69, 45, 50, 128, 67, 82, 85, 67, 73, 66, 76, 69, - 128, 67, 82, 79, 87, 78, 128, 67, 82, 79, 83, 83, 73, 78, 71, 128, 67, - 82, 79, 83, 83, 73, 78, 199, 67, 82, 79, 83, 83, 72, 65, 84, 67, 200, 67, - 82, 79, 83, 83, 69, 68, 45, 84, 65, 73, 76, 128, 67, 82, 79, 83, 83, 69, - 68, 128, 67, 82, 79, 83, 83, 69, 196, 67, 82, 79, 83, 83, 66, 79, 78, 69, - 83, 128, 67, 82, 79, 83, 83, 66, 65, 82, 128, 67, 82, 79, 83, 83, 128, - 67, 82, 79, 83, 211, 67, 82, 79, 80, 128, 67, 82, 79, 73, 88, 128, 67, - 82, 79, 73, 83, 83, 65, 78, 84, 128, 67, 82, 79, 67, 85, 211, 67, 82, 79, - 67, 79, 68, 73, 76, 69, 128, 67, 82, 73, 67, 75, 69, 84, 128, 67, 82, 73, - 67, 75, 69, 212, 67, 82, 69, 83, 67, 69, 78, 84, 83, 128, 67, 82, 69, 83, - 67, 69, 78, 84, 128, 67, 82, 69, 83, 67, 69, 78, 212, 67, 82, 69, 68, 73, - 212, 67, 82, 69, 65, 84, 73, 86, 197, 67, 82, 69, 65, 77, 128, 67, 82, - 65, 89, 79, 78, 128, 67, 82, 65, 66, 128, 67, 82, 128, 67, 79, 88, 128, - 67, 79, 87, 66, 79, 217, 67, 79, 87, 128, 67, 79, 215, 67, 79, 86, 69, - 82, 73, 78, 199, 67, 79, 86, 69, 82, 128, 67, 79, 85, 80, 76, 197, 67, - 79, 85, 78, 84, 73, 78, 199, 67, 79, 85, 78, 84, 69, 82, 83, 73, 78, 75, - 128, 67, 79, 85, 78, 84, 69, 82, 66, 79, 82, 69, 128, 67, 79, 85, 78, 67, - 73, 204, 67, 79, 85, 67, 200, 67, 79, 84, 128, 67, 79, 82, 82, 69, 83, - 80, 79, 78, 68, 211, 67, 79, 82, 82, 69, 67, 84, 128, 67, 79, 82, 80, 83, - 69, 128, 67, 79, 82, 80, 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 82, 79, - 78, 73, 83, 128, 67, 79, 82, 78, 73, 83, 200, 67, 79, 82, 78, 69, 82, 83, - 128, 67, 79, 82, 78, 69, 82, 128, 67, 79, 82, 78, 69, 210, 67, 79, 82, - 75, 128, 67, 79, 82, 65, 76, 128, 67, 79, 80, 89, 82, 73, 71, 72, 84, - 128, 67, 79, 80, 89, 82, 73, 71, 72, 212, 67, 79, 80, 89, 76, 69, 70, - 212, 67, 79, 80, 89, 128, 67, 79, 80, 82, 79, 68, 85, 67, 84, 128, 67, - 79, 80, 80, 69, 82, 45, 50, 128, 67, 79, 80, 80, 69, 82, 128, 67, 79, 80, - 128, 67, 79, 79, 76, 128, 67, 79, 79, 75, 73, 78, 71, 128, 67, 79, 79, - 75, 73, 69, 128, 67, 79, 79, 75, 69, 196, 67, 79, 79, 128, 67, 79, 78, - 86, 69, 82, 71, 73, 78, 199, 67, 79, 78, 86, 69, 78, 73, 69, 78, 67, 197, - 67, 79, 78, 84, 82, 79, 76, 128, 67, 79, 78, 84, 82, 79, 204, 67, 79, 78, - 84, 82, 65, 82, 73, 69, 84, 89, 128, 67, 79, 78, 84, 82, 65, 67, 84, 73, - 79, 78, 128, 67, 79, 78, 84, 79, 85, 82, 69, 196, 67, 79, 78, 84, 79, 85, - 210, 67, 79, 78, 84, 73, 78, 85, 73, 78, 199, 67, 79, 78, 84, 73, 78, 85, - 65, 84, 73, 79, 206, 67, 79, 78, 84, 69, 78, 84, 73, 79, 78, 128, 67, 79, - 78, 84, 69, 77, 80, 76, 65, 84, 73, 79, 78, 128, 67, 79, 78, 84, 65, 73, - 78, 211, 67, 79, 78, 84, 65, 73, 78, 73, 78, 199, 67, 79, 78, 84, 65, 73, - 206, 67, 79, 78, 84, 65, 67, 84, 128, 67, 79, 78, 83, 84, 82, 85, 67, 84, - 73, 79, 78, 128, 67, 79, 78, 83, 84, 82, 85, 67, 84, 73, 79, 206, 67, 79, - 78, 83, 84, 65, 78, 84, 128, 67, 79, 78, 83, 84, 65, 78, 212, 67, 79, 78, - 83, 84, 65, 78, 67, 89, 128, 67, 79, 78, 83, 69, 67, 85, 84, 73, 86, 197, - 67, 79, 78, 74, 85, 78, 67, 84, 73, 79, 78, 128, 67, 79, 78, 74, 85, 71, - 65, 84, 197, 67, 79, 78, 74, 79, 73, 78, 73, 78, 199, 67, 79, 78, 74, 79, - 73, 78, 69, 82, 128, 67, 79, 78, 74, 79, 73, 78, 69, 68, 128, 67, 79, 78, - 74, 79, 73, 78, 69, 196, 67, 79, 78, 73, 67, 65, 204, 67, 79, 78, 71, 82, - 85, 69, 78, 212, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, - 128, 67, 79, 78, 70, 85, 83, 69, 196, 67, 79, 78, 70, 79, 85, 78, 68, 69, - 196, 67, 79, 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 70, 69, 84, 84, - 201, 67, 79, 78, 67, 65, 86, 69, 45, 83, 73, 68, 69, 196, 67, 79, 78, 67, - 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 196, 67, 79, 77, 80, 85, 84, 69, - 82, 83, 128, 67, 79, 77, 80, 85, 84, 69, 82, 128, 67, 79, 77, 80, 82, 69, - 83, 83, 73, 79, 78, 128, 67, 79, 77, 80, 82, 69, 83, 83, 69, 196, 67, 79, - 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 67, 79, 77, 80, 79, 83, 73, 84, - 73, 79, 206, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 55, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 55, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, - 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 55, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 55, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 54, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, - 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 54, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 54, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 54, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, - 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 53, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 53, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 53, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 53, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 52, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 52, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 52, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 52, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, - 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 51, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 51, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 51, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 51, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, - 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 50, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 50, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 50, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 50, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, - 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 49, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 49, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 49, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, - 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 49, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 57, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 56, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 52, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 51, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 48, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 57, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 53, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 52, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 49, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 48, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 54, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 53, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 50, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 49, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 55, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 54, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 51, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 50, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 56, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 55, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 52, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 51, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 57, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 56, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 53, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 52, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 48, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 57, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 54, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 53, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 49, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 48, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 55, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 54, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 50, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 49, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, - 45, 48, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 56, - 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 55, 128, 67, 79, 77, - 80, 79, 78, 69, 78, 84, 45, 48, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, - 78, 84, 45, 48, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, - 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 51, 128, 67, - 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 50, 128, 67, 79, 77, 80, 79, - 78, 69, 78, 84, 45, 48, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 212, - 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, 67, 79, 77, 80, 76, 69, 84, - 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, 69, 68, 128, 67, 79, 77, 80, - 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, 65, 83, 83, 128, 67, 79, 77, - 80, 65, 82, 69, 128, 67, 79, 77, 77, 79, 206, 67, 79, 77, 77, 69, 82, 67, - 73, 65, 204, 67, 79, 77, 77, 65, 78, 68, 128, 67, 79, 77, 77, 65, 128, - 67, 79, 77, 77, 193, 67, 79, 77, 69, 84, 128, 67, 79, 77, 66, 73, 78, 69, - 68, 128, 67, 79, 77, 66, 73, 78, 65, 84, 73, 79, 78, 128, 67, 79, 77, 66, - 128, 67, 79, 76, 85, 77, 78, 128, 67, 79, 76, 79, 82, 128, 67, 79, 76, - 76, 73, 83, 73, 79, 206, 67, 79, 76, 76, 128, 67, 79, 76, 196, 67, 79, - 73, 78, 128, 67, 79, 70, 70, 73, 78, 128, 67, 79, 69, 78, 71, 128, 67, - 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, 79, 67, 79, 78, 85, 84, 128, - 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 67, 75, 82, 79, 65, 67, 72, 128, - 67, 79, 65, 84, 128, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, 65, 128, - 67, 77, 51, 48, 50, 128, 67, 77, 51, 48, 49, 128, 67, 77, 49, 49, 52, - 128, 67, 77, 49, 49, 50, 128, 67, 77, 49, 49, 48, 128, 67, 77, 49, 48, - 57, 128, 67, 77, 49, 48, 56, 128, 67, 77, 49, 48, 55, 128, 67, 77, 49, - 48, 53, 128, 67, 77, 49, 48, 52, 128, 67, 77, 49, 48, 51, 128, 67, 77, - 49, 48, 50, 128, 67, 77, 49, 48, 49, 128, 67, 77, 49, 48, 48, 128, 67, - 77, 48, 57, 57, 128, 67, 77, 48, 57, 56, 128, 67, 77, 48, 57, 55, 128, - 67, 77, 48, 57, 54, 128, 67, 77, 48, 57, 53, 128, 67, 77, 48, 57, 52, - 128, 67, 77, 48, 57, 50, 128, 67, 77, 48, 57, 49, 128, 67, 77, 48, 57, - 48, 128, 67, 77, 48, 56, 57, 128, 67, 77, 48, 56, 56, 128, 67, 77, 48, - 56, 55, 128, 67, 77, 48, 56, 54, 128, 67, 77, 48, 56, 53, 128, 67, 77, - 48, 56, 52, 128, 67, 77, 48, 56, 51, 128, 67, 77, 48, 56, 50, 128, 67, - 77, 48, 56, 49, 128, 67, 77, 48, 56, 48, 128, 67, 77, 48, 55, 57, 128, - 67, 77, 48, 55, 56, 128, 67, 77, 48, 55, 54, 128, 67, 77, 48, 55, 53, 66, - 128, 67, 77, 48, 55, 53, 128, 67, 77, 48, 55, 52, 128, 67, 77, 48, 55, - 51, 128, 67, 77, 48, 55, 50, 128, 67, 77, 48, 55, 49, 128, 67, 77, 48, - 55, 48, 128, 67, 77, 48, 54, 57, 128, 67, 77, 48, 54, 56, 128, 67, 77, - 48, 54, 55, 128, 67, 77, 48, 54, 54, 128, 67, 77, 48, 54, 52, 128, 67, - 77, 48, 54, 51, 128, 67, 77, 48, 54, 50, 128, 67, 77, 48, 54, 49, 128, - 67, 77, 48, 54, 48, 128, 67, 77, 48, 53, 57, 128, 67, 77, 48, 53, 56, - 128, 67, 77, 48, 53, 54, 128, 67, 77, 48, 53, 53, 128, 67, 77, 48, 53, - 52, 128, 67, 77, 48, 53, 51, 128, 67, 77, 48, 53, 50, 128, 67, 77, 48, - 53, 49, 128, 67, 77, 48, 53, 48, 128, 67, 77, 48, 52, 57, 128, 67, 77, - 48, 52, 55, 128, 67, 77, 48, 52, 54, 128, 67, 77, 48, 52, 52, 128, 67, - 77, 48, 52, 49, 128, 67, 77, 48, 52, 48, 128, 67, 77, 48, 51, 57, 128, - 67, 77, 48, 51, 56, 128, 67, 77, 48, 51, 55, 128, 67, 77, 48, 51, 54, - 128, 67, 77, 48, 51, 53, 128, 67, 77, 48, 51, 52, 128, 67, 77, 48, 51, - 51, 128, 67, 77, 48, 51, 48, 128, 67, 77, 48, 50, 57, 128, 67, 77, 48, - 50, 56, 128, 67, 77, 48, 50, 55, 128, 67, 77, 48, 50, 54, 128, 67, 77, - 48, 50, 53, 128, 67, 77, 48, 50, 52, 128, 67, 77, 48, 50, 51, 128, 67, - 77, 48, 50, 49, 128, 67, 77, 48, 49, 57, 128, 67, 77, 48, 49, 55, 128, - 67, 77, 48, 49, 53, 128, 67, 77, 48, 49, 51, 128, 67, 77, 48, 49, 50, 66, - 128, 67, 77, 48, 49, 50, 128, 67, 77, 48, 49, 49, 128, 67, 77, 48, 49, - 48, 128, 67, 77, 48, 48, 57, 128, 67, 77, 48, 48, 56, 128, 67, 77, 48, - 48, 55, 128, 67, 77, 48, 48, 54, 128, 67, 77, 48, 48, 53, 128, 67, 77, - 48, 48, 52, 128, 67, 77, 48, 48, 50, 128, 67, 77, 48, 48, 49, 128, 67, - 77, 128, 67, 205, 67, 76, 85, 83, 84, 69, 82, 45, 73, 78, 73, 84, 73, 65, - 204, 67, 76, 85, 83, 84, 69, 82, 45, 70, 73, 78, 65, 204, 67, 76, 85, 83, - 84, 69, 210, 67, 76, 85, 66, 83, 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, - 69, 196, 67, 76, 85, 66, 128, 67, 76, 85, 194, 67, 76, 79, 87, 206, 67, - 76, 79, 86, 69, 82, 128, 67, 76, 79, 85, 68, 128, 67, 76, 79, 85, 196, - 67, 76, 79, 84, 72, 69, 83, 128, 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, - 69, 84, 128, 67, 76, 79, 83, 69, 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, - 68, 128, 67, 76, 79, 83, 197, 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, - 76, 79, 67, 203, 67, 76, 73, 86, 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, - 82, 68, 128, 67, 76, 73, 78, 75, 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, - 199, 67, 76, 73, 77, 66, 73, 78, 71, 128, 67, 76, 73, 77, 65, 67, 85, 83, - 128, 67, 76, 73, 70, 70, 128, 67, 76, 73, 67, 75, 128, 67, 76, 73, 67, - 203, 67, 76, 69, 70, 45, 50, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, - 69, 70, 128, 67, 76, 69, 198, 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, - 69, 65, 210, 67, 76, 65, 83, 83, 73, 67, 65, 204, 67, 76, 65, 80, 80, 73, - 78, 199, 67, 76, 65, 80, 80, 69, 210, 67, 76, 65, 78, 128, 67, 76, 65, - 206, 67, 76, 65, 77, 83, 72, 69, 76, 204, 67, 76, 65, 73, 77, 128, 67, - 76, 128, 67, 73, 88, 128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, - 84, 89, 83, 67, 65, 80, 69, 128, 67, 73, 84, 89, 83, 67, 65, 80, 197, 67, - 73, 84, 201, 67, 73, 84, 65, 84, 73, 79, 206, 67, 73, 84, 128, 67, 73, - 82, 67, 85, 211, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 128, 67, 73, 82, - 67, 85, 77, 70, 76, 69, 216, 67, 73, 82, 67, 85, 76, 65, 84, 73, 79, 206, - 67, 73, 82, 67, 76, 73, 78, 71, 128, 67, 73, 82, 67, 76, 73, 78, 199, 67, - 73, 82, 67, 76, 69, 83, 128, 67, 73, 82, 67, 76, 69, 211, 67, 73, 82, 67, - 76, 69, 68, 128, 67, 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, 128, - 67, 73, 78, 69, 77, 65, 128, 67, 73, 206, 67, 73, 77, 128, 67, 73, 205, - 67, 73, 73, 128, 67, 73, 69, 88, 128, 67, 73, 69, 85, 67, 45, 83, 83, 65, - 78, 71, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, 45, 80, 73, 69, 85, - 80, 128, 67, 73, 69, 85, 67, 45, 73, 69, 85, 78, 71, 128, 67, 73, 69, 85, - 195, 67, 73, 69, 84, 128, 67, 73, 69, 80, 128, 67, 73, 69, 128, 67, 72, - 89, 88, 128, 67, 72, 89, 84, 128, 67, 72, 89, 82, 88, 128, 67, 72, 89, - 82, 128, 67, 72, 89, 80, 128, 67, 72, 87, 86, 128, 67, 72, 85, 88, 128, - 67, 72, 85, 82, 88, 128, 67, 72, 85, 82, 67, 72, 128, 67, 72, 85, 82, - 128, 67, 72, 85, 80, 128, 67, 72, 85, 79, 88, 128, 67, 72, 85, 79, 84, - 128, 67, 72, 85, 79, 80, 128, 67, 72, 85, 79, 128, 67, 72, 85, 76, 65, - 128, 67, 72, 85, 128, 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 85, 77, - 128, 67, 72, 82, 79, 78, 79, 85, 128, 67, 72, 82, 79, 78, 79, 78, 128, - 67, 72, 82, 79, 77, 193, 67, 72, 82, 79, 193, 67, 72, 82, 73, 86, 73, - 128, 67, 72, 82, 73, 83, 84, 77, 65, 83, 128, 67, 72, 82, 73, 83, 84, 77, - 65, 211, 67, 72, 79, 89, 128, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, - 67, 72, 79, 82, 69, 86, 77, 193, 67, 72, 79, 82, 65, 83, 77, 73, 65, 206, - 67, 72, 79, 80, 83, 84, 73, 67, 75, 83, 128, 67, 72, 79, 80, 128, 67, 72, - 79, 75, 69, 128, 67, 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, - 197, 67, 72, 79, 65, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, - 71, 83, 73, 79, 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, - 71, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, - 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, - 73, 84, 85, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, - 79, 78, 128, 67, 72, 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, - 128, 67, 72, 73, 78, 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, - 78, 69, 83, 197, 67, 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, - 73, 77, 128, 67, 72, 73, 76, 76, 213, 67, 72, 73, 76, 68, 82, 69, 206, - 67, 72, 73, 76, 68, 128, 67, 72, 73, 76, 128, 67, 72, 73, 75, 201, 67, - 72, 73, 69, 85, 67, 72, 45, 75, 72, 73, 69, 85, 75, 72, 128, 67, 72, 73, - 69, 85, 67, 72, 45, 72, 73, 69, 85, 72, 128, 67, 72, 73, 69, 85, 67, 200, - 67, 72, 73, 67, 75, 69, 78, 128, 67, 72, 73, 67, 75, 128, 67, 72, 73, - 128, 67, 72, 201, 67, 72, 72, 73, 77, 128, 67, 72, 72, 65, 128, 67, 72, - 69, 88, 128, 67, 72, 69, 86, 82, 79, 78, 128, 67, 72, 69, 86, 82, 79, - 206, 67, 72, 69, 84, 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, - 69, 83, 84, 128, 67, 72, 69, 83, 211, 67, 72, 69, 82, 89, 128, 67, 72, - 69, 82, 82, 217, 67, 72, 69, 82, 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, - 69, 82, 69, 196, 67, 72, 69, 80, 128, 67, 72, 69, 76, 89, 85, 83, 84, 75, - 65, 128, 67, 72, 69, 76, 78, 85, 128, 67, 72, 69, 73, 78, 65, 80, 128, - 67, 72, 69, 73, 75, 72, 69, 73, 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, - 67, 72, 69, 69, 83, 197, 67, 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, - 77, 128, 67, 72, 69, 69, 75, 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, - 69, 128, 67, 72, 69, 67, 75, 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, - 69, 67, 203, 67, 72, 197, 67, 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, - 65, 78, 73, 128, 67, 72, 65, 84, 84, 65, 87, 65, 128, 67, 72, 65, 84, - 128, 67, 72, 65, 83, 72, 75, 65, 128, 67, 72, 65, 83, 72, 75, 193, 67, - 72, 65, 82, 84, 128, 67, 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, - 128, 67, 72, 65, 82, 73, 79, 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 54, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 54, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 53, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 53, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 52, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 51, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 51, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 50, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 50, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 49, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 49, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 48, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 48, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 128, 67, 72, 65, 82, 65, 67, 84, 69, 210, 67, 72, - 65, 82, 128, 67, 72, 65, 80, 84, 69, 82, 128, 67, 72, 65, 80, 128, 67, - 72, 65, 78, 71, 128, 67, 72, 65, 78, 128, 67, 72, 65, 77, 75, 79, 128, - 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 77, 73, 76, 73, 128, 67, - 72, 65, 205, 67, 72, 65, 75, 77, 193, 67, 72, 65, 73, 78, 83, 128, 67, - 72, 65, 68, 65, 128, 67, 72, 65, 196, 67, 72, 65, 65, 128, 67, 71, 74, - 128, 67, 69, 88, 128, 67, 69, 86, 73, 84, 85, 128, 67, 69, 82, 69, 83, - 128, 67, 69, 82, 69, 77, 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, - 69, 82, 45, 87, 65, 128, 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, - 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, - 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, - 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, - 78, 71, 67, 72, 73, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, - 71, 67, 72, 73, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, - 84, 85, 82, 73, 65, 204, 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, - 78, 84, 82, 69, 68, 128, 67, 69, 78, 84, 82, 69, 196, 67, 69, 78, 84, 82, - 69, 128, 67, 69, 78, 84, 82, 197, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, - 84, 73, 79, 206, 67, 69, 78, 128, 67, 69, 76, 84, 73, 195, 67, 69, 76, - 83, 73, 85, 83, 128, 67, 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, 128, 67, - 69, 73, 82, 84, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 69, 73, 76, 73, - 78, 199, 67, 69, 69, 86, 128, 67, 69, 69, 66, 128, 67, 69, 69, 128, 67, - 69, 68, 73, 76, 76, 65, 128, 67, 69, 68, 73, 76, 76, 193, 67, 69, 68, - 201, 67, 69, 67, 69, 75, 128, 67, 69, 67, 65, 75, 128, 67, 69, 67, 65, - 203, 67, 69, 65, 76, 67, 128, 67, 67, 85, 128, 67, 67, 79, 128, 67, 67, - 73, 128, 67, 67, 72, 85, 128, 67, 67, 72, 79, 128, 67, 67, 72, 73, 128, - 67, 67, 72, 72, 85, 128, 67, 67, 72, 72, 79, 128, 67, 67, 72, 72, 73, - 128, 67, 67, 72, 72, 69, 69, 128, 67, 67, 72, 72, 69, 128, 67, 67, 72, - 72, 65, 65, 128, 67, 67, 72, 72, 65, 128, 67, 67, 72, 69, 69, 128, 67, - 67, 72, 69, 128, 67, 67, 72, 65, 65, 128, 67, 67, 72, 65, 128, 67, 67, - 72, 128, 67, 67, 69, 69, 128, 67, 67, 65, 65, 128, 67, 65, 89, 78, 128, - 67, 65, 89, 65, 78, 78, 65, 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, - 67, 65, 85, 84, 73, 79, 206, 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, - 85, 68, 65, 84, 197, 67, 65, 85, 68, 65, 128, 67, 65, 85, 67, 65, 83, 73, - 65, 206, 67, 65, 85, 128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, - 67, 65, 212, 67, 65, 83, 84, 76, 69, 128, 67, 65, 83, 75, 69, 212, 67, - 65, 82, 89, 83, 84, 73, 65, 206, 67, 65, 82, 84, 87, 72, 69, 69, 76, 128, - 67, 65, 82, 84, 82, 73, 68, 71, 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, - 211, 67, 65, 82, 82, 79, 84, 128, 67, 65, 82, 82, 73, 65, 71, 197, 67, - 65, 82, 80, 69, 78, 84, 82, 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, - 69, 204, 67, 65, 82, 79, 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, - 203, 67, 65, 82, 73, 65, 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, - 212, 67, 65, 82, 197, 67, 65, 82, 68, 83, 128, 67, 65, 82, 196, 67, 65, - 82, 128, 67, 65, 210, 67, 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, - 128, 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, - 67, 65, 80, 79, 128, 67, 65, 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, - 73, 84, 65, 76, 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, - 65, 78, 79, 69, 128, 67, 65, 78, 78, 79, 78, 128, 67, 65, 78, 78, 69, - 196, 67, 65, 78, 199, 67, 65, 78, 69, 128, 67, 65, 78, 68, 89, 128, 67, - 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, - 73, 78, 68, 213, 67, 65, 78, 68, 82, 65, 128, 67, 65, 78, 68, 82, 193, - 67, 65, 78, 68, 76, 69, 128, 67, 65, 78, 67, 69, 82, 128, 67, 65, 78, 67, - 69, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, - 67, 69, 204, 67, 65, 78, 128, 67, 65, 77, 80, 73, 78, 71, 128, 67, 65, - 77, 78, 85, 195, 67, 65, 77, 69, 82, 65, 128, 67, 65, 77, 69, 82, 193, - 67, 65, 77, 69, 76, 128, 67, 65, 76, 89, 65, 128, 67, 65, 76, 89, 193, - 67, 65, 76, 88, 128, 67, 65, 76, 76, 128, 67, 65, 76, 204, 67, 65, 76, - 69, 78, 68, 65, 82, 128, 67, 65, 76, 69, 78, 68, 65, 210, 67, 65, 76, 67, - 85, 76, 65, 84, 79, 82, 128, 67, 65, 76, 67, 128, 67, 65, 75, 82, 65, - 128, 67, 65, 75, 197, 67, 65, 73, 128, 67, 65, 72, 128, 67, 65, 69, 83, - 85, 82, 65, 128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 68, 193, - 67, 65, 67, 84, 85, 83, 128, 67, 65, 66, 76, 69, 87, 65, 89, 128, 67, 65, - 66, 73, 78, 69, 84, 128, 67, 65, 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, - 128, 67, 65, 65, 78, 71, 128, 67, 65, 65, 73, 128, 67, 193, 67, 48, 50, - 52, 128, 67, 48, 50, 51, 128, 67, 48, 50, 50, 128, 67, 48, 50, 49, 128, - 67, 48, 50, 48, 128, 67, 48, 49, 57, 128, 67, 48, 49, 56, 128, 67, 48, - 49, 55, 128, 67, 48, 49, 54, 128, 67, 48, 49, 53, 128, 67, 48, 49, 52, - 128, 67, 48, 49, 51, 128, 67, 48, 49, 50, 128, 67, 48, 49, 49, 128, 67, - 48, 49, 48, 65, 128, 67, 48, 49, 48, 128, 67, 48, 48, 57, 128, 67, 48, - 48, 56, 128, 67, 48, 48, 55, 128, 67, 48, 48, 54, 128, 67, 48, 48, 53, - 128, 67, 48, 48, 52, 128, 67, 48, 48, 51, 128, 67, 48, 48, 50, 67, 128, - 67, 48, 48, 50, 66, 128, 67, 48, 48, 50, 65, 128, 67, 48, 48, 50, 128, - 67, 48, 48, 49, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, - 45, 51, 57, 128, 67, 45, 49, 56, 128, 66, 90, 85, 78, 199, 66, 90, 72, - 201, 66, 89, 84, 197, 66, 89, 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, - 85, 75, 82, 65, 73, 78, 73, 65, 206, 66, 88, 71, 128, 66, 87, 73, 128, - 66, 87, 69, 69, 128, 66, 87, 69, 128, 66, 87, 65, 128, 66, 85, 85, 77, - 73, 83, 72, 128, 66, 85, 84, 84, 79, 78, 128, 66, 85, 84, 84, 79, 206, - 66, 85, 84, 84, 69, 82, 70, 76, 89, 128, 66, 85, 84, 84, 69, 82, 128, 66, - 85, 212, 66, 85, 83, 84, 211, 66, 85, 83, 212, 66, 85, 83, 83, 89, 69, - 82, 85, 128, 66, 85, 83, 73, 78, 69, 83, 211, 66, 85, 211, 66, 85, 82, - 213, 66, 85, 82, 82, 73, 84, 79, 128, 66, 85, 82, 50, 128, 66, 85, 210, - 66, 85, 79, 89, 128, 66, 85, 79, 88, 128, 66, 85, 79, 80, 128, 66, 85, - 78, 78, 217, 66, 85, 78, 71, 128, 66, 85, 77, 80, 217, 66, 85, 76, 85, - 71, 128, 66, 85, 76, 85, 199, 66, 85, 76, 76, 83, 69, 89, 69, 128, 66, - 85, 76, 76, 211, 66, 85, 76, 76, 72, 79, 82, 78, 128, 66, 85, 76, 76, 72, - 79, 82, 206, 66, 85, 76, 76, 69, 84, 128, 66, 85, 76, 76, 69, 212, 66, - 85, 76, 76, 128, 66, 85, 76, 66, 128, 66, 85, 75, 89, 128, 66, 85, 73, - 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, 76, 68, 73, 78, 71, 128, 66, 85, - 73, 76, 68, 73, 78, 199, 66, 85, 72, 73, 196, 66, 85, 71, 73, 78, 69, 83, - 197, 66, 85, 71, 128, 66, 85, 70, 70, 65, 76, 79, 128, 66, 85, 68, 128, - 66, 85, 67, 75, 76, 69, 128, 66, 85, 67, 75, 69, 84, 128, 66, 85, 66, 66, - 76, 69, 83, 128, 66, 85, 66, 66, 76, 69, 128, 66, 85, 66, 66, 76, 197, - 66, 83, 84, 65, 82, 128, 66, 83, 75, 85, 210, 66, 83, 75, 65, 173, 66, - 83, 68, 85, 211, 66, 82, 85, 83, 200, 66, 82, 79, 87, 206, 66, 82, 79, - 79, 77, 128, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, 66, - 82, 79, 67, 67, 79, 76, 73, 128, 66, 82, 79, 65, 196, 66, 82, 73, 83, 84, - 76, 69, 128, 66, 82, 73, 71, 72, 84, 78, 69, 83, 211, 66, 82, 73, 69, 70, - 83, 128, 66, 82, 73, 69, 70, 67, 65, 83, 69, 128, 66, 82, 73, 68, 71, - 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 128, 66, 82, 73, 128, 66, - 82, 69, 86, 73, 83, 128, 66, 82, 69, 86, 69, 45, 77, 65, 67, 82, 79, 78, - 128, 66, 82, 69, 86, 197, 66, 82, 69, 65, 84, 72, 217, 66, 82, 69, 65, - 84, 200, 66, 82, 69, 65, 83, 84, 45, 70, 69, 69, 68, 73, 78, 71, 128, 66, - 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, 72, 128, 66, 82, 68, 193, 66, 82, - 65, 78, 67, 72, 73, 78, 199, 66, 82, 65, 78, 67, 72, 69, 83, 128, 66, 82, - 65, 78, 67, 72, 128, 66, 82, 65, 78, 67, 200, 66, 82, 65, 75, 67, 69, 84, - 128, 66, 82, 65, 73, 78, 128, 66, 82, 65, 67, 75, 69, 84, 211, 66, 82, - 65, 67, 75, 69, 84, 69, 196, 66, 82, 65, 67, 75, 69, 84, 128, 66, 82, 65, - 67, 75, 69, 212, 66, 82, 65, 67, 69, 128, 66, 81, 128, 66, 80, 72, 128, - 66, 79, 89, 211, 66, 79, 89, 128, 66, 79, 88, 73, 78, 199, 66, 79, 87, - 84, 73, 69, 128, 66, 79, 87, 84, 73, 197, 66, 79, 87, 76, 73, 78, 71, - 128, 66, 79, 87, 76, 128, 66, 79, 87, 204, 66, 79, 87, 73, 78, 199, 66, - 79, 215, 66, 79, 85, 81, 85, 69, 84, 128, 66, 79, 85, 81, 85, 69, 212, - 66, 79, 85, 78, 68, 65, 82, 217, 66, 79, 84, 84, 79, 77, 45, 83, 72, 65, - 68, 69, 196, 66, 79, 84, 84, 79, 77, 45, 76, 73, 71, 72, 84, 69, 196, 66, - 79, 84, 84, 79, 77, 128, 66, 79, 84, 84, 79, 205, 66, 79, 84, 84, 76, 69, - 128, 66, 79, 84, 84, 76, 197, 66, 79, 84, 200, 66, 79, 82, 90, 89, 128, - 66, 79, 82, 90, 65, 89, 65, 128, 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, - 65, 88, 45, 51, 128, 66, 79, 82, 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, - 128, 66, 79, 80, 79, 77, 79, 70, 207, 66, 79, 79, 84, 83, 128, 66, 79, - 79, 84, 128, 66, 79, 79, 77, 69, 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, - 128, 66, 79, 79, 75, 77, 65, 82, 75, 128, 66, 79, 79, 75, 77, 65, 82, - 203, 66, 79, 78, 69, 128, 66, 79, 77, 66, 128, 66, 79, 77, 128, 66, 79, - 76, 84, 128, 66, 79, 76, 212, 66, 79, 72, 65, 73, 82, 73, 195, 66, 79, - 68, 89, 128, 66, 79, 68, 217, 66, 79, 65, 82, 128, 66, 79, 65, 128, 66, - 76, 85, 69, 66, 69, 82, 82, 73, 69, 83, 128, 66, 76, 85, 69, 128, 66, 76, - 85, 197, 66, 76, 79, 87, 73, 78, 199, 66, 76, 79, 87, 70, 73, 83, 72, - 128, 66, 76, 79, 215, 66, 76, 79, 83, 83, 79, 77, 128, 66, 76, 79, 79, - 68, 128, 66, 76, 79, 78, 196, 66, 76, 79, 67, 75, 45, 55, 128, 66, 76, - 79, 67, 75, 45, 54, 128, 66, 76, 79, 67, 75, 45, 53, 128, 66, 76, 79, 67, - 75, 45, 52, 128, 66, 76, 79, 67, 75, 45, 51, 128, 66, 76, 79, 67, 75, 45, - 50, 128, 66, 76, 79, 67, 75, 45, 49, 51, 53, 56, 128, 66, 76, 79, 67, 75, - 128, 66, 76, 73, 78, 203, 66, 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, - 66, 76, 65, 68, 197, 66, 76, 65, 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, - 65, 67, 75, 70, 79, 79, 212, 66, 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, - 210, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, - 65, 67, 75, 128, 66, 75, 65, 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, - 84, 73, 78, 199, 66, 73, 84, 197, 66, 73, 84, 67, 79, 73, 206, 66, 73, - 83, 79, 78, 128, 66, 73, 83, 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, - 65, 200, 66, 73, 83, 72, 79, 208, 66, 73, 83, 69, 67, 84, 73, 78, 199, - 66, 73, 83, 65, 72, 128, 66, 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, - 217, 66, 73, 82, 71, 65, 128, 66, 73, 82, 71, 193, 66, 73, 82, 68, 128, - 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, 78, 79, 86, 73, 76, 69, 128, - 66, 73, 78, 79, 67, 85, 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, - 78, 68, 73, 128, 66, 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, - 128, 66, 73, 76, 76, 73, 65, 82, 68, 83, 128, 66, 73, 76, 76, 69, 196, - 66, 73, 76, 65, 66, 73, 65, 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, - 128, 66, 73, 199, 66, 73, 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, - 66, 73, 68, 65, 75, 85, 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, - 66, 73, 67, 89, 67, 76, 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, - 73, 67, 69, 80, 83, 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, - 66, 128, 66, 201, 66, 72, 85, 128, 66, 72, 79, 79, 128, 66, 72, 79, 128, - 66, 72, 73, 128, 66, 72, 69, 84, 72, 128, 66, 72, 69, 69, 128, 66, 72, - 69, 128, 66, 72, 65, 84, 84, 73, 80, 82, 79, 76, 213, 66, 72, 65, 77, - 128, 66, 72, 65, 76, 69, 128, 66, 72, 65, 76, 197, 66, 72, 65, 73, 75, - 83, 85, 75, 201, 66, 72, 65, 65, 128, 66, 72, 65, 128, 66, 69, 89, 89, - 65, 76, 128, 66, 69, 88, 128, 66, 69, 86, 69, 82, 65, 71, 69, 128, 66, - 69, 86, 69, 82, 65, 71, 197, 66, 69, 84, 87, 69, 69, 78, 128, 66, 69, 84, - 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, 84, - 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, 65, - 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, 66, - 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, 66, - 69, 78, 212, 66, 69, 78, 71, 65, 76, 201, 66, 69, 78, 68, 69, 128, 66, - 69, 78, 68, 128, 66, 69, 78, 196, 66, 69, 206, 66, 69, 76, 84, 128, 66, - 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, 66, 69, - 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, 66, 69, - 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, 66, - 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, 78, - 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, - 206, 66, 69, 70, 79, 82, 197, 66, 69, 69, 84, 76, 69, 128, 66, 69, 69, - 84, 65, 128, 66, 69, 69, 210, 66, 69, 69, 72, 73, 86, 69, 128, 66, 69, - 69, 72, 128, 66, 69, 69, 200, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, - 65, 86, 69, 82, 128, 66, 69, 65, 86, 69, 210, 66, 69, 65, 84, 73, 78, - 199, 66, 69, 65, 84, 128, 66, 69, 65, 82, 68, 69, 196, 66, 69, 65, 82, - 128, 66, 69, 65, 210, 66, 69, 65, 78, 83, 128, 66, 69, 65, 78, 128, 66, - 69, 65, 77, 69, 196, 66, 69, 65, 68, 83, 128, 66, 69, 65, 67, 200, 66, - 67, 65, 68, 128, 66, 67, 65, 196, 66, 66, 89, 88, 128, 66, 66, 89, 84, - 128, 66, 66, 89, 80, 128, 66, 66, 89, 128, 66, 66, 85, 88, 128, 66, 66, - 85, 84, 128, 66, 66, 85, 82, 88, 128, 66, 66, 85, 82, 128, 66, 66, 85, - 80, 128, 66, 66, 85, 79, 88, 128, 66, 66, 85, 79, 80, 128, 66, 66, 85, - 79, 128, 66, 66, 85, 128, 66, 66, 79, 88, 128, 66, 66, 79, 84, 128, 66, - 66, 79, 80, 128, 66, 66, 79, 128, 66, 66, 73, 88, 128, 66, 66, 73, 80, - 128, 66, 66, 73, 69, 88, 128, 66, 66, 73, 69, 84, 128, 66, 66, 73, 69, - 80, 128, 66, 66, 73, 69, 128, 66, 66, 73, 128, 66, 66, 69, 88, 128, 66, - 66, 69, 80, 128, 66, 66, 69, 69, 128, 66, 66, 65, 88, 128, 66, 66, 65, - 84, 128, 66, 66, 65, 80, 128, 66, 66, 65, 65, 128, 66, 65, 89, 65, 78, - 78, 65, 128, 66, 65, 85, 128, 66, 65, 84, 84, 69, 82, 89, 128, 66, 65, - 84, 72, 84, 85, 66, 128, 66, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 66, - 65, 84, 72, 128, 66, 65, 84, 200, 66, 65, 84, 65, 203, 66, 65, 83, 83, - 65, 128, 66, 65, 83, 83, 193, 66, 65, 83, 75, 69, 84, 66, 65, 76, 204, - 66, 65, 83, 72, 75, 73, 210, 66, 65, 83, 72, 128, 66, 65, 83, 69, 76, 73, - 78, 197, 66, 65, 83, 69, 66, 65, 76, 76, 128, 66, 65, 83, 69, 128, 66, - 65, 83, 197, 66, 65, 82, 83, 128, 66, 65, 82, 211, 66, 65, 82, 82, 73, - 69, 82, 128, 66, 65, 82, 82, 69, 75, 72, 128, 66, 65, 82, 82, 69, 69, - 128, 66, 65, 82, 82, 69, 197, 66, 65, 82, 76, 73, 78, 69, 128, 66, 65, - 82, 76, 69, 89, 128, 66, 65, 82, 73, 89, 79, 79, 83, 65, 78, 128, 66, 65, - 82, 66, 69, 210, 66, 65, 82, 65, 50, 128, 66, 65, 210, 66, 65, 78, 84, - 79, 67, 128, 66, 65, 78, 75, 78, 79, 84, 197, 66, 65, 78, 75, 128, 66, - 65, 78, 203, 66, 65, 78, 74, 79, 128, 66, 65, 78, 68, 128, 66, 65, 78, - 65, 78, 65, 128, 66, 65, 78, 50, 128, 66, 65, 78, 178, 66, 65, 77, 66, - 79, 79, 83, 128, 66, 65, 77, 66, 79, 79, 128, 66, 65, 76, 85, 68, 65, - 128, 66, 65, 76, 76, 80, 79, 73, 78, 212, 66, 65, 76, 76, 79, 84, 128, - 66, 65, 76, 76, 79, 212, 66, 65, 76, 76, 79, 79, 78, 45, 83, 80, 79, 75, - 69, 196, 66, 65, 76, 76, 79, 79, 78, 128, 66, 65, 76, 76, 69, 212, 66, - 65, 76, 68, 128, 66, 65, 76, 65, 71, 128, 66, 65, 76, 128, 66, 65, 204, - 66, 65, 73, 82, 75, 65, 78, 128, 66, 65, 73, 77, 65, 73, 128, 66, 65, 72, - 84, 128, 66, 65, 72, 73, 82, 71, 79, 77, 85, 75, 72, 65, 128, 66, 65, 72, - 65, 82, 50, 128, 66, 65, 72, 65, 82, 178, 66, 65, 72, 128, 66, 65, 71, - 85, 69, 84, 84, 197, 66, 65, 71, 83, 128, 66, 65, 71, 71, 65, 71, 197, - 66, 65, 71, 69, 76, 128, 66, 65, 71, 65, 128, 66, 65, 71, 51, 128, 66, - 65, 199, 66, 65, 68, 77, 73, 78, 84, 79, 206, 66, 65, 68, 71, 69, 82, - 128, 66, 65, 68, 71, 69, 128, 66, 65, 196, 66, 65, 67, 84, 82, 73, 65, - 206, 66, 65, 67, 79, 78, 128, 66, 65, 67, 75, 87, 65, 82, 68, 128, 66, - 65, 67, 75, 83, 80, 65, 67, 69, 128, 66, 65, 67, 75, 83, 76, 65, 83, 72, - 128, 66, 65, 67, 75, 83, 76, 65, 83, 200, 66, 65, 67, 75, 83, 76, 65, 78, - 84, 69, 196, 66, 65, 67, 75, 72, 65, 78, 196, 66, 65, 67, 75, 45, 84, 73, - 76, 84, 69, 196, 66, 65, 67, 75, 128, 66, 65, 67, 203, 66, 65, 66, 89, - 128, 66, 65, 66, 217, 66, 65, 65, 82, 69, 82, 85, 128, 66, 65, 45, 50, - 128, 66, 51, 48, 53, 128, 66, 50, 53, 180, 66, 50, 52, 183, 66, 50, 52, - 179, 66, 50, 52, 178, 66, 50, 52, 177, 66, 50, 52, 176, 66, 50, 51, 179, - 66, 50, 51, 177, 66, 50, 51, 176, 66, 50, 50, 181, 66, 50, 50, 176, 66, - 49, 57, 177, 66, 49, 55, 182, 66, 49, 55, 179, 66, 49, 54, 57, 128, 66, - 49, 54, 56, 128, 66, 49, 54, 55, 128, 66, 49, 54, 54, 128, 66, 49, 54, - 53, 128, 66, 49, 54, 52, 128, 66, 49, 54, 179, 66, 49, 54, 178, 66, 49, - 54, 49, 128, 66, 49, 54, 48, 128, 66, 49, 53, 185, 66, 49, 53, 56, 128, - 66, 49, 53, 55, 128, 66, 49, 53, 182, 66, 49, 53, 53, 128, 66, 49, 53, - 52, 128, 66, 49, 53, 51, 128, 66, 49, 53, 50, 128, 66, 49, 53, 177, 66, - 49, 53, 48, 128, 66, 49, 52, 54, 128, 66, 49, 52, 181, 66, 49, 52, 50, - 128, 66, 49, 52, 177, 66, 49, 52, 176, 66, 49, 51, 181, 66, 49, 51, 179, - 66, 49, 51, 50, 128, 66, 49, 51, 177, 66, 49, 51, 176, 66, 49, 50, 184, - 66, 49, 50, 183, 66, 49, 50, 181, 66, 49, 50, 179, 66, 49, 50, 178, 66, - 49, 50, 177, 66, 49, 50, 176, 66, 49, 48, 57, 205, 66, 49, 48, 57, 198, - 66, 49, 48, 56, 205, 66, 49, 48, 56, 198, 66, 49, 48, 55, 205, 66, 49, - 48, 55, 198, 66, 49, 48, 54, 205, 66, 49, 48, 54, 198, 66, 49, 48, 53, - 205, 66, 49, 48, 53, 198, 66, 49, 48, 181, 66, 49, 48, 180, 66, 49, 48, - 178, 66, 49, 48, 176, 66, 48, 57, 177, 66, 48, 57, 176, 66, 48, 56, 57, - 128, 66, 48, 56, 183, 66, 48, 56, 54, 128, 66, 48, 56, 181, 66, 48, 56, - 51, 128, 66, 48, 56, 50, 128, 66, 48, 56, 177, 66, 48, 56, 176, 66, 48, - 55, 57, 128, 66, 48, 55, 184, 66, 48, 55, 183, 66, 48, 55, 182, 66, 48, - 55, 181, 66, 48, 55, 180, 66, 48, 55, 179, 66, 48, 55, 178, 66, 48, 55, - 177, 66, 48, 55, 176, 66, 48, 54, 185, 66, 48, 54, 184, 66, 48, 54, 183, - 66, 48, 54, 182, 66, 48, 54, 181, 66, 48, 54, 52, 128, 66, 48, 54, 51, - 128, 66, 48, 54, 178, 66, 48, 54, 177, 66, 48, 54, 176, 66, 48, 53, 185, - 66, 48, 53, 184, 66, 48, 53, 183, 66, 48, 53, 54, 128, 66, 48, 53, 181, - 66, 48, 53, 180, 66, 48, 53, 179, 66, 48, 53, 178, 66, 48, 53, 177, 66, - 48, 53, 176, 66, 48, 52, 57, 128, 66, 48, 52, 184, 66, 48, 52, 55, 128, - 66, 48, 52, 182, 66, 48, 52, 181, 66, 48, 52, 180, 66, 48, 52, 179, 66, - 48, 52, 178, 66, 48, 52, 177, 66, 48, 52, 176, 66, 48, 51, 185, 66, 48, - 51, 184, 66, 48, 51, 183, 66, 48, 51, 182, 66, 48, 51, 52, 128, 66, 48, - 51, 179, 66, 48, 51, 178, 66, 48, 51, 177, 66, 48, 51, 176, 66, 48, 50, - 185, 66, 48, 50, 184, 66, 48, 50, 183, 66, 48, 50, 182, 66, 48, 50, 181, - 66, 48, 50, 180, 66, 48, 50, 179, 66, 48, 50, 50, 128, 66, 48, 50, 177, - 66, 48, 50, 176, 66, 48, 49, 57, 128, 66, 48, 49, 56, 128, 66, 48, 49, - 183, 66, 48, 49, 182, 66, 48, 49, 181, 66, 48, 49, 180, 66, 48, 49, 179, - 66, 48, 49, 178, 66, 48, 49, 177, 66, 48, 49, 176, 66, 48, 48, 57, 128, - 66, 48, 48, 185, 66, 48, 48, 56, 128, 66, 48, 48, 184, 66, 48, 48, 55, - 128, 66, 48, 48, 183, 66, 48, 48, 54, 128, 66, 48, 48, 182, 66, 48, 48, - 53, 65, 128, 66, 48, 48, 53, 128, 66, 48, 48, 181, 66, 48, 48, 52, 128, - 66, 48, 48, 180, 66, 48, 48, 51, 128, 66, 48, 48, 179, 66, 48, 48, 50, - 128, 66, 48, 48, 178, 66, 48, 48, 49, 128, 66, 48, 48, 177, 65, 90, 90, - 193, 65, 90, 85, 128, 65, 89, 66, 128, 65, 89, 65, 72, 128, 65, 88, 69, - 128, 65, 87, 90, 128, 65, 87, 88, 128, 65, 87, 81, 128, 65, 87, 69, 128, - 65, 87, 67, 128, 65, 87, 65, 217, 65, 86, 79, 67, 65, 68, 79, 128, 65, - 86, 69, 83, 84, 65, 206, 65, 86, 69, 82, 65, 71, 197, 65, 86, 65, 75, 82, - 65, 72, 65, 83, 65, 78, 89, 65, 128, 65, 86, 65, 71, 82, 65, 72, 65, 128, - 65, 85, 89, 65, 78, 78, 65, 128, 65, 85, 84, 85, 77, 78, 128, 65, 85, 84, - 79, 77, 79, 66, 73, 76, 69, 128, 65, 85, 84, 79, 77, 65, 84, 69, 196, 65, - 85, 84, 207, 65, 85, 83, 84, 82, 65, 204, 65, 85, 82, 73, 80, 73, 71, 77, - 69, 78, 84, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 72, 65, 128, 65, - 85, 82, 65, 77, 65, 90, 68, 65, 65, 45, 50, 128, 65, 85, 82, 65, 77, 65, - 90, 68, 65, 65, 128, 65, 85, 78, 78, 128, 65, 85, 71, 85, 83, 84, 128, - 65, 85, 71, 77, 69, 78, 84, 65, 84, 73, 79, 206, 65, 85, 69, 128, 65, 85, - 66, 69, 82, 71, 73, 78, 69, 128, 65, 84, 84, 73, 195, 65, 84, 84, 72, 65, - 67, 65, 78, 128, 65, 84, 84, 69, 78, 84, 73, 79, 78, 128, 65, 84, 84, 65, - 203, 65, 84, 84, 65, 67, 72, 73, 78, 199, 65, 84, 84, 65, 67, 72, 69, - 196, 65, 84, 79, 205, 65, 84, 78, 65, 200, 65, 84, 77, 65, 65, 85, 128, - 65, 84, 73, 89, 65, 128, 65, 84, 73, 85, 128, 65, 84, 73, 75, 82, 65, 77, - 65, 128, 65, 84, 72, 76, 69, 84, 73, 195, 65, 84, 72, 65, 82, 86, 65, 86, - 69, 68, 73, 195, 65, 84, 72, 65, 80, 65, 83, 67, 65, 206, 65, 84, 72, 45, - 84, 72, 65, 76, 65, 84, 72, 65, 128, 65, 83, 90, 128, 65, 83, 89, 85, 82, - 193, 65, 83, 89, 77, 80, 84, 79, 84, 73, 67, 65, 76, 76, 217, 65, 83, 84, - 82, 79, 78, 79, 77, 73, 67, 65, 204, 65, 83, 84, 82, 79, 76, 79, 71, 73, - 67, 65, 204, 65, 83, 84, 82, 65, 69, 65, 128, 65, 83, 84, 79, 78, 73, 83, - 72, 69, 196, 65, 83, 84, 69, 82, 73, 83, 77, 128, 65, 83, 84, 69, 82, 73, - 83, 75, 211, 65, 83, 84, 69, 82, 73, 83, 75, 128, 65, 83, 84, 69, 82, 73, - 83, 203, 65, 83, 84, 69, 82, 73, 83, 67, 85, 83, 128, 65, 83, 83, 89, 82, - 73, 65, 206, 65, 83, 83, 69, 82, 84, 73, 79, 78, 128, 65, 83, 80, 73, 82, - 65, 84, 73, 79, 78, 128, 65, 83, 80, 73, 82, 65, 84, 69, 196, 65, 83, 80, - 69, 82, 128, 65, 83, 73, 65, 45, 65, 85, 83, 84, 82, 65, 76, 73, 65, 128, - 65, 83, 72, 71, 65, 66, 128, 65, 83, 72, 69, 83, 128, 65, 83, 72, 57, - 128, 65, 83, 72, 51, 128, 65, 83, 72, 178, 65, 83, 67, 73, 193, 65, 83, - 67, 69, 78, 84, 128, 65, 83, 67, 69, 78, 68, 73, 78, 199, 65, 83, 65, 76, - 50, 128, 65, 83, 45, 83, 65, 76, 65, 65, 84, 213, 65, 83, 45, 83, 65, 74, - 68, 65, 128, 65, 82, 85, 72, 85, 65, 128, 65, 82, 84, 211, 65, 82, 84, - 73, 83, 212, 65, 82, 84, 73, 67, 85, 76, 65, 84, 69, 196, 65, 82, 84, 65, - 66, 197, 65, 82, 84, 65, 128, 65, 82, 83, 69, 79, 83, 128, 65, 82, 83, - 69, 79, 211, 65, 82, 83, 69, 78, 73, 67, 128, 65, 82, 82, 79, 87, 83, - 128, 65, 82, 82, 79, 87, 211, 65, 82, 82, 79, 87, 72, 69, 65, 68, 83, - 128, 65, 82, 82, 79, 87, 72, 69, 65, 68, 45, 83, 72, 65, 80, 69, 196, 65, - 82, 82, 79, 87, 72, 69, 65, 68, 128, 65, 82, 82, 79, 87, 72, 69, 65, 196, - 65, 82, 82, 79, 87, 45, 84, 65, 73, 76, 128, 65, 82, 82, 73, 86, 73, 78, - 71, 128, 65, 82, 82, 73, 86, 69, 128, 65, 82, 82, 65, 89, 128, 65, 82, - 80, 69, 71, 71, 73, 65, 84, 207, 65, 82, 79, 85, 83, 73, 78, 199, 65, 82, - 79, 85, 82, 193, 65, 82, 79, 85, 78, 68, 45, 80, 82, 79, 70, 73, 76, 69, - 128, 65, 82, 79, 85, 78, 196, 65, 82, 77, 89, 128, 65, 82, 77, 211, 65, - 82, 77, 79, 85, 82, 128, 65, 82, 77, 69, 78, 73, 65, 206, 65, 82, 77, - 128, 65, 82, 205, 65, 82, 76, 65, 85, 199, 65, 82, 75, 84, 73, 75, 207, - 65, 82, 75, 65, 66, 128, 65, 82, 75, 65, 65, 78, 85, 128, 65, 82, 73, 83, - 84, 69, 82, 65, 128, 65, 82, 73, 83, 84, 69, 82, 193, 65, 82, 73, 69, 83, - 128, 65, 82, 71, 79, 84, 69, 82, 73, 128, 65, 82, 71, 79, 83, 89, 78, 84, - 72, 69, 84, 79, 78, 128, 65, 82, 71, 73, 128, 65, 82, 69, 80, 65, 128, - 65, 82, 69, 65, 128, 65, 82, 68, 72, 65, 86, 73, 83, 65, 82, 71, 65, 128, - 65, 82, 68, 72, 65, 67, 65, 78, 68, 82, 65, 128, 65, 82, 67, 72, 65, 73, - 79, 78, 128, 65, 82, 67, 72, 65, 73, 79, 206, 65, 82, 67, 72, 65, 73, - 195, 65, 82, 67, 200, 65, 82, 67, 128, 65, 82, 195, 65, 82, 65, 77, 65, - 73, 195, 65, 82, 65, 69, 65, 69, 128, 65, 82, 65, 69, 65, 45, 85, 128, - 65, 82, 65, 69, 65, 45, 73, 128, 65, 82, 65, 69, 65, 45, 69, 79, 128, 65, - 82, 65, 69, 65, 45, 69, 128, 65, 82, 65, 69, 65, 45, 65, 128, 65, 82, 65, - 68, 128, 65, 82, 65, 196, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, - 195, 65, 82, 65, 66, 73, 65, 206, 65, 82, 45, 82, 85, 66, 128, 65, 82, - 45, 82, 65, 72, 77, 65, 206, 65, 82, 45, 82, 65, 72, 69, 69, 77, 128, 65, - 81, 85, 65, 82, 73, 85, 83, 128, 65, 81, 85, 65, 70, 79, 82, 84, 73, 83, - 128, 65, 81, 85, 193, 65, 80, 85, 206, 65, 80, 82, 73, 76, 128, 65, 80, - 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 217, 65, 80, 80, 82, 79, 88, 73, - 77, 65, 84, 69, 128, 65, 80, 80, 82, 79, 65, 67, 72, 69, 211, 65, 80, 80, - 82, 79, 65, 67, 72, 128, 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, - 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 206, 65, 80, 79, 84, 72, 69, 83, - 128, 65, 80, 79, 84, 72, 69, 77, 65, 128, 65, 80, 79, 83, 84, 82, 79, 80, - 72, 69, 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 83, 128, 65, 80, 79, 83, - 84, 82, 79, 70, 79, 211, 65, 80, 79, 83, 84, 82, 79, 70, 79, 201, 65, 80, - 79, 76, 76, 79, 78, 128, 65, 80, 79, 68, 69, 88, 73, 65, 128, 65, 80, 79, - 68, 69, 82, 77, 193, 65, 80, 76, 79, 85, 78, 128, 65, 80, 76, 201, 65, - 80, 204, 65, 80, 73, 78, 128, 65, 80, 69, 83, 207, 65, 80, 67, 128, 65, - 80, 65, 82, 84, 128, 65, 80, 65, 65, 84, 79, 128, 65, 79, 85, 128, 65, - 79, 82, 128, 65, 78, 89, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, - 128, 65, 78, 85, 83, 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, - 193, 65, 78, 85, 68, 65, 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, - 193, 65, 78, 84, 73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, - 78, 84, 73, 77, 79, 78, 89, 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, - 128, 65, 78, 84, 73, 77, 79, 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, - 84, 69, 128, 65, 78, 84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, - 75, 69, 78, 79, 75, 89, 76, 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, - 78, 73, 65, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, - 82, 79, 84, 65, 84, 69, 196, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, - 83, 69, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 197, 65, 78, - 84, 69, 78, 78, 65, 128, 65, 78, 84, 69, 78, 78, 193, 65, 78, 84, 65, 82, - 71, 79, 77, 85, 75, 72, 65, 128, 65, 78, 83, 85, 218, 65, 78, 83, 72, 69, - 128, 65, 78, 80, 69, 65, 128, 65, 78, 207, 65, 78, 78, 85, 73, 84, 217, - 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 65, 78, 78, 65, 65, 85, 128, 65, - 78, 75, 72, 128, 65, 78, 74, 73, 128, 65, 78, 73, 77, 65, 76, 128, 65, - 78, 72, 85, 78, 78, 65, 128, 65, 78, 72, 85, 77, 65, 65, 128, 65, 78, 72, - 85, 77, 128, 65, 78, 72, 85, 128, 65, 78, 72, 65, 65, 128, 65, 78, 72, - 128, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, 72, 69, - 196, 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 82, 217, 65, 78, 71, - 76, 73, 67, 65, 78, 193, 65, 78, 71, 76, 69, 68, 128, 65, 78, 71, 76, 69, - 196, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 71, 75, 65, - 128, 65, 78, 71, 69, 210, 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, 68, - 128, 65, 78, 68, 65, 80, 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, 67, - 72, 79, 82, 128, 65, 78, 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, - 78, 65, 84, 79, 77, 73, 67, 65, 204, 65, 78, 65, 80, 128, 65, 78, 45, 78, - 73, 83, 70, 128, 65, 77, 85, 76, 69, 84, 128, 65, 77, 80, 83, 128, 65, - 77, 80, 72, 79, 82, 65, 128, 65, 77, 80, 69, 82, 83, 65, 78, 68, 128, 65, - 77, 80, 69, 82, 83, 65, 78, 196, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, - 73, 67, 65, 83, 128, 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, - 65, 78, 67, 69, 128, 65, 77, 66, 193, 65, 77, 66, 128, 65, 77, 65, 82, - 128, 65, 77, 65, 210, 65, 77, 65, 76, 71, 65, 77, 65, 84, 73, 79, 206, - 65, 77, 65, 76, 71, 65, 77, 128, 65, 76, 86, 69, 79, 76, 65, 210, 65, 76, - 85, 77, 128, 65, 76, 84, 69, 82, 78, 65, 84, 73, 86, 197, 65, 76, 84, 69, - 82, 78, 65, 84, 73, 79, 206, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, - 128, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 199, 65, 76, 84, 69, 82, 78, - 65, 84, 69, 128, 65, 76, 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, - 128, 65, 76, 80, 72, 65, 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, - 82, 65, 78, 65, 128, 65, 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, - 65, 128, 65, 76, 77, 79, 83, 212, 65, 76, 76, 79, 128, 65, 76, 76, 73, - 65, 78, 67, 69, 128, 65, 76, 76, 201, 65, 76, 76, 65, 200, 65, 76, 76, - 65, 65, 72, 128, 65, 76, 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, 76, - 73, 128, 65, 76, 73, 71, 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, 76, - 73, 70, 128, 65, 76, 73, 198, 65, 76, 73, 69, 78, 128, 65, 76, 73, 69, - 206, 65, 76, 71, 73, 218, 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, 65, - 76, 69, 82, 84, 128, 65, 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, 67, - 128, 65, 76, 69, 70, 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, 65, - 89, 78, 65, 65, 128, 65, 76, 65, 89, 72, 73, 77, 65, 193, 65, 76, 65, 89, - 72, 73, 205, 65, 76, 65, 89, 72, 201, 65, 76, 65, 89, 72, 69, 128, 65, - 76, 65, 89, 72, 197, 65, 76, 65, 89, 72, 65, 193, 65, 76, 65, 82, 205, - 65, 76, 65, 80, 72, 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 76, - 45, 74, 85, 90, 128, 65, 75, 85, 82, 213, 65, 75, 84, 73, 69, 83, 69, 76, - 83, 75, 65, 66, 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, 73, 77, 73, - 195, 65, 75, 66, 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, 65, 82, 193, - 65, 73, 89, 65, 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, 203, 65, 73, 86, - 65, 128, 65, 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, - 73, 82, 80, 76, 65, 78, 197, 65, 73, 78, 213, 65, 73, 78, 78, 128, 65, - 73, 76, 77, 128, 65, 73, 75, 65, 82, 65, 128, 65, 73, 72, 86, 85, 83, - 128, 65, 72, 83, 68, 65, 128, 65, 72, 83, 65, 128, 65, 72, 79, 205, 65, - 72, 65, 78, 199, 65, 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, - 71, 85, 78, 71, 128, 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, - 73, 79, 78, 128, 65, 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, - 78, 83, 212, 65, 71, 65, 73, 78, 128, 65, 70, 84, 69, 210, 65, 70, 83, - 65, 65, 81, 128, 65, 70, 82, 73, 67, 65, 206, 65, 70, 79, 82, 69, 77, 69, - 78, 84, 73, 79, 78, 69, 68, 128, 65, 70, 71, 72, 65, 78, 201, 65, 70, 70, - 82, 73, 67, 65, 84, 73, 79, 206, 65, 70, 70, 73, 216, 65, 69, 89, 65, 78, - 78, 65, 128, 65, 69, 89, 128, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, - 128, 65, 69, 83, 67, 128, 65, 69, 83, 128, 65, 69, 82, 73, 65, 204, 65, - 69, 82, 128, 65, 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 76, - 128, 65, 69, 75, 128, 65, 69, 71, 69, 65, 206, 65, 69, 71, 128, 65, 69, - 69, 89, 65, 78, 78, 65, 128, 65, 69, 69, 128, 65, 69, 68, 65, 45, 80, 73, - 76, 76, 65, 128, 65, 69, 68, 128, 65, 69, 66, 128, 65, 68, 86, 65, 78, - 84, 65, 71, 69, 128, 65, 68, 86, 65, 78, 67, 69, 128, 65, 68, 85, 76, 84, - 128, 65, 68, 77, 73, 83, 83, 73, 79, 206, 65, 68, 77, 69, 84, 79, 83, - 128, 65, 68, 76, 65, 205, 65, 68, 72, 69, 83, 73, 86, 197, 65, 68, 69, - 71, 128, 65, 68, 69, 199, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 68, - 68, 82, 69, 83, 211, 65, 68, 68, 65, 75, 128, 65, 68, 65, 203, 65, 67, - 85, 84, 69, 45, 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, 84, 69, 45, 71, - 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, 84, 197, 65, 67, - 84, 85, 65, 76, 76, 217, 65, 67, 84, 73, 86, 65, 84, 197, 65, 67, 82, 79, - 80, 72, 79, 78, 73, 195, 65, 67, 75, 78, 79, 87, 76, 69, 68, 71, 69, 128, - 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78, 128, 65, 67, 67, 79, 85, - 78, 212, 65, 67, 67, 79, 82, 68, 73, 79, 78, 128, 65, 67, 67, 79, 77, 77, - 79, 68, 65, 84, 73, 79, 78, 128, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, - 69, 78, 84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, - 84, 128, 65, 67, 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, - 89, 83, 77, 65, 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, - 72, 65, 83, 73, 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, - 65, 66, 65, 70, 73, 76, 73, 128, 65, 66, 65, 67, 85, 83, 128, 65, 66, - 178, 65, 66, 49, 57, 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, - 48, 128, 65, 66, 49, 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, - 51, 49, 66, 128, 65, 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, - 65, 66, 49, 50, 50, 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, - 128, 65, 66, 48, 56, 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, - 53, 128, 65, 66, 48, 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, - 56, 48, 128, 65, 66, 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, - 48, 55, 55, 128, 65, 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, - 66, 48, 55, 51, 128, 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, - 65, 66, 48, 54, 55, 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, - 128, 65, 66, 48, 54, 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, - 57, 128, 65, 66, 48, 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, - 53, 54, 128, 65, 66, 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, - 48, 53, 51, 128, 65, 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, - 66, 48, 52, 57, 128, 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, - 65, 66, 48, 52, 54, 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, - 128, 65, 66, 48, 52, 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, - 57, 128, 65, 66, 48, 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, - 51, 52, 128, 65, 66, 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, - 48, 50, 57, 128, 65, 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, - 66, 48, 50, 54, 128, 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, - 128, 65, 66, 48, 50, 51, 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, - 50, 50, 70, 128, 65, 66, 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, - 65, 66, 48, 50, 49, 70, 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, - 128, 65, 66, 48, 49, 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, - 51, 128, 65, 66, 48, 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, - 48, 57, 128, 65, 66, 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, - 48, 48, 54, 128, 65, 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, - 66, 48, 48, 51, 128, 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, - 65, 65, 90, 72, 65, 65, 75, 75, 85, 128, 65, 65, 89, 73, 78, 128, 65, 65, - 89, 65, 78, 78, 65, 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, - 128, 65, 65, 74, 128, 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, - 48, 51, 50, 128, 65, 65, 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, - 65, 48, 50, 57, 128, 65, 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, - 65, 65, 48, 50, 54, 128, 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, - 128, 65, 65, 48, 50, 51, 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, - 49, 128, 65, 65, 48, 50, 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, - 49, 56, 128, 65, 65, 48, 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, - 48, 49, 53, 128, 65, 65, 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, - 65, 48, 49, 50, 128, 65, 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, - 65, 65, 48, 48, 57, 128, 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, - 128, 65, 65, 48, 48, 55, 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, - 48, 54, 128, 65, 65, 48, 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, - 48, 48, 51, 128, 65, 65, 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, - 56, 48, 55, 128, 65, 56, 48, 54, 128, 65, 56, 48, 53, 128, 65, 56, 48, - 52, 128, 65, 56, 48, 51, 128, 65, 56, 48, 50, 128, 65, 56, 48, 49, 128, - 65, 56, 48, 48, 128, 65, 55, 51, 178, 65, 55, 50, 182, 65, 55, 49, 183, - 65, 55, 49, 181, 65, 55, 49, 180, 65, 55, 49, 179, 65, 55, 49, 178, 65, - 55, 49, 177, 65, 55, 49, 176, 65, 55, 48, 57, 45, 182, 65, 55, 48, 57, - 45, 180, 65, 55, 48, 57, 45, 179, 65, 55, 48, 57, 45, 178, 65, 55, 48, - 185, 65, 55, 48, 184, 65, 55, 48, 183, 65, 55, 48, 182, 65, 55, 48, 181, - 65, 55, 48, 180, 65, 55, 48, 179, 65, 55, 48, 178, 65, 55, 48, 177, 65, - 54, 54, 52, 128, 65, 54, 54, 51, 128, 65, 54, 54, 50, 128, 65, 54, 54, - 49, 128, 65, 54, 54, 48, 128, 65, 54, 53, 57, 128, 65, 54, 53, 56, 128, - 65, 54, 53, 55, 128, 65, 54, 53, 54, 128, 65, 54, 53, 53, 128, 65, 54, - 53, 52, 128, 65, 54, 53, 51, 128, 65, 54, 53, 50, 128, 65, 54, 53, 49, - 128, 65, 54, 52, 57, 128, 65, 54, 52, 56, 128, 65, 54, 52, 54, 128, 65, - 54, 52, 53, 128, 65, 54, 52, 52, 128, 65, 54, 52, 51, 128, 65, 54, 52, - 50, 128, 65, 54, 52, 48, 128, 65, 54, 51, 56, 128, 65, 54, 51, 55, 128, - 65, 54, 51, 52, 128, 65, 54, 50, 57, 128, 65, 54, 50, 56, 128, 65, 54, - 50, 55, 128, 65, 54, 50, 54, 128, 65, 54, 50, 52, 128, 65, 54, 50, 51, - 128, 65, 54, 50, 50, 128, 65, 54, 50, 49, 128, 65, 54, 50, 48, 128, 65, - 54, 49, 57, 128, 65, 54, 49, 56, 128, 65, 54, 49, 55, 128, 65, 54, 49, - 54, 128, 65, 54, 49, 53, 128, 65, 54, 49, 52, 128, 65, 54, 49, 51, 128, - 65, 54, 49, 50, 128, 65, 54, 49, 49, 128, 65, 54, 49, 48, 128, 65, 54, - 48, 57, 128, 65, 54, 48, 56, 128, 65, 54, 48, 54, 128, 65, 54, 48, 52, - 128, 65, 54, 48, 51, 128, 65, 54, 48, 50, 128, 65, 54, 48, 49, 128, 65, - 54, 48, 48, 128, 65, 53, 57, 56, 128, 65, 53, 57, 54, 128, 65, 53, 57, - 53, 128, 65, 53, 57, 52, 128, 65, 53, 57, 50, 128, 65, 53, 57, 49, 128, - 65, 53, 56, 57, 128, 65, 53, 56, 56, 128, 65, 53, 56, 55, 128, 65, 53, - 56, 54, 128, 65, 53, 56, 53, 128, 65, 53, 56, 52, 128, 65, 53, 56, 51, - 128, 65, 53, 56, 50, 128, 65, 53, 56, 49, 128, 65, 53, 56, 48, 128, 65, - 53, 55, 57, 128, 65, 53, 55, 56, 128, 65, 53, 55, 55, 128, 65, 53, 55, - 54, 128, 65, 53, 55, 53, 128, 65, 53, 55, 52, 128, 65, 53, 55, 51, 128, - 65, 53, 55, 50, 128, 65, 53, 55, 49, 128, 65, 53, 55, 48, 128, 65, 53, - 54, 57, 128, 65, 53, 54, 56, 128, 65, 53, 54, 54, 128, 65, 53, 54, 53, - 128, 65, 53, 54, 52, 128, 65, 53, 54, 51, 128, 65, 53, 53, 57, 128, 65, - 53, 53, 55, 128, 65, 53, 53, 54, 128, 65, 53, 53, 53, 128, 65, 53, 53, - 52, 128, 65, 53, 53, 51, 128, 65, 53, 53, 50, 128, 65, 53, 53, 49, 128, - 65, 53, 53, 48, 128, 65, 53, 52, 57, 128, 65, 53, 52, 56, 128, 65, 53, - 52, 55, 128, 65, 53, 52, 53, 128, 65, 53, 52, 50, 128, 65, 53, 52, 49, - 128, 65, 53, 52, 48, 128, 65, 53, 51, 57, 128, 65, 53, 51, 56, 128, 65, - 53, 51, 55, 128, 65, 53, 51, 54, 128, 65, 53, 51, 53, 128, 65, 53, 51, - 52, 128, 65, 53, 51, 50, 128, 65, 53, 51, 49, 128, 65, 53, 51, 48, 128, - 65, 53, 50, 57, 128, 65, 53, 50, 56, 128, 65, 53, 50, 55, 128, 65, 53, - 50, 54, 128, 65, 53, 50, 53, 128, 65, 53, 50, 52, 128, 65, 53, 50, 51, - 128, 65, 53, 50, 50, 128, 65, 53, 50, 49, 128, 65, 53, 50, 48, 128, 65, - 53, 49, 57, 128, 65, 53, 49, 56, 128, 65, 53, 49, 55, 128, 65, 53, 49, - 54, 128, 65, 53, 49, 53, 128, 65, 53, 49, 52, 128, 65, 53, 49, 51, 128, - 65, 53, 49, 50, 128, 65, 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, - 48, 57, 128, 65, 53, 48, 56, 128, 65, 53, 48, 55, 128, 65, 53, 48, 54, - 128, 65, 53, 48, 53, 128, 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, - 53, 48, 50, 128, 65, 53, 48, 49, 128, 65, 52, 57, 55, 128, 65, 52, 57, - 54, 128, 65, 52, 57, 53, 128, 65, 52, 57, 52, 128, 65, 52, 57, 51, 128, - 65, 52, 57, 50, 128, 65, 52, 57, 49, 128, 65, 52, 57, 48, 128, 65, 52, - 56, 57, 128, 65, 52, 56, 56, 128, 65, 52, 56, 55, 128, 65, 52, 56, 54, - 128, 65, 52, 56, 53, 128, 65, 52, 56, 52, 128, 65, 52, 56, 51, 128, 65, - 52, 56, 50, 128, 65, 52, 56, 49, 128, 65, 52, 56, 48, 128, 65, 52, 55, - 57, 128, 65, 52, 55, 56, 128, 65, 52, 55, 55, 128, 65, 52, 55, 54, 128, - 65, 52, 55, 53, 128, 65, 52, 55, 52, 128, 65, 52, 55, 51, 128, 65, 52, - 55, 50, 128, 65, 52, 55, 49, 128, 65, 52, 55, 48, 128, 65, 52, 54, 57, - 128, 65, 52, 54, 56, 128, 65, 52, 54, 55, 128, 65, 52, 54, 54, 128, 65, - 52, 54, 53, 128, 65, 52, 54, 52, 128, 65, 52, 54, 51, 128, 65, 52, 54, - 50, 128, 65, 52, 54, 49, 128, 65, 52, 54, 48, 128, 65, 52, 53, 57, 128, - 65, 52, 53, 56, 128, 65, 52, 53, 55, 65, 128, 65, 52, 53, 55, 128, 65, - 52, 53, 54, 128, 65, 52, 53, 53, 128, 65, 52, 53, 52, 128, 65, 52, 53, - 51, 128, 65, 52, 53, 50, 128, 65, 52, 53, 49, 128, 65, 52, 53, 48, 65, - 128, 65, 52, 53, 48, 128, 65, 52, 52, 57, 128, 65, 52, 52, 56, 128, 65, - 52, 52, 55, 128, 65, 52, 52, 54, 128, 65, 52, 52, 53, 128, 65, 52, 52, - 52, 128, 65, 52, 52, 51, 128, 65, 52, 52, 50, 128, 65, 52, 52, 49, 128, - 65, 52, 52, 48, 128, 65, 52, 51, 57, 128, 65, 52, 51, 56, 128, 65, 52, - 51, 55, 128, 65, 52, 51, 54, 128, 65, 52, 51, 53, 128, 65, 52, 51, 52, - 128, 65, 52, 51, 51, 128, 65, 52, 51, 50, 128, 65, 52, 51, 49, 128, 65, - 52, 51, 48, 128, 65, 52, 50, 57, 128, 65, 52, 50, 56, 128, 65, 52, 50, - 55, 128, 65, 52, 50, 54, 128, 65, 52, 50, 53, 128, 65, 52, 50, 52, 128, - 65, 52, 50, 51, 128, 65, 52, 50, 50, 128, 65, 52, 50, 49, 128, 65, 52, - 50, 48, 128, 65, 52, 49, 57, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, - 65, 52, 49, 56, 128, 65, 52, 49, 55, 45, 86, 65, 83, 128, 65, 52, 49, 55, - 128, 65, 52, 49, 54, 45, 86, 65, 83, 128, 65, 52, 49, 54, 128, 65, 52, - 49, 53, 45, 86, 65, 83, 128, 65, 52, 49, 53, 128, 65, 52, 49, 52, 45, 86, - 65, 83, 128, 65, 52, 49, 52, 128, 65, 52, 49, 51, 45, 86, 65, 83, 128, - 65, 52, 49, 51, 128, 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 50, - 128, 65, 52, 49, 49, 45, 86, 65, 83, 128, 65, 52, 49, 49, 128, 65, 52, - 49, 48, 193, 65, 52, 49, 48, 45, 86, 65, 83, 128, 65, 52, 49, 176, 65, - 52, 48, 57, 45, 86, 65, 83, 128, 65, 52, 48, 57, 128, 65, 52, 48, 56, 45, - 86, 65, 83, 128, 65, 52, 48, 56, 128, 65, 52, 48, 55, 45, 86, 65, 83, - 128, 65, 52, 48, 55, 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, - 48, 54, 128, 65, 52, 48, 53, 45, 86, 65, 83, 128, 65, 52, 48, 53, 128, - 65, 52, 48, 52, 45, 86, 65, 83, 128, 65, 52, 48, 52, 128, 65, 52, 48, 51, - 45, 86, 65, 83, 128, 65, 52, 48, 51, 128, 65, 52, 48, 50, 45, 86, 65, 83, - 128, 65, 52, 48, 50, 128, 65, 52, 48, 49, 45, 86, 65, 83, 128, 65, 52, - 48, 49, 128, 65, 52, 48, 48, 45, 86, 65, 83, 128, 65, 52, 48, 48, 128, - 65, 51, 57, 57, 128, 65, 51, 57, 56, 128, 65, 51, 57, 55, 128, 65, 51, - 57, 54, 128, 65, 51, 57, 53, 128, 65, 51, 57, 52, 128, 65, 51, 57, 179, - 65, 51, 57, 50, 128, 65, 51, 57, 49, 128, 65, 51, 57, 48, 128, 65, 51, - 56, 57, 128, 65, 51, 56, 56, 128, 65, 51, 56, 55, 128, 65, 51, 56, 54, - 65, 128, 65, 51, 56, 54, 128, 65, 51, 56, 53, 128, 65, 51, 56, 52, 128, - 65, 51, 56, 51, 65, 128, 65, 51, 56, 179, 65, 51, 56, 50, 128, 65, 51, - 56, 49, 65, 128, 65, 51, 56, 49, 128, 65, 51, 56, 48, 128, 65, 51, 55, - 57, 128, 65, 51, 55, 56, 128, 65, 51, 55, 55, 128, 65, 51, 55, 54, 128, - 65, 51, 55, 53, 128, 65, 51, 55, 52, 128, 65, 51, 55, 51, 128, 65, 51, - 55, 50, 128, 65, 51, 55, 49, 65, 128, 65, 51, 55, 49, 128, 65, 51, 55, - 48, 128, 65, 51, 54, 57, 128, 65, 51, 54, 56, 65, 128, 65, 51, 54, 56, - 128, 65, 51, 54, 55, 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, - 51, 54, 52, 65, 128, 65, 51, 54, 52, 128, 65, 51, 54, 51, 128, 65, 51, - 54, 50, 128, 65, 51, 54, 49, 128, 65, 51, 54, 48, 128, 65, 51, 53, 57, - 65, 128, 65, 51, 53, 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, 55, 128, - 65, 51, 53, 54, 128, 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, 65, 51, - 53, 51, 128, 65, 51, 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, 53, 48, - 128, 65, 51, 52, 57, 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, 128, 65, - 51, 52, 54, 128, 65, 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, 51, 52, - 51, 128, 65, 51, 52, 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, 48, 128, - 65, 51, 51, 57, 128, 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, 65, 51, - 51, 54, 67, 128, 65, 51, 51, 54, 66, 128, 65, 51, 51, 54, 65, 128, 65, - 51, 51, 54, 128, 65, 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, 51, - 51, 128, 65, 51, 51, 50, 67, 128, 65, 51, 51, 50, 66, 128, 65, 51, 51, - 50, 65, 128, 65, 51, 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, - 128, 65, 51, 50, 57, 65, 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, - 65, 51, 50, 55, 128, 65, 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, - 50, 52, 128, 65, 51, 50, 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, - 128, 65, 51, 50, 48, 128, 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, - 51, 49, 55, 128, 65, 51, 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, - 52, 128, 65, 51, 49, 51, 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, - 51, 65, 128, 65, 51, 49, 51, 128, 65, 51, 49, 50, 128, 65, 51, 49, 49, - 128, 65, 51, 49, 48, 128, 65, 51, 48, 57, 67, 128, 65, 51, 48, 57, 66, - 128, 65, 51, 48, 57, 65, 128, 65, 51, 48, 57, 128, 65, 51, 48, 56, 128, - 65, 51, 48, 55, 128, 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, 51, - 48, 52, 128, 65, 51, 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, 49, - 128, 65, 51, 48, 48, 128, 65, 50, 57, 57, 65, 128, 65, 50, 57, 57, 128, - 65, 50, 57, 56, 128, 65, 50, 57, 55, 128, 65, 50, 57, 54, 128, 65, 50, - 57, 53, 128, 65, 50, 57, 52, 65, 128, 65, 50, 57, 52, 128, 65, 50, 57, - 51, 128, 65, 50, 57, 50, 128, 65, 50, 57, 49, 128, 65, 50, 57, 48, 128, - 65, 50, 56, 57, 65, 128, 65, 50, 56, 57, 128, 65, 50, 56, 56, 128, 65, - 50, 56, 55, 128, 65, 50, 56, 54, 128, 65, 50, 56, 53, 128, 65, 50, 56, - 52, 128, 65, 50, 56, 51, 128, 65, 50, 56, 50, 128, 65, 50, 56, 49, 128, - 65, 50, 56, 48, 128, 65, 50, 55, 57, 128, 65, 50, 55, 56, 128, 65, 50, - 55, 55, 128, 65, 50, 55, 54, 128, 65, 50, 55, 53, 128, 65, 50, 55, 52, - 128, 65, 50, 55, 51, 128, 65, 50, 55, 50, 128, 65, 50, 55, 49, 128, 65, - 50, 55, 48, 128, 65, 50, 54, 57, 128, 65, 50, 54, 56, 128, 65, 50, 54, - 55, 65, 128, 65, 50, 54, 55, 128, 65, 50, 54, 54, 128, 65, 50, 54, 53, - 128, 65, 50, 54, 52, 128, 65, 50, 54, 51, 128, 65, 50, 54, 50, 128, 65, - 50, 54, 49, 128, 65, 50, 54, 48, 128, 65, 50, 53, 57, 128, 65, 50, 53, - 56, 128, 65, 50, 53, 55, 128, 65, 50, 53, 54, 128, 65, 50, 53, 53, 128, - 65, 50, 53, 52, 128, 65, 50, 53, 51, 128, 65, 50, 53, 50, 128, 65, 50, - 53, 49, 128, 65, 50, 53, 48, 128, 65, 50, 52, 57, 128, 65, 50, 52, 56, - 128, 65, 50, 52, 55, 128, 65, 50, 52, 54, 128, 65, 50, 52, 53, 128, 65, - 50, 52, 52, 128, 65, 50, 52, 51, 128, 65, 50, 52, 50, 128, 65, 50, 52, - 49, 128, 65, 50, 52, 48, 128, 65, 50, 51, 57, 128, 65, 50, 51, 56, 128, - 65, 50, 51, 55, 128, 65, 50, 51, 54, 128, 65, 50, 51, 53, 128, 65, 50, - 51, 52, 128, 65, 50, 51, 51, 128, 65, 50, 51, 50, 128, 65, 50, 51, 49, - 128, 65, 50, 51, 48, 128, 65, 50, 50, 57, 128, 65, 50, 50, 56, 128, 65, - 50, 50, 55, 65, 128, 65, 50, 50, 55, 128, 65, 50, 50, 54, 128, 65, 50, - 50, 53, 128, 65, 50, 50, 52, 128, 65, 50, 50, 51, 128, 65, 50, 50, 50, - 128, 65, 50, 50, 49, 128, 65, 50, 50, 48, 128, 65, 50, 49, 57, 128, 65, - 50, 49, 56, 128, 65, 50, 49, 55, 128, 65, 50, 49, 54, 65, 128, 65, 50, - 49, 54, 128, 65, 50, 49, 53, 65, 128, 65, 50, 49, 53, 128, 65, 50, 49, - 52, 128, 65, 50, 49, 51, 128, 65, 50, 49, 50, 128, 65, 50, 49, 49, 128, - 65, 50, 49, 48, 128, 65, 50, 48, 57, 65, 128, 65, 50, 48, 57, 128, 65, - 50, 48, 56, 128, 65, 50, 48, 55, 65, 128, 65, 50, 48, 55, 128, 65, 50, - 48, 54, 128, 65, 50, 48, 53, 128, 65, 50, 48, 52, 128, 65, 50, 48, 51, - 128, 65, 50, 48, 50, 66, 128, 65, 50, 48, 50, 65, 128, 65, 50, 48, 50, - 128, 65, 50, 48, 49, 128, 65, 50, 48, 48, 128, 65, 49, 57, 57, 128, 65, - 49, 57, 56, 128, 65, 49, 57, 55, 128, 65, 49, 57, 54, 128, 65, 49, 57, - 53, 128, 65, 49, 57, 52, 128, 65, 49, 57, 51, 128, 65, 49, 57, 50, 128, - 65, 49, 57, 49, 128, 65, 49, 57, 48, 128, 65, 49, 56, 57, 128, 65, 49, - 56, 56, 128, 65, 49, 56, 55, 128, 65, 49, 56, 54, 128, 65, 49, 56, 53, - 128, 65, 49, 56, 52, 128, 65, 49, 56, 51, 128, 65, 49, 56, 50, 128, 65, - 49, 56, 49, 128, 65, 49, 56, 48, 128, 65, 49, 55, 57, 128, 65, 49, 55, - 56, 128, 65, 49, 55, 55, 128, 65, 49, 55, 54, 128, 65, 49, 55, 53, 128, - 65, 49, 55, 52, 128, 65, 49, 55, 51, 128, 65, 49, 55, 50, 128, 65, 49, - 55, 49, 128, 65, 49, 55, 48, 128, 65, 49, 54, 57, 128, 65, 49, 54, 56, - 128, 65, 49, 54, 55, 128, 65, 49, 54, 54, 128, 65, 49, 54, 53, 128, 65, - 49, 54, 52, 128, 65, 49, 54, 51, 128, 65, 49, 54, 50, 128, 65, 49, 54, - 49, 128, 65, 49, 54, 48, 128, 65, 49, 53, 57, 128, 65, 49, 53, 56, 128, - 65, 49, 53, 55, 128, 65, 49, 53, 54, 128, 65, 49, 53, 53, 128, 65, 49, - 53, 52, 128, 65, 49, 53, 51, 128, 65, 49, 53, 50, 128, 65, 49, 53, 49, - 128, 65, 49, 53, 48, 128, 65, 49, 52, 57, 128, 65, 49, 52, 56, 128, 65, - 49, 52, 55, 128, 65, 49, 52, 54, 128, 65, 49, 52, 53, 128, 65, 49, 52, - 52, 128, 65, 49, 52, 51, 128, 65, 49, 52, 50, 128, 65, 49, 52, 49, 128, - 65, 49, 52, 48, 128, 65, 49, 51, 57, 128, 65, 49, 51, 56, 128, 65, 49, - 51, 55, 128, 65, 49, 51, 54, 128, 65, 49, 51, 53, 65, 128, 65, 49, 51, - 53, 128, 65, 49, 51, 52, 128, 65, 49, 51, 51, 128, 65, 49, 51, 50, 128, - 65, 49, 51, 49, 67, 128, 65, 49, 51, 49, 128, 65, 49, 51, 48, 128, 65, - 49, 50, 57, 128, 65, 49, 50, 56, 128, 65, 49, 50, 55, 128, 65, 49, 50, - 54, 128, 65, 49, 50, 53, 65, 128, 65, 49, 50, 53, 128, 65, 49, 50, 52, - 128, 65, 49, 50, 51, 128, 65, 49, 50, 50, 128, 65, 49, 50, 49, 128, 65, - 49, 50, 48, 66, 128, 65, 49, 50, 48, 128, 65, 49, 49, 57, 128, 65, 49, - 49, 56, 128, 65, 49, 49, 55, 128, 65, 49, 49, 54, 128, 65, 49, 49, 53, - 65, 128, 65, 49, 49, 53, 128, 65, 49, 49, 52, 128, 65, 49, 49, 51, 128, - 65, 49, 49, 50, 128, 65, 49, 49, 49, 128, 65, 49, 49, 48, 66, 128, 65, - 49, 49, 48, 65, 128, 65, 49, 49, 48, 128, 65, 49, 48, 57, 128, 65, 49, - 48, 56, 128, 65, 49, 48, 55, 67, 128, 65, 49, 48, 55, 66, 128, 65, 49, - 48, 55, 65, 128, 65, 49, 48, 55, 128, 65, 49, 48, 54, 128, 65, 49, 48, - 53, 66, 128, 65, 49, 48, 53, 65, 128, 65, 49, 48, 53, 128, 65, 49, 48, - 52, 67, 128, 65, 49, 48, 52, 66, 128, 65, 49, 48, 52, 65, 128, 65, 49, - 48, 52, 128, 65, 49, 48, 51, 128, 65, 49, 48, 50, 65, 128, 65, 49, 48, - 50, 128, 65, 49, 48, 49, 65, 128, 65, 49, 48, 49, 128, 65, 49, 48, 48, - 65, 128, 65, 49, 48, 48, 45, 49, 48, 50, 128, 65, 49, 48, 48, 128, 65, - 48, 57, 57, 128, 65, 48, 57, 56, 65, 128, 65, 48, 57, 56, 128, 65, 48, - 57, 55, 65, 128, 65, 48, 57, 55, 128, 65, 48, 57, 54, 128, 65, 48, 57, - 53, 128, 65, 48, 57, 52, 128, 65, 48, 57, 51, 128, 65, 48, 57, 50, 128, - 65, 48, 57, 49, 128, 65, 48, 57, 48, 128, 65, 48, 56, 57, 128, 65, 48, - 56, 56, 128, 65, 48, 56, 55, 128, 65, 48, 56, 54, 128, 65, 48, 56, 53, - 128, 65, 48, 56, 52, 128, 65, 48, 56, 51, 128, 65, 48, 56, 50, 128, 65, - 48, 56, 49, 128, 65, 48, 56, 48, 128, 65, 48, 55, 57, 128, 65, 48, 55, - 56, 128, 65, 48, 55, 55, 128, 65, 48, 55, 54, 128, 65, 48, 55, 53, 128, - 65, 48, 55, 52, 128, 65, 48, 55, 51, 128, 65, 48, 55, 50, 128, 65, 48, - 55, 49, 128, 65, 48, 55, 48, 128, 65, 48, 54, 57, 128, 65, 48, 54, 56, - 128, 65, 48, 54, 55, 128, 65, 48, 54, 54, 67, 128, 65, 48, 54, 54, 66, - 128, 65, 48, 54, 54, 65, 128, 65, 48, 54, 54, 128, 65, 48, 54, 53, 128, - 65, 48, 54, 52, 128, 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, 65, 48, - 54, 49, 128, 65, 48, 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, 53, 56, - 128, 65, 48, 53, 55, 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, 128, 65, - 48, 53, 52, 128, 65, 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, 48, 53, - 49, 128, 65, 48, 53, 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, 56, 128, - 65, 48, 52, 55, 128, 65, 48, 52, 54, 66, 128, 65, 48, 52, 54, 65, 128, - 65, 48, 52, 54, 128, 65, 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, - 48, 52, 52, 128, 65, 48, 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, - 52, 50, 65, 128, 65, 48, 52, 50, 128, 65, 48, 52, 49, 65, 128, 65, 48, - 52, 49, 128, 65, 48, 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, 51, - 57, 65, 128, 65, 48, 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, - 128, 65, 48, 51, 54, 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, - 48, 51, 51, 128, 65, 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, - 48, 50, 54, 65, 128, 65, 48, 49, 55, 65, 128, 65, 48, 49, 52, 65, 128, - 65, 48, 49, 48, 65, 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, - 128, 65, 48, 48, 53, 65, 128, 65, 45, 87, 79, 128, 65, 45, 69, 85, 128, - 45, 85, 205, 45, 80, 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, - 72, 89, 73, 76, 128, 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, - 72, 65, 76, 128, -}; - -static const unsigned int lexicon_offset[] = { - 0, 0, 6, 11, 15, 19, 27, 34, 44, 49, 55, 64, 66, 69, 81, 89, 102, 108, - 113, 118, 124, 129, 137, 146, 149, 160, 165, 170, 176, 180, 189, 195, - 201, 207, 216, 224, 229, 237, 244, 177, 252, 255, 261, 262, 268, 273, - 277, 282, 289, 296, 306, 311, 317, 325, 330, 333, 339, 344, 350, 356, - 359, 365, 375, 380, 385, 390, 392, 394, 403, 405, 412, 354, 419, 427, - 436, 438, 441, 449, 454, 455, 457, 464, 472, 478, 484, 491, 496, 503, - 507, 512, 519, 524, 527, 531, 536, 542, 547, 557, 565, 572, 575, 585, - 593, 598, 606, 615, 618, 625, 629, 633, 637, 642, 645, 652, 659, 666, - 671, 676, 683, 692, 694, 703, 707, 715, 719, 727, 281, 736, 749, 753, - 758, 761, 765, 769, 771, 776, 786, 792, 796, 802, 806, 809, 814, 823, - 828, 832, 774, 838, 846, 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, 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, - 1221, 1226, 1231, 1236, 1071, 1076, 1081, 1087, 1092, 1240, 1102, 1246, - 1251, 1256, 1263, 1267, 1270, 1279, 1106, 1283, 1111, 1117, 1122, 1287, - 1292, 1297, 1301, 1305, 1311, 1315, 1127, 1318, 1320, 1137, 1325, 1329, - 1142, 1335, 1147, 1339, 1343, 1350, 1152, 1354, 1362, 1367, 1371, 1374, - 1378, 1156, 1161, 1383, 1389, 1166, 1401, 1407, 1413, 1419, 1171, 1183, - 1189, 1423, 1427, 1431, 1434, 1194, 1438, 1440, 1445, 1450, 1456, 1461, - 1466, 1470, 1475, 1480, 1485, 1490, 1496, 1501, 1506, 1512, 1518, 1523, - 1527, 1532, 1537, 1542, 1547, 1552, 1556, 1564, 1569, 1573, 1578, 1583, - 1588, 1593, 1597, 1600, 1607, 1612, 1617, 1622, 1627, 1633, 1638, 1642, - 1198, 1645, 1651, 1656, 1661, 1666, 1203, 1670, 1674, 1681, 1688, 1208, - 1693, 1698, 1213, 1702, 1704, 1709, 1720, 1726, 1217, 1731, 1740, 1222, - 1745, 1751, 1756, 1761, 1771, 1780, 1788, 1227, 1798, 1807, 1816, 1821, - 1825, 1828, 1837, 1847, 1856, 1861, 1865, 1869, 1873, 1876, 1880, 1885, - 1232, 1895, 1237, 1899, 1901, 1907, 1913, 1919, 1925, 1931, 1937, 1943, - 1949, 1954, 1960, 1966, 1972, 1978, 1984, 1990, 1996, 2002, 2008, 2013, - 2018, 2023, 2028, 2033, 2038, 2043, 2048, 2053, 2058, 2064, 2069, 2075, - 2080, 2086, 2092, 2097, 2103, 2109, 2115, 2121, 2126, 2131, 2133, 2134, - 2138, 2142, 2147, 2151, 2155, 2159, 2164, 2168, 2171, 2176, 2180, 2185, - 2189, 2193, 2198, 2202, 2205, 2209, 2215, 2229, 2233, 2237, 2241, 2244, - 2249, 2253, 2257, 2260, 2264, 2269, 2274, 2279, 2284, 2288, 2292, 2296, - 2300, 2304, 2309, 2313, 2318, 2322, 2327, 2333, 2340, 2346, 2351, 2356, - 2361, 2367, 2372, 2378, 2383, 2388, 2393, 2398, 2403, 2406, 2408, 1088, - 2412, 2419, 2427, 2437, 2446, 2460, 2464, 2468, 2473, 2486, 2494, 2497, - 2501, 2504, 2509, 2513, 2516, 2520, 2524, 2529, 1715, 2534, 2538, 2541, - 2545, 2551, 2558, 2565, 2571, 2576, 2581, 2587, 2593, 2598, 2603, 2608, - 2613, 2618, 2623, 2548, 2628, 1706, 2630, 2636, 2640, 2645, 2649, 2653, - 1603, 1728, 2658, 2662, 2666, 2669, 2674, 2679, 2684, 2689, 2693, 2700, - 2705, 2708, 2712, 2716, 2723, 2729, 2733, 2739, 2743, 2747, 2752, 2759, - 2764, 2769, 2776, 2782, 2788, 2794, 2815, 2829, 2846, 2861, 2877, 2894, - 2909, 2918, 2923, 2927, 2932, 2937, 2941, 2953, 2960, 2966, 2336, 2972, - 2979, 2985, 2989, 2992, 2999, 3005, 3010, 3014, 3019, 3023, 3027, 2156, - 3031, 3036, 3041, 3045, 3050, 3058, 3062, 3069, 3074, 3078, 3082, 3086, - 3091, 3096, 3101, 3105, 3110, 3115, 3119, 3124, 3129, 3133, 3136, 3140, - 3144, 3152, 3157, 3161, 3165, 3171, 3180, 3184, 3188, 3194, 3199, 3206, - 3210, 3220, 3224, 3228, 3233, 3237, 3242, 3248, 3253, 3257, 3261, 3265, - 2561, 3273, 3278, 3284, 3289, 3293, 3298, 3303, 3307, 3313, 3318, 2160, - 3324, 3330, 3335, 3340, 3345, 3350, 3355, 3360, 3365, 3370, 3375, 3380, - 3385, 3390, 3395, 3400, 3406, 3411, 1103, 101, 3417, 3421, 3425, 3429, - 3434, 3438, 3442, 3448, 3453, 3457, 3461, 3466, 3471, 3475, 3480, 3484, - 3487, 3491, 3496, 3500, 3505, 3509, 3512, 3514, 3518, 3522, 3527, 3531, - 3534, 3547, 3551, 3555, 3559, 3564, 3568, 3572, 3575, 3579, 3583, 3588, - 3592, 3597, 3602, 3607, 3611, 3618, 3623, 3626, 3632, 3635, 3640, 3646, - 3650, 3654, 3657, 3662, 3666, 3671, 3675, 3679, 3682, 3688, 3693, 3698, - 3704, 3709, 3714, 3720, 3726, 3731, 3736, 3741, 3746, 3749, 979, 644, - 3755, 3758, 3763, 3767, 3771, 3775, 3779, 3782, 3786, 3791, 3796, 3800, - 3805, 3809, 3814, 3818, 3822, 3826, 3832, 3838, 3841, 3844, 153, 3850, - 3855, 3864, 3872, 3881, 3891, 3898, 3904, 3911, 3916, 3920, 3924, 3932, - 3939, 3944, 3949, 3956, 3961, 3965, 3975, 3979, 3983, 3988, 3993, 4003, - 2172, 4008, 4012, 4015, 4021, 4026, 4032, 4038, 4043, 4050, 4054, 4058, - 4062, 4067, 4072, 4077, 4082, 4087, 4092, 634, 616, 1264, 4097, 4104, - 4111, 4117, 4126, 4131, 4138, 4145, 4150, 4156, 4162, 4167, 4172, 4176, - 4182, 4189, 4194, 4198, 4202, 2181, 4208, 4216, 4222, 4230, 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, - 4458, 3492, 4463, 4475, 4481, 4489, 4493, 4498, 4505, 4510, 4515, 4520, - 1472, 4525, 4528, 4531, 4535, 4538, 4544, 4548, 4562, 4566, 4569, 4573, - 4579, 4585, 4590, 4594, 4598, 4604, 4615, 4621, 4626, 4632, 4636, 4644, - 4656, 4666, 4672, 4677, 4686, 4694, 4705, 4712, 4718, 4724, 4728, 4734, - 4743, 4752, 4757, 4763, 4767, 4776, 4782, 4787, 4791, 4796, 4800, 4808, - 4814, 4818, 4825, 4830, 4834, 4840, 4846, 4853, 2194, 4862, 4873, 4883, - 4892, 4897, 4902, 4907, 4912, 1280, 4917, 4919, 4924, 4930, 4935, 4940, - 4945, 4950, 4955, 4960, 4966, 4971, 4977, 4982, 4987, 4992, 4998, 5003, - 5008, 5013, 5018, 5024, 5029, 5035, 5040, 5045, 5050, 5055, 5060, 5065, - 5071, 5076, 5081, 348, 389, 5086, 5092, 5095, 5099, 5103, 5110, 5116, - 5121, 5125, 5129, 5132, 5135, 5139, 5143, 5146, 5150, 5154, 5158, 5163, - 5167, 5171, 5177, 5186, 4843, 5191, 5195, 5198, 5203, 5208, 5213, 5218, - 5223, 5228, 5233, 5238, 5243, 5248, 5252, 5257, 5262, 5267, 5272, 5277, - 5282, 5287, 5292, 5297, 5302, 5306, 5311, 5316, 5321, 5326, 5331, 5336, - 5341, 5346, 5351, 5356, 5360, 5365, 5370, 5375, 5380, 5385, 5390, 5395, - 5400, 5405, 5410, 5414, 5419, 5424, 5429, 5434, 5439, 5444, 5449, 5454, - 5459, 5464, 5468, 5473, 5478, 5483, 5488, 5493, 5498, 5503, 5508, 5513, - 5518, 5522, 5527, 5532, 5537, 5542, 5547, 5552, 5557, 5562, 5567, 5572, - 5576, 5581, 5586, 5591, 5596, 5602, 5608, 5614, 5620, 5626, 5632, 5638, - 5643, 5649, 5655, 5661, 5667, 5673, 5679, 5685, 5691, 5697, 5703, 5708, - 5714, 5720, 5726, 5732, 5738, 5744, 5750, 5756, 5762, 5768, 5773, 5779, - 5785, 5791, 5797, 5803, 5809, 5815, 5821, 5827, 5833, 5838, 5844, 5850, - 5856, 5862, 5868, 5874, 5880, 5886, 5892, 5898, 5903, 5909, 5915, 5921, - 5927, 5933, 5939, 5945, 5951, 5957, 5963, 5968, 5972, 5978, 5984, 5990, - 5996, 6002, 6008, 6014, 6020, 6026, 6032, 6037, 6043, 6049, 6055, 6061, - 6067, 6073, 6079, 6085, 6091, 6097, 6102, 6108, 6114, 6120, 6126, 6132, - 6138, 6144, 6150, 6156, 6162, 6167, 6173, 6179, 6185, 6191, 6197, 6203, - 6209, 6215, 6221, 6227, 6232, 6238, 6244, 6250, 6256, 6262, 6268, 6274, - 6280, 6286, 6292, 6297, 6303, 6309, 6315, 6321, 6327, 6333, 6339, 6345, - 6351, 6357, 6362, 6368, 6374, 6380, 6386, 6392, 6398, 6404, 6410, 6416, - 6422, 6427, 6433, 6439, 6445, 6451, 6457, 6463, 6469, 6475, 6481, 6487, - 6492, 6498, 6504, 6510, 6516, 6522, 6528, 6534, 6540, 6546, 6552, 6557, - 6563, 6569, 6575, 6581, 6587, 6593, 6599, 6605, 6611, 6617, 6622, 6626, - 6629, 6637, 6644, 6647, 6651, 6664, 6668, 6672, 6676, 6679, 6683, 6688, - 6692, 6701, 6705, 6711, 6718, 6729, 6737, 6744, 6750, 6754, 6762, 6771, - 6777, 6781, 6793, 6798, 6801, 6806, 6810, 6820, 6828, 6836, 6844, 6850, - 6854, 6864, 6874, 6882, 6889, 6896, 6902, 6908, 6915, 6919, 6926, 6936, - 6946, 6954, 6961, 6966, 6970, 6974, 6982, 6986, 6996, 7001, 7008, 7015, - 7023, 7033, 7038, 7042, 7047, 7051, 7058, 7063, 7077, 7082, 7087, 7094, - 3768, 7103, 7107, 7111, 7116, 7120, 7124, 7127, 7132, 7137, 7146, 7152, - 7158, 7163, 7169, 7173, 7184, 7194, 7209, 7224, 7239, 7254, 7269, 7284, - 7299, 7314, 7329, 7344, 7359, 7374, 7389, 7404, 7419, 7434, 7449, 7464, - 7479, 7494, 7509, 7524, 7539, 7554, 7569, 7584, 7599, 7614, 7629, 7644, - 7659, 7674, 7689, 7704, 7719, 7734, 7749, 7764, 7779, 7794, 7809, 7824, - 7839, 7854, 7869, 7884, 7899, 7914, 7929, 7938, 7947, 7952, 7958, 7968, - 7972, 7976, 7981, 7986, 7991, 7999, 8003, 8006, 8010, 3215, 8013, 8018, - 353, 534, 8024, 8027, 8035, 8039, 8043, 8046, 8050, 8056, 8060, 8068, - 8074, 8079, 8086, 8094, 8101, 8107, 8112, 8119, 8125, 8134, 8142, 8146, - 8151, 8159, 8171, 8182, 8189, 8200, 8204, 8208, 8212, 8215, 8221, 3519, - 8225, 8227, 8233, 8238, 8243, 8248, 8254, 8259, 8264, 8269, 8274, 8280, - 8285, 8290, 8296, 8301, 8307, 8312, 8318, 8323, 8329, 8334, 8339, 8344, - 8349, 8354, 8360, 8365, 8370, 8375, 8381, 8387, 8393, 8399, 8405, 8411, - 8417, 8423, 8429, 8435, 8441, 8447, 8452, 8457, 8462, 8467, 8472, 8477, - 8482, 8487, 8493, 8499, 8504, 8510, 8516, 8522, 8528, 8533, 8538, 8543, - 8548, 8554, 8560, 8565, 8570, 8575, 8580, 8585, 8591, 8596, 8602, 8608, - 8614, 8620, 8626, 8632, 8638, 8644, 8650, 2203, 8045, 8655, 8659, 8667, - 8671, 8674, 8677, 8683, 8690, 1107, 8693, 8697, 8705, 8710, 8715, 8706, - 8720, 2230, 8724, 8730, 8736, 8741, 8746, 8753, 8761, 8766, 8770, 8773, - 8777, 8783, 8789, 8793, 1653, 631, 8796, 8800, 8805, 8811, 8816, 8820, - 8823, 8827, 8833, 8838, 8842, 8849, 8853, 8857, 8861, 773, 8681, 2254, - 8864, 8872, 8879, 8886, 8892, 8899, 8907, 8914, 8925, 8932, 8938, 8950, - 1123, 1288, 1293, 8961, 8965, 1298, 8969, 8973, 8982, 8990, 8994, 9003, - 9009, 9015, 9020, 9024, 9030, 9035, 9043, 9050, 2914, 9057, 9063, 9067, - 9076, 9085, 9094, 9103, 9109, 9114, 9119, 9130, 9139, 9151, 9156, 9164, - 2289, 9168, 9170, 9175, 9179, 9188, 9196, 1302, 168, 3810, 3815, 9202, - 9206, 9215, 9221, 9226, 9229, 9233, 9237, 9242, 9247, 9252, 9257, 9261, - 9270, 9276, 2301, 9280, 2906, 9284, 9292, 9296, 9300, 2305, 9304, 9308, - 9312, 9316, 9320, 2310, 9324, 9329, 9336, 9342, 9349, 9355, 9358, 9254, - 9360, 9368, 9376, 9384, 9387, 9392, 2323, 9397, 8717, 9400, 9402, 9407, - 9412, 9417, 9422, 9427, 9432, 9437, 9442, 9447, 9452, 9458, 9463, 9468, - 9473, 9479, 9484, 9489, 9494, 9499, 9504, 9509, 9515, 9520, 9525, 9530, - 9535, 9540, 9545, 9550, 9555, 9560, 9565, 9570, 9575, 9580, 9585, 9590, - 9595, 9600, 9606, 9612, 9617, 9622, 9627, 9632, 9637, 2334, 2341, 2347, - 9642, 9650, 9656, 9664, 2373, 2379, 9672, 2384, 2389, 2394, 2399, 9676, - 9680, 9685, 9689, 9693, 9697, 9702, 9706, 9711, 9715, 9718, 9721, 9727, - 9734, 9740, 9747, 9753, 9760, 9766, 9773, 9779, 9785, 9794, 9800, 9804, - 9808, 9812, 9816, 9821, 9825, 9830, 9834, 9840, 9844, 9849, 9856, 9867, - 9875, 9885, 9891, 9901, 9910, 9917, 9922, 9926, 9937, 9947, 9960, 9971, - 9984, 9995, 10007, 10019, 10031, 10042, 10055, 10068, 10075, 10081, - 10092, 10102, 10116, 10123, 10129, 10138, 10146, 10150, 10155, 10159, - 10166, 10174, 10181, 10185, 10191, 10195, 10201, 10211, 10215, 10220, - 10225, 10232, 10238, 8894, 10248, 10252, 10259, 10265, 10272, 10279, - 10283, 10286, 10292, 10296, 10301, 10306, 10311, 10315, 10321, 10329, - 10336, 10342, 10346, 10349, 10355, 10365, 10369, 10375, 10380, 10384, - 10389, 10393, 10399, 10405, 10410, 10416, 10421, 10426, 10431, 2226, - 10436, 10438, 10443, 10451, 10460, 10464, 10470, 10475, 10480, 10485, - 10490, 10496, 10501, 10506, 4600, 10511, 10516, 10520, 10526, 10531, - 10537, 10542, 10547, 10553, 10558, 10465, 10564, 10568, 10575, 10581, - 10586, 10590, 7073, 10595, 10604, 10609, 10614, 9332, 9339, 10619, 3088, - 10623, 10628, 10633, 10638, 10476, 10642, 10647, 10652, 10481, 10656, - 10486, 10661, 10668, 10675, 10681, 10688, 10694, 10700, 10705, 10712, - 10717, 10722, 10727, 10733, 10491, 10497, 10739, 10744, 10750, 10755, - 10760, 10768, 1358, 10773, 1048, 10776, 10784, 10800, 10816, 10831, - 10839, 10845, 10851, 10860, 10868, 10876, 10884, 10892, 10900, 10908, - 10916, 10924, 10933, 10942, 10950, 10959, 10968, 10977, 10986, 10995, - 11004, 11013, 11022, 11031, 11040, 11048, 11053, 11057, 11063, 11071, - 11078, 11093, 11110, 11129, 11138, 11146, 11161, 11172, 11180, 11186, - 11196, 11206, 11214, 11220, 11232, 11241, 11249, 11256, 11263, 11270, - 11276, 11281, 11291, 11297, 11305, 11315, 11322, 11332, 11342, 11352, - 11360, 11367, 11376, 11386, 11400, 11415, 11424, 11432, 11437, 11441, - 11451, 11461, 11473, 11482, 11488, 11493, 11503, 11513, 11523, 11528, - 11532, 11542, 11551, 11556, 11572, 11589, 11599, 11604, 11615, 11628, - 11639, 11647, 11660, 11672, 11680, 11685, 11689, 11695, 11700, 11708, - 11716, 11723, 11734, 11739, 11747, 11757, 11763, 11767, 11770, 11776, - 11780, 11786, 11793, 11797, 11805, 11814, 11822, 11829, 11834, 11838, - 11843, 11847, 11851, 11859, 11874, 11890, 11896, 11904, 11913, 11921, - 11927, 11931, 11938, 11949, 11953, 11956, 11967, 11973, 11978, 10507, - 11986, 11992, 11999, 12005, 12010, 12017, 12024, 12031, 12038, 12045, - 12052, 12059, 12066, 12073, 12080, 12087, 12094, 12101, 12108, 12115, - 12120, 11106, 12125, 12131, 12138, 12145, 12150, 12157, 12166, 12170, - 12177, 12189, 12193, 12199, 12204, 12209, 12214, 12219, 12224, 12229, - 12232, 12236, 11457, 12240, 12244, 12250, 12256, 12261, 12267, 12272, - 12277, 12283, 12288, 12293, 10228, 12298, 12302, 12306, 12310, 12315, - 12320, 12325, 12333, 12339, 12344, 12348, 12352, 12359, 12364, 12372, - 12379, 12384, 12388, 12391, 12397, 12404, 12408, 12411, 12416, 12420, - 4639, 12426, 12435, 46, 12443, 12449, 12454, 12459, 12467, 12474, 12479, - 6991, 12485, 12491, 12496, 12500, 12503, 12509, 12517, 12524, 12539, - 12558, 12570, 12583, 12596, 12609, 12623, 12636, 12651, 12658, 10512, - 12664, 12678, 12683, 12689, 12694, 12702, 12707, 9072, 12712, 12715, - 12723, 12730, 12735, 12739, 12745, 12749, 12754, 12759, 12764, 12769, - 12774, 12779, 3093, 11194, 12784, 12788, 12794, 12800, 12805, 12811, - 12816, 10521, 12822, 12828, 12833, 12838, 12846, 12852, 12865, 12873, - 12880, 12886, 10527, 12892, 12900, 12908, 12915, 12928, 12941, 12953, - 12963, 12975, 13003, 13011, 13020, 13027, 13039, 13046, 13056, 13065, - 13073, 13080, 13085, 13091, 10532, 13096, 13102, 13107, 13112, 13117, - 10538, 13122, 13125, 13132, 13138, 13152, 13165, 13176, 9860, 13187, - 13193, 13202, 13210, 13217, 13223, 13234, 13240, 13245, 13253, 4113, - 13259, 13264, 12531, 13270, 13277, 13282, 10543, 13288, 13293, 13300, - 13306, 13312, 13317, 13325, 13333, 13340, 13344, 13356, 13370, 13380, - 13385, 13389, 13400, 13406, 13411, 13416, 10548, 13420, 10554, 13425, - 13428, 13433, 13445, 13452, 13457, 13461, 13469, 13474, 13478, 13483, - 13487, 13494, 13500, 10559, 10466, 13507, 3098, 17, 13514, 13519, 13523, - 13527, 13533, 13541, 13551, 13556, 13561, 13568, 13575, 13579, 13590, - 13600, 13609, 13618, 13630, 13635, 13639, 13647, 13661, 13665, 13668, - 13672, 13680, 13687, 13695, 13699, 13710, 13718, 13722, 13729, 13734, - 13738, 13744, 13749, 13755, 13760, 13765, 13769, 13775, 13780, 13791, - 13795, 13798, 13804, 13811, 13817, 13822, 13828, 13834, 13841, 13852, - 13862, 13872, 13881, 13888, 13897, 13901, 10569, 10576, 10582, 10587, - 13907, 13913, 13919, 13924, 13930, 10591, 13936, 13939, 13946, 13951, - 13957, 13962, 13977, 13993, 14008, 14016, 14021, 14028, 14034, 14038, - 14043, 14048, 14053, 14058, 14063, 14068, 14073, 14078, 14083, 1561, 383, - 14088, 14096, 14103, 14109, 14114, 14119, 10596, 14121, 14125, 14130, - 14134, 14144, 14149, 14153, 14156, 14165, 14169, 14172, 14179, 10605, - 14184, 14187, 14195, 14202, 14210, 14214, 14220, 14228, 14232, 14239, - 14248, 14255, 14251, 14262, 14266, 14272, 14276, 14280, 14284, 14290, - 14296, 14306, 14314, 14321, 14325, 14333, 14338, 14342, 14349, 14354, - 14361, 14365, 14370, 14375, 14379, 14386, 14392, 14400, 14406, 14411, - 14421, 14428, 14433, 14438, 14442, 14446, 14454, 4469, 14462, 14467, - 10610, 14471, 14478, 14482, 14485, 14493, 14500, 14504, 14507, 6846, - 14511, 14516, 14521, 14525, 14536, 14546, 14551, 14557, 14562, 14571, - 14575, 14578, 14586, 14591, 14596, 14603, 14608, 4865, 10615, 14613, - 14617, 14624, 14629, 14634, 14639, 7021, 14644, 14649, 14654, 14659, - 14665, 14670, 14676, 14681, 14686, 14691, 14696, 14701, 14706, 14711, - 14716, 14721, 14726, 14731, 14736, 14741, 14746, 14751, 14756, 14762, - 14767, 14772, 14777, 14782, 14787, 14793, 14798, 14803, 14809, 14814, - 14820, 14825, 14831, 14836, 14841, 14846, 14851, 14857, 14862, 14867, - 14872, 14880, 988, 112, 14886, 14890, 14895, 14900, 14904, 14908, 14912, - 14917, 14921, 14926, 14930, 14933, 14937, 14941, 14947, 14952, 14962, - 14968, 14976, 14982, 14986, 14990, 14997, 15005, 15014, 15025, 15035, - 15042, 15049, 15053, 15062, 15071, 15079, 15086, 15095, 15104, 15113, - 15122, 15132, 15142, 15152, 15162, 15172, 15181, 15191, 15201, 15211, - 15221, 15231, 15241, 15251, 15260, 15270, 15280, 15290, 15300, 15310, - 15320, 15329, 15339, 15349, 15359, 15369, 15379, 15389, 15399, 15409, - 15419, 15428, 15438, 15448, 15458, 15468, 15478, 15488, 15498, 15508, - 15518, 15528, 15537, 15543, 1132, 15547, 15550, 15554, 15559, 15566, - 15572, 15577, 15581, 15586, 15595, 15604, 15612, 15617, 15621, 15625, - 15631, 15636, 15642, 10624, 15647, 15652, 15661, 15666, 10634, 15671, - 11444, 11454, 11464, 15674, 15680, 15688, 10639, 15695, 15699, 15703, - 15709, 15714, 15718, 15728, 15734, 15740, 15745, 15754, 15762, 15769, - 15776, 15781, 15788, 15793, 15797, 15800, 15811, 15821, 15834, 15843, - 15851, 15862, 15874, 15884, 15894, 15899, 15903, 15908, 15913, 15917, - 15923, 15931, 15938, 15949, 15954, 15964, 15973, 15977, 15980, 15987, - 15997, 16006, 16013, 16017, 16024, 16030, 16035, 16040, 16044, 15590, - 16053, 16057, 16063, 16067, 16072, 16076, 16083, 16090, 16094, 16103, - 16111, 16119, 16126, 16134, 16146, 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, - 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, +/* name->code dictionary */ +static const unsigned char packed_name_dawg[] = { + 228, 174, 4, 250, 2, 65, 206, 254, 2, 66, 222, 254, 2, 67, 198, 245, 4, + 68, 222, 134, 1, 69, 250, 151, 1, 70, 206, 52, 71, 186, 154, 1, 72, 242, + 223, 1, 73, 146, 65, 74, 138, 23, 75, 230, 134, 1, 76, 146, 130, 3, 77, + 162, 200, 3, 78, 162, 107, 79, 226, 124, 80, 128, 159, 1, 2, 81, 85, 194, + 7, 82, 182, 169, 1, 83, 166, 175, 4, 84, 170, 203, 2, 85, 222, 90, 86, + 182, 80, 87, 182, 111, 88, 254, 4, 89, 179, 48, 90, 182, 40, 222, 2, 67, + 238, 1, 68, 182, 10, 69, 172, 5, 4, 72, 79, 77, 32, 244, 6, 7, 73, 82, + 80, 76, 65, 78, 69, 82, 76, 210, 32, 77, 198, 1, 78, 142, 26, 80, 142, + 20, 82, 158, 136, 2, 83, 210, 2, 84, 70, 85, 214, 1, 86, 172, 213, 11, 4, + 70, 71, 72, 65, 206, 192, 9, 66, 220, 219, 2, 9, 75, 84, 73, 69, 83, 69, + 76, 83, 75, 164, 187, 2, 2, 81, 85, 199, 135, 10, 88, 18, 132, 1, 2, 67, + 79, 46, 75, 20, 5, 85, 84, 69, 32, 65, 140, 230, 16, 6, 84, 73, 86, 65, + 84, 69, 225, 150, 22, 5, 32, 67, 85, 82, 82, 4, 162, 185, 25, 85, 237, + 182, 13, 2, 82, 68, 5, 147, 175, 33, 78, 4, 178, 207, 34, 67, 167, 207, + 3, 78, 188, 1, 232, 1, 4, 76, 65, 77, 32, 242, 7, 77, 216, 141, 13, 7, + 72, 69, 83, 73, 86, 69, 32, 168, 151, 4, 19, 68, 82, 69, 83, 83, 69, 68, + 32, 84, 79, 32, 84, 72, 69, 32, 83, 85, 66, 74, 234, 178, 13, 85, 161, + 186, 1, 6, 73, 32, 83, 72, 65, 75, 176, 1, 218, 1, 67, 44, 4, 83, 77, 65, + 76, 168, 4, 7, 71, 69, 77, 73, 78, 65, 84, 116, 8, 73, 78, 73, 84, 73, + 65, 76, 32, 38, 78, 178, 209, 2, 72, 220, 244, 22, 4, 65, 76, 73, 70, 0, + 5, 86, 79, 87, 69, 76, 131, 130, 12, 68, 70, 40, 5, 65, 80, 73, 84, 65, + 215, 4, 79, 68, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 68, 142, 2, + 68, 38, 71, 34, 74, 2, 77, 22, 75, 46, 78, 42, 83, 210, 158, 29, 81, 190, + 205, 4, 76, 130, 40, 67, 202, 154, 4, 90, 212, 7, 2, 65, 76, 170, 2, 66, + 2, 89, 146, 1, 87, 182, 89, 84, 150, 14, 80, 158, 20, 70, 2, 72, 2, 82, + 2, 86, 186, 2, 69, 2, 73, 2, 79, 3, 85, 4, 250, 186, 5, 65, 247, 251, 33, + 72, 4, 174, 162, 39, 66, 215, 22, 65, 2, 171, 182, 38, 73, 6, 194, 183, + 38, 65, 154, 98, 80, 191, 28, 72, 6, 206, 232, 38, 85, 158, 77, 72, 3, + 89, 4, 188, 181, 2, 6, 73, 78, 78, 89, 73, 73, 135, 128, 37, 72, 4, 40, + 4, 69, 32, 67, 79, 151, 206, 38, 73, 2, 173, 174, 38, 13, 78, 83, 79, 78, + 65, 78, 84, 32, 77, 79, 68, 73, 70, 4, 218, 222, 32, 69, 191, 141, 4, 81, + 4, 166, 151, 25, 65, 199, 185, 10, 85, 4, 182, 215, 26, 69, 185, 202, 11, + 12, 73, 83, 83, 73, 79, 78, 32, 84, 73, 67, 75, 69, 116, 80, 5, 71, 69, + 65, 78, 32, 249, 144, 33, 9, 82, 73, 65, 76, 32, 84, 82, 65, 77, 114, + 136, 1, 3, 68, 82, 89, 0, 6, 76, 73, 81, 85, 73, 68, 60, 8, 77, 69, 65, + 83, 85, 82, 69, 32, 26, 87, 130, 185, 26, 78, 147, 185, 11, 67, 2, 153, + 2, 11, 32, 77, 69, 65, 83, 85, 82, 69, 32, 70, 73, 4, 246, 1, 83, 31, 84, + 14, 100, 6, 69, 73, 71, 72, 84, 32, 241, 1, 14, 79, 82, 68, 32, 83, 69, + 80, 65, 82, 65, 84, 79, 82, 32, 10, 54, 70, 66, 83, 30, 84, 65, 5, 66, + 65, 83, 69, 32, 4, 38, 73, 89, 5, 79, 85, 82, 84, 72, 2, 85, 3, 82, 83, + 84, 2, 49, 4, 69, 67, 79, 78, 2, 21, 3, 72, 73, 82, 2, 11, 68, 2, 25, 4, + 32, 83, 85, 66, 2, 133, 148, 39, 2, 85, 78, 4, 130, 151, 38, 76, 247, 72, + 68, 130, 1, 140, 2, 22, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, + 71, 78, 32, 77, 69, 68, 73, 65, 76, 32, 88, 7, 76, 69, 84, 84, 69, 82, + 32, 242, 1, 83, 168, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, + 140, 234, 31, 8, 78, 85, 77, 66, 69, 82, 32, 84, 219, 209, 5, 68, 6, 26, + 76, 159, 171, 39, 82, 4, 132, 227, 38, 7, 73, 71, 65, 84, 73, 78, 71, + 207, 74, 65, 68, 154, 1, 65, 210, 195, 35, 68, 46, 84, 222, 225, 1, 76, + 246, 189, 1, 78, 126, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, + 2, 77, 2, 82, 3, 83, 9, 45, 9, 76, 84, 69, 82, 78, 65, 84, 69, 32, 6, + 146, 169, 39, 66, 2, 71, 3, 84, 10, 60, 4, 73, 71, 78, 32, 241, 193, 22, + 5, 89, 77, 66, 79, 76, 8, 50, 83, 182, 130, 25, 75, 145, 233, 9, 2, 82, + 85, 4, 148, 183, 36, 4, 77, 65, 76, 76, 207, 162, 2, 69, 22, 66, 65, 162, + 218, 35, 85, 210, 200, 1, 73, 206, 134, 2, 69, 3, 79, 11, 186, 169, 39, + 65, 2, 73, 2, 77, 3, 87, 7, 11, 32, 4, 252, 190, 34, 3, 68, 69, 80, 141, + 153, 4, 5, 65, 82, 82, 73, 86, 130, 2, 232, 1, 20, 67, 72, 69, 77, 73, + 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 166, 28, 69, + 60, 2, 76, 32, 82, 77, 108, 6, 84, 69, 82, 78, 65, 84, 208, 179, 28, 7, + 73, 69, 78, 32, 77, 79, 78, 225, 230, 6, 3, 65, 82, 77, 232, 1, 158, 2, + 65, 246, 2, 66, 210, 1, 67, 138, 3, 68, 98, 71, 38, 72, 132, 1, 4, 73, + 82, 79, 78, 82, 76, 74, 77, 144, 1, 2, 78, 73, 34, 80, 176, 2, 3, 81, 85, + 73, 74, 82, 146, 2, 83, 210, 5, 84, 166, 1, 86, 200, 1, 2, 87, 65, 214, + 245, 33, 85, 190, 206, 1, 69, 202, 153, 1, 79, 195, 27, 70, 30, 194, 1, + 76, 72, 3, 81, 85, 65, 204, 8, 7, 78, 84, 73, 77, 79, 78, 89, 148, 137, + 3, 3, 77, 65, 76, 176, 222, 8, 5, 85, 82, 73, 80, 73, 188, 129, 12, 3, + 82, 83, 69, 234, 156, 14, 83, 159, 91, 73, 8, 224, 24, 2, 69, 77, 252, + 209, 25, 4, 75, 65, 76, 73, 179, 167, 13, 85, 10, 38, 32, 149, 139, 24, + 3, 70, 79, 82, 8, 216, 7, 4, 86, 73, 84, 65, 225, 194, 22, 4, 82, 69, 71, + 73, 16, 148, 1, 7, 65, 84, 72, 32, 79, 70, 32, 204, 6, 6, 73, 83, 77, 85, + 84, 72, 144, 1, 4, 79, 82, 65, 88, 164, 1, 4, 76, 65, 67, 75, 203, 232, + 37, 82, 4, 230, 182, 16, 77, 253, 218, 21, 5, 86, 65, 80, 79, 85, 28, 82, + 65, 92, 6, 79, 80, 80, 69, 82, 32, 34, 82, 217, 206, 36, 4, 73, 78, 78, + 65, 6, 216, 218, 5, 2, 68, 85, 196, 156, 32, 9, 80, 85, 84, 32, 77, 79, + 82, 84, 85, 235, 27, 76, 4, 230, 13, 65, 179, 240, 37, 79, 16, 72, 8, 79, + 67, 85, 83, 32, 79, 70, 32, 53, 6, 85, 67, 73, 66, 76, 69, 6, 228, 16, 5, + 67, 79, 80, 80, 69, 219, 232, 37, 73, 11, 11, 45, 8, 138, 157, 39, 50, 2, + 51, 2, 52, 3, 53, 8, 44, 2, 73, 83, 185, 133, 5, 3, 65, 89, 45, 6, 144, + 2, 4, 83, 79, 76, 86, 203, 169, 36, 84, 4, 234, 182, 29, 79, 191, 212, 9, + 85, 8, 32, 4, 65, 76, 70, 32, 47, 79, 4, 240, 191, 34, 2, 79, 85, 255, + 161, 3, 68, 4, 132, 245, 2, 4, 82, 83, 69, 32, 183, 237, 35, 85, 6, 56, + 3, 32, 79, 82, 73, 7, 45, 67, 79, 80, 80, 69, 82, 4, 147, 226, 25, 69, 4, + 48, 3, 69, 65, 68, 221, 158, 13, 3, 79, 68, 69, 2, 135, 225, 34, 32, 10, + 120, 16, 69, 82, 67, 85, 82, 89, 32, 83, 85, 66, 76, 73, 77, 65, 84, 69, + 176, 133, 16, 4, 65, 82, 67, 65, 135, 148, 21, 79, 7, 207, 151, 39, 45, + 4, 142, 248, 37, 84, 235, 117, 71, 14, 108, 11, 72, 73, 76, 79, 83, 79, + 80, 72, 69, 82, 83, 34, 79, 98, 85, 181, 155, 29, 6, 82, 69, 67, 73, 80, + 73, 2, 209, 9, 4, 32, 83, 85, 76, 6, 52, 4, 87, 68, 69, 82, 161, 145, 35, + 3, 84, 32, 65, 5, 237, 231, 37, 5, 69, 68, 32, 66, 82, 4, 180, 143, 33, + 4, 84, 82, 69, 70, 161, 245, 5, 3, 82, 73, 70, 4, 132, 185, 34, 5, 78, + 84, 69, 83, 83, 249, 196, 3, 4, 67, 75, 32, 76, 24, 58, 69, 213, 220, 25, + 8, 79, 67, 75, 32, 83, 65, 76, 84, 20, 68, 5, 71, 85, 76, 85, 83, 164, 7, + 3, 65, 76, 71, 179, 172, 25, 84, 15, 32, 4, 32, 79, 70, 32, 71, 45, 6, + 228, 219, 25, 8, 65, 78, 84, 73, 77, 79, 78, 89, 255, 147, 12, 73, 6, + 170, 147, 39, 50, 2, 51, 3, 52, 34, 164, 1, 2, 65, 76, 194, 1, 84, 142, + 1, 85, 184, 139, 17, 2, 80, 73, 200, 255, 11, 2, 73, 76, 194, 243, 8, 79, + 133, 20, 11, 67, 69, 80, 84, 69, 82, 32, 79, 70, 32, 74, 8, 58, 84, 197, + 234, 37, 8, 45, 65, 77, 77, 79, 78, 73, 65, 7, 25, 4, 32, 79, 70, 32, 4, + 52, 8, 67, 79, 80, 80, 69, 82, 32, 65, 231, 5, 65, 2, 237, 149, 29, 7, + 78, 84, 73, 77, 79, 78, 73, 6, 236, 3, 8, 65, 82, 82, 69, 68, 32, 84, 82, + 169, 212, 25, 19, 82, 65, 84, 85, 77, 32, 83, 85, 80, 69, 82, 32, 83, 84, + 82, 65, 84, 85, 77, 12, 44, 6, 66, 76, 73, 77, 65, 84, 155, 1, 76, 10, + 44, 5, 69, 32, 79, 70, 32, 215, 190, 38, 73, 8, 68, 8, 83, 65, 76, 84, + 32, 79, 70, 32, 130, 3, 65, 175, 209, 26, 67, 4, 254, 2, 65, 175, 209, + 26, 67, 2, 135, 149, 38, 70, 12, 68, 3, 65, 82, 84, 32, 2, 73, 78, 34, + 82, 189, 162, 37, 2, 85, 84, 4, 11, 65, 4, 219, 212, 25, 82, 4, 222, 162, + 34, 67, 167, 49, 32, 2, 145, 201, 38, 2, 73, 68, 14, 50, 73, 245, 238, + 36, 6, 69, 82, 68, 73, 71, 82, 12, 64, 5, 78, 69, 71, 65, 82, 149, 211, + 25, 5, 84, 82, 73, 79, 76, 9, 44, 5, 32, 79, 70, 32, 65, 251, 137, 39, + 45, 2, 221, 188, 23, 3, 78, 84, 73, 4, 234, 204, 38, 84, 227, 61, 88, 6, + 38, 77, 246, 246, 37, 70, 231, 118, 82, 2, 151, 227, 37, 66, 4, 134, 227, + 32, 69, 233, 136, 4, 11, 65, 82, 79, 85, 78, 68, 45, 80, 82, 79, 70, 9, + 49, 10, 79, 83, 84, 32, 69, 81, 85, 65, 76, 32, 6, 32, 2, 84, 79, 235, + 176, 31, 79, 5, 147, 205, 6, 32, 4, 240, 192, 10, 3, 73, 86, 69, 253, + 159, 27, 5, 69, 32, 79, 78, 69, 10, 162, 1, 80, 180, 194, 28, 6, 69, 82, + 73, 67, 65, 78, 200, 232, 5, 3, 66, 85, 76, 209, 204, 3, 16, 65, 76, 71, + 65, 77, 65, 84, 73, 79, 78, 32, 79, 82, 32, 67, 79, 4, 158, 205, 35, 69, + 171, 78, 72, 192, 9, 92, 3, 65, 84, 79, 174, 20, 71, 174, 1, 84, 150, + 167, 24, 67, 182, 203, 11, 68, 155, 252, 2, 75, 144, 9, 104, 17, 76, 73, + 65, 78, 32, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 32, 65, 133, 241, 12, + 3, 77, 73, 67, 142, 9, 70, 48, 138, 4, 49, 198, 2, 50, 162, 3, 51, 174, + 5, 52, 163, 3, 53, 222, 1, 106, 50, 102, 52, 110, 54, 102, 57, 182, 7, + 51, 234, 190, 11, 49, 202, 174, 22, 48, 242, 1, 53, 2, 55, 3, 56, 22, + 238, 193, 33, 54, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 55, 2, 56, 3, 57, 28, 250, 135, 12, 54, 146, 185, 21, 49, 2, 53, 174, + 193, 5, 48, 2, 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, 26, 210, 238, 11, + 54, 250, 146, 27, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, + 57, 24, 186, 191, 33, 55, 2, 56, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 3, 57, 232, 1, 98, 48, 114, 49, 254, 242, 11, 50, 2, + 51, 158, 129, 22, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 42, 162, 236, + 11, 52, 2, 55, 190, 24, 53, 146, 185, 21, 48, 2, 49, 2, 50, 174, 193, 5, + 51, 2, 54, 2, 56, 3, 57, 26, 238, 131, 12, 48, 146, 185, 21, 53, 174, + 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 222, 1, 102, + 48, 110, 49, 102, 57, 210, 1, 56, 170, 225, 11, 50, 2, 54, 250, 141, 22, + 51, 2, 52, 2, 53, 3, 55, 28, 150, 130, 12, 50, 146, 185, 21, 55, 2, 57, + 174, 193, 5, 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 54, 3, 56, 24, 186, 186, + 33, 53, 2, 54, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 55, 2, 56, + 3, 57, 24, 214, 185, 33, 52, 2, 57, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, + 2, 53, 2, 54, 2, 55, 3, 56, 228, 1, 102, 48, 2, 50, 2, 53, 102, 51, 110, + 54, 102, 56, 162, 1, 57, 174, 201, 11, 55, 162, 162, 22, 49, 3, 52, 22, + 134, 184, 33, 57, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 54, 2, 55, 3, 56, 30, 214, 229, 11, 54, 242, 150, 8, 50, 138, 252, 18, + 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 24, 182, 182, 33, + 52, 2, 56, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 53, 2, 54, 2, 55, 3, + 57, 26, 98, 51, 242, 180, 33, 49, 2, 54, 174, 193, 5, 48, 2, 50, 2, 52, + 2, 53, 2, 55, 2, 56, 3, 57, 4, 144, 173, 20, 6, 32, 82, 65, 32, 79, 82, + 139, 201, 18, 65, 20, 140, 203, 38, 3, 51, 32, 69, 210, 42, 48, 2, 49, 2, + 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 202, 1, 102, 49, 210, 1, + 53, 130, 132, 20, 57, 166, 228, 13, 48, 2, 50, 2, 51, 2, 52, 2, 54, 2, + 55, 3, 56, 22, 90, 48, 174, 243, 38, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 54, 2, 55, 2, 56, 3, 57, 4, 60, 6, 32, 66, 69, 71, 73, 78, 1, 5, 65, 32, + 69, 78, 68, 2, 129, 248, 15, 8, 32, 76, 79, 71, 79, 71, 82, 65, 24, 138, + 177, 33, 48, 2, 55, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, + 2, 56, 3, 57, 60, 218, 142, 32, 51, 246, 214, 1, 48, 242, 1, 49, 3, 50, + 14, 96, 2, 76, 69, 250, 161, 2, 85, 208, 173, 31, 2, 83, 84, 230, 192, 3, + 69, 249, 162, 1, 2, 82, 89, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 254, + 133, 31, 83, 191, 161, 4, 85, 29, 104, 11, 73, 67, 76, 79, 67, 75, 87, + 73, 83, 69, 32, 233, 219, 35, 9, 69, 78, 78, 65, 32, 87, 73, 84, 72, 24, + 90, 84, 254, 220, 6, 67, 58, 68, 122, 71, 138, 4, 79, 253, 173, 27, 5, + 73, 78, 84, 69, 71, 12, 84, 15, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, + 65, 68, 69, 68, 32, 187, 225, 6, 79, 10, 112, 3, 76, 69, 70, 0, 4, 82, + 73, 71, 72, 12, 6, 66, 79, 84, 84, 79, 77, 0, 3, 84, 79, 80, 223, 224, 6, + 79, 2, 11, 84, 2, 169, 152, 36, 7, 32, 85, 45, 83, 72, 65, 80, 158, 1, + 128, 1, 20, 76, 32, 70, 85, 78, 67, 84, 73, 79, 78, 65, 76, 32, 83, 89, + 77, 66, 79, 76, 32, 210, 15, 79, 38, 80, 167, 219, 38, 67, 140, 1, 222, + 2, 67, 186, 1, 68, 190, 2, 73, 44, 4, 65, 76, 80, 72, 0, 4, 79, 77, 69, + 71, 32, 4, 74, 79, 84, 32, 36, 4, 76, 69, 70, 84, 68, 2, 81, 85, 222, 3, + 82, 54, 83, 92, 4, 69, 80, 83, 73, 32, 6, 66, 65, 67, 75, 83, 76, 76, 2, + 85, 80, 208, 216, 15, 12, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 78, + 0, 5, 84, 73, 76, 68, 69, 191, 195, 19, 90, 14, 64, 6, 73, 82, 67, 76, + 69, 32, 165, 152, 36, 4, 79, 77, 77, 65, 12, 80, 2, 83, 84, 202, 138, 19, + 68, 170, 246, 5, 66, 214, 157, 10, 85, 175, 248, 2, 74, 4, 246, 197, 37, + 73, 215, 104, 65, 22, 76, 2, 69, 76, 120, 3, 79, 87, 78, 253, 140, 31, 6, + 73, 65, 77, 79, 78, 68, 10, 30, 32, 53, 3, 84, 65, 32, 6, 182, 137, 19, + 68, 174, 155, 16, 84, 159, 163, 1, 83, 4, 254, 156, 35, 85, 207, 170, 1, + 83, 10, 22, 32, 171, 9, 87, 8, 52, 5, 84, 65, 67, 75, 32, 182, 1, 83, + 231, 6, 67, 4, 138, 156, 35, 85, 175, 248, 2, 74, 6, 40, 2, 79, 84, 173, + 155, 31, 2, 45, 66, 4, 11, 65, 5, 219, 139, 31, 32, 4, 158, 135, 19, 68, + 255, 147, 16, 85, 4, 28, 2, 32, 83, 191, 7, 87, 2, 149, 197, 36, 4, 72, + 79, 69, 32, 46, 44, 2, 65, 68, 137, 3, 4, 79, 84, 69, 32, 43, 11, 32, 40, + 178, 1, 67, 34, 68, 92, 2, 85, 80, 44, 2, 76, 69, 186, 158, 6, 81, 200, + 170, 13, 3, 78, 79, 84, 22, 69, 182, 176, 5, 66, 198, 133, 7, 83, 234, + 209, 4, 71, 162, 111, 82, 183, 79, 74, 4, 158, 146, 37, 73, 147, 127, 79, + 12, 54, 73, 36, 3, 79, 87, 78, 197, 188, 35, 2, 69, 76, 4, 218, 246, 30, + 86, 219, 174, 6, 65, 4, 152, 167, 10, 2, 32, 67, 215, 153, 27, 87, 4, + 174, 209, 36, 83, 255, 110, 70, 4, 242, 248, 11, 81, 139, 158, 23, 85, 4, + 184, 3, 5, 73, 71, 72, 84, 87, 131, 189, 38, 72, 10, 88, 5, 69, 77, 73, + 67, 79, 34, 76, 34, 84, 129, 247, 11, 7, 81, 85, 73, 83, 72, 32, 81, 2, + 229, 133, 31, 3, 76, 79, 78, 2, 177, 142, 36, 3, 65, 83, 72, 4, 248, 216, + 15, 2, 65, 82, 239, 133, 7, 73, 12, 22, 32, 171, 1, 87, 10, 78, 67, 36, + 5, 84, 65, 67, 75, 32, 253, 139, 38, 6, 83, 72, 79, 69, 32, 74, 2, 229, + 221, 22, 4, 65, 82, 69, 84, 6, 210, 255, 18, 68, 162, 195, 16, 79, 139, + 201, 2, 74, 2, 169, 207, 35, 6, 65, 82, 68, 83, 32, 86, 4, 242, 237, 32, + 83, 235, 157, 5, 76, 12, 92, 2, 82, 79, 153, 200, 25, 15, 76, 73, 67, 65, + 84, 73, 79, 78, 32, 80, 82, 79, 71, 82, 65, 10, 112, 9, 88, 73, 77, 65, + 84, 69, 76, 89, 32, 153, 189, 38, 13, 65, 67, 72, 69, 83, 32, 84, 72, 69, + 32, 76, 73, 77, 8, 76, 6, 69, 81, 85, 65, 76, 32, 201, 161, 24, 7, 66, + 85, 84, 32, 78, 79, 84, 6, 32, 2, 84, 79, 255, 128, 31, 79, 5, 181, 201, + 25, 13, 32, 79, 82, 32, 84, 72, 69, 32, 73, 77, 65, 71, 69, 230, 22, 148, + 1, 4, 65, 66, 73, 67, 208, 245, 1, 7, 77, 69, 78, 73, 65, 78, 32, 224, + 12, 3, 82, 79, 87, 236, 3, 2, 84, 73, 254, 188, 35, 73, 227, 147, 1, 67, + 148, 21, 54, 32, 141, 244, 1, 7, 45, 73, 78, 68, 73, 67, 32, 248, 20, + 178, 3, 67, 158, 1, 68, 242, 2, 69, 198, 1, 70, 212, 1, 2, 72, 65, 104, + 5, 75, 65, 83, 82, 65, 86, 76, 248, 167, 1, 2, 77, 65, 220, 18, 7, 78, + 85, 77, 66, 69, 82, 32, 36, 5, 79, 80, 69, 78, 32, 82, 80, 214, 1, 82, + 156, 2, 8, 66, 65, 83, 69, 76, 73, 78, 69, 52, 6, 73, 78, 86, 69, 82, 84, + 98, 83, 154, 33, 84, 202, 4, 86, 188, 245, 16, 9, 87, 65, 86, 89, 32, 72, + 65, 77, 90, 138, 164, 17, 81, 201, 190, 1, 6, 90, 87, 65, 82, 65, 75, 14, + 44, 5, 85, 82, 76, 89, 32, 191, 135, 36, 79, 12, 72, 4, 68, 65, 77, 77, + 0, 4, 70, 65, 84, 72, 1, 4, 75, 65, 83, 82, 4, 11, 65, 5, 199, 138, 37, + 84, 24, 154, 1, 65, 108, 5, 79, 85, 66, 76, 69, 152, 2, 16, 73, 83, 80, + 85, 84, 69, 68, 32, 69, 78, 68, 32, 79, 70, 32, 65, 137, 253, 22, 5, 69, + 67, 73, 77, 65, 14, 36, 3, 77, 77, 65, 171, 189, 32, 84, 13, 22, 32, 211, + 5, 84, 6, 158, 226, 1, 73, 58, 77, 167, 202, 35, 87, 6, 202, 4, 68, 157, + 193, 1, 18, 32, 82, 73, 71, 72, 84, 32, 65, 82, 82, 79, 87, 72, 69, 65, + 68, 32, 65, 8, 88, 12, 77, 80, 84, 89, 32, 67, 69, 78, 84, 82, 69, 32, + 57, 6, 78, 68, 32, 79, 70, 32, 4, 184, 131, 36, 4, 72, 73, 71, 72, 1, 3, + 76, 79, 87, 4, 26, 65, 139, 249, 28, 84, 2, 255, 148, 31, 89, 22, 84, 4, + 65, 84, 72, 65, 230, 209, 1, 79, 164, 196, 4, 3, 73, 86, 69, 223, 235, + 29, 85, 17, 22, 32, 139, 2, 84, 10, 52, 5, 87, 73, 84, 72, 32, 162, 222, + 1, 73, 59, 77, 6, 170, 254, 36, 84, 174, 77, 68, 191, 47, 82, 6, 72, 13, + 76, 70, 32, 77, 65, 68, 68, 65, 32, 79, 86, 69, 82, 231, 16, 77, 2, 181, + 157, 17, 2, 32, 77, 13, 18, 32, 43, 84, 6, 230, 72, 87, 146, 148, 1, 73, + 59, 77, 4, 161, 82, 2, 65, 78, 224, 15, 84, 5, 65, 82, 71, 69, 32, 146, + 1, 69, 149, 90, 8, 73, 71, 65, 84, 85, 82, 69, 32, 8, 64, 10, 82, 79, 85, + 78, 68, 32, 68, 79, 84, 32, 251, 218, 10, 67, 6, 220, 218, 10, 6, 73, 78, + 83, 73, 68, 69, 238, 213, 25, 66, 223, 155, 1, 65, 252, 7, 80, 5, 84, 84, + 69, 82, 32, 157, 251, 6, 9, 70, 84, 32, 65, 82, 82, 79, 87, 72, 248, 7, + 206, 2, 65, 240, 10, 2, 66, 69, 150, 4, 68, 214, 5, 70, 246, 4, 71, 226, + 2, 72, 156, 9, 2, 74, 69, 122, 75, 246, 5, 76, 222, 2, 77, 154, 1, 78, + 140, 3, 3, 80, 69, 72, 176, 1, 3, 81, 65, 70, 214, 1, 82, 230, 3, 83, + 158, 9, 84, 186, 7, 85, 148, 2, 2, 86, 69, 28, 3, 87, 65, 87, 202, 1, 89, + 246, 3, 79, 248, 2, 2, 90, 65, 31, 69, 112, 92, 7, 70, 82, 73, 67, 65, + 78, 32, 92, 2, 73, 78, 144, 2, 3, 76, 69, 70, 195, 193, 38, 69, 8, 52, 3, + 81, 65, 70, 214, 144, 32, 70, 243, 161, 3, 78, 5, 221, 64, 5, 32, 87, 73, + 84, 72, 21, 11, 32, 18, 72, 6, 87, 73, 84, 72, 32, 84, 154, 160, 1, 70, + 230, 43, 73, 203, 9, 77, 10, 60, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, + 32, 131, 55, 87, 6, 216, 204, 14, 17, 80, 79, 73, 78, 84, 73, 78, 71, 32, + 68, 79, 87, 78, 87, 65, 82, 68, 166, 221, 21, 66, 223, 155, 1, 65, 83, + 11, 32, 80, 70, 87, 196, 45, 6, 77, 65, 75, 83, 85, 82, 202, 112, 70, + 247, 52, 73, 70, 48, 4, 73, 84, 72, 32, 145, 45, 3, 65, 83, 76, 64, 192, + 2, 9, 65, 84, 84, 65, 67, 72, 69, 68, 32, 220, 1, 19, 82, 73, 71, 72, 84, + 32, 77, 73, 68, 68, 76, 69, 32, 83, 84, 82, 79, 75, 69, 188, 1, 6, 72, + 65, 77, 90, 65, 32, 44, 8, 87, 65, 86, 89, 32, 72, 65, 77, 254, 69, 69, + 204, 1, 4, 77, 65, 68, 68, 196, 139, 35, 9, 76, 69, 70, 84, 32, 77, 73, + 68, 68, 243, 230, 1, 68, 28, 204, 1, 17, 66, 79, 84, 84, 79, 77, 32, 82, + 73, 71, 72, 84, 32, 75, 65, 83, 82, 0, 14, 84, 79, 80, 32, 82, 73, 71, + 72, 84, 32, 70, 65, 84, 72, 94, 82, 56, 3, 76, 69, 70, 186, 201, 1, 75, + 223, 160, 31, 70, 6, 11, 65, 7, 29, 5, 32, 65, 78, 68, 32, 4, 196, 231, + 18, 3, 76, 69, 70, 255, 211, 18, 68, 8, 52, 3, 73, 71, 72, 253, 214, 1, + 4, 79, 85, 78, 68, 4, 17, 2, 84, 32, 4, 162, 176, 1, 82, 227, 37, 72, 12, + 146, 72, 65, 37, 5, 66, 69, 76, 79, 87, 4, 211, 143, 36, 90, 50, 22, 72, + 219, 63, 69, 41, 22, 32, 195, 63, 69, 28, 68, 5, 87, 73, 84, 72, 32, 198, + 150, 1, 70, 230, 43, 73, 203, 9, 77, 20, 116, 6, 83, 77, 65, 76, 76, 32, + 34, 84, 154, 19, 73, 200, 33, 10, 68, 79, 84, 32, 66, 69, 76, 79, 87, 32, + 215, 19, 72, 6, 226, 39, 77, 175, 232, 22, 86, 8, 88, 10, 72, 82, 69, 69, + 32, 68, 79, 84, 83, 32, 177, 49, 7, 87, 79, 32, 68, 79, 84, 83, 6, 144, + 1, 22, 80, 79, 73, 78, 84, 73, 78, 71, 32, 85, 80, 87, 65, 82, 68, 83, + 32, 66, 69, 76, 79, 87, 133, 29, 8, 72, 79, 82, 73, 90, 79, 78, 84, 5, + 227, 191, 14, 32, 76, 90, 65, 164, 4, 2, 68, 65, 40, 7, 79, 84, 76, 69, + 83, 83, 32, 190, 28, 89, 255, 24, 85, 42, 34, 76, 154, 4, 72, 187, 46, + 68, 25, 11, 32, 22, 56, 5, 87, 73, 84, 72, 32, 226, 145, 1, 70, 247, 52, + 73, 18, 132, 1, 9, 68, 79, 84, 32, 66, 69, 76, 79, 87, 16, 9, 73, 78, 86, + 69, 82, 84, 69, 68, 32, 34, 84, 202, 215, 11, 70, 203, 138, 26, 82, 5, + 243, 1, 32, 4, 226, 14, 83, 199, 164, 38, 86, 6, 160, 1, 10, 72, 82, 69, + 69, 32, 68, 79, 84, 83, 32, 33, 25, 87, 79, 32, 68, 79, 84, 83, 32, 86, + 69, 82, 84, 73, 67, 65, 76, 76, 89, 32, 66, 69, 76, 79, 87, 32, 4, 234, + 53, 65, 195, 227, 35, 66, 2, 253, 235, 14, 10, 65, 78, 68, 32, 83, 77, + 65, 76, 76, 32, 12, 22, 72, 207, 62, 76, 6, 199, 53, 65, 6, 190, 253, 31, + 66, 2, 70, 139, 178, 5, 81, 44, 60, 8, 65, 82, 83, 73, 32, 89, 69, 72, + 169, 2, 2, 69, 72, 23, 11, 32, 20, 68, 5, 87, 73, 84, 72, 32, 194, 140, + 1, 70, 230, 43, 73, 203, 9, 77, 12, 144, 1, 28, 69, 88, 84, 69, 78, 68, + 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, 32, 68, 73, + 71, 73, 84, 32, 30, 84, 163, 40, 73, 6, 250, 8, 70, 219, 49, 84, 4, 226, + 245, 6, 72, 131, 194, 7, 87, 23, 11, 32, 20, 68, 5, 87, 73, 84, 72, 32, + 154, 138, 1, 70, 230, 43, 73, 203, 9, 77, 12, 32, 4, 68, 79, 84, 32, 51, + 84, 6, 254, 40, 66, 249, 142, 15, 4, 77, 79, 86, 69, 6, 64, 10, 72, 82, + 69, 69, 32, 68, 79, 84, 83, 32, 203, 132, 36, 87, 4, 198, 17, 80, 227, + 129, 36, 66, 44, 72, 2, 65, 70, 160, 1, 4, 72, 65, 73, 78, 178, 21, 85, + 143, 147, 37, 82, 19, 11, 32, 16, 68, 5, 87, 73, 84, 72, 32, 194, 135, 1, + 70, 230, 43, 73, 203, 9, 77, 8, 162, 24, 84, 134, 193, 37, 82, 229, 32, + 8, 73, 78, 86, 69, 82, 84, 69, 68, 15, 11, 32, 12, 68, 5, 87, 73, 84, 72, + 32, 162, 134, 1, 70, 230, 43, 73, 203, 9, 77, 4, 254, 37, 84, 171, 140, + 26, 68, 82, 78, 65, 236, 5, 2, 69, 72, 161, 2, 9, 73, 71, 72, 32, 72, 65, + 77, 90, 65, 34, 34, 72, 213, 47, 3, 77, 90, 65, 31, 11, 32, 28, 68, 5, + 87, 73, 84, 72, 32, 186, 132, 1, 70, 230, 43, 73, 203, 9, 77, 20, 132, 2, + 29, 69, 88, 84, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, + 78, 68, 73, 67, 32, 68, 73, 71, 73, 84, 32, 70, 30, 73, 92, 24, 83, 77, + 65, 76, 76, 32, 65, 82, 65, 66, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, + 84, 65, 72, 32, 62, 84, 135, 52, 72, 2, 145, 186, 1, 2, 79, 85, 2, 45, 9, + 78, 86, 69, 82, 84, 69, 68, 32, 83, 2, 221, 253, 35, 6, 77, 65, 76, 76, + 32, 86, 6, 26, 65, 199, 139, 36, 66, 4, 174, 31, 78, 255, 135, 37, 66, 8, + 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 33, 8, 87, 79, 32, 68, + 79, 84, 83, 32, 4, 230, 8, 80, 191, 157, 37, 65, 4, 232, 165, 37, 8, 86, + 69, 82, 84, 73, 67, 65, 76, 27, 65, 41, 11, 32, 38, 144, 1, 4, 71, 79, + 65, 76, 88, 5, 87, 73, 84, 72, 32, 220, 46, 10, 68, 79, 65, 67, 72, 65, + 83, 72, 77, 69, 242, 78, 70, 230, 43, 73, 203, 9, 77, 13, 11, 32, 10, + 156, 49, 6, 87, 73, 84, 72, 32, 72, 250, 76, 70, 230, 43, 73, 203, 9, 77, + 8, 218, 26, 73, 245, 18, 3, 89, 69, 72, 9, 11, 32, 6, 166, 254, 22, 65, + 178, 238, 8, 89, 135, 181, 5, 87, 22, 28, 2, 69, 77, 131, 45, 72, 17, 11, + 32, 14, 140, 31, 6, 87, 73, 84, 72, 32, 84, 170, 93, 70, 230, 43, 73, + 203, 9, 77, 68, 98, 65, 208, 1, 4, 69, 72, 69, 72, 160, 3, 7, 73, 82, 71, + 72, 73, 90, 32, 205, 30, 2, 72, 65, 22, 46, 70, 177, 162, 1, 5, 83, 72, + 77, 73, 82, 21, 11, 32, 18, 64, 5, 87, 73, 84, 72, 32, 138, 122, 70, 230, + 43, 73, 203, 9, 77, 10, 42, 84, 130, 174, 34, 68, 199, 157, 3, 82, 4, + 174, 166, 14, 87, 207, 206, 21, 72, 25, 11, 32, 22, 64, 5, 87, 73, 84, + 72, 32, 234, 120, 70, 230, 43, 73, 203, 9, 77, 14, 38, 84, 226, 41, 83, + 143, 241, 36, 68, 10, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, + 121, 8, 87, 79, 32, 68, 79, 84, 83, 32, 6, 42, 80, 226, 129, 36, 66, 223, + 155, 1, 65, 2, 165, 243, 35, 14, 79, 73, 78, 84, 73, 78, 71, 32, 85, 80, + 87, 65, 82, 68, 4, 48, 6, 86, 69, 82, 84, 73, 67, 191, 156, 37, 65, 2, + 145, 188, 11, 3, 65, 76, 76, 12, 198, 38, 79, 13, 2, 89, 85, 26, 40, 2, + 65, 77, 245, 169, 1, 2, 79, 87, 25, 11, 32, 22, 64, 5, 87, 73, 84, 72, + 32, 254, 116, 70, 230, 43, 73, 203, 9, 77, 14, 88, 2, 68, 79, 36, 6, 83, + 77, 65, 76, 76, 32, 216, 162, 32, 2, 84, 72, 223, 209, 4, 66, 4, 166, + 161, 17, 85, 231, 248, 19, 84, 4, 204, 26, 16, 65, 82, 65, 66, 73, 67, + 32, 76, 69, 84, 84, 69, 82, 32, 84, 65, 143, 252, 37, 86, 18, 36, 3, 69, + 69, 77, 195, 212, 37, 65, 17, 11, 32, 14, 64, 5, 87, 73, 84, 72, 32, 166, + 114, 70, 230, 43, 73, 203, 9, 77, 6, 130, 18, 84, 199, 148, 34, 68, 60, + 38, 71, 26, 89, 17, 3, 79, 79, 78, 21, 22, 79, 255, 108, 32, 10, 247, 25, + 69, 31, 11, 32, 28, 92, 5, 71, 72, 85, 78, 78, 16, 5, 87, 73, 84, 72, 32, + 186, 112, 70, 230, 43, 73, 203, 9, 77, 6, 131, 33, 65, 14, 116, 6, 83, + 77, 65, 76, 76, 32, 38, 84, 184, 23, 8, 73, 78, 86, 69, 82, 84, 69, 68, + 238, 131, 26, 68, 227, 165, 11, 82, 4, 214, 217, 30, 84, 203, 184, 7, 86, + 4, 238, 217, 6, 72, 247, 144, 29, 87, 25, 22, 32, 151, 23, 69, 12, 88, + 11, 87, 73, 84, 72, 32, 83, 77, 65, 76, 76, 32, 134, 110, 70, 230, 43, + 73, 203, 9, 77, 4, 26, 77, 203, 144, 38, 86, 2, 209, 147, 37, 3, 69, 69, + 77, 19, 11, 32, 16, 64, 5, 87, 73, 84, 72, 32, 250, 108, 70, 230, 43, 73, + 203, 9, 77, 8, 36, 4, 68, 79, 84, 32, 179, 12, 84, 6, 44, 5, 66, 69, 76, + 79, 87, 167, 146, 37, 65, 5, 241, 152, 14, 6, 32, 65, 78, 68, 32, 78, 52, + 108, 2, 69, 72, 192, 27, 3, 82, 69, 72, 136, 3, 4, 78, 79, 79, 78, 197, + 118, 7, 79, 72, 73, 78, 71, 89, 65, 35, 11, 32, 32, 52, 5, 87, 73, 84, + 72, 32, 194, 106, 70, 247, 52, 73, 28, 134, 1, 83, 96, 2, 84, 87, 234, 5, + 73, 250, 21, 72, 154, 148, 11, 70, 148, 226, 6, 5, 68, 79, 84, 32, 66, + 234, 39, 76, 207, 128, 19, 82, 10, 44, 5, 77, 65, 76, 76, 32, 251, 219, + 37, 84, 8, 194, 6, 65, 182, 198, 6, 78, 215, 150, 16, 86, 4, 37, 7, 79, + 32, 68, 79, 84, 83, 32, 4, 162, 8, 86, 147, 134, 37, 65, 60, 184, 1, 2, + 65, 68, 120, 3, 69, 69, 78, 132, 6, 4, 72, 69, 69, 78, 220, 147, 1, 4, + 85, 80, 69, 82, 156, 145, 4, 7, 84, 82, 65, 73, 71, 72, 84, 169, 220, 31, + 6, 87, 65, 83, 72, 32, 75, 17, 11, 32, 14, 68, 6, 87, 73, 84, 72, 32, 84, + 130, 102, 70, 230, 43, 73, 203, 9, 77, 6, 218, 148, 32, 72, 239, 204, 3, + 87, 27, 11, 32, 24, 64, 5, 87, 73, 84, 72, 32, 142, 101, 70, 230, 43, 73, + 203, 9, 77, 16, 232, 1, 3, 68, 79, 84, 50, 73, 44, 7, 83, 77, 65, 76, 76, + 32, 65, 110, 84, 250, 168, 11, 70, 177, 137, 5, 31, 69, 88, 84, 69, 78, + 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, 32, 68, + 73, 71, 73, 84, 32, 70, 79, 85, 2, 249, 140, 18, 7, 32, 66, 69, 76, 79, + 87, 32, 2, 169, 20, 7, 78, 86, 69, 82, 84, 69, 68, 2, 85, 19, 82, 65, 66, + 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 84, 65, 72, 32, 65, 78, 2, 159, + 167, 22, 68, 6, 96, 11, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 66, 105, + 9, 87, 79, 32, 68, 79, 84, 83, 32, 86, 4, 25, 4, 69, 76, 79, 87, 5, 11, + 32, 2, 21, 3, 65, 78, 68, 2, 17, 2, 32, 84, 2, 243, 202, 6, 72, 2, 209, + 165, 11, 8, 69, 82, 84, 73, 67, 65, 76, 76, 13, 11, 32, 10, 46, 87, 158, + 95, 70, 230, 43, 73, 203, 9, 77, 2, 161, 139, 26, 5, 73, 84, 72, 32, 68, + 118, 92, 2, 65, 72, 144, 1, 4, 67, 72, 69, 72, 124, 2, 69, 72, 150, 3, + 72, 61, 3, 84, 69, 72, 19, 11, 32, 16, 64, 5, 87, 73, 84, 72, 32, 198, + 93, 70, 230, 43, 73, 203, 9, 77, 8, 26, 84, 179, 137, 26, 68, 6, 250, + 137, 14, 87, 139, 130, 18, 72, 25, 22, 32, 163, 5, 69, 12, 64, 5, 87, 73, + 84, 72, 32, 170, 92, 70, 230, 43, 73, 203, 9, 77, 4, 198, 13, 83, 143, + 241, 36, 68, 37, 22, 32, 167, 4, 69, 24, 62, 77, 116, 5, 87, 73, 84, 72, + 32, 190, 90, 70, 231, 43, 73, 10, 48, 6, 65, 82, 66, 85, 84, 65, 183, + 144, 1, 69, 9, 11, 32, 6, 238, 90, 70, 246, 52, 73, 197, 228, 35, 2, 71, + 79, 8, 104, 6, 83, 77, 65, 76, 76, 32, 56, 12, 84, 72, 82, 69, 69, 32, + 68, 79, 84, 83, 32, 65, 131, 171, 37, 82, 4, 32, 2, 84, 69, 143, 252, 37, + 86, 2, 151, 255, 36, 72, 2, 237, 135, 27, 4, 66, 79, 86, 69, 18, 42, 65, + 126, 69, 213, 129, 1, 2, 73, 78, 6, 131, 9, 76, 23, 18, 32, 91, 69, 10, + 60, 4, 87, 73, 84, 72, 230, 87, 70, 230, 43, 73, 203, 9, 77, 2, 129, 9, + 2, 32, 83, 10, 143, 11, 72, 15, 158, 1, 32, 181, 80, 33, 73, 71, 72, 85, + 82, 32, 75, 65, 90, 65, 75, 72, 32, 75, 73, 82, 71, 72, 73, 90, 32, 65, + 76, 69, 70, 32, 77, 65, 75, 83, 85, 82, 65, 8, 96, 16, 87, 73, 84, 72, + 32, 72, 65, 77, 90, 65, 32, 65, 66, 79, 86, 69, 186, 85, 70, 247, 52, 73, + 5, 155, 75, 32, 17, 234, 8, 72, 167, 76, 32, 25, 11, 32, 22, 52, 5, 87, + 73, 84, 72, 32, 202, 84, 70, 247, 52, 73, 18, 80, 4, 68, 79, 84, 32, 162, + 2, 69, 182, 1, 72, 234, 252, 13, 84, 163, 165, 23, 82, 4, 192, 178, 30, + 3, 87, 73, 84, 183, 199, 6, 65, 54, 28, 2, 69, 72, 227, 3, 85, 49, 11, + 32, 46, 100, 6, 66, 65, 82, 82, 69, 69, 252, 2, 5, 87, 73, 84, 72, 32, + 182, 79, 70, 230, 43, 73, 203, 9, 77, 17, 11, 32, 14, 52, 5, 87, 73, 84, + 72, 32, 238, 81, 70, 247, 52, 73, 10, 22, 69, 183, 1, 72, 4, 121, 28, 88, + 84, 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, + 67, 32, 68, 73, 71, 73, 84, 32, 84, 4, 160, 229, 34, 3, 72, 82, 69, 161, + 145, 2, 2, 87, 79, 6, 21, 3, 65, 77, 90, 6, 11, 65, 6, 17, 2, 32, 65, 6, + 21, 3, 66, 79, 86, 6, 11, 69, 7, 171, 79, 32, 22, 64, 10, 72, 65, 77, 90, + 65, 32, 65, 66, 79, 86, 18, 83, 51, 84, 10, 179, 2, 69, 2, 25, 4, 77, 65, + 76, 76, 2, 255, 150, 31, 32, 10, 108, 18, 87, 79, 32, 68, 79, 84, 83, 32, + 66, 69, 76, 79, 87, 32, 65, 78, 68, 32, 174, 195, 35, 65, 183, 5, 72, 6, + 70, 72, 232, 176, 6, 7, 83, 77, 65, 76, 76, 32, 78, 191, 190, 30, 68, 2, + 205, 248, 32, 3, 65, 77, 90, 18, 26, 72, 17, 2, 73, 78, 11, 243, 71, 32, + 9, 11, 32, 6, 158, 76, 70, 246, 52, 73, 161, 11, 13, 87, 73, 84, 72, 32, + 73, 78, 86, 69, 82, 84, 69, 68, 220, 7, 230, 5, 65, 158, 5, 66, 176, 2, + 9, 68, 65, 68, 32, 87, 73, 84, 72, 32, 80, 9, 70, 69, 72, 32, 87, 73, 84, + 72, 32, 72, 11, 71, 72, 65, 73, 78, 32, 87, 73, 84, 72, 32, 154, 1, 72, + 134, 3, 74, 190, 2, 75, 252, 1, 9, 76, 65, 77, 32, 87, 73, 84, 72, 32, + 226, 4, 77, 152, 4, 10, 78, 79, 79, 78, 32, 87, 73, 84, 72, 32, 182, 2, + 81, 190, 2, 82, 178, 2, 83, 146, 16, 84, 196, 9, 7, 87, 65, 83, 65, 76, + 76, 65, 40, 9, 89, 69, 72, 32, 87, 73, 84, 72, 32, 216, 3, 53, 85, 73, + 71, 72, 85, 82, 32, 75, 73, 82, 71, 72, 73, 90, 32, 89, 69, 72, 32, 87, + 73, 84, 72, 32, 72, 65, 77, 90, 65, 32, 65, 66, 79, 86, 69, 32, 87, 73, + 84, 72, 32, 65, 76, 69, 70, 32, 77, 65, 75, 83, 85, 82, 65, 205, 6, 14, + 90, 65, 72, 32, 87, 73, 84, 72, 32, 77, 69, 69, 77, 32, 54, 128, 1, 8, + 73, 78, 32, 87, 73, 84, 72, 32, 70, 76, 232, 57, 4, 75, 66, 65, 82, 205, + 168, 35, 8, 90, 90, 65, 32, 87, 65, 32, 74, 28, 152, 19, 4, 77, 69, 69, + 77, 150, 16, 74, 238, 23, 65, 255, 8, 89, 22, 56, 3, 65, 89, 72, 216, 1, + 3, 69, 70, 32, 207, 13, 76, 12, 30, 73, 122, 65, 151, 56, 69, 8, 52, 9, + 32, 65, 83, 45, 83, 65, 76, 65, 65, 47, 77, 4, 80, 4, 84, 85, 32, 87, + 139, 229, 37, 77, 4, 18, 65, 23, 32, 2, 17, 2, 65, 32, 2, 149, 153, 32, + 6, 65, 83, 45, 83, 65, 76, 8, 212, 65, 29, 77, 65, 75, 83, 85, 82, 65, + 32, 87, 73, 84, 72, 32, 83, 85, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, + 65, 76, 69, 70, 1, 13, 87, 73, 84, 72, 32, 70, 65, 84, 72, 65, 84, 65, + 78, 44, 160, 1, 8, 69, 72, 32, 87, 73, 84, 72, 32, 141, 135, 25, 25, 73, + 83, 77, 73, 76, 76, 65, 72, 32, 65, 82, 45, 82, 65, 72, 77, 65, 78, 32, + 65, 82, 45, 82, 65, 72, 42, 98, 72, 24, 3, 75, 72, 65, 230, 52, 65, 250, + 3, 74, 78, 77, 86, 78, 78, 90, 242, 2, 82, 43, 89, 10, 22, 65, 171, 56, + 69, 6, 131, 59, 72, 36, 222, 6, 72, 158, 7, 75, 218, 38, 65, 250, 3, 74, + 2, 77, 134, 5, 82, 3, 89, 30, 170, 13, 75, 218, 38, 65, 250, 3, 74, 146, + 2, 77, 110, 72, 139, 2, 89, 22, 64, 5, 77, 69, 69, 77, 32, 250, 50, 65, + 250, 3, 74, 135, 5, 89, 10, 40, 5, 87, 73, 84, 72, 32, 235, 103, 73, 6, + 174, 21, 77, 170, 25, 65, 203, 12, 89, 40, 80, 8, 65, 72, 32, 87, 73, 84, + 72, 32, 69, 8, 69, 72, 32, 87, 73, 84, 72, 32, 22, 236, 3, 4, 77, 69, 69, + 77, 226, 45, 65, 138, 6, 74, 247, 2, 89, 18, 164, 1, 5, 77, 69, 69, 77, + 32, 196, 11, 6, 65, 76, 69, 70, 32, 77, 150, 2, 89, 134, 38, 74, 53, 16, + 83, 85, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 8, 40, 5, + 87, 73, 84, 72, 32, 215, 100, 73, 4, 254, 43, 74, 3, 77, 30, 104, 9, 69, + 69, 77, 32, 87, 73, 84, 72, 32, 173, 230, 3, 11, 65, 76, 76, 65, 74, 65, + 76, 65, 76, 79, 85, 28, 62, 72, 60, 5, 77, 69, 69, 77, 32, 186, 45, 65, + 255, 8, 89, 8, 17, 2, 65, 72, 8, 11, 32, 8, 178, 29, 87, 191, 69, 73, 12, + 40, 5, 87, 73, 84, 72, 32, 171, 98, 73, 8, 166, 37, 72, 242, 3, 65, 203, + 12, 89, 64, 84, 8, 65, 70, 32, 87, 73, 84, 72, 32, 93, 9, 72, 65, 72, 32, + 87, 73, 84, 72, 32, 46, 168, 46, 2, 65, 76, 218, 1, 74, 96, 2, 76, 65, + 146, 2, 75, 14, 72, 30, 77, 239, 1, 89, 18, 54, 72, 250, 42, 65, 250, 3, + 74, 2, 77, 135, 5, 89, 2, 247, 8, 65, 74, 116, 5, 65, 76, 69, 70, 32, + 210, 1, 72, 124, 5, 74, 69, 69, 77, 32, 78, 75, 28, 5, 77, 69, 69, 77, + 32, 187, 47, 89, 20, 64, 5, 87, 73, 84, 72, 32, 138, 44, 77, 222, 6, 70, + 247, 52, 73, 12, 68, 6, 72, 65, 77, 90, 65, 32, 41, 7, 77, 65, 68, 68, + 65, 32, 65, 8, 38, 65, 249, 45, 4, 66, 69, 76, 79, 4, 229, 45, 3, 66, 79, + 86, 14, 28, 2, 65, 72, 163, 44, 69, 12, 11, 32, 12, 40, 5, 87, 73, 84, + 72, 32, 231, 92, 73, 8, 210, 35, 65, 130, 12, 77, 75, 89, 14, 40, 5, 87, + 73, 84, 72, 32, 151, 92, 73, 10, 130, 47, 74, 2, 77, 75, 89, 8, 129, 15, + 3, 72, 65, 72, 14, 150, 14, 87, 222, 33, 70, 230, 43, 73, 203, 9, 77, 48, + 84, 9, 69, 69, 77, 32, 87, 73, 84, 72, 32, 193, 36, 7, 79, 72, 65, 77, + 77, 65, 68, 46, 116, 5, 65, 76, 69, 70, 32, 66, 72, 0, 2, 75, 72, 104, 5, + 74, 69, 69, 77, 32, 92, 5, 77, 69, 69, 77, 32, 43, 89, 4, 22, 77, 219, + 45, 70, 2, 173, 35, 6, 65, 75, 83, 85, 82, 65, 10, 21, 3, 65, 72, 32, 10, + 40, 5, 87, 73, 84, 72, 32, 211, 88, 73, 6, 250, 31, 74, 2, 77, 143, 12, + 89, 12, 40, 5, 87, 73, 84, 72, 32, 131, 88, 73, 8, 170, 31, 77, 194, 7, + 75, 14, 72, 195, 4, 89, 8, 246, 40, 87, 246, 2, 70, 231, 43, 73, 2, 11, + 69, 2, 143, 33, 72, 60, 134, 1, 72, 28, 5, 74, 69, 69, 77, 32, 92, 5, 77, + 69, 69, 77, 32, 242, 31, 65, 154, 5, 78, 78, 90, 134, 1, 75, 238, 1, 82, + 43, 89, 14, 146, 27, 65, 155, 9, 69, 16, 40, 5, 87, 73, 84, 72, 32, 191, + 85, 73, 12, 186, 24, 72, 242, 3, 65, 130, 12, 77, 75, 89, 12, 206, 15, + 87, 218, 25, 70, 230, 43, 73, 203, 9, 77, 28, 70, 65, 197, 146, 30, 11, + 85, 68, 68, 73, 83, 65, 32, 83, 73, 82, 82, 26, 64, 7, 70, 32, 87, 73, + 84, 72, 32, 193, 8, 4, 76, 65, 32, 85, 24, 64, 5, 77, 69, 69, 77, 32, + 238, 29, 65, 246, 6, 72, 139, 2, 89, 12, 40, 5, 87, 73, 84, 72, 32, 223, + 82, 73, 8, 34, 77, 186, 21, 72, 187, 16, 89, 2, 129, 38, 3, 69, 69, 77, + 18, 30, 65, 129, 26, 2, 69, 72, 16, 128, 1, 14, 68, 73, 32, 65, 76, 76, + 65, 65, 72, 85, 32, 65, 78, 72, 76, 6, 72, 73, 77, 65, 72, 85, 161, 26, + 4, 83, 79, 85, 76, 11, 26, 85, 163, 197, 37, 65, 6, 26, 77, 251, 140, 36, + 78, 5, 131, 197, 37, 65, 4, 26, 32, 1, 2, 77, 32, 2, 193, 142, 30, 4, 65, + 76, 76, 65, 190, 1, 138, 1, 65, 192, 6, 9, 69, 69, 78, 32, 87, 73, 84, + 72, 32, 250, 3, 72, 233, 5, 13, 85, 66, 72, 65, 65, 78, 65, 72, 85, 32, + 87, 65, 32, 46, 48, 7, 68, 32, 87, 73, 84, 72, 32, 251, 1, 76, 32, 76, 4, + 72, 65, 72, 32, 82, 77, 238, 23, 65, 138, 4, 75, 246, 4, 82, 3, 89, 10, + 22, 87, 195, 77, 73, 6, 25, 4, 73, 84, 72, 32, 6, 162, 16, 72, 187, 16, + 89, 8, 21, 3, 69, 69, 77, 8, 11, 32, 8, 208, 31, 6, 87, 73, 84, 72, 32, + 77, 147, 45, 73, 14, 26, 65, 77, 2, 76, 65, 4, 134, 22, 77, 193, 189, 35, + 11, 65, 77, 85, 72, 85, 32, 65, 76, 65, 89, 78, 10, 34, 32, 133, 1, 3, + 76, 76, 65, 4, 22, 85, 159, 84, 73, 2, 217, 8, 23, 83, 69, 68, 32, 65, + 83, 32, 75, 79, 82, 65, 78, 73, 67, 32, 83, 84, 79, 80, 32, 83, 73, 71, + 6, 98, 72, 169, 191, 37, 18, 65, 72, 85, 32, 65, 76, 65, 89, 72, 73, 32, + 87, 65, 45, 65, 65, 76, 73, 4, 220, 63, 12, 79, 85, 32, 65, 76, 65, 89, + 72, 69, 32, 87, 65, 1, 22, 85, 32, 65, 76, 65, 89, 72, 73, 32, 87, 65, + 65, 65, 76, 73, 72, 69, 69, 32, 87, 65, 45, 60, 130, 1, 72, 100, 5, 74, + 69, 69, 77, 32, 84, 5, 75, 72, 65, 72, 32, 92, 5, 77, 69, 69, 77, 32, + 234, 15, 65, 254, 8, 82, 3, 89, 12, 32, 3, 65, 72, 32, 159, 21, 69, 8, + 156, 14, 6, 87, 73, 84, 72, 32, 74, 214, 56, 73, 203, 9, 77, 10, 52, 5, + 87, 73, 84, 72, 32, 254, 69, 73, 203, 9, 77, 4, 234, 12, 65, 139, 8, 72, + 10, 34, 87, 190, 69, 73, 203, 9, 77, 4, 25, 4, 73, 84, 72, 32, 4, 142, + 12, 65, 203, 12, 89, 16, 52, 5, 87, 73, 84, 72, 32, 206, 68, 73, 203, 9, + 77, 10, 202, 7, 72, 174, 4, 74, 199, 11, 77, 82, 96, 10, 65, 68, 68, 65, + 32, 87, 73, 84, 72, 32, 161, 1, 9, 69, 69, 78, 32, 87, 73, 84, 72, 32, + 18, 96, 4, 68, 65, 77, 77, 0, 4, 75, 65, 83, 82, 138, 11, 83, 237, 41, 6, + 70, 65, 84, 72, 65, 32, 6, 11, 65, 6, 28, 2, 84, 65, 203, 52, 32, 2, 163, + 12, 78, 64, 130, 1, 72, 36, 5, 74, 69, 69, 77, 32, 52, 5, 77, 69, 69, 77, + 32, 170, 11, 65, 228, 4, 4, 75, 72, 65, 72, 154, 4, 82, 3, 89, 18, 194, + 15, 69, 229, 3, 2, 65, 72, 10, 158, 18, 87, 246, 2, 70, 230, 43, 73, 203, + 9, 77, 16, 64, 5, 87, 73, 84, 72, 32, 158, 20, 70, 230, 43, 73, 203, 9, + 77, 8, 252, 2, 2, 75, 72, 243, 15, 77, 122, 66, 65, 176, 2, 8, 69, 72, + 32, 87, 73, 84, 72, 32, 179, 4, 72, 28, 88, 11, 66, 65, 65, 82, 65, 75, + 65, 32, 87, 65, 45, 29, 7, 72, 32, 87, 73, 84, 72, 32, 2, 177, 163, 27, + 2, 84, 65, 26, 64, 5, 77, 69, 69, 77, 32, 194, 8, 65, 246, 6, 72, 139, 2, + 89, 14, 52, 5, 87, 73, 84, 72, 32, 166, 61, 73, 203, 9, 77, 8, 34, 72, + 174, 4, 77, 143, 12, 89, 4, 133, 16, 2, 65, 72, 66, 138, 1, 72, 108, 3, + 75, 72, 65, 12, 4, 74, 69, 69, 77, 92, 5, 77, 69, 69, 77, 32, 238, 4, 65, + 154, 5, 78, 78, 90, 242, 2, 82, 43, 89, 14, 32, 3, 65, 72, 32, 227, 9, + 69, 10, 40, 5, 87, 73, 84, 72, 32, 143, 59, 73, 6, 182, 2, 77, 199, 11, + 74, 10, 11, 72, 10, 11, 32, 10, 40, 5, 87, 73, 84, 72, 32, 175, 58, 73, + 6, 154, 1, 65, 62, 77, 143, 12, 89, 18, 64, 5, 87, 73, 84, 72, 32, 226, + 13, 70, 230, 43, 73, 203, 9, 77, 10, 50, 65, 62, 74, 194, 7, 75, 14, 72, + 195, 4, 89, 2, 217, 12, 11, 76, 69, 70, 32, 77, 65, 75, 83, 85, 82, 65, + 2, 225, 7, 3, 69, 69, 77, 28, 56, 2, 65, 76, 117, 8, 69, 72, 32, 87, 73, + 84, 72, 32, 2, 37, 7, 32, 87, 73, 84, 72, 32, 83, 2, 197, 1, 15, 85, 80, + 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 26, 108, 3, 74, 69, + 69, 126, 65, 198, 4, 77, 86, 78, 78, 90, 242, 2, 82, 42, 89, 233, 53, 5, + 72, 69, 72, 32, 77, 2, 11, 77, 2, 11, 32, 2, 143, 63, 73, 114, 82, 65, + 38, 72, 246, 4, 78, 78, 90, 38, 74, 98, 75, 42, 77, 198, 1, 82, 43, 89, + 4, 217, 2, 5, 76, 69, 70, 32, 77, 76, 22, 65, 139, 3, 69, 72, 80, 15, 77, + 90, 65, 32, 65, 66, 79, 86, 69, 32, 87, 73, 84, 72, 32, 147, 5, 72, 66, + 118, 65, 126, 69, 42, 72, 78, 74, 18, 75, 62, 77, 86, 78, 22, 79, 16, 2, + 87, 65, 18, 89, 26, 90, 242, 2, 82, 67, 85, 12, 22, 76, 247, 6, 69, 8, + 21, 3, 69, 70, 32, 8, 34, 77, 222, 6, 70, 247, 52, 73, 4, 181, 6, 6, 65, + 75, 83, 85, 82, 65, 6, 11, 32, 6, 166, 6, 70, 231, 43, 73, 8, 22, 69, + 191, 3, 65, 4, 11, 72, 4, 11, 32, 4, 230, 4, 73, 163, 54, 77, 4, 251, 48, + 69, 2, 11, 72, 2, 11, 65, 2, 11, 72, 2, 149, 4, 2, 32, 73, 8, 17, 2, 69, + 69, 8, 11, 77, 8, 11, 32, 8, 198, 4, 70, 230, 43, 73, 203, 9, 77, 2, 93, + 2, 79, 79, 4, 231, 3, 69, 4, 215, 3, 87, 8, 186, 3, 69, 15, 85, 2, 17, 2, + 65, 73, 2, 239, 2, 78, 6, 21, 3, 69, 69, 77, 6, 11, 32, 6, 22, 87, 219, + 46, 73, 2, 141, 2, 5, 73, 84, 72, 32, 89, 4, 11, 72, 4, 11, 65, 4, 135, + 46, 72, 14, 21, 3, 69, 69, 77, 14, 11, 32, 14, 64, 5, 87, 73, 84, 72, 32, + 194, 1, 70, 230, 43, 73, 203, 9, 77, 6, 18, 77, 75, 89, 4, 21, 3, 69, 69, + 77, 4, 11, 32, 4, 18, 73, 119, 70, 2, 239, 44, 78, 2, 17, 2, 69, 72, 2, + 77, 2, 32, 70, 4, 11, 69, 4, 11, 72, 4, 11, 32, 4, 22, 70, 247, 52, 73, + 2, 205, 53, 2, 73, 78, 6, 202, 43, 73, 203, 9, 77, 166, 2, 92, 3, 68, 68, + 65, 52, 3, 82, 75, 32, 109, 11, 84, 72, 69, 77, 65, 84, 73, 67, 65, 76, + 32, 4, 148, 231, 35, 5, 32, 87, 65, 65, 74, 191, 61, 72, 4, 58, 78, 1, + 10, 83, 73, 68, 69, 87, 65, 89, 83, 32, 78, 2, 221, 254, 33, 7, 79, 79, + 78, 32, 71, 72, 85, 158, 2, 178, 2, 68, 144, 3, 8, 73, 78, 73, 84, 73, + 65, 76, 32, 222, 1, 76, 132, 2, 9, 79, 80, 69, 82, 65, 84, 79, 82, 32, + 166, 1, 83, 146, 3, 84, 158, 205, 23, 65, 102, 75, 110, 90, 246, 104, 74, + 2, 77, 166, 162, 5, 72, 170, 133, 1, 66, 2, 70, 2, 82, 2, 89, 174, 57, + 71, 198, 232, 2, 78, 154, 144, 2, 81, 255, 2, 87, 62, 26, 79, 187, 155, + 36, 65, 58, 88, 6, 84, 76, 69, 83, 83, 32, 61, 12, 85, 66, 76, 69, 45, + 83, 84, 82, 85, 67, 75, 32, 8, 214, 233, 30, 66, 2, 70, 242, 161, 3, 78, + 155, 144, 2, 81, 50, 190, 12, 83, 186, 20, 75, 158, 183, 23, 84, 74, 90, + 246, 104, 74, 2, 77, 166, 162, 5, 72, 170, 133, 1, 66, 2, 70, 2, 82, 2, + 89, 174, 57, 71, 198, 232, 2, 78, 246, 215, 1, 76, 150, 55, 68, 146, 1, + 81, 222, 1, 65, 163, 1, 87, 40, 182, 1, 84, 174, 9, 83, 150, 203, 23, 72, + 30, 75, 226, 105, 74, 2, 77, 206, 167, 6, 66, 2, 70, 2, 89, 174, 57, 71, + 198, 232, 2, 78, 246, 215, 1, 76, 166, 56, 81, 222, 1, 65, 159, 57, 68, + 4, 134, 230, 30, 72, 147, 178, 6, 69, 56, 48, 6, 79, 79, 80, 69, 68, 32, + 251, 135, 37, 65, 54, 210, 8, 83, 186, 20, 75, 150, 182, 23, 65, 74, 72, + 66, 84, 74, 90, 246, 104, 74, 2, 77, 206, 167, 6, 66, 2, 70, 2, 82, 2, + 89, 174, 57, 71, 198, 232, 2, 78, 246, 215, 1, 76, 150, 55, 68, 146, 1, + 81, 255, 2, 87, 4, 160, 154, 28, 23, 77, 69, 69, 77, 32, 87, 73, 84, 72, + 32, 72, 65, 72, 32, 87, 73, 84, 72, 32, 84, 65, 84, 87, 177, 233, 7, 9, + 72, 65, 72, 32, 87, 73, 84, 72, 32, 52, 84, 9, 84, 82, 69, 84, 67, 72, + 69, 68, 32, 134, 196, 35, 72, 14, 69, 227, 138, 1, 65, 46, 182, 1, 68, + 86, 84, 254, 2, 83, 150, 203, 23, 72, 30, 75, 226, 105, 74, 2, 77, 166, + 162, 5, 90, 170, 133, 1, 66, 2, 70, 2, 89, 174, 57, 71, 198, 232, 2, 78, + 154, 144, 2, 81, 223, 1, 65, 6, 52, 7, 79, 84, 76, 69, 83, 83, 32, 131, + 205, 36, 65, 4, 242, 223, 30, 66, 3, 70, 6, 214, 223, 30, 72, 146, 178, + 6, 65, 3, 69, 38, 42, 65, 158, 206, 23, 72, 247, 194, 13, 69, 32, 44, 5, + 73, 76, 69, 68, 32, 243, 145, 37, 72, 30, 150, 1, 68, 94, 83, 186, 20, + 75, 218, 160, 24, 74, 166, 162, 5, 72, 170, 133, 1, 89, 174, 57, 71, 198, + 232, 2, 78, 246, 215, 1, 76, 166, 56, 81, 223, 1, 65, 6, 52, 7, 79, 84, + 76, 69, 83, 83, 32, 143, 202, 36, 65, 4, 238, 254, 33, 78, 155, 144, 2, + 81, 6, 250, 190, 35, 72, 14, 69, 227, 138, 1, 65, 4, 238, 252, 17, 77, + 147, 140, 18, 83, 6, 128, 149, 24, 3, 75, 65, 83, 12, 4, 68, 65, 77, 77, + 1, 4, 70, 65, 84, 72, 10, 130, 1, 79, 212, 156, 12, 11, 76, 65, 67, 69, + 32, 79, 70, 32, 83, 65, 74, 144, 222, 5, 6, 73, 65, 83, 84, 82, 69, 175, + 173, 13, 69, 4, 148, 141, 12, 8, 69, 84, 73, 67, 32, 86, 69, 82, 205, + 237, 5, 3, 85, 78, 68, 14, 238, 1, 65, 96, 5, 69, 86, 69, 82, 83, 36, 15, + 73, 71, 72, 84, 32, 65, 82, 82, 79, 87, 72, 69, 65, 68, 32, 201, 206, 22, + 28, 79, 85, 78, 68, 69, 68, 32, 72, 73, 71, 72, 32, 83, 84, 79, 80, 32, + 87, 73, 84, 72, 32, 70, 73, 76, 76, 69, 68, 4, 40, 4, 73, 83, 69, 68, + 239, 138, 37, 89, 2, 17, 2, 32, 82, 2, 165, 193, 35, 3, 79, 85, 78, 2, + 133, 135, 21, 4, 69, 68, 32, 68, 6, 26, 65, 195, 241, 34, 66, 4, 193, + 230, 35, 3, 66, 79, 86, 202, 1, 238, 1, 69, 244, 2, 5, 72, 65, 68, 68, + 65, 36, 4, 73, 71, 78, 32, 240, 4, 5, 77, 65, 76, 76, 32, 246, 15, 85, + 244, 2, 6, 89, 77, 66, 79, 76, 32, 209, 178, 35, 18, 84, 65, 82, 84, 32, + 79, 70, 32, 82, 85, 66, 32, 69, 76, 32, 72, 73, 90, 20, 52, 7, 81, 85, + 69, 78, 67, 69, 32, 223, 209, 33, 77, 18, 184, 1, 26, 89, 69, 72, 32, 87, + 73, 84, 72, 32, 72, 65, 77, 90, 65, 32, 65, 66, 79, 86, 69, 32, 87, 73, + 84, 72, 32, 209, 210, 30, 13, 78, 79, 79, 78, 32, 87, 73, 84, 72, 32, 75, + 69, 72, 16, 70, 65, 142, 135, 36, 87, 182, 89, 89, 150, 14, 79, 214, 22, + 69, 3, 85, 6, 36, 3, 76, 69, 70, 131, 133, 37, 69, 5, 159, 13, 32, 7, 11, + 32, 4, 246, 22, 73, 59, 77, 22, 132, 1, 2, 82, 65, 158, 1, 83, 188, 1, 7, + 65, 76, 65, 89, 72, 69, 32, 160, 15, 2, 77, 73, 209, 148, 33, 6, 84, 65, + 75, 72, 65, 76, 4, 132, 1, 13, 72, 77, 65, 84, 85, 76, 76, 65, 72, 32, + 65, 76, 65, 213, 192, 32, 13, 68, 73, 32, 65, 76, 76, 65, 72, 79, 85, 32, + 65, 78, 2, 175, 213, 36, 89, 12, 46, 65, 193, 1, 6, 73, 78, 68, 72, 73, + 32, 8, 136, 1, 18, 76, 76, 65, 76, 76, 65, 72, 79, 85, 32, 65, 76, 65, + 89, 72, 69, 32, 87, 166, 200, 29, 78, 142, 193, 5, 70, 237, 99, 2, 77, + 86, 2, 17, 2, 65, 83, 2, 229, 173, 15, 3, 83, 65, 76, 4, 140, 249, 19, + 12, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 78, 233, 205, 13, 2, 65, + 77, 106, 132, 1, 2, 70, 65, 32, 5, 72, 73, 71, 72, 32, 240, 11, 4, 76, + 79, 87, 32, 110, 75, 170, 238, 20, 68, 146, 208, 9, 89, 135, 181, 5, 87, + 4, 190, 3, 82, 219, 131, 35, 84, 74, 236, 2, 17, 68, 79, 84, 76, 69, 83, + 83, 32, 72, 69, 65, 68, 32, 79, 70, 32, 75, 22, 70, 102, 76, 142, 3, 77, + 116, 4, 78, 79, 79, 78, 18, 83, 78, 84, 38, 87, 196, 2, 3, 89, 69, 72, + 228, 128, 14, 18, 85, 80, 82, 73, 71, 72, 84, 32, 82, 69, 67, 84, 65, 78, + 71, 85, 76, 65, 196, 180, 8, 7, 82, 79, 85, 78, 68, 69, 68, 130, 122, 90, + 246, 104, 74, 214, 217, 11, 81, 223, 1, 65, 2, 251, 194, 29, 72, 4, 24, + 2, 65, 82, 31, 79, 2, 11, 83, 2, 175, 2, 73, 2, 181, 220, 25, 6, 79, 84, + 78, 79, 84, 69, 10, 60, 8, 73, 71, 65, 84, 85, 82, 69, 32, 213, 11, 2, + 65, 77, 8, 88, 10, 65, 76, 69, 70, 32, 87, 73, 84, 72, 32, 116, 3, 81, + 65, 70, 1, 3, 83, 65, 68, 4, 84, 8, 76, 65, 77, 32, 87, 73, 84, 72, 153, + 140, 35, 7, 89, 69, 72, 32, 66, 65, 82, 2, 181, 197, 30, 2, 32, 89, 2, + 89, 20, 32, 87, 73, 84, 72, 32, 76, 65, 77, 32, 87, 73, 84, 72, 32, 65, + 76, 69, 70, 32, 2, 225, 193, 21, 3, 77, 65, 75, 6, 26, 69, 215, 201, 15, + 65, 4, 17, 2, 69, 77, 4, 17, 2, 32, 73, 4, 22, 78, 135, 9, 83, 2, 197, 9, + 2, 73, 84, 5, 207, 4, 32, 6, 252, 254, 34, 7, 73, 71, 78, 32, 83, 65, 70, + 202, 38, 69, 227, 138, 1, 65, 4, 194, 243, 22, 72, 159, 129, 14, 65, 20, + 40, 4, 79, 82, 68, 32, 147, 247, 35, 65, 18, 74, 65, 172, 1, 2, 83, 65, + 200, 214, 24, 3, 87, 65, 81, 143, 155, 11, 81, 10, 228, 225, 6, 3, 76, + 45, 74, 236, 253, 17, 3, 82, 45, 82, 132, 196, 6, 7, 84, 72, 45, 84, 72, + 65, 76, 240, 207, 4, 5, 78, 45, 78, 73, 83, 137, 92, 5, 83, 45, 83, 65, + 74, 4, 218, 206, 36, 75, 207, 36, 72, 5, 149, 150, 10, 12, 32, 66, 65, + 82, 82, 69, 69, 32, 87, 73, 84, 72, 20, 68, 5, 78, 79, 79, 78, 32, 70, + 87, 206, 150, 24, 77, 239, 137, 11, 83, 2, 33, 6, 87, 73, 84, 72, 32, 75, + 2, 11, 65, 2, 151, 173, 36, 83, 14, 40, 4, 79, 82, 68, 32, 255, 242, 35, + 65, 12, 106, 73, 198, 194, 15, 77, 204, 135, 9, 3, 84, 65, 83, 212, 192, + 8, 2, 83, 65, 237, 172, 3, 3, 81, 65, 83, 4, 252, 230, 12, 2, 77, 65, + 177, 189, 18, 3, 83, 72, 77, 12, 138, 1, 66, 64, 3, 75, 85, 78, 177, 152, + 24, 22, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, 76, 69, 70, 32, 77, + 79, 75, 72, 65, 83, 83, 2, 33, 6, 83, 67, 82, 73, 80, 84, 2, 229, 204, + 21, 2, 32, 65, 9, 11, 32, 6, 34, 73, 58, 77, 255, 212, 34, 66, 2, 11, 83, + 2, 141, 239, 35, 6, 79, 76, 65, 84, 69, 68, 2, 11, 69, 2, 11, 68, 2, 11, + 73, 2, 189, 238, 35, 2, 65, 76, 34, 152, 1, 2, 68, 79, 114, 84, 224, 145, + 5, 8, 83, 77, 65, 76, 76, 32, 84, 65, 156, 229, 25, 4, 70, 79, 85, 82, + 228, 124, 4, 87, 65, 83, 76, 147, 166, 4, 82, 6, 88, 16, 85, 66, 76, 69, + 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, 159, 210, 34, 84, 2, 151, + 196, 34, 82, 16, 88, 10, 72, 82, 69, 69, 32, 68, 79, 84, 83, 32, 121, 8, + 87, 79, 32, 68, 79, 84, 83, 32, 8, 184, 246, 30, 17, 80, 79, 73, 78, 84, + 73, 78, 71, 32, 68, 79, 87, 78, 87, 65, 82, 68, 154, 219, 3, 66, 223, + 155, 1, 65, 8, 176, 208, 34, 10, 86, 69, 82, 84, 73, 67, 65, 76, 76, 89, + 42, 66, 223, 155, 1, 65, 30, 202, 1, 65, 152, 2, 4, 79, 78, 69, 32, 244, + 209, 10, 12, 82, 73, 80, 76, 69, 32, 68, 79, 84, 32, 80, 85, 152, 164, 6, + 8, 85, 82, 78, 69, 68, 32, 68, 65, 149, 222, 13, 8, 72, 79, 85, 83, 65, + 78, 68, 83, 12, 68, 5, 84, 87, 69, 69, 76, 157, 180, 9, 6, 73, 76, 32, + 70, 82, 65, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 112, 11, 79, 86, 69, + 82, 83, 84, 82, 85, 67, 75, 32, 184, 166, 5, 7, 70, 65, 84, 72, 65, 84, + 65, 131, 226, 4, 84, 4, 26, 72, 223, 230, 35, 87, 2, 197, 254, 28, 2, 65, + 77, 12, 68, 3, 79, 78, 69, 234, 159, 29, 84, 205, 171, 5, 4, 76, 79, 79, + 80, 4, 213, 245, 32, 2, 32, 68, 8, 64, 10, 79, 87, 69, 76, 32, 83, 73, + 71, 78, 32, 243, 178, 23, 69, 6, 72, 10, 73, 78, 86, 69, 82, 84, 69, 68, + 32, 83, 2, 83, 147, 236, 24, 68, 2, 25, 4, 77, 65, 76, 76, 2, 213, 229, + 35, 2, 32, 86, 28, 104, 4, 80, 69, 82, 32, 136, 214, 5, 3, 67, 85, 66, + 208, 128, 5, 5, 70, 79, 85, 82, 84, 211, 156, 24, 68, 4, 250, 182, 24, + 77, 31, 84, 188, 1, 222, 1, 65, 34, 67, 138, 3, 69, 60, 7, 83, 77, 65, + 76, 76, 32, 76, 240, 176, 20, 17, 77, 79, 68, 73, 70, 73, 69, 82, 32, 76, + 69, 84, 84, 69, 82, 32, 76, 222, 225, 8, 72, 184, 168, 2, 3, 68, 82, 65, + 218, 213, 2, 70, 83, 81, 4, 214, 215, 30, 66, 135, 26, 80, 78, 80, 14, + 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, 187, 147, 34, 79, + 76, 250, 1, 84, 36, 2, 89, 73, 150, 3, 67, 38, 82, 34, 69, 42, 71, 34, + 74, 38, 75, 22, 80, 38, 83, 106, 65, 22, 86, 158, 1, 76, 254, 161, 30, + 70, 2, 88, 170, 227, 1, 73, 134, 255, 2, 66, 2, 77, 234, 54, 78, 226, 26, + 90, 186, 96, 72, 190, 28, 68, 171, 1, 79, 4, 178, 139, 35, 73, 163, 209, + 1, 79, 5, 219, 140, 36, 87, 4, 216, 135, 25, 6, 77, 80, 72, 65, 83, 73, + 191, 233, 5, 88, 92, 76, 6, 69, 84, 84, 69, 82, 32, 157, 5, 8, 73, 71, + 65, 84, 85, 82, 69, 32, 80, 242, 1, 67, 38, 82, 34, 69, 42, 71, 34, 74, + 38, 75, 22, 80, 38, 83, 34, 84, 74, 65, 22, 86, 32, 2, 89, 73, 126, 76, + 254, 161, 30, 70, 2, 88, 170, 227, 1, 73, 134, 255, 2, 66, 2, 77, 234, + 54, 78, 226, 26, 90, 186, 96, 72, 190, 28, 68, 171, 1, 79, 8, 34, 72, + 250, 216, 36, 65, 3, 79, 4, 230, 215, 36, 69, 147, 1, 65, 6, 198, 215, + 36, 67, 146, 1, 72, 3, 84, 4, 142, 146, 36, 72, 203, 53, 73, 4, 238, 164, + 30, 72, 163, 179, 6, 65, 4, 207, 225, 32, 69, 4, 166, 217, 3, 73, 163, + 253, 32, 69, 4, 250, 212, 36, 72, 171, 1, 69, 6, 68, 7, 85, 82, 78, 69, + 68, 32, 65, 174, 133, 35, 73, 163, 209, 1, 79, 2, 167, 156, 35, 89, 4, + 166, 216, 35, 69, 147, 126, 79, 7, 222, 216, 20, 32, 231, 173, 15, 87, + 12, 84, 5, 69, 67, 72, 32, 89, 20, 4, 77, 69, 78, 32, 133, 136, 29, 4, + 86, 69, 87, 32, 2, 251, 131, 35, 73, 8, 230, 161, 30, 88, 170, 227, 1, + 73, 238, 181, 3, 78, 231, 119, 69, 14, 116, 10, 32, 80, 79, 73, 78, 84, + 73, 78, 71, 32, 177, 151, 35, 13, 72, 69, 65, 68, 45, 83, 72, 65, 80, 69, + 68, 32, 80, 12, 156, 2, 24, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 32, + 84, 72, 69, 78, 32, 67, 85, 82, 86, 73, 78, 71, 32, 48, 16, 85, 80, 87, + 65, 82, 68, 83, 32, 84, 72, 69, 78, 32, 78, 79, 82, 201, 248, 33, 22, 68, + 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, 72, 69, 78, 32, 67, 85, 82, 86, + 73, 78, 71, 6, 44, 3, 83, 79, 85, 210, 239, 25, 68, 35, 85, 2, 173, 173, + 28, 4, 84, 72, 32, 87, 4, 144, 135, 30, 10, 67, 85, 76, 65, 84, 69, 68, + 32, 76, 79, 137, 133, 5, 6, 83, 84, 32, 80, 65, 76, 20, 58, 67, 38, 84, + 146, 200, 22, 89, 241, 156, 9, 2, 83, 69, 4, 222, 141, 8, 69, 175, 128, + 11, 73, 12, 48, 4, 69, 82, 73, 83, 36, 2, 79, 78, 31, 82, 6, 238, 192, 2, + 75, 247, 141, 34, 77, 2, 209, 199, 13, 2, 73, 83, 4, 226, 254, 29, 65, + 189, 204, 4, 22, 79, 78, 79, 77, 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, + 76, 32, 70, 79, 82, 32, 85, 82, 4, 216, 219, 18, 6, 72, 76, 69, 84, 73, + 67, 189, 222, 16, 2, 79, 77, 10, 68, 2, 84, 79, 240, 142, 21, 2, 83, 84, + 185, 162, 2, 3, 66, 69, 82, 6, 54, 77, 201, 205, 35, 7, 32, 82, 73, 67, + 75, 83, 72, 4, 218, 176, 23, 79, 153, 182, 5, 12, 65, 84, 69, 68, 32, 84, + 69, 76, 76, 69, 82, 32, 112, 56, 6, 69, 83, 84, 65, 78, 32, 133, 196, 4, + 2, 79, 67, 110, 52, 7, 76, 69, 84, 84, 69, 82, 32, 167, 194, 30, 65, 108, + 234, 1, 65, 58, 71, 42, 72, 34, 78, 50, 88, 42, 83, 42, 89, 34, 84, 246, + 246, 32, 85, 158, 144, 1, 79, 182, 56, 73, 198, 134, 1, 66, 2, 68, 2, 90, + 246, 63, 69, 194, 41, 67, 2, 70, 2, 74, 2, 75, 2, 76, 2, 77, 2, 80, 2, + 82, 3, 86, 17, 254, 130, 34, 65, 158, 133, 2, 69, 150, 64, 78, 3, 79, 6, + 162, 177, 36, 71, 2, 72, 215, 22, 69, 4, 250, 176, 36, 77, 215, 22, 69, + 12, 46, 71, 174, 176, 36, 78, 2, 89, 215, 22, 69, 6, 170, 176, 36, 86, 2, + 89, 215, 22, 69, 8, 38, 72, 166, 153, 36, 83, 143, 45, 69, 4, 218, 175, + 36, 89, 215, 22, 69, 6, 186, 175, 36, 72, 2, 84, 215, 22, 69, 134, 37, + 178, 1, 65, 182, 169, 1, 69, 132, 16, 9, 72, 65, 73, 75, 83, 85, 75, 73, + 32, 198, 6, 73, 130, 3, 76, 186, 34, 79, 130, 55, 82, 138, 19, 85, 138, + 8, 89, 222, 139, 34, 80, 147, 1, 83, 182, 14, 132, 1, 2, 66, 89, 94, 67, + 206, 2, 68, 146, 1, 71, 106, 76, 140, 28, 4, 77, 85, 77, 32, 230, 114, + 78, 178, 1, 82, 98, 83, 223, 6, 84, 11, 11, 32, 8, 238, 188, 12, 67, 134, + 212, 5, 66, 204, 209, 13, 3, 65, 78, 71, 227, 205, 3, 83, 16, 62, 75, + 172, 223, 8, 5, 84, 82, 73, 65, 78, 139, 147, 27, 79, 12, 42, 32, 46, 83, + 229, 186, 10, 2, 45, 84, 4, 178, 220, 9, 87, 161, 145, 20, 2, 79, 70, 6, + 132, 1, 26, 76, 65, 78, 84, 69, 68, 32, 83, 79, 85, 84, 72, 32, 65, 82, + 82, 79, 87, 32, 87, 73, 84, 72, 32, 72, 79, 175, 131, 36, 80, 4, 150, + 215, 28, 82, 245, 130, 5, 2, 79, 75, 4, 188, 215, 33, 27, 77, 73, 78, 84, + 79, 78, 32, 82, 65, 67, 81, 85, 69, 84, 32, 65, 78, 68, 32, 83, 72, 85, + 84, 84, 76, 69, 67, 223, 170, 2, 71, 6, 228, 247, 29, 6, 85, 69, 84, 84, + 69, 32, 234, 189, 5, 69, 229, 6, 8, 71, 65, 71, 69, 32, 67, 76, 65, 150, + 2, 44, 6, 73, 78, 69, 83, 69, 32, 131, 24, 76, 248, 1, 188, 2, 6, 67, 65, + 82, 73, 75, 32, 104, 7, 76, 69, 84, 84, 69, 82, 32, 224, 8, 15, 77, 85, + 83, 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, 196, 6, 2, 80, 65, + 120, 5, 83, 73, 71, 78, 32, 180, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, + 71, 78, 32, 192, 246, 13, 5, 65, 68, 69, 71, 32, 162, 204, 18, 87, 219, + 247, 1, 68, 6, 32, 2, 80, 65, 255, 230, 2, 83, 4, 156, 130, 29, 5, 77, + 85, 78, 71, 75, 213, 231, 5, 3, 82, 69, 82, 110, 166, 2, 65, 112, 2, 66, + 65, 32, 2, 67, 65, 32, 2, 68, 65, 110, 69, 32, 2, 71, 65, 30, 73, 2, 79, + 2, 85, 36, 2, 74, 65, 30, 75, 68, 2, 76, 65, 18, 78, 72, 2, 80, 65, 36, + 2, 82, 65, 16, 2, 83, 65, 54, 84, 128, 1, 2, 86, 69, 0, 3, 90, 65, 76, + 170, 175, 36, 72, 2, 77, 2, 87, 3, 89, 10, 226, 2, 75, 184, 3, 5, 83, 89, + 85, 82, 65, 172, 243, 14, 8, 82, 67, 72, 65, 73, 67, 32, 74, 243, 217, 3, + 73, 5, 213, 165, 18, 3, 32, 75, 69, 5, 221, 192, 22, 3, 32, 76, 65, 9, + 17, 2, 32, 77, 6, 44, 5, 85, 82, 68, 65, 32, 175, 208, 32, 65, 4, 166, + 129, 14, 77, 25, 3, 65, 76, 80, 4, 254, 3, 70, 163, 237, 35, 75, 5, 185, + 202, 33, 2, 32, 71, 4, 11, 75, 4, 229, 14, 2, 65, 82, 5, 133, 169, 34, 2, + 32, 74, 8, 34, 65, 225, 2, 3, 72, 79, 84, 7, 222, 2, 70, 247, 252, 13, + 32, 7, 199, 12, 32, 8, 34, 65, 182, 177, 36, 71, 3, 89, 5, 221, 154, 26, + 4, 32, 82, 65, 77, 5, 157, 170, 35, 4, 32, 75, 65, 80, 7, 235, 11, 32, 7, + 21, 3, 32, 83, 65, 4, 194, 176, 36, 71, 3, 80, 10, 30, 65, 97, 3, 90, 73, + 82, 9, 11, 32, 6, 196, 253, 13, 6, 77, 85, 82, 68, 65, 32, 208, 7, 3, 76, + 65, 84, 151, 232, 17, 84, 2, 229, 249, 13, 2, 32, 83, 56, 168, 1, 10, 67, + 79, 77, 66, 73, 78, 73, 78, 71, 32, 246, 1, 68, 172, 1, 10, 76, 69, 70, + 84, 45, 72, 65, 78, 68, 32, 117, 11, 82, 73, 71, 72, 84, 45, 72, 65, 78, + 68, 32, 18, 132, 1, 4, 75, 69, 77, 80, 78, 74, 180, 181, 19, 2, 66, 69, + 136, 159, 7, 3, 69, 78, 68, 232, 166, 3, 3, 84, 69, 71, 195, 246, 3, 71, + 8, 32, 2, 76, 73, 1, 2, 85, 76, 5, 37, 7, 32, 87, 73, 84, 72, 32, 74, 2, + 225, 243, 13, 3, 69, 71, 79, 20, 50, 65, 90, 69, 174, 220, 35, 73, 2, 79, + 3, 85, 10, 40, 2, 78, 71, 218, 220, 35, 69, 3, 73, 7, 11, 32, 4, 158, 4, + 83, 227, 203, 10, 71, 4, 170, 220, 35, 85, 155, 80, 78, 10, 76, 6, 79, + 80, 69, 78, 32, 80, 113, 9, 67, 76, 79, 83, 69, 68, 32, 80, 76, 6, 186, + 219, 35, 65, 2, 73, 3, 85, 8, 72, 8, 67, 76, 79, 83, 69, 68, 32, 84, 29, + 6, 79, 80, 69, 78, 32, 68, 4, 158, 168, 36, 65, 3, 85, 4, 198, 170, 36, + 65, 3, 85, 10, 30, 77, 49, 3, 78, 84, 73, 6, 44, 3, 65, 68, 65, 129, 238, + 33, 2, 69, 78, 5, 233, 209, 35, 5, 32, 76, 65, 78, 84, 12, 110, 83, 20, + 4, 85, 76, 85, 32, 188, 240, 28, 3, 66, 73, 83, 150, 134, 1, 67, 153, + 248, 1, 4, 82, 69, 82, 69, 2, 247, 146, 24, 85, 4, 130, 245, 19, 67, 213, + 161, 16, 3, 82, 73, 67, 30, 120, 3, 76, 65, 32, 32, 3, 82, 65, 32, 12, 4, + 83, 85, 75, 85, 34, 84, 104, 5, 80, 69, 80, 69, 84, 53, 3, 85, 76, 85, 4, + 165, 1, 4, 76, 69, 78, 71, 4, 115, 82, 5, 233, 173, 35, 3, 32, 73, 76, + 10, 36, 5, 65, 76, 73, 78, 71, 99, 69, 9, 11, 32, 6, 18, 82, 55, 84, 4, + 17, 2, 69, 80, 4, 11, 65, 5, 17, 2, 32, 84, 2, 11, 69, 2, 131, 245, 29, + 68, 5, 133, 157, 29, 3, 32, 83, 65, 30, 86, 79, 164, 196, 22, 5, 32, 79, + 70, 32, 89, 245, 204, 12, 6, 69, 84, 32, 83, 72, 79, 26, 32, 2, 79, 78, + 21, 2, 84, 32, 5, 199, 147, 34, 45, 22, 44, 2, 66, 79, 246, 1, 83, 159, + 162, 36, 88, 18, 38, 88, 205, 1, 4, 76, 68, 32, 83, 17, 33, 6, 32, 87, + 73, 84, 72, 32, 14, 82, 66, 86, 83, 140, 167, 12, 4, 76, 73, 71, 72, 210, + 145, 10, 67, 195, 233, 13, 88, 6, 52, 4, 79, 76, 68, 32, 141, 210, 35, 3, + 65, 76, 76, 4, 26, 83, 223, 184, 22, 67, 2, 137, 167, 12, 4, 67, 82, 73, + 80, 162, 10, 120, 2, 67, 79, 180, 1, 7, 76, 69, 84, 84, 69, 82, 32, 248, + 91, 3, 78, 74, 65, 186, 234, 27, 83, 146, 142, 5, 70, 83, 81, 8, 26, 77, + 255, 208, 35, 76, 6, 72, 12, 66, 73, 78, 73, 78, 71, 32, 77, 65, 82, 75, + 32, 219, 157, 36, 77, 4, 168, 137, 21, 6, 84, 85, 75, 87, 69, 78, 241, + 165, 3, 4, 75, 79, 81, 78, 146, 10, 170, 1, 70, 58, 75, 170, 1, 76, 66, + 77, 102, 78, 234, 1, 80, 206, 103, 82, 102, 83, 134, 1, 84, 54, 89, 202, + 193, 2, 87, 166, 215, 32, 69, 214, 22, 65, 2, 73, 2, 79, 3, 85, 8, 226, + 79, 65, 222, 183, 35, 69, 254, 5, 79, 219, 16, 85, 22, 78, 69, 46, 79, + 174, 176, 34, 89, 254, 233, 1, 80, 186, 2, 65, 2, 73, 3, 85, 6, 254, 144, + 35, 85, 142, 140, 1, 78, 3, 84, 7, 218, 173, 34, 86, 161, 222, 1, 2, 71, + 72, 10, 194, 102, 69, 190, 162, 25, 79, 182, 147, 10, 65, 2, 73, 3, 85, + 19, 62, 69, 166, 101, 66, 146, 182, 35, 65, 2, 73, 2, 79, 3, 85, 4, 254, + 174, 34, 69, 183, 236, 1, 78, 30, 102, 71, 50, 74, 50, 84, 150, 101, 85, + 250, 188, 33, 83, 246, 7, 68, 242, 219, 1, 89, 218, 19, 65, 3, 73, 6, + 178, 223, 31, 75, 190, 184, 4, 71, 187, 2, 65, 6, 222, 236, 25, 85, 198, + 150, 10, 69, 171, 4, 65, 4, 222, 244, 35, 85, 151, 14, 69, 254, 8, 76, 5, + 72, 65, 83, 69, 45, 210, 100, 69, 138, 2, 85, 254, 177, 35, 65, 3, 73, + 242, 8, 116, 2, 65, 32, 160, 18, 2, 66, 32, 136, 13, 2, 67, 32, 160, 20, + 2, 68, 32, 172, 18, 2, 69, 32, 137, 25, 2, 70, 32, 174, 1, 158, 1, 71, + 106, 75, 130, 1, 76, 102, 77, 190, 3, 78, 210, 4, 80, 146, 2, 83, 190, 2, + 84, 154, 1, 85, 144, 253, 28, 2, 70, 73, 182, 156, 5, 86, 211, 219, 1, + 82, 6, 60, 5, 72, 69, 85, 65, 69, 173, 46, 5, 66, 73, 69, 69, 32, 4, 168, + 27, 2, 71, 72, 179, 205, 25, 82, 12, 38, 65, 34, 69, 142, 67, 80, 3, 85, + 4, 234, 146, 36, 70, 187, 2, 81, 4, 132, 192, 26, 5, 85, 75, 69, 85, 84, + 255, 212, 9, 84, 10, 78, 85, 222, 65, 79, 224, 190, 25, 2, 65, 80, 129, + 154, 9, 4, 69, 84, 32, 75, 5, 243, 185, 26, 65, 34, 142, 1, 65, 168, 1, + 2, 66, 65, 38, 79, 76, 6, 86, 69, 85, 65, 69, 78, 244, 70, 8, 69, 85, 78, + 74, 79, 77, 78, 68, 157, 152, 33, 2, 71, 66, 18, 62, 69, 164, 49, 2, 78, + 83, 149, 253, 30, 4, 80, 32, 80, 73, 14, 58, 77, 242, 254, 11, 75, 246, + 134, 7, 78, 163, 248, 16, 83, 9, 178, 24, 66, 206, 44, 86, 183, 248, 26, + 75, 4, 182, 133, 19, 78, 251, 139, 17, 81, 6, 36, 2, 79, 77, 237, 1, 2, + 78, 32, 4, 250, 207, 12, 80, 171, 199, 22, 69, 2, 131, 215, 34, 71, 48, + 122, 65, 32, 2, 68, 65, 54, 71, 98, 75, 32, 2, 83, 72, 38, 84, 102, 89, + 74, 90, 210, 210, 34, 74, 234, 105, 69, 239, 70, 73, 4, 250, 8, 65, 183, + 134, 36, 81, 4, 22, 65, 159, 22, 32, 2, 153, 44, 3, 78, 71, 71, 8, 52, 3, + 75, 85, 69, 222, 202, 31, 65, 215, 242, 2, 71, 4, 250, 7, 32, 181, 239, + 11, 2, 78, 90, 4, 246, 25, 65, 147, 253, 18, 73, 4, 166, 161, 34, 73, + 183, 236, 1, 65, 8, 40, 2, 65, 80, 229, 184, 27, 2, 79, 81, 7, 11, 32, 4, + 180, 157, 34, 2, 77, 70, 1, 2, 78, 84, 6, 26, 73, 143, 240, 35, 69, 5, + 193, 13, 7, 84, 32, 77, 79, 78, 71, 75, 4, 214, 5, 65, 245, 243, 11, 4, + 85, 78, 32, 77, 22, 58, 65, 80, 3, 79, 78, 32, 166, 238, 35, 69, 163, 28, + 85, 10, 42, 65, 154, 18, 32, 250, 17, 77, 15, 83, 4, 218, 221, 25, 82, + 155, 173, 10, 77, 8, 56, 4, 77, 70, 79, 78, 1, 6, 80, 65, 32, 78, 74, 73, + 4, 37, 7, 32, 80, 73, 80, 65, 69, 77, 4, 206, 16, 71, 231, 246, 35, 66, + 22, 70, 72, 194, 1, 79, 192, 66, 2, 69, 85, 158, 160, 35, 85, 167, 34, + 73, 10, 74, 73, 70, 85, 129, 224, 34, 10, 79, 81, 32, 78, 83, 72, 85, 84, + 32, 89, 4, 158, 219, 25, 82, 233, 194, 6, 8, 78, 68, 65, 32, 80, 65, 32, + 78, 4, 188, 11, 4, 69, 78, 83, 72, 183, 252, 35, 77, 6, 132, 206, 34, 2, + 78, 74, 190, 185, 1, 81, 3, 84, 10, 44, 2, 69, 85, 44, 3, 73, 84, 65, 31, + 85, 4, 234, 181, 34, 65, 1, 4, 84, 69, 85, 87, 2, 11, 32, 2, 223, 30, 77, + 4, 186, 26, 32, 215, 145, 26, 65, 4, 228, 3, 5, 32, 89, 85, 81, 32, 145, + 130, 27, 3, 78, 75, 78, 112, 164, 1, 7, 71, 72, 69, 85, 71, 72, 69, 34, + 75, 126, 76, 122, 77, 154, 3, 78, 234, 2, 80, 90, 83, 178, 1, 84, 106, + 89, 190, 22, 87, 204, 46, 2, 70, 69, 147, 157, 11, 86, 4, 198, 56, 85, + 203, 203, 35, 78, 12, 40, 2, 69, 85, 50, 73, 191, 242, 35, 65, 6, 230, + 54, 89, 246, 139, 12, 80, 191, 174, 23, 65, 4, 230, 240, 35, 69, 175, 18, + 81, 8, 46, 65, 240, 69, 2, 79, 77, 171, 160, 35, 69, 4, 50, 65, 129, 61, + 7, 77, 32, 78, 83, 72, 85, 84, 2, 247, 212, 25, 78, 26, 70, 65, 74, 66, + 140, 1, 2, 69, 85, 58, 70, 145, 23, 3, 79, 78, 84, 7, 21, 3, 32, 78, 74, + 4, 194, 134, 18, 85, 137, 192, 16, 3, 69, 85, 65, 10, 90, 65, 154, 46, + 85, 144, 201, 28, 2, 69, 85, 173, 182, 6, 7, 73, 84, 32, 77, 66, 65, 65, + 4, 150, 12, 65, 245, 242, 18, 4, 32, 77, 65, 69, 4, 252, 155, 31, 5, 84, + 32, 78, 71, 71, 227, 227, 4, 81, 4, 48, 4, 79, 78, 32, 84, 181, 235, 25, + 2, 73, 89, 2, 163, 65, 69, 24, 110, 71, 166, 1, 83, 50, 89, 152, 23, 8, + 84, 73, 69, 69, 32, 83, 72, 69, 193, 245, 33, 5, 68, 85, 32, 78, 74, 12, + 70, 71, 168, 132, 35, 8, 75, 73, 78, 68, 73, 32, 77, 86, 175, 104, 79, 8, + 60, 3, 85, 79, 81, 216, 133, 19, 2, 69, 85, 219, 189, 15, 65, 5, 137, + 208, 27, 2, 32, 76, 4, 26, 72, 227, 172, 35, 69, 2, 167, 199, 35, 85, 4, + 248, 45, 2, 65, 69, 211, 17, 73, 8, 152, 155, 10, 2, 69, 69, 210, 130, + 12, 65, 160, 146, 8, 3, 85, 78, 71, 199, 175, 5, 73, 12, 88, 2, 65, 75, + 16, 2, 72, 69, 160, 236, 18, 2, 69, 84, 230, 161, 15, 73, 227, 213, 1, + 85, 2, 211, 25, 69, 4, 244, 230, 25, 4, 84, 32, 78, 74, 129, 239, 4, 4, + 85, 65, 69, 81, 6, 32, 2, 85, 32, 151, 192, 34, 65, 4, 36, 4, 77, 65, 69, + 77, 139, 7, 78, 2, 11, 71, 2, 135, 7, 66, 4, 44, 4, 65, 70, 85, 32, 229, + 4, 2, 69, 85, 2, 221, 179, 31, 6, 76, 69, 69, 82, 65, 69, 196, 1, 170, 1, + 71, 82, 75, 206, 2, 76, 50, 77, 250, 3, 78, 238, 6, 80, 78, 83, 118, 84, + 176, 1, 3, 86, 69, 85, 46, 87, 62, 89, 250, 179, 29, 66, 166, 208, 2, 70, + 247, 187, 3, 82, 6, 40, 2, 72, 65, 221, 234, 18, 2, 66, 65, 4, 186, 201, + 25, 82, 155, 173, 10, 80, 22, 66, 69, 182, 1, 85, 248, 224, 25, 3, 80, + 65, 82, 139, 145, 10, 65, 14, 40, 2, 78, 32, 54, 85, 143, 245, 35, 84, 4, + 212, 148, 32, 4, 70, 65, 84, 73, 207, 226, 2, 76, 8, 42, 83, 162, 225, + 25, 75, 195, 147, 10, 77, 4, 232, 14, 3, 72, 69, 85, 239, 53, 69, 4, 48, + 6, 79, 80, 32, 78, 75, 65, 135, 244, 35, 84, 2, 11, 65, 2, 223, 198, 25, + 82, 8, 202, 47, 65, 230, 176, 25, 73, 183, 147, 10, 85, 38, 82, 65, 130, + 1, 66, 202, 196, 25, 85, 216, 25, 4, 71, 66, 65, 83, 143, 167, 8, 73, 8, + 18, 32, 79, 69, 4, 42, 78, 209, 159, 17, 4, 75, 69, 85, 65, 2, 11, 83, 2, + 223, 133, 34, 73, 4, 214, 196, 35, 77, 211, 25, 83, 24, 34, 65, 114, 69, + 82, 73, 35, 85, 6, 32, 2, 65, 32, 163, 229, 18, 78, 4, 204, 219, 30, 8, + 67, 65, 66, 66, 65, 71, 69, 45, 129, 195, 4, 2, 80, 73, 8, 50, 85, 130, + 195, 25, 82, 185, 201, 5, 2, 69, 75, 4, 150, 240, 35, 77, 3, 88, 7, 226, + 7, 82, 155, 232, 35, 84, 4, 174, 221, 35, 65, 175, 18, 69, 72, 130, 1, + 65, 54, 68, 110, 71, 222, 1, 74, 102, 83, 130, 1, 84, 102, 90, 237, 7, + 12, 89, 73, 82, 32, 77, 75, 80, 65, 82, 65, 81, 32, 4, 244, 218, 25, 4, + 78, 83, 65, 78, 195, 147, 10, 81, 12, 60, 2, 69, 85, 174, 41, 65, 146, + 205, 18, 79, 135, 210, 16, 73, 4, 128, 129, 34, 2, 65, 69, 195, 236, 1, + 84, 20, 50, 71, 98, 75, 210, 216, 25, 65, 223, 130, 10, 79, 12, 26, 85, + 247, 156, 35, 69, 11, 180, 39, 3, 65, 69, 78, 190, 245, 34, 79, 202, 26, + 69, 143, 53, 77, 4, 36, 3, 85, 69, 32, 171, 216, 25, 65, 2, 145, 230, 18, + 3, 77, 65, 69, 10, 34, 65, 34, 69, 255, 169, 12, 85, 4, 190, 218, 35, 69, + 219, 16, 77, 4, 194, 254, 33, 69, 171, 96, 85, 12, 78, 85, 202, 214, 25, + 72, 216, 216, 5, 2, 69, 85, 146, 170, 4, 79, 219, 16, 65, 4, 212, 214, + 35, 4, 79, 84, 32, 78, 179, 19, 78, 8, 54, 69, 232, 204, 35, 4, 85, 32, + 77, 66, 131, 26, 65, 4, 204, 225, 18, 2, 85, 78, 211, 135, 17, 78, 4, + 254, 192, 34, 69, 247, 167, 1, 65, 6, 26, 73, 227, 152, 35, 69, 4, 26, + 82, 155, 232, 35, 78, 2, 151, 151, 34, 73, 10, 30, 69, 50, 72, 255, 6, + 85, 4, 26, 84, 191, 219, 34, 85, 2, 231, 151, 35, 70, 4, 182, 166, 12, + 85, 203, 173, 13, 73, 10, 40, 2, 65, 65, 34, 69, 41, 2, 73, 84, 2, 11, + 83, 2, 191, 185, 25, 72, 4, 228, 25, 2, 85, 84, 223, 204, 35, 84, 4, 38, + 85, 153, 133, 32, 3, 65, 32, 89, 2, 235, 139, 26, 65, 4, 180, 145, 27, 2, + 65, 69, 171, 212, 8, 88, 4, 40, 4, 65, 78, 71, 75, 255, 228, 35, 85, 2, + 143, 19, 85, 10, 42, 85, 230, 163, 12, 69, 179, 190, 23, 65, 6, 210, 18, + 87, 212, 3, 4, 32, 77, 85, 79, 167, 206, 35, 77, 234, 1, 134, 1, 70, 68, + 2, 71, 72, 34, 75, 254, 1, 76, 142, 1, 77, 130, 3, 78, 130, 5, 80, 122, + 82, 90, 83, 190, 1, 84, 158, 1, 87, 39, 89, 4, 36, 3, 69, 85, 70, 167, + 224, 35, 65, 2, 11, 69, 2, 151, 2, 85, 4, 202, 1, 69, 191, 222, 35, 65, + 22, 46, 69, 146, 1, 85, 42, 87, 135, 244, 33, 89, 10, 26, 85, 215, 225, + 35, 84, 8, 72, 3, 65, 69, 84, 20, 5, 79, 84, 32, 77, 66, 246, 224, 35, + 77, 3, 80, 2, 251, 205, 11, 77, 2, 219, 179, 25, 85, 9, 134, 208, 35, 79, + 218, 16, 78, 3, 81, 2, 171, 171, 35, 65, 14, 58, 69, 182, 204, 25, 79, + 130, 167, 8, 73, 223, 219, 1, 85, 8, 42, 85, 138, 243, 33, 69, 183, 236, + 1, 84, 4, 178, 133, 26, 65, 139, 218, 9, 77, 41, 94, 65, 58, 66, 66, 69, + 38, 70, 80, 2, 71, 66, 214, 140, 31, 79, 246, 214, 3, 86, 135, 121, 85, + 4, 228, 139, 17, 2, 76, 69, 197, 157, 18, 3, 69, 78, 74, 6, 32, 2, 65, + 65, 235, 190, 35, 85, 5, 237, 130, 28, 2, 32, 83, 6, 250, 226, 17, 85, + 147, 142, 16, 69, 10, 44, 2, 69, 85, 238, 228, 33, 79, 207, 11, 73, 4, + 150, 198, 35, 65, 215, 22, 84, 6, 150, 240, 33, 73, 192, 68, 2, 79, 70, + 223, 39, 69, 72, 78, 68, 46, 71, 226, 1, 74, 98, 83, 110, 84, 34, 89, + 210, 215, 35, 73, 3, 85, 8, 194, 39, 69, 178, 228, 34, 79, 255, 62, 65, + 24, 18, 71, 99, 75, 12, 54, 65, 202, 42, 69, 162, 245, 30, 87, 135, 170, + 4, 85, 6, 152, 38, 2, 65, 77, 183, 180, 35, 80, 12, 68, 2, 69, 85, 174, + 237, 33, 73, 2, 89, 226, 156, 1, 85, 203, 79, 65, 4, 226, 152, 12, 65, + 167, 173, 23, 82, 12, 60, 2, 69, 85, 230, 15, 73, 158, 136, 12, 85, 243, + 192, 23, 65, 4, 206, 198, 35, 65, 175, 18, 84, 10, 46, 72, 32, 3, 73, 69, + 69, 183, 199, 35, 85, 4, 254, 187, 35, 85, 219, 5, 69, 4, 138, 216, 35, + 80, 3, 84, 6, 130, 14, 69, 135, 165, 35, 85, 8, 162, 187, 35, 69, 218, 5, + 85, 254, 5, 65, 219, 16, 73, 12, 42, 69, 46, 85, 182, 214, 35, 65, 3, 73, + 4, 208, 169, 25, 2, 85, 84, 155, 173, 10, 69, 4, 146, 186, 35, 85, 175, + 28, 81, 8, 48, 3, 69, 78, 32, 150, 194, 35, 73, 175, 1, 65, 4, 214, 240, + 25, 79, 227, 194, 9, 77, 26, 58, 72, 90, 85, 186, 16, 65, 174, 6, 69, + 167, 161, 35, 79, 12, 54, 69, 162, 193, 25, 79, 222, 255, 9, 73, 219, 19, + 85, 6, 214, 7, 85, 255, 204, 35, 69, 6, 222, 189, 35, 65, 214, 22, 69, 3, + 85, 18, 62, 69, 74, 85, 210, 191, 25, 79, 226, 252, 9, 65, 215, 22, 73, + 8, 26, 85, 255, 230, 33, 69, 6, 186, 130, 34, 65, 246, 208, 1, 78, 3, 84, + 5, 215, 182, 35, 79, 4, 134, 152, 31, 85, 223, 186, 4, 65, 10, 40, 2, 65, + 69, 18, 85, 191, 130, 35, 69, 2, 251, 3, 77, 6, 22, 87, 227, 13, 79, 2, + 195, 190, 25, 79, 186, 2, 178, 1, 70, 154, 1, 71, 202, 1, 75, 170, 1, 76, + 158, 1, 77, 134, 2, 78, 190, 7, 80, 166, 2, 82, 78, 83, 166, 1, 84, 246, + 1, 86, 66, 87, 34, 89, 226, 186, 35, 65, 2, 73, 3, 79, 18, 54, 85, 218, + 172, 22, 65, 202, 140, 13, 69, 255, 5, 79, 10, 26, 32, 231, 154, 30, 69, + 6, 148, 143, 23, 4, 82, 69, 77, 69, 134, 188, 10, 67, 191, 132, 2, 73, + 16, 24, 2, 66, 69, 39, 72, 4, 234, 194, 34, 85, 143, 140, 1, 84, 12, 34, + 65, 34, 69, 187, 189, 35, 79, 2, 11, 65, 2, 139, 161, 25, 77, 8, 26, 85, + 247, 205, 35, 84, 6, 158, 183, 35, 65, 214, 22, 78, 3, 88, 18, 50, 69, + 62, 80, 18, 85, 206, 204, 35, 73, 3, 79, 6, 26, 85, 255, 204, 35, 84, 4, + 166, 182, 35, 65, 215, 22, 88, 2, 211, 28, 69, 6, 158, 176, 35, 69, 162, + 28, 79, 15, 84, 18, 50, 65, 40, 2, 69, 85, 22, 79, 183, 203, 35, 85, 6, + 150, 187, 35, 65, 218, 16, 80, 3, 81, 2, 155, 185, 35, 65, 8, 238, 208, + 17, 79, 198, 250, 17, 77, 3, 81, 32, 110, 65, 44, 2, 66, 69, 34, 70, 20, + 2, 71, 66, 34, 73, 130, 156, 25, 85, 198, 221, 9, 69, 2, 79, 255, 59, 86, + 11, 234, 164, 17, 69, 174, 165, 18, 80, 3, 81, 4, 146, 185, 35, 85, 219, + 16, 69, 2, 227, 136, 12, 69, 4, 226, 249, 34, 69, 215, 79, 65, 5, 195, + 178, 35, 69, 80, 114, 68, 170, 1, 71, 138, 3, 74, 112, 2, 83, 72, 58, 84, + 32, 3, 89, 73, 32, 54, 90, 210, 129, 35, 65, 179, 47, 75, 12, 34, 65, 98, + 73, 187, 247, 34, 85, 6, 32, 2, 65, 32, 203, 199, 35, 80, 4, 128, 215, + 17, 3, 77, 89, 32, 249, 140, 13, 3, 83, 79, 70, 4, 214, 179, 25, 65, 183, + 147, 10, 81, 36, 78, 71, 50, 85, 122, 75, 118, 79, 188, 177, 11, 3, 69, + 85, 82, 195, 146, 24, 65, 12, 18, 69, 51, 85, 6, 26, 85, 183, 217, 33, + 69, 4, 199, 187, 23, 65, 6, 64, 6, 65, 69, 83, 72, 65, 69, 250, 151, 25, + 82, 155, 173, 10, 80, 2, 11, 32, 2, 203, 231, 22, 78, 12, 34, 65, 20, 2, + 69, 85, 35, 85, 5, 231, 176, 35, 65, 4, 138, 178, 35, 65, 175, 18, 88, 4, + 150, 196, 35, 77, 3, 80, 4, 250, 195, 35, 80, 3, 81, 8, 18, 65, 31, 69, + 2, 201, 244, 30, 2, 69, 77, 6, 26, 69, 139, 183, 34, 85, 5, 233, 160, 35, + 4, 32, 69, 80, 79, 6, 26, 85, 163, 214, 33, 73, 4, 198, 194, 35, 79, 15, + 69, 4, 222, 177, 35, 85, 207, 16, 65, 4, 128, 190, 25, 4, 67, 76, 69, 65, + 247, 240, 1, 66, 4, 174, 174, 25, 65, 3, 85, 34, 42, 65, 90, 69, 58, 73, + 50, 79, 23, 85, 8, 32, 2, 32, 80, 207, 155, 17, 65, 4, 152, 176, 27, 2, + 69, 79, 169, 135, 7, 2, 76, 85, 6, 26, 85, 211, 175, 35, 69, 4, 166, 192, + 35, 84, 3, 88, 7, 11, 69, 4, 202, 172, 25, 69, 183, 147, 10, 84, 5, 135, + 240, 34, 79, 11, 82, 65, 246, 190, 35, 69, 3, 77, 8, 46, 65, 238, 14, 69, + 185, 168, 18, 2, 73, 77, 4, 242, 190, 35, 69, 3, 81, 18, 62, 69, 30, 72, + 150, 131, 31, 85, 146, 170, 4, 79, 163, 14, 65, 4, 150, 190, 35, 69, 3, + 84, 8, 42, 69, 182, 154, 22, 79, 235, 143, 3, 73, 2, 209, 252, 11, 2, 85, + 65, 28, 34, 65, 94, 69, 50, 79, 39, 85, 10, 56, 2, 69, 78, 186, 153, 22, + 65, 158, 163, 13, 77, 3, 81, 2, 221, 165, 11, 3, 32, 78, 84, 6, 26, 85, + 155, 188, 35, 78, 5, 155, 251, 11, 65, 6, 130, 196, 33, 79, 131, 248, 1, + 81, 6, 170, 7, 77, 227, 157, 35, 65, 6, 26, 69, 207, 170, 35, 79, 4, 138, + 142, 25, 85, 155, 173, 10, 69, 6, 246, 10, 69, 255, 203, 31, 85, 26, 68, + 2, 69, 85, 46, 73, 32, 3, 79, 81, 32, 54, 85, 143, 185, 35, 65, 8, 246, + 175, 23, 65, 162, 138, 12, 77, 3, 88, 4, 150, 163, 35, 69, 215, 22, 84, + 4, 248, 150, 12, 4, 83, 87, 73, 77, 223, 162, 9, 67, 8, 226, 165, 25, 69, + 194, 194, 8, 65, 246, 208, 1, 78, 3, 81, 108, 162, 1, 75, 82, 76, 46, 77, + 98, 78, 190, 1, 80, 66, 82, 50, 83, 110, 84, 38, 89, 170, 196, 2, 87, + 252, 172, 9, 2, 86, 85, 170, 170, 23, 69, 242, 5, 70, 231, 16, 85, 14, + 242, 188, 17, 69, 146, 142, 16, 89, 254, 233, 1, 80, 186, 2, 65, 2, 79, + 3, 85, 6, 178, 163, 25, 79, 182, 147, 10, 65, 3, 73, 13, 42, 66, 34, 69, + 242, 181, 35, 65, 3, 79, 4, 186, 230, 34, 69, 159, 77, 65, 2, 187, 201, + 33, 69, 22, 94, 71, 38, 74, 38, 85, 250, 188, 33, 83, 246, 7, 68, 150, 3, + 84, 222, 216, 1, 89, 219, 19, 73, 4, 134, 250, 30, 75, 191, 184, 4, 71, + 4, 190, 135, 25, 85, 239, 154, 10, 65, 5, 223, 157, 35, 65, 6, 26, 69, + 239, 134, 25, 85, 4, 246, 167, 34, 85, 143, 140, 1, 69, 12, 186, 2, 69, + 154, 231, 8, 73, 143, 202, 26, 85, 14, 66, 72, 230, 2, 69, 194, 170, 18, + 65, 226, 224, 16, 85, 235, 36, 73, 6, 146, 159, 35, 73, 218, 19, 79, 3, + 85, 6, 186, 190, 20, 65, 223, 215, 14, 69, 4, 234, 158, 25, 79, 183, 147, + 10, 65, 4, 166, 155, 35, 65, 215, 22, 69, 14, 54, 69, 154, 231, 8, 73, + 186, 179, 26, 65, 215, 22, 85, 6, 150, 165, 34, 85, 142, 140, 1, 69, 3, + 78, 16, 62, 72, 50, 69, 194, 170, 18, 65, 226, 224, 16, 85, 235, 36, 73, + 8, 46, 69, 178, 156, 35, 73, 218, 19, 79, 3, 85, 2, 251, 163, 34, 85, 10, + 174, 181, 17, 69, 190, 134, 3, 65, 139, 244, 14, 73, 6, 138, 156, 25, 79, + 2, 85, 183, 147, 10, 65, 14, 42, 75, 166, 244, 33, 65, 211, 155, 1, 74, + 11, 49, 10, 78, 79, 84, 69, 32, 87, 73, 84, 72, 32, 8, 224, 173, 9, 2, + 80, 79, 190, 1, 89, 188, 131, 12, 2, 69, 85, 147, 156, 6, 68, 6, 38, 32, + 237, 172, 16, 3, 66, 69, 82, 4, 170, 226, 28, 67, 189, 186, 5, 5, 79, 70, + 32, 83, 79, 78, 72, 3, 75, 69, 84, 60, 7, 83, 65, 32, 86, 65, 72, 32, + 183, 167, 33, 69, 5, 241, 218, 15, 10, 66, 65, 76, 76, 32, 65, 78, 68, + 32, 72, 72, 104, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 164, 1, 7, + 76, 69, 84, 84, 69, 82, 32, 235, 222, 32, 70, 10, 52, 4, 72, 73, 71, 72, + 44, 3, 76, 79, 87, 39, 77, 4, 172, 140, 21, 2, 45, 76, 251, 207, 10, 32, + 4, 32, 2, 45, 77, 219, 219, 31, 32, 2, 201, 219, 31, 2, 73, 68, 60, 238, + 1, 68, 38, 69, 38, 71, 34, 75, 38, 85, 20, 2, 87, 65, 22, 89, 128, 238, + 27, 2, 72, 87, 154, 196, 2, 77, 178, 181, 2, 79, 154, 154, 2, 86, 246, 5, + 74, 2, 84, 2, 90, 162, 8, 67, 2, 83, 158, 20, 66, 2, 70, 2, 80, 186, 2, + 65, 3, 73, 4, 222, 235, 32, 72, 159, 188, 2, 79, 7, 222, 215, 30, 78, + 251, 207, 4, 69, 4, 202, 130, 35, 66, 219, 35, 65, 4, 202, 238, 27, 80, + 203, 184, 7, 65, 5, 135, 130, 35, 87, 5, 215, 129, 35, 68, 4, 138, 167, + 34, 69, 235, 104, 73, 121, 48, 3, 65, 75, 32, 230, 10, 72, 179, 218, 21, + 84, 112, 196, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, + 78, 32, 28, 7, 76, 69, 84, 84, 69, 82, 32, 248, 4, 3, 80, 65, 78, 50, 83, + 141, 2, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 4, 214, 163, 35, + 78, 87, 72, 76, 194, 1, 77, 114, 78, 68, 2, 80, 65, 38, 83, 232, 144, 18, + 4, 75, 65, 82, 79, 214, 141, 17, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, + 2, 76, 2, 82, 2, 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 10, 26, 65, 251, + 159, 35, 66, 9, 45, 9, 78, 68, 65, 73, 76, 73, 78, 71, 32, 6, 198, 159, + 35, 72, 2, 78, 3, 83, 10, 152, 2, 2, 79, 82, 138, 157, 35, 68, 2, 71, 2, + 89, 187, 2, 65, 5, 189, 165, 20, 4, 75, 80, 65, 75, 24, 80, 10, 73, 77, + 65, 76, 85, 78, 71, 85, 78, 32, 96, 2, 79, 85, 195, 159, 35, 65, 20, 230, + 157, 35, 71, 2, 72, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 87, 2, 89, 187, + 2, 65, 2, 145, 145, 18, 5, 84, 72, 69, 82, 78, 4, 166, 2, 71, 161, 145, + 18, 4, 79, 78, 71, 79, 10, 96, 12, 89, 77, 66, 79, 76, 32, 66, 73, 78, + 68, 85, 32, 193, 140, 10, 6, 73, 71, 78, 32, 84, 79, 8, 78, 80, 152, 243, + 10, 3, 74, 85, 68, 249, 166, 24, 6, 78, 65, 32, 77, 69, 84, 4, 64, 3, 65, + 78, 71, 133, 199, 22, 7, 73, 78, 65, 82, 66, 79, 82, 2, 139, 131, 25, 79, + 18, 122, 85, 228, 173, 25, 6, 80, 65, 75, 80, 65, 75, 180, 248, 2, 5, 75, + 65, 82, 79, 32, 182, 181, 6, 69, 150, 64, 73, 3, 79, 5, 177, 200, 29, 15, + 32, 70, 79, 82, 32, 83, 73, 77, 65, 76, 85, 78, 71, 85, 78, 5, 143, 134, + 23, 84, 254, 1, 134, 1, 65, 230, 2, 69, 50, 76, 130, 1, 78, 198, 10, 84, + 144, 220, 31, 2, 67, 65, 204, 162, 2, 5, 86, 69, 82, 65, 71, 191, 140, 1, + 68, 20, 136, 1, 4, 77, 69, 68, 32, 170, 1, 82, 164, 143, 3, 10, 67, 72, + 32, 87, 73, 84, 72, 32, 85, 77, 210, 144, 7, 84, 234, 185, 24, 86, 19, + 78, 8, 86, 65, 0, 2, 68, 69, 52, 4, 69, 73, 71, 72, 1, 7, 83, 73, 88, 84, + 69, 69, 78, 2, 201, 214, 19, 8, 83, 67, 69, 78, 68, 73, 78, 71, 2, 193, + 214, 19, 2, 84, 72, 4, 128, 196, 28, 3, 68, 69, 68, 179, 150, 6, 32, 4, + 176, 166, 8, 3, 82, 32, 77, 183, 207, 25, 84, 13, 11, 76, 11, 38, 32, + 217, 187, 24, 3, 72, 79, 80, 6, 162, 140, 12, 80, 212, 232, 15, 6, 87, + 73, 84, 72, 32, 67, 187, 142, 6, 83, 208, 1, 84, 5, 71, 65, 76, 73, 32, + 162, 9, 84, 37, 9, 90, 69, 78, 69, 32, 82, 73, 78, 71, 200, 1, 210, 1, + 65, 44, 9, 67, 85, 82, 82, 69, 78, 67, 89, 32, 148, 2, 7, 76, 69, 84, 84, + 69, 82, 32, 204, 3, 6, 82, 85, 80, 69, 69, 32, 34, 83, 242, 128, 22, 73, + 130, 4, 86, 242, 153, 11, 68, 141, 105, 3, 71, 65, 78, 6, 190, 147, 30, + 85, 138, 149, 1, 66, 51, 78, 12, 120, 10, 78, 85, 77, 69, 82, 65, 84, 79, + 82, 32, 221, 212, 22, 14, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 82, 32, + 83, 73, 10, 52, 3, 79, 78, 69, 214, 170, 30, 70, 155, 250, 2, 84, 5, 165, + 201, 28, 19, 32, 76, 69, 83, 83, 32, 84, 72, 65, 78, 32, 84, 72, 69, 32, + 68, 69, 78, 79, 108, 226, 1, 75, 90, 82, 226, 232, 20, 86, 234, 239, 7, + 89, 150, 205, 2, 65, 38, 68, 46, 84, 230, 24, 85, 210, 200, 1, 73, 158, + 190, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 80, 254, 68, 72, 2, + 76, 2, 77, 186, 2, 69, 3, 79, 8, 26, 72, 235, 142, 35, 65, 6, 26, 65, + 155, 208, 13, 73, 5, 157, 128, 18, 3, 78, 68, 65, 10, 34, 65, 210, 139, + 35, 72, 3, 82, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 244, 179, 24, 5, 76, + 79, 87, 69, 82, 1, 6, 77, 73, 68, 68, 76, 69, 4, 202, 134, 34, 83, 179, + 69, 77, 20, 116, 19, 69, 81, 85, 69, 78, 67, 69, 32, 70, 79, 82, 32, 76, + 69, 84, 84, 69, 82, 32, 154, 154, 25, 65, 187, 138, 6, 73, 6, 150, 131, + 22, 82, 147, 134, 13, 89, 4, 182, 173, 25, 32, 251, 209, 8, 79, 5, 137, + 247, 31, 4, 32, 87, 73, 84, 4, 150, 186, 33, 87, 255, 61, 32, 194, 1, + 180, 2, 7, 76, 69, 84, 84, 69, 82, 32, 244, 1, 7, 78, 85, 77, 66, 69, 82, + 32, 72, 5, 83, 73, 71, 78, 32, 44, 11, 86, 79, 87, 69, 76, 32, 83, 73, + 71, 78, 32, 250, 143, 25, 68, 130, 229, 3, 87, 136, 97, 10, 71, 65, 80, + 32, 70, 73, 76, 76, 69, 82, 153, 229, 4, 12, 72, 85, 78, 68, 82, 69, 68, + 83, 32, 85, 78, 73, 92, 210, 1, 86, 154, 158, 31, 65, 38, 68, 46, 84, + 230, 24, 85, 210, 200, 1, 73, 158, 190, 1, 78, 46, 83, 82, 66, 2, 67, 2, + 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, 76, 2, 77, 2, 82, 2, 89, 186, 2, + 69, 3, 79, 8, 234, 1, 79, 255, 132, 35, 65, 36, 138, 100, 69, 38, 70, 66, + 78, 26, 83, 250, 241, 20, 84, 183, 150, 12, 79, 10, 142, 159, 31, 65, 74, + 67, 171, 163, 3, 86, 24, 84, 2, 86, 79, 166, 160, 31, 65, 190, 21, 85, + 210, 200, 1, 73, 206, 134, 2, 69, 3, 79, 6, 33, 6, 67, 65, 76, 73, 67, + 32, 6, 178, 161, 31, 82, 167, 227, 3, 76, 26, 148, 1, 4, 67, 89, 67, 76, + 36, 2, 71, 32, 28, 2, 76, 76, 46, 82, 66, 84, 212, 216, 18, 4, 79, 72, + 65, 90, 164, 217, 11, 2, 75, 73, 155, 128, 4, 83, 4, 210, 187, 31, 73, + 203, 199, 3, 69, 4, 186, 240, 32, 82, 67, 83, 4, 164, 175, 9, 2, 69, 68, + 219, 251, 22, 73, 4, 176, 188, 31, 7, 84, 72, 68, 65, 89, 32, 67, 255, + 197, 3, 68, 4, 160, 165, 13, 2, 67, 79, 149, 219, 21, 4, 73, 78, 71, 32, + 230, 3, 42, 65, 222, 29, 79, 249, 3, 2, 85, 69, 228, 2, 32, 2, 67, 75, + 135, 159, 17, 78, 226, 2, 22, 32, 143, 28, 45, 210, 2, 214, 1, 67, 254, + 4, 68, 174, 2, 70, 102, 72, 82, 76, 170, 2, 77, 250, 2, 80, 46, 82, 202, + 3, 83, 210, 3, 84, 82, 85, 248, 2, 3, 86, 69, 82, 198, 215, 11, 79, 208, + 240, 19, 3, 66, 79, 87, 154, 227, 1, 78, 179, 1, 81, 98, 196, 1, 5, 73, + 82, 67, 76, 69, 200, 1, 6, 85, 82, 86, 69, 68, 32, 192, 150, 25, 12, 82, + 79, 83, 83, 32, 79, 78, 32, 83, 72, 73, 69, 240, 155, 3, 5, 69, 78, 84, + 82, 69, 178, 238, 4, 72, 203, 13, 76, 11, 11, 32, 8, 72, 5, 87, 73, 84, + 72, 32, 145, 164, 16, 7, 70, 79, 82, 32, 82, 69, 67, 6, 224, 51, 8, 87, + 72, 73, 84, 69, 32, 68, 79, 238, 181, 18, 68, 221, 144, 2, 8, 84, 87, 79, + 32, 87, 72, 73, 84, 16, 84, 4, 68, 79, 87, 78, 0, 2, 85, 80, 56, 3, 76, + 69, 70, 1, 4, 82, 73, 71, 72, 4, 141, 139, 31, 9, 87, 65, 82, 68, 83, 32, + 65, 78, 68, 4, 53, 11, 84, 87, 65, 82, 68, 83, 32, 65, 78, 68, 32, 4, + 178, 164, 10, 85, 179, 237, 21, 68, 30, 64, 6, 73, 65, 77, 79, 78, 68, + 152, 1, 3, 79, 87, 78, 43, 82, 13, 11, 32, 10, 210, 15, 67, 152, 208, 12, + 10, 77, 73, 78, 85, 83, 32, 87, 72, 73, 84, 184, 134, 6, 6, 87, 73, 84, + 72, 32, 68, 242, 212, 14, 79, 131, 11, 83, 12, 142, 16, 32, 62, 45, 175, + 185, 30, 87, 6, 196, 155, 33, 2, 79, 80, 175, 20, 65, 8, 18, 76, 39, 79, + 4, 150, 134, 27, 79, 191, 240, 7, 65, 4, 172, 192, 2, 2, 85, 82, 231, + 146, 30, 76, 12, 38, 69, 146, 179, 33, 65, 239, 2, 79, 6, 216, 180, 33, + 2, 65, 82, 215, 10, 88, 32, 60, 3, 69, 70, 84, 202, 1, 79, 161, 228, 32, + 3, 65, 82, 71, 22, 96, 10, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 64, 6, + 87, 65, 82, 68, 83, 32, 155, 183, 33, 32, 12, 162, 6, 68, 246, 7, 73, + 174, 170, 33, 80, 166, 24, 83, 51, 84, 4, 226, 142, 32, 69, 143, 137, 1, + 66, 6, 230, 13, 87, 143, 178, 33, 90, 30, 76, 6, 69, 68, 73, 85, 77, 32, + 197, 145, 21, 7, 79, 79, 78, 32, 76, 73, 76, 28, 66, 68, 42, 76, 36, 4, + 82, 73, 71, 72, 12, 2, 85, 80, 111, 83, 6, 84, 3, 79, 87, 78, 219, 182, + 33, 73, 6, 32, 2, 69, 70, 235, 189, 33, 79, 4, 11, 84, 4, 81, 18, 45, 80, + 79, 73, 78, 84, 73, 78, 71, 32, 84, 82, 73, 65, 78, 71, 76, 69, 5, 217, + 7, 2, 32, 67, 8, 130, 12, 77, 207, 196, 33, 81, 8, 142, 169, 24, 85, 222, + 141, 9, 65, 87, 69, 32, 52, 4, 73, 71, 72, 84, 178, 228, 32, 79, 251, + 105, 69, 28, 100, 10, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 244, 1, 6, + 87, 65, 82, 68, 83, 32, 159, 199, 33, 32, 16, 90, 68, 88, 8, 84, 82, 73, + 65, 78, 71, 76, 69, 158, 7, 73, 162, 175, 33, 80, 179, 19, 83, 4, 65, 14, + 79, 85, 66, 76, 69, 32, 84, 82, 73, 65, 78, 71, 76, 69, 5, 247, 146, 12, + 32, 5, 197, 153, 20, 11, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, 8, + 226, 211, 18, 65, 134, 180, 13, 69, 143, 137, 1, 66, 38, 150, 2, 77, 84, + 5, 81, 85, 65, 82, 69, 172, 156, 25, 3, 85, 78, 32, 196, 223, 1, 5, 75, + 85, 76, 76, 32, 208, 164, 3, 3, 78, 79, 87, 208, 195, 1, 5, 65, 70, 69, + 84, 89, 164, 118, 13, 76, 73, 71, 72, 84, 76, 89, 32, 83, 77, 65, 76, 76, + 146, 90, 67, 50, 72, 226, 1, 80, 143, 17, 84, 10, 40, 4, 65, 76, 76, 32, + 239, 182, 33, 73, 8, 134, 175, 33, 68, 134, 7, 76, 71, 83, 9, 11, 32, 6, + 54, 67, 228, 158, 32, 3, 70, 79, 82, 243, 152, 1, 66, 2, 245, 137, 30, 3, + 69, 78, 84, 14, 180, 4, 3, 73, 78, 89, 134, 221, 22, 82, 226, 221, 10, + 79, 54, 69, 135, 2, 87, 18, 38, 80, 133, 208, 31, 3, 78, 73, 86, 16, 46, + 32, 62, 45, 170, 1, 80, 135, 184, 30, 87, 2, 185, 194, 33, 10, 80, 79, + 73, 78, 84, 73, 78, 71, 32, 66, 8, 45, 9, 80, 79, 73, 78, 84, 73, 78, 71, + 32, 8, 66, 73, 236, 190, 33, 5, 68, 79, 85, 66, 76, 230, 3, 83, 51, 84, + 2, 129, 199, 32, 8, 83, 79, 83, 67, 69, 76, 69, 83, 4, 21, 3, 69, 82, 32, + 4, 190, 222, 23, 76, 143, 232, 8, 82, 10, 56, 6, 84, 73, 67, 65, 76, 32, + 29, 4, 89, 32, 83, 77, 4, 134, 195, 33, 69, 51, 82, 6, 21, 3, 65, 76, 76, + 6, 11, 32, 6, 182, 169, 33, 68, 134, 7, 76, 227, 19, 83, 16, 84, 15, 76, + 69, 84, 84, 69, 82, 32, 67, 65, 80, 73, 84, 65, 76, 32, 155, 234, 10, 70, + 10, 218, 227, 34, 67, 2, 72, 2, 73, 2, 82, 3, 90, 124, 84, 11, 67, 75, + 32, 83, 69, 88, 84, 65, 78, 84, 45, 238, 128, 2, 83, 135, 181, 10, 87, + 120, 62, 49, 214, 1, 50, 46, 51, 38, 52, 42, 53, 199, 223, 34, 54, 61, + 50, 50, 118, 51, 126, 52, 42, 53, 199, 223, 34, 54, 31, 46, 51, 194, 1, + 52, 42, 53, 199, 223, 34, 54, 15, 38, 52, 194, 1, 53, 199, 223, 34, 54, + 7, 130, 225, 34, 53, 3, 54, 15, 122, 52, 190, 248, 27, 53, 179, 231, 6, + 54, 31, 42, 51, 66, 52, 14, 53, 199, 223, 34, 54, 17, 34, 52, 42, 53, + 199, 223, 34, 54, 9, 38, 53, 199, 223, 34, 54, 7, 11, 53, 5, 195, 223, + 34, 54, 6, 178, 207, 21, 32, 241, 166, 8, 4, 66, 69, 82, 82, 144, 4, 200, + 1, 3, 76, 68, 32, 78, 79, 104, 7, 80, 79, 77, 79, 70, 79, 32, 188, 6, 2, + 84, 84, 140, 3, 5, 85, 81, 85, 69, 84, 54, 87, 198, 1, 88, 210, 204, 5, + 77, 194, 153, 3, 89, 218, 177, 25, 65, 255, 33, 78, 14, 246, 169, 8, 83, + 210, 164, 7, 69, 134, 252, 16, 70, 234, 2, 87, 207, 10, 71, 10, 26, 75, + 155, 198, 22, 77, 9, 40, 4, 77, 65, 82, 75, 155, 220, 34, 83, 5, 197, + 224, 22, 3, 32, 84, 65, 150, 1, 96, 13, 70, 73, 78, 65, 76, 32, 76, 69, + 84, 84, 69, 82, 32, 53, 7, 76, 69, 84, 84, 69, 82, 32, 10, 142, 219, 34, + 71, 2, 72, 2, 75, 2, 80, 3, 84, 140, 1, 234, 1, 65, 54, 85, 22, 69, 82, + 71, 46, 73, 70, 78, 38, 79, 98, 90, 226, 138, 7, 75, 162, 215, 23, 67, 2, + 76, 2, 83, 198, 36, 66, 210, 200, 1, 74, 206, 134, 2, 68, 2, 70, 2, 72, + 2, 77, 2, 80, 2, 81, 2, 82, 2, 84, 2, 86, 3, 88, 21, 50, 73, 2, 85, 74, + 78, 242, 215, 34, 72, 3, 77, 5, 227, 136, 34, 78, 17, 50, 78, 242, 215, + 34, 69, 2, 72, 2, 73, 3, 82, 7, 238, 215, 34, 71, 3, 78, 11, 210, 215, + 34, 72, 2, 78, 2, 85, 3, 87, 15, 164, 223, 32, 2, 78, 78, 130, 248, 1, + 72, 2, 77, 2, 82, 3, 85, 9, 206, 222, 32, 71, 151, 248, 1, 78, 17, 66, + 78, 146, 213, 33, 32, 238, 128, 1, 69, 2, 77, 2, 79, 3, 85, 4, 250, 213, + 34, 71, 3, 78, 9, 222, 213, 34, 72, 2, 73, 3, 89, 34, 104, 3, 79, 77, 32, + 197, 238, 20, 17, 76, 69, 32, 87, 73, 84, 72, 32, 80, 79, 80, 80, 73, 78, + 71, 32, 67, 32, 168, 1, 5, 72, 65, 76, 70, 32, 52, 14, 83, 81, 85, 65, + 82, 69, 32, 66, 82, 65, 67, 75, 69, 84, 134, 157, 15, 65, 166, 217, 15, + 67, 134, 2, 80, 126, 76, 22, 82, 175, 1, 84, 8, 226, 247, 30, 66, 46, 76, + 26, 82, 255, 214, 1, 73, 5, 193, 250, 30, 11, 32, 79, 86, 69, 82, 32, 84, + 79, 80, 32, 83, 5, 229, 195, 33, 8, 32, 79, 70, 32, 70, 76, 79, 87, 14, + 58, 76, 116, 3, 84, 73, 69, 181, 252, 31, 3, 32, 65, 78, 6, 26, 32, 187, + 128, 34, 73, 4, 160, 158, 9, 7, 79, 70, 32, 72, 89, 71, 73, 197, 161, 22, + 6, 87, 73, 84, 72, 32, 83, 7, 235, 196, 31, 32, 162, 2, 88, 10, 32, 68, + 82, 65, 87, 73, 78, 71, 83, 32, 137, 211, 33, 6, 73, 78, 71, 32, 71, 76, + 160, 2, 176, 1, 2, 68, 79, 148, 4, 6, 72, 69, 65, 86, 89, 32, 194, 2, 76, + 156, 17, 6, 82, 73, 71, 72, 84, 32, 144, 4, 3, 85, 80, 32, 245, 3, 9, 86, + 69, 82, 84, 73, 67, 65, 76, 32, 58, 48, 5, 85, 66, 76, 69, 32, 89, 3, 87, + 78, 32, 22, 68, 4, 68, 79, 87, 78, 0, 2, 85, 80, 250, 21, 86, 155, 177, + 28, 72, 6, 171, 22, 32, 36, 128, 1, 10, 72, 69, 65, 86, 89, 32, 65, 78, + 68, 32, 132, 1, 10, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 230, 29, 68, + 131, 4, 83, 12, 76, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 248, 26, 2, 85, + 80, 151, 5, 72, 4, 17, 2, 84, 32, 4, 250, 23, 85, 227, 136, 34, 76, 12, + 76, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 176, 27, 2, 85, 80, 235, 4, 72, + 4, 17, 2, 84, 32, 4, 218, 23, 85, 135, 9, 72, 46, 120, 4, 76, 69, 70, 84, + 68, 2, 85, 80, 176, 14, 2, 68, 79, 106, 81, 34, 84, 234, 1, 86, 154, 177, + 28, 72, 199, 219, 5, 82, 5, 45, 9, 32, 65, 78, 68, 32, 76, 73, 71, 72, 2, + 207, 250, 32, 84, 11, 29, 5, 32, 65, 78, 68, 32, 8, 42, 76, 238, 193, 28, + 72, 199, 219, 5, 82, 4, 204, 223, 23, 4, 73, 71, 72, 84, 211, 189, 10, + 69, 108, 56, 4, 69, 70, 84, 32, 169, 2, 5, 73, 71, 72, 84, 32, 16, 244, + 18, 19, 68, 79, 87, 78, 32, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 82, + 73, 71, 72, 24, 14, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 82, 73, 71, + 72, 100, 14, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 82, 73, 71, 72, 97, + 17, 85, 80, 32, 72, 69, 65, 86, 89, 32, 65, 78, 68, 32, 82, 73, 71, 72, + 92, 172, 1, 4, 65, 82, 67, 32, 30, 68, 172, 9, 4, 76, 69, 70, 84, 62, 81, + 34, 84, 112, 2, 85, 80, 122, 86, 176, 134, 34, 10, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 175, 6, 82, 8, 158, 143, 17, 68, 67, 85, 48, 52, 8, + 73, 65, 71, 79, 78, 65, 76, 32, 203, 8, 79, 36, 100, 7, 77, 73, 68, 68, + 76, 69, 32, 216, 2, 6, 85, 80, 80, 69, 82, 32, 194, 129, 33, 67, 191, 2, + 68, 12, 88, 8, 76, 69, 70, 84, 32, 84, 79, 32, 161, 1, 9, 82, 73, 71, 72, + 84, 32, 84, 79, 32, 8, 136, 1, 28, 85, 80, 80, 69, 82, 32, 67, 69, 78, + 84, 82, 69, 32, 84, 79, 32, 77, 73, 68, 68, 76, 69, 32, 82, 73, 71, 72, + 84, 195, 3, 76, 5, 143, 132, 20, 32, 4, 232, 4, 15, 85, 80, 80, 69, 82, + 32, 67, 69, 78, 84, 82, 69, 32, 84, 79, 175, 255, 19, 76, 20, 196, 1, 17, + 67, 69, 78, 84, 82, 69, 32, 84, 79, 32, 77, 73, 68, 68, 76, 69, 32, 228, + 239, 22, 7, 76, 69, 70, 84, 32, 84, 79, 193, 155, 11, 14, 82, 73, 71, 72, + 84, 32, 84, 79, 32, 76, 79, 87, 69, 82, 16, 56, 4, 76, 69, 70, 84, 165, + 1, 5, 82, 73, 71, 72, 84, 9, 11, 32, 6, 60, 4, 84, 79, 32, 76, 137, 128, + 20, 5, 65, 78, 68, 32, 77, 4, 53, 11, 79, 87, 69, 82, 32, 67, 69, 78, 84, + 82, 69, 5, 169, 198, 31, 3, 32, 84, 79, 9, 11, 32, 6, 88, 3, 65, 78, 68, + 65, 15, 84, 79, 32, 76, 79, 87, 69, 82, 32, 67, 69, 78, 84, 82, 69, 2, + 249, 254, 19, 11, 32, 77, 73, 68, 68, 76, 69, 32, 76, 69, 70, 5, 165, + 187, 10, 9, 32, 84, 79, 32, 77, 73, 68, 68, 76, 12, 164, 1, 2, 85, 66, + 241, 1, 2, 87, 78, 5, 221, 235, 32, 10, 32, 65, 78, 68, 32, 72, 69, 65, + 86, 89, 4, 49, 5, 85, 65, 68, 82, 85, 4, 17, 2, 82, 73, 4, 11, 80, 4, 41, + 8, 76, 69, 32, 68, 65, 83, 72, 32, 4, 230, 130, 16, 86, 207, 175, 12, 72, + 11, 29, 5, 32, 65, 78, 68, 32, 8, 34, 72, 246, 140, 34, 76, 31, 82, 4, + 172, 207, 23, 4, 69, 65, 86, 89, 171, 226, 4, 79, 8, 37, 7, 69, 82, 84, + 73, 67, 65, 76, 9, 11, 32, 6, 25, 4, 65, 78, 68, 32, 6, 198, 176, 28, 72, + 170, 219, 5, 76, 31, 82, 16, 148, 2, 18, 68, 79, 87, 78, 32, 72, 69, 65, + 86, 89, 32, 65, 78, 68, 32, 76, 69, 70, 24, 13, 72, 69, 65, 86, 89, 32, + 65, 78, 68, 32, 76, 69, 70, 100, 13, 76, 73, 71, 72, 84, 32, 65, 78, 68, + 32, 76, 69, 70, 97, 16, 85, 80, 32, 72, 69, 65, 86, 89, 32, 65, 78, 68, + 32, 76, 69, 70, 2, 101, 3, 84, 32, 85, 6, 17, 2, 84, 32, 6, 58, 85, 178, + 3, 68, 245, 4, 6, 86, 69, 82, 84, 73, 67, 2, 227, 157, 32, 80, 6, 17, 2, + 84, 32, 6, 58, 85, 134, 4, 68, 205, 4, 6, 86, 69, 82, 84, 73, 67, 2, 239, + 8, 80, 2, 185, 2, 3, 84, 32, 68, 36, 128, 1, 10, 72, 69, 65, 86, 89, 32, + 65, 78, 68, 32, 188, 1, 10, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 186, + 2, 68, 131, 4, 83, 12, 80, 4, 68, 79, 87, 78, 24, 3, 76, 69, 70, 0, 4, + 82, 73, 71, 72, 255, 4, 72, 2, 145, 5, 2, 32, 72, 4, 17, 2, 84, 32, 4, + 26, 68, 179, 133, 34, 76, 2, 177, 154, 32, 3, 79, 87, 78, 12, 80, 4, 68, + 79, 87, 78, 24, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 211, 4, 72, 2, 229, + 4, 2, 32, 72, 4, 17, 2, 84, 32, 4, 22, 68, 131, 5, 72, 2, 233, 4, 3, 79, + 87, 78, 24, 130, 1, 68, 188, 1, 10, 72, 69, 65, 86, 89, 32, 65, 78, 68, + 32, 144, 1, 10, 76, 73, 71, 72, 84, 32, 65, 78, 68, 32, 183, 1, 83, 6, + 49, 10, 79, 85, 66, 76, 69, 32, 65, 78, 68, 32, 6, 92, 3, 76, 69, 70, 0, + 4, 82, 73, 71, 72, 13, 10, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 2, 11, + 84, 2, 189, 157, 26, 2, 32, 83, 6, 54, 72, 68, 3, 76, 69, 70, 1, 4, 82, + 73, 71, 72, 2, 37, 7, 79, 82, 73, 90, 79, 78, 84, 2, 189, 149, 32, 2, 65, + 76, 2, 163, 149, 32, 84, 6, 54, 72, 60, 3, 76, 69, 70, 1, 4, 82, 73, 71, + 72, 2, 37, 7, 79, 82, 73, 90, 79, 78, 84, 2, 29, 2, 65, 76, 2, 11, 84, 2, + 17, 2, 32, 72, 2, 253, 151, 34, 3, 69, 65, 86, 6, 49, 10, 73, 78, 71, 76, + 69, 32, 65, 78, 68, 32, 6, 96, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 165, + 225, 25, 9, 72, 79, 82, 73, 90, 79, 78, 84, 65, 2, 175, 225, 25, 84, 134, + 6, 46, 65, 186, 14, 69, 150, 1, 73, 191, 1, 79, 232, 5, 36, 4, 72, 77, + 73, 32, 255, 9, 73, 230, 1, 192, 1, 7, 76, 69, 84, 84, 69, 82, 32, 196, + 2, 7, 78, 85, 77, 66, 69, 82, 32, 144, 2, 12, 80, 85, 78, 67, 84, 85, 65, + 84, 73, 79, 78, 32, 84, 5, 83, 73, 71, 78, 32, 126, 86, 215, 169, 24, 68, + 108, 210, 1, 79, 178, 187, 30, 65, 38, 68, 46, 84, 46, 86, 186, 24, 85, + 210, 200, 1, 73, 42, 76, 246, 189, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, + 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, 77, 2, 82, 2, 89, 187, 2, 69, 15, + 45, 9, 76, 68, 32, 84, 65, 77, 73, 76, 32, 12, 226, 165, 28, 76, 186, + 153, 2, 83, 190, 66, 78, 199, 221, 2, 82, 42, 82, 69, 38, 70, 66, 78, 26, + 83, 250, 241, 20, 84, 174, 213, 5, 79, 155, 156, 7, 74, 4, 193, 175, 30, + 4, 73, 71, 72, 84, 8, 26, 79, 135, 218, 20, 73, 4, 134, 184, 32, 82, 167, + 177, 1, 85, 4, 65, 3, 73, 78, 69, 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, + 5, 203, 143, 34, 84, 10, 46, 76, 170, 188, 12, 68, 169, 16, 2, 67, 82, 4, + 178, 138, 19, 79, 139, 253, 13, 73, 12, 204, 155, 16, 9, 79, 76, 68, 32, + 84, 65, 77, 73, 76, 182, 158, 14, 67, 198, 180, 1, 74, 158, 2, 86, 122, + 85, 231, 233, 1, 65, 34, 64, 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, + 247, 236, 31, 73, 32, 142, 1, 79, 140, 213, 28, 11, 66, 72, 65, 84, 84, + 73, 80, 82, 79, 76, 85, 250, 227, 1, 65, 106, 86, 214, 20, 85, 210, 200, + 1, 73, 207, 134, 2, 69, 7, 165, 185, 30, 10, 76, 68, 32, 84, 65, 77, 73, + 76, 32, 83, 130, 4, 72, 12, 76, 76, 69, 32, 80, 65, 84, 84, 69, 82, 78, + 32, 211, 156, 34, 78, 128, 4, 44, 5, 68, 79, 84, 83, 45, 215, 243, 6, 66, + 254, 3, 74, 49, 74, 50, 66, 51, 54, 52, 46, 53, 38, 54, 30, 55, 167, 153, + 34, 56, 129, 2, 66, 50, 66, 51, 54, 52, 46, 53, 38, 54, 30, 55, 167, 153, + 34, 56, 129, 1, 58, 51, 54, 52, 46, 53, 38, 54, 30, 55, 167, 153, 34, 56, + 65, 50, 52, 46, 53, 38, 54, 30, 55, 167, 153, 34, 56, 33, 42, 53, 38, 54, + 30, 55, 167, 153, 34, 56, 17, 34, 54, 30, 55, 167, 153, 34, 56, 9, 26, + 55, 167, 153, 34, 56, 5, 163, 153, 34, 56, 8, 26, 65, 163, 130, 34, 86, + 6, 212, 131, 20, 11, 75, 32, 80, 69, 82, 77, 73, 84, 84, 69, 68, 196, + 135, 8, 6, 83, 84, 45, 70, 69, 69, 219, 141, 6, 68, 10, 42, 68, 108, 2, + 69, 70, 207, 147, 34, 67, 4, 84, 6, 71, 69, 32, 65, 84, 32, 133, 234, 31, + 9, 69, 32, 87, 73, 84, 72, 32, 86, 69, 2, 167, 236, 33, 78, 4, 190, 134, + 31, 67, 167, 144, 3, 83, 12, 84, 4, 75, 69, 78, 32, 232, 177, 8, 2, 67, + 67, 220, 220, 24, 2, 87, 78, 207, 118, 79, 6, 140, 227, 26, 17, 67, 73, + 82, 67, 76, 69, 32, 87, 73, 84, 72, 32, 78, 79, 82, 84, 72, 178, 144, 6, + 66, 155, 27, 72, 134, 1, 208, 1, 4, 66, 66, 76, 69, 46, 71, 156, 4, 4, + 72, 73, 68, 32, 36, 2, 76, 76, 122, 83, 56, 4, 84, 84, 69, 82, 220, 230, + 10, 10, 73, 76, 68, 73, 78, 71, 32, 67, 79, 78, 208, 154, 16, 2, 82, 82, + 155, 185, 6, 67, 4, 216, 195, 27, 2, 32, 84, 195, 207, 6, 83, 63, 33, 6, + 73, 78, 69, 83, 69, 32, 60, 144, 1, 7, 76, 69, 84, 84, 69, 82, 32, 172, + 2, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 154, 252, 15, 69, 237, + 205, 13, 4, 80, 65, 76, 76, 46, 154, 1, 77, 34, 78, 198, 141, 34, 66, 2, + 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, 80, 2, 82, 2, 83, 2, 84, + 2, 86, 2, 89, 187, 2, 65, 4, 226, 141, 34, 80, 187, 2, 65, 12, 46, 71, + 34, 89, 246, 140, 34, 82, 187, 2, 65, 4, 146, 141, 34, 75, 187, 2, 65, 4, + 242, 140, 34, 67, 187, 2, 65, 10, 182, 248, 33, 65, 214, 22, 69, 2, 73, + 2, 79, 3, 85, 40, 134, 134, 10, 76, 183, 169, 18, 86, 10, 56, 2, 69, 84, + 20, 4, 72, 79, 82, 78, 151, 149, 9, 83, 5, 211, 227, 30, 32, 5, 221, 237, + 26, 5, 32, 87, 73, 84, 72, 9, 26, 84, 203, 194, 31, 32, 4, 214, 237, 26, + 83, 15, 32, 5, 207, 233, 33, 70, 240, 3, 140, 1, 23, 90, 65, 78, 84, 73, + 78, 69, 32, 77, 85, 83, 73, 67, 65, 76, 32, 83, 89, 77, 66, 79, 76, 32, + 173, 254, 19, 5, 84, 69, 32, 79, 82, 238, 3, 154, 2, 65, 128, 7, 2, 67, + 72, 170, 1, 68, 158, 5, 69, 206, 2, 70, 166, 8, 71, 202, 3, 73, 162, 2, + 75, 142, 5, 76, 190, 2, 77, 250, 4, 79, 114, 80, 174, 4, 82, 42, 83, 194, + 5, 84, 196, 5, 2, 86, 65, 250, 1, 89, 238, 162, 31, 78, 149, 136, 2, 9, + 88, 73, 82, 79, 78, 32, 75, 76, 65, 62, 60, 5, 71, 79, 71, 73, 32, 222, + 1, 78, 118, 80, 199, 2, 82, 16, 70, 65, 0, 2, 71, 79, 64, 2, 77, 69, 37, + 5, 80, 79, 76, 73, 32, 4, 17, 2, 82, 71, 4, 200, 181, 15, 2, 79, 84, 211, + 210, 18, 73, 4, 134, 138, 9, 84, 147, 234, 24, 83, 4, 26, 65, 1, 2, 71, + 79, 2, 223, 150, 17, 82, 6, 72, 6, 84, 73, 75, 69, 78, 79, 169, 229, 33, + 6, 65, 84, 82, 73, 67, 72, 4, 168, 32, 2, 75, 89, 239, 227, 33, 77, 22, + 52, 5, 69, 83, 79, 32, 69, 38, 79, 247, 241, 33, 76, 4, 204, 1, 2, 88, + 79, 147, 55, 75, 16, 80, 6, 83, 84, 82, 79, 70, 79, 188, 40, 3, 68, 69, + 82, 181, 128, 1, 2, 84, 72, 10, 24, 2, 73, 32, 79, 83, 4, 56, 9, 83, 89, + 78, 68, 69, 83, 77, 79, 83, 195, 24, 84, 2, 143, 44, 32, 7, 11, 32, 4, + 214, 60, 68, 251, 213, 21, 78, 18, 48, 2, 71, 79, 33, 6, 75, 84, 73, 75, + 79, 32, 4, 170, 21, 83, 135, 238, 33, 78, 14, 194, 242, 26, 86, 218, 241, + 6, 90, 162, 8, 75, 254, 2, 68, 2, 78, 162, 17, 71, 3, 80, 14, 80, 4, 82, + 79, 65, 32, 168, 37, 4, 79, 82, 69, 86, 221, 2, 4, 65, 77, 73, 76, 6, + 204, 161, 19, 2, 83, 80, 152, 184, 3, 3, 90, 89, 71, 161, 246, 9, 3, 75, + 76, 73, 42, 50, 73, 220, 205, 8, 2, 65, 83, 143, 148, 25, 89, 38, 122, + 65, 200, 1, 5, 69, 83, 73, 83, 32, 70, 71, 208, 1, 3, 80, 76, 73, 185, + 235, 26, 8, 70, 84, 79, 71, 71, 79, 83, 32, 10, 48, 6, 83, 84, 79, 76, + 73, 32, 187, 200, 32, 82, 8, 80, 6, 65, 80, 76, 73, 32, 77, 174, 55, 68, + 177, 159, 22, 5, 84, 72, 69, 83, 69, 4, 40, 2, 69, 71, 197, 245, 26, 2, + 73, 75, 2, 171, 175, 29, 65, 12, 38, 84, 246, 50, 65, 42, 68, 63, 77, 6, + 194, 10, 69, 239, 41, 82, 10, 72, 5, 79, 82, 71, 79, 78, 181, 252, 33, 7, + 82, 65, 77, 77, 65, 32, 71, 9, 69, 15, 32, 80, 65, 82, 69, 83, 84, 73, + 71, 77, 69, 78, 79, 78, 32, 6, 222, 38, 68, 137, 10, 8, 65, 82, 73, 83, + 84, 69, 82, 65, 5, 175, 47, 32, 16, 166, 1, 78, 116, 6, 84, 69, 82, 79, + 78, 32, 188, 44, 4, 88, 79, 32, 69, 252, 236, 31, 4, 80, 69, 71, 69, 196, + 46, 6, 75, 83, 84, 82, 69, 80, 209, 13, 3, 76, 65, 70, 4, 224, 22, 3, 68, + 79, 70, 157, 211, 26, 18, 65, 82, 88, 73, 83, 32, 75, 65, 73, 32, 70, 84, + 72, 79, 82, 65, 32, 86, 4, 208, 11, 5, 65, 82, 71, 79, 83, 151, 20, 80, + 44, 180, 1, 9, 65, 78, 69, 82, 79, 83, 73, 83, 32, 52, 6, 84, 72, 79, 82, + 65, 32, 165, 6, 22, 72, 84, 79, 82, 65, 32, 83, 75, 76, 73, 82, 79, 78, + 32, 67, 72, 82, 79, 77, 65, 32, 86, 6, 246, 4, 68, 14, 77, 25, 5, 84, 69, + 84, 82, 65, 36, 220, 2, 8, 65, 82, 67, 72, 65, 73, 79, 78, 80, 10, 68, + 73, 65, 84, 79, 78, 73, 75, 73, 32, 96, 11, 73, 32, 89, 70, 69, 83, 73, + 83, 32, 84, 69, 32, 15, 77, 65, 76, 65, 75, 79, 78, 32, 67, 72, 82, 79, + 77, 65, 32, 74, 78, 40, 8, 83, 75, 76, 73, 82, 79, 78, 32, 133, 157, 18, + 18, 69, 78, 65, 82, 77, 79, 78, 73, 79, 83, 32, 65, 78, 84, 73, 70, 79, + 78, 5, 57, 12, 32, 68, 69, 89, 84, 69, 82, 79, 85, 32, 73, 67, 2, 211, + 227, 26, 72, 14, 62, 78, 218, 212, 33, 90, 162, 8, 75, 254, 2, 68, 163, + 17, 80, 6, 242, 39, 73, 151, 145, 32, 65, 2, 237, 42, 4, 84, 65, 82, 84, + 4, 18, 68, 15, 77, 2, 35, 73, 2, 21, 3, 79, 78, 79, 2, 151, 19, 70, 4, + 166, 19, 65, 193, 218, 31, 2, 69, 78, 6, 84, 7, 67, 72, 82, 79, 77, 65, + 32, 205, 225, 16, 8, 68, 73, 65, 84, 79, 78, 79, 78, 4, 42, 86, 181, 229, + 16, 4, 83, 89, 78, 65, 2, 159, 212, 31, 65, 22, 80, 6, 69, 78, 73, 75, + 73, 32, 44, 2, 79, 82, 185, 26, 5, 82, 79, 78, 84, 72, 4, 140, 150, 30, + 2, 68, 73, 1, 2, 89, 70, 16, 68, 2, 71, 79, 225, 1, 10, 84, 72, 77, 73, + 75, 79, 78, 32, 78, 32, 12, 28, 2, 78, 32, 155, 1, 83, 10, 96, 14, 80, + 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 78, 32, 242, 33, 65, 113, 3, + 78, 69, 79, 4, 214, 24, 68, 233, 201, 31, 5, 65, 82, 73, 83, 84, 2, 165, + 188, 32, 5, 89, 78, 84, 72, 69, 4, 142, 28, 65, 1, 2, 68, 73, 16, 56, 2, + 77, 73, 114, 83, 213, 236, 32, 4, 67, 72, 65, 68, 8, 34, 70, 169, 28, 3, + 68, 73, 65, 6, 40, 4, 84, 72, 79, 82, 183, 226, 32, 79, 4, 218, 156, 33, + 79, 215, 79, 65, 6, 44, 6, 65, 75, 73, 65, 32, 84, 231, 13, 79, 2, 145, + 141, 21, 12, 69, 76, 79, 85, 83, 32, 73, 67, 72, 73, 77, 65, 54, 108, 2, + 65, 84, 96, 6, 69, 78, 84, 73, 77, 65, 140, 1, 5, 76, 65, 83, 77, 65, 18, + 79, 98, 82, 175, 1, 89, 6, 40, 3, 65, 86, 65, 201, 3, 2, 72, 73, 4, 140, + 29, 5, 32, 84, 82, 79, 77, 227, 171, 33, 83, 18, 24, 2, 84, 65, 15, 32, + 11, 11, 32, 8, 36, 4, 78, 69, 79, 32, 183, 28, 65, 6, 220, 144, 25, 2, + 77, 69, 166, 247, 4, 75, 235, 183, 3, 65, 7, 243, 28, 32, 8, 64, 6, 78, + 84, 69, 86, 77, 65, 250, 198, 8, 82, 195, 255, 24, 85, 5, 165, 254, 13, + 2, 32, 65, 14, 44, 4, 65, 84, 73, 77, 105, 3, 69, 77, 65, 12, 18, 65, 35, + 79, 8, 182, 23, 32, 159, 205, 33, 84, 4, 134, 12, 75, 181, 201, 30, 5, + 89, 80, 79, 82, 82, 2, 187, 194, 26, 83, 2, 251, 196, 33, 76, 14, 22, 69, + 147, 22, 89, 12, 44, 5, 73, 77, 77, 65, 32, 167, 163, 29, 77, 10, 72, 2, + 69, 78, 0, 5, 73, 77, 73, 83, 69, 54, 84, 69, 3, 68, 89, 79, 2, 173, 212, + 26, 8, 79, 83, 32, 67, 72, 82, 79, 78, 4, 44, 5, 69, 83, 83, 65, 82, 1, + 2, 82, 73, 2, 17, 2, 79, 78, 2, 25, 4, 32, 67, 72, 82, 2, 235, 217, 32, + 79, 28, 84, 8, 65, 82, 84, 89, 82, 73, 65, 32, 241, 143, 27, 7, 73, 75, + 82, 79, 78, 32, 73, 26, 72, 5, 65, 76, 76, 73, 32, 38, 68, 38, 80, 134, + 1, 86, 30, 84, 87, 76, 4, 34, 68, 177, 2, 3, 80, 82, 79, 2, 237, 2, 5, + 69, 89, 84, 69, 82, 8, 60, 7, 76, 65, 71, 73, 79, 83, 32, 45, 4, 82, 79, + 84, 79, 4, 200, 1, 5, 84, 69, 84, 65, 82, 111, 73, 4, 22, 86, 227, 1, 83, + 2, 209, 1, 3, 65, 82, 89, 8, 56, 8, 69, 84, 65, 82, 84, 79, 83, 32, 61, + 2, 82, 73, 4, 22, 76, 135, 1, 73, 2, 21, 3, 69, 71, 69, 2, 63, 84, 4, 18, + 70, 35, 84, 2, 205, 137, 21, 3, 79, 78, 73, 2, 11, 79, 2, 11, 83, 2, 17, + 2, 32, 73, 2, 195, 178, 22, 67, 18, 92, 4, 76, 73, 71, 79, 180, 1, 5, 89, + 82, 65, 78, 73, 210, 14, 88, 141, 254, 32, 2, 77, 65, 4, 211, 1, 78, 42, + 60, 2, 65, 82, 100, 2, 73, 65, 90, 69, 169, 1, 2, 83, 73, 12, 40, 2, 65, + 75, 201, 246, 16, 2, 73, 67, 10, 52, 3, 65, 76, 69, 45, 6, 76, 73, 84, + 73, 75, 73, 4, 11, 83, 4, 17, 2, 77, 65, 4, 23, 32, 7, 11, 32, 4, 198, + 15, 65, 151, 219, 21, 78, 12, 72, 3, 84, 65, 83, 136, 3, 6, 76, 65, 83, + 84, 79, 78, 239, 202, 8, 82, 6, 26, 84, 211, 216, 33, 77, 4, 32, 2, 79, + 75, 231, 218, 33, 73, 2, 173, 185, 33, 2, 79, 85, 14, 36, 5, 70, 73, 83, + 84, 79, 67, 76, 10, 46, 80, 214, 1, 78, 170, 8, 76, 187, 1, 83, 2, 135, + 11, 65, 4, 138, 138, 33, 79, 215, 79, 73, 4, 178, 5, 69, 229, 178, 33, 2, + 65, 80, 42, 120, 5, 69, 73, 83, 77, 65, 32, 8, 73, 77, 65, 78, 83, 73, + 83, 32, 182, 1, 84, 154, 1, 89, 249, 240, 1, 3, 65, 88, 73, 5, 11, 32, 2, + 219, 230, 21, 78, 16, 36, 2, 65, 82, 1, 3, 84, 72, 69, 8, 25, 4, 83, 69, + 79, 83, 9, 11, 32, 6, 18, 84, 39, 68, 4, 34, 82, 13, 4, 69, 84, 82, 65, + 2, 11, 73, 2, 153, 198, 26, 3, 83, 73, 77, 8, 68, 5, 65, 86, 82, 79, 83, + 52, 4, 82, 65, 71, 71, 175, 147, 16, 73, 5, 29, 5, 32, 65, 80, 79, 68, 2, + 175, 206, 8, 69, 2, 145, 241, 1, 2, 73, 83, 12, 34, 78, 149, 1, 3, 82, + 77, 65, 8, 36, 5, 65, 71, 77, 65, 32, 91, 69, 6, 154, 8, 65, 150, 219, + 21, 78, 233, 224, 4, 10, 77, 69, 84, 65, 32, 83, 84, 65, 86, 82, 2, 251, + 178, 33, 86, 5, 11, 84, 2, 255, 193, 16, 73, 40, 42, 69, 70, 72, 218, 1, + 82, 227, 2, 73, 6, 136, 12, 3, 84, 82, 65, 162, 148, 8, 76, 137, 167, 23, + 2, 83, 83, 12, 26, 69, 131, 174, 33, 73, 10, 64, 2, 77, 65, 133, 190, 32, + 8, 83, 32, 75, 65, 73, 32, 65, 80, 9, 56, 2, 32, 65, 33, 8, 84, 73, 83, + 77, 79, 83, 32, 69, 2, 177, 209, 32, 3, 80, 76, 79, 4, 182, 178, 33, 83, + 3, 88, 20, 38, 73, 73, 5, 79, 77, 73, 75, 79, 6, 48, 2, 71, 79, 182, 129, + 29, 80, 131, 207, 4, 65, 2, 191, 153, 32, 82, 14, 42, 76, 32, 2, 78, 32, + 62, 80, 95, 83, 2, 11, 89, 2, 191, 174, 33, 71, 6, 26, 65, 135, 222, 21, + 78, 4, 250, 2, 82, 239, 169, 33, 76, 4, 46, 65, 141, 157, 32, 5, 83, 73, + 70, 73, 83, 2, 201, 173, 33, 6, 82, 65, 75, 65, 76, 69, 2, 11, 89, 2, + 141, 140, 16, 2, 78, 65, 10, 26, 82, 183, 172, 33, 84, 8, 21, 3, 69, 73, + 65, 8, 26, 32, 113, 2, 73, 32, 6, 38, 69, 242, 5, 68, 251, 213, 21, 78, + 2, 11, 75, 2, 29, 5, 70, 79, 78, 73, 84, 2, 141, 253, 32, 2, 73, 75, 2, + 11, 65, 2, 11, 82, 2, 129, 252, 32, 3, 67, 72, 65, 22, 28, 2, 70, 69, + 231, 3, 80, 14, 34, 78, 49, 4, 83, 73, 83, 32, 4, 11, 32, 4, 210, 234, + 29, 75, 235, 183, 3, 65, 10, 42, 65, 42, 68, 62, 77, 89, 2, 84, 82, 2, + 133, 2, 6, 80, 76, 73, 32, 68, 89, 2, 233, 1, 11, 73, 71, 82, 65, 77, 77, + 79, 83, 32, 69, 88, 2, 173, 1, 18, 79, 78, 79, 71, 82, 65, 77, 77, 79, + 83, 32, 84, 69, 83, 83, 69, 82, 65, 4, 11, 73, 4, 60, 11, 71, 82, 65, 77, + 77, 79, 83, 32, 79, 75, 84, 59, 84, 2, 11, 79, 2, 189, 174, 2, 6, 32, 68, + 79, 68, 69, 75, 2, 129, 248, 32, 4, 73, 77, 79, 82, 8, 26, 79, 243, 248, + 28, 83, 6, 56, 6, 75, 82, 73, 83, 73, 83, 157, 133, 29, 2, 82, 82, 5, 17, + 2, 32, 68, 2, 11, 73, 2, 159, 248, 28, 80, 162, 82, 182, 1, 65, 134, 72, + 69, 230, 1, 72, 154, 31, 73, 240, 41, 3, 74, 75, 32, 238, 25, 76, 186, + 18, 79, 194, 113, 82, 162, 8, 85, 130, 128, 2, 89, 166, 221, 18, 71, 226, + 155, 10, 83, 203, 18, 67, 198, 13, 110, 68, 66, 76, 50, 77, 90, 78, 174, + 51, 80, 62, 82, 198, 7, 84, 138, 1, 85, 198, 240, 17, 67, 139, 181, 6, + 83, 4, 34, 85, 221, 189, 26, 2, 65, 32, 2, 201, 193, 31, 2, 67, 69, 4, + 144, 189, 9, 3, 76, 32, 77, 131, 130, 19, 69, 6, 36, 3, 69, 82, 65, 207, + 242, 32, 80, 5, 217, 226, 26, 7, 32, 87, 73, 84, 72, 32, 70, 193, 11, + 148, 1, 16, 65, 68, 73, 65, 78, 32, 83, 89, 76, 76, 65, 66, 73, 67, 83, + 32, 148, 49, 2, 67, 69, 94, 68, 172, 152, 23, 3, 78, 69, 68, 139, 225, 9, + 79, 172, 11, 226, 1, 65, 190, 1, 66, 162, 2, 67, 242, 8, 69, 50, 70, 198, + 4, 72, 38, 73, 30, 75, 134, 1, 76, 82, 77, 174, 1, 78, 202, 4, 81, 178, + 1, 79, 194, 1, 80, 70, 82, 142, 1, 83, 194, 4, 84, 246, 3, 87, 254, 5, + 89, 223, 152, 17, 71, 21, 90, 65, 30, 73, 40, 10, 84, 72, 65, 80, 65, 83, + 67, 65, 78, 32, 242, 190, 33, 78, 3, 89, 7, 178, 191, 33, 73, 3, 89, 5, + 133, 150, 23, 5, 86, 73, 76, 73, 75, 4, 238, 190, 33, 77, 3, 83, 42, 156, + 1, 9, 76, 65, 67, 75, 70, 79, 79, 84, 32, 172, 226, 18, 9, 73, 66, 76, + 69, 45, 67, 82, 69, 69, 253, 180, 7, 10, 69, 65, 86, 69, 82, 32, 68, 69, + 78, 69, 36, 82, 87, 158, 208, 11, 75, 2, 78, 198, 236, 21, 65, 2, 69, 2, + 73, 2, 79, 3, 83, 11, 222, 188, 33, 65, 2, 69, 2, 73, 3, 79, 141, 3, 82, + 65, 186, 42, 87, 206, 155, 8, 72, 218, 182, 22, 79, 182, 56, 73, 207, + 134, 2, 69, 241, 2, 48, 6, 82, 82, 73, 69, 82, 32, 219, 180, 31, 65, 234, + 2, 170, 1, 68, 122, 71, 94, 72, 46, 73, 46, 74, 82, 75, 30, 78, 66, 83, + 66, 80, 2, 90, 58, 84, 38, 76, 132, 1, 2, 67, 72, 2, 77, 2, 82, 2, 87, 2, + 89, 171, 157, 33, 69, 32, 46, 69, 202, 5, 76, 2, 90, 255, 179, 33, 73, 6, + 26, 78, 171, 185, 33, 69, 4, 166, 210, 16, 69, 181, 191, 6, 2, 84, 65, + 30, 254, 4, 72, 174, 234, 20, 87, 166, 136, 7, 65, 154, 129, 5, 69, 150, + 64, 73, 2, 79, 3, 85, 19, 162, 4, 87, 170, 157, 33, 69, 215, 22, 73, 5, + 209, 223, 13, 6, 78, 73, 84, 73, 65, 76, 26, 202, 3, 74, 234, 243, 32, + 69, 222, 61, 87, 186, 2, 65, 2, 73, 2, 79, 3, 85, 26, 154, 1, 75, 227, 1, + 72, 14, 198, 246, 32, 69, 150, 64, 65, 2, 71, 2, 73, 2, 79, 3, 85, 26, + 62, 72, 202, 245, 32, 69, 150, 64, 65, 2, 73, 2, 79, 3, 85, 15, 198, 245, + 32, 69, 150, 64, 65, 2, 73, 2, 79, 3, 85, 72, 34, 76, 70, 84, 66, 72, 3, + 83, 24, 130, 1, 72, 234, 243, 32, 69, 150, 64, 65, 2, 73, 2, 79, 3, 85, + 24, 62, 83, 234, 243, 32, 69, 150, 64, 65, 2, 73, 2, 79, 3, 85, 12, 230, + 243, 32, 69, 150, 64, 65, 2, 73, 2, 79, 3, 85, 7, 236, 29, 4, 65, 83, 84, + 69, 215, 149, 33, 78, 51, 74, 65, 22, 73, 190, 231, 30, 85, 250, 11, 79, + 186, 79, 87, 203, 239, 1, 69, 7, 251, 171, 31, 65, 33, 40, 4, 78, 65, 76, + 32, 139, 178, 33, 73, 28, 160, 1, 2, 68, 79, 134, 1, 82, 78, 83, 150, + 221, 13, 71, 186, 2, 65, 132, 165, 3, 6, 66, 79, 84, 84, 79, 77, 0, 3, + 84, 79, 80, 202, 205, 12, 80, 211, 203, 2, 77, 6, 44, 5, 85, 66, 76, 69, + 32, 195, 212, 23, 87, 4, 232, 193, 6, 12, 83, 72, 79, 82, 84, 32, 86, 69, + 82, 84, 73, 67, 131, 159, 7, 65, 6, 38, 73, 253, 229, 31, 3, 65, 73, 83, + 4, 218, 132, 17, 71, 139, 170, 16, 78, 4, 184, 199, 24, 4, 77, 65, 76, + 76, 129, 202, 6, 4, 72, 79, 82, 84, 4, 198, 229, 25, 89, 139, 201, 7, 75, + 7, 170, 174, 33, 73, 3, 78, 39, 66, 87, 234, 27, 65, 230, 210, 30, 79, + 182, 56, 73, 207, 134, 2, 69, 19, 182, 250, 11, 65, 150, 244, 18, 79, + 182, 56, 73, 207, 134, 2, 69, 49, 142, 7, 72, 154, 20, 65, 66, 87, 166, + 210, 30, 79, 182, 56, 73, 207, 134, 2, 69, 43, 70, 69, 38, 79, 238, 25, + 65, 66, 87, 218, 138, 31, 73, 207, 134, 2, 72, 7, 229, 133, 26, 4, 68, + 73, 65, 76, 7, 11, 79, 5, 161, 233, 31, 8, 83, 69, 45, 67, 82, 69, 69, + 32, 149, 1, 164, 1, 8, 45, 67, 82, 69, 69, 32, 84, 72, 38, 65, 250, 2, + 71, 76, 2, 78, 71, 48, 4, 85, 78, 65, 86, 142, 20, 79, 30, 87, 218, 138, + 31, 73, 206, 134, 2, 69, 3, 72, 6, 150, 163, 31, 73, 207, 134, 2, 69, 63, + 104, 6, 83, 75, 65, 80, 73, 32, 188, 1, 7, 84, 84, 73, 76, 73, 75, 32, + 206, 160, 31, 65, 207, 134, 2, 89, 30, 70, 83, 86, 87, 210, 17, 67, 2, + 75, 2, 77, 2, 78, 2, 84, 3, 89, 14, 220, 230, 27, 2, 75, 87, 178, 124, + 67, 2, 80, 2, 84, 182, 213, 2, 87, 187, 113, 45, 4, 194, 136, 33, 79, + 191, 28, 65, 24, 30, 72, 1, 3, 83, 72, 82, 12, 202, 229, 27, 65, 174, + 130, 3, 79, 183, 56, 73, 19, 38, 65, 162, 231, 30, 79, 183, 56, 73, 9, + 210, 159, 31, 65, 207, 134, 2, 73, 15, 206, 228, 27, 65, 174, 130, 3, 79, + 183, 56, 73, 18, 224, 9, 3, 73, 75, 32, 149, 243, 22, 2, 85, 84, 33, 68, + 7, 74, 73, 66, 87, 65, 89, 32, 210, 164, 33, 78, 2, 79, 3, 89, 24, 74, + 78, 166, 176, 29, 83, 226, 243, 3, 67, 2, 75, 2, 77, 2, 80, 3, 84, 11, + 11, 87, 8, 246, 228, 30, 79, 183, 56, 73, 39, 206, 4, 87, 166, 13, 65, + 38, 79, 246, 138, 31, 73, 207, 134, 2, 69, 39, 104, 7, 45, 67, 82, 69, + 69, 32, 82, 146, 14, 87, 182, 2, 65, 230, 210, 30, 79, 182, 56, 73, 207, + 134, 2, 69, 4, 210, 139, 33, 87, 215, 22, 69, 125, 94, 65, 218, 1, 72, + 138, 1, 79, 238, 2, 87, 154, 175, 11, 80, 250, 229, 19, 73, 207, 134, 2, + 69, 43, 26, 89, 195, 154, 31, 65, 37, 25, 4, 73, 83, 73, 32, 34, 70, 72, + 54, 74, 218, 4, 83, 198, 135, 33, 89, 202, 18, 84, 147, 1, 77, 10, 166, + 225, 30, 79, 130, 191, 2, 65, 2, 69, 3, 73, 6, 214, 208, 29, 85, 159, + 207, 3, 73, 37, 70, 87, 202, 13, 79, 174, 222, 11, 65, 202, 172, 19, 73, + 207, 134, 2, 69, 16, 198, 13, 79, 150, 208, 27, 65, 226, 186, 3, 73, 207, + 134, 2, 69, 15, 80, 12, 85, 84, 72, 45, 83, 76, 65, 86, 69, 89, 32, 75, + 246, 157, 33, 79, 3, 89, 8, 226, 156, 33, 65, 2, 69, 2, 73, 3, 79, 117, + 110, 72, 190, 1, 76, 78, 84, 238, 8, 65, 66, 87, 226, 164, 11, 89, 198, + 173, 19, 79, 182, 56, 73, 207, 134, 2, 69, 39, 108, 7, 45, 67, 82, 69, + 69, 32, 84, 226, 4, 87, 222, 213, 27, 65, 174, 130, 3, 79, 182, 56, 73, + 207, 134, 2, 69, 16, 11, 72, 17, 174, 218, 27, 65, 174, 130, 3, 79, 182, + 56, 73, 207, 134, 2, 69, 12, 11, 72, 12, 142, 220, 30, 79, 174, 168, 2, + 87, 214, 22, 65, 2, 69, 3, 73, 24, 50, 72, 158, 154, 33, 65, 2, 69, 2, + 73, 3, 79, 17, 238, 216, 27, 65, 174, 130, 3, 79, 174, 168, 2, 87, 214, + 22, 69, 3, 73, 224, 1, 54, 69, 218, 3, 79, 174, 226, 11, 65, 203, 172, + 19, 73, 185, 1, 17, 2, 83, 84, 182, 1, 44, 6, 45, 67, 82, 69, 69, 32, + 251, 2, 69, 180, 1, 110, 76, 66, 77, 2, 80, 2, 89, 16, 2, 78, 87, 38, 82, + 62, 83, 26, 67, 2, 75, 18, 84, 26, 70, 199, 4, 87, 27, 178, 6, 87, 250, + 207, 27, 65, 174, 130, 3, 79, 131, 191, 2, 69, 17, 243, 5, 87, 6, 218, + 213, 27, 65, 175, 193, 5, 69, 13, 154, 167, 31, 87, 202, 239, 1, 65, 2, + 69, 2, 73, 3, 79, 28, 22, 72, 239, 4, 87, 14, 235, 4, 87, 16, 22, 72, + 199, 4, 87, 2, 159, 166, 31, 87, 2, 135, 240, 22, 82, 31, 11, 79, 29, 41, + 8, 68, 83, 45, 67, 82, 69, 69, 32, 26, 56, 2, 84, 72, 201, 149, 31, 6, + 70, 73, 78, 65, 76, 32, 25, 50, 87, 154, 148, 33, 65, 2, 69, 2, 73, 3, + 79, 14, 234, 210, 27, 65, 174, 130, 3, 79, 182, 56, 73, 251, 239, 1, 69, + 61, 92, 6, 45, 67, 82, 69, 69, 32, 150, 1, 65, 38, 79, 30, 87, 218, 138, + 31, 73, 207, 134, 2, 69, 24, 110, 80, 194, 209, 30, 67, 2, 75, 2, 76, 2, + 77, 2, 78, 2, 83, 2, 84, 2, 89, 214, 161, 2, 79, 247, 30, 87, 4, 190, + 162, 31, 87, 215, 208, 1, 79, 9, 150, 139, 31, 65, 207, 134, 2, 89, 7, + 190, 145, 33, 79, 3, 89, 14, 246, 207, 27, 65, 174, 130, 3, 79, 182, 56, + 73, 207, 134, 2, 69, 10, 26, 76, 203, 144, 33, 82, 9, 26, 32, 239, 162, + 9, 76, 4, 222, 217, 21, 67, 207, 208, 9, 84, 4, 178, 249, 32, 76, 215, + 22, 89, 4, 180, 247, 14, 3, 73, 84, 85, 253, 241, 7, 3, 82, 73, 67, 124, + 140, 1, 2, 68, 32, 102, 69, 72, 11, 73, 65, 78, 32, 76, 69, 84, 84, 69, + 82, 32, 210, 3, 79, 62, 80, 90, 82, 181, 250, 26, 4, 32, 83, 76, 73, 6, + 52, 5, 73, 78, 68, 69, 88, 157, 129, 32, 2, 70, 73, 5, 153, 255, 31, 6, + 32, 68, 73, 86, 73, 68, 6, 26, 84, 147, 131, 21, 32, 5, 209, 136, 10, 6, + 32, 73, 78, 83, 69, 82, 98, 196, 1, 2, 67, 45, 38, 76, 22, 77, 50, 78, + 38, 83, 46, 84, 22, 85, 230, 213, 3, 65, 2, 68, 2, 69, 2, 71, 2, 75, 2, + 80, 214, 208, 25, 82, 218, 220, 1, 73, 206, 134, 2, 66, 2, 79, 2, 81, 3, + 88, 4, 226, 163, 26, 49, 159, 148, 3, 51, 7, 139, 215, 3, 68, 11, 11, 66, + 9, 226, 138, 33, 50, 2, 51, 3, 52, 9, 190, 138, 33, 68, 2, 71, 3, 78, 13, + 162, 214, 3, 72, 2, 84, 251, 179, 29, 83, 7, 247, 213, 3, 84, 13, 11, 85, + 11, 11, 85, 9, 194, 137, 33, 50, 2, 51, 3, 85, 4, 148, 128, 32, 6, 85, + 83, 69, 76, 32, 72, 139, 137, 1, 78, 4, 152, 230, 26, 6, 32, 83, 84, 82, + 69, 65, 173, 164, 5, 7, 69, 78, 84, 82, 89, 32, 83, 4, 198, 240, 26, 73, + 155, 251, 5, 79, 9, 29, 5, 32, 70, 65, 67, 69, 7, 33, 6, 32, 87, 73, 84, + 72, 32, 4, 132, 229, 6, 2, 84, 69, 157, 132, 24, 6, 87, 82, 89, 32, 83, + 77, 108, 88, 16, 67, 65, 83, 73, 65, 78, 32, 65, 76, 66, 65, 78, 73, 65, + 78, 32, 159, 172, 29, 84, 106, 60, 7, 76, 69, 84, 84, 69, 82, 32, 189, + 160, 27, 2, 67, 73, 104, 174, 2, 65, 34, 67, 146, 1, 68, 78, 69, 34, 71, + 46, 73, 46, 74, 34, 75, 34, 76, 34, 80, 34, 83, 74, 84, 62, 89, 46, 90, + 140, 189, 16, 2, 81, 65, 166, 173, 6, 77, 208, 156, 6, 3, 86, 69, 89, + 182, 189, 2, 70, 220, 18, 3, 78, 79, 87, 146, 19, 82, 234, 21, 88, 150, + 46, 79, 202, 26, 66, 225, 24, 3, 72, 69, 89, 4, 194, 202, 32, 79, 167, + 28, 76, 16, 34, 65, 34, 72, 49, 2, 89, 65, 4, 250, 178, 32, 89, 215, 79, + 82, 8, 186, 205, 27, 65, 174, 163, 5, 79, 203, 17, 73, 4, 254, 129, 33, + 87, 3, 89, 8, 42, 90, 134, 186, 31, 89, 139, 171, 1, 65, 4, 202, 245, 31, + 89, 167, 122, 65, 4, 194, 177, 32, 89, 215, 79, 66, 4, 136, 214, 31, 2, + 72, 69, 151, 154, 1, 73, 6, 166, 198, 31, 82, 210, 106, 87, 251, 76, 78, + 4, 134, 244, 31, 72, 191, 14, 65, 4, 238, 129, 32, 73, 195, 69, 65, 4, + 138, 176, 32, 65, 159, 51, 89, 4, 142, 1, 73, 223, 174, 32, 69, 8, 34, + 72, 229, 251, 32, 2, 69, 89, 6, 142, 220, 19, 65, 167, 145, 13, 79, 6, + 38, 73, 198, 242, 31, 89, 159, 78, 65, 2, 223, 197, 32, 87, 4, 132, 184, + 32, 2, 65, 89, 1, 2, 79, 87, 6, 142, 223, 15, 72, 199, 177, 4, 65, 16, + 72, 2, 68, 73, 32, 2, 78, 84, 180, 155, 31, 3, 76, 84, 73, 207, 77, 82, + 4, 162, 246, 31, 32, 199, 100, 76, 8, 32, 2, 82, 69, 227, 245, 31, 32, 6, + 44, 5, 76, 73, 78, 69, 32, 207, 226, 4, 32, 4, 174, 154, 21, 76, 255, + 252, 9, 79, 252, 5, 102, 65, 170, 17, 69, 134, 8, 73, 150, 1, 79, 140, + 152, 4, 6, 82, 73, 83, 84, 77, 65, 195, 222, 18, 85, 198, 2, 66, 73, 32, + 4, 75, 77, 65, 32, 148, 6, 2, 77, 32, 131, 8, 82, 4, 226, 188, 32, 78, + 211, 61, 82, 142, 1, 156, 1, 7, 76, 69, 84, 84, 69, 82, 32, 142, 3, 83, + 98, 86, 170, 255, 22, 68, 170, 171, 7, 81, 236, 90, 5, 77, 65, 65, 89, + 89, 144, 174, 1, 2, 65, 85, 3, 79, 76, 202, 1, 68, 54, 78, 54, 84, 54, + 89, 142, 162, 28, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 76, 2, 80, 182, 228, + 2, 72, 2, 77, 2, 82, 2, 83, 2, 86, 2, 87, 146, 237, 1, 65, 186, 2, 69, 2, + 73, 3, 85, 8, 166, 163, 28, 68, 182, 228, 2, 72, 147, 237, 1, 65, 8, 166, + 135, 31, 71, 2, 78, 2, 89, 147, 237, 1, 65, 8, 190, 162, 28, 84, 182, + 228, 2, 72, 147, 237, 1, 65, 4, 190, 134, 31, 89, 147, 237, 1, 65, 8, 40, + 4, 73, 71, 78, 32, 195, 188, 21, 69, 6, 142, 143, 29, 67, 226, 182, 1, + 86, 223, 234, 1, 65, 26, 64, 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, + 203, 194, 30, 73, 24, 238, 139, 29, 65, 182, 25, 85, 210, 200, 1, 69, 2, + 73, 3, 79, 166, 1, 236, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, + 83, 73, 71, 78, 32, 112, 7, 76, 69, 84, 84, 69, 82, 32, 152, 4, 12, 80, + 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 60, 11, 86, 79, 87, 69, 76, + 32, 83, 73, 71, 78, 32, 175, 254, 30, 68, 14, 72, 6, 70, 73, 78, 65, 76, + 32, 138, 239, 32, 76, 2, 82, 2, 87, 3, 89, 6, 234, 240, 32, 78, 86, 72, + 3, 77, 104, 132, 2, 6, 70, 73, 78, 65, 76, 32, 110, 78, 50, 77, 78, 80, + 146, 195, 11, 66, 198, 231, 5, 68, 234, 191, 2, 83, 166, 252, 10, 65, + 152, 191, 1, 2, 67, 72, 2, 71, 2, 74, 2, 75, 2, 84, 254, 68, 72, 2, 76, + 2, 82, 2, 86, 2, 89, 186, 2, 69, 2, 73, 2, 79, 3, 85, 22, 254, 246, 30, + 78, 198, 186, 1, 83, 194, 60, 67, 146, 1, 71, 2, 75, 2, 76, 2, 80, 2, 82, + 2, 84, 3, 89, 14, 46, 71, 34, 72, 134, 215, 32, 85, 215, 22, 65, 4, 162, + 215, 32, 85, 215, 22, 65, 6, 130, 215, 32, 85, 158, 20, 74, 187, 2, 65, + 6, 242, 234, 32, 72, 2, 80, 187, 2, 65, 8, 190, 136, 11, 83, 246, 142, + 12, 68, 45, 4, 84, 82, 73, 80, 20, 238, 135, 29, 65, 142, 222, 1, 73, + 186, 198, 1, 79, 2, 85, 191, 44, 69, 14, 72, 7, 65, 67, 84, 69, 82, 32, + 84, 49, 7, 84, 32, 87, 73, 84, 72, 32, 8, 140, 223, 9, 3, 65, 66, 85, + 211, 245, 22, 73, 6, 128, 1, 13, 85, 80, 87, 65, 82, 68, 83, 32, 84, 82, + 69, 78, 68, 149, 214, 24, 12, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, + 82, 5, 233, 234, 6, 6, 32, 65, 78, 68, 32, 89, 234, 2, 80, 2, 67, 75, 82, + 69, 90, 82, 224, 247, 4, 2, 83, 84, 241, 219, 14, 2, 81, 85, 6, 56, 8, + 69, 82, 32, 66, 79, 65, 82, 68, 151, 167, 32, 32, 5, 223, 247, 29, 32, 4, + 184, 215, 26, 4, 83, 69, 32, 87, 177, 231, 4, 9, 82, 73, 78, 71, 32, 77, + 69, 71, 65, 220, 2, 40, 5, 79, 75, 69, 69, 32, 143, 5, 82, 216, 2, 46, + 76, 1, 7, 83, 77, 65, 76, 76, 32, 76, 172, 1, 33, 6, 69, 84, 84, 69, 82, + 32, 172, 1, 170, 1, 68, 74, 72, 74, 78, 70, 83, 62, 84, 54, 71, 2, 76, 2, + 77, 0, 2, 81, 85, 2, 87, 2, 89, 158, 224, 32, 75, 186, 2, 65, 2, 69, 2, + 73, 2, 79, 2, 85, 3, 86, 14, 222, 226, 32, 76, 186, 2, 65, 2, 69, 2, 73, + 2, 79, 2, 85, 3, 86, 14, 150, 226, 32, 78, 186, 2, 65, 2, 69, 2, 73, 2, + 79, 2, 85, 3, 86, 14, 166, 240, 28, 65, 226, 243, 3, 69, 2, 73, 2, 79, 2, + 85, 3, 86, 15, 194, 227, 32, 65, 2, 69, 2, 73, 2, 79, 2, 85, 3, 86, 30, + 50, 76, 2, 83, 214, 226, 32, 65, 2, 69, 3, 73, 12, 210, 226, 32, 65, 2, + 69, 2, 73, 2, 79, 2, 85, 3, 86, 4, 48, 6, 89, 32, 66, 76, 79, 83, 135, + 206, 31, 73, 2, 255, 208, 32, 83, 12, 96, 2, 76, 68, 174, 222, 7, 32, + 232, 239, 2, 2, 80, 77, 228, 193, 20, 2, 67, 75, 151, 129, 1, 82, 5, 213, + 128, 28, 7, 82, 69, 78, 32, 67, 82, 79, 60, 92, 8, 82, 65, 83, 77, 73, + 65, 78, 32, 222, 253, 4, 80, 249, 203, 11, 5, 67, 79, 76, 65, 84, 56, 52, + 7, 76, 69, 84, 84, 69, 82, 32, 243, 134, 21, 78, 42, 224, 1, 6, 67, 85, + 82, 76, 69, 68, 30, 83, 202, 131, 21, 68, 34, 76, 254, 194, 1, 82, 134, + 212, 2, 65, 50, 71, 90, 90, 98, 89, 154, 193, 1, 72, 234, 5, 75, 130, 76, + 66, 190, 173, 4, 78, 254, 1, 84, 2, 87, 202, 103, 80, 171, 4, 77, 2, 161, + 223, 31, 2, 32, 87, 6, 176, 131, 21, 6, 77, 65, 76, 76, 32, 65, 172, 210, + 5, 2, 65, 77, 139, 136, 5, 72, 232, 4, 66, 78, 20, 2, 82, 67, 233, 40, 7, + 84, 89, 83, 67, 65, 80, 69, 2, 247, 186, 32, 69, 226, 4, 28, 2, 76, 69, + 239, 39, 85, 220, 4, 30, 32, 181, 6, 2, 68, 32, 24, 244, 1, 5, 87, 73, + 84, 72, 32, 161, 133, 18, 49, 68, 73, 86, 73, 68, 69, 68, 32, 66, 89, 32, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 66, 65, 82, 32, 65, 78, 68, + 32, 84, 79, 80, 32, 72, 65, 76, 70, 32, 68, 73, 86, 73, 68, 69, 68, 32, + 66, 89, 22, 142, 2, 76, 46, 83, 108, 22, 84, 87, 79, 32, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 32, 83, 84, 82, 79, 75, 69, 83, 44, 6, 85, 80, + 80, 69, 82, 32, 44, 17, 65, 76, 76, 32, 66, 85, 84, 32, 85, 80, 80, 69, + 82, 32, 76, 69, 70, 238, 230, 25, 86, 190, 227, 3, 82, 231, 58, 72, 4, + 138, 204, 29, 69, 49, 4, 79, 87, 69, 82, 4, 104, 11, 77, 65, 76, 76, 32, + 67, 73, 82, 67, 76, 69, 221, 5, 10, 85, 80, 69, 82, 73, 77, 80, 79, 83, + 69, 2, 173, 225, 29, 6, 32, 84, 79, 32, 84, 72, 4, 40, 4, 82, 73, 71, 72, + 227, 202, 29, 72, 2, 245, 202, 29, 10, 84, 32, 81, 85, 65, 68, 82, 65, + 78, 84, 196, 4, 230, 2, 65, 186, 1, 66, 58, 67, 230, 1, 68, 246, 1, 72, + 250, 2, 73, 210, 10, 75, 190, 2, 76, 38, 77, 136, 1, 7, 78, 85, 77, 66, + 69, 82, 32, 192, 4, 17, 79, 80, 69, 78, 32, 67, 69, 78, 84, 82, 69, 32, + 69, 73, 71, 72, 84, 54, 80, 114, 82, 50, 84, 78, 87, 224, 228, 9, 4, 90, + 69, 82, 79, 222, 253, 15, 69, 250, 129, 4, 86, 130, 65, 71, 190, 110, 83, + 199, 160, 1, 88, 6, 100, 12, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, + 69, 249, 166, 29, 7, 83, 84, 69, 82, 73, 83, 75, 4, 160, 220, 8, 11, 45, + 82, 79, 84, 65, 84, 69, 68, 32, 68, 73, 211, 218, 22, 32, 4, 32, 2, 79, + 76, 139, 244, 30, 85, 2, 175, 225, 13, 68, 16, 60, 4, 82, 79, 83, 83, + 210, 2, 32, 142, 205, 32, 67, 3, 68, 10, 26, 32, 219, 193, 1, 73, 8, 64, + 6, 70, 79, 82, 77, 69, 69, 201, 226, 30, 4, 80, 79, 77, 77, 7, 33, 6, 32, + 87, 73, 84, 72, 32, 4, 254, 177, 30, 70, 251, 78, 84, 30, 34, 73, 70, 79, + 183, 232, 30, 65, 24, 152, 188, 4, 8, 86, 73, 83, 73, 79, 78, 32, 83, + 247, 163, 26, 71, 4, 64, 10, 76, 76, 65, 82, 32, 83, 73, 71, 78, 32, 227, + 162, 29, 84, 2, 197, 230, 18, 13, 87, 73, 84, 72, 32, 79, 86, 69, 82, 76, + 65, 73, 68, 64, 212, 1, 6, 65, 78, 71, 85, 76, 32, 184, 151, 12, 20, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 32, 66, 65, 82, 32, 87, 73, 84, 72, 32, + 78, 152, 181, 9, 4, 69, 65, 86, 89, 189, 158, 6, 8, 85, 77, 65, 78, 32, + 70, 73, 71, 58, 110, 67, 160, 128, 20, 5, 73, 69, 85, 78, 71, 42, 72, 30, + 75, 66, 77, 34, 78, 34, 80, 62, 82, 30, 83, 27, 84, 8, 254, 255, 19, 72, + 157, 3, 4, 73, 69, 85, 67, 116, 220, 1, 9, 68, 69, 79, 71, 82, 65, 80, + 72, 32, 212, 8, 27, 84, 65, 76, 73, 67, 32, 76, 65, 84, 73, 78, 32, 67, + 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, 165, 176, 26, 9, + 78, 70, 79, 82, 77, 65, 84, 73, 79, 110, 178, 1, 65, 110, 67, 90, 69, 86, + 70, 62, 72, 38, 75, 70, 76, 50, 77, 86, 78, 62, 81, 30, 82, 74, 83, 246, + 128, 20, 84, 50, 87, 146, 204, 1, 73, 172, 24, 2, 80, 82, 231, 193, 9, + 79, 8, 130, 129, 20, 76, 180, 132, 1, 3, 67, 67, 69, 196, 212, 6, 3, 84, + 84, 69, 245, 17, 5, 68, 86, 65, 78, 84, 8, 26, 79, 159, 208, 29, 69, 6, + 168, 180, 10, 2, 82, 82, 146, 204, 9, 78, 175, 179, 12, 80, 8, 206, 128, + 20, 78, 246, 253, 8, 65, 148, 131, 3, 5, 88, 67, 69, 76, 76, 219, 24, 73, + 10, 218, 128, 20, 73, 128, 169, 5, 2, 69, 77, 131, 162, 6, 79, 4, 214, + 203, 28, 73, 203, 251, 2, 65, 4, 240, 141, 7, 8, 73, 78, 68, 69, 82, 71, + 65, 82, 199, 233, 21, 79, 6, 234, 255, 19, 65, 130, 197, 11, 79, 179, 83, + 69, 8, 38, 69, 130, 161, 31, 65, 199, 81, 79, 4, 128, 169, 31, 3, 68, 73, + 67, 251, 15, 84, 6, 26, 73, 139, 170, 31, 65, 4, 162, 151, 32, 71, 231, + 19, 78, 2, 237, 218, 27, 2, 85, 69, 8, 26, 69, 195, 150, 32, 73, 6, 242, + 254, 19, 83, 205, 225, 7, 2, 76, 73, 22, 90, 69, 38, 85, 164, 230, 13, 2, + 67, 72, 166, 152, 6, 79, 22, 80, 34, 84, 211, 180, 11, 73, 4, 178, 132, + 10, 67, 215, 234, 20, 86, 6, 198, 255, 19, 80, 180, 177, 4, 3, 73, 84, + 65, 223, 142, 8, 78, 4, 150, 191, 32, 67, 3, 82, 98, 116, 8, 65, 84, 65, + 75, 65, 78, 65, 32, 133, 1, 16, 79, 82, 69, 65, 78, 32, 67, 72, 65, 82, + 65, 67, 84, 69, 82, 32, 94, 194, 208, 10, 72, 2, 75, 2, 77, 2, 78, 2, 82, + 2, 83, 2, 84, 126, 87, 46, 89, 154, 236, 21, 65, 2, 69, 2, 73, 2, 79, 3, + 85, 4, 216, 214, 15, 3, 74, 85, 69, 165, 199, 16, 4, 67, 72, 65, 77, 106, + 166, 211, 26, 65, 203, 218, 3, 69, 4, 100, 19, 85, 76, 84, 73, 80, 76, + 73, 67, 65, 84, 73, 79, 78, 32, 83, 73, 71, 78, 32, 191, 184, 30, 73, 2, + 129, 84, 4, 87, 73, 84, 72, 98, 50, 69, 46, 70, 98, 83, 94, 84, 151, 251, + 19, 78, 6, 180, 1, 3, 73, 71, 72, 191, 222, 24, 76, 30, 28, 3, 73, 70, + 84, 35, 79, 6, 214, 1, 89, 203, 231, 30, 69, 24, 142, 2, 82, 255, 250, + 19, 85, 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 4, 11, 84, 4, 104, 2, 89, + 32, 191, 231, 30, 69, 52, 56, 2, 69, 78, 32, 4, 72, 73, 82, 84, 29, 2, + 87, 69, 5, 11, 32, 2, 135, 252, 24, 79, 24, 74, 89, 223, 230, 30, 69, 24, + 26, 78, 163, 187, 31, 76, 22, 17, 2, 84, 89, 23, 11, 32, 20, 72, 2, 79, + 78, 218, 201, 30, 70, 30, 83, 42, 84, 190, 83, 78, 211, 110, 69, 4, 226, + 250, 24, 32, 151, 188, 7, 69, 2, 213, 163, 30, 8, 32, 80, 79, 73, 78, 84, + 69, 68, 8, 184, 146, 17, 3, 79, 83, 84, 246, 223, 6, 65, 188, 189, 2, 8, + 69, 82, 80, 69, 78, 68, 73, 67, 203, 131, 4, 76, 4, 128, 139, 29, 3, 73, + 78, 71, 255, 151, 1, 69, 6, 52, 7, 82, 73, 65, 78, 71, 76, 69, 151, 224, + 25, 73, 5, 163, 204, 21, 32, 6, 44, 5, 72, 73, 84, 69, 32, 135, 180, 32, + 90, 4, 206, 215, 30, 66, 211, 24, 83, 6, 226, 198, 26, 77, 252, 138, 4, + 6, 76, 65, 84, 73, 79, 78, 233, 158, 1, 3, 83, 32, 84, 5, 233, 240, 30, + 6, 32, 65, 84, 32, 68, 85, 154, 18, 192, 1, 24, 67, 79, 77, 80, 65, 84, + 73, 66, 73, 76, 73, 84, 89, 32, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 144, 3, 8, 82, 65, 68, 73, 67, 65, 76, 32, 245, 17, 7, 83, 84, 82, 79, + 75, 69, 32, 236, 15, 24, 2, 50, 70, 75, 70, 188, 8, 34, 65, 194, 225, 10, + 56, 3, 57, 60, 202, 1, 49, 143, 182, 18, 48, 176, 7, 26, 65, 131, 225, + 10, 57, 176, 3, 134, 1, 54, 142, 182, 18, 48, 2, 49, 2, 50, 2, 51, 2, 52, + 2, 53, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 231, 238, 8, 68, 28, + 130, 175, 32, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, + 2, 57, 2, 65, 2, 66, 2, 67, 3, 68, 230, 1, 210, 1, 66, 126, 67, 226, 4, + 68, 62, 69, 50, 70, 34, 71, 50, 72, 86, 74, 154, 1, 76, 62, 77, 130, 1, + 80, 46, 82, 78, 83, 182, 3, 84, 82, 87, 200, 197, 10, 2, 78, 69, 252, 16, + 4, 75, 78, 73, 70, 159, 225, 11, 79, 14, 74, 79, 192, 229, 10, 4, 82, 85, + 83, 72, 154, 218, 4, 65, 179, 139, 13, 76, 6, 230, 140, 10, 76, 170, 136, + 22, 78, 215, 22, 88, 56, 104, 12, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, + 68, 32, 162, 3, 73, 50, 76, 234, 168, 31, 79, 175, 78, 72, 44, 114, 69, + 38, 70, 50, 71, 38, 76, 34, 83, 94, 84, 214, 146, 14, 87, 42, 68, 246, + 149, 16, 66, 234, 117, 72, 135, 2, 67, 4, 222, 216, 30, 86, 203, 180, 1, + 65, 6, 146, 196, 30, 73, 214, 211, 1, 76, 235, 16, 82, 4, 234, 195, 22, + 79, 235, 160, 8, 65, 4, 194, 167, 31, 69, 175, 48, 79, 10, 174, 204, 6, + 73, 242, 253, 16, 65, 142, 194, 1, 72, 232, 249, 6, 3, 80, 69, 69, 215, + 11, 69, 6, 214, 10, 85, 176, 155, 10, 2, 65, 78, 143, 255, 3, 79, 4, 156, + 150, 20, 3, 86, 73, 76, 195, 255, 11, 84, 4, 214, 161, 17, 73, 171, 241, + 13, 79, 6, 220, 201, 23, 2, 73, 86, 194, 226, 2, 69, 227, 249, 5, 79, 10, + 196, 6, 2, 65, 84, 254, 136, 32, 87, 3, 89, 4, 198, 133, 31, 73, 247, 79, + 79, 8, 244, 5, 4, 82, 65, 83, 83, 255, 215, 28, 72, 10, 48, 2, 69, 65, + 218, 198, 27, 79, 175, 208, 3, 65, 6, 186, 8, 82, 171, 156, 32, 68, 10, + 72, 12, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 68, 32, 135, 151, 30, 65, + 8, 42, 84, 234, 142, 14, 68, 251, 167, 16, 69, 4, 194, 6, 85, 191, 154, + 14, 79, 12, 132, 221, 10, 3, 79, 78, 71, 197, 176, 15, 3, 65, 77, 69, 14, + 18, 69, 35, 79, 4, 174, 134, 32, 65, 159, 27, 83, 10, 148, 220, 10, 3, + 85, 78, 68, 158, 236, 12, 84, 166, 150, 7, 82, 147, 116, 79, 6, 200, 219, + 10, 2, 65, 87, 143, 243, 14, 69, 8, 34, 65, 233, 252, 27, 2, 69, 80, 6, + 202, 209, 31, 73, 214, 79, 77, 3, 80, 38, 122, 69, 90, 73, 186, 1, 78, + 196, 1, 4, 80, 73, 82, 73, 132, 214, 10, 4, 77, 65, 76, 76, 250, 222, 11, + 72, 219, 151, 9, 85, 8, 40, 4, 67, 79, 78, 68, 183, 150, 31, 65, 6, 11, + 32, 6, 230, 178, 30, 84, 203, 83, 79, 12, 60, 9, 77, 80, 76, 73, 70, 73, + 69, 68, 32, 207, 155, 32, 76, 10, 34, 72, 50, 87, 159, 161, 10, 89, 4, + 184, 139, 10, 3, 65, 76, 70, 251, 180, 17, 79, 4, 130, 194, 6, 65, 215, + 183, 21, 72, 6, 192, 1, 2, 79, 85, 211, 236, 31, 65, 8, 58, 85, 174, 142, + 24, 65, 230, 199, 1, 72, 135, 143, 3, 73, 2, 243, 187, 23, 82, 12, 26, + 65, 49, 2, 69, 83, 8, 176, 214, 10, 2, 76, 75, 1, 3, 84, 69, 82, 4, 131, + 214, 10, 84, 72, 110, 72, 162, 1, 80, 38, 83, 226, 161, 30, 84, 172, 247, + 1, 2, 66, 88, 2, 87, 2, 88, 86, 68, 2, 78, 3, 81, 29, 50, 80, 22, 90, + 136, 154, 32, 2, 88, 87, 87, 71, 5, 155, 154, 32, 87, 19, 50, 90, 150, + 162, 30, 87, 150, 248, 1, 71, 3, 84, 9, 146, 162, 30, 90, 151, 248, 1, + 80, 9, 130, 154, 32, 68, 2, 71, 3, 90, 21, 50, 87, 30, 90, 146, 153, 32, + 71, 2, 80, 3, 84, 7, 170, 153, 32, 71, 3, 90, 7, 186, 152, 32, 87, 87, + 90, 124, 62, 65, 194, 1, 73, 114, 79, 173, 181, 20, 4, 69, 65, 82, 32, 8, + 132, 1, 2, 80, 80, 252, 177, 18, 6, 83, 83, 73, 67, 65, 76, 241, 187, 12, + 14, 77, 83, 72, 69, 76, 76, 32, 77, 79, 66, 73, 76, 69, 32, 4, 144, 130, + 19, 5, 73, 78, 71, 32, 72, 199, 226, 1, 69, 6, 48, 6, 78, 75, 73, 78, 71, + 32, 207, 255, 30, 80, 4, 234, 198, 24, 71, 229, 169, 3, 6, 66, 69, 69, + 82, 32, 77, 108, 72, 2, 67, 75, 140, 10, 2, 83, 69, 236, 3, 2, 85, 68, + 227, 154, 29, 87, 70, 64, 6, 32, 70, 65, 67, 69, 32, 237, 2, 5, 87, 73, + 83, 69, 32, 48, 58, 69, 46, 70, 36, 2, 78, 73, 2, 79, 18, 83, 51, 84, 8, + 120, 2, 76, 69, 125, 4, 73, 71, 72, 84, 8, 178, 1, 73, 25, 3, 79, 85, 82, + 4, 155, 1, 78, 8, 26, 69, 125, 2, 73, 88, 4, 57, 2, 86, 69, 16, 38, 69, + 14, 87, 41, 3, 72, 82, 69, 4, 63, 78, 8, 24, 2, 69, 76, 27, 79, 4, 11, + 86, 4, 11, 69, 4, 196, 164, 28, 2, 32, 79, 213, 131, 2, 3, 45, 84, 72, + 22, 90, 67, 58, 68, 122, 71, 48, 5, 82, 73, 71, 72, 84, 226, 2, 84, 122, + 79, 247, 135, 30, 73, 4, 196, 1, 3, 76, 79, 83, 141, 99, 4, 79, 78, 84, + 79, 2, 141, 3, 26, 79, 87, 78, 87, 65, 82, 68, 83, 32, 65, 78, 68, 32, + 85, 80, 87, 65, 82, 68, 83, 32, 79, 80, 69, 78, 32, 2, 21, 3, 65, 80, 80, + 2, 133, 4, 2, 69, 68, 6, 228, 1, 14, 32, 65, 78, 68, 32, 76, 69, 70, 84, + 32, 83, 69, 77, 73, 45, 38, 87, 65, 82, 68, 83, 32, 65, 78, 68, 32, 76, + 69, 70, 84, 87, 65, 82, 68, 83, 32, 79, 80, 69, 78, 32, 67, 73, 82, 67, + 76, 69, 32, 65, 82, 82, 79, 87, 83, 2, 129, 184, 29, 6, 67, 73, 82, 67, + 76, 69, 5, 161, 83, 15, 32, 87, 73, 84, 72, 32, 67, 73, 82, 67, 76, 69, + 68, 32, 79, 4, 82, 79, 37, 16, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, + 65, 68, 69, 68, 32, 79, 2, 69, 6, 80, 32, 83, 69, 77, 73, 2, 21, 3, 80, + 69, 78, 2, 11, 32, 2, 161, 182, 29, 4, 67, 73, 82, 67, 26, 32, 2, 68, 32, + 167, 149, 31, 32, 24, 216, 1, 2, 83, 85, 66, 85, 254, 243, 18, 77, 180, + 3, 9, 76, 79, 67, 75, 32, 87, 73, 84, 72, 222, 192, 11, 66, 145, 147, 1, + 23, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 78, 32, 87, 73, 84, 72, + 32, 83, 69, 82, 73, 70, 8, 30, 66, 1, 3, 80, 69, 82, 4, 145, 177, 24, 3, + 83, 69, 84, 6, 82, 77, 33, 16, 78, 73, 79, 78, 32, 87, 73, 84, 72, 32, + 83, 69, 82, 73, 70, 83, 2, 197, 148, 24, 3, 66, 82, 69, 5, 221, 248, 30, + 9, 32, 65, 78, 68, 32, 83, 77, 65, 83, 11, 33, 6, 32, 87, 73, 84, 72, 32, + 8, 72, 4, 84, 79, 82, 78, 190, 162, 5, 76, 146, 151, 19, 83, 215, 161, 6, + 82, 2, 155, 140, 25, 65, 226, 9, 158, 1, 67, 82, 76, 98, 77, 162, 82, 78, + 220, 5, 2, 79, 75, 58, 80, 154, 19, 82, 138, 1, 85, 186, 165, 27, 87, + 160, 242, 2, 2, 70, 70, 234, 47, 73, 171, 51, 65, 6, 26, 75, 139, 149, 4, + 79, 4, 186, 214, 8, 82, 129, 151, 22, 4, 84, 65, 73, 76, 8, 44, 2, 79, + 78, 209, 187, 24, 3, 76, 73, 83, 7, 11, 32, 4, 146, 178, 25, 69, 171, + 203, 5, 83, 158, 6, 72, 7, 66, 73, 78, 73, 78, 71, 32, 166, 80, 77, 94, + 80, 239, 149, 31, 69, 142, 6, 214, 2, 65, 174, 2, 66, 134, 1, 67, 246, + 12, 68, 174, 9, 69, 146, 2, 70, 54, 71, 140, 9, 2, 72, 79, 82, 73, 216, + 1, 2, 75, 65, 162, 1, 76, 230, 13, 77, 250, 1, 78, 78, 79, 138, 2, 80, + 174, 1, 82, 244, 4, 5, 90, 73, 71, 90, 65, 166, 2, 83, 242, 3, 84, 238, + 2, 85, 148, 1, 9, 86, 69, 82, 84, 73, 67, 65, 76, 32, 36, 2, 87, 73, 183, + 1, 88, 24, 148, 1, 4, 67, 85, 84, 69, 86, 78, 168, 185, 24, 6, 83, 84, + 69, 82, 73, 83, 201, 172, 5, 14, 76, 77, 79, 83, 84, 32, 69, 81, 85, 65, + 76, 32, 84, 79, 10, 22, 45, 167, 33, 32, 4, 180, 164, 12, 6, 71, 82, 65, + 86, 69, 45, 195, 193, 3, 77, 6, 244, 2, 4, 84, 73, 67, 76, 177, 180, 3, + 4, 78, 85, 73, 84, 12, 42, 82, 129, 215, 29, 4, 73, 78, 68, 85, 10, 48, + 3, 69, 86, 69, 197, 228, 29, 3, 73, 68, 71, 7, 162, 252, 11, 45, 183, + 218, 17, 32, 142, 1, 142, 1, 65, 34, 76, 98, 79, 116, 8, 89, 82, 73, 76, + 76, 73, 67, 32, 184, 28, 11, 73, 82, 67, 85, 77, 70, 76, 69, 88, 32, 65, + 175, 238, 11, 69, 6, 162, 18, 82, 199, 131, 28, 78, 4, 41, 8, 79, 67, 75, + 87, 73, 83, 69, 32, 4, 184, 131, 12, 4, 82, 73, 78, 71, 239, 160, 16, 65, + 10, 76, 4, 77, 77, 65, 32, 189, 16, 10, 78, 74, 79, 73, 78, 73, 78, 71, + 32, 77, 6, 250, 229, 12, 65, 247, 251, 16, 66, 116, 252, 1, 8, 72, 85, + 78, 68, 82, 69, 68, 32, 32, 7, 76, 69, 84, 84, 69, 82, 32, 166, 5, 80, + 116, 5, 68, 65, 83, 73, 65, 38, 84, 106, 77, 206, 243, 2, 75, 132, 214, + 12, 15, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 66, 89, 217, + 241, 15, 2, 86, 90, 4, 194, 7, 77, 215, 158, 3, 84, 84, 238, 1, 66, 38, + 68, 50, 69, 82, 73, 106, 79, 22, 83, 66, 85, 30, 89, 214, 137, 3, 76, + 140, 5, 5, 77, 79, 78, 79, 71, 142, 18, 72, 202, 174, 12, 84, 190, 163, + 15, 90, 254, 82, 67, 2, 71, 182, 8, 70, 134, 14, 80, 2, 86, 158, 20, 75, + 187, 2, 65, 4, 174, 147, 6, 73, 199, 226, 25, 69, 4, 168, 155, 25, 3, 74, + 69, 82, 167, 218, 6, 69, 14, 58, 83, 230, 244, 31, 70, 2, 76, 2, 77, 2, + 78, 3, 82, 5, 183, 176, 30, 45, 11, 56, 8, 79, 84, 73, 70, 73, 69, 68, + 32, 151, 244, 31, 69, 6, 194, 145, 6, 66, 210, 226, 25, 65, 3, 69, 5, + 239, 243, 24, 77, 6, 26, 72, 155, 209, 15, 79, 4, 250, 251, 29, 67, 191, + 247, 1, 65, 5, 193, 153, 3, 2, 75, 82, 8, 142, 230, 27, 69, 190, 240, 3, + 65, 174, 28, 73, 3, 85, 8, 66, 65, 48, 4, 83, 73, 76, 73, 133, 212, 28, + 4, 79, 75, 82, 89, 4, 170, 246, 2, 89, 241, 175, 12, 3, 76, 65, 84, 2, + 145, 13, 5, 32, 80, 78, 69, 85, 10, 80, 2, 69, 78, 0, 7, 72, 79, 85, 83, + 65, 78, 68, 177, 8, 4, 73, 84, 76, 79, 2, 17, 2, 32, 77, 2, 169, 164, 21, + 5, 73, 76, 76, 73, 79, 110, 62, 69, 244, 1, 8, 73, 65, 69, 82, 69, 83, + 73, 83, 39, 79, 38, 68, 9, 86, 65, 78, 65, 71, 65, 82, 73, 32, 249, 133, + 31, 2, 76, 69, 36, 92, 7, 76, 69, 84, 84, 69, 82, 32, 240, 179, 25, 6, + 83, 73, 71, 78, 32, 65, 167, 204, 4, 68, 14, 214, 218, 31, 86, 162, 17, + 75, 2, 78, 2, 80, 2, 82, 186, 2, 65, 3, 85, 7, 246, 140, 27, 45, 151, + 186, 2, 32, 66, 58, 84, 128, 1, 4, 85, 66, 76, 69, 241, 4, 2, 87, 78, 14, + 38, 32, 149, 215, 15, 3, 84, 69, 68, 10, 64, 5, 65, 66, 79, 86, 69, 241, + 165, 6, 5, 66, 69, 76, 79, 87, 7, 151, 193, 31, 32, 48, 22, 32, 191, 4, + 68, 46, 230, 1, 66, 0, 10, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 26, + 77, 54, 79, 34, 80, 68, 2, 82, 73, 48, 5, 84, 73, 76, 68, 69, 80, 9, 86, + 69, 82, 84, 73, 67, 65, 76, 32, 174, 210, 15, 65, 42, 71, 166, 179, 4, + 76, 187, 228, 10, 67, 4, 229, 16, 2, 82, 69, 4, 21, 3, 65, 67, 82, 4, + 181, 193, 16, 2, 79, 78, 4, 230, 35, 80, 255, 224, 29, 86, 6, 238, 36, + 76, 205, 206, 7, 9, 65, 82, 69, 78, 84, 72, 69, 83, 69, 4, 156, 51, 4, + 71, 72, 84, 87, 139, 228, 9, 78, 7, 11, 32, 4, 44, 3, 76, 69, 70, 1, 4, + 82, 73, 71, 72, 2, 199, 205, 29, 84, 6, 178, 239, 11, 83, 211, 255, 13, + 76, 2, 141, 205, 15, 2, 32, 67, 4, 128, 41, 2, 32, 84, 227, 158, 30, 87, + 16, 76, 9, 78, 67, 76, 79, 83, 73, 78, 71, 32, 129, 193, 25, 4, 81, 85, + 65, 76, 14, 132, 1, 6, 67, 73, 82, 67, 76, 69, 22, 83, 216, 145, 6, 3, + 75, 69, 89, 160, 241, 1, 7, 85, 80, 87, 65, 82, 68, 32, 227, 166, 22, 68, + 5, 219, 254, 17, 32, 4, 134, 138, 25, 67, 195, 186, 5, 81, 4, 32, 2, 69, + 82, 135, 137, 5, 79, 2, 143, 74, 77, 126, 88, 17, 76, 65, 71, 79, 76, 73, + 84, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 143, 3, 82, 76, 238, 1, 68, + 30, 73, 46, 83, 50, 84, 182, 250, 5, 65, 22, 66, 94, 67, 134, 1, 70, 38, + 71, 238, 2, 77, 32, 2, 76, 74, 34, 78, 88, 2, 80, 79, 30, 82, 194, 2, 86, + 22, 89, 90, 90, 182, 199, 18, 72, 142, 243, 1, 85, 154, 253, 4, 79, 235, + 5, 75, 4, 238, 252, 5, 74, 31, 79, 11, 250, 253, 5, 78, 54, 79, 135, 182, + 25, 90, 8, 218, 254, 5, 77, 130, 4, 76, 243, 204, 20, 72, 4, 142, 131, 6, + 86, 255, 201, 25, 83, 50, 38, 65, 173, 3, 4, 69, 69, 75, 32, 36, 84, 5, + 78, 84, 72, 65, 32, 196, 1, 2, 86, 69, 153, 228, 27, 5, 80, 72, 69, 77, + 69, 24, 68, 6, 68, 73, 71, 73, 84, 32, 65, 7, 76, 69, 84, 84, 69, 82, 32, + 14, 202, 177, 16, 83, 142, 192, 13, 70, 70, 84, 62, 90, 143, 83, 79, 10, + 222, 202, 31, 86, 162, 17, 75, 2, 78, 2, 80, 187, 2, 65, 10, 18, 32, 67, + 45, 6, 26, 65, 215, 242, 15, 84, 4, 245, 143, 4, 4, 67, 67, 69, 78, 4, + 208, 220, 11, 6, 65, 67, 85, 84, 69, 45, 195, 231, 3, 77, 14, 148, 1, 8, + 77, 85, 83, 73, 67, 65, 76, 32, 150, 151, 4, 75, 250, 182, 2, 80, 174, 4, + 89, 249, 227, 3, 11, 68, 73, 65, 76, 89, 84, 73, 75, 65, 32, 84, 6, 26, + 84, 131, 135, 15, 80, 4, 218, 135, 15, 69, 35, 82, 6, 206, 200, 12, 79, + 216, 149, 18, 8, 77, 79, 84, 72, 69, 84, 73, 67, 163, 45, 82, 14, 26, 78, + 207, 179, 29, 83, 12, 52, 7, 86, 69, 82, 84, 69, 68, 32, 143, 222, 27, + 70, 10, 64, 2, 66, 82, 45, 10, 68, 79, 85, 66, 76, 69, 32, 65, 82, 67, 6, + 22, 69, 235, 37, 73, 4, 211, 181, 11, 86, 4, 167, 192, 29, 72, 8, 128, 1, + 16, 84, 65, 75, 65, 78, 65, 45, 72, 73, 82, 65, 71, 65, 78, 65, 32, 153, + 180, 17, 9, 86, 89, 75, 65, 32, 65, 66, 79, 86, 4, 146, 237, 9, 83, 35, + 86, 158, 1, 80, 5, 65, 84, 73, 78, 32, 156, 8, 3, 69, 70, 84, 184, 3, 2, + 73, 71, 83, 79, 106, 156, 1, 21, 76, 69, 84, 84, 69, 82, 32, 83, 77, 65, + 76, 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, 53, 13, 83, 77, 65, 76, 76, + 32, 76, 69, 84, 84, 69, 82, 32, 10, 218, 213, 31, 71, 2, 76, 2, 77, 2, + 78, 3, 82, 96, 226, 1, 65, 70, 67, 34, 69, 30, 70, 78, 73, 86, 76, 106, + 79, 2, 85, 134, 1, 82, 50, 84, 206, 131, 12, 83, 194, 134, 2, 66, 226, + 156, 2, 87, 158, 168, 15, 68, 2, 71, 2, 72, 2, 75, 2, 77, 2, 78, 2, 80, + 2, 86, 2, 88, 3, 90, 13, 142, 244, 2, 32, 146, 235, 12, 76, 166, 244, 15, + 69, 2, 79, 3, 86, 5, 221, 227, 11, 3, 32, 67, 69, 7, 206, 209, 31, 83, 3, + 84, 5, 185, 219, 26, 14, 76, 65, 84, 84, 69, 78, 69, 68, 32, 79, 80, 69, + 78, 32, 11, 37, 7, 78, 83, 85, 76, 65, 82, 32, 8, 206, 209, 31, 68, 2, + 71, 2, 82, 3, 84, 7, 136, 210, 15, 14, 32, 87, 73, 84, 72, 32, 68, 79, + 85, 66, 76, 69, 32, 77, 165, 172, 12, 3, 79, 78, 71, 7, 33, 6, 32, 87, + 73, 84, 72, 32, 4, 194, 243, 11, 68, 201, 187, 12, 15, 76, 73, 71, 72, + 84, 32, 67, 69, 78, 84, 82, 65, 76, 73, 90, 7, 11, 32, 4, 146, 210, 11, + 82, 227, 228, 17, 66, 5, 129, 26, 6, 85, 82, 78, 69, 68, 32, 32, 46, 32, + 213, 2, 6, 87, 65, 82, 68, 83, 32, 28, 154, 1, 65, 112, 12, 80, 65, 82, + 69, 78, 84, 72, 69, 83, 73, 83, 32, 226, 12, 72, 182, 1, 84, 177, 165, + 29, 11, 82, 73, 71, 72, 84, 32, 65, 82, 82, 79, 87, 12, 48, 4, 82, 82, + 79, 87, 233, 179, 29, 2, 78, 71, 8, 26, 72, 243, 179, 29, 32, 4, 225, + 179, 29, 3, 69, 65, 68, 4, 244, 204, 7, 4, 65, 66, 79, 86, 245, 204, 23, + 5, 66, 69, 76, 79, 87, 4, 230, 13, 72, 133, 198, 11, 5, 65, 82, 82, 79, + 87, 10, 52, 6, 65, 84, 85, 82, 69, 32, 169, 17, 2, 72, 84, 8, 238, 1, 76, + 23, 82, 10, 36, 3, 78, 71, 32, 251, 176, 30, 87, 8, 172, 7, 7, 68, 79, + 85, 66, 76, 69, 32, 246, 7, 83, 71, 86, 20, 52, 5, 65, 67, 82, 79, 78, + 145, 164, 25, 2, 73, 78, 19, 18, 32, 127, 45, 10, 34, 76, 22, 82, 183, + 176, 29, 66, 4, 41, 2, 69, 70, 4, 21, 3, 73, 71, 72, 4, 181, 160, 16, 6, + 84, 32, 72, 65, 76, 70, 6, 166, 246, 11, 71, 186, 2, 65, 139, 157, 3, 66, + 4, 152, 9, 9, 85, 77, 66, 69, 82, 32, 83, 73, 71, 177, 173, 11, 2, 79, + 84, 18, 136, 1, 17, 76, 68, 32, 80, 69, 82, 77, 73, 67, 32, 76, 69, 84, + 84, 69, 82, 32, 82, 80, 248, 243, 11, 4, 71, 79, 78, 69, 135, 237, 17, + 86, 10, 246, 43, 90, 206, 218, 17, 78, 186, 253, 8, 68, 138, 134, 2, 83, + 203, 236, 1, 65, 2, 213, 128, 24, 6, 69, 78, 32, 77, 65, 82, 12, 18, 65, + 107, 76, 8, 236, 7, 9, 82, 69, 78, 84, 72, 69, 83, 69, 83, 141, 248, 23, + 9, 76, 65, 84, 65, 76, 73, 90, 69, 68, 4, 197, 171, 29, 7, 85, 83, 32, + 83, 73, 71, 78, 38, 18, 69, 127, 73, 6, 72, 5, 86, 69, 82, 83, 69, 133, + 254, 23, 7, 84, 82, 79, 70, 76, 69, 88, 4, 22, 32, 227, 12, 68, 2, 141, + 8, 2, 83, 79, 32, 40, 3, 71, 72, 84, 157, 5, 2, 78, 71, 26, 50, 32, 149, + 4, 7, 87, 65, 82, 68, 83, 32, 72, 24, 104, 5, 65, 82, 82, 79, 87, 218, 1, + 72, 124, 12, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 32, 59, 84, 12, + 44, 5, 72, 69, 65, 68, 32, 155, 168, 29, 32, 8, 26, 65, 155, 168, 29, 66, + 6, 36, 3, 78, 68, 32, 219, 195, 30, 66, 4, 40, 4, 68, 79, 87, 78, 1, 2, + 85, 80, 2, 157, 203, 8, 9, 32, 65, 82, 82, 79, 87, 72, 69, 65, 6, 11, 65, + 6, 48, 6, 76, 70, 32, 82, 73, 78, 21, 2, 82, 80, 4, 163, 166, 29, 71, 2, + 17, 2, 79, 79, 2, 231, 193, 30, 78, 4, 174, 198, 9, 65, 137, 170, 20, 5, + 66, 69, 76, 79, 87, 2, 149, 249, 23, 2, 65, 67, 2, 233, 201, 20, 16, 65, + 82, 80, 79, 79, 78, 32, 87, 73, 84, 72, 32, 66, 65, 82, 66, 6, 11, 32, 6, + 182, 197, 11, 79, 166, 223, 17, 66, 223, 155, 1, 65, 18, 188, 1, 5, 72, + 79, 82, 84, 32, 160, 1, 7, 81, 85, 65, 82, 69, 32, 66, 56, 5, 84, 82, 79, + 78, 71, 232, 193, 3, 2, 85, 83, 148, 179, 20, 2, 78, 65, 233, 157, 5, 6, + 69, 65, 71, 85, 76, 76, 6, 18, 83, 71, 86, 4, 26, 79, 223, 194, 11, 84, + 2, 253, 194, 11, 5, 76, 73, 68, 85, 83, 2, 49, 10, 69, 82, 84, 73, 67, + 65, 76, 32, 76, 73, 2, 151, 194, 11, 78, 4, 148, 196, 7, 5, 82, 65, 67, + 75, 69, 191, 221, 21, 69, 2, 225, 244, 23, 17, 32, 67, 69, 78, 84, 82, + 65, 76, 73, 90, 65, 84, 73, 79, 78, 32, 83, 20, 98, 72, 32, 4, 73, 76, + 68, 69, 136, 1, 6, 82, 73, 80, 76, 69, 32, 69, 5, 85, 82, 78, 69, 68, 2, + 137, 194, 7, 3, 82, 69, 69, 11, 11, 32, 8, 76, 3, 76, 69, 70, 0, 4, 82, + 73, 71, 72, 182, 191, 11, 79, 167, 223, 17, 66, 2, 169, 144, 29, 6, 84, + 32, 72, 65, 76, 70, 6, 186, 161, 15, 65, 184, 132, 15, 5, 85, 78, 68, 69, + 82, 199, 64, 68, 2, 145, 252, 14, 2, 32, 67, 10, 34, 80, 238, 184, 30, + 82, 3, 83, 6, 42, 87, 141, 240, 23, 4, 32, 84, 65, 67, 2, 45, 9, 65, 82, + 68, 83, 32, 65, 82, 82, 79, 2, 159, 142, 29, 87, 6, 158, 188, 25, 76, + 171, 183, 2, 84, 6, 52, 3, 68, 69, 32, 133, 189, 11, 4, 71, 71, 76, 89, + 4, 92, 12, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 82, 73, 161, 165, 28, + 5, 66, 82, 73, 68, 71, 2, 241, 238, 23, 2, 68, 71, 6, 178, 196, 11, 45, + 147, 214, 17, 32, 6, 52, 7, 69, 82, 67, 73, 65, 76, 32, 191, 178, 31, 65, + 4, 206, 152, 28, 77, 195, 253, 2, 65, 8, 178, 140, 8, 82, 144, 221, 15, + 3, 79, 83, 73, 246, 225, 2, 76, 171, 208, 3, 65, 38, 214, 1, 70, 84, 10, + 83, 84, 82, 85, 67, 84, 73, 79, 78, 32, 46, 84, 172, 236, 2, 8, 86, 69, + 78, 73, 69, 78, 67, 69, 172, 237, 17, 6, 73, 67, 65, 76, 32, 84, 170, + 243, 8, 74, 133, 97, 7, 71, 82, 85, 69, 78, 84, 32, 6, 168, 187, 26, 4, + 69, 84, 84, 73, 162, 214, 1, 85, 229, 141, 2, 4, 79, 85, 78, 68, 4, 240, + 144, 20, 2, 87, 79, 219, 151, 10, 83, 20, 80, 5, 65, 73, 78, 83, 32, 198, + 1, 79, 28, 4, 82, 79, 76, 32, 199, 146, 3, 73, 12, 48, 3, 65, 83, 32, 93, + 5, 87, 73, 84, 72, 32, 6, 242, 205, 23, 77, 253, 7, 15, 78, 79, 82, 77, + 65, 76, 32, 83, 85, 66, 71, 82, 79, 85, 80, 6, 162, 190, 4, 76, 218, 144, + 19, 86, 223, 196, 4, 79, 2, 193, 168, 29, 2, 85, 82, 4, 232, 176, 19, 3, + 75, 78, 79, 173, 242, 3, 8, 83, 69, 81, 85, 69, 78, 67, 69, 6, 26, 73, + 175, 158, 2, 69, 4, 250, 170, 31, 78, 87, 69, 206, 2, 36, 4, 84, 73, 67, + 32, 175, 18, 89, 202, 2, 186, 1, 67, 204, 1, 6, 69, 80, 65, 67, 84, 32, + 86, 70, 36, 11, 79, 76, 68, 32, 78, 85, 66, 73, 65, 78, 32, 110, 83, 129, + 133, 28, 13, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 76, 126, 76, + 9, 79, 77, 66, 73, 78, 73, 78, 71, 32, 161, 3, 5, 65, 80, 73, 84, 65, 6, + 68, 9, 83, 80, 73, 82, 73, 84, 85, 83, 32, 189, 171, 30, 2, 78, 73, 4, + 196, 135, 6, 2, 76, 69, 161, 198, 16, 2, 65, 83, 56, 184, 211, 19, 8, 84, + 72, 79, 85, 83, 65, 78, 68, 166, 146, 1, 78, 195, 190, 2, 68, 4, 230, + 241, 17, 82, 203, 234, 10, 85, 8, 58, 68, 0, 3, 73, 78, 68, 146, 15, 86, + 183, 204, 28, 70, 2, 145, 220, 28, 7, 73, 82, 69, 67, 84, 32, 81, 134, 1, + 56, 3, 77, 65, 76, 197, 11, 6, 89, 77, 66, 79, 76, 32, 120, 45, 9, 76, + 32, 76, 69, 84, 84, 69, 82, 32, 120, 138, 2, 65, 48, 6, 66, 79, 72, 65, + 73, 82, 32, 2, 67, 82, 170, 1, 68, 160, 1, 2, 71, 65, 34, 72, 38, 75, 46, + 70, 34, 76, 66, 79, 138, 3, 83, 90, 84, 46, 90, 146, 197, 5, 86, 210, 55, + 80, 206, 203, 3, 73, 138, 179, 21, 82, 198, 3, 69, 218, 7, 77, 2, 78, + 163, 17, 85, 4, 44, 5, 75, 72, 77, 73, 77, 143, 134, 19, 76, 2, 177, 1, + 4, 73, 67, 32, 75, 10, 92, 12, 89, 80, 84, 79, 71, 82, 65, 77, 77, 73, + 67, 32, 53, 7, 79, 83, 83, 69, 68, 32, 83, 8, 50, 83, 226, 4, 71, 170, + 129, 31, 69, 219, 7, 78, 2, 215, 144, 24, 72, 12, 80, 9, 73, 65, 76, 69, + 67, 84, 45, 80, 32, 204, 251, 30, 2, 65, 76, 175, 17, 69, 8, 222, 137, 8, + 72, 162, 245, 7, 65, 240, 252, 11, 2, 75, 65, 139, 145, 3, 78, 4, 190, 3, + 78, 183, 251, 30, 77, 4, 250, 150, 24, 79, 191, 196, 5, 65, 8, 42, 72, + 182, 250, 27, 65, 139, 145, 3, 83, 4, 186, 139, 31, 69, 219, 19, 73, 4, + 224, 131, 19, 7, 45, 83, 72, 65, 80, 69, 68, 207, 212, 7, 65, 35, 36, 3, + 76, 68, 32, 167, 249, 30, 79, 30, 76, 7, 67, 79, 80, 84, 73, 67, 32, 193, + 1, 7, 78, 85, 66, 73, 65, 78, 32, 22, 98, 71, 42, 72, 188, 1, 2, 83, 72, + 238, 169, 14, 68, 190, 224, 9, 79, 178, 171, 5, 69, 227, 101, 65, 2, 17, + 2, 65, 78, 2, 171, 199, 15, 71, 8, 198, 147, 24, 79, 246, 211, 1, 65, + 159, 161, 5, 69, 8, 50, 78, 176, 253, 15, 2, 83, 72, 163, 139, 5, 87, 4, + 238, 135, 31, 71, 3, 89, 10, 54, 72, 178, 137, 6, 65, 222, 236, 24, 79, + 219, 3, 73, 4, 226, 249, 30, 73, 187, 13, 69, 4, 196, 237, 30, 3, 72, 69, + 84, 167, 8, 65, 2, 219, 245, 30, 65, 14, 62, 75, 30, 77, 2, 80, 22, 83, + 253, 146, 27, 3, 84, 65, 85, 4, 26, 72, 227, 133, 31, 65, 2, 143, 147, + 27, 73, 4, 136, 251, 15, 6, 72, 73, 77, 65, 32, 83, 145, 246, 3, 3, 84, + 65, 85, 4, 220, 252, 23, 3, 76, 69, 70, 157, 133, 2, 4, 82, 73, 71, 72, + 6, 96, 6, 78, 73, 83, 72, 32, 86, 252, 240, 24, 8, 82, 69, 83, 80, 79, + 78, 68, 83, 163, 157, 5, 65, 2, 157, 246, 27, 4, 69, 82, 83, 69, 44, 104, + 2, 78, 84, 208, 132, 3, 6, 67, 72, 32, 65, 78, 68, 181, 138, 27, 8, 80, + 76, 69, 32, 87, 73, 84, 72, 40, 56, 2, 69, 82, 33, 8, 73, 78, 71, 32, 82, + 79, 68, 32, 4, 158, 221, 26, 66, 235, 121, 83, 36, 48, 4, 84, 69, 78, 83, + 1, 4, 85, 78, 73, 84, 18, 185, 145, 23, 2, 32, 68, 51, 82, 69, 76, 5, 73, + 67, 75, 69, 84, 34, 79, 254, 5, 85, 50, 89, 239, 210, 29, 65, 4, 220, + 148, 8, 3, 68, 73, 84, 153, 238, 19, 7, 83, 67, 69, 78, 84, 32, 77, 5, + 237, 158, 26, 3, 32, 66, 65, 28, 84, 2, 83, 83, 228, 244, 28, 3, 67, 79, + 68, 188, 148, 1, 3, 73, 83, 83, 243, 57, 87, 22, 46, 32, 240, 2, 3, 69, + 68, 32, 223, 1, 73, 14, 44, 3, 79, 70, 32, 82, 80, 151, 208, 30, 77, 4, + 236, 202, 27, 6, 74, 69, 82, 85, 83, 65, 245, 173, 2, 5, 76, 79, 82, 82, + 65, 8, 76, 10, 65, 84, 84, 89, 32, 87, 73, 84, 72, 32, 97, 5, 79, 77, 77, + 69, 69, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 241, 192, 28, 7, + 84, 32, 67, 82, 79, 83, 83, 5, 233, 161, 3, 11, 32, 87, 73, 84, 72, 32, + 72, 65, 76, 70, 45, 6, 196, 181, 24, 37, 78, 69, 71, 65, 84, 73, 86, 69, + 32, 83, 81, 85, 65, 82, 69, 68, 32, 76, 65, 84, 73, 78, 32, 67, 65, 80, + 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 160, 212, 2, 2, 70, 76, 137, + 169, 2, 3, 83, 87, 79, 2, 141, 160, 23, 5, 78, 71, 32, 76, 65, 4, 228, + 145, 17, 3, 90, 69, 73, 179, 217, 13, 84, 6, 194, 159, 19, 73, 137, 249, + 6, 4, 83, 84, 65, 76, 204, 19, 154, 1, 66, 20, 8, 78, 69, 73, 70, 79, 82, + 77, 32, 138, 250, 1, 80, 114, 82, 172, 3, 2, 83, 84, 254, 165, 15, 67, + 209, 194, 9, 6, 84, 32, 79, 70, 32, 77, 2, 207, 160, 5, 69, 168, 19, 176, + 1, 13, 78, 85, 77, 69, 82, 73, 67, 32, 83, 73, 71, 78, 32, 184, 20, 17, + 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 83, 73, 71, 78, 32, 233, + 1, 5, 83, 73, 71, 78, 32, 222, 1, 78, 69, 166, 2, 70, 152, 3, 2, 78, 73, + 154, 2, 79, 130, 3, 83, 151, 4, 84, 24, 68, 5, 73, 71, 72, 84, 32, 153, + 1, 7, 76, 65, 77, 73, 84, 69, 32, 16, 142, 14, 83, 214, 113, 85, 238, 50, + 71, 136, 56, 17, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 85, + 83, 83, 85, 186, 223, 25, 68, 171, 217, 1, 65, 8, 136, 197, 20, 5, 79, + 78, 69, 32, 84, 250, 214, 8, 70, 175, 14, 84, 58, 48, 4, 73, 86, 69, 32, + 125, 4, 79, 85, 82, 32, 26, 70, 83, 206, 1, 66, 250, 12, 65, 82, 71, 250, + 109, 85, 175, 202, 26, 68, 6, 182, 15, 72, 165, 212, 18, 5, 73, 88, 84, + 72, 83, 32, 150, 1, 66, 44, 18, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, + 82, 77, 32, 76, 73, 77, 77, 85, 206, 12, 65, 82, 71, 26, 83, 226, 109, + 85, 175, 202, 26, 68, 6, 188, 123, 3, 65, 78, 50, 139, 252, 25, 85, 9, + 194, 156, 12, 32, 195, 231, 18, 52, 24, 44, 4, 71, 73, 68, 65, 33, 3, 78, + 69, 32, 4, 146, 158, 29, 69, 227, 101, 77, 20, 156, 1, 19, 86, 65, 82, + 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 73, 76, 73, 77, 77, 85, 174, 7, + 83, 214, 113, 85, 238, 50, 71, 194, 151, 26, 68, 171, 217, 1, 65, 9, 182, + 255, 30, 32, 186, 2, 51, 3, 52, 28, 92, 16, 76, 68, 32, 65, 83, 83, 89, + 82, 73, 65, 78, 32, 79, 78, 69, 32, 37, 3, 78, 69, 32, 4, 170, 134, 18, + 83, 203, 250, 10, 81, 24, 166, 1, 69, 52, 8, 81, 85, 65, 82, 84, 69, 82, + 32, 206, 7, 66, 54, 71, 84, 5, 84, 72, 73, 82, 68, 224, 244, 23, 2, 83, + 72, 241, 136, 6, 6, 72, 65, 76, 70, 32, 71, 4, 158, 8, 83, 189, 164, 1, + 5, 73, 71, 72, 84, 72, 4, 202, 153, 29, 65, 219, 108, 71, 38, 144, 1, 5, + 69, 86, 69, 78, 32, 188, 1, 20, 72, 65, 82, 50, 32, 84, 73, 77, 69, 83, + 32, 71, 65, 76, 32, 80, 76, 85, 83, 32, 37, 3, 73, 88, 32, 18, 148, 1, + 17, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 73, 77, 73, 78, + 218, 1, 83, 214, 113, 85, 238, 50, 71, 194, 151, 26, 68, 171, 217, 1, 65, + 6, 218, 148, 12, 32, 195, 231, 18, 51, 4, 178, 189, 27, 68, 139, 191, 2, + 77, 16, 142, 1, 83, 142, 3, 65, 202, 110, 85, 238, 50, 71, 220, 130, 26, + 16, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 32, 65, 83, 72, 231, + 20, 68, 2, 227, 61, 72, 50, 52, 5, 72, 82, 69, 69, 32, 241, 1, 3, 87, 79, + 32, 28, 142, 1, 66, 40, 4, 83, 72, 65, 82, 24, 16, 86, 65, 82, 73, 65, + 78, 84, 32, 70, 79, 82, 77, 32, 69, 83, 72, 118, 65, 82, 71, 167, 184, + 27, 68, 6, 248, 111, 3, 85, 82, 85, 199, 10, 65, 8, 210, 111, 50, 3, 85, + 4, 250, 144, 24, 49, 203, 3, 50, 22, 82, 65, 30, 66, 32, 2, 69, 83, 22, + 71, 26, 83, 61, 6, 84, 72, 73, 82, 68, 83, 4, 209, 184, 1, 2, 83, 72, 4, + 238, 120, 65, 199, 241, 25, 85, 2, 239, 147, 24, 72, 4, 53, 3, 69, 83, + 72, 4, 11, 72, 4, 17, 2, 65, 82, 4, 174, 246, 30, 50, 3, 85, 4, 11, 32, + 4, 128, 226, 26, 12, 86, 65, 82, 73, 65, 78, 84, 32, 70, 79, 82, 77, 195, + 85, 68, 10, 160, 1, 9, 68, 73, 65, 71, 79, 78, 65, 76, 32, 188, 241, 24, + 6, 86, 69, 82, 84, 73, 67, 169, 225, 2, 14, 79, 76, 68, 32, 65, 83, 83, + 89, 82, 73, 65, 78, 32, 87, 6, 192, 190, 27, 2, 84, 82, 204, 229, 2, 4, + 81, 85, 65, 68, 15, 67, 192, 17, 202, 1, 65, 186, 15, 66, 170, 5, 68, + 190, 15, 69, 202, 10, 71, 182, 30, 72, 238, 3, 73, 238, 4, 75, 138, 20, + 76, 134, 37, 77, 134, 6, 78, 226, 17, 80, 210, 3, 82, 42, 83, 238, 19, + 84, 186, 8, 85, 207, 20, 90, 141, 1, 160, 1, 7, 32, 84, 73, 77, 69, 83, + 32, 142, 1, 66, 250, 3, 68, 38, 75, 90, 76, 212, 1, 3, 77, 65, 82, 78, + 78, 134, 2, 82, 42, 83, 210, 230, 29, 80, 191, 127, 50, 16, 128, 173, 1, + 5, 76, 65, 71, 65, 82, 226, 23, 71, 166, 187, 12, 73, 198, 144, 13, 77, + 142, 250, 1, 83, 226, 159, 1, 66, 234, 67, 72, 187, 2, 65, 45, 22, 32, + 219, 2, 50, 28, 48, 6, 84, 73, 77, 69, 83, 32, 251, 202, 1, 71, 26, 180, + 1, 2, 71, 65, 38, 73, 36, 2, 83, 72, 240, 112, 8, 85, 32, 80, 76, 85, 83, + 32, 85, 188, 56, 4, 68, 85, 78, 51, 166, 2, 65, 204, 2, 3, 78, 85, 78, + 242, 27, 76, 191, 160, 29, 72, 4, 178, 210, 1, 78, 151, 155, 29, 76, 4, + 194, 169, 1, 71, 167, 196, 28, 77, 4, 170, 137, 24, 85, 187, 254, 4, 69, + 15, 37, 7, 32, 84, 73, 77, 69, 83, 32, 12, 190, 133, 1, 77, 130, 59, 71, + 194, 9, 83, 234, 10, 84, 192, 177, 27, 2, 66, 65, 143, 230, 1, 65, 5, + 249, 51, 5, 32, 84, 73, 77, 69, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, + 252, 27, 5, 83, 72, 73, 84, 65, 199, 80, 69, 23, 68, 7, 32, 84, 73, 77, + 69, 83, 32, 202, 240, 24, 69, 247, 169, 5, 65, 16, 102, 75, 140, 173, 1, + 2, 68, 73, 218, 253, 25, 71, 170, 217, 1, 85, 130, 92, 65, 146, 92, 83, + 215, 42, 72, 4, 242, 157, 1, 65, 183, 203, 29, 73, 7, 37, 7, 32, 84, 73, + 77, 69, 83, 32, 4, 130, 248, 3, 75, 207, 195, 26, 83, 13, 26, 32, 147, + 187, 30, 83, 8, 128, 1, 10, 80, 76, 85, 83, 32, 78, 65, 71, 65, 32, 148, + 164, 8, 7, 84, 72, 82, 69, 69, 32, 84, 245, 220, 5, 4, 79, 86, 69, 82, 4, + 128, 140, 1, 16, 79, 80, 80, 79, 83, 73, 78, 71, 32, 65, 78, 32, 80, 76, + 85, 83, 163, 226, 22, 83, 6, 200, 49, 2, 65, 68, 175, 219, 17, 75, 18, + 26, 72, 239, 245, 11, 65, 17, 42, 32, 138, 140, 18, 71, 191, 217, 12, 50, + 10, 68, 9, 79, 86, 69, 82, 32, 65, 83, 72, 32, 158, 97, 90, 135, 112, 75, + 6, 176, 1, 8, 79, 86, 69, 82, 32, 65, 83, 72, 141, 143, 1, 29, 84, 85, + 71, 50, 32, 79, 86, 69, 82, 32, 84, 85, 71, 50, 32, 84, 85, 71, 50, 32, + 79, 86, 69, 82, 32, 84, 85, 71, 50, 5, 133, 145, 1, 27, 32, 67, 82, 79, + 83, 83, 73, 78, 71, 32, 65, 83, 72, 32, 79, 86, 69, 82, 32, 65, 83, 72, + 32, 79, 86, 69, 82, 52, 30, 65, 158, 2, 73, 95, 85, 27, 66, 68, 44, 4, + 72, 65, 82, 50, 90, 76, 66, 82, 183, 140, 27, 71, 5, 129, 208, 1, 6, 32, + 84, 73, 77, 69, 83, 9, 37, 7, 32, 84, 73, 77, 69, 83, 32, 6, 222, 164, 1, + 65, 218, 168, 29, 78, 163, 17, 90, 7, 180, 215, 29, 7, 32, 79, 86, 69, + 82, 32, 66, 215, 136, 1, 65, 5, 203, 252, 23, 65, 9, 37, 7, 32, 84, 73, + 77, 69, 83, 32, 6, 246, 155, 1, 73, 198, 161, 28, 71, 171, 162, 1, 65, + 19, 50, 32, 168, 1, 3, 76, 85, 71, 223, 169, 1, 82, 8, 88, 8, 79, 86, 69, + 82, 32, 66, 85, 32, 217, 222, 26, 8, 67, 82, 79, 83, 83, 73, 78, 71, 6, + 144, 152, 12, 7, 84, 73, 77, 69, 83, 32, 78, 234, 139, 17, 65, 211, 106, + 85, 5, 237, 236, 3, 8, 32, 79, 86, 69, 82, 32, 66, 85, 180, 1, 34, 65, + 222, 5, 73, 195, 2, 85, 67, 50, 71, 150, 5, 82, 146, 49, 32, 163, 166, + 30, 77, 55, 26, 32, 171, 220, 30, 51, 50, 76, 13, 75, 73, 83, 73, 77, 53, + 32, 84, 73, 77, 69, 83, 32, 211, 198, 1, 84, 48, 146, 1, 65, 30, 66, 38, + 71, 112, 2, 73, 82, 42, 76, 94, 85, 166, 131, 1, 80, 162, 61, 84, 234, + 232, 26, 75, 146, 152, 2, 78, 254, 2, 83, 163, 17, 72, 4, 110, 32, 175, + 183, 29, 77, 4, 154, 244, 28, 65, 143, 230, 1, 73, 10, 34, 65, 58, 73, + 151, 147, 30, 85, 5, 11, 32, 2, 169, 244, 28, 6, 80, 76, 85, 83, 32, 77, + 5, 211, 245, 23, 82, 5, 181, 203, 13, 5, 32, 80, 76, 85, 83, 8, 26, 85, + 211, 216, 30, 65, 7, 144, 151, 1, 7, 32, 80, 76, 85, 83, 32, 77, 191, + 193, 29, 77, 6, 52, 7, 50, 32, 80, 76, 85, 83, 32, 203, 214, 30, 83, 4, + 128, 27, 2, 71, 73, 175, 215, 28, 77, 7, 171, 147, 12, 65, 25, 54, 77, + 150, 1, 78, 76, 2, 83, 72, 135, 213, 30, 66, 13, 44, 7, 32, 84, 73, 77, + 69, 83, 32, 59, 50, 6, 220, 69, 2, 85, 32, 134, 160, 13, 73, 199, 195, + 16, 83, 5, 153, 228, 12, 6, 32, 84, 73, 77, 69, 83, 5, 173, 179, 18, 14, + 32, 75, 65, 83, 75, 65, 76, 32, 85, 32, 71, 85, 78, 85, 5, 229, 157, 1, + 5, 32, 80, 76, 85, 83, 91, 70, 32, 66, 66, 94, 71, 234, 4, 78, 190, 234, + 23, 82, 215, 227, 6, 72, 6, 138, 176, 1, 71, 170, 3, 83, 249, 144, 12, 4, + 79, 86, 69, 82, 9, 52, 7, 32, 84, 73, 77, 69, 83, 32, 159, 211, 30, 50, + 4, 234, 145, 1, 69, 167, 148, 29, 83, 61, 52, 7, 32, 84, 73, 77, 69, 83, + 32, 175, 140, 30, 85, 56, 122, 65, 58, 68, 30, 71, 74, 75, 90, 76, 110, + 77, 50, 83, 242, 79, 69, 218, 58, 73, 250, 139, 16, 72, 158, 164, 13, 78, + 3, 80, 6, 32, 2, 83, 72, 139, 164, 30, 78, 5, 143, 154, 14, 32, 4, 182, + 129, 30, 73, 3, 85, 8, 26, 73, 215, 208, 30, 65, 7, 252, 140, 1, 2, 82, + 50, 199, 194, 29, 83, 8, 26, 85, 195, 185, 1, 65, 6, 40, 4, 83, 72, 85, + 50, 227, 207, 30, 82, 5, 175, 26, 32, 8, 26, 65, 45, 2, 85, 72, 6, 202, + 26, 77, 197, 207, 23, 3, 75, 45, 48, 2, 225, 57, 5, 32, 80, 76, 85, 83, + 6, 198, 233, 28, 65, 206, 167, 1, 69, 211, 61, 73, 4, 222, 138, 1, 73, + 131, 173, 29, 72, 11, 26, 51, 247, 205, 30, 52, 7, 143, 9, 32, 117, 130, + 1, 32, 90, 50, 210, 1, 78, 202, 1, 82, 60, 3, 83, 72, 50, 52, 3, 90, 69, + 78, 230, 164, 18, 71, 226, 163, 11, 68, 191, 127, 76, 4, 168, 25, 11, 79, + 86, 69, 82, 32, 69, 32, 78, 85, 78, 32, 237, 94, 4, 84, 73, 77, 69, 19, + 37, 7, 32, 84, 73, 77, 69, 83, 32, 16, 134, 1, 83, 128, 168, 1, 10, 65, + 32, 80, 76, 85, 83, 32, 72, 65, 32, 178, 128, 28, 71, 214, 17, 80, 146, + 24, 75, 238, 100, 77, 219, 19, 85, 4, 186, 193, 29, 65, 203, 114, 72, 15, + 11, 32, 12, 96, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 36, 6, 84, 73, + 77, 69, 83, 32, 179, 208, 23, 83, 2, 189, 222, 13, 4, 83, 73, 78, 71, 6, + 188, 138, 1, 4, 71, 65, 78, 50, 147, 168, 29, 77, 6, 36, 3, 73, 78, 50, + 247, 248, 29, 69, 5, 187, 188, 29, 32, 5, 229, 16, 9, 32, 67, 82, 79, 83, + 83, 73, 78, 71, 63, 11, 32, 60, 96, 14, 83, 72, 69, 83, 72, 73, 71, 32, + 84, 73, 77, 69, 83, 32, 97, 6, 84, 73, 77, 69, 83, 32, 16, 162, 131, 1, + 73, 130, 219, 2, 77, 210, 131, 25, 65, 128, 105, 2, 76, 65, 182, 87, 83, + 147, 17, 72, 44, 134, 1, 65, 68, 5, 68, 85, 78, 51, 32, 26, 75, 58, 76, + 62, 83, 34, 85, 206, 127, 73, 204, 31, 2, 72, 65, 226, 249, 27, 71, 163, + 100, 66, 9, 228, 86, 9, 32, 80, 76, 85, 83, 32, 76, 65, 76, 195, 238, 29, + 78, 4, 217, 32, 2, 71, 85, 6, 192, 203, 23, 5, 65, 83, 75, 65, 76, 159, + 165, 3, 85, 8, 34, 65, 242, 195, 30, 73, 3, 85, 5, 185, 85, 2, 76, 32, 4, + 130, 173, 30, 72, 215, 22, 85, 4, 182, 195, 30, 50, 3, 68, 160, 2, 42, + 65, 166, 19, 69, 122, 73, 135, 5, 85, 191, 1, 114, 50, 144, 16, 2, 66, + 65, 94, 68, 22, 76, 38, 78, 190, 140, 1, 32, 154, 6, 82, 218, 143, 27, + 83, 167, 142, 2, 77, 153, 1, 11, 32, 150, 1, 68, 6, 84, 73, 77, 69, 83, + 32, 137, 128, 1, 5, 79, 86, 69, 82, 32, 148, 1, 202, 1, 65, 162, 2, 66, + 154, 1, 68, 178, 1, 69, 58, 71, 178, 1, 72, 230, 1, 73, 70, 75, 194, 1, + 76, 62, 77, 50, 78, 130, 1, 83, 142, 1, 85, 206, 154, 1, 84, 248, 179, + 22, 3, 90, 73, 90, 159, 225, 6, 80, 18, 132, 1, 6, 32, 80, 76, 85, 83, + 32, 50, 78, 52, 2, 83, 72, 161, 228, 17, 14, 66, 50, 32, 84, 69, 78, 85, + 32, 80, 76, 85, 83, 32, 84, 6, 186, 58, 68, 182, 147, 13, 73, 155, 238, + 16, 72, 5, 169, 61, 9, 32, 80, 76, 85, 83, 32, 75, 65, 75, 7, 11, 50, 5, + 245, 89, 6, 32, 80, 76, 85, 83, 32, 10, 26, 65, 77, 2, 85, 82, 6, 42, 72, + 44, 2, 82, 32, 183, 188, 30, 68, 2, 11, 65, 2, 255, 216, 23, 82, 5, 11, + 32, 2, 229, 241, 29, 4, 80, 76, 85, 83, 14, 34, 73, 54, 85, 187, 187, 30, + 65, 7, 17, 2, 77, 32, 4, 146, 22, 84, 191, 129, 1, 71, 6, 56, 8, 71, 32, + 84, 73, 77, 69, 83, 32, 255, 186, 30, 66, 4, 142, 119, 73, 151, 45, 75, + 10, 38, 78, 254, 2, 76, 203, 230, 28, 82, 5, 243, 28, 32, 18, 18, 65, 99, + 73, 11, 26, 82, 231, 158, 1, 78, 7, 33, 6, 32, 80, 76, 85, 83, 32, 4, + 254, 162, 30, 78, 255, 2, 68, 9, 158, 122, 52, 193, 176, 12, 7, 82, 50, + 32, 80, 76, 85, 83, 12, 62, 65, 138, 124, 85, 173, 174, 12, 6, 73, 32, + 80, 76, 85, 83, 8, 40, 6, 32, 80, 76, 85, 83, 32, 83, 76, 4, 48, 6, 76, + 85, 32, 80, 76, 85, 219, 183, 30, 65, 2, 11, 83, 2, 199, 97, 32, 5, 201, + 169, 13, 5, 32, 80, 76, 85, 83, 4, 160, 100, 10, 83, 72, 32, 80, 76, 85, + 83, 32, 72, 85, 147, 15, 71, 12, 34, 65, 36, 2, 73, 68, 27, 85, 4, 218, + 252, 23, 83, 211, 185, 6, 75, 5, 209, 77, 2, 32, 80, 4, 60, 5, 83, 72, + 85, 50, 32, 181, 127, 5, 51, 32, 80, 76, 85, 2, 189, 158, 1, 3, 80, 76, + 85, 8, 26, 65, 231, 179, 30, 85, 7, 11, 77, 5, 211, 159, 1, 32, 6, 234, + 77, 69, 206, 129, 28, 85, 159, 229, 1, 73, 10, 26, 69, 73, 2, 85, 78, 7, + 33, 6, 32, 80, 76, 85, 83, 32, 4, 142, 208, 23, 69, 255, 207, 6, 71, 5, + 11, 32, 2, 171, 101, 79, 14, 42, 72, 250, 140, 23, 65, 171, 149, 7, 85, + 8, 18, 69, 51, 73, 5, 157, 186, 29, 7, 32, 80, 76, 85, 83, 32, 84, 4, + 178, 178, 30, 68, 3, 77, 7, 11, 68, 5, 161, 162, 13, 5, 32, 80, 76, 85, + 83, 7, 11, 32, 4, 170, 216, 28, 82, 133, 172, 1, 11, 67, 82, 79, 83, 83, + 73, 78, 71, 32, 71, 65, 5, 175, 131, 1, 32, 7, 246, 130, 1, 32, 167, 157, + 29, 65, 11, 11, 50, 9, 11, 32, 6, 80, 8, 67, 82, 79, 83, 83, 73, 78, 71, + 0, 4, 79, 86, 69, 82, 255, 221, 25, 84, 2, 181, 49, 3, 32, 71, 65, 8, 44, + 5, 83, 72, 84, 73, 78, 199, 203, 23, 50, 7, 37, 7, 32, 84, 73, 77, 69, + 83, 32, 4, 170, 182, 29, 75, 199, 120, 85, 49, 70, 32, 94, 52, 114, 82, + 190, 1, 83, 202, 168, 29, 68, 187, 130, 1, 71, 6, 172, 232, 8, 6, 84, 73, + 77, 69, 83, 32, 253, 212, 4, 8, 67, 82, 79, 83, 83, 73, 78, 71, 7, 11, + 32, 4, 64, 8, 67, 82, 79, 83, 83, 73, 78, 71, 1, 4, 79, 86, 69, 82, 2, + 225, 199, 23, 3, 32, 71, 73, 16, 26, 51, 131, 136, 1, 50, 13, 37, 7, 32, + 84, 73, 77, 69, 83, 32, 10, 70, 65, 0, 2, 76, 85, 190, 127, 71, 166, 187, + 12, 73, 155, 238, 16, 80, 2, 221, 186, 13, 7, 32, 80, 76, 85, 83, 32, 73, + 14, 26, 72, 203, 161, 29, 65, 13, 11, 32, 10, 22, 84, 247, 20, 67, 8, 44, + 5, 73, 77, 69, 83, 32, 159, 133, 30, 69, 6, 192, 20, 6, 71, 73, 83, 72, + 32, 67, 130, 126, 84, 175, 209, 28, 66, 43, 110, 50, 174, 1, 68, 218, 1, + 77, 54, 82, 176, 183, 13, 9, 32, 67, 82, 79, 83, 83, 73, 78, 71, 247, + 237, 16, 76, 15, 11, 32, 12, 48, 6, 84, 73, 77, 69, 83, 32, 151, 132, 1, + 71, 10, 252, 24, 3, 75, 65, 75, 178, 75, 73, 152, 20, 10, 83, 65, 76, 32, + 80, 76, 85, 83, 32, 84, 191, 175, 28, 78, 11, 11, 32, 8, 128, 1, 10, 80, + 76, 85, 83, 32, 71, 73, 83, 72, 32, 16, 6, 84, 73, 77, 69, 83, 32, 161, + 66, 8, 79, 86, 69, 82, 32, 71, 85, 68, 2, 247, 120, 84, 4, 156, 145, 1, + 5, 65, 32, 80, 76, 85, 175, 156, 28, 75, 5, 17, 2, 32, 84, 2, 225, 42, 4, + 73, 77, 69, 83, 9, 26, 85, 139, 165, 30, 55, 4, 246, 163, 30, 83, 147, 1, + 78, 50, 30, 65, 82, 73, 215, 1, 85, 11, 26, 32, 175, 164, 30, 76, 6, 32, + 2, 84, 69, 131, 128, 1, 71, 4, 219, 127, 78, 23, 37, 7, 32, 84, 73, 77, + 69, 83, 32, 20, 104, 3, 65, 83, 72, 162, 228, 26, 68, 174, 190, 2, 78, + 94, 75, 158, 57, 66, 2, 71, 150, 25, 83, 143, 45, 85, 7, 208, 55, 8, 32, + 79, 86, 69, 82, 32, 72, 73, 147, 235, 29, 50, 19, 48, 2, 66, 50, 158, + 190, 23, 76, 199, 226, 6, 83, 13, 37, 7, 32, 84, 73, 77, 69, 83, 32, 10, + 238, 138, 1, 75, 150, 216, 25, 76, 158, 181, 2, 72, 214, 57, 65, 195, 9, + 85, 49, 104, 3, 68, 73, 77, 94, 71, 214, 1, 76, 62, 77, 238, 154, 30, 32, + 170, 1, 83, 146, 1, 66, 2, 78, 3, 82, 7, 53, 11, 32, 79, 86, 69, 82, 32, + 73, 68, 73, 77, 32, 4, 226, 166, 23, 83, 179, 128, 6, 66, 13, 11, 73, 11, + 11, 32, 8, 146, 123, 71, 168, 178, 11, 31, 79, 86, 69, 82, 32, 73, 71, + 73, 32, 83, 72, 73, 82, 32, 79, 86, 69, 82, 32, 83, 72, 73, 82, 32, 85, + 68, 32, 79, 86, 69, 82, 178, 183, 16, 68, 219, 166, 1, 82, 7, 26, 32, + 199, 157, 30, 50, 2, 153, 72, 4, 84, 73, 77, 69, 13, 26, 32, 183, 205, + 29, 73, 8, 76, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 146, 111, 84, + 183, 180, 22, 83, 2, 253, 153, 29, 5, 83, 73, 78, 71, 32, 222, 1, 78, 65, + 130, 15, 73, 242, 1, 85, 158, 73, 69, 237, 217, 22, 4, 87, 85, 51, 49, + 175, 1, 164, 1, 7, 32, 84, 73, 77, 69, 83, 32, 210, 9, 50, 66, 68, 102, + 75, 50, 76, 82, 77, 28, 4, 83, 75, 65, 76, 152, 140, 15, 6, 80, 32, 69, + 76, 65, 77, 235, 129, 15, 66, 134, 1, 170, 1, 65, 94, 66, 82, 69, 30, 71, + 182, 2, 73, 34, 75, 34, 76, 38, 77, 170, 1, 83, 118, 84, 34, 85, 198, 8, + 72, 246, 51, 78, 154, 157, 16, 80, 142, 147, 13, 82, 147, 17, 90, 13, 46, + 68, 154, 235, 29, 78, 165, 44, 2, 83, 72, 5, 213, 50, 7, 32, 80, 76, 85, + 83, 32, 75, 10, 34, 65, 226, 151, 30, 73, 3, 85, 6, 222, 177, 28, 76, + 130, 230, 1, 68, 3, 82, 4, 250, 24, 82, 151, 61, 83, 26, 30, 65, 98, 73, + 147, 1, 85, 11, 38, 82, 190, 123, 78, 151, 155, 29, 76, 5, 233, 21, 10, + 32, 80, 76, 85, 83, 32, 83, 72, 65, 51, 11, 32, 2, 83, 72, 163, 178, 23, + 82, 7, 11, 32, 4, 26, 67, 239, 130, 1, 80, 2, 37, 7, 82, 79, 83, 83, 73, + 78, 71, 2, 221, 214, 26, 2, 32, 71, 7, 242, 193, 26, 82, 151, 211, 3, 68, + 4, 138, 129, 30, 71, 219, 19, 77, 8, 234, 8, 73, 239, 232, 16, 65, 6, + 246, 238, 11, 85, 175, 165, 18, 73, 12, 18, 69, 83, 73, 9, 33, 6, 32, 80, + 76, 85, 83, 32, 6, 222, 238, 29, 68, 150, 14, 84, 255, 2, 71, 5, 45, 9, + 32, 80, 76, 85, 83, 32, 78, 85, 78, 2, 251, 155, 26, 85, 18, 62, 72, 246, + 174, 26, 65, 224, 234, 2, 2, 85, 72, 243, 119, 73, 10, 250, 149, 29, 85, + 138, 54, 73, 150, 70, 65, 3, 69, 4, 146, 217, 29, 65, 211, 56, 85, 17, + 110, 32, 222, 92, 82, 156, 182, 25, 9, 77, 85, 77, 32, 84, 73, 77, 69, + 83, 206, 252, 3, 83, 146, 1, 50, 3, 68, 2, 207, 190, 20, 85, 5, 177, 202, + 11, 11, 32, 67, 82, 79, 83, 83, 73, 78, 71, 32, 75, 10, 42, 53, 214, 143, + 30, 50, 2, 51, 3, 52, 5, 249, 169, 23, 9, 32, 79, 86, 69, 82, 32, 75, 65, + 68, 5, 173, 75, 8, 32, 84, 73, 77, 69, 83, 32, 73, 7, 11, 32, 4, 166, + 105, 84, 233, 235, 22, 9, 67, 82, 79, 83, 83, 73, 78, 71, 32, 4, 154, + 142, 30, 50, 3, 52, 7, 11, 32, 4, 70, 76, 1, 13, 79, 86, 69, 82, 32, 75, + 65, 83, 75, 65, 76, 32, 76, 2, 173, 116, 24, 65, 71, 65, 66, 32, 84, 73, + 77, 69, 83, 32, 85, 32, 79, 86, 69, 82, 32, 76, 65, 71, 65, 66, 32, 21, + 68, 7, 32, 84, 73, 77, 69, 83, 32, 50, 83, 198, 139, 30, 68, 3, 78, 6, + 26, 85, 187, 197, 29, 66, 5, 215, 139, 30, 68, 8, 52, 3, 73, 77, 53, 242, + 129, 29, 65, 159, 137, 1, 72, 5, 177, 165, 23, 11, 32, 79, 86, 69, 82, + 32, 75, 73, 83, 73, 77, 25, 200, 1, 29, 32, 79, 86, 69, 82, 32, 72, 73, + 32, 84, 73, 77, 69, 83, 32, 65, 83, 72, 50, 32, 75, 85, 32, 79, 86, 69, + 82, 32, 72, 18, 52, 54, 82, 186, 98, 83, 230, 1, 76, 162, 164, 29, 51, 2, + 55, 3, 78, 2, 155, 71, 73, 5, 157, 138, 29, 8, 32, 86, 65, 82, 73, 65, + 78, 84, 5, 213, 115, 9, 32, 79, 80, 80, 79, 83, 73, 78, 71, 240, 2, 30, + 65, 174, 26, 73, 59, 85, 141, 2, 68, 2, 71, 65, 252, 12, 2, 75, 45, 222, + 11, 76, 46, 77, 135, 55, 72, 118, 22, 66, 131, 11, 82, 109, 11, 32, 106, + 48, 6, 84, 73, 77, 69, 83, 32, 207, 141, 23, 83, 104, 190, 1, 65, 186, 1, + 66, 34, 71, 70, 72, 66, 73, 94, 75, 118, 76, 46, 77, 46, 83, 138, 2, 84, + 126, 85, 200, 150, 4, 8, 90, 85, 32, 79, 86, 69, 82, 32, 138, 196, 24, + 68, 214, 82, 69, 131, 57, 78, 15, 80, 6, 32, 80, 76, 85, 83, 32, 76, 4, + 83, 72, 32, 90, 226, 131, 30, 76, 3, 78, 6, 38, 68, 222, 225, 28, 71, + 131, 25, 76, 2, 201, 62, 5, 65, 32, 80, 76, 85, 2, 149, 112, 2, 73, 68, + 4, 178, 189, 29, 65, 151, 70, 73, 10, 48, 2, 85, 68, 210, 159, 26, 65, + 167, 227, 3, 73, 5, 191, 105, 32, 6, 244, 177, 17, 7, 73, 32, 84, 73, 77, + 69, 83, 211, 212, 11, 65, 8, 22, 77, 175, 62, 71, 7, 33, 6, 32, 80, 76, + 85, 83, 32, 4, 254, 220, 29, 76, 179, 34, 72, 10, 26, 85, 175, 137, 28, + 73, 6, 26, 76, 147, 129, 30, 51, 5, 41, 8, 32, 80, 76, 85, 83, 32, 72, + 73, 2, 219, 65, 32, 8, 198, 100, 65, 242, 182, 27, 73, 131, 105, 85, 6, + 26, 69, 243, 154, 28, 85, 5, 175, 25, 32, 12, 26, 72, 139, 239, 29, 85, + 10, 100, 14, 73, 84, 65, 32, 80, 76, 85, 83, 32, 71, 73, 83, 72, 32, 96, + 2, 85, 50, 217, 3, 2, 69, 32, 4, 48, 6, 80, 76, 85, 83, 32, 69, 223, 172, + 25, 84, 2, 11, 82, 2, 11, 73, 2, 215, 154, 23, 78, 5, 189, 73, 5, 32, 80, + 76, 85, 83, 6, 86, 65, 189, 30, 16, 69, 32, 80, 76, 85, 83, 32, 65, 32, + 80, 76, 85, 83, 32, 83, 85, 4, 162, 152, 23, 75, 251, 228, 6, 71, 13, 72, + 6, 32, 80, 76, 85, 83, 32, 190, 41, 50, 226, 209, 29, 83, 147, 1, 68, 4, + 26, 85, 147, 252, 29, 65, 2, 255, 40, 32, 11, 11, 32, 8, 68, 4, 71, 85, + 78, 85, 97, 9, 84, 73, 77, 69, 83, 32, 83, 72, 69, 5, 73, 16, 32, 79, 86, + 69, 82, 32, 76, 65, 71, 65, 82, 32, 71, 85, 78, 85, 2, 199, 205, 29, 32, + 5, 11, 32, 2, 229, 143, 14, 4, 80, 76, 85, 83, 136, 1, 82, 48, 146, 2, + 49, 30, 50, 114, 51, 82, 52, 222, 2, 54, 154, 4, 55, 243, 24, 53, 22, + 158, 1, 50, 30, 56, 180, 52, 15, 55, 57, 32, 79, 86, 69, 82, 32, 76, 65, + 75, 45, 48, 55, 57, 242, 199, 10, 53, 146, 152, 12, 54, 2, 57, 94, 51, + 143, 143, 3, 48, 4, 162, 248, 29, 49, 3, 53, 4, 144, 148, 23, 12, 49, 32, + 79, 86, 69, 82, 32, 76, 65, 75, 45, 48, 247, 227, 6, 48, 4, 222, 147, 23, + 52, 95, 51, 16, 46, 50, 38, 54, 230, 140, 23, 49, 159, 2, 51, 6, 230, + 246, 29, 48, 2, 53, 3, 56, 4, 194, 246, 29, 53, 3, 54, 12, 42, 52, 250, + 177, 11, 56, 143, 225, 11, 57, 6, 250, 245, 29, 51, 2, 55, 3, 56, 30, 62, + 52, 214, 1, 53, 30, 57, 178, 144, 23, 55, 143, 143, 3, 56, 14, 26, 57, + 255, 244, 29, 49, 13, 37, 7, 32, 84, 73, 77, 69, 83, 32, 10, 116, 9, 80, + 65, 80, 32, 80, 76, 85, 83, 32, 208, 227, 12, 7, 85, 50, 32, 80, 76, 85, + 83, 190, 31, 73, 235, 203, 16, 71, 4, 210, 13, 80, 51, 76, 4, 194, 243, + 29, 48, 3, 55, 8, 166, 243, 29, 48, 2, 50, 2, 51, 3, 53, 46, 60, 2, 49, + 55, 240, 1, 2, 52, 56, 138, 137, 23, 48, 23, 51, 23, 37, 7, 32, 84, 73, + 77, 69, 83, 32, 20, 122, 84, 34, 85, 162, 11, 75, 132, 34, 9, 68, 85, 78, + 51, 32, 71, 85, 78, 85, 186, 222, 27, 65, 254, 158, 1, 66, 235, 67, 76, + 4, 198, 184, 29, 65, 211, 56, 69, 6, 250, 146, 14, 82, 254, 221, 15, 50, + 3, 68, 21, 37, 7, 32, 84, 73, 77, 69, 83, 32, 18, 154, 1, 85, 220, 8, 4, + 80, 65, 80, 32, 146, 45, 73, 164, 167, 12, 10, 83, 72, 69, 83, 72, 32, + 80, 76, 85, 83, 250, 252, 4, 68, 170, 129, 12, 78, 163, 17, 71, 4, 138, + 145, 14, 82, 255, 221, 15, 68, 4, 234, 137, 23, 50, 211, 145, 3, 52, 5, + 11, 32, 2, 145, 6, 4, 84, 73, 77, 69, 7, 49, 10, 32, 84, 73, 77, 69, 83, + 32, 75, 85, 82, 5, 221, 160, 11, 5, 32, 80, 76, 85, 83, 9, 200, 160, 11, + 2, 77, 77, 222, 203, 18, 83, 147, 1, 76, 93, 90, 50, 212, 7, 3, 71, 65, + 76, 142, 1, 77, 130, 62, 32, 198, 165, 29, 51, 2, 72, 3, 76, 69, 11, 32, + 66, 88, 4, 67, 82, 79, 83, 0, 4, 79, 80, 80, 79, 44, 4, 71, 85, 78, 85, + 38, 83, 35, 84, 2, 205, 158, 11, 6, 83, 73, 78, 71, 32, 76, 2, 193, 24, + 5, 32, 84, 73, 77, 69, 6, 250, 68, 72, 139, 173, 22, 81, 54, 44, 5, 73, + 77, 69, 83, 32, 171, 197, 29, 69, 52, 188, 1, 4, 69, 83, 72, 50, 94, 72, + 42, 75, 68, 2, 76, 65, 34, 77, 60, 3, 80, 65, 80, 118, 83, 90, 84, 250, + 56, 71, 158, 230, 7, 78, 150, 135, 18, 68, 170, 181, 2, 65, 254, 66, 66, + 203, 53, 73, 7, 11, 32, 4, 26, 80, 207, 150, 25, 84, 2, 17, 2, 76, 85, 2, + 245, 222, 28, 3, 83, 32, 76, 4, 184, 66, 2, 73, 32, 171, 156, 28, 65, 8, + 32, 2, 65, 68, 183, 231, 29, 73, 6, 226, 19, 51, 211, 211, 29, 50, 4, + 174, 20, 32, 171, 249, 16, 71, 2, 11, 69, 2, 11, 32, 2, 209, 251, 12, 4, + 80, 76, 85, 83, 5, 11, 32, 2, 33, 6, 80, 76, 85, 83, 32, 80, 2, 45, 9, + 65, 80, 32, 80, 76, 85, 83, 32, 76, 2, 235, 145, 26, 85, 6, 26, 73, 195, + 192, 29, 72, 4, 194, 18, 32, 157, 211, 25, 7, 75, 50, 32, 80, 76, 85, 83, + 4, 162, 53, 85, 139, 24, 65, 9, 11, 32, 6, 22, 79, 207, 67, 83, 4, 56, 7, + 80, 80, 79, 83, 73, 78, 71, 1, 3, 86, 69, 82, 2, 21, 3, 32, 76, 85, 2, + 175, 218, 28, 71, 7, 45, 9, 32, 79, 86, 69, 82, 32, 76, 85, 77, 5, 187, + 59, 32, 70, 34, 65, 70, 69, 22, 73, 71, 85, 17, 170, 45, 32, 188, 1, 2, + 83, 72, 250, 179, 29, 50, 2, 72, 3, 82, 7, 187, 238, 25, 83, 7, 240, 142, + 26, 8, 32, 80, 76, 85, 83, 32, 90, 65, 151, 211, 3, 78, 43, 104, 2, 83, + 72, 186, 60, 71, 140, 215, 10, 5, 32, 79, 86, 69, 82, 40, 2, 82, 71, 237, + 183, 6, 2, 78, 83, 31, 22, 32, 183, 2, 51, 16, 136, 1, 9, 79, 86, 69, 82, + 32, 77, 85, 83, 72, 124, 6, 84, 73, 77, 69, 83, 32, 173, 254, 25, 10, 67, + 82, 79, 83, 83, 73, 78, 71, 32, 77, 9, 37, 7, 32, 84, 73, 77, 69, 83, 32, + 6, 42, 65, 254, 175, 27, 75, 175, 172, 2, 71, 2, 237, 142, 11, 5, 32, 80, + 76, 85, 83, 6, 242, 229, 28, 75, 142, 118, 90, 187, 2, 65, 13, 11, 32, + 10, 44, 6, 84, 73, 77, 69, 83, 32, 203, 57, 71, 8, 38, 65, 210, 201, 29, + 68, 163, 17, 90, 5, 173, 205, 12, 5, 32, 80, 76, 85, 83, 158, 1, 42, 65, + 134, 2, 69, 94, 73, 199, 7, 85, 23, 52, 2, 71, 65, 166, 1, 77, 246, 218, + 29, 50, 3, 52, 11, 26, 32, 255, 219, 29, 82, 6, 100, 8, 79, 80, 80, 79, + 83, 73, 78, 71, 146, 59, 73, 197, 14, 9, 84, 73, 77, 69, 83, 32, 83, 72, + 85, 2, 217, 152, 29, 3, 32, 78, 65, 7, 204, 21, 2, 32, 78, 167, 197, 29, + 50, 9, 11, 32, 6, 44, 6, 84, 73, 77, 69, 83, 32, 179, 57, 83, 4, 250, + 147, 29, 85, 151, 70, 65, 73, 90, 77, 78, 78, 204, 234, 19, 6, 32, 84, + 73, 77, 69, 83, 254, 135, 8, 83, 131, 230, 1, 50, 7, 45, 9, 32, 84, 73, + 77, 69, 83, 32, 71, 65, 4, 158, 3, 82, 179, 58, 78, 59, 36, 3, 68, 65, + 50, 163, 216, 29, 57, 55, 37, 7, 32, 84, 73, 77, 69, 83, 32, 52, 162, 1, + 65, 34, 71, 50, 75, 16, 5, 76, 65, 75, 45, 48, 22, 77, 86, 78, 34, 80, + 76, 3, 83, 72, 69, 94, 85, 240, 15, 3, 68, 73, 77, 174, 186, 28, 66, 211, + 117, 72, 6, 246, 2, 83, 223, 211, 29, 78, 8, 26, 73, 255, 211, 28, 85, 5, + 135, 213, 29, 83, 2, 211, 20, 69, 2, 251, 242, 22, 53, 4, 26, 69, 171, + 240, 27, 65, 2, 25, 4, 32, 80, 76, 85, 2, 177, 41, 3, 83, 32, 71, 4, 182, + 133, 29, 85, 215, 79, 69, 2, 33, 6, 65, 80, 32, 80, 76, 85, 2, 11, 83, 2, + 229, 195, 28, 2, 32, 80, 9, 37, 7, 32, 80, 76, 85, 83, 32, 65, 6, 26, 83, + 171, 140, 28, 32, 4, 11, 72, 5, 107, 32, 11, 50, 32, 34, 50, 246, 244, + 13, 82, 239, 220, 15, 83, 2, 233, 217, 13, 3, 80, 76, 85, 2, 11, 32, 2, + 21, 3, 80, 76, 85, 2, 11, 83, 2, 151, 237, 27, 32, 57, 24, 2, 49, 49, 99, + 78, 9, 11, 32, 6, 200, 25, 9, 79, 86, 69, 82, 32, 78, 85, 49, 49, 210, + 230, 24, 84, 191, 248, 2, 82, 47, 30, 32, 169, 3, 2, 85, 90, 18, 144, 1, + 12, 67, 82, 79, 83, 83, 73, 78, 71, 32, 78, 85, 78, 72, 12, 76, 65, 71, + 65, 82, 32, 84, 73, 77, 69, 83, 32, 174, 1, 79, 163, 252, 24, 84, 5, 209, + 40, 14, 32, 76, 65, 71, 65, 82, 32, 79, 86, 69, 82, 32, 76, 65, 10, 56, + 3, 83, 65, 76, 210, 233, 27, 77, 14, 85, 247, 66, 71, 5, 205, 197, 28, + 23, 32, 79, 86, 69, 82, 32, 78, 85, 78, 32, 76, 65, 71, 65, 82, 32, 84, + 73, 77, 69, 83, 32, 83, 2, 153, 253, 16, 3, 86, 69, 82, 27, 11, 32, 24, + 120, 10, 65, 66, 50, 32, 84, 73, 77, 69, 83, 32, 205, 37, 15, 75, 73, 83, + 73, 77, 53, 32, 84, 73, 77, 69, 83, 32, 66, 73, 20, 168, 1, 2, 75, 65, + 202, 7, 73, 212, 39, 2, 65, 83, 194, 171, 2, 68, 164, 166, 8, 3, 83, 73, + 76, 226, 230, 11, 85, 150, 185, 5, 71, 238, 147, 1, 78, 254, 2, 66, 163, + 17, 76, 2, 199, 247, 25, 68, 46, 42, 65, 36, 4, 69, 83, 72, 50, 23, 73, + 9, 242, 202, 29, 68, 2, 78, 3, 80, 5, 135, 186, 27, 32, 35, 22, 32, 151, + 1, 82, 20, 80, 6, 84, 73, 77, 69, 83, 32, 205, 199, 17, 8, 67, 82, 79, + 83, 83, 73, 78, 71, 18, 214, 21, 85, 146, 48, 65, 2, 73, 190, 195, 28, + 66, 175, 64, 69, 12, 32, 2, 73, 71, 239, 200, 29, 50, 11, 11, 32, 8, 96, + 6, 84, 73, 77, 69, 83, 32, 173, 193, 25, 12, 79, 80, 80, 79, 83, 73, 78, + 71, 32, 80, 73, 82, 6, 210, 190, 28, 75, 150, 67, 85, 223, 67, 90, 8, + 230, 67, 65, 234, 131, 29, 73, 3, 85, 202, 1, 46, 65, 250, 5, 72, 150, + 11, 73, 163, 1, 85, 63, 46, 71, 190, 4, 76, 122, 78, 147, 193, 29, 82, + 53, 11, 32, 50, 92, 4, 71, 85, 78, 85, 54, 78, 32, 6, 84, 73, 77, 69, 83, + 32, 241, 21, 4, 79, 86, 69, 82, 5, 29, 5, 32, 84, 73, 77, 69, 2, 167, + 170, 17, 83, 2, 177, 203, 24, 3, 85, 84, 73, 42, 150, 1, 73, 42, 75, 34, + 83, 64, 2, 84, 65, 38, 85, 216, 62, 2, 68, 85, 246, 219, 27, 76, 222, 39, + 78, 198, 48, 69, 254, 59, 77, 162, 17, 72, 187, 2, 65, 2, 11, 71, 2, 11, + 73, 2, 191, 31, 32, 4, 242, 138, 29, 85, 187, 53, 65, 6, 26, 72, 239, + 185, 28, 65, 4, 234, 139, 13, 69, 139, 241, 15, 73, 4, 234, 221, 22, 75, + 251, 228, 6, 66, 10, 174, 193, 29, 83, 146, 1, 50, 2, 66, 2, 77, 3, 82, + 5, 33, 6, 32, 76, 65, 71, 65, 66, 2, 37, 7, 32, 84, 73, 77, 69, 83, 32, + 2, 11, 65, 2, 11, 83, 2, 207, 221, 22, 72, 2, 131, 251, 10, 71, 106, 46, + 65, 250, 1, 69, 242, 2, 73, 239, 3, 85, 29, 50, 51, 182, 1, 54, 182, 215, + 22, 66, 223, 3, 82, 19, 37, 7, 32, 84, 73, 77, 69, 83, 32, 16, 90, 85, + 146, 25, 83, 194, 231, 25, 71, 130, 198, 2, 84, 166, 50, 66, 206, 47, 78, + 215, 22, 65, 5, 11, 32, 2, 129, 171, 25, 4, 80, 76, 85, 83, 5, 175, 45, + 32, 27, 62, 32, 140, 2, 2, 83, 72, 226, 232, 25, 71, 171, 211, 3, 78, 14, + 84, 8, 79, 86, 69, 82, 32, 83, 72, 69, 88, 5, 80, 76, 85, 83, 32, 255, + 151, 29, 72, 7, 11, 32, 4, 190, 15, 71, 141, 6, 12, 84, 65, 66, 32, 79, + 86, 69, 82, 32, 84, 65, 66, 6, 48, 2, 72, 85, 20, 2, 78, 65, 247, 153, + 28, 83, 2, 219, 216, 22, 66, 2, 199, 216, 22, 77, 7, 202, 130, 28, 76, + 191, 185, 1, 50, 40, 62, 68, 74, 77, 218, 1, 82, 182, 178, 25, 78, 155, + 132, 4, 84, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, 162, 170, 29, 73, + 219, 16, 65, 25, 37, 7, 32, 84, 73, 77, 69, 83, 32, 22, 114, 66, 38, 73, + 130, 19, 75, 198, 181, 2, 77, 190, 198, 2, 76, 246, 135, 23, 71, 130, 25, + 83, 238, 9, 68, 191, 127, 65, 4, 218, 200, 2, 85, 203, 231, 25, 65, 4, + 249, 20, 2, 71, 73, 7, 11, 32, 4, 60, 9, 79, 86, 69, 82, 32, 83, 72, 73, + 82, 211, 230, 24, 84, 2, 241, 191, 28, 11, 32, 66, 85, 82, 32, 79, 86, + 69, 82, 32, 66, 13, 88, 14, 32, 79, 86, 69, 82, 32, 73, 78, 86, 69, 82, + 84, 69, 68, 34, 50, 187, 190, 28, 66, 2, 11, 32, 2, 167, 245, 24, 83, 7, + 33, 6, 32, 80, 76, 85, 83, 32, 4, 88, 7, 69, 50, 32, 84, 73, 77, 69, 173, + 234, 10, 9, 68, 85, 71, 32, 84, 73, 77, 69, 83, 2, 235, 207, 12, 83, 17, + 50, 32, 30, 71, 230, 234, 10, 76, 227, 230, 11, 75, 4, 138, 8, 84, 163, + 9, 71, 7, 11, 52, 5, 49, 10, 32, 79, 86, 69, 82, 32, 83, 73, 71, 52, 2, + 199, 14, 32, 19, 78, 68, 22, 77, 22, 82, 252, 164, 12, 5, 32, 79, 86, 69, + 82, 147, 150, 16, 72, 5, 247, 179, 29, 50, 5, 199, 206, 27, 65, 5, 207, + 179, 29, 57, 72, 46, 65, 150, 4, 73, 250, 1, 85, 227, 8, 69, 37, 66, 32, + 94, 66, 166, 1, 71, 148, 1, 2, 75, 52, 183, 175, 29, 82, 8, 60, 6, 84, + 73, 77, 69, 83, 32, 130, 14, 71, 207, 147, 27, 65, 4, 174, 158, 29, 72, + 3, 77, 7, 11, 32, 4, 188, 143, 17, 29, 79, 86, 69, 82, 32, 84, 65, 66, + 32, 78, 73, 32, 79, 86, 69, 82, 32, 78, 73, 32, 68, 73, 83, 72, 32, 79, + 86, 69, 82, 175, 169, 5, 83, 15, 37, 7, 32, 84, 73, 77, 69, 83, 32, 12, + 74, 84, 252, 233, 7, 2, 83, 72, 154, 155, 20, 71, 174, 100, 85, 191, 50, + 66, 2, 11, 85, 2, 243, 203, 22, 71, 5, 29, 5, 32, 80, 76, 85, 83, 2, 145, + 201, 27, 2, 32, 83, 17, 46, 82, 150, 29, 32, 182, 145, 29, 50, 3, 76, 9, + 11, 32, 6, 48, 8, 79, 86, 69, 82, 32, 84, 73, 82, 99, 84, 5, 11, 32, 2, + 11, 71, 2, 21, 3, 65, 68, 32, 2, 241, 5, 8, 79, 86, 69, 82, 32, 71, 65, + 68, 2, 217, 21, 6, 73, 77, 69, 83, 32, 84, 17, 50, 77, 114, 82, 138, 200, + 22, 71, 215, 227, 6, 75, 7, 37, 7, 32, 84, 73, 77, 69, 83, 32, 4, 46, 71, + 213, 137, 17, 5, 84, 72, 82, 69, 69, 2, 221, 16, 2, 65, 78, 5, 137, 221, + 10, 17, 32, 79, 86, 69, 82, 32, 84, 85, 82, 32, 90, 65, 32, 79, 86, 69, + 82, 179, 1, 138, 1, 32, 246, 2, 68, 226, 2, 78, 46, 77, 158, 2, 82, 128, + 9, 2, 83, 72, 174, 1, 90, 192, 133, 12, 2, 84, 85, 238, 145, 17, 50, 3, + 66, 12, 64, 7, 79, 86, 69, 82, 32, 85, 32, 158, 2, 85, 215, 252, 27, 71, + 6, 200, 1, 10, 80, 65, 32, 79, 86, 69, 82, 32, 80, 65, 168, 247, 8, 19, + 85, 32, 82, 69, 86, 69, 82, 83, 69, 68, 32, 79, 86, 69, 82, 32, 85, 32, + 82, 249, 183, 19, 10, 83, 85, 82, 32, 79, 86, 69, 82, 32, 83, 2, 11, 32, + 2, 45, 9, 71, 65, 82, 32, 79, 86, 69, 82, 32, 2, 255, 132, 28, 71, 5, + 171, 130, 29, 32, 21, 26, 32, 147, 166, 29, 85, 16, 70, 75, 44, 2, 83, + 72, 100, 6, 84, 73, 77, 69, 83, 32, 135, 1, 71, 2, 11, 85, 2, 11, 83, 2, + 151, 217, 10, 72, 4, 29, 5, 69, 83, 72, 73, 71, 5, 11, 32, 2, 11, 84, 2, + 149, 223, 28, 6, 73, 77, 69, 83, 32, 66, 8, 92, 14, 85, 32, 80, 76, 85, + 83, 32, 85, 32, 80, 76, 85, 83, 32, 142, 222, 28, 66, 203, 50, 77, 4, 11, + 85, 5, 11, 32, 2, 11, 71, 2, 147, 255, 28, 85, 21, 72, 7, 32, 84, 73, 77, + 69, 83, 32, 136, 1, 2, 85, 77, 231, 162, 28, 66, 10, 50, 76, 16, 2, 77, + 69, 50, 83, 183, 162, 29, 85, 2, 231, 6, 65, 5, 11, 32, 2, 177, 153, 25, + 4, 80, 76, 85, 83, 2, 255, 215, 10, 72, 7, 37, 7, 32, 84, 73, 77, 69, 83, + 32, 4, 158, 11, 75, 163, 148, 29, 80, 93, 54, 32, 102, 50, 194, 2, 73, + 22, 85, 235, 157, 29, 52, 4, 62, 83, 157, 168, 28, 9, 67, 82, 79, 83, 83, + 73, 78, 71, 32, 2, 141, 154, 25, 4, 72, 69, 83, 72, 23, 11, 32, 20, 42, + 73, 37, 6, 84, 73, 77, 69, 83, 32, 2, 165, 168, 23, 4, 78, 86, 69, 82, + 18, 46, 65, 82, 85, 202, 158, 28, 78, 227, 125, 72, 6, 48, 6, 32, 80, 76, + 85, 83, 32, 255, 158, 29, 76, 4, 194, 156, 29, 72, 3, 78, 8, 26, 50, 199, + 158, 29, 68, 7, 33, 6, 32, 80, 76, 85, 83, 32, 4, 130, 185, 27, 65, 199, + 209, 1, 66, 5, 251, 157, 29, 51, 59, 56, 7, 32, 84, 73, 77, 69, 83, 32, + 165, 4, 2, 68, 65, 52, 134, 1, 65, 46, 68, 38, 71, 82, 73, 46, 76, 78, + 83, 46, 85, 186, 247, 27, 66, 238, 34, 77, 214, 90, 84, 146, 17, 75, 162, + 17, 72, 3, 80, 5, 11, 83, 2, 11, 72, 2, 207, 194, 16, 71, 4, 186, 208, + 10, 65, 235, 251, 17, 85, 10, 26, 65, 187, 155, 29, 85, 9, 34, 78, 150, + 155, 29, 76, 3, 82, 2, 211, 9, 50, 6, 170, 135, 29, 71, 202, 18, 83, 147, + 1, 77, 6, 46, 85, 229, 178, 22, 5, 65, 75, 45, 54, 54, 4, 166, 154, 29, + 51, 3, 77, 4, 144, 181, 22, 2, 73, 71, 167, 206, 6, 72, 6, 42, 32, 186, + 187, 13, 82, 255, 221, 15, 68, 2, 241, 238, 27, 6, 80, 76, 85, 83, 32, + 71, 5, 11, 32, 2, 213, 159, 13, 4, 84, 73, 77, 69, 17, 84, 7, 32, 84, 73, + 77, 69, 83, 32, 244, 139, 28, 2, 85, 77, 142, 140, 1, 50, 3, 88, 8, 50, + 84, 168, 180, 25, 2, 75, 85, 167, 227, 3, 65, 2, 11, 65, 2, 199, 178, 22, + 75, 6, 26, 51, 147, 151, 29, 85, 5, 29, 5, 32, 84, 73, 77, 69, 2, 21, 3, + 83, 32, 75, 2, 11, 65, 2, 251, 220, 22, 83, 42, 50, 65, 190, 1, 73, 146, + 1, 85, 231, 175, 22, 69, 13, 50, 32, 198, 137, 28, 77, 142, 140, 1, 55, + 3, 71, 4, 56, 8, 83, 81, 85, 65, 82, 69, 68, 32, 175, 195, 24, 84, 2, 11, + 84, 2, 21, 3, 73, 77, 69, 2, 11, 83, 2, 157, 156, 28, 2, 32, 75, 15, 86, + 66, 132, 152, 22, 6, 32, 79, 86, 69, 82, 32, 154, 24, 90, 214, 227, 6, + 51, 3, 71, 5, 17, 2, 32, 75, 2, 17, 2, 65, 66, 2, 135, 2, 65, 15, 84, 10, + 32, 79, 86, 69, 82, 32, 90, 85, 32, 80, 42, 53, 246, 153, 28, 66, 199, + 120, 77, 2, 181, 240, 27, 5, 76, 85, 83, 32, 83, 7, 37, 7, 32, 84, 73, + 77, 69, 83, 32, 4, 44, 5, 84, 72, 82, 69, 69, 227, 145, 29, 65, 2, 29, 5, + 32, 68, 73, 83, 72, 2, 11, 32, 2, 203, 191, 24, 84, 8, 42, 32, 194, 150, + 22, 73, 187, 180, 3, 67, 4, 202, 212, 21, 79, 141, 190, 6, 8, 87, 73, 84, + 72, 32, 83, 84, 82, 18, 134, 1, 76, 154, 1, 82, 189, 202, 28, 23, 86, 69, + 68, 32, 83, 84, 69, 77, 32, 80, 65, 82, 65, 71, 82, 65, 80, 72, 32, 83, + 73, 71, 78, 10, 48, 2, 89, 32, 253, 147, 3, 4, 73, 78, 71, 32, 8, 60, 2, + 76, 79, 177, 128, 6, 7, 66, 82, 65, 67, 75, 69, 84, 6, 210, 226, 25, 71, + 215, 171, 3, 79, 6, 52, 5, 69, 78, 67, 89, 32, 53, 4, 89, 32, 65, 78, 4, + 248, 158, 24, 4, 69, 88, 67, 72, 143, 232, 3, 83, 2, 133, 160, 19, 3, 68, + 32, 82, 4, 174, 246, 27, 65, 133, 89, 2, 79, 77, 236, 8, 128, 1, 2, 80, + 82, 140, 9, 7, 82, 73, 76, 76, 73, 67, 32, 244, 134, 25, 7, 76, 73, 78, + 68, 82, 73, 67, 173, 210, 2, 2, 67, 76, 180, 2, 140, 1, 13, 73, 79, 84, + 32, 83, 89, 76, 76, 65, 66, 76, 69, 32, 169, 1, 16, 79, 45, 77, 73, 78, + 79, 65, 78, 32, 83, 73, 71, 78, 32, 67, 77, 110, 254, 156, 7, 75, 2, 76, + 2, 77, 2, 78, 2, 80, 2, 82, 2, 83, 2, 84, 126, 87, 254, 41, 74, 2, 90, + 194, 206, 6, 88, 138, 244, 14, 65, 2, 69, 2, 73, 2, 79, 3, 85, 198, 1, + 46, 48, 146, 5, 49, 141, 212, 23, 2, 51, 48, 170, 1, 102, 48, 78, 49, 74, + 50, 78, 51, 78, 52, 62, 53, 86, 55, 190, 140, 10, 57, 190, 3, 54, 179, + 234, 13, 56, 16, 246, 135, 29, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, + 56, 3, 57, 16, 194, 3, 50, 234, 131, 29, 48, 2, 49, 2, 51, 2, 53, 2, 55, + 3, 57, 16, 226, 134, 29, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, + 57, 16, 150, 134, 29, 48, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, + 57, 12, 202, 133, 29, 48, 2, 49, 2, 52, 2, 54, 2, 55, 3, 57, 18, 142, + 133, 29, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 20, + 82, 53, 234, 131, 29, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 54, 2, 56, 3, + 57, 5, 231, 131, 29, 66, 24, 18, 48, 87, 49, 18, 190, 131, 29, 48, 2, 49, + 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 6, 234, 130, 29, 48, 2, + 50, 3, 52, 180, 6, 140, 1, 9, 67, 65, 80, 73, 84, 65, 76, 32, 76, 194, 4, + 75, 32, 7, 76, 69, 84, 84, 69, 82, 32, 132, 1, 3, 80, 65, 89, 30, 83, + 203, 41, 84, 240, 2, 44, 6, 69, 84, 84, 69, 82, 32, 159, 43, 73, 234, 2, + 150, 2, 76, 46, 78, 34, 80, 34, 82, 58, 84, 54, 85, 190, 5, 65, 214, 1, + 66, 242, 1, 67, 150, 1, 68, 254, 1, 69, 206, 2, 71, 130, 1, 72, 134, 1, + 73, 230, 3, 75, 226, 3, 77, 218, 1, 79, 226, 2, 83, 210, 7, 89, 166, 1, + 90, 230, 178, 28, 70, 134, 14, 74, 2, 86, 2, 87, 159, 20, 81, 6, 214, 25, + 73, 186, 206, 28, 74, 159, 20, 72, 4, 254, 26, 69, 231, 204, 28, 74, 8, + 246, 33, 69, 203, 200, 28, 83, 12, 212, 9, 3, 79, 85, 78, 226, 18, 69, + 139, 223, 28, 72, 18, 158, 33, 69, 106, 83, 174, 174, 28, 67, 187, 22, + 87, 13, 190, 34, 32, 115, 75, 2, 137, 244, 28, 3, 65, 86, 89, 6, 248, 10, + 5, 77, 85, 76, 84, 73, 156, 205, 12, 2, 80, 65, 229, 195, 11, 14, 83, 77, + 65, 76, 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, 2, 237, 209, 28, 2, 69, + 82, 184, 3, 136, 1, 6, 77, 65, 76, 76, 32, 76, 193, 37, 22, 85, 66, 83, + 67, 82, 73, 80, 84, 32, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, + 32, 132, 3, 44, 6, 69, 84, 84, 69, 82, 32, 143, 36, 73, 254, 2, 154, 2, + 65, 214, 1, 66, 242, 1, 67, 150, 1, 68, 254, 1, 69, 206, 2, 71, 130, 1, + 72, 134, 1, 73, 230, 3, 75, 222, 2, 76, 134, 1, 77, 114, 78, 106, 79, + 110, 80, 50, 82, 198, 1, 83, 218, 2, 84, 210, 2, 85, 246, 1, 87, 54, 89, + 166, 1, 90, 230, 178, 28, 70, 134, 14, 74, 2, 86, 159, 20, 81, 17, 108, + 6, 32, 87, 73, 84, 72, 32, 36, 9, 66, 75, 72, 65, 83, 73, 65, 78, 32, + 229, 228, 11, 4, 76, 69, 85, 84, 4, 138, 154, 9, 68, 151, 170, 3, 66, 8, + 128, 209, 12, 3, 67, 72, 69, 250, 189, 6, 68, 139, 229, 9, 72, 18, 110, + 65, 78, 73, 32, 3, 82, 79, 65, 128, 146, 3, 6, 76, 69, 78, 68, 69, 68, + 178, 187, 9, 89, 243, 166, 16, 69, 6, 200, 21, 6, 82, 82, 69, 68, 32, 79, + 233, 205, 11, 5, 83, 72, 75, 73, 82, 4, 230, 2, 78, 187, 143, 3, 71, 2, + 179, 133, 10, 68, 14, 76, 2, 72, 69, 246, 9, 76, 164, 222, 12, 4, 82, 79, + 83, 83, 155, 222, 15, 67, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 142, 29, + 68, 195, 165, 28, 86, 26, 96, 2, 74, 69, 20, 6, 79, 85, 66, 76, 69, 32, + 66, 90, 182, 196, 28, 67, 186, 22, 87, 215, 22, 69, 5, 239, 151, 22, 82, + 4, 36, 3, 77, 79, 78, 219, 241, 28, 79, 2, 153, 13, 2, 79, 67, 12, 46, + 69, 138, 241, 27, 90, 182, 105, 72, 3, 87, 5, 155, 210, 28, 76, 41, 86, + 76, 98, 78, 110, 82, 166, 15, 32, 254, 185, 12, 83, 250, 247, 13, 77, + 195, 173, 2, 70, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 158, 20, 77, 222, + 182, 12, 68, 134, 248, 13, 84, 163, 92, 72, 13, 33, 6, 32, 87, 73, 84, + 72, 32, 10, 190, 19, 77, 222, 182, 12, 68, 202, 52, 76, 190, 195, 13, 84, + 163, 92, 72, 5, 229, 191, 27, 5, 32, 87, 73, 84, 72, 14, 32, 2, 72, 69, + 187, 215, 28, 74, 13, 33, 6, 32, 87, 73, 84, 72, 32, 10, 134, 18, 77, + 146, 15, 85, 206, 167, 12, 68, 143, 31, 83, 12, 26, 65, 195, 214, 28, 87, + 11, 48, 6, 32, 87, 73, 84, 72, 32, 143, 135, 27, 82, 6, 218, 199, 12, 68, + 166, 212, 14, 72, 231, 160, 1, 83, 35, 84, 6, 32, 87, 73, 84, 72, 32, 50, + 69, 74, 79, 201, 1, 6, 90, 72, 73, 84, 83, 65, 6, 254, 142, 9, 68, 214, + 10, 71, 239, 184, 3, 77, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 254, 152, + 9, 71, 195, 159, 3, 66, 17, 11, 84, 14, 48, 6, 73, 70, 73, 69, 68, 32, + 159, 234, 28, 65, 12, 80, 2, 67, 76, 38, 76, 214, 134, 3, 66, 130, 207, + 24, 89, 210, 147, 1, 65, 3, 69, 2, 33, 6, 79, 83, 69, 68, 32, 76, 2, 151, + 4, 73, 5, 145, 212, 12, 14, 32, 87, 73, 84, 72, 32, 68, 79, 85, 66, 76, + 69, 32, 71, 34, 102, 65, 98, 79, 244, 185, 28, 11, 72, 65, 75, 65, 83, + 83, 73, 65, 78, 32, 67, 186, 22, 74, 255, 2, 83, 11, 33, 6, 32, 87, 73, + 84, 72, 32, 8, 182, 194, 12, 68, 166, 212, 14, 72, 154, 160, 1, 86, 79, + 83, 18, 36, 3, 77, 73, 32, 251, 193, 25, 80, 16, 58, 68, 198, 236, 11, + 76, 2, 78, 2, 83, 2, 84, 3, 90, 6, 194, 236, 11, 90, 134, 227, 16, 74, + 215, 22, 69, 8, 94, 73, 236, 154, 10, 10, 79, 78, 71, 45, 76, 69, 71, 71, + 69, 68, 206, 179, 18, 74, 159, 20, 72, 2, 233, 130, 3, 4, 84, 84, 76, 69, + 4, 21, 3, 79, 78, 79, 4, 18, 67, 39, 71, 2, 205, 188, 18, 4, 85, 76, 65, + 82, 2, 237, 10, 4, 82, 65, 80, 72, 6, 62, 69, 204, 187, 18, 5, 65, 82, + 82, 79, 87, 155, 145, 10, 74, 2, 249, 192, 12, 5, 85, 84, 82, 65, 76, 11, + 52, 4, 77, 69, 71, 65, 166, 3, 32, 183, 223, 28, 84, 5, 233, 185, 28, 8, + 32, 87, 73, 84, 72, 32, 84, 73, 10, 130, 6, 69, 230, 183, 12, 65, 231, + 144, 16, 83, 14, 50, 69, 100, 4, 79, 85, 78, 68, 167, 222, 28, 72, 8, 37, + 7, 86, 69, 82, 83, 69, 68, 32, 8, 214, 249, 18, 68, 206, 222, 8, 84, 142, + 100, 89, 151, 14, 90, 4, 250, 241, 9, 32, 241, 237, 1, 2, 69, 68, 34, + 108, 4, 67, 72, 87, 65, 34, 72, 132, 1, 4, 79, 70, 84, 32, 170, 186, 12, + 84, 213, 1, 5, 69, 77, 73, 83, 79, 5, 11, 32, 2, 183, 218, 5, 87, 16, 92, + 4, 79, 82, 84, 32, 136, 185, 12, 2, 72, 65, 254, 173, 14, 67, 234, 224, + 1, 87, 215, 22, 65, 6, 254, 176, 26, 73, 195, 173, 2, 85, 8, 38, 69, 166, + 215, 27, 83, 255, 111, 68, 4, 242, 221, 28, 76, 3, 77, 26, 132, 1, 4, 65, + 76, 76, 32, 50, 69, 106, 83, 212, 211, 11, 11, 72, 82, 69, 69, 45, 76, + 69, 71, 71, 69, 68, 218, 218, 16, 67, 187, 22, 87, 6, 178, 179, 12, 72, + 206, 149, 15, 89, 255, 124, 84, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 26, + 77, 223, 182, 12, 68, 2, 185, 169, 21, 5, 73, 68, 68, 76, 69, 8, 226, + 196, 28, 72, 2, 83, 2, 87, 215, 22, 69, 15, 58, 32, 114, 75, 53, 8, 78, + 66, 76, 69, 78, 68, 69, 68, 6, 29, 5, 87, 73, 84, 72, 32, 6, 26, 68, 255, + 192, 12, 77, 4, 172, 255, 8, 5, 79, 85, 66, 76, 69, 187, 8, 73, 5, 11, + 82, 2, 213, 4, 6, 65, 73, 78, 73, 65, 78, 2, 159, 144, 24, 32, 4, 176, + 197, 27, 4, 73, 68, 69, 32, 227, 147, 1, 69, 18, 62, 65, 28, 3, 69, 82, + 85, 134, 216, 28, 73, 2, 78, 3, 85, 7, 158, 216, 28, 69, 3, 84, 7, 33, 6, + 32, 87, 73, 84, 72, 32, 4, 138, 251, 8, 68, 131, 186, 3, 66, 18, 18, 69, + 71, 72, 9, 156, 1, 7, 32, 87, 73, 84, 72, 32, 68, 173, 211, 28, 2, 77, + 76, 10, 26, 69, 247, 191, 28, 87, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, + 26, 68, 203, 163, 12, 66, 4, 222, 131, 9, 73, 179, 173, 3, 69, 6, 37, 7, + 71, 65, 84, 85, 82, 69, 32, 6, 66, 65, 176, 140, 15, 2, 84, 69, 189, 155, + 13, 4, 69, 78, 32, 71, 2, 199, 185, 28, 32, 52, 198, 1, 66, 38, 68, 38, + 69, 36, 3, 71, 72, 69, 38, 72, 246, 188, 21, 89, 222, 157, 5, 83, 202, + 110, 84, 238, 8, 90, 246, 63, 73, 138, 19, 67, 186, 22, 80, 2, 86, 158, + 20, 75, 186, 2, 65, 2, 79, 3, 85, 4, 170, 172, 12, 89, 243, 166, 16, 69, + 6, 238, 210, 27, 90, 139, 128, 1, 69, 6, 210, 210, 28, 70, 2, 76, 3, 83, + 5, 201, 5, 5, 32, 87, 73, 84, 72, 4, 11, 65, 5, 171, 236, 26, 82, 2, 209, + 188, 15, 4, 72, 79, 85, 83, 184, 15, 178, 1, 65, 138, 4, 67, 54, 69, 198, + 35, 73, 250, 22, 79, 142, 44, 82, 174, 3, 85, 180, 180, 12, 13, 78, 65, + 32, 68, 79, 85, 66, 76, 69, 32, 72, 69, 76, 154, 231, 14, 86, 195, 47, + 76, 30, 116, 4, 71, 71, 69, 82, 146, 1, 78, 32, 4, 82, 75, 32, 83, 36, 2, + 83, 72, 200, 177, 21, 2, 76, 69, 155, 133, 1, 84, 9, 11, 32, 6, 44, 5, + 87, 73, 84, 72, 32, 143, 190, 6, 75, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, + 71, 72, 2, 201, 183, 27, 4, 84, 32, 71, 85, 4, 166, 144, 28, 67, 239, 30, + 71, 4, 254, 253, 20, 85, 175, 224, 4, 72, 10, 30, 32, 105, 3, 69, 68, 32, + 4, 60, 9, 87, 73, 84, 72, 32, 76, 69, 70, 84, 239, 185, 27, 83, 2, 17, 2, + 32, 85, 2, 175, 181, 22, 80, 6, 170, 215, 4, 84, 182, 147, 12, 76, 255, + 252, 9, 79, 10, 134, 204, 28, 49, 2, 50, 2, 51, 2, 52, 3, 83, 176, 4, + 182, 2, 67, 132, 2, 5, 71, 82, 69, 69, 32, 98, 76, 80, 21, 78, 84, 73, + 83, 84, 82, 89, 32, 83, 89, 77, 66, 79, 76, 32, 76, 73, 71, 72, 84, 32, + 160, 3, 8, 80, 65, 82, 84, 77, 69, 78, 84, 34, 83, 174, 6, 86, 188, 214, + 14, 11, 82, 69, 76, 73, 67, 84, 32, 72, 79, 85, 83, 132, 146, 7, 2, 65, + 70, 235, 154, 6, 69, 8, 50, 73, 217, 229, 5, 6, 82, 69, 65, 83, 69, 32, + 6, 48, 4, 68, 85, 79, 85, 21, 4, 77, 65, 76, 32, 2, 219, 178, 23, 83, 4, + 88, 9, 83, 69, 80, 65, 82, 65, 84, 79, 82, 197, 171, 21, 7, 69, 88, 80, + 79, 78, 69, 78, 2, 21, 3, 32, 75, 69, 2, 151, 180, 27, 89, 6, 200, 242, + 21, 4, 67, 69, 76, 83, 250, 205, 5, 83, 153, 106, 8, 70, 65, 72, 82, 69, + 78, 72, 69, 9, 176, 190, 16, 5, 73, 86, 69, 82, 89, 128, 225, 5, 2, 84, + 65, 215, 226, 4, 69, 30, 88, 4, 68, 79, 87, 78, 0, 2, 85, 80, 153, 1, 9, + 86, 69, 82, 84, 73, 67, 65, 76, 32, 8, 69, 15, 32, 65, 78, 68, 32, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, + 234, 219, 26, 87, 170, 25, 67, 191, 43, 84, 14, 52, 4, 65, 78, 68, 32, + 85, 5, 87, 73, 84, 72, 32, 10, 200, 158, 17, 2, 84, 79, 190, 188, 9, 87, + 165, 189, 1, 6, 66, 79, 84, 84, 79, 77, 4, 218, 243, 26, 67, 191, 43, 84, + 2, 245, 137, 24, 3, 32, 83, 84, 170, 1, 64, 2, 67, 69, 48, 2, 69, 82, + 129, 5, 5, 75, 84, 79, 80, 32, 2, 217, 180, 26, 7, 78, 68, 73, 78, 71, + 32, 78, 164, 1, 32, 3, 69, 84, 32, 183, 4, 84, 160, 1, 56, 6, 67, 65, 80, + 73, 84, 65, 1, 4, 83, 77, 65, 76, 80, 45, 9, 76, 32, 76, 69, 84, 84, 69, + 82, 32, 80, 218, 1, 69, 96, 4, 76, 79, 78, 71, 0, 5, 83, 72, 79, 82, 84, + 74, 79, 30, 84, 2, 90, 246, 178, 11, 67, 206, 157, 15, 66, 2, 68, 2, 74, + 2, 80, 2, 86, 2, 89, 202, 96, 71, 2, 75, 134, 103, 87, 162, 19, 65, 203, + 17, 72, 20, 214, 202, 24, 83, 206, 251, 1, 78, 134, 247, 1, 84, 146, 1, + 70, 2, 76, 2, 77, 2, 82, 3, 87, 12, 11, 32, 12, 234, 201, 24, 65, 226, + 180, 1, 79, 130, 191, 2, 69, 3, 73, 4, 142, 189, 28, 73, 3, 87, 4, 190, + 208, 26, 72, 227, 213, 1, 69, 5, 225, 174, 27, 4, 32, 73, 83, 76, 4, 186, + 153, 16, 67, 229, 136, 11, 4, 87, 73, 78, 68, 202, 2, 100, 8, 65, 78, 65, + 71, 65, 82, 73, 32, 185, 18, 12, 73, 67, 69, 32, 67, 79, 78, 84, 82, 79, + 76, 32, 192, 2, 222, 1, 65, 38, 67, 22, 71, 36, 4, 72, 69, 65, 68, 96, 7, + 76, 69, 84, 84, 69, 82, 32, 198, 5, 83, 176, 7, 11, 86, 79, 87, 69, 76, + 32, 83, 73, 71, 78, 32, 158, 181, 18, 68, 148, 245, 5, 4, 74, 65, 73, 78, + 243, 239, 3, 79, 4, 138, 164, 12, 67, 191, 170, 12, 66, 2, 187, 253, 5, + 65, 4, 250, 163, 12, 82, 215, 236, 1, 65, 6, 44, 5, 32, 77, 65, 82, 75, + 163, 136, 28, 83, 5, 209, 195, 18, 7, 32, 87, 73, 84, 72, 32, 72, 158, 1, + 158, 2, 65, 54, 67, 62, 68, 50, 71, 62, 72, 52, 2, 77, 65, 46, 83, 154, + 10, 79, 218, 254, 6, 66, 82, 74, 218, 220, 4, 75, 238, 194, 3, 82, 166, + 212, 6, 89, 170, 109, 85, 238, 30, 78, 230, 46, 76, 238, 146, 1, 84, 46, + 86, 138, 225, 1, 73, 154, 191, 1, 80, 2, 90, 254, 68, 70, 2, 81, 187, 2, + 69, 13, 198, 181, 28, 65, 2, 73, 2, 85, 2, 87, 3, 89, 10, 26, 65, 195, + 178, 28, 72, 9, 185, 2, 4, 78, 68, 82, 65, 12, 170, 204, 24, 68, 246, + 229, 3, 72, 187, 2, 65, 10, 182, 185, 12, 76, 190, 179, 15, 72, 254, 68, + 71, 187, 2, 65, 4, 232, 150, 16, 4, 69, 65, 86, 89, 131, 157, 12, 65, 5, + 229, 133, 7, 6, 82, 87, 65, 82, 73, 32, 12, 38, 72, 174, 176, 28, 83, + 187, 2, 65, 8, 36, 3, 79, 82, 84, 191, 178, 28, 65, 6, 163, 212, 11, 32, + 68, 168, 1, 19, 69, 81, 85, 69, 78, 67, 69, 32, 70, 79, 82, 32, 76, 69, + 84, 84, 69, 82, 32, 104, 4, 73, 71, 78, 32, 141, 128, 26, 10, 84, 82, 69, + 83, 83, 32, 83, 73, 71, 78, 16, 226, 202, 3, 71, 2, 75, 220, 238, 22, 3, + 68, 68, 68, 2, 82, 226, 244, 1, 89, 38, 70, 2, 81, 3, 90, 48, 210, 3, 66, + 0, 10, 69, 88, 84, 69, 78, 68, 69, 68, 32, 66, 36, 11, 67, 65, 78, 68, + 82, 65, 66, 73, 78, 68, 85, 60, 8, 87, 69, 83, 84, 69, 82, 78, 32, 32, + 10, 82, 69, 86, 69, 82, 83, 69, 68, 32, 78, 148, 231, 4, 5, 80, 85, 83, + 72, 80, 182, 204, 1, 83, 156, 243, 3, 18, 68, 79, 85, 66, 76, 69, 32, 67, + 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 182, 148, 8, 73, 186, 137, 6, 65, + 126, 77, 46, 78, 204, 212, 2, 12, 72, 73, 71, 72, 32, 83, 80, 65, 67, 73, + 78, 71, 255, 77, 86, 4, 133, 170, 12, 4, 72, 65, 76, 69, 11, 11, 32, 8, + 206, 241, 21, 65, 210, 89, 86, 151, 244, 3, 84, 4, 30, 78, 21, 3, 70, 73, + 86, 2, 17, 2, 73, 78, 2, 217, 144, 21, 8, 69, 45, 76, 73, 75, 69, 32, 66, + 50, 146, 1, 65, 52, 7, 67, 65, 78, 68, 82, 65, 32, 62, 79, 190, 186, 18, + 80, 254, 165, 4, 85, 138, 228, 1, 83, 70, 86, 166, 221, 1, 73, 207, 134, + 2, 69, 10, 226, 169, 28, 65, 2, 73, 2, 85, 2, 87, 3, 89, 6, 176, 187, 18, + 4, 76, 79, 78, 71, 254, 237, 9, 69, 3, 79, 7, 158, 146, 28, 79, 215, 22, + 69, 10, 222, 193, 23, 70, 136, 6, 2, 83, 84, 146, 244, 2, 84, 203, 83, + 79, 228, 2, 182, 2, 65, 134, 2, 69, 74, 71, 224, 4, 6, 78, 71, 66, 65, + 84, 32, 248, 1, 5, 82, 69, 67, 84, 32, 98, 83, 178, 2, 86, 200, 7, 2, 89, + 65, 32, 4, 90, 90, 89, 32, 192, 152, 5, 2, 84, 84, 216, 229, 14, 10, 70, + 70, 69, 82, 69, 78, 67, 69, 32, 66, 229, 147, 7, 12, 77, 69, 78, 83, 73, + 79, 78, 32, 79, 82, 73, 71, 18, 26, 77, 167, 211, 8, 69, 16, 40, 4, 79, + 78, 68, 32, 195, 138, 3, 69, 14, 128, 1, 5, 87, 73, 84, 72, 32, 218, 220, + 17, 84, 128, 221, 2, 12, 83, 72, 65, 80, 69, 32, 87, 73, 84, 72, 32, 65, + 159, 192, 4, 79, 8, 202, 177, 21, 66, 162, 2, 84, 250, 228, 3, 76, 27, + 82, 14, 164, 240, 4, 5, 32, 70, 65, 67, 69, 225, 229, 16, 4, 83, 69, 76, + 32, 78, 64, 3, 73, 84, 32, 149, 2, 8, 82, 65, 77, 32, 70, 79, 82, 32, 60, + 98, 70, 44, 2, 78, 73, 2, 79, 14, 83, 46, 84, 44, 3, 90, 69, 82, 13, 5, + 69, 73, 71, 72, 84, 12, 128, 1, 2, 73, 86, 25, 3, 79, 85, 82, 6, 87, 78, + 12, 96, 4, 69, 86, 69, 78, 1, 2, 73, 88, 12, 28, 3, 72, 82, 69, 15, 87, + 6, 23, 69, 6, 11, 79, 7, 207, 186, 16, 32, 18, 88, 5, 69, 65, 82, 84, 72, + 64, 5, 71, 82, 69, 65, 84, 0, 4, 76, 69, 83, 83, 39, 72, 7, 25, 4, 76, + 89, 32, 72, 4, 238, 213, 23, 85, 187, 131, 1, 69, 4, 229, 207, 12, 4, 69, + 82, 32, 89, 4, 172, 129, 5, 7, 69, 65, 86, 69, 78, 76, 89, 1, 4, 85, 77, + 65, 78, 64, 120, 17, 78, 69, 71, 65, 84, 73, 86, 69, 32, 67, 73, 82, 67, + 76, 69, 68, 32, 41, 9, 67, 73, 82, 67, 76, 69, 68, 32, 83, 42, 38, 83, + 162, 32, 78, 139, 249, 19, 68, 22, 49, 10, 65, 78, 83, 45, 83, 69, 82, + 73, 70, 32, 22, 234, 31, 78, 203, 142, 26, 68, 4, 140, 143, 22, 15, 67, + 85, 82, 82, 69, 78, 84, 32, 83, 89, 77, 66, 79, 76, 32, 235, 240, 5, 72, + 10, 70, 65, 144, 1, 5, 67, 79, 78, 84, 73, 213, 251, 24, 3, 71, 85, 73, + 6, 76, 9, 80, 80, 79, 73, 78, 84, 69, 68, 32, 217, 255, 14, 4, 66, 76, + 69, 68, 4, 232, 226, 16, 7, 66, 85, 84, 32, 82, 69, 76, 211, 250, 10, 70, + 2, 53, 11, 78, 85, 79, 85, 83, 32, 85, 78, 68, 69, 82, 2, 213, 197, 16, + 3, 76, 73, 78, 156, 1, 80, 9, 69, 83, 32, 65, 75, 85, 82, 85, 32, 238, 5, + 73, 233, 190, 16, 2, 79, 82, 144, 1, 142, 2, 68, 36, 7, 76, 69, 84, 84, + 69, 82, 32, 236, 1, 5, 83, 73, 71, 78, 32, 58, 86, 252, 243, 8, 6, 77, + 69, 68, 73, 65, 76, 198, 247, 4, 71, 198, 211, 4, 69, 172, 189, 4, 12, + 80, 82, 69, 70, 73, 88, 69, 68, 32, 78, 65, 83, 241, 204, 4, 7, 73, 78, + 73, 84, 73, 65, 76, 22, 246, 192, 18, 79, 175, 231, 7, 73, 84, 186, 142, + 10, 84, 242, 209, 11, 89, 186, 116, 65, 130, 217, 1, 68, 146, 25, 85, + 210, 200, 1, 73, 42, 76, 246, 189, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, + 2, 75, 2, 80, 254, 68, 72, 2, 74, 2, 77, 2, 82, 2, 86, 2, 90, 186, 2, 69, + 3, 79, 8, 234, 128, 24, 72, 146, 45, 67, 98, 78, 223, 160, 3, 65, 18, 64, + 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 179, 225, 25, 73, 16, 178, + 219, 14, 65, 218, 232, 9, 85, 210, 200, 1, 73, 206, 134, 2, 69, 3, 79, + 10, 68, 5, 83, 73, 79, 78, 32, 204, 234, 1, 2, 78, 71, 235, 147, 25, 68, + 6, 26, 83, 247, 206, 5, 84, 4, 206, 172, 26, 76, 231, 94, 73, 2, 173, + 184, 18, 3, 32, 76, 65, 4, 190, 254, 26, 83, 255, 85, 70, 190, 5, 188, 2, + 6, 67, 85, 77, 69, 78, 84, 124, 7, 69, 83, 32, 78, 79, 84, 32, 194, 3, + 71, 210, 3, 76, 36, 10, 77, 73, 78, 79, 32, 84, 73, 76, 69, 32, 226, 1, + 78, 38, 84, 246, 2, 85, 204, 17, 2, 87, 78, 220, 128, 16, 8, 32, 78, 79, + 84, 32, 76, 73, 84, 136, 178, 11, 8, 86, 69, 32, 79, 70, 32, 80, 69, 174, + 4, 79, 223, 25, 68, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 40, 4, 84, 69, + 88, 84, 191, 133, 2, 80, 5, 185, 133, 2, 6, 32, 65, 78, 68, 32, 80, 22, + 164, 1, 11, 67, 79, 78, 84, 65, 73, 78, 32, 65, 83, 32, 92, 6, 68, 73, + 86, 73, 68, 69, 112, 2, 80, 82, 48, 7, 83, 85, 67, 67, 69, 69, 68, 233, + 251, 21, 2, 70, 79, 6, 248, 1, 15, 78, 79, 82, 77, 65, 76, 32, 83, 85, + 66, 71, 82, 79, 85, 80, 195, 170, 20, 77, 5, 209, 170, 21, 23, 32, 87, + 73, 84, 72, 32, 82, 69, 86, 69, 82, 83, 69, 68, 32, 78, 69, 71, 65, 84, + 73, 79, 78, 6, 44, 5, 69, 67, 69, 68, 69, 243, 141, 27, 79, 5, 217, 240, + 8, 2, 32, 79, 125, 36, 3, 82, 65, 32, 235, 204, 27, 32, 120, 120, 7, 76, + 69, 84, 84, 69, 82, 32, 212, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, + 78, 32, 158, 199, 22, 65, 191, 2, 83, 88, 214, 232, 23, 82, 206, 55, 65, + 38, 68, 46, 84, 230, 24, 85, 210, 200, 1, 73, 158, 190, 1, 78, 46, 83, + 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, 76, 2, 77, 2, + 86, 2, 89, 186, 2, 69, 3, 79, 22, 162, 193, 18, 86, 166, 225, 5, 65, 190, + 21, 85, 210, 200, 1, 73, 206, 134, 2, 69, 3, 79, 4, 182, 194, 20, 80, + 243, 173, 2, 76, 200, 1, 72, 8, 72, 79, 82, 73, 90, 79, 78, 84, 1, 6, 86, + 69, 82, 84, 73, 67, 100, 17, 2, 65, 76, 100, 32, 2, 45, 48, 191, 162, 23, + 32, 98, 58, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 14, 197, 219, + 19, 2, 45, 48, 4, 254, 237, 25, 75, 223, 143, 1, 71, 26, 34, 32, 57, 4, + 84, 69, 68, 32, 8, 254, 166, 24, 80, 34, 77, 202, 50, 79, 187, 173, 2, + 65, 18, 214, 1, 67, 34, 83, 144, 213, 15, 3, 76, 73, 78, 192, 132, 1, 4, + 79, 66, 69, 76, 160, 9, 9, 84, 82, 65, 78, 83, 80, 79, 83, 73, 134, 194, + 6, 70, 141, 41, 14, 82, 73, 71, 72, 84, 45, 80, 79, 73, 78, 84, 73, 78, + 71, 4, 238, 178, 26, 73, 167, 17, 82, 4, 182, 241, 25, 79, 223, 111, 81, + 162, 1, 40, 3, 66, 76, 69, 137, 17, 2, 71, 72, 160, 1, 42, 32, 190, 10, + 45, 241, 5, 2, 68, 32, 106, 226, 2, 67, 174, 1, 68, 38, 72, 32, 4, 73, + 78, 84, 69, 38, 76, 144, 1, 7, 78, 69, 83, 84, 69, 68, 32, 74, 80, 66, + 83, 130, 2, 85, 36, 9, 86, 69, 82, 84, 73, 67, 65, 76, 32, 132, 140, 6, + 6, 79, 66, 76, 73, 81, 85, 172, 167, 2, 9, 82, 73, 71, 72, 84, 32, 65, + 82, 67, 194, 174, 3, 65, 186, 189, 9, 69, 190, 141, 4, 81, 213, 101, 6, + 87, 65, 86, 89, 32, 79, 24, 100, 7, 73, 82, 67, 76, 69, 68, 32, 252, 166, + 7, 4, 85, 82, 76, 89, 145, 191, 1, 4, 79, 76, 79, 78, 20, 26, 78, 139, + 249, 19, 68, 2, 137, 199, 2, 5, 85, 77, 66, 69, 82, 4, 186, 160, 18, 79, + 131, 164, 6, 65, 4, 186, 243, 19, 73, 215, 63, 89, 4, 230, 136, 25, 82, + 223, 233, 1, 71, 12, 54, 79, 141, 222, 16, 7, 69, 70, 84, 32, 65, 82, 67, + 10, 26, 87, 163, 207, 24, 71, 6, 26, 45, 187, 225, 26, 32, 4, 162, 242, + 19, 82, 211, 1, 57, 6, 196, 204, 16, 9, 76, 69, 83, 83, 45, 84, 72, 65, + 78, 255, 158, 9, 71, 8, 26, 82, 247, 246, 25, 76, 6, 154, 152, 1, 69, + 139, 180, 15, 73, 18, 80, 6, 81, 85, 65, 82, 69, 32, 30, 84, 50, 85, 185, + 161, 13, 4, 79, 76, 73, 68, 4, 238, 221, 24, 73, 55, 85, 4, 252, 138, 12, + 3, 65, 67, 75, 187, 192, 4, 82, 8, 58, 83, 186, 150, 1, 67, 170, 182, 20, + 80, 191, 194, 4, 66, 2, 209, 142, 27, 4, 80, 69, 78, 83, 4, 210, 155, 18, + 80, 179, 139, 9, 78, 10, 36, 3, 66, 65, 82, 211, 221, 26, 76, 9, 11, 32, + 6, 52, 7, 68, 79, 85, 66, 76, 69, 32, 163, 215, 25, 76, 4, 158, 215, 25, + 76, 51, 82, 48, 112, 5, 76, 73, 78, 69, 32, 220, 1, 7, 83, 84, 82, 85, + 67, 75, 32, 189, 182, 8, 7, 69, 78, 68, 69, 68, 32, 77, 12, 48, 8, 83, + 76, 65, 78, 84, 69, 68, 32, 75, 69, 8, 70, 69, 56, 7, 71, 82, 69, 65, 84, + 69, 82, 1, 4, 76, 69, 83, 83, 4, 177, 232, 19, 9, 81, 85, 65, 76, 32, 84, + 79, 32, 79, 2, 193, 239, 13, 5, 45, 84, 72, 65, 78, 34, 160, 1, 8, 67, + 65, 80, 73, 84, 65, 76, 32, 92, 7, 73, 84, 65, 76, 73, 67, 32, 124, 6, + 83, 77, 65, 76, 76, 32, 153, 155, 13, 8, 78, 45, 65, 82, 89, 32, 83, 85, + 18, 234, 238, 11, 71, 230, 252, 13, 80, 206, 134, 2, 67, 2, 72, 2, 78, 2, + 81, 2, 82, 3, 90, 10, 76, 6, 83, 77, 65, 76, 76, 32, 185, 151, 21, 7, 67, + 65, 80, 73, 84, 65, 76, 8, 238, 240, 27, 68, 2, 69, 2, 73, 3, 74, 4, 146, + 237, 11, 71, 219, 239, 15, 80, 6, 146, 237, 9, 70, 26, 77, 255, 239, 16, + 83, 2, 179, 246, 26, 78, 144, 1, 86, 32, 156, 1, 10, 45, 80, 79, 73, 78, + 84, 73, 78, 71, 32, 65, 4, 87, 65, 82, 68, 10, 60, 4, 84, 65, 67, 75, + 250, 222, 24, 70, 30, 82, 251, 64, 65, 5, 29, 5, 32, 87, 73, 84, 72, 2, + 11, 32, 2, 11, 67, 2, 201, 169, 20, 4, 73, 82, 67, 76, 8, 178, 225, 24, + 82, 0, 7, 83, 77, 65, 76, 76, 32, 82, 35, 84, 126, 56, 8, 32, 70, 65, 67, + 73, 78, 71, 32, 89, 2, 83, 32, 8, 54, 72, 1, 9, 78, 79, 84, 67, 72, 69, + 68, 32, 72, 4, 137, 201, 26, 3, 79, 79, 75, 118, 158, 1, 65, 202, 2, 84, + 168, 192, 8, 2, 87, 72, 186, 138, 8, 90, 198, 184, 8, 66, 154, 1, 68, 50, + 70, 82, 72, 146, 4, 67, 46, 81, 42, 82, 22, 83, 243, 7, 80, 34, 40, 4, + 82, 82, 79, 87, 187, 255, 24, 78, 33, 11, 32, 30, 144, 1, 5, 87, 73, 84, + 72, 32, 208, 147, 3, 14, 76, 69, 70, 84, 87, 65, 82, 68, 83, 32, 79, 70, + 32, 85, 254, 235, 21, 65, 170, 10, 70, 175, 5, 84, 22, 180, 163, 5, 6, + 67, 79, 82, 78, 69, 82, 182, 222, 19, 68, 58, 76, 42, 77, 38, 78, 58, 83, + 66, 69, 246, 12, 84, 139, 59, 72, 36, 36, 2, 82, 73, 161, 2, 2, 87, 79, + 32, 44, 5, 65, 78, 71, 76, 69, 171, 146, 25, 80, 30, 56, 8, 45, 72, 69, + 65, 68, 69, 68, 32, 215, 152, 25, 32, 28, 68, 5, 65, 82, 82, 79, 87, 134, + 201, 16, 90, 162, 199, 8, 68, 39, 80, 23, 11, 32, 20, 216, 139, 25, 15, + 76, 69, 70, 84, 87, 65, 82, 68, 83, 32, 79, 70, 32, 85, 80, 98, 84, 19, + 87, 4, 162, 145, 25, 32, 105, 15, 45, 72, 69, 65, 68, 69, 68, 32, 65, 82, + 82, 79, 87, 32, 87, 22, 138, 1, 65, 106, 79, 152, 1, 12, 85, 77, 32, 87, + 73, 84, 72, 32, 68, 82, 85, 77, 152, 182, 16, 6, 73, 86, 69, 32, 83, 76, + 179, 149, 10, 69, 8, 238, 189, 2, 67, 236, 243, 5, 10, 70, 84, 73, 78, + 71, 32, 80, 79, 73, 78, 201, 192, 15, 3, 71, 79, 78, 8, 56, 6, 77, 69, + 68, 65, 82, 89, 34, 80, 251, 174, 26, 79, 2, 217, 160, 20, 3, 32, 67, 65, + 4, 240, 234, 17, 6, 32, 79, 70, 32, 66, 76, 191, 194, 9, 76, 2, 217, 165, + 12, 3, 83, 84, 73, 162, 2, 76, 7, 80, 76, 79, 89, 65, 78, 32, 128, 187, + 19, 2, 77, 80, 247, 162, 8, 67, 158, 2, 212, 2, 6, 65, 70, 70, 73, 88, + 32, 152, 7, 7, 76, 69, 84, 84, 69, 82, 32, 208, 188, 1, 16, 84, 72, 73, + 67, 75, 32, 76, 69, 84, 84, 69, 82, 32, 83, 69, 76, 236, 160, 3, 4, 68, + 79, 85, 66, 204, 172, 16, 19, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, + 32, 67, 72, 73, 78, 79, 79, 75, 153, 143, 5, 11, 83, 73, 71, 78, 32, 79, + 32, 87, 73, 84, 72, 64, 140, 1, 9, 65, 84, 84, 65, 67, 72, 69, 68, 32, + 184, 1, 5, 72, 73, 71, 72, 32, 102, 76, 40, 4, 82, 73, 71, 72, 169, 2, 4, + 77, 73, 68, 32, 14, 112, 2, 84, 65, 224, 4, 13, 76, 69, 70, 84, 45, 84, + 79, 45, 82, 73, 71, 72, 84, 26, 83, 146, 165, 20, 69, 3, 73, 6, 44, 5, + 78, 71, 69, 78, 84, 227, 210, 26, 73, 5, 227, 169, 20, 32, 20, 166, 2, + 76, 50, 84, 38, 86, 238, 134, 8, 71, 186, 2, 65, 154, 231, 17, 87, 170, + 25, 67, 223, 126, 68, 24, 36, 2, 69, 70, 29, 3, 79, 87, 32, 2, 209, 2, 3, + 84, 32, 72, 22, 90, 65, 38, 76, 50, 84, 38, 86, 238, 134, 8, 71, 210, + 233, 17, 87, 170, 25, 67, 223, 126, 68, 4, 202, 150, 21, 67, 131, 169, 5, + 82, 4, 220, 216, 7, 3, 79, 78, 71, 207, 231, 18, 73, 2, 173, 254, 7, 4, + 73, 71, 72, 84, 4, 37, 7, 69, 82, 84, 73, 67, 65, 76, 5, 131, 1, 32, 4, + 42, 72, 41, 6, 86, 69, 82, 84, 73, 67, 2, 37, 7, 79, 82, 73, 90, 79, 78, + 84, 2, 17, 2, 65, 76, 2, 11, 32, 2, 11, 83, 2, 237, 205, 26, 2, 69, 67, + 214, 1, 222, 1, 65, 22, 68, 34, 69, 30, 70, 22, 71, 22, 74, 162, 1, 75, + 66, 76, 50, 77, 62, 78, 134, 1, 79, 50, 80, 86, 82, 74, 83, 210, 2, 84, + 66, 85, 42, 86, 38, 87, 70, 88, 230, 206, 26, 72, 138, 60, 73, 194, 41, + 89, 215, 22, 66, 5, 203, 176, 27, 79, 7, 206, 151, 27, 32, 211, 61, 72, + 7, 254, 212, 27, 69, 3, 85, 5, 143, 133, 27, 32, 5, 207, 129, 24, 32, 19, + 11, 32, 16, 76, 8, 87, 73, 84, 72, 32, 68, 79, 84, 230, 5, 77, 2, 78, + 215, 170, 26, 83, 5, 233, 214, 26, 12, 83, 32, 73, 78, 83, 73, 68, 69, + 32, 65, 78, 68, 9, 26, 32, 131, 211, 27, 75, 4, 138, 128, 24, 82, 247, + 210, 3, 77, 9, 248, 243, 21, 3, 79, 78, 71, 227, 222, 5, 72, 11, 11, 32, + 8, 162, 4, 78, 238, 170, 26, 87, 147, 163, 1, 83, 19, 38, 32, 49, 5, 65, + 83, 65, 76, 32, 8, 202, 3, 77, 238, 170, 26, 87, 147, 163, 1, 83, 8, 150, + 209, 27, 65, 2, 73, 2, 79, 3, 85, 11, 218, 207, 27, 79, 146, 1, 65, 2, + 85, 3, 87, 9, 52, 7, 69, 82, 78, 73, 78, 32, 65, 179, 128, 27, 32, 4, + 130, 208, 27, 77, 3, 78, 11, 248, 240, 21, 6, 79, 77, 65, 78, 73, 65, + 158, 161, 5, 32, 211, 61, 72, 49, 58, 32, 164, 1, 5, 76, 79, 65, 78, 32, + 195, 158, 6, 72, 26, 102, 74, 22, 75, 2, 80, 2, 84, 20, 7, 87, 73, 84, + 72, 32, 68, 79, 214, 205, 27, 77, 2, 78, 3, 83, 5, 171, 144, 27, 32, 5, + 151, 149, 27, 32, 4, 183, 165, 12, 84, 18, 74, 69, 138, 176, 5, 79, 154, + 205, 21, 65, 198, 78, 68, 146, 1, 74, 3, 85, 6, 242, 204, 27, 69, 2, 72, + 3, 78, 9, 26, 32, 183, 204, 27, 72, 4, 190, 249, 23, 82, 247, 210, 3, 83, + 9, 186, 252, 26, 32, 214, 79, 72, 3, 73, 5, 217, 237, 6, 4, 79, 67, 65, + 76, 17, 66, 79, 178, 146, 27, 32, 250, 36, 69, 218, 19, 65, 2, 72, 3, 73, + 5, 255, 202, 27, 87, 250, 28, 234, 2, 65, 188, 3, 10, 68, 73, 84, 79, 82, + 73, 65, 76, 32, 67, 22, 71, 240, 75, 4, 73, 71, 72, 84, 198, 1, 76, 194, + 9, 77, 214, 5, 78, 246, 3, 79, 36, 2, 81, 85, 182, 8, 82, 222, 1, 83, + 118, 84, 242, 31, 85, 198, 1, 88, 252, 3, 2, 89, 69, 152, 72, 4, 45, 77, + 65, 73, 132, 207, 18, 3, 74, 69, 67, 168, 134, 2, 8, 86, 69, 82, 71, 82, + 69, 69, 78, 159, 147, 5, 80, 22, 38, 82, 130, 230, 25, 83, 179, 64, 71, + 19, 30, 32, 137, 1, 2, 84, 72, 6, 88, 3, 79, 70, 32, 221, 210, 4, 13, 87, + 73, 84, 72, 32, 72, 69, 65, 82, 73, 78, 71, 32, 4, 216, 138, 11, 2, 77, + 65, 227, 206, 6, 82, 11, 17, 2, 32, 71, 8, 44, 5, 76, 79, 66, 69, 32, + 239, 165, 24, 82, 6, 70, 65, 149, 207, 13, 11, 69, 85, 82, 79, 80, 69, + 45, 65, 70, 82, 73, 4, 128, 214, 9, 4, 77, 69, 82, 73, 133, 154, 2, 11, + 83, 73, 65, 45, 65, 85, 83, 84, 82, 65, 76, 2, 191, 163, 2, 79, 174, 17, + 96, 18, 89, 80, 84, 73, 65, 78, 32, 72, 73, 69, 82, 79, 71, 76, 89, 80, + 72, 32, 199, 195, 27, 71, 172, 17, 146, 3, 65, 178, 4, 66, 52, 2, 67, 48, + 224, 1, 2, 68, 48, 170, 4, 69, 198, 3, 70, 164, 4, 2, 71, 48, 210, 3, 72, + 222, 1, 73, 238, 2, 76, 122, 77, 134, 9, 78, 210, 5, 79, 140, 5, 2, 80, + 48, 120, 2, 82, 48, 232, 1, 2, 83, 48, 190, 3, 84, 220, 2, 2, 85, 48, + 250, 2, 86, 134, 5, 87, 236, 2, 3, 88, 48, 48, 88, 3, 89, 48, 48, 84, 2, + 90, 48, 224, 196, 3, 3, 75, 48, 48, 177, 218, 14, 3, 81, 48, 48, 228, 1, + 30, 48, 133, 3, 2, 65, 48, 160, 1, 86, 48, 98, 49, 102, 52, 234, 55, 51, + 138, 163, 20, 55, 230, 216, 1, 50, 2, 53, 3, 54, 24, 238, 68, 54, 146, + 185, 21, 53, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, + 24, 158, 253, 21, 52, 2, 55, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 53, + 2, 54, 2, 56, 3, 57, 28, 186, 252, 21, 48, 2, 50, 2, 51, 2, 53, 174, 193, + 5, 49, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 68, 46, 48, 186, 55, 51, 138, + 251, 21, 49, 3, 50, 22, 150, 66, 55, 190, 250, 26, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 2, 56, 3, 57, 26, 148, 9, 4, 69, 71, 73, 78, 253, 25, + 2, 48, 48, 56, 34, 48, 90, 49, 207, 199, 8, 50, 24, 170, 40, 50, 250, + 146, 27, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 22, 158, + 249, 21, 48, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, + 2, 56, 3, 57, 184, 1, 70, 48, 94, 51, 102, 52, 102, 53, 106, 54, 134, 30, + 50, 251, 141, 22, 49, 20, 238, 247, 21, 56, 174, 193, 5, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 24, 146, 247, 21, 49, 2, 52, 174, + 193, 5, 48, 2, 50, 2, 51, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, 174, + 246, 21, 54, 2, 56, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 55, 3, 57, 42, 154, 61, 48, 178, 184, 21, 50, 2, 52, 174, 193, 5, 49, + 2, 51, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 32, 134, 61, 55, 138, 249, 26, + 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 94, 30, 48, 189, 2, 2, 78, + 68, 88, 38, 48, 94, 50, 102, 51, 235, 7, 49, 22, 202, 243, 21, 56, 2, 57, + 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 24, 238, 242, + 21, 48, 2, 56, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, + 3, 57, 18, 138, 242, 21, 52, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 54, + 2, 55, 3, 56, 6, 11, 32, 6, 68, 2, 83, 69, 136, 160, 5, 6, 87, 65, 76, + 76, 69, 68, 191, 19, 69, 2, 231, 238, 26, 71, 132, 1, 42, 48, 133, 9, 5, + 85, 76, 76, 32, 66, 130, 1, 54, 48, 94, 49, 102, 51, 102, 52, 102, 53, + 215, 1, 50, 20, 226, 239, 21, 49, 174, 193, 5, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 2, 55, 2, 56, 3, 57, 22, 134, 239, 21, 51, 174, 193, 5, 48, 2, 49, + 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 26, 162, 238, 21, 49, 2, + 55, 2, 56, 174, 193, 5, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 57, 26, + 190, 237, 21, 53, 2, 54, 2, 55, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 56, 3, 57, 14, 142, 27, 49, 250, 146, 27, 48, 2, 50, 3, 51, 128, + 1, 62, 48, 98, 49, 102, 51, 102, 52, 130, 28, 50, 239, 155, 8, 53, 24, + 214, 50, 55, 146, 185, 21, 54, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, + 53, 2, 56, 3, 57, 22, 134, 235, 21, 49, 174, 193, 5, 48, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 24, 162, 234, 21, 54, 2, 55, 174, + 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 56, 3, 57, 24, 190, + 233, 21, 51, 2, 53, 174, 193, 5, 48, 2, 49, 2, 50, 2, 52, 2, 54, 2, 55, + 2, 56, 3, 57, 24, 80, 2, 48, 48, 84, 4, 65, 76, 70, 32, 209, 40, 7, 79, + 82, 73, 90, 79, 78, 84, 18, 134, 232, 21, 54, 174, 193, 5, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 2, 55, 3, 56, 4, 22, 66, 175, 43, 76, 2, 237, 233, 23, + 2, 76, 65, 52, 58, 48, 181, 1, 9, 78, 83, 69, 82, 84, 32, 65, 84, 32, 38, + 18, 48, 95, 49, 22, 174, 230, 21, 53, 2, 57, 174, 193, 5, 49, 2, 50, 2, + 51, 2, 52, 2, 54, 2, 55, 3, 56, 16, 210, 229, 21, 48, 2, 49, 174, 193, 5, + 50, 2, 51, 2, 52, 3, 53, 14, 68, 6, 66, 79, 84, 84, 79, 77, 0, 3, 84, 79, + 80, 239, 138, 19, 77, 7, 11, 32, 4, 134, 152, 26, 69, 221, 6, 2, 83, 84, + 22, 32, 2, 48, 48, 215, 162, 15, 79, 20, 238, 227, 21, 50, 2, 54, 174, + 193, 5, 49, 2, 51, 2, 52, 2, 53, 2, 55, 3, 56, 164, 1, 158, 1, 48, 128, + 4, 15, 79, 68, 73, 70, 73, 69, 82, 32, 68, 65, 77, 65, 71, 69, 68, 189, + 239, 23, 14, 73, 82, 82, 79, 82, 32, 72, 79, 82, 73, 90, 79, 78, 84, 132, + 1, 42, 48, 98, 49, 106, 50, 102, 51, 107, 52, 24, 182, 40, 49, 146, 185, + 21, 51, 174, 193, 5, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 44, + 138, 41, 50, 222, 183, 21, 48, 2, 53, 2, 54, 2, 55, 174, 193, 5, 49, 2, + 51, 2, 52, 2, 56, 3, 57, 26, 254, 223, 21, 50, 2, 52, 2, 56, 174, 193, 5, + 48, 2, 49, 2, 51, 2, 53, 2, 54, 2, 55, 3, 57, 26, 138, 38, 51, 146, 185, + 21, 49, 174, 193, 5, 48, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, + 12, 178, 222, 21, 48, 174, 193, 5, 49, 2, 50, 2, 51, 3, 52, 31, 25, 4, + 32, 65, 84, 32, 28, 96, 6, 66, 79, 84, 84, 79, 77, 120, 5, 83, 84, 65, + 82, 84, 68, 3, 84, 79, 80, 139, 143, 26, 69, 11, 11, 32, 8, 56, 5, 83, + 84, 65, 82, 84, 186, 1, 65, 199, 142, 26, 69, 5, 129, 2, 8, 32, 65, 78, + 68, 32, 84, 79, 80, 7, 29, 5, 32, 65, 78, 68, 32, 4, 146, 212, 23, 66, + 247, 207, 2, 84, 11, 11, 32, 8, 54, 65, 20, 5, 83, 84, 65, 82, 84, 179, + 142, 26, 69, 2, 73, 2, 78, 68, 5, 53, 11, 32, 65, 78, 68, 32, 66, 79, 84, + 84, 79, 77, 2, 235, 135, 19, 32, 194, 1, 50, 48, 128, 2, 2, 76, 48, 229, + 1, 2, 85, 48, 98, 58, 49, 98, 51, 194, 14, 50, 150, 6, 52, 155, 249, 21, + 48, 24, 146, 32, 56, 190, 250, 26, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 2, 55, 3, 57, 28, 194, 216, 21, 51, 2, 52, 2, 53, 2, 55, 174, 193, + 5, 48, 2, 49, 2, 50, 2, 54, 2, 56, 3, 57, 44, 34, 48, 94, 49, 151, 181, + 20, 50, 20, 186, 215, 21, 53, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, + 54, 2, 55, 2, 56, 3, 57, 22, 222, 214, 21, 55, 174, 193, 5, 48, 2, 49, 2, + 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 52, 34, 49, 102, 50, 159, + 138, 22, 48, 26, 214, 213, 21, 48, 2, 49, 2, 56, 174, 193, 5, 50, 2, 51, + 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 8, 242, 212, 21, 50, 174, 193, 5, 48, + 3, 49, 152, 1, 50, 48, 229, 172, 18, 6, 86, 69, 82, 76, 65, 89, 150, 1, + 66, 48, 154, 1, 49, 138, 1, 50, 102, 51, 106, 53, 247, 134, 22, 52, 34, + 90, 54, 238, 210, 21, 49, 2, 53, 174, 193, 5, 50, 2, 51, 2, 52, 2, 55, 2, + 56, 3, 57, 15, 150, 148, 27, 65, 2, 66, 2, 67, 2, 68, 2, 69, 3, 70, 28, + 98, 48, 206, 209, 21, 57, 174, 193, 5, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 54, 2, 55, 3, 56, 9, 246, 146, 27, 65, 2, 66, 3, 67, 28, 166, 209, 21, + 48, 2, 52, 2, 53, 2, 57, 174, 193, 5, 49, 2, 50, 2, 51, 2, 54, 2, 55, 3, + 56, 32, 134, 23, 54, 190, 185, 21, 48, 2, 51, 174, 193, 5, 49, 2, 50, 2, + 52, 2, 53, 2, 55, 2, 56, 3, 57, 8, 202, 22, 48, 191, 250, 26, 49, 26, 26, + 48, 235, 148, 8, 49, 22, 158, 207, 21, 49, 2, 51, 174, 193, 5, 50, 2, 52, + 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 68, 34, 48, 98, 49, 219, 132, 22, 50, + 24, 142, 21, 51, 146, 185, 21, 50, 174, 193, 5, 49, 2, 52, 2, 53, 2, 54, + 2, 55, 2, 56, 3, 57, 24, 190, 205, 21, 48, 2, 54, 174, 193, 5, 49, 2, 50, + 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 108, 50, 48, 94, 49, 106, 50, + 98, 51, 155, 226, 18, 52, 22, 166, 204, 21, 50, 2, 54, 174, 193, 5, 49, + 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, 3, 57, 26, 186, 18, 52, 146, 185, 21, + 55, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 2, 53, 2, 54, 2, 56, 3, 57, 24, + 210, 17, 54, 190, 250, 26, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, + 2, 56, 3, 57, 22, 130, 202, 21, 53, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, + 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 90, 34, 48, 249, 12, 3, 65, 76, 76, + 88, 42, 48, 94, 49, 102, 51, 171, 254, 21, 50, 26, 206, 200, 21, 51, 2, + 55, 2, 56, 2, 57, 174, 193, 5, 49, 2, 50, 2, 52, 2, 53, 3, 54, 24, 242, + 199, 21, 49, 2, 54, 174, 193, 5, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, + 2, 56, 3, 57, 18, 142, 199, 21, 50, 2, 51, 174, 193, 5, 48, 2, 49, 2, 52, + 2, 53, 3, 54, 94, 50, 48, 90, 50, 102, 51, 102, 52, 139, 251, 21, 49, 22, + 254, 12, 54, 190, 250, 26, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 55, 2, 56, + 3, 57, 24, 182, 197, 21, 51, 2, 57, 174, 193, 5, 48, 2, 49, 2, 50, 2, 52, + 2, 53, 2, 54, 2, 55, 3, 56, 22, 210, 196, 21, 50, 174, 193, 5, 48, 2, 49, + 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 6, 154, 133, 27, 48, 2, + 49, 3, 50, 158, 1, 42, 48, 185, 4, 5, 69, 82, 84, 73, 67, 156, 1, 62, 48, + 98, 49, 98, 50, 210, 1, 51, 201, 191, 21, 2, 52, 48, 42, 198, 9, 55, 98, + 49, 178, 184, 21, 50, 174, 193, 5, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, + 32, 186, 8, 49, 46, 50, 190, 250, 26, 48, 2, 51, 2, 52, 2, 53, 2, 54, 2, + 55, 2, 56, 3, 57, 50, 98, 48, 182, 192, 21, 51, 2, 56, 2, 57, 174, 193, + 5, 49, 2, 50, 2, 52, 2, 53, 2, 54, 3, 55, 27, 222, 129, 27, 65, 2, 66, 2, + 67, 2, 68, 2, 69, 2, 70, 2, 71, 2, 72, 2, 73, 2, 74, 2, 75, 3, 76, 28, + 198, 191, 21, 48, 2, 49, 2, 51, 2, 55, 174, 193, 5, 50, 2, 52, 2, 53, 2, + 54, 2, 56, 3, 57, 2, 169, 134, 23, 2, 65, 76, 66, 34, 48, 161, 2, 3, 73, + 68, 69, 64, 26, 48, 94, 49, 103, 50, 22, 134, 190, 21, 51, 2, 57, 174, + 193, 5, 49, 2, 50, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 28, 170, 189, 21, + 48, 2, 52, 2, 55, 2, 56, 174, 193, 5, 49, 2, 50, 2, 51, 2, 53, 2, 54, 3, + 57, 14, 198, 188, 21, 52, 174, 193, 5, 48, 2, 49, 2, 50, 2, 51, 3, 53, 2, + 17, 2, 32, 76, 2, 211, 250, 14, 79, 24, 202, 2, 52, 146, 185, 21, 54, 2, + 56, 174, 193, 5, 49, 2, 50, 2, 51, 2, 53, 3, 55, 18, 130, 187, 21, 49, + 174, 193, 5, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 82, 22, 48, + 167, 1, 49, 34, 90, 50, 46, 51, 146, 185, 21, 52, 2, 53, 174, 193, 5, 49, + 2, 54, 2, 55, 2, 56, 3, 57, 11, 230, 250, 26, 65, 2, 66, 2, 67, 3, 68, 7, + 186, 250, 26, 65, 3, 66, 48, 66, 53, 86, 54, 138, 249, 26, 48, 2, 49, 2, + 50, 2, 51, 3, 52, 21, 218, 249, 26, 65, 2, 66, 2, 67, 2, 68, 2, 69, 2, + 70, 2, 71, 2, 72, 3, 73, 19, 134, 249, 26, 65, 2, 66, 2, 67, 2, 68, 2, + 69, 2, 70, 2, 71, 3, 72, 14, 26, 32, 159, 171, 15, 72, 12, 42, 80, 242, + 133, 3, 84, 135, 225, 21, 83, 8, 242, 132, 3, 79, 213, 129, 16, 22, 69, + 84, 65, 76, 76, 69, 68, 32, 79, 85, 84, 76, 73, 78, 69, 68, 32, 66, 76, + 65, 67, 75, 160, 1, 132, 1, 13, 66, 65, 83, 65, 78, 32, 76, 69, 84, 84, + 69, 82, 32, 166, 3, 69, 176, 4, 7, 89, 77, 65, 73, 67, 32, 76, 155, 238, + 26, 70, 80, 230, 1, 71, 78, 76, 34, 78, 50, 82, 158, 236, 24, 69, 198, + 134, 1, 67, 2, 68, 2, 75, 2, 83, 2, 84, 2, 90, 182, 105, 66, 2, 70, 2, + 72, 2, 74, 2, 77, 2, 80, 2, 81, 2, 86, 2, 88, 214, 22, 65, 2, 73, 2, 79, + 2, 85, 3, 89, 8, 38, 72, 138, 221, 26, 74, 215, 22, 69, 4, 194, 168, 24, + 65, 155, 203, 2, 69, 4, 226, 220, 26, 76, 215, 22, 69, 8, 194, 220, 26, + 68, 2, 74, 214, 22, 65, 3, 69, 4, 146, 220, 26, 82, 215, 22, 69, 32, 96, + 5, 67, 84, 82, 73, 67, 160, 1, 7, 77, 69, 78, 84, 32, 79, 70, 246, 230, + 25, 80, 223, 80, 86, 10, 26, 32, 215, 165, 23, 65, 8, 98, 80, 244, 134, + 17, 2, 84, 79, 204, 175, 8, 9, 76, 73, 71, 72, 84, 32, 66, 85, 76, 131, + 32, 65, 2, 11, 76, 2, 131, 240, 26, 85, 19, 11, 32, 16, 72, 5, 87, 73, + 84, 72, 32, 157, 142, 16, 7, 79, 80, 69, 78, 73, 78, 71, 12, 130, 1, 76, + 32, 12, 84, 87, 79, 32, 72, 79, 82, 73, 90, 79, 78, 84, 186, 144, 19, 86, + 186, 149, 4, 85, 166, 47, 79, 131, 153, 2, 68, 2, 141, 209, 24, 3, 79, + 78, 71, 2, 233, 158, 14, 7, 65, 76, 32, 83, 84, 82, 79, 46, 170, 154, 4, + 69, 153, 147, 15, 15, 73, 71, 65, 84, 85, 82, 69, 32, 90, 65, 89, 73, 78, + 45, 89, 53, 48, 4, 79, 74, 73, 32, 218, 2, 80, 163, 3, 32, 18, 164, 1, + 10, 67, 79, 77, 80, 79, 78, 69, 78, 84, 32, 109, 26, 77, 79, 68, 73, 70, + 73, 69, 82, 32, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, 75, 32, 84, 89, + 80, 69, 45, 8, 140, 200, 14, 2, 82, 69, 12, 5, 67, 85, 82, 76, 89, 0, 5, + 87, 72, 73, 84, 69, 173, 190, 2, 2, 66, 65, 10, 152, 135, 20, 2, 49, 45, + 214, 227, 6, 51, 2, 52, 2, 53, 3, 54, 26, 44, 3, 84, 89, 32, 225, 229, 3, + 2, 72, 65, 24, 82, 78, 60, 3, 80, 65, 71, 20, 3, 83, 69, 84, 177, 165, + 26, 4, 68, 79, 67, 85, 8, 36, 3, 79, 84, 69, 187, 161, 23, 69, 7, 131, + 232, 12, 32, 4, 139, 229, 24, 69, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, + 234, 203, 13, 82, 24, 3, 76, 69, 70, 176, 166, 1, 2, 83, 77, 207, 220, 8, + 79, 38, 86, 32, 64, 2, 68, 32, 214, 1, 81, 20, 6, 86, 69, 76, 79, 80, 69, + 235, 164, 15, 84, 6, 42, 81, 186, 129, 25, 68, 139, 167, 1, 83, 2, 191, + 160, 26, 85, 20, 32, 3, 79, 70, 32, 131, 1, 87, 18, 88, 3, 80, 82, 79, + 146, 149, 20, 71, 56, 2, 83, 69, 194, 59, 77, 30, 84, 139, 251, 4, 76, 4, + 210, 149, 20, 84, 239, 206, 5, 79, 2, 241, 169, 19, 7, 73, 84, 72, 32, + 76, 69, 70, 5, 167, 209, 20, 85, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 42, + 76, 221, 140, 23, 4, 68, 79, 87, 78, 2, 209, 248, 21, 4, 73, 71, 72, 84, + 6, 238, 227, 26, 76, 2, 77, 3, 84, 44, 28, 2, 65, 76, 231, 6, 73, 38, 30, + 32, 133, 2, 2, 83, 32, 12, 56, 3, 84, 79, 32, 237, 220, 12, 5, 65, 78, + 68, 32, 80, 10, 68, 3, 79, 82, 32, 217, 144, 26, 8, 66, 89, 32, 68, 69, + 70, 73, 78, 8, 64, 3, 80, 82, 69, 28, 3, 83, 85, 67, 170, 210, 24, 71, + 39, 76, 2, 133, 230, 14, 2, 67, 69, 2, 221, 132, 25, 3, 67, 69, 69, 26, + 72, 4, 83, 73, 71, 78, 232, 207, 24, 4, 87, 73, 84, 72, 223, 192, 1, 67, + 23, 11, 32, 20, 42, 65, 201, 1, 5, 87, 73, 84, 72, 32, 12, 112, 5, 66, + 79, 86, 69, 32, 65, 19, 78, 68, 32, 83, 76, 65, 78, 84, 69, 68, 32, 80, + 65, 82, 65, 76, 76, 69, 76, 8, 158, 178, 20, 80, 154, 5, 84, 150, 184, 2, + 76, 231, 207, 2, 82, 5, 135, 205, 6, 32, 8, 160, 1, 4, 66, 85, 77, 80, + 20, 7, 73, 78, 70, 73, 78, 73, 84, 20, 18, 84, 87, 79, 32, 68, 79, 84, + 83, 32, 65, 66, 79, 86, 69, 32, 65, 78, 68, 155, 230, 14, 68, 2, 163, + 224, 25, 89, 2, 159, 182, 24, 89, 2, 17, 2, 32, 84, 2, 195, 181, 24, 87, + 6, 80, 7, 86, 65, 76, 69, 78, 84, 32, 185, 181, 20, 7, 65, 78, 71, 85, + 76, 65, 82, 4, 48, 6, 87, 73, 84, 72, 32, 70, 207, 188, 26, 84, 2, 11, + 79, 2, 177, 229, 2, 2, 85, 82, 20, 152, 1, 11, 82, 79, 82, 45, 66, 65, + 82, 82, 69, 68, 32, 216, 147, 5, 7, 73, 83, 32, 70, 79, 82, 77, 205, 162, + 7, 9, 65, 83, 69, 32, 84, 79, 32, 84, 72, 12, 240, 200, 5, 4, 87, 72, 73, + 84, 13, 5, 66, 76, 65, 67, 75, 10, 58, 67, 20, 6, 84, 73, 77, 65, 84, 69, + 239, 216, 26, 65, 5, 143, 148, 25, 65, 4, 218, 197, 25, 68, 147, 147, 1, + 83, 154, 8, 60, 7, 72, 73, 79, 80, 73, 67, 32, 134, 216, 26, 66, 3, 88, + 150, 8, 204, 1, 2, 67, 79, 232, 1, 7, 78, 85, 77, 66, 69, 82, 32, 114, + 80, 54, 83, 156, 24, 11, 84, 79, 78, 65, 76, 32, 77, 65, 82, 75, 32, 174, + 183, 18, 68, 218, 184, 5, 70, 82, 81, 137, 140, 2, 4, 87, 79, 82, 68, 10, + 26, 77, 183, 134, 26, 76, 8, 52, 7, 66, 73, 78, 73, 78, 71, 32, 167, 211, + 26, 77, 6, 60, 11, 71, 69, 77, 73, 78, 65, 84, 73, 79, 78, 32, 51, 86, 4, + 44, 5, 65, 78, 68, 32, 86, 207, 147, 26, 77, 2, 129, 213, 21, 4, 79, 87, + 69, 76, 22, 66, 84, 226, 171, 21, 72, 210, 188, 3, 69, 30, 70, 42, 78, + 39, 83, 8, 130, 134, 16, 69, 222, 227, 8, 72, 27, 87, 4, 242, 103, 65, + 201, 155, 25, 5, 82, 69, 70, 65, 67, 198, 7, 50, 69, 37, 8, 89, 76, 76, + 65, 66, 76, 69, 32, 4, 154, 157, 23, 77, 187, 204, 2, 67, 194, 7, 210, 1, + 66, 90, 67, 246, 1, 68, 186, 1, 70, 90, 71, 214, 2, 72, 162, 1, 75, 102, + 77, 90, 78, 90, 80, 138, 2, 81, 174, 1, 82, 86, 83, 210, 1, 84, 122, 74, + 2, 76, 138, 1, 87, 2, 89, 66, 88, 134, 1, 90, 95, 86, 38, 194, 12, 87, + 230, 8, 66, 158, 250, 20, 65, 2, 79, 154, 129, 5, 69, 150, 64, 73, 3, 85, + 78, 94, 67, 254, 15, 72, 146, 254, 20, 65, 2, 79, 154, 129, 5, 69, 222, + 61, 87, 186, 2, 73, 3, 85, 42, 70, 72, 198, 141, 21, 65, 154, 129, 5, 69, + 150, 64, 73, 2, 79, 3, 85, 28, 166, 19, 72, 158, 250, 20, 65, 154, 129, + 5, 69, 150, 64, 73, 2, 79, 3, 85, 60, 94, 68, 214, 14, 90, 198, 253, 20, + 65, 2, 79, 154, 129, 5, 69, 222, 61, 87, 186, 2, 73, 3, 85, 30, 210, 14, + 72, 198, 253, 20, 65, 2, 79, 154, 129, 5, 69, 222, 61, 87, 186, 2, 73, 3, + 85, 24, 190, 8, 87, 130, 131, 21, 65, 154, 129, 5, 69, 222, 61, 89, 186, + 2, 73, 2, 79, 3, 85, 118, 142, 1, 85, 226, 7, 71, 232, 3, 7, 76, 79, 84, + 84, 65, 76, 32, 158, 2, 87, 218, 1, 89, 158, 250, 20, 65, 2, 79, 154, + 129, 5, 69, 151, 64, 73, 39, 29, 5, 82, 65, 71, 69, 32, 36, 74, 66, 2, + 70, 2, 77, 2, 80, 46, 71, 2, 75, 2, 81, 191, 210, 11, 72, 4, 11, 87, 4, + 182, 179, 26, 69, 215, 22, 73, 6, 11, 87, 6, 202, 137, 26, 69, 151, 64, + 73, 52, 70, 72, 206, 135, 21, 65, 2, 79, 154, 129, 5, 69, 150, 64, 73, 3, + 85, 36, 202, 4, 87, 230, 8, 89, 158, 250, 20, 65, 154, 129, 5, 69, 150, + 64, 73, 2, 79, 3, 85, 64, 250, 4, 88, 134, 6, 87, 218, 1, 89, 158, 250, + 20, 65, 2, 79, 154, 129, 5, 69, 150, 64, 73, 3, 85, 26, 142, 3, 87, 130, + 131, 21, 65, 2, 79, 154, 129, 5, 69, 222, 61, 89, 186, 2, 73, 3, 85, 36, + 166, 7, 89, 146, 254, 20, 65, 2, 79, 154, 129, 5, 69, 222, 61, 87, 186, + 2, 73, 3, 85, 56, 82, 72, 142, 1, 87, 130, 131, 21, 65, 2, 79, 154, 129, + 5, 69, 150, 64, 73, 3, 85, 32, 74, 65, 194, 131, 21, 79, 154, 129, 5, 69, + 222, 61, 87, 186, 2, 73, 3, 85, 19, 160, 9, 8, 82, 89, 78, 71, 69, 65, + 76, 32, 203, 187, 26, 65, 8, 150, 132, 26, 69, 150, 64, 65, 3, 73, 64, + 94, 72, 134, 6, 87, 218, 1, 89, 158, 250, 20, 65, 2, 79, 154, 129, 5, 69, + 150, 64, 73, 3, 85, 24, 130, 6, 87, 246, 251, 20, 65, 154, 129, 5, 69, + 150, 64, 73, 2, 79, 3, 85, 20, 170, 129, 21, 65, 2, 79, 154, 129, 5, 69, + 222, 61, 87, 2, 89, 186, 2, 73, 3, 85, 74, 102, 69, 226, 1, 72, 170, 3, + 90, 78, 83, 158, 250, 20, 65, 2, 79, 246, 190, 5, 87, 186, 2, 73, 3, 85, + 13, 56, 8, 66, 65, 84, 66, 69, 73, 84, 32, 227, 192, 26, 69, 8, 226, 251, + 21, 66, 2, 70, 2, 77, 3, 80, 80, 118, 72, 76, 2, 84, 72, 62, 90, 162, 2, + 83, 234, 250, 20, 65, 2, 79, 154, 129, 5, 69, 222, 61, 87, 186, 2, 73, 3, + 85, 18, 142, 254, 20, 65, 2, 79, 154, 129, 5, 69, 222, 61, 87, 186, 2, + 73, 3, 85, 12, 218, 254, 25, 69, 222, 61, 65, 186, 2, 73, 2, 79, 3, 85, + 16, 134, 253, 20, 65, 2, 79, 154, 129, 5, 69, 150, 64, 73, 3, 85, 40, 82, + 87, 218, 1, 89, 158, 250, 20, 65, 2, 79, 154, 129, 5, 69, 150, 64, 73, 3, + 85, 10, 242, 251, 20, 65, 154, 129, 5, 69, 151, 64, 73, 48, 90, 72, 78, + 90, 158, 250, 20, 65, 2, 79, 154, 129, 5, 69, 222, 61, 87, 186, 2, 73, 3, + 85, 16, 230, 250, 20, 65, 154, 129, 5, 69, 222, 61, 87, 186, 2, 73, 2, + 79, 3, 85, 14, 154, 250, 20, 65, 154, 129, 5, 69, 150, 64, 73, 2, 79, 3, + 85, 20, 130, 1, 68, 74, 72, 30, 75, 42, 82, 0, 7, 83, 72, 79, 82, 84, 32, + 82, 176, 253, 3, 3, 67, 72, 73, 189, 134, 22, 3, 89, 73, 90, 6, 48, 4, + 69, 82, 69, 84, 129, 166, 25, 2, 73, 70, 5, 17, 2, 45, 72, 2, 173, 132, + 26, 2, 73, 68, 4, 204, 165, 25, 2, 69, 78, 219, 12, 85, 2, 217, 139, 4, + 3, 73, 75, 82, 10, 68, 2, 82, 79, 205, 174, 25, 9, 76, 69, 82, 32, 67, + 79, 78, 83, 84, 8, 92, 5, 80, 69, 65, 78, 32, 172, 153, 23, 8, 45, 67, + 85, 82, 82, 69, 78, 67, 171, 151, 2, 32, 4, 186, 248, 3, 67, 19, 80, 42, + 82, 67, 102, 84, 201, 248, 25, 12, 80, 82, 69, 83, 83, 73, 79, 78, 76, + 69, 83, 83, 6, 60, 9, 76, 65, 77, 65, 84, 73, 79, 78, 32, 203, 159, 25, + 69, 4, 202, 235, 23, 81, 151, 137, 2, 77, 34, 98, 82, 217, 223, 20, 18, + 69, 78, 68, 69, 68, 32, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 67, + 14, 140, 1, 12, 69, 77, 69, 76, 89, 32, 72, 69, 65, 86, 89, 32, 245, 226, + 24, 16, 65, 84, 69, 82, 82, 69, 83, 84, 82, 73, 65, 76, 32, 65, 76, 73, + 12, 50, 83, 214, 160, 24, 70, 234, 2, 87, 207, 10, 71, 4, 230, 161, 24, + 65, 43, 73, 7, 194, 227, 18, 71, 215, 207, 7, 83, 130, 4, 142, 1, 65, + 206, 18, 69, 194, 1, 73, 186, 7, 76, 214, 4, 79, 238, 6, 82, 142, 5, 85, + 136, 232, 19, 2, 86, 83, 254, 150, 4, 83, 207, 134, 2, 70, 90, 122, 67, + 254, 14, 76, 176, 2, 2, 88, 32, 230, 129, 3, 77, 252, 213, 5, 2, 82, 83, + 168, 250, 1, 2, 84, 72, 255, 192, 9, 73, 68, 72, 2, 69, 32, 236, 235, 15, + 4, 83, 73, 77, 73, 249, 183, 4, 2, 84, 79, 64, 226, 1, 83, 160, 1, 4, 87, + 73, 84, 72, 168, 203, 12, 2, 80, 65, 176, 130, 2, 2, 77, 65, 132, 201, + 10, 13, 84, 72, 82, 79, 87, 73, 78, 71, 32, 65, 32, 75, 73, 201, 1, 14, + 72, 79, 76, 68, 73, 78, 71, 32, 66, 65, 67, 75, 32, 84, 4, 212, 182, 16, + 18, 65, 86, 79, 85, 82, 73, 78, 71, 32, 68, 69, 76, 73, 67, 73, 79, 85, + 83, 161, 243, 4, 13, 67, 82, 69, 65, 77, 73, 78, 71, 32, 73, 78, 32, 70, + 52, 38, 32, 221, 190, 21, 3, 79, 85, 84, 50, 144, 4, 2, 67, 79, 44, 5, + 72, 69, 65, 68, 45, 38, 77, 98, 79, 92, 7, 78, 79, 32, 71, 79, 79, 68, + 238, 1, 80, 164, 1, 16, 83, 84, 85, 67, 75, 45, 79, 85, 84, 32, 84, 79, + 78, 71, 85, 69, 110, 84, 168, 140, 18, 22, 70, 73, 78, 71, 69, 82, 32, + 67, 79, 86, 69, 82, 73, 78, 71, 32, 67, 76, 79, 83, 69, 68, 172, 67, 3, + 82, 79, 76, 180, 217, 1, 13, 76, 79, 79, 75, 32, 79, 70, 32, 84, 82, 73, + 85, 77, 184, 139, 1, 8, 68, 73, 65, 71, 79, 78, 65, 76, 1, 20, 85, 78, + 69, 86, 69, 78, 32, 69, 89, 69, 83, 32, 65, 78, 68, 32, 87, 65, 86, 89, + 4, 252, 4, 3, 87, 66, 79, 163, 208, 18, 76, 2, 225, 205, 21, 4, 66, 65, + 78, 68, 4, 60, 6, 69, 68, 73, 67, 65, 76, 217, 216, 24, 3, 79, 78, 79, 2, + 165, 229, 24, 3, 32, 77, 65, 12, 90, 75, 36, 4, 80, 69, 78, 32, 165, 218, + 19, 10, 78, 69, 32, 69, 89, 69, 66, 82, 79, 87, 2, 217, 188, 21, 4, 32, + 71, 69, 83, 8, 116, 5, 77, 79, 85, 84, 72, 161, 183, 21, 18, 69, 89, 69, + 83, 32, 65, 78, 68, 32, 72, 65, 78, 68, 32, 79, 86, 69, 82, 7, 11, 32, 4, + 228, 206, 9, 3, 86, 79, 77, 241, 130, 9, 5, 65, 78, 68, 32, 67, 6, 132, + 1, 18, 65, 82, 84, 89, 32, 72, 79, 82, 78, 32, 65, 78, 68, 32, 80, 65, + 82, 84, 100, 2, 69, 69, 133, 208, 18, 4, 76, 69, 65, 68, 2, 213, 230, 21, + 2, 89, 32, 7, 29, 5, 32, 65, 78, 68, 32, 4, 36, 3, 87, 73, 78, 159, 208, + 18, 84, 2, 153, 170, 1, 4, 75, 73, 78, 71, 4, 50, 69, 149, 234, 21, 6, + 72, 69, 82, 77, 79, 77, 2, 197, 144, 26, 8, 65, 82, 83, 32, 79, 70, 32, + 74, 10, 34, 76, 237, 192, 21, 2, 65, 70, 8, 84, 13, 73, 78, 71, 32, 68, + 73, 65, 71, 79, 78, 65, 76, 32, 197, 236, 22, 2, 69, 78, 6, 128, 1, 9, + 67, 82, 79, 83, 83, 73, 78, 71, 32, 181, 227, 18, 16, 73, 78, 32, 87, 72, + 73, 84, 69, 32, 67, 73, 82, 67, 76, 69, 32, 4, 224, 197, 15, 3, 82, 73, + 83, 135, 165, 3, 78, 4, 166, 191, 14, 73, 175, 251, 3, 77, 14, 50, 65, + 54, 77, 44, 2, 82, 82, 147, 149, 18, 78, 4, 214, 196, 17, 84, 245, 156, + 8, 4, 82, 70, 85, 76, 4, 144, 188, 8, 2, 73, 78, 239, 157, 7, 65, 4, 168, + 199, 7, 2, 73, 83, 215, 214, 18, 89, 54, 200, 1, 5, 71, 85, 82, 69, 32, + 38, 76, 186, 1, 82, 182, 2, 83, 208, 12, 4, 86, 69, 32, 68, 172, 233, 4, + 10, 69, 76, 68, 32, 72, 79, 67, 75, 69, 89, 233, 157, 19, 9, 78, 73, 84, + 69, 32, 80, 65, 82, 84, 4, 222, 182, 24, 68, 139, 167, 1, 83, 10, 32, 2, + 69, 32, 65, 2, 77, 32, 6, 174, 133, 15, 70, 172, 59, 4, 67, 65, 66, 73, + 247, 193, 7, 83, 4, 52, 4, 80, 82, 79, 74, 149, 198, 19, 3, 70, 82, 65, + 2, 221, 225, 25, 2, 69, 67, 22, 34, 69, 189, 1, 3, 83, 84, 32, 13, 56, 2, + 32, 69, 68, 4, 87, 79, 82, 75, 207, 244, 14, 67, 4, 214, 254, 12, 78, + 237, 192, 4, 8, 88, 84, 73, 78, 71, 85, 73, 83, 4, 220, 209, 22, 6, 32, + 83, 80, 65, 82, 75, 171, 199, 3, 83, 10, 222, 137, 5, 81, 168, 146, 10, + 8, 83, 84, 82, 79, 78, 71, 32, 73, 219, 197, 6, 80, 10, 38, 72, 177, 224, + 22, 3, 84, 69, 68, 9, 236, 234, 3, 13, 73, 78, 71, 32, 80, 79, 76, 69, + 32, 65, 78, 68, 32, 182, 171, 5, 69, 209, 250, 15, 19, 32, 67, 65, 75, + 69, 32, 87, 73, 84, 72, 32, 83, 87, 73, 82, 76, 32, 68, 69, 36, 50, 65, + 134, 1, 69, 98, 79, 194, 1, 85, 39, 89, 10, 78, 84, 220, 148, 7, 6, 71, + 32, 73, 78, 32, 72, 229, 246, 16, 3, 77, 73, 78, 6, 214, 163, 8, 32, 202, + 170, 11, 66, 183, 176, 5, 78, 4, 132, 245, 22, 8, 88, 69, 68, 32, 66, 73, + 67, 69, 241, 130, 1, 7, 85, 82, 45, 68, 69, 45, 76, 10, 46, 82, 28, 3, + 87, 69, 82, 231, 208, 24, 80, 2, 173, 140, 25, 2, 65, 76, 7, 17, 2, 32, + 80, 4, 58, 85, 141, 187, 23, 8, 76, 65, 89, 73, 78, 71, 32, 67, 2, 193, + 169, 25, 4, 78, 67, 84, 85, 4, 214, 139, 3, 83, 155, 240, 22, 84, 9, 25, + 4, 73, 78, 71, 32, 6, 242, 213, 9, 68, 148, 179, 8, 2, 83, 65, 139, 181, + 1, 69, 54, 102, 71, 20, 2, 76, 68, 68, 2, 79, 84, 22, 82, 238, 1, 85, + 172, 173, 22, 2, 78, 68, 203, 163, 3, 88, 5, 151, 255, 25, 71, 4, 196, + 148, 9, 8, 73, 78, 71, 32, 72, 65, 78, 68, 183, 195, 16, 69, 5, 147, 224, + 13, 80, 16, 102, 75, 218, 252, 19, 77, 250, 141, 4, 32, 222, 112, 67, + 177, 120, 9, 84, 85, 78, 69, 32, 67, 79, 79, 75, 8, 80, 10, 32, 65, 78, + 68, 32, 75, 78, 73, 70, 69, 218, 225, 14, 69, 247, 219, 10, 73, 5, 133, + 146, 15, 7, 32, 87, 73, 84, 72, 32, 80, 22, 26, 82, 159, 200, 22, 78, 20, + 38, 32, 218, 2, 84, 255, 154, 18, 45, 16, 110, 67, 174, 1, 68, 234, 154, + 2, 66, 204, 240, 9, 7, 76, 69, 65, 70, 32, 67, 76, 242, 105, 84, 171, + 130, 11, 80, 4, 244, 246, 12, 3, 76, 85, 66, 229, 85, 32, 79, 82, 78, 69, + 82, 32, 65, 82, 82, 79, 87, 83, 32, 67, 73, 82, 67, 76, 73, 78, 71, 32, + 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 4, 21, 3, 79, 84, 32, 4, 186, + 222, 22, 80, 183, 235, 2, 77, 2, 255, 31, 72, 28, 78, 65, 226, 1, 69, 98, + 79, 165, 174, 16, 8, 73, 69, 68, 32, 83, 72, 82, 73, 10, 72, 6, 67, 84, + 73, 79, 78, 32, 69, 8, 77, 69, 32, 87, 73, 84, 72, 32, 4, 214, 168, 19, + 83, 177, 6, 9, 78, 85, 77, 69, 82, 65, 84, 79, 82, 6, 50, 80, 166, 155, + 2, 65, 213, 196, 20, 2, 84, 73, 2, 213, 158, 21, 2, 73, 67, 6, 48, 6, 78, + 67, 72, 32, 70, 82, 171, 185, 18, 69, 4, 150, 244, 24, 73, 249, 12, 3, + 65, 78, 67, 10, 52, 3, 78, 84, 45, 116, 2, 87, 78, 143, 201, 25, 71, 4, + 70, 84, 145, 128, 2, 11, 70, 65, 67, 73, 78, 71, 32, 66, 65, 66, 89, 2, + 253, 132, 12, 6, 73, 76, 84, 69, 68, 32, 5, 181, 176, 18, 15, 73, 78, 71, + 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 79, 224, 1, 80, 2, 76, 76, + 250, 5, 78, 216, 165, 16, 5, 69, 76, 32, 80, 85, 215, 194, 9, 83, 216, 1, + 42, 32, 73, 6, 87, 73, 68, 84, 72, 32, 10, 158, 210, 11, 77, 160, 159, 3, + 2, 79, 85, 194, 170, 8, 66, 131, 30, 83, 206, 1, 238, 1, 67, 42, 76, 78, + 78, 30, 80, 66, 82, 134, 1, 83, 38, 89, 130, 230, 9, 77, 130, 171, 10, + 65, 158, 2, 68, 58, 69, 98, 71, 118, 72, 190, 4, 81, 214, 139, 2, 87, + 182, 24, 84, 220, 113, 6, 66, 82, 79, 75, 69, 78, 202, 4, 70, 159, 177, + 1, 86, 10, 238, 148, 20, 73, 62, 79, 227, 75, 69, 116, 42, 69, 162, 152, + 20, 65, 171, 132, 4, 79, 10, 162, 1, 70, 139, 154, 20, 83, 4, 182, 234, + 20, 79, 35, 85, 6, 42, 79, 138, 155, 20, 69, 247, 203, 2, 76, 2, 239, + 154, 24, 85, 10, 36, 3, 73, 71, 72, 231, 237, 23, 69, 8, 17, 2, 84, 32, + 8, 182, 163, 22, 67, 240, 1, 5, 87, 72, 73, 84, 69, 22, 80, 155, 2, 83, + 4, 218, 201, 22, 69, 203, 165, 1, 79, 2, 247, 136, 24, 69, 4, 236, 146, + 11, 8, 67, 84, 73, 79, 78, 32, 65, 80, 253, 212, 8, 5, 69, 82, 65, 76, + 32, 228, 18, 110, 65, 62, 69, 198, 17, 73, 162, 1, 76, 134, 15, 79, 194, + 6, 82, 158, 93, 85, 226, 175, 21, 72, 215, 199, 3, 83, 4, 196, 214, 24, + 2, 82, 76, 189, 139, 1, 4, 77, 69, 32, 68, 242, 2, 112, 2, 65, 82, 110, + 77, 50, 79, 224, 220, 22, 9, 82, 77, 65, 78, 32, 80, 69, 78, 78, 130, + 153, 2, 84, 215, 105, 78, 7, 29, 5, 32, 87, 73, 84, 72, 4, 220, 230, 13, + 5, 79, 85, 84, 32, 72, 177, 236, 8, 5, 32, 72, 65, 78, 68, 4, 26, 32, + 131, 171, 21, 73, 2, 199, 172, 22, 83, 226, 2, 64, 6, 77, 69, 84, 82, 73, + 67, 73, 6, 82, 71, 73, 65, 78, 32, 6, 236, 185, 19, 4, 65, 76, 76, 89, + 137, 214, 1, 5, 32, 80, 82, 79, 80, 220, 2, 228, 1, 6, 67, 65, 80, 73, + 84, 65, 0, 4, 83, 77, 65, 76, 172, 3, 7, 76, 69, 84, 84, 69, 82, 32, 180, + 2, 24, 77, 84, 65, 86, 82, 85, 76, 73, 32, 67, 65, 80, 73, 84, 65, 76, + 32, 76, 69, 84, 84, 69, 82, 32, 165, 6, 2, 80, 65, 80, 45, 9, 76, 32, 76, + 69, 84, 84, 69, 82, 32, 80, 142, 2, 65, 34, 72, 166, 5, 67, 118, 71, 130, + 1, 74, 34, 75, 82, 80, 34, 83, 94, 90, 176, 155, 5, 2, 84, 65, 234, 250, + 7, 76, 214, 168, 2, 82, 230, 229, 8, 66, 2, 77, 2, 88, 142, 37, 78, 2, + 81, 238, 34, 86, 222, 47, 68, 14, 69, 2, 73, 2, 79, 2, 85, 2, 89, 131, + 57, 87, 4, 210, 165, 25, 69, 215, 79, 78, 10, 46, 65, 134, 222, 25, 73, + 2, 79, 215, 22, 69, 4, 214, 244, 25, 69, 3, 82, 94, 254, 1, 85, 178, 2, + 65, 42, 67, 74, 69, 46, 71, 34, 72, 98, 74, 34, 75, 34, 76, 50, 80, 34, + 83, 34, 84, 62, 90, 238, 190, 15, 82, 230, 229, 8, 66, 2, 77, 2, 88, 142, + 37, 78, 2, 81, 238, 34, 86, 222, 47, 68, 14, 73, 2, 79, 2, 89, 130, 57, + 87, 255, 2, 70, 4, 252, 174, 21, 4, 45, 66, 82, 74, 191, 195, 4, 78, 92, + 250, 1, 65, 42, 67, 74, 69, 46, 71, 34, 72, 98, 74, 34, 75, 34, 76, 50, + 80, 34, 83, 34, 84, 62, 90, 238, 190, 15, 82, 230, 229, 8, 66, 2, 77, 2, + 88, 142, 37, 78, 2, 81, 238, 34, 86, 222, 47, 68, 14, 73, 2, 79, 2, 85, + 2, 89, 130, 57, 87, 255, 2, 70, 6, 182, 160, 25, 69, 2, 73, 215, 79, 78, + 8, 38, 72, 162, 230, 24, 73, 203, 57, 65, 4, 230, 159, 25, 73, 135, 23, + 65, 4, 180, 227, 8, 2, 76, 73, 231, 139, 17, 78, 4, 186, 167, 24, 72, + 227, 119, 65, 12, 46, 65, 206, 215, 25, 73, 2, 79, 215, 22, 69, 6, 26, + 82, 135, 238, 25, 69, 5, 155, 231, 24, 68, 4, 186, 166, 24, 72, 155, 62, + 73, 4, 166, 203, 24, 72, 215, 82, 65, 4, 11, 65, 4, 134, 154, 15, 66, + 159, 211, 10, 83, 4, 214, 202, 24, 72, 219, 105, 65, 4, 162, 237, 24, 72, + 235, 47, 65, 6, 220, 177, 3, 6, 85, 82, 78, 69, 68, 32, 143, 234, 1, 65, + 4, 218, 201, 24, 72, 215, 82, 69, 2, 165, 219, 19, 7, 82, 65, 71, 82, 65, + 80, 72, 10, 48, 2, 77, 69, 20, 4, 78, 71, 69, 82, 31, 82, 2, 239, 215, + 24, 76, 2, 141, 252, 17, 2, 32, 82, 6, 38, 76, 237, 189, 13, 3, 65, 70, + 70, 5, 151, 215, 24, 83, 202, 1, 66, 65, 214, 13, 79, 217, 154, 25, 7, + 69, 73, 67, 72, 32, 83, 84, 194, 1, 84, 8, 71, 79, 76, 73, 84, 73, 67, + 32, 229, 12, 8, 83, 83, 32, 79, 70, 32, 77, 73, 192, 1, 56, 6, 67, 65, + 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 96, 45, 9, 76, 32, 76, 69, 84, 84, + 69, 82, 32, 96, 206, 1, 65, 22, 66, 42, 67, 94, 68, 94, 70, 38, 71, 46, + 73, 138, 2, 76, 58, 77, 66, 78, 34, 79, 30, 80, 58, 82, 30, 83, 186, 1, + 84, 110, 86, 22, 89, 90, 90, 182, 199, 18, 72, 142, 243, 1, 85, 131, 131, + 5, 75, 2, 199, 193, 25, 90, 4, 214, 3, 73, 253, 208, 25, 2, 85, 75, 4, + 48, 8, 65, 85, 68, 65, 84, 69, 32, 67, 15, 72, 2, 11, 72, 2, 197, 252, 8, + 2, 82, 73, 6, 42, 74, 30, 79, 129, 194, 25, 2, 90, 69, 2, 253, 251, 8, 2, + 69, 82, 2, 187, 248, 23, 66, 4, 238, 191, 20, 82, 131, 128, 5, 73, 2, 21, + 3, 76, 65, 71, 2, 255, 148, 21, 79, 13, 38, 78, 54, 79, 141, 1, 2, 90, + 72, 2, 181, 182, 25, 8, 73, 84, 73, 65, 76, 32, 73, 90, 4, 33, 6, 84, 65, + 84, 69, 68, 32, 4, 26, 66, 25, 2, 83, 77, 2, 11, 73, 2, 35, 71, 2, 21, 3, + 65, 76, 76, 2, 177, 223, 23, 2, 32, 89, 4, 178, 223, 25, 73, 211, 2, 69, + 4, 52, 9, 65, 84, 73, 78, 65, 84, 69, 32, 77, 35, 74, 2, 193, 223, 10, 3, + 89, 83, 76, 2, 177, 231, 8, 3, 85, 68, 73, 2, 11, 65, 2, 239, 188, 20, + 83, 4, 226, 187, 25, 78, 3, 84, 4, 26, 79, 151, 224, 25, 69, 2, 225, 245, + 21, 2, 75, 79, 2, 225, 161, 21, 2, 73, 84, 14, 106, 72, 58, 76, 168, 195, + 13, 6, 80, 73, 68, 69, 82, 89, 209, 237, 9, 8, 77, 65, 76, 76, 32, 89, + 85, 83, 6, 32, 2, 84, 65, 207, 222, 25, 65, 5, 223, 183, 24, 80, 2, 251, + 218, 8, 79, 6, 78, 86, 208, 201, 21, 9, 82, 79, 75, 85, 84, 65, 83, 84, + 73, 175, 128, 4, 83, 2, 157, 227, 18, 2, 82, 73, 2, 195, 208, 23, 69, 12, + 50, 69, 246, 184, 18, 65, 254, 163, 7, 79, 3, 85, 6, 174, 184, 20, 83, + 151, 228, 4, 82, 4, 192, 235, 8, 3, 69, 77, 76, 221, 172, 15, 4, 72, 73, + 86, 69, 2, 243, 216, 25, 76, 6, 212, 199, 11, 13, 66, 69, 32, 87, 73, 84, + 72, 32, 77, 69, 82, 73, 68, 146, 177, 4, 87, 179, 207, 8, 86, 68, 162, 1, + 65, 44, 12, 84, 72, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 178, 174, 17, + 71, 182, 55, 82, 252, 182, 5, 3, 78, 71, 71, 238, 179, 1, 79, 149, 75, 2, + 76, 70, 4, 132, 255, 14, 2, 76, 32, 231, 218, 10, 84, 54, 202, 2, 65, 50, + 72, 46, 73, 46, 78, 46, 80, 2, 81, 40, 2, 82, 65, 22, 84, 240, 227, 8, 2, + 87, 73, 142, 233, 11, 85, 160, 70, 3, 70, 65, 73, 204, 7, 4, 66, 65, 73, + 82, 248, 21, 2, 79, 84, 202, 30, 68, 218, 99, 77, 144, 117, 3, 83, 65, + 85, 138, 16, 69, 128, 26, 3, 76, 65, 71, 142, 197, 1, 74, 184, 16, 2, 71, + 73, 141, 12, 2, 75, 85, 4, 132, 212, 23, 3, 73, 72, 86, 171, 128, 2, 72, + 4, 154, 179, 13, 87, 141, 154, 11, 2, 65, 71, 4, 142, 229, 8, 85, 201, + 155, 14, 2, 71, 71, 6, 194, 149, 15, 73, 137, 195, 8, 2, 65, 85, 2, 137, + 145, 25, 5, 65, 73, 82, 84, 72, 2, 147, 176, 25, 73, 4, 136, 231, 20, 2, + 72, 73, 185, 152, 2, 2, 69, 73, 234, 9, 46, 65, 190, 6, 69, 206, 82, 73, + 139, 3, 79, 152, 1, 96, 7, 68, 85, 65, 84, 73, 79, 78, 32, 5, 78, 84, 72, + 65, 32, 226, 232, 19, 86, 215, 214, 4, 80, 2, 11, 32, 2, 211, 194, 24, + 67, 146, 1, 156, 1, 7, 76, 69, 84, 84, 69, 82, 32, 212, 2, 5, 83, 73, 71, + 78, 32, 104, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 234, 191, 7, + 65, 247, 253, 17, 79, 100, 214, 1, 86, 202, 231, 21, 65, 38, 68, 46, 84, + 230, 24, 85, 210, 200, 1, 73, 42, 76, 246, 189, 1, 78, 46, 83, 82, 66, 2, + 67, 2, 71, 2, 74, 2, 75, 2, 80, 194, 40, 79, 162, 8, 69, 158, 20, 72, 2, + 77, 2, 82, 3, 89, 14, 60, 5, 69, 68, 73, 67, 32, 246, 235, 21, 79, 231, + 227, 3, 65, 4, 212, 160, 23, 6, 68, 79, 85, 66, 76, 69, 151, 234, 1, 65, + 16, 66, 67, 162, 191, 21, 80, 202, 40, 65, 170, 1, 78, 203, 162, 3, 86, + 4, 238, 200, 7, 79, 207, 159, 14, 65, 26, 218, 233, 21, 65, 106, 86, 214, + 20, 85, 210, 200, 1, 73, 218, 231, 1, 79, 163, 8, 69, 192, 8, 76, 10, 65, + 84, 69, 82, 45, 84, 72, 65, 78, 32, 206, 7, 69, 159, 190, 24, 89, 56, + 134, 1, 65, 150, 3, 66, 62, 79, 216, 2, 11, 69, 81, 85, 65, 76, 32, 84, + 79, 32, 79, 82, 218, 173, 6, 67, 138, 4, 87, 175, 141, 18, 83, 16, 44, 5, + 66, 79, 86, 69, 32, 183, 178, 6, 78, 12, 150, 1, 83, 180, 1, 19, 68, 79, + 85, 66, 76, 69, 45, 76, 73, 78, 69, 32, 69, 81, 85, 65, 76, 32, 65, 220, + 172, 6, 4, 76, 69, 83, 83, 207, 252, 17, 82, 6, 148, 1, 7, 73, 77, 73, + 76, 65, 82, 32, 221, 175, 6, 23, 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, + 65, 76, 32, 65, 66, 79, 86, 69, 32, 76, 69, 83, 83, 4, 26, 65, 179, 175, + 6, 79, 2, 65, 3, 66, 79, 86, 6, 40, 4, 69, 83, 73, 68, 155, 176, 6, 85, + 2, 231, 2, 69, 20, 40, 2, 82, 32, 245, 1, 3, 86, 69, 82, 16, 120, 16, 83, + 76, 65, 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, 32, 84, 79, 226, 177, 6, + 65, 150, 213, 12, 69, 191, 177, 4, 76, 9, 49, 10, 32, 87, 73, 84, 72, 32, + 68, 79, 84, 32, 6, 44, 5, 65, 66, 79, 86, 69, 171, 220, 17, 73, 5, 251, + 147, 25, 32, 4, 52, 7, 76, 65, 80, 80, 73, 78, 71, 235, 158, 19, 32, 2, + 253, 182, 23, 2, 32, 76, 134, 8, 36, 2, 75, 32, 185, 73, 2, 78, 32, 254, + 7, 130, 3, 65, 216, 15, 8, 67, 65, 80, 73, 84, 65, 76, 32, 182, 11, 68, + 134, 1, 70, 68, 2, 73, 78, 222, 3, 75, 138, 1, 76, 174, 3, 78, 66, 77, + 84, 3, 88, 69, 83, 22, 79, 202, 1, 80, 90, 82, 182, 1, 83, 130, 22, 84, + 200, 2, 13, 85, 80, 83, 73, 76, 79, 78, 32, 87, 73, 84, 72, 32, 150, 1, + 86, 142, 2, 89, 254, 186, 7, 66, 164, 174, 3, 4, 71, 82, 65, 77, 204, 23, + 2, 90, 69, 167, 177, 11, 81, 112, 92, 10, 67, 82, 79, 80, 72, 79, 78, 73, + 67, 32, 172, 14, 6, 78, 79, 32, 84, 69, 76, 23, 82, 106, 188, 2, 6, 65, + 84, 84, 73, 67, 32, 222, 5, 67, 92, 3, 78, 65, 88, 32, 12, 68, 69, 76, + 80, 72, 73, 67, 32, 70, 73, 86, 69, 0, 14, 83, 84, 82, 65, 84, 73, 65, + 78, 32, 70, 73, 70, 84, 89, 40, 11, 69, 80, 73, 68, 65, 85, 82, 69, 65, + 78, 32, 112, 3, 72, 69, 82, 164, 1, 9, 77, 69, 83, 83, 69, 78, 73, 65, + 78, 35, 84, 48, 72, 2, 70, 73, 180, 2, 4, 79, 78, 69, 32, 205, 1, 4, 84, + 69, 78, 32, 26, 36, 3, 70, 84, 89, 105, 2, 86, 69, 11, 11, 32, 8, 22, 84, + 171, 4, 83, 6, 48, 7, 72, 79, 85, 83, 65, 78, 68, 215, 3, 65, 5, 231, 3, + 32, 17, 11, 32, 14, 56, 7, 72, 85, 78, 68, 82, 69, 68, 18, 84, 143, 3, + 83, 7, 131, 2, 32, 6, 48, 7, 72, 79, 85, 83, 65, 78, 68, 187, 2, 65, 5, + 213, 1, 2, 32, 84, 14, 98, 72, 48, 7, 84, 72, 79, 85, 83, 65, 78, 230, + 186, 23, 81, 229, 222, 1, 5, 68, 82, 65, 67, 72, 6, 44, 5, 85, 78, 68, + 82, 69, 203, 186, 23, 65, 4, 17, 2, 68, 32, 4, 22, 84, 131, 1, 83, 2, 95, + 65, 8, 30, 84, 86, 83, 175, 1, 77, 4, 50, 65, 21, 8, 72, 79, 85, 83, 65, + 78, 68, 32, 2, 171, 241, 15, 76, 2, 11, 83, 2, 201, 187, 23, 2, 84, 65, + 4, 88, 5, 65, 82, 89, 83, 84, 145, 1, 12, 89, 82, 69, 78, 65, 73, 67, 32, + 84, 87, 79, 32, 2, 101, 5, 73, 65, 78, 32, 70, 2, 17, 2, 32, 77, 2, 147, + 226, 12, 78, 6, 30, 70, 29, 3, 84, 87, 79, 2, 221, 248, 14, 2, 73, 86, 5, + 11, 32, 2, 161, 234, 9, 5, 68, 82, 65, 67, 72, 8, 112, 8, 77, 73, 79, 78, + 73, 65, 78, 32, 253, 145, 24, 14, 65, 69, 85, 77, 32, 79, 78, 69, 32, 80, + 76, 69, 84, 72, 6, 150, 140, 12, 70, 254, 216, 11, 84, 227, 55, 79, 2, + 11, 32, 2, 215, 228, 23, 84, 32, 92, 8, 72, 69, 83, 80, 73, 65, 78, 32, + 129, 1, 10, 82, 79, 69, 90, 69, 78, 73, 65, 78, 32, 20, 40, 2, 70, 73, + 38, 84, 239, 217, 17, 79, 6, 222, 139, 20, 86, 219, 190, 3, 70, 8, 246, + 244, 14, 72, 190, 239, 9, 69, 227, 48, 87, 12, 36, 2, 70, 73, 209, 24, 2, + 84, 69, 8, 142, 243, 17, 86, 145, 193, 6, 3, 70, 84, 89, 2, 231, 221, 9, + 69, 4, 252, 246, 21, 2, 79, 85, 149, 164, 1, 3, 84, 65, 66, 154, 2, 66, + 76, 174, 45, 82, 66, 68, 168, 188, 7, 2, 75, 65, 135, 6, 84, 144, 2, 44, + 6, 69, 84, 84, 69, 82, 32, 239, 45, 85, 142, 2, 198, 2, 65, 190, 1, 69, + 28, 4, 73, 79, 84, 65, 128, 1, 2, 79, 77, 156, 3, 3, 82, 72, 79, 46, 83, + 48, 7, 85, 80, 83, 73, 76, 79, 78, 146, 33, 80, 170, 2, 84, 138, 157, 5, + 68, 156, 164, 2, 2, 75, 65, 146, 192, 1, 71, 194, 223, 10, 67, 166, 255, + 1, 66, 2, 72, 2, 90, 166, 1, 76, 254, 210, 2, 89, 198, 43, 77, 2, 78, + 147, 17, 88, 48, 68, 4, 76, 80, 72, 65, 213, 28, 8, 82, 67, 72, 65, 73, + 67, 32, 83, 47, 33, 6, 32, 87, 73, 84, 72, 32, 44, 242, 2, 68, 30, 80, + 226, 29, 86, 226, 5, 79, 142, 226, 3, 84, 147, 140, 5, 77, 62, 186, 1, + 84, 131, 27, 80, 31, 33, 6, 32, 87, 73, 84, 72, 32, 28, 186, 5, 68, 136, + 25, 2, 80, 83, 158, 1, 86, 226, 5, 79, 142, 226, 3, 84, 147, 140, 5, 77, + 62, 28, 2, 69, 71, 235, 34, 73, 42, 11, 65, 43, 33, 6, 32, 87, 73, 84, + 72, 32, 40, 54, 68, 30, 80, 194, 35, 79, 22, 86, 251, 225, 3, 84, 16, 65, + 4, 65, 83, 73, 65, 18, 36, 4, 83, 73, 76, 73, 211, 16, 82, 17, 29, 5, 32, + 65, 78, 68, 32, 14, 44, 2, 79, 88, 0, 3, 86, 65, 82, 23, 80, 4, 81, 2, + 73, 65, 6, 60, 10, 69, 82, 73, 83, 80, 79, 77, 69, 78, 73, 175, 15, 82, + 5, 169, 15, 7, 32, 65, 78, 68, 32, 80, 82, 5, 161, 35, 7, 32, 87, 73, 84, + 72, 32, 68, 6, 170, 230, 7, 73, 206, 242, 16, 65, 227, 48, 72, 23, 33, 6, + 32, 87, 73, 84, 72, 32, 20, 66, 68, 166, 26, 86, 226, 5, 79, 142, 226, 3, + 84, 147, 140, 5, 77, 10, 130, 24, 65, 133, 203, 1, 5, 73, 65, 76, 89, 84, + 18, 76, 9, 73, 65, 76, 89, 84, 73, 75, 65, 32, 32, 3, 82, 65, 67, 227, + 22, 65, 8, 174, 24, 65, 223, 232, 3, 84, 2, 235, 146, 11, 72, 4, 40, 3, + 73, 86, 69, 1, 3, 79, 85, 82, 2, 205, 37, 2, 32, 79, 76, 144, 1, 27, 83, + 84, 82, 85, 77, 69, 78, 84, 65, 76, 32, 78, 79, 84, 65, 84, 73, 79, 78, + 32, 83, 89, 77, 66, 79, 76, 45, 165, 202, 21, 2, 68, 73, 74, 70, 49, 70, + 50, 62, 51, 62, 52, 170, 37, 53, 250, 252, 24, 55, 3, 56, 17, 218, 163, + 25, 49, 2, 50, 2, 51, 2, 52, 2, 55, 2, 56, 3, 57, 15, 150, 163, 25, 51, + 2, 52, 2, 53, 2, 54, 2, 55, 3, 57, 12, 218, 162, 25, 48, 2, 50, 2, 54, 2, + 55, 2, 56, 3, 57, 17, 158, 162, 25, 48, 2, 50, 2, 51, 2, 53, 2, 55, 2, + 56, 3, 57, 8, 54, 65, 38, 79, 169, 32, 6, 89, 65, 84, 72, 79, 83, 4, 210, + 216, 7, 80, 195, 181, 16, 73, 2, 11, 82, 2, 11, 79, 2, 251, 131, 23, 78, + 32, 128, 1, 6, 69, 84, 84, 69, 82, 32, 168, 2, 6, 79, 87, 69, 82, 32, 78, + 32, 6, 85, 78, 65, 84, 69, 32, 157, 225, 21, 2, 73, 84, 24, 94, 83, 140, + 13, 9, 65, 82, 67, 72, 65, 73, 67, 32, 75, 2, 75, 182, 11, 68, 135, 182, + 24, 89, 16, 88, 13, 77, 65, 76, 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, + 210, 12, 65, 195, 205, 7, 84, 12, 74, 80, 154, 154, 9, 71, 174, 131, 9, + 79, 238, 195, 2, 82, 243, 152, 1, 76, 4, 238, 137, 25, 83, 219, 19, 73, + 2, 249, 223, 9, 3, 85, 77, 69, 4, 222, 25, 83, 163, 186, 7, 69, 4, 80, 4, + 69, 84, 82, 69, 253, 208, 22, 10, 85, 83, 73, 67, 65, 76, 32, 76, 69, 73, + 2, 139, 206, 2, 84, 12, 88, 3, 78, 69, 32, 142, 198, 9, 88, 200, 136, 5, + 3, 85, 78, 75, 161, 181, 5, 2, 66, 79, 6, 64, 8, 72, 65, 76, 70, 32, 83, + 73, 71, 21, 4, 81, 85, 65, 82, 4, 207, 155, 24, 78, 2, 159, 132, 20, 84, + 16, 62, 82, 206, 11, 83, 114, 69, 230, 197, 7, 72, 203, 180, 16, 73, 2, + 217, 29, 2, 79, 83, 6, 100, 3, 72, 79, 32, 241, 207, 7, 16, 69, 86, 69, + 82, 83, 69, 68, 32, 76, 85, 78, 65, 84, 69, 32, 69, 4, 140, 197, 13, 10, + 87, 73, 84, 72, 32, 83, 84, 82, 79, 75, 243, 192, 10, 83, 226, 2, 220, 1, + 5, 77, 65, 76, 76, 32, 192, 19, 22, 85, 66, 83, 67, 82, 73, 80, 84, 32, + 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 72, 10, 89, 77, 66, + 79, 76, 32, 84, 65, 85, 32, 237, 156, 23, 6, 73, 78, 85, 83, 79, 73, 212, + 2, 56, 7, 76, 69, 84, 84, 69, 82, 32, 202, 17, 82, 67, 68, 206, 2, 178, + 2, 65, 162, 2, 68, 38, 69, 52, 4, 73, 79, 84, 65, 0, 7, 85, 80, 83, 73, + 76, 79, 78, 254, 3, 75, 28, 2, 79, 77, 182, 5, 80, 112, 3, 82, 72, 79, + 94, 83, 94, 84, 192, 192, 7, 2, 70, 73, 246, 192, 1, 71, 194, 223, 10, + 67, 166, 255, 1, 66, 2, 72, 2, 90, 166, 1, 76, 194, 254, 2, 77, 2, 78, + 147, 17, 88, 58, 64, 4, 76, 80, 72, 65, 149, 1, 7, 82, 67, 72, 65, 73, + 67, 32, 55, 33, 6, 32, 87, 73, 84, 72, 32, 52, 82, 86, 226, 6, 68, 30, + 80, 114, 79, 142, 1, 89, 250, 227, 3, 84, 147, 140, 5, 77, 6, 154, 5, 82, + 155, 3, 65, 4, 18, 75, 23, 83, 2, 163, 206, 7, 79, 2, 11, 65, 2, 203, + 143, 13, 77, 4, 214, 184, 7, 73, 191, 180, 14, 69, 70, 22, 80, 215, 4, + 84, 20, 249, 7, 3, 83, 73, 76, 41, 33, 6, 32, 87, 73, 84, 72, 32, 38, 78, + 68, 166, 1, 80, 178, 1, 86, 226, 5, 79, 142, 226, 3, 84, 147, 140, 5, 77, + 18, 50, 65, 29, 8, 73, 65, 76, 89, 84, 73, 75, 65, 8, 153, 1, 3, 83, 73, + 65, 11, 29, 5, 32, 65, 78, 68, 32, 8, 170, 1, 80, 154, 6, 79, 22, 86, + 251, 225, 3, 84, 10, 18, 83, 115, 69, 8, 21, 3, 73, 76, 73, 9, 17, 2, 32, + 65, 6, 21, 3, 78, 68, 32, 6, 30, 80, 154, 6, 79, 23, 86, 2, 11, 69, 2, + 11, 82, 2, 181, 17, 4, 73, 83, 80, 79, 4, 22, 82, 147, 15, 65, 2, 177, + 235, 24, 2, 65, 67, 4, 154, 201, 7, 65, 3, 79, 70, 28, 2, 69, 71, 151, 3, + 73, 50, 11, 65, 51, 33, 6, 32, 87, 73, 84, 72, 32, 48, 58, 68, 30, 80, + 114, 79, 62, 86, 82, 89, 251, 227, 3, 84, 16, 61, 4, 65, 83, 73, 65, 20, + 32, 4, 83, 73, 76, 73, 91, 69, 17, 29, 5, 32, 65, 78, 68, 32, 14, 42, 79, + 12, 2, 80, 69, 50, 86, 83, 89, 4, 83, 88, 4, 89, 9, 82, 73, 83, 80, 79, + 77, 69, 78, 73, 4, 11, 65, 4, 11, 82, 4, 17, 2, 73, 65, 5, 33, 6, 32, 65, + 78, 68, 32, 89, 2, 243, 12, 80, 20, 17, 2, 67, 82, 20, 17, 2, 79, 78, 21, + 33, 6, 32, 87, 73, 84, 72, 32, 18, 88, 5, 68, 65, 83, 73, 65, 0, 5, 80, + 83, 73, 76, 73, 54, 79, 22, 86, 251, 225, 3, 84, 7, 29, 5, 32, 65, 78, + 68, 32, 4, 18, 79, 23, 86, 2, 151, 178, 9, 88, 2, 179, 9, 65, 8, 88, 11, + 65, 77, 80, 72, 89, 76, 73, 65, 78, 32, 68, 218, 242, 24, 72, 2, 83, 219, + 19, 73, 2, 215, 173, 7, 73, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 34, 68, + 201, 182, 20, 2, 80, 83, 2, 215, 159, 8, 65, 10, 54, 65, 134, 193, 7, 84, + 230, 1, 73, 175, 163, 17, 72, 4, 142, 131, 13, 77, 251, 129, 12, 78, 4, + 150, 224, 21, 72, 231, 255, 2, 65, 4, 41, 8, 69, 86, 69, 82, 83, 69, 68, + 32, 4, 18, 68, 43, 76, 2, 37, 7, 79, 84, 84, 69, 68, 32, 76, 2, 11, 85, + 2, 33, 6, 78, 65, 84, 69, 32, 83, 2, 245, 193, 7, 3, 73, 71, 77, 10, 214, + 255, 8, 71, 194, 223, 10, 67, 2, 80, 218, 103, 82, 207, 151, 1, 66, 2, + 167, 198, 20, 82, 16, 106, 72, 104, 7, 82, 89, 66, 76, 73, 79, 78, 44, 3, + 87, 79, 32, 150, 219, 3, 79, 141, 132, 16, 2, 65, 76, 6, 40, 4, 82, 69, + 69, 32, 219, 191, 7, 69, 4, 146, 1, 79, 185, 230, 21, 7, 81, 85, 65, 82, + 84, 69, 82, 2, 21, 3, 32, 66, 65, 2, 231, 232, 22, 83, 4, 42, 79, 253, + 234, 11, 4, 84, 72, 73, 82, 2, 229, 148, 19, 2, 66, 79, 6, 80, 5, 65, 67, + 85, 84, 69, 0, 9, 68, 73, 65, 69, 82, 69, 83, 73, 83, 39, 72, 2, 33, 6, + 32, 65, 78, 68, 32, 72, 2, 145, 157, 7, 2, 79, 79, 60, 102, 65, 21, 21, + 79, 67, 65, 76, 32, 78, 79, 84, 65, 84, 73, 79, 78, 32, 83, 89, 77, 66, + 79, 76, 45, 2, 207, 168, 9, 82, 58, 90, 50, 2, 53, 166, 195, 22, 49, 214, + 185, 2, 51, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 13, 246, 252, 24, 48, 2, + 49, 2, 50, 2, 51, 3, 52, 4, 26, 80, 139, 230, 19, 69, 2, 11, 79, 2, 33, + 6, 71, 69, 71, 82, 65, 77, 2, 253, 171, 20, 2, 77, 69, 8, 238, 189, 13, + 65, 142, 237, 9, 66, 210, 73, 72, 241, 64, 3, 83, 65, 76, 12, 60, 6, 78, + 78, 73, 78, 71, 32, 205, 242, 23, 3, 77, 65, 67, 10, 100, 4, 70, 65, 67, + 69, 217, 166, 17, 15, 67, 65, 84, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, + 32, 83, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 108, 23, 79, 78, 69, 32, 76, + 65, 82, 71, 69, 32, 65, 78, 68, 32, 79, 78, 69, 32, 83, 77, 65, 76, 76, + 35, 83, 2, 11, 32, 2, 159, 247, 7, 69, 4, 174, 165, 17, 77, 145, 1, 3, + 84, 65, 82, 6, 28, 3, 85, 80, 32, 39, 87, 4, 250, 222, 21, 83, 211, 215, + 2, 77, 2, 251, 211, 17, 73, 232, 3, 164, 1, 2, 65, 82, 70, 73, 52, 7, 74, + 65, 82, 65, 84, 73, 32, 212, 6, 12, 78, 74, 65, 76, 65, 32, 71, 79, 78, + 68, 73, 32, 137, 3, 7, 82, 77, 85, 75, 72, 73, 32, 4, 34, 65, 157, 172, + 20, 2, 68, 83, 2, 11, 78, 2, 239, 238, 23, 73, 4, 154, 211, 23, 84, 201, + 161, 1, 4, 68, 69, 32, 68, 182, 1, 168, 1, 7, 76, 69, 84, 84, 69, 82, 32, + 220, 1, 5, 83, 73, 71, 78, 32, 160, 2, 6, 86, 79, 87, 69, 76, 32, 226, + 175, 19, 65, 210, 24, 82, 154, 185, 3, 68, 199, 221, 1, 79, 98, 142, 139, + 21, 65, 38, 68, 46, 84, 46, 86, 186, 24, 85, 210, 200, 1, 73, 42, 76, + 234, 14, 90, 142, 175, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, + 2, 80, 254, 68, 72, 2, 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, 24, 98, 67, + 28, 3, 77, 65, 68, 22, 84, 250, 194, 3, 83, 138, 199, 17, 65, 170, 1, 78, + 203, 162, 3, 86, 4, 118, 73, 143, 138, 21, 65, 2, 187, 184, 17, 68, 4, + 68, 5, 87, 79, 45, 67, 73, 29, 8, 72, 82, 69, 69, 45, 68, 79, 84, 2, 25, + 4, 82, 67, 76, 69, 2, 129, 249, 19, 5, 32, 78, 85, 75, 84, 34, 36, 5, 83, + 73, 71, 78, 32, 91, 67, 30, 86, 67, 142, 138, 21, 65, 106, 86, 214, 20, + 85, 210, 200, 1, 73, 206, 134, 2, 69, 3, 79, 4, 201, 138, 21, 5, 65, 78, + 68, 82, 65, 126, 108, 7, 76, 69, 84, 84, 69, 82, 32, 212, 1, 5, 83, 73, + 71, 78, 32, 38, 86, 186, 253, 22, 68, 199, 221, 1, 79, 80, 250, 132, 21, + 65, 38, 68, 46, 84, 230, 24, 85, 22, 78, 190, 200, 1, 73, 42, 76, 242, + 190, 1, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 194, 40, 79, 162, 8, 69, + 158, 20, 72, 2, 77, 2, 82, 2, 83, 2, 86, 3, 89, 4, 174, 188, 22, 86, 223, + 234, 1, 65, 20, 230, 6, 79, 247, 178, 22, 73, 172, 1, 194, 1, 65, 44, 7, + 76, 69, 84, 84, 69, 82, 32, 242, 1, 83, 228, 2, 2, 86, 79, 244, 226, 12, + 3, 84, 73, 80, 146, 249, 4, 73, 172, 130, 3, 5, 69, 75, 32, 79, 78, 162, + 152, 2, 68, 235, 169, 1, 85, 4, 138, 255, 20, 66, 253, 187, 1, 2, 68, 68, + 96, 202, 156, 8, 71, 2, 75, 218, 172, 12, 82, 206, 55, 65, 38, 68, 46, + 84, 230, 24, 85, 210, 200, 1, 73, 42, 76, 246, 189, 1, 78, 126, 66, 2, + 67, 2, 74, 2, 80, 2, 83, 194, 40, 79, 162, 8, 69, 158, 20, 70, 2, 72, 2, + 77, 2, 86, 2, 89, 3, 90, 26, 108, 19, 69, 81, 85, 69, 78, 67, 69, 32, 70, + 79, 82, 32, 76, 69, 84, 84, 69, 82, 32, 93, 4, 73, 71, 78, 32, 12, 70, + 71, 2, 75, 222, 238, 22, 83, 166, 213, 1, 76, 226, 31, 70, 3, 90, 2, 219, + 238, 22, 72, 14, 128, 1, 6, 65, 68, 65, 75, 32, 66, 2, 66, 164, 211, 14, + 2, 85, 68, 150, 172, 6, 78, 160, 128, 2, 3, 89, 65, 75, 171, 162, 1, 86, + 2, 139, 238, 7, 73, 18, 45, 9, 87, 69, 76, 32, 83, 73, 71, 78, 32, 18, + 226, 255, 20, 65, 190, 21, 85, 210, 200, 1, 73, 218, 231, 1, 79, 163, 8, + 69, 142, 23, 110, 65, 162, 95, 69, 206, 103, 73, 146, 9, 79, 142, 11, 84, + 30, 85, 130, 1, 89, 137, 186, 12, 4, 82, 89, 86, 78, 136, 11, 248, 1, 2, + 73, 82, 60, 8, 76, 70, 87, 73, 68, 84, 72, 32, 254, 10, 77, 210, 1, 78, + 236, 76, 21, 80, 80, 89, 32, 80, 69, 82, 83, 79, 78, 32, 82, 65, 73, 83, + 73, 78, 71, 32, 79, 78, 22, 84, 180, 183, 17, 2, 85, 77, 128, 141, 5, 2, + 82, 68, 227, 46, 68, 6, 26, 32, 163, 231, 23, 67, 4, 134, 178, 23, 80, + 187, 112, 83, 244, 1, 132, 2, 7, 72, 65, 78, 71, 85, 76, 32, 216, 4, 8, + 75, 65, 84, 65, 75, 65, 78, 65, 204, 3, 3, 76, 69, 70, 0, 4, 82, 73, 71, + 72, 58, 85, 228, 159, 6, 11, 70, 79, 82, 77, 83, 32, 76, 73, 71, 72, 84, + 194, 207, 6, 73, 174, 170, 4, 66, 190, 185, 4, 87, 167, 26, 68, 104, 52, + 7, 76, 69, 84, 84, 69, 82, 32, 255, 181, 10, 70, 102, 206, 1, 75, 28, 5, + 78, 73, 69, 85, 78, 42, 80, 24, 5, 82, 73, 69, 85, 76, 86, 83, 98, 89, + 222, 61, 67, 54, 69, 30, 73, 242, 4, 77, 138, 1, 84, 206, 3, 87, 198, 1, + 72, 214, 208, 23, 65, 2, 79, 151, 64, 85, 6, 242, 65, 72, 155, 3, 73, 7, + 11, 45, 4, 154, 72, 67, 131, 3, 72, 6, 166, 69, 72, 35, 73, 17, 11, 45, + 14, 226, 49, 84, 226, 14, 80, 130, 4, 77, 194, 3, 75, 218, 2, 72, 99, 83, + 12, 40, 4, 83, 65, 78, 71, 215, 178, 13, 73, 10, 230, 70, 67, 42, 75, 74, + 80, 34, 84, 211, 2, 83, 14, 154, 155, 22, 69, 238, 254, 1, 65, 150, 64, + 73, 2, 79, 3, 85, 118, 70, 32, 149, 238, 2, 11, 45, 72, 73, 82, 65, 71, + 65, 78, 65, 32, 80, 116, 76, 7, 76, 69, 84, 84, 69, 82, 32, 234, 237, 2, + 83, 34, 86, 147, 217, 20, 77, 110, 146, 1, 83, 222, 231, 2, 78, 150, 2, + 72, 2, 75, 2, 77, 2, 82, 2, 84, 170, 1, 89, 210, 41, 87, 202, 194, 21, + 65, 2, 69, 2, 73, 2, 79, 3, 85, 28, 76, 5, 77, 65, 76, 76, 32, 226, 214, + 24, 65, 2, 69, 2, 73, 2, 79, 3, 85, 18, 198, 234, 2, 89, 178, 199, 21, + 84, 234, 36, 65, 2, 69, 2, 73, 2, 79, 3, 85, 4, 11, 84, 4, 236, 243, 12, + 2, 32, 67, 231, 194, 10, 87, 2, 155, 182, 23, 80, 14, 56, 3, 77, 69, 82, + 106, 83, 173, 156, 21, 3, 66, 85, 82, 9, 29, 5, 32, 65, 78, 68, 32, 6, + 172, 128, 12, 3, 87, 82, 69, 180, 213, 3, 2, 83, 73, 175, 208, 7, 80, 4, + 136, 151, 24, 3, 84, 69, 82, 151, 61, 65, 194, 8, 118, 68, 202, 2, 71, + 128, 66, 13, 73, 70, 73, 32, 82, 79, 72, 73, 78, 71, 89, 65, 32, 165, 5, + 5, 85, 78, 79, 79, 32, 10, 100, 12, 32, 87, 73, 84, 72, 32, 73, 78, 68, + 69, 88, 32, 188, 1, 2, 66, 65, 217, 138, 21, 2, 83, 72, 4, 156, 1, 18, + 65, 78, 68, 32, 77, 73, 68, 68, 76, 69, 32, 70, 73, 78, 71, 69, 82, 83, + 1, 16, 70, 73, 78, 71, 69, 82, 32, 65, 78, 68, 32, 84, 72, 85, 77, 66, 2, + 145, 206, 15, 2, 32, 67, 4, 182, 199, 23, 76, 159, 137, 1, 71, 170, 7, + 84, 3, 85, 76, 32, 217, 64, 13, 90, 72, 79, 85, 32, 78, 85, 77, 69, 82, + 65, 76, 32, 146, 7, 164, 1, 9, 67, 72, 79, 83, 69, 79, 78, 71, 32, 244, + 15, 4, 68, 79, 85, 66, 0, 4, 83, 73, 78, 71, 46, 74, 180, 31, 7, 76, 69, + 84, 84, 69, 82, 32, 215, 246, 9, 70, 250, 1, 246, 1, 67, 172, 2, 5, 73, + 69, 85, 78, 71, 146, 1, 75, 132, 1, 5, 77, 73, 69, 85, 77, 56, 5, 78, 73, + 69, 85, 78, 74, 80, 172, 2, 5, 82, 73, 69, 85, 76, 210, 1, 83, 166, 3, + 84, 124, 2, 89, 69, 200, 40, 5, 72, 73, 69, 85, 72, 139, 238, 9, 70, 30, + 76, 2, 72, 73, 84, 7, 69, 79, 78, 71, 67, 72, 73, 121, 4, 73, 69, 85, 67, + 16, 40, 4, 69, 85, 67, 72, 41, 2, 84, 85, 7, 11, 45, 4, 202, 31, 75, 243, + 26, 72, 10, 21, 3, 69, 85, 77, 10, 22, 83, 155, 46, 67, 6, 40, 4, 83, 65, + 78, 71, 179, 162, 13, 73, 4, 194, 54, 67, 227, 3, 83, 5, 215, 30, 45, 27, + 11, 45, 24, 90, 80, 234, 30, 82, 242, 13, 67, 194, 5, 77, 138, 1, 84, + 186, 2, 75, 218, 2, 72, 99, 83, 6, 214, 50, 72, 214, 3, 73, 207, 2, 65, + 16, 80, 7, 65, 80, 89, 69, 79, 85, 78, 228, 20, 5, 73, 89, 69, 79, 75, + 131, 25, 72, 10, 234, 29, 82, 178, 15, 80, 30, 83, 231, 3, 77, 11, 11, + 45, 8, 158, 52, 75, 74, 80, 34, 84, 211, 2, 83, 15, 11, 45, 12, 190, 51, + 67, 42, 75, 74, 80, 34, 84, 242, 1, 72, 99, 83, 42, 68, 6, 72, 73, 69, + 85, 80, 72, 40, 4, 73, 69, 85, 80, 223, 53, 65, 7, 11, 45, 4, 158, 51, + 80, 147, 2, 72, 35, 11, 45, 32, 82, 83, 234, 20, 80, 214, 7, 75, 162, 12, + 67, 202, 6, 84, 226, 2, 78, 179, 2, 72, 14, 32, 3, 73, 79, 83, 251, 3, + 83, 13, 11, 45, 10, 242, 46, 84, 146, 2, 67, 42, 75, 75, 80, 29, 11, 45, + 26, 78, 75, 42, 83, 190, 44, 77, 154, 3, 67, 82, 78, 34, 80, 34, 84, 243, + 1, 72, 6, 170, 22, 65, 130, 19, 72, 135, 7, 73, 8, 40, 4, 83, 65, 78, 71, + 151, 155, 13, 73, 6, 206, 47, 75, 74, 80, 35, 84, 58, 48, 3, 73, 79, 83, + 217, 1, 4, 83, 65, 78, 71, 33, 11, 45, 30, 130, 1, 80, 44, 2, 83, 83, + 210, 22, 82, 210, 1, 75, 162, 12, 67, 194, 5, 77, 138, 1, 84, 226, 2, 78, + 178, 2, 72, 223, 223, 17, 73, 6, 184, 23, 4, 73, 69, 85, 80, 179, 19, 72, + 2, 233, 48, 3, 65, 78, 71, 26, 236, 17, 5, 67, 73, 69, 85, 67, 172, 3, 4, + 83, 73, 79, 83, 154, 1, 82, 186, 20, 84, 54, 89, 134, 2, 75, 42, 78, 34, + 80, 146, 2, 72, 223, 223, 17, 73, 16, 40, 5, 73, 75, 69, 85, 84, 195, 41, + 72, 15, 11, 45, 12, 226, 20, 82, 178, 19, 77, 154, 3, 67, 42, 75, 74, 80, + 243, 2, 83, 4, 150, 19, 83, 139, 22, 79, 2, 165, 211, 8, 6, 76, 69, 32, + 68, 79, 84, 216, 3, 92, 9, 79, 78, 71, 83, 69, 79, 78, 71, 32, 165, 21, + 9, 85, 78, 71, 83, 69, 79, 78, 71, 32, 154, 2, 226, 1, 67, 80, 5, 72, 73, + 69, 85, 72, 60, 5, 73, 69, 85, 78, 71, 46, 75, 220, 1, 5, 77, 73, 69, 85, + 77, 188, 1, 5, 78, 73, 69, 85, 78, 94, 80, 240, 2, 5, 82, 73, 69, 85, 76, + 190, 4, 83, 194, 3, 84, 213, 1, 2, 89, 69, 8, 36, 4, 73, 69, 85, 67, 239, + 30, 72, 7, 11, 45, 4, 162, 32, 83, 239, 7, 80, 11, 11, 45, 8, 174, 16, + 82, 178, 19, 77, 234, 3, 78, 35, 80, 9, 11, 45, 6, 194, 17, 75, 57, 2, + 83, 83, 28, 76, 7, 65, 80, 89, 69, 79, 85, 78, 40, 5, 73, 89, 69, 79, 75, + 215, 30, 72, 8, 130, 15, 82, 178, 15, 80, 131, 4, 77, 19, 11, 45, 16, + 166, 13, 75, 170, 1, 82, 42, 83, 224, 13, 2, 67, 72, 146, 9, 78, 34, 80, + 147, 2, 72, 27, 11, 45, 24, 74, 80, 30, 83, 134, 13, 82, 242, 13, 67, + 130, 9, 75, 42, 78, 179, 2, 72, 6, 174, 33, 73, 131, 6, 65, 6, 40, 4, 83, + 65, 78, 71, 143, 143, 13, 73, 4, 238, 35, 78, 147, 3, 83, 21, 11, 45, 18, + 174, 12, 82, 242, 13, 67, 202, 6, 84, 186, 2, 75, 218, 2, 72, 62, 80, 39, + 83, 36, 88, 6, 65, 78, 83, 73, 79, 83, 48, 6, 72, 73, 69, 85, 80, 72, 53, + 4, 73, 69, 85, 80, 7, 11, 45, 4, 236, 7, 2, 75, 65, 195, 26, 80, 9, 11, + 45, 6, 150, 11, 84, 234, 22, 80, 243, 2, 83, 23, 11, 45, 20, 112, 5, 82, + 73, 69, 85, 76, 24, 4, 83, 73, 79, 83, 134, 3, 80, 246, 19, 67, 194, 5, + 77, 170, 4, 84, 243, 1, 72, 5, 153, 3, 2, 45, 80, 5, 221, 32, 2, 45, 84, + 57, 11, 45, 54, 102, 75, 92, 5, 77, 73, 69, 85, 77, 50, 80, 126, 83, 74, + 84, 44, 2, 89, 69, 154, 28, 78, 179, 2, 72, 10, 52, 5, 73, 89, 69, 79, + 75, 190, 4, 65, 131, 19, 72, 7, 11, 45, 4, 254, 32, 72, 99, 83, 9, 11, + 45, 6, 130, 30, 75, 218, 2, 72, 99, 83, 14, 48, 4, 73, 69, 85, 80, 174, + 26, 72, 163, 6, 65, 11, 11, 45, 8, 42, 80, 222, 29, 84, 242, 1, 72, 99, + 83, 2, 243, 25, 72, 6, 40, 4, 83, 65, 78, 71, 255, 135, 13, 73, 4, 182, + 28, 75, 187, 3, 83, 6, 100, 5, 73, 75, 69, 85, 84, 151, 25, 72, 6, 56, 9, + 79, 82, 73, 78, 72, 73, 69, 85, 72, 191, 3, 83, 5, 255, 29, 45, 52, 48, + 3, 73, 79, 83, 161, 1, 4, 83, 65, 78, 71, 25, 11, 45, 22, 82, 75, 162, 3, + 82, 242, 13, 67, 198, 2, 80, 254, 2, 77, 138, 1, 84, 147, 5, 72, 4, 22, + 65, 135, 26, 73, 2, 237, 18, 6, 80, 89, 69, 79, 85, 78, 28, 160, 1, 5, + 82, 73, 69, 85, 76, 36, 6, 84, 73, 75, 69, 85, 84, 16, 3, 89, 69, 83, + 138, 19, 83, 178, 1, 77, 154, 3, 67, 42, 75, 42, 78, 34, 80, 239, 225, + 17, 73, 5, 17, 2, 45, 75, 2, 159, 17, 72, 5, 255, 16, 45, 2, 171, 250, + 17, 73, 20, 40, 5, 73, 75, 69, 85, 84, 155, 21, 72, 19, 11, 45, 16, 58, + 82, 42, 83, 42, 84, 162, 13, 67, 130, 9, 75, 75, 80, 2, 17, 2, 73, 69, 2, + 255, 160, 23, 85, 4, 21, 3, 73, 79, 83, 5, 223, 1, 45, 2, 255, 19, 72, + 18, 44, 6, 83, 73, 69, 85, 78, 71, 243, 19, 79, 17, 11, 45, 14, 50, 75, + 30, 83, 198, 17, 77, 154, 6, 72, 63, 80, 4, 166, 14, 72, 135, 7, 73, 4, + 26, 83, 175, 128, 13, 73, 2, 21, 3, 65, 78, 71, 2, 207, 20, 75, 190, 1, + 122, 65, 118, 69, 134, 1, 73, 92, 7, 83, 83, 65, 78, 71, 65, 82, 106, 79, + 138, 1, 85, 102, 89, 174, 15, 87, 175, 234, 9, 70, 23, 48, 4, 82, 65, 69, + 65, 98, 45, 239, 165, 24, 69, 13, 11, 45, 10, 190, 231, 21, 69, 130, 191, + 2, 65, 2, 73, 3, 85, 25, 18, 79, 55, 85, 9, 11, 45, 6, 130, 129, 24, 69, + 234, 36, 79, 3, 85, 15, 11, 45, 12, 170, 9, 69, 142, 156, 24, 65, 2, 79, + 3, 85, 31, 11, 45, 28, 66, 65, 34, 89, 166, 1, 79, 142, 254, 23, 69, 234, + 36, 73, 3, 85, 5, 11, 82, 2, 235, 212, 17, 65, 14, 50, 65, 230, 228, 21, + 69, 130, 191, 2, 79, 3, 85, 7, 238, 132, 24, 45, 247, 30, 69, 23, 26, 45, + 171, 163, 24, 69, 18, 50, 79, 22, 89, 226, 227, 21, 69, 131, 191, 2, 85, + 5, 155, 143, 24, 45, 8, 222, 227, 21, 69, 239, 254, 1, 65, 17, 11, 45, + 14, 158, 19, 89, 234, 136, 5, 73, 192, 170, 4, 3, 69, 79, 45, 214, 155, + 14, 65, 151, 64, 85, 62, 42, 65, 70, 69, 66, 73, 22, 79, 107, 85, 11, 26, + 45, 147, 161, 24, 69, 6, 154, 130, 24, 89, 246, 30, 79, 3, 85, 11, 11, + 79, 9, 11, 45, 6, 150, 158, 24, 89, 186, 2, 79, 3, 85, 5, 191, 251, 23, + 45, 19, 11, 45, 16, 58, 89, 186, 223, 23, 65, 162, 33, 69, 246, 30, 73, + 3, 79, 6, 182, 223, 23, 65, 163, 33, 69, 21, 11, 45, 18, 142, 16, 89, + 146, 208, 21, 69, 238, 254, 1, 65, 150, 64, 73, 2, 79, 3, 85, 186, 1, + 226, 1, 65, 46, 67, 54, 69, 30, 73, 22, 75, 188, 1, 5, 77, 73, 69, 85, + 77, 64, 5, 78, 73, 69, 85, 78, 70, 80, 168, 1, 5, 82, 73, 69, 85, 76, + 254, 1, 84, 90, 83, 246, 2, 87, 50, 89, 150, 1, 72, 214, 208, 23, 79, + 151, 64, 85, 9, 156, 13, 3, 82, 65, 69, 207, 143, 24, 69, 4, 22, 72, 207, + 8, 73, 2, 241, 249, 23, 2, 73, 69, 7, 138, 156, 24, 79, 3, 85, 5, 239, + 234, 17, 69, 14, 56, 7, 65, 80, 89, 69, 79, 85, 78, 106, 72, 155, 3, 73, + 8, 30, 80, 30, 83, 231, 3, 77, 4, 190, 4, 72, 215, 3, 73, 2, 25, 4, 83, + 65, 78, 71, 2, 207, 7, 80, 2, 253, 59, 2, 73, 69, 9, 11, 45, 6, 22, 80, + 247, 9, 83, 4, 142, 7, 73, 207, 2, 65, 13, 11, 45, 10, 234, 5, 67, 146, + 1, 84, 242, 1, 72, 62, 80, 39, 83, 20, 48, 4, 73, 69, 85, 80, 170, 2, 72, + 163, 6, 65, 17, 11, 45, 14, 42, 83, 186, 2, 84, 146, 2, 67, 43, 75, 6, + 21, 3, 73, 79, 83, 7, 11, 45, 4, 202, 4, 75, 107, 84, 27, 11, 45, 24, 68, + 2, 75, 73, 34, 77, 34, 80, 106, 84, 54, 89, 222, 4, 72, 99, 83, 4, 149, + 1, 4, 89, 69, 79, 75, 2, 11, 73, 2, 255, 238, 22, 69, 8, 30, 72, 34, 73, + 131, 6, 65, 2, 245, 156, 18, 3, 73, 69, 85, 4, 21, 3, 69, 85, 80, 5, 243, + 5, 45, 4, 22, 72, 151, 3, 73, 2, 229, 167, 19, 2, 73, 69, 2, 17, 2, 69, + 79, 2, 167, 4, 82, 28, 44, 3, 73, 79, 83, 57, 4, 83, 65, 78, 71, 13, 11, + 45, 10, 122, 67, 42, 75, 42, 78, 34, 80, 35, 84, 16, 78, 67, 42, 75, 42, + 78, 34, 80, 34, 84, 242, 1, 72, 98, 83, 255, 222, 17, 73, 2, 11, 73, 2, + 249, 236, 22, 2, 69, 85, 2, 11, 73, 2, 209, 233, 23, 2, 89, 69, 2, 11, + 73, 2, 243, 146, 23, 69, 2, 11, 73, 2, 135, 157, 23, 69, 2, 11, 73, 2, + 11, 75, 2, 255, 152, 23, 69, 10, 170, 211, 21, 69, 238, 254, 1, 65, 151, + 64, 73, 34, 58, 69, 206, 1, 79, 62, 85, 166, 207, 23, 65, 151, 64, 73, + 13, 42, 79, 73, 6, 83, 73, 69, 85, 78, 71, 5, 11, 82, 2, 17, 2, 73, 78, + 2, 11, 72, 2, 157, 200, 9, 2, 73, 69, 7, 11, 45, 4, 18, 80, 39, 83, 2, + 11, 65, 2, 11, 78, 2, 11, 83, 2, 139, 232, 12, 73, 9, 11, 45, 6, 26, 89, + 207, 143, 24, 73, 4, 183, 207, 23, 65, 9, 11, 45, 6, 26, 89, 147, 143, + 24, 73, 4, 143, 208, 21, 69, 24, 178, 223, 10, 84, 170, 194, 11, 70, 30, + 83, 230, 83, 78, 14, 79, 199, 110, 69, 100, 156, 1, 7, 76, 69, 84, 84, + 69, 82, 32, 196, 2, 5, 77, 65, 82, 75, 32, 72, 5, 83, 73, 71, 78, 32, + 196, 156, 2, 6, 86, 79, 87, 69, 76, 32, 167, 255, 19, 68, 58, 202, 1, 68, + 34, 75, 222, 249, 18, 84, 174, 113, 82, 246, 168, 2, 78, 246, 175, 1, 83, + 254, 68, 66, 2, 67, 2, 70, 2, 71, 2, 72, 2, 74, 2, 76, 2, 77, 2, 80, 2, + 86, 2, 87, 2, 89, 2, 90, 187, 2, 65, 4, 138, 137, 24, 68, 187, 2, 65, 8, + 56, 5, 73, 78, 78, 65, 32, 178, 136, 24, 72, 187, 2, 65, 4, 174, 136, 24, + 87, 3, 89, 4, 208, 232, 20, 6, 78, 65, 32, 75, 72, 79, 189, 162, 2, 3, + 83, 65, 75, 8, 52, 2, 84, 65, 209, 255, 21, 5, 72, 65, 82, 66, 65, 6, 42, + 72, 142, 203, 19, 83, 223, 187, 4, 78, 2, 135, 231, 23, 65, 42, 62, 76, + 172, 167, 18, 6, 83, 73, 71, 78, 32, 80, 139, 2, 86, 36, 33, 6, 69, 84, + 84, 69, 82, 32, 36, 158, 185, 20, 78, 210, 204, 3, 66, 2, 68, 2, 71, 2, + 72, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, 2, 89, 186, + 2, 65, 2, 73, 3, 85, 2, 135, 249, 22, 69, 54, 52, 5, 67, 72, 73, 78, 71, + 41, 4, 82, 65, 78, 32, 2, 17, 2, 32, 67, 2, 207, 215, 22, 72, 52, 52, 7, + 76, 69, 84, 84, 69, 82, 32, 211, 145, 6, 78, 42, 218, 1, 65, 226, 132, + 11, 90, 210, 46, 84, 150, 119, 76, 50, 81, 60, 6, 68, 65, 76, 69, 84, 72, + 198, 150, 4, 71, 122, 83, 66, 89, 154, 193, 1, 72, 234, 5, 75, 130, 76, + 66, 190, 173, 4, 78, 254, 1, 87, 202, 103, 80, 171, 4, 77, 4, 222, 193, + 16, 76, 207, 242, 6, 89, 170, 9, 230, 1, 65, 184, 32, 5, 66, 82, 69, 87, + 32, 230, 32, 76, 200, 1, 16, 78, 84, 65, 73, 71, 65, 78, 65, 32, 76, 69, + 84, 84, 69, 82, 32, 174, 12, 82, 120, 11, 88, 65, 71, 82, 65, 77, 32, 70, + 79, 82, 32, 137, 177, 23, 4, 68, 71, 69, 72, 212, 1, 42, 68, 98, 82, 201, + 1, 3, 86, 89, 32, 6, 44, 5, 83, 84, 79, 78, 69, 223, 215, 22, 80, 5, 205, + 219, 2, 7, 32, 71, 82, 65, 86, 69, 89, 12, 32, 2, 84, 32, 143, 222, 16, + 45, 10, 60, 5, 87, 73, 84, 72, 32, 210, 250, 11, 68, 139, 220, 8, 72, 6, + 76, 9, 84, 73, 80, 32, 79, 78, 32, 84, 72, 130, 200, 12, 82, 139, 157, + 10, 65, 2, 243, 204, 23, 69, 194, 1, 134, 2, 65, 202, 1, 66, 230, 2, 67, + 154, 3, 68, 162, 1, 69, 186, 3, 70, 94, 72, 62, 76, 222, 1, 77, 110, 79, + 162, 1, 82, 142, 2, 83, 228, 1, 3, 78, 79, 82, 198, 1, 84, 128, 2, 2, 85, + 80, 174, 1, 87, 146, 215, 13, 73, 146, 223, 3, 80, 242, 220, 3, 86, 215, + 74, 71, 12, 108, 17, 82, 82, 79, 87, 32, 83, 72, 65, 70, 84, 32, 87, 73, + 68, 84, 72, 32, 154, 217, 17, 77, 215, 146, 4, 83, 8, 36, 3, 79, 78, 69, + 235, 158, 22, 84, 7, 11, 32, 4, 182, 185, 13, 84, 151, 194, 8, 72, 14, + 48, 4, 65, 76, 76, 79, 21, 4, 76, 65, 67, 75, 2, 143, 140, 5, 84, 12, 30, + 32, 153, 1, 2, 45, 70, 6, 52, 7, 67, 85, 82, 86, 69, 68, 32, 151, 243, + 22, 72, 4, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 245, 217, 22, 8, 87, + 65, 82, 68, 83, 32, 65, 78, 6, 45, 9, 69, 65, 84, 72, 69, 82, 69, 68, 32, + 6, 194, 159, 13, 83, 210, 164, 3, 78, 163, 149, 6, 82, 14, 116, 2, 72, + 69, 52, 5, 73, 82, 67, 76, 69, 245, 159, 17, 14, 79, 78, 67, 65, 86, 69, + 45, 80, 79, 73, 78, 84, 69, 68, 4, 156, 134, 20, 4, 86, 82, 79, 78, 247, + 176, 2, 67, 9, 64, 6, 32, 87, 73, 84, 72, 32, 165, 229, 21, 4, 68, 32, + 83, 65, 4, 52, 7, 83, 84, 82, 79, 75, 69, 32, 159, 227, 4, 67, 2, 29, 5, + 65, 78, 68, 32, 84, 2, 11, 87, 2, 11, 79, 2, 21, 3, 32, 68, 79, 2, 11, + 84, 2, 231, 248, 22, 83, 14, 52, 7, 65, 83, 72, 69, 68, 32, 84, 18, 73, + 31, 79, 2, 175, 16, 82, 2, 157, 201, 18, 2, 86, 73, 10, 192, 16, 3, 87, + 78, 87, 206, 214, 13, 85, 135, 162, 4, 76, 16, 120, 5, 73, 71, 72, 84, + 32, 156, 2, 16, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 32, 77, 65, 82, + 75, 32, 231, 133, 18, 81, 10, 40, 2, 80, 79, 126, 84, 135, 225, 21, 83, + 6, 33, 6, 73, 78, 84, 69, 68, 32, 6, 174, 130, 16, 80, 128, 221, 5, 11, + 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 82, 23, 66, 2, 173, 225, 21, 24, + 69, 65, 82, 68, 82, 79, 80, 45, 83, 80, 79, 75, 69, 68, 32, 80, 82, 79, + 80, 69, 76, 76, 69, 82, 4, 150, 222, 22, 83, 187, 79, 79, 6, 44, 5, 79, + 85, 82, 32, 66, 227, 226, 4, 73, 2, 225, 218, 10, 6, 65, 76, 76, 79, 79, + 78, 4, 210, 254, 16, 79, 157, 170, 5, 6, 69, 65, 82, 84, 32, 69, 20, 74, + 65, 44, 3, 69, 70, 84, 28, 2, 79, 87, 237, 221, 4, 3, 73, 71, 65, 4, 212, + 236, 20, 2, 82, 71, 167, 196, 1, 84, 8, 254, 3, 45, 195, 6, 87, 6, 26, + 32, 179, 236, 9, 69, 4, 162, 225, 13, 68, 25, 4, 83, 73, 78, 71, 4, 56, + 8, 85, 76, 84, 73, 80, 76, 73, 67, 227, 211, 20, 73, 2, 25, 4, 65, 84, + 73, 79, 2, 163, 254, 4, 78, 6, 172, 234, 5, 9, 80, 69, 78, 32, 67, 69, + 78, 84, 82, 204, 152, 10, 13, 86, 65, 76, 32, 87, 73, 84, 72, 32, 79, 86, + 65, 76, 213, 214, 5, 5, 85, 84, 76, 73, 78, 12, 76, 4, 73, 71, 72, 84, + 149, 203, 22, 9, 79, 85, 78, 68, 45, 84, 73, 80, 80, 10, 62, 45, 109, 11, + 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 4, 69, 15, 80, 79, 73, 78, + 84, 73, 78, 71, 32, 65, 78, 71, 76, 69, 32, 4, 130, 196, 6, 66, 247, 153, + 7, 81, 7, 139, 6, 32, 26, 106, 65, 78, 73, 44, 2, 79, 85, 168, 229, 13, + 7, 67, 82, 73, 80, 84, 32, 76, 225, 131, 1, 3, 80, 65, 82, 4, 244, 220, + 13, 10, 78, 83, 45, 83, 69, 82, 73, 70, 32, 73, 195, 250, 7, 76, 8, 224, + 218, 13, 2, 78, 71, 203, 249, 7, 88, 10, 21, 3, 84, 72, 32, 10, 60, 5, + 69, 65, 83, 84, 32, 29, 6, 87, 69, 83, 84, 32, 80, 6, 26, 80, 235, 204, + 22, 65, 4, 41, 8, 79, 73, 78, 84, 73, 78, 71, 32, 4, 178, 181, 16, 86, + 239, 134, 6, 66, 12, 88, 9, 69, 65, 82, 68, 82, 79, 80, 45, 83, 130, 1, + 82, 169, 192, 6, 4, 87, 69, 76, 86, 6, 64, 6, 80, 79, 75, 69, 68, 32, + 145, 197, 22, 4, 72, 65, 78, 75, 4, 196, 212, 21, 8, 80, 73, 78, 87, 72, + 69, 69, 76, 27, 65, 2, 137, 3, 5, 73, 65, 78, 71, 76, 6, 26, 87, 159, + 226, 9, 80, 4, 53, 11, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 4, 29, + 5, 87, 73, 84, 72, 32, 4, 204, 181, 19, 5, 76, 65, 82, 71, 69, 187, 200, + 1, 69, 10, 72, 5, 72, 73, 84, 69, 32, 112, 2, 73, 68, 177, 254, 21, 3, + 69, 68, 71, 6, 56, 5, 68, 79, 87, 78, 45, 130, 147, 22, 67, 199, 46, 83, + 2, 165, 190, 22, 8, 80, 79, 73, 78, 84, 73, 78, 71, 2, 145, 153, 20, 2, + 69, 45, 140, 2, 112, 7, 65, 67, 67, 69, 78, 84, 32, 146, 8, 76, 164, 14, + 5, 77, 65, 82, 75, 32, 114, 80, 245, 188, 20, 2, 89, 79, 60, 132, 2, 9, + 65, 84, 78, 65, 72, 32, 72, 65, 70, 22, 68, 36, 3, 71, 69, 82, 74, 77, + 128, 1, 2, 80, 65, 28, 4, 69, 84, 78, 65, 20, 2, 81, 65, 58, 83, 58, 84, + 156, 1, 2, 89, 69, 78, 90, 152, 132, 8, 3, 82, 69, 86, 246, 179, 14, 79, + 221, 143, 1, 3, 73, 76, 85, 2, 255, 214, 17, 85, 4, 178, 186, 18, 69, + 175, 225, 4, 65, 6, 32, 3, 69, 83, 72, 195, 28, 83, 5, 237, 187, 6, 4, + 32, 77, 85, 81, 8, 88, 5, 69, 82, 75, 72, 65, 148, 164, 16, 2, 85, 78, + 145, 177, 1, 5, 65, 72, 65, 80, 65, 5, 149, 150, 19, 4, 32, 75, 69, 70, + 4, 26, 83, 191, 158, 23, 90, 2, 207, 183, 23, 72, 4, 196, 151, 23, 6, 82, + 78, 69, 89, 32, 80, 179, 35, 68, 4, 194, 24, 69, 241, 230, 21, 6, 72, 65, + 76, 83, 72, 69, 8, 38, 69, 181, 227, 21, 3, 73, 80, 69, 6, 48, 6, 76, 73, + 83, 72, 65, 32, 163, 183, 11, 86, 4, 136, 177, 21, 3, 81, 69, 84, 153, + 135, 2, 4, 71, 69, 68, 79, 4, 176, 171, 8, 10, 82, 65, 72, 32, 66, 69, + 78, 32, 89, 79, 167, 214, 2, 84, 8, 34, 65, 177, 160, 23, 2, 73, 78, 6, + 40, 4, 81, 69, 70, 32, 139, 222, 5, 82, 4, 194, 222, 10, 81, 197, 231, + 11, 3, 71, 65, 68, 150, 1, 76, 6, 69, 84, 84, 69, 82, 32, 201, 11, 8, 73, + 71, 65, 84, 85, 82, 69, 32, 140, 1, 134, 3, 65, 204, 1, 3, 66, 69, 84, 0, + 3, 75, 65, 70, 0, 2, 80, 69, 68, 6, 70, 73, 78, 65, 76, 32, 92, 2, 81, + 79, 16, 2, 72, 69, 52, 2, 78, 85, 0, 4, 90, 65, 89, 73, 18, 83, 48, 3, + 82, 69, 83, 170, 1, 84, 52, 4, 68, 65, 76, 69, 12, 5, 71, 73, 77, 69, 76, + 0, 5, 76, 65, 77, 69, 68, 0, 3, 77, 69, 77, 48, 3, 86, 65, 86, 80, 5, 87, + 73, 68, 69, 32, 153, 1, 3, 89, 79, 68, 14, 26, 76, 251, 212, 22, 89, 12, + 64, 2, 69, 70, 73, 10, 84, 69, 82, 78, 65, 84, 73, 86, 69, 32, 9, 33, 6, + 32, 87, 73, 84, 72, 32, 6, 250, 12, 77, 130, 1, 80, 35, 81, 4, 254, 145, + 16, 65, 187, 148, 1, 80, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 154, 15, + 82, 243, 172, 13, 68, 14, 88, 2, 75, 65, 236, 2, 2, 80, 69, 136, 152, 1, + 2, 84, 83, 218, 182, 21, 78, 239, 109, 77, 4, 235, 2, 70, 7, 236, 10, 5, + 32, 87, 73, 84, 72, 231, 198, 23, 84, 4, 167, 2, 78, 16, 44, 4, 65, 77, + 69, 75, 17, 3, 72, 73, 78, 4, 231, 1, 72, 13, 33, 6, 32, 87, 73, 84, 72, + 32, 10, 40, 6, 68, 65, 71, 69, 83, 72, 39, 83, 7, 33, 6, 32, 65, 78, 68, + 32, 83, 4, 210, 221, 5, 72, 167, 192, 2, 73, 12, 50, 69, 12, 2, 65, 86, + 1, 4, 83, 65, 68, 73, 4, 11, 84, 5, 161, 184, 13, 7, 32, 87, 73, 84, 72, + 32, 68, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 176, 251, 1, 2, 72, 79, 159, + 188, 11, 68, 16, 174, 2, 76, 250, 169, 8, 65, 246, 188, 2, 84, 158, 206, + 2, 82, 164, 186, 8, 2, 68, 65, 134, 91, 75, 198, 106, 72, 169, 4, 7, 70, + 73, 78, 65, 76, 32, 77, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 168, 7, 2, + 72, 73, 191, 174, 13, 68, 10, 72, 6, 65, 76, 69, 70, 32, 76, 29, 8, 89, + 73, 68, 68, 73, 83, 72, 32, 2, 133, 236, 18, 2, 65, 77, 8, 120, 7, 68, + 79, 85, 66, 76, 69, 32, 224, 4, 9, 89, 79, 68, 32, 89, 79, 68, 32, 80, + 237, 163, 20, 5, 86, 65, 86, 32, 89, 4, 210, 229, 10, 86, 251, 194, 9, + 89, 6, 80, 3, 76, 79, 87, 0, 3, 85, 80, 80, 153, 250, 21, 6, 77, 65, 83, + 79, 82, 65, 2, 185, 184, 22, 2, 69, 82, 50, 84, 5, 79, 73, 78, 84, 32, + 241, 5, 11, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 38, 220, 1, 9, + 68, 65, 71, 69, 83, 72, 32, 79, 82, 46, 72, 106, 80, 164, 1, 17, 74, 85, + 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 72, 32, 86, 65, 82, 22, 81, 86, + 82, 22, 83, 168, 174, 9, 2, 84, 83, 173, 207, 13, 3, 77, 69, 84, 2, 17, + 2, 32, 77, 2, 201, 1, 2, 65, 80, 12, 60, 5, 65, 84, 65, 70, 32, 106, 73, + 33, 4, 79, 76, 65, 77, 6, 38, 80, 34, 81, 165, 2, 2, 83, 69, 2, 11, 65, + 2, 251, 140, 16, 84, 2, 153, 177, 22, 3, 65, 77, 65, 2, 11, 82, 2, 207, + 177, 13, 73, 5, 145, 224, 10, 12, 32, 72, 65, 83, 69, 82, 32, 70, 79, 82, + 32, 86, 2, 195, 187, 23, 73, 6, 52, 5, 65, 77, 65, 84, 83, 133, 150, 11, + 2, 85, 66, 5, 193, 201, 10, 2, 32, 81, 2, 243, 191, 6, 65, 8, 34, 69, 22, + 72, 151, 145, 8, 73, 2, 179, 176, 22, 71, 4, 146, 145, 8, 73, 171, 187, + 7, 69, 12, 152, 1, 3, 71, 69, 82, 60, 3, 80, 65, 83, 20, 7, 83, 79, 70, + 32, 80, 65, 83, 224, 142, 21, 7, 78, 85, 78, 32, 72, 65, 70, 241, 176, 1, + 3, 77, 65, 81, 4, 26, 83, 131, 220, 21, 69, 2, 225, 190, 22, 3, 72, 65, + 89, 2, 199, 173, 13, 69, 2, 179, 173, 13, 85, 8, 114, 77, 248, 235, 11, + 15, 76, 83, 67, 72, 82, 69, 73, 66, 69, 82, 32, 80, 65, 85, 83, 221, 193, + 5, 3, 73, 67, 79, 4, 252, 188, 5, 12, 69, 84, 32, 87, 73, 84, 72, 32, 87, + 72, 73, 84, 223, 239, 16, 32, 188, 4, 164, 1, 2, 65, 45, 50, 72, 70, 75, + 230, 1, 77, 114, 78, 146, 2, 82, 66, 83, 154, 1, 84, 226, 1, 87, 62, 89, + 110, 69, 186, 206, 8, 85, 250, 148, 5, 79, 167, 178, 3, 73, 8, 234, 158, + 23, 87, 246, 30, 49, 2, 50, 3, 51, 72, 166, 6, 79, 182, 157, 8, 65, 222, + 201, 5, 85, 162, 115, 69, 3, 73, 74, 72, 2, 65, 45, 104, 2, 79, 45, 178, + 4, 73, 226, 3, 69, 211, 214, 14, 85, 24, 210, 193, 11, 49, 250, 227, 11, + 75, 214, 22, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 8, 222, + 167, 23, 75, 218, 19, 49, 2, 50, 3, 51, 54, 68, 2, 69, 45, 154, 7, 79, + 210, 214, 14, 65, 2, 73, 135, 191, 2, 85, 6, 134, 184, 23, 77, 186, 2, + 49, 3, 50, 68, 116, 2, 69, 45, 72, 2, 73, 45, 246, 2, 65, 246, 208, 8, + 79, 250, 148, 5, 85, 165, 160, 4, 6, 45, 77, 85, 45, 77, 79, 14, 170, + 154, 23, 75, 246, 30, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 16, 130, + 162, 23, 84, 214, 22, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 54, + 222, 4, 79, 2, 85, 210, 214, 14, 73, 134, 191, 2, 65, 3, 69, 68, 62, 65, + 2, 85, 226, 3, 73, 186, 206, 8, 69, 155, 136, 6, 79, 16, 11, 45, 16, 250, + 182, 23, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 64, 74, 69, + 20, 2, 79, 45, 72, 2, 85, 45, 178, 216, 14, 73, 135, 191, 2, 65, 18, 223, + 169, 18, 45, 14, 150, 179, 23, 82, 186, 2, 49, 2, 50, 2, 51, 2, 52, 2, + 53, 3, 54, 10, 146, 150, 23, 84, 246, 30, 49, 2, 50, 2, 51, 3, 52, 42, + 222, 207, 8, 65, 2, 73, 154, 136, 6, 79, 135, 191, 2, 69, 32, 40, 2, 65, + 45, 66, 79, 215, 149, 17, 85, 12, 242, 148, 23, 89, 246, 30, 49, 2, 50, + 2, 51, 2, 52, 3, 53, 12, 11, 45, 12, 154, 179, 23, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 3, 54, 4, 176, 133, 8, 21, 77, 73, 84, 73, 65, 78, 32, 67, 79, + 78, 74, 85, 71, 65, 84, 69, 32, 77, 65, 84, 82, 175, 173, 15, 66, 128, 1, + 210, 2, 65, 110, 66, 144, 1, 2, 67, 79, 94, 68, 198, 2, 70, 66, 71, 40, + 4, 72, 79, 76, 68, 164, 1, 2, 73, 78, 112, 2, 77, 79, 58, 79, 122, 80, + 100, 2, 82, 69, 62, 83, 238, 1, 84, 210, 5, 87, 216, 227, 14, 4, 76, 73, + 77, 73, 184, 137, 5, 11, 89, 79, 85, 84, 72, 70, 85, 76, 32, 70, 79, 133, + 159, 3, 9, 69, 78, 84, 72, 85, 83, 73, 65, 83, 6, 76, 3, 80, 80, 82, 124, + 4, 70, 84, 69, 82, 245, 209, 18, 4, 66, 85, 78, 68, 2, 149, 140, 23, 2, + 79, 65, 6, 92, 5, 69, 70, 79, 82, 69, 192, 193, 3, 6, 73, 84, 73, 78, 71, + 32, 1, 4, 82, 69, 65, 75, 2, 253, 220, 22, 7, 32, 67, 79, 77, 80, 76, 69, + 6, 26, 78, 239, 200, 18, 77, 4, 196, 236, 19, 4, 84, 69, 77, 80, 217, + 177, 2, 3, 70, 76, 73, 14, 110, 69, 78, 73, 134, 205, 18, 85, 173, 200, + 2, 15, 65, 82, 75, 69, 78, 73, 78, 71, 32, 79, 70, 32, 84, 72, 69, 6, + 150, 201, 18, 67, 192, 6, 2, 76, 73, 201, 152, 4, 5, 86, 69, 76, 79, 80, + 4, 184, 191, 18, 21, 70, 70, 73, 67, 85, 76, 84, 89, 32, 65, 84, 32, 84, + 72, 69, 32, 66, 69, 71, 73, 78, 137, 210, 2, 4, 83, 80, 69, 82, 4, 148, + 196, 18, 2, 79, 76, 221, 144, 4, 5, 69, 76, 76, 79, 87, 12, 36, 5, 65, + 84, 72, 69, 82, 35, 82, 2, 213, 206, 14, 3, 73, 78, 71, 10, 40, 4, 69, + 65, 84, 32, 211, 235, 22, 65, 8, 22, 80, 207, 5, 84, 6, 22, 79, 143, 5, + 82, 4, 168, 2, 2, 83, 83, 135, 232, 22, 87, 8, 50, 78, 134, 197, 18, 67, + 217, 5, 3, 70, 76, 85, 4, 184, 185, 18, 5, 69, 82, 32, 84, 82, 161, 17, + 2, 79, 67, 4, 128, 189, 21, 3, 68, 69, 83, 221, 59, 3, 85, 84, 72, 6, 26, + 66, 37, 2, 80, 80, 2, 209, 213, 22, 4, 83, 84, 82, 85, 4, 26, 82, 171, + 212, 22, 79, 2, 169, 140, 21, 2, 69, 83, 6, 200, 211, 14, 9, 85, 83, 72, + 73, 78, 71, 32, 85, 80, 168, 134, 2, 3, 82, 79, 71, 219, 142, 6, 69, 6, + 26, 84, 235, 180, 18, 86, 4, 186, 198, 18, 85, 215, 57, 82, 8, 132, 1, 5, + 77, 65, 76, 76, 32, 204, 178, 20, 6, 84, 65, 78, 68, 83, 84, 209, 233, 1, + 11, 80, 76, 73, 84, 84, 73, 78, 71, 32, 65, 80, 4, 24, 2, 80, 82, 43, 84, + 2, 157, 199, 18, 5, 69, 80, 79, 78, 68, 2, 11, 65, 2, 215, 209, 22, 77, + 30, 36, 3, 72, 69, 32, 171, 148, 17, 82, 28, 186, 2, 65, 130, 1, 67, 132, + 1, 3, 70, 65, 77, 20, 9, 82, 69, 67, 69, 80, 84, 73, 86, 69, 30, 87, 156, + 21, 12, 77, 65, 82, 82, 89, 73, 78, 71, 32, 77, 65, 73, 232, 242, 4, 6, + 71, 69, 78, 84, 76, 69, 204, 199, 10, 13, 75, 69, 69, 80, 73, 78, 71, 32, + 83, 84, 73, 76, 76, 177, 220, 3, 7, 74, 79, 89, 79, 85, 83, 32, 6, 58, + 82, 141, 140, 11, 8, 66, 89, 83, 77, 65, 76, 32, 87, 4, 220, 217, 19, 8, + 79, 85, 83, 73, 78, 71, 32, 84, 247, 179, 3, 77, 6, 160, 129, 1, 2, 65, + 85, 152, 215, 18, 9, 82, 69, 65, 84, 73, 86, 69, 32, 72, 233, 180, 1, 9, + 76, 73, 78, 71, 73, 78, 71, 32, 70, 2, 163, 250, 22, 73, 2, 129, 215, 19, + 2, 32, 69, 4, 242, 152, 21, 69, 209, 198, 1, 5, 65, 78, 68, 69, 82, 4, + 174, 198, 6, 65, 217, 146, 6, 14, 79, 82, 75, 32, 79, 78, 32, 84, 72, 69, + 32, 68, 69, 67, 222, 1, 236, 1, 2, 71, 72, 180, 2, 7, 82, 65, 71, 65, 78, + 65, 32, 212, 4, 7, 83, 84, 79, 82, 73, 67, 32, 184, 130, 15, 7, 78, 68, + 85, 32, 84, 69, 77, 236, 33, 4, 75, 73, 78, 71, 150, 235, 1, 66, 241, + 128, 4, 8, 80, 80, 79, 80, 79, 84, 65, 77, 12, 18, 32, 119, 45, 6, 144, + 234, 4, 2, 66, 82, 156, 152, 16, 6, 86, 79, 76, 84, 65, 71, 149, 47, 9, + 79, 67, 84, 69, 84, 32, 80, 82, 69, 6, 92, 11, 83, 80, 69, 69, 68, 32, + 84, 82, 65, 73, 78, 233, 166, 5, 6, 72, 69, 69, 76, 69, 68, 5, 133, 145, + 11, 14, 32, 87, 73, 84, 72, 32, 66, 85, 76, 76, 69, 84, 32, 78, 200, 1, + 112, 9, 68, 73, 71, 82, 65, 80, 72, 32, 89, 20, 7, 76, 69, 84, 84, 69, + 82, 32, 234, 170, 1, 86, 215, 207, 19, 73, 2, 135, 142, 16, 79, 194, 1, + 194, 1, 65, 74, 83, 218, 161, 1, 66, 162, 3, 78, 150, 2, 68, 2, 71, 2, + 72, 2, 75, 2, 77, 2, 80, 2, 82, 2, 84, 2, 90, 126, 87, 46, 89, 178, 199, + 21, 86, 234, 36, 69, 2, 73, 2, 79, 3, 85, 7, 37, 7, 82, 67, 72, 65, 73, + 67, 32, 4, 130, 240, 22, 87, 151, 14, 89, 42, 76, 5, 77, 65, 76, 76, 32, + 254, 147, 23, 65, 2, 69, 2, 73, 2, 79, 3, 85, 32, 182, 167, 1, 87, 46, + 89, 130, 142, 5, 75, 178, 185, 16, 84, 234, 36, 65, 2, 69, 2, 73, 2, 79, + 3, 85, 2, 171, 145, 8, 83, 92, 166, 1, 76, 52, 3, 78, 69, 89, 46, 82, + 130, 6, 84, 138, 1, 85, 210, 130, 16, 83, 138, 203, 2, 67, 172, 149, 3, + 6, 77, 79, 84, 72, 69, 84, 214, 163, 1, 79, 155, 3, 80, 6, 180, 212, 15, + 4, 76, 79, 87, 32, 163, 189, 7, 69, 4, 238, 164, 21, 66, 137, 156, 1, 2, + 32, 80, 50, 60, 8, 73, 90, 79, 78, 84, 65, 76, 32, 137, 5, 2, 83, 69, 44, + 198, 1, 66, 108, 4, 76, 73, 78, 69, 28, 17, 79, 78, 69, 32, 69, 73, 71, + 72, 84, 72, 32, 66, 76, 79, 67, 75, 45, 88, 10, 83, 67, 65, 78, 32, 76, + 73, 78, 69, 45, 46, 84, 210, 239, 20, 69, 251, 4, 77, 6, 44, 5, 76, 65, + 67, 75, 32, 243, 213, 22, 65, 4, 38, 79, 153, 215, 21, 3, 72, 69, 88, 2, + 139, 215, 21, 67, 2, 173, 244, 20, 2, 32, 69, 14, 160, 166, 16, 3, 49, + 51, 53, 198, 231, 6, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 8, 142, 141, + 23, 49, 2, 51, 2, 55, 3, 57, 10, 32, 2, 65, 66, 215, 246, 20, 82, 8, 26, + 85, 215, 245, 20, 32, 6, 33, 6, 76, 65, 84, 73, 79, 78, 7, 11, 32, 4, + 208, 163, 9, 8, 87, 73, 84, 72, 32, 74, 85, 83, 151, 179, 13, 83, 7, 11, + 32, 4, 140, 159, 7, 2, 82, 65, 155, 175, 15, 70, 10, 26, 32, 195, 129, + 22, 69, 8, 86, 80, 188, 175, 18, 5, 66, 69, 86, 69, 82, 204, 80, 3, 83, + 80, 82, 159, 137, 4, 68, 2, 175, 175, 14, 69, 12, 48, 6, 82, 71, 76, 65, + 83, 83, 77, 2, 83, 69, 5, 153, 208, 19, 14, 32, 87, 73, 84, 72, 32, 70, + 76, 79, 87, 73, 78, 71, 32, 9, 11, 32, 6, 88, 8, 87, 73, 84, 72, 32, 71, + 65, 82, 169, 132, 21, 8, 66, 85, 73, 76, 68, 73, 78, 71, 2, 147, 183, 21, + 68, 7, 242, 135, 23, 74, 3, 83, 8, 106, 83, 208, 243, 21, 11, 78, 68, 82, + 69, 68, 32, 80, 79, 73, 78, 84, 148, 11, 2, 71, 71, 139, 136, 1, 84, 2, + 171, 246, 21, 72, 18, 90, 80, 224, 1, 5, 83, 84, 69, 82, 69, 220, 180, + 16, 2, 71, 73, 193, 207, 4, 2, 65, 67, 12, 60, 3, 72, 69, 78, 129, 133, + 4, 6, 79, 68, 73, 65, 83, 84, 11, 34, 32, 82, 65, 227, 167, 19, 45, 4, + 26, 87, 203, 168, 21, 66, 2, 21, 3, 73, 84, 72, 2, 141, 168, 3, 2, 32, + 68, 2, 193, 169, 12, 6, 84, 73, 79, 78, 32, 80, 2, 253, 240, 21, 2, 83, + 73, 202, 5, 160, 1, 3, 67, 69, 32, 152, 1, 2, 68, 69, 222, 24, 77, 214, + 2, 78, 132, 37, 7, 90, 65, 75, 65, 89, 65, 32, 237, 137, 19, 9, 32, 76, + 79, 86, 69, 32, 89, 79, 85, 8, 114, 67, 252, 249, 10, 18, 72, 79, 67, 75, + 69, 89, 32, 83, 84, 73, 67, 75, 32, 65, 78, 68, 32, 80, 155, 179, 1, 83, + 4, 250, 184, 15, 82, 187, 212, 2, 85, 246, 1, 68, 3, 78, 84, 73, 201, 1, + 9, 79, 71, 82, 65, 80, 72, 73, 67, 32, 8, 64, 4, 67, 65, 76, 32, 105, 8, + 70, 73, 67, 65, 84, 73, 79, 78, 6, 32, 2, 84, 79, 175, 255, 21, 87, 5, + 129, 188, 14, 12, 32, 65, 78, 68, 32, 83, 76, 65, 78, 84, 69, 68, 2, 229, + 232, 21, 2, 32, 67, 238, 1, 208, 2, 11, 65, 78, 78, 79, 84, 65, 84, 73, + 79, 78, 32, 242, 3, 67, 72, 2, 68, 69, 248, 5, 5, 78, 85, 77, 66, 69, 22, + 84, 220, 204, 5, 8, 72, 65, 76, 70, 32, 70, 73, 76, 144, 186, 1, 5, 69, + 78, 84, 69, 82, 0, 3, 82, 73, 83, 24, 5, 76, 69, 86, 69, 76, 236, 240, 8, + 5, 86, 65, 82, 73, 65, 158, 175, 4, 70, 230, 46, 73, 131, 222, 1, 83, 32, + 232, 1, 5, 66, 79, 84, 84, 79, 22, 70, 82, 77, 62, 84, 140, 1, 4, 76, 73, + 78, 75, 188, 142, 1, 4, 83, 69, 67, 79, 150, 255, 5, 79, 228, 238, 5, 6, + 82, 69, 86, 69, 82, 83, 148, 147, 9, 5, 72, 69, 65, 86, 69, 165, 39, 3, + 69, 65, 82, 2, 175, 185, 22, 77, 6, 48, 3, 79, 85, 82, 229, 175, 22, 3, + 73, 82, 83, 4, 218, 184, 22, 84, 27, 32, 4, 36, 3, 73, 68, 68, 235, 144, + 22, 65, 2, 211, 253, 12, 76, 8, 34, 72, 46, 87, 131, 226, 7, 79, 4, 222, + 236, 8, 82, 181, 192, 13, 2, 73, 82, 2, 191, 183, 22, 79, 4, 36, 3, 76, + 79, 83, 167, 173, 20, 79, 2, 129, 183, 22, 3, 73, 78, 71, 36, 104, 20, + 83, 67, 82, 73, 80, 84, 73, 79, 78, 32, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 32, 247, 139, 7, 80, 34, 144, 2, 9, 65, 66, 79, 86, 69, 32, 84, 79, + 32, 84, 8, 76, 69, 70, 84, 32, 84, 79, 32, 76, 5, 79, 86, 69, 82, 76, 20, + 2, 83, 85, 202, 186, 14, 82, 152, 153, 5, 8, 70, 85, 76, 76, 32, 83, 85, + 82, 173, 207, 2, 15, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 82, 69, + 70, 76, 4, 60, 9, 77, 73, 68, 68, 76, 69, 32, 65, 78, 167, 220, 20, 66, + 2, 247, 205, 20, 68, 4, 180, 166, 21, 10, 77, 73, 68, 68, 76, 69, 32, 65, + 78, 68, 195, 163, 1, 82, 2, 231, 162, 16, 65, 18, 72, 12, 82, 82, 79, 85, + 78, 68, 32, 70, 82, 79, 77, 32, 163, 236, 16, 66, 16, 82, 76, 200, 163, + 11, 3, 85, 80, 80, 202, 182, 9, 66, 222, 155, 1, 65, 143, 82, 82, 6, 186, + 163, 11, 79, 175, 164, 11, 69, 2, 195, 180, 8, 82, 148, 1, 92, 10, 65, + 76, 76, 89, 32, 77, 65, 82, 75, 32, 41, 9, 69, 76, 69, 71, 82, 65, 80, + 72, 32, 10, 138, 132, 21, 70, 70, 84, 203, 83, 79, 138, 1, 140, 1, 11, + 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 205, 179, 12, 17, 76, 73, 78, + 69, 32, 70, 69, 69, 68, 32, 83, 69, 80, 65, 82, 65, 84, 136, 1, 182, 1, + 65, 58, 68, 200, 2, 5, 72, 79, 85, 82, 32, 214, 1, 74, 28, 4, 70, 69, 66, + 82, 64, 2, 77, 65, 144, 137, 15, 3, 78, 79, 86, 0, 4, 83, 69, 80, 84, 25, + 4, 79, 67, 84, 79, 4, 232, 166, 19, 3, 85, 71, 85, 213, 154, 1, 2, 80, + 82, 64, 44, 3, 65, 89, 32, 217, 141, 15, 2, 69, 67, 62, 66, 84, 130, 177, + 5, 69, 66, 70, 70, 78, 26, 83, 219, 161, 16, 79, 34, 34, 72, 90, 87, 187, + 156, 22, 69, 8, 36, 3, 73, 82, 84, 139, 128, 21, 82, 6, 26, 89, 175, 155, + 21, 69, 5, 247, 194, 21, 45, 24, 26, 69, 243, 235, 22, 79, 22, 36, 3, 78, + 84, 89, 135, 239, 21, 76, 21, 147, 232, 14, 45, 50, 78, 84, 222, 174, 5, + 69, 66, 70, 70, 78, 26, 83, 206, 206, 15, 90, 143, 83, 79, 20, 42, 87, + 186, 176, 5, 72, 175, 234, 16, 69, 14, 26, 69, 159, 234, 22, 79, 12, 36, + 3, 78, 84, 89, 179, 237, 21, 76, 11, 159, 212, 16, 45, 6, 24, 2, 65, 78, + 35, 85, 2, 11, 85, 2, 131, 221, 16, 65, 4, 206, 210, 22, 78, 143, 5, 76, + 4, 218, 198, 22, 82, 171, 34, 89, 68, 40, 6, 65, 71, 69, 32, 79, 70, 83, + 80, 5, 233, 225, 8, 15, 32, 79, 82, 32, 65, 80, 80, 82, 79, 88, 73, 77, + 65, 84, 69, 65, 65, 14, 69, 82, 73, 65, 76, 32, 65, 82, 65, 77, 65, 73, + 67, 32, 62, 64, 7, 78, 85, 77, 66, 69, 82, 32, 234, 18, 76, 239, 249, 18, + 83, 16, 26, 84, 171, 140, 15, 79, 10, 138, 143, 11, 87, 186, 137, 1, 69, + 195, 225, 8, 72, 132, 3, 202, 1, 67, 234, 1, 68, 218, 6, 70, 132, 2, 5, + 72, 73, 66, 73, 84, 156, 1, 15, 80, 85, 84, 32, 83, 89, 77, 66, 79, 76, + 32, 70, 79, 82, 32, 206, 1, 83, 236, 5, 2, 84, 69, 206, 8, 86, 175, 211, + 9, 66, 10, 32, 2, 79, 77, 69, 2, 82, 69, 4, 144, 144, 16, 3, 73, 78, 71, + 129, 216, 2, 5, 80, 76, 69, 84, 69, 6, 36, 3, 65, 83, 69, 151, 160, 22, + 77, 4, 34, 32, 161, 141, 10, 2, 83, 32, 2, 161, 143, 11, 8, 70, 79, 78, + 84, 32, 83, 73, 90, 145, 1, 24, 2, 69, 88, 103, 73, 5, 205, 201, 21, 20, + 32, 80, 79, 73, 78, 84, 73, 78, 71, 32, 65, 84, 32, 84, 72, 69, 32, 86, + 73, 69, 138, 1, 72, 8, 67, 32, 83, 73, 89, 65, 81, 32, 209, 185, 17, 4, + 65, 78, 32, 82, 136, 1, 200, 1, 11, 65, 76, 84, 69, 82, 78, 65, 84, 69, + 32, 76, 2, 76, 28, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 100, 7, 78, 85, + 77, 66, 69, 82, 32, 222, 209, 8, 82, 201, 246, 2, 6, 80, 76, 65, 67, 69, + 72, 2, 237, 157, 22, 2, 65, 75, 6, 68, 4, 79, 78, 69, 32, 217, 224, 20, + 7, 84, 72, 82, 69, 69, 32, 81, 4, 178, 222, 20, 72, 43, 81, 122, 212, 1, + 10, 65, 76, 84, 69, 82, 78, 65, 84, 69, 32, 72, 5, 75, 65, 82, 79, 82, 0, + 4, 76, 65, 75, 72, 250, 226, 9, 69, 66, 70, 94, 78, 26, 83, 78, 84, 220, + 243, 4, 8, 80, 82, 69, 70, 73, 88, 69, 68, 167, 41, 79, 6, 26, 84, 175, + 195, 21, 79, 4, 236, 128, 6, 2, 69, 78, 223, 188, 16, 87, 5, 191, 140, + 22, 65, 16, 72, 5, 73, 78, 73, 84, 89, 85, 9, 79, 82, 77, 65, 84, 73, 79, + 78, 32, 5, 45, 9, 32, 78, 69, 71, 65, 84, 69, 68, 32, 2, 237, 134, 8, 4, + 87, 73, 84, 72, 12, 42, 83, 253, 134, 16, 4, 68, 69, 83, 75, 10, 156, + 245, 6, 5, 69, 80, 65, 82, 65, 191, 214, 9, 79, 4, 11, 32, 4, 232, 136, + 22, 15, 65, 82, 65, 66, 73, 67, 32, 70, 79, 82, 77, 32, 83, 72, 65, 1, + 14, 83, 89, 77, 77, 69, 84, 82, 73, 67, 32, 83, 87, 65, 80, 10, 80, 6, + 76, 65, 84, 73, 78, 32, 234, 185, 14, 83, 221, 143, 7, 4, 78, 85, 77, 66, + 6, 64, 6, 67, 65, 80, 73, 84, 65, 0, 4, 83, 77, 65, 76, 27, 76, 2, 21, 3, + 76, 32, 76, 2, 205, 217, 20, 2, 69, 84, 116, 84, 13, 67, 82, 73, 80, 84, + 73, 79, 78, 65, 76, 32, 80, 65, 233, 141, 15, 2, 69, 82, 114, 72, 6, 72, + 76, 65, 86, 73, 32, 225, 1, 7, 82, 84, 72, 73, 65, 78, 32, 54, 48, 7, 76, + 69, 84, 84, 69, 82, 32, 191, 3, 78, 38, 234, 132, 10, 84, 226, 118, 65, + 22, 68, 34, 76, 22, 77, 50, 87, 238, 150, 4, 71, 90, 90, 34, 83, 66, 89, + 154, 193, 1, 72, 234, 5, 75, 130, 76, 66, 190, 173, 4, 78, 199, 105, 80, + 60, 22, 76, 251, 1, 78, 44, 11, 69, 44, 29, 5, 84, 84, 69, 82, 32, 44, + 250, 130, 10, 84, 246, 118, 68, 34, 76, 50, 81, 206, 194, 1, 82, 134, + 212, 2, 65, 50, 71, 90, 90, 34, 83, 66, 89, 154, 193, 1, 72, 234, 5, 75, + 130, 76, 66, 190, 173, 4, 78, 254, 1, 87, 202, 103, 80, 171, 4, 77, 16, + 33, 6, 85, 77, 66, 69, 82, 32, 16, 246, 249, 10, 84, 202, 253, 3, 79, + 171, 243, 2, 70, 50, 36, 4, 71, 82, 65, 76, 179, 3, 82, 23, 11, 32, 20, + 58, 65, 140, 1, 5, 87, 73, 84, 72, 32, 219, 181, 20, 69, 4, 96, 6, 86, + 69, 82, 65, 71, 69, 173, 237, 15, 12, 82, 79, 85, 78, 68, 32, 65, 32, 80, + 79, 73, 78, 2, 209, 238, 15, 5, 32, 87, 73, 84, 72, 14, 160, 1, 3, 84, + 73, 77, 20, 2, 85, 78, 200, 203, 6, 16, 76, 69, 70, 84, 87, 65, 82, 68, + 83, 32, 65, 82, 82, 79, 87, 32, 182, 231, 12, 73, 198, 1, 79, 251, 49, + 68, 2, 191, 180, 19, 69, 4, 202, 180, 19, 68, 203, 201, 2, 73, 28, 94, + 76, 232, 1, 7, 83, 69, 67, 84, 73, 79, 78, 202, 6, 82, 144, 200, 11, 2, + 67, 65, 43, 73, 8, 164, 1, 17, 73, 78, 69, 65, 82, 32, 65, 78, 78, 79, + 84, 65, 84, 73, 79, 78, 32, 201, 200, 4, 17, 79, 67, 75, 69, 68, 32, 70, + 69, 77, 65, 76, 69, 32, 65, 78, 68, 32, 6, 232, 130, 8, 3, 65, 78, 67, + 170, 128, 8, 84, 199, 175, 3, 83, 15, 11, 32, 12, 168, 1, 6, 65, 66, 79, + 86, 69, 32, 64, 5, 87, 73, 84, 72, 32, 133, 174, 19, 22, 66, 69, 83, 73, + 68, 69, 32, 65, 78, 68, 32, 74, 79, 73, 78, 69, 68, 32, 87, 73, 84, 72, + 4, 244, 174, 19, 9, 66, 65, 82, 32, 65, 66, 79, 86, 69, 23, 85, 6, 158, + 143, 4, 76, 190, 160, 15, 79, 139, 201, 2, 68, 36, 56, 2, 69, 82, 245, 4, + 7, 73, 83, 73, 66, 76, 69, 32, 30, 48, 3, 83, 69, 32, 153, 2, 4, 84, 69, + 68, 32, 12, 180, 1, 5, 67, 72, 69, 67, 75, 68, 24, 68, 79, 87, 78, 87, + 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 87, 73, 84, 72, 32, 84, 73, + 80, 166, 195, 19, 87, 230, 18, 77, 183, 147, 1, 66, 4, 196, 213, 19, 8, + 69, 82, 32, 66, 79, 65, 82, 68, 195, 175, 2, 32, 2, 229, 237, 19, 2, 32, + 76, 18, 144, 1, 6, 73, 78, 84, 69, 82, 82, 22, 76, 150, 195, 11, 80, 170, + 169, 4, 69, 148, 183, 1, 2, 79, 72, 136, 131, 2, 4, 85, 78, 68, 69, 163, + 83, 81, 2, 151, 179, 4, 79, 6, 60, 9, 79, 87, 32, 75, 65, 86, 89, 75, 65, + 187, 196, 6, 65, 5, 225, 204, 17, 11, 32, 87, 73, 84, 72, 32, 75, 65, 86, + 89, 75, 6, 38, 84, 138, 230, 18, 80, 143, 68, 83, 2, 207, 238, 15, 73, + 218, 1, 94, 65, 134, 21, 69, 62, 79, 42, 85, 165, 146, 11, 10, 73, 71, + 83, 65, 87, 32, 80, 85, 90, 90, 202, 1, 120, 5, 67, 75, 45, 79, 45, 32, + 7, 80, 65, 78, 69, 83, 69, 32, 184, 2, 7, 86, 65, 78, 69, 83, 69, 32, + 183, 190, 22, 82, 2, 233, 226, 17, 3, 76, 65, 78, 16, 246, 1, 67, 18, 80, + 128, 153, 1, 10, 73, 78, 68, 85, 83, 84, 82, 73, 65, 76, 140, 196, 3, 3, + 66, 65, 78, 250, 171, 3, 68, 244, 171, 12, 3, 71, 79, 66, 204, 105, 2, + 79, 71, 181, 98, 16, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 66, 69, + 71, 73, 78, 2, 199, 32, 65, 2, 197, 209, 12, 7, 79, 83, 84, 32, 79, 70, + 70, 182, 1, 172, 2, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, + 71, 78, 32, 76, 2, 76, 69, 40, 4, 82, 73, 71, 72, 224, 6, 2, 80, 65, 176, + 3, 14, 84, 85, 82, 78, 69, 68, 32, 80, 65, 68, 65, 32, 80, 73, 88, 5, 83, + 73, 71, 78, 32, 140, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, + 255, 192, 20, 68, 6, 52, 2, 75, 69, 228, 129, 16, 2, 80, 69, 175, 5, 67, + 2, 187, 134, 22, 82, 96, 38, 70, 65, 5, 84, 84, 69, 82, 32, 2, 41, 8, 84, + 32, 82, 69, 82, 69, 78, 71, 2, 171, 243, 20, 71, 94, 230, 1, 68, 26, 73, + 48, 2, 75, 65, 66, 78, 130, 1, 66, 2, 67, 2, 71, 16, 2, 80, 65, 56, 2, + 82, 65, 32, 2, 83, 65, 42, 84, 74, 74, 186, 174, 20, 65, 150, 132, 2, 72, + 2, 76, 2, 77, 2, 87, 2, 89, 186, 2, 69, 2, 79, 3, 85, 8, 222, 3, 68, 15, + 65, 7, 164, 167, 5, 3, 32, 75, 65, 167, 145, 17, 73, 7, 11, 32, 4, 22, + 83, 215, 2, 77, 2, 145, 137, 20, 2, 65, 83, 14, 36, 2, 71, 65, 90, 89, + 167, 1, 65, 7, 33, 6, 32, 76, 69, 76, 69, 84, 5, 29, 5, 32, 82, 65, 83, + 87, 2, 135, 192, 5, 65, 4, 163, 1, 65, 7, 11, 32, 4, 154, 1, 77, 129, + 178, 22, 3, 67, 69, 82, 5, 145, 133, 16, 3, 32, 65, 71, 7, 17, 2, 32, 77, + 4, 70, 85, 71, 65, 8, 18, 65, 55, 84, 5, 17, 2, 32, 77, 2, 11, 85, 2, + 147, 144, 22, 82, 4, 11, 65, 5, 11, 32, 2, 11, 77, 2, 11, 65, 2, 11, 72, + 2, 233, 232, 16, 2, 65, 80, 28, 40, 3, 68, 65, 32, 165, 3, 2, 78, 71, 24, + 174, 1, 65, 90, 76, 86, 80, 168, 240, 6, 10, 84, 73, 82, 84, 65, 32, 84, + 85, 77, 69, 138, 219, 11, 87, 128, 149, 2, 7, 73, 83, 69, 78, 45, 73, 83, + 153, 206, 1, 3, 77, 65, 68, 6, 44, 3, 68, 69, 71, 205, 161, 21, 2, 78, + 68, 5, 11, 32, 2, 181, 236, 21, 2, 65, 68, 6, 38, 85, 141, 175, 22, 3, + 73, 78, 71, 4, 184, 243, 17, 2, 78, 71, 211, 197, 3, 72, 4, 38, 73, 149, + 236, 17, 3, 65, 78, 71, 2, 217, 253, 15, 3, 83, 69, 76, 4, 208, 214, 12, + 5, 82, 65, 78, 71, 75, 171, 138, 9, 75, 10, 104, 5, 67, 69, 67, 65, 75, + 204, 165, 5, 5, 80, 65, 78, 89, 65, 176, 2, 3, 87, 73, 71, 239, 212, 10, + 76, 5, 233, 218, 17, 3, 32, 84, 69, 18, 116, 4, 83, 85, 75, 85, 42, 84, + 64, 4, 87, 85, 76, 85, 182, 251, 15, 80, 165, 210, 1, 7, 68, 73, 82, 71, + 65, 32, 77, 5, 221, 180, 21, 5, 32, 77, 69, 78, 68, 6, 26, 65, 243, 252, + 15, 79, 4, 218, 252, 15, 82, 139, 224, 5, 76, 5, 25, 4, 32, 77, 69, 76, + 2, 131, 170, 22, 73, 4, 36, 3, 76, 76, 89, 207, 254, 18, 65, 2, 155, 238, + 18, 70, 4, 228, 253, 20, 2, 89, 83, 147, 95, 73, 6, 148, 134, 14, 2, 71, + 71, 138, 230, 4, 80, 147, 161, 3, 78, 192, 24, 74, 65, 178, 78, 69, 202, + 1, 72, 178, 50, 73, 178, 2, 78, 50, 79, 111, 82, 198, 10, 200, 1, 5, 73, + 84, 72, 73, 32, 230, 4, 78, 168, 45, 6, 84, 65, 75, 65, 78, 65, 208, 13, + 3, 87, 73, 32, 240, 8, 7, 89, 65, 72, 32, 76, 73, 32, 252, 163, 4, 6, 75, + 84, 79, 86, 73, 75, 219, 143, 17, 65, 136, 1, 204, 1, 7, 76, 69, 84, 84, + 69, 82, 32, 174, 2, 83, 234, 115, 68, 156, 206, 3, 2, 86, 79, 168, 136, + 3, 11, 78, 85, 77, 66, 69, 82, 32, 83, 73, 71, 78, 154, 155, 9, 65, 197, + 213, 1, 6, 69, 78, 85, 77, 69, 82, 90, 210, 1, 68, 210, 189, 18, 65, 82, + 84, 230, 24, 85, 210, 200, 1, 73, 158, 190, 1, 78, 46, 83, 82, 66, 2, 67, + 2, 71, 2, 74, 2, 75, 2, 80, 2, 82, 254, 68, 72, 2, 76, 2, 77, 2, 86, 2, + 89, 186, 2, 69, 3, 79, 10, 38, 68, 194, 163, 22, 72, 187, 2, 65, 6, 186, + 174, 20, 68, 134, 245, 1, 72, 187, 2, 65, 12, 40, 4, 73, 71, 78, 32, 167, + 236, 10, 69, 10, 242, 190, 18, 67, 98, 78, 222, 160, 3, 65, 239, 1, 86, + 230, 4, 42, 71, 221, 39, 5, 78, 65, 68, 65, 32, 174, 3, 76, 11, 88, 73, + 32, 82, 65, 68, 73, 67, 65, 76, 32, 153, 227, 19, 2, 65, 82, 172, 3, 130, + 2, 65, 94, 66, 230, 2, 67, 150, 2, 68, 158, 3, 69, 198, 1, 70, 138, 2, + 71, 146, 1, 72, 210, 2, 73, 76, 2, 74, 65, 34, 75, 30, 76, 230, 1, 77, + 254, 1, 78, 62, 79, 102, 80, 110, 82, 166, 1, 83, 210, 6, 84, 226, 2, 86, + 50, 87, 210, 2, 89, 131, 244, 20, 85, 10, 56, 2, 82, 82, 238, 245, 20, + 71, 158, 101, 78, 195, 47, 88, 4, 138, 163, 21, 79, 207, 1, 73, 34, 58, + 65, 38, 73, 46, 76, 54, 79, 102, 82, 167, 215, 20, 69, 4, 190, 180, 5, + 77, 143, 180, 13, 68, 6, 206, 233, 20, 84, 186, 112, 82, 151, 70, 71, 6, + 138, 254, 18, 79, 154, 243, 1, 65, 251, 151, 1, 85, 10, 62, 76, 210, 130, + 22, 65, 218, 5, 78, 142, 5, 68, 203, 17, 87, 2, 173, 193, 3, 4, 84, 32, + 79, 70, 6, 42, 73, 246, 201, 9, 65, 159, 239, 10, 85, 2, 151, 189, 13, + 83, 28, 58, 65, 70, 76, 74, 79, 190, 135, 10, 72, 163, 171, 10, 73, 6, + 38, 85, 138, 129, 22, 82, 219, 5, 86, 2, 165, 249, 20, 2, 76, 68, 8, 42, + 65, 206, 151, 7, 73, 171, 241, 13, 79, 4, 234, 156, 22, 78, 3, 87, 10, + 214, 250, 20, 82, 204, 1, 2, 77, 80, 206, 98, 86, 134, 5, 76, 223, 56, + 87, 34, 38, 69, 38, 73, 98, 79, 195, 1, 82, 4, 214, 156, 20, 65, 183, + 198, 1, 69, 8, 38, 83, 158, 190, 13, 86, 175, 2, 80, 4, 200, 220, 18, 5, + 84, 73, 78, 71, 85, 199, 190, 3, 72, 16, 94, 84, 76, 3, 85, 66, 76, 214, + 191, 12, 87, 172, 137, 9, 2, 32, 78, 222, 23, 79, 211, 56, 71, 7, 25, 4, + 84, 69, 68, 32, 4, 184, 148, 7, 3, 67, 76, 73, 135, 194, 14, 84, 2, 171, + 170, 3, 69, 6, 162, 226, 20, 65, 158, 166, 1, 85, 219, 16, 89, 20, 106, + 65, 38, 78, 32, 3, 86, 69, 78, 216, 214, 8, 6, 77, 66, 82, 79, 73, 68, + 158, 150, 13, 73, 243, 19, 89, 6, 202, 152, 16, 82, 179, 255, 5, 84, 4, + 158, 25, 67, 219, 192, 21, 84, 5, 203, 198, 21, 73, 28, 74, 65, 50, 73, + 62, 76, 38, 82, 150, 20, 69, 138, 177, 21, 79, 223, 23, 85, 6, 206, 188, + 13, 84, 182, 195, 8, 67, 131, 22, 78, 8, 146, 177, 12, 69, 222, 186, 9, + 71, 230, 19, 82, 199, 21, 83, 4, 190, 209, 20, 85, 175, 196, 1, 89, 4, + 220, 232, 20, 2, 65, 71, 151, 172, 1, 79, 14, 58, 79, 52, 2, 82, 65, 218, + 204, 18, 72, 171, 131, 2, 65, 7, 202, 206, 21, 76, 229, 34, 5, 32, 83, + 76, 79, 87, 4, 214, 196, 21, 73, 135, 18, 83, 22, 58, 65, 142, 1, 69, 60, + 5, 73, 68, 73, 78, 71, 19, 79, 8, 38, 76, 150, 205, 21, 78, 199, 13, 73, + 4, 34, 70, 177, 252, 20, 2, 66, 69, 2, 41, 8, 32, 84, 82, 69, 69, 32, 84, + 82, 2, 255, 211, 18, 85, 6, 26, 65, 159, 146, 22, 77, 4, 250, 245, 21, + 82, 175, 28, 68, 2, 175, 19, 32, 6, 26, 82, 199, 142, 22, 79, 4, 134, + 251, 21, 83, 215, 22, 78, 6, 26, 78, 207, 250, 21, 67, 4, 26, 83, 247, + 143, 22, 67, 2, 171, 130, 21, 69, 4, 154, 250, 21, 68, 215, 22, 82, 2, + 253, 140, 5, 2, 78, 73, 22, 46, 65, 34, 69, 78, 73, 41, 3, 79, 78, 71, 4, + 174, 249, 21, 77, 191, 19, 67, 8, 38, 65, 238, 209, 21, 71, 187, 58, 69, + 4, 178, 181, 13, 84, 139, 218, 8, 70, 6, 194, 248, 21, 70, 2, 78, 215, + 22, 68, 5, 209, 146, 11, 3, 32, 83, 84, 22, 42, 69, 34, 73, 46, 79, 135, + 190, 21, 65, 4, 194, 190, 21, 76, 183, 51, 65, 4, 156, 185, 11, 2, 78, + 73, 203, 248, 8, 76, 12, 34, 82, 34, 85, 195, 189, 21, 79, 4, 138, 235, + 20, 84, 179, 81, 78, 6, 26, 78, 235, 139, 22, 84, 4, 198, 225, 20, 84, + 179, 171, 1, 68, 6, 26, 79, 143, 240, 21, 69, 4, 226, 245, 21, 83, 215, + 22, 84, 10, 40, 2, 78, 69, 22, 80, 199, 197, 21, 76, 5, 139, 247, 5, 83, + 4, 170, 132, 10, 80, 215, 173, 2, 69, 10, 54, 82, 242, 240, 20, 76, 166, + 1, 79, 151, 152, 1, 73, 4, 152, 144, 12, 2, 73, 86, 229, 218, 6, 2, 79, + 70, 18, 62, 65, 42, 73, 214, 255, 9, 79, 186, 186, 11, 85, 195, 9, 69, 6, + 178, 186, 21, 73, 214, 79, 80, 3, 84, 6, 232, 175, 12, 3, 71, 72, 84, + 150, 156, 9, 86, 143, 39, 67, 74, 170, 1, 65, 86, 67, 46, 69, 62, 72, + 166, 1, 73, 46, 76, 62, 80, 106, 84, 234, 159, 17, 87, 182, 145, 1, 78, + 190, 50, 79, 182, 155, 1, 77, 134, 100, 81, 254, 32, 75, 235, 47, 85, 6, + 192, 168, 3, 9, 67, 82, 73, 70, 73, 67, 73, 65, 76, 138, 195, 18, 76, + 175, 28, 89, 4, 150, 198, 10, 82, 229, 186, 5, 2, 72, 79, 8, 242, 203, + 20, 67, 234, 49, 65, 146, 8, 76, 143, 129, 1, 69, 10, 18, 69, 39, 79, 4, + 138, 253, 20, 76, 147, 137, 1, 69, 6, 40, 4, 82, 84, 32, 84, 175, 233, + 21, 79, 4, 222, 190, 15, 72, 137, 200, 4, 7, 65, 73, 76, 69, 68, 32, 66, + 4, 148, 162, 17, 2, 67, 75, 235, 223, 4, 76, 6, 26, 65, 227, 199, 21, 73, + 4, 250, 237, 21, 86, 199, 21, 83, 10, 50, 69, 34, 73, 178, 177, 18, 82, + 207, 130, 3, 79, 4, 170, 203, 21, 65, 171, 22, 69, 2, 163, 231, 21, 82, + 12, 34, 69, 34, 79, 167, 245, 20, 65, 4, 202, 242, 21, 65, 219, 16, 80, + 6, 26, 80, 151, 236, 21, 78, 5, 239, 177, 21, 80, 30, 82, 65, 98, 73, 34, + 79, 38, 82, 52, 2, 85, 82, 32, 2, 87, 79, 183, 176, 21, 69, 6, 38, 78, + 182, 224, 20, 66, 139, 24, 76, 2, 33, 6, 78, 69, 68, 32, 76, 69, 2, 159, + 167, 13, 65, 4, 190, 195, 21, 71, 143, 39, 76, 4, 150, 160, 18, 78, 231, + 225, 1, 79, 6, 214, 159, 16, 73, 186, 178, 4, 65, 251, 151, 1, 69, 4, + 242, 184, 20, 66, 147, 38, 84, 5, 215, 214, 18, 32, 4, 170, 157, 12, 65, + 129, 136, 5, 3, 73, 76, 76, 26, 58, 65, 110, 69, 42, 72, 32, 2, 73, 78, + 30, 79, 39, 82, 6, 32, 2, 76, 75, 135, 193, 21, 84, 5, 11, 32, 2, 11, 69, + 2, 17, 2, 78, 67, 2, 201, 158, 17, 2, 76, 79, 4, 184, 174, 21, 2, 65, 80, + 183, 51, 83, 4, 198, 185, 20, 73, 223, 48, 69, 4, 210, 253, 21, 68, 3, + 69, 4, 130, 182, 20, 77, 159, 196, 1, 82, 4, 166, 172, 21, 79, 227, 80, + 65, 2, 197, 228, 19, 2, 69, 76, 184, 1, 92, 2, 76, 69, 148, 2, 5, 83, 73, + 71, 78, 32, 238, 249, 16, 65, 174, 9, 86, 175, 136, 3, 68, 110, 44, 5, + 84, 84, 69, 82, 32, 235, 185, 21, 78, 108, 214, 128, 17, 76, 38, 78, 174, + 90, 82, 206, 55, 65, 38, 68, 46, 84, 46, 86, 186, 24, 85, 158, 144, 1, + 79, 182, 56, 73, 202, 190, 1, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, + 80, 162, 7, 69, 222, 61, 70, 2, 72, 2, 77, 3, 89, 22, 94, 67, 138, 1, 83, + 138, 145, 18, 65, 170, 1, 78, 230, 179, 1, 74, 150, 3, 85, 211, 235, 1, + 86, 4, 100, 19, 79, 77, 66, 73, 78, 73, 78, 71, 32, 65, 78, 85, 83, 86, + 65, 82, 65, 32, 65, 255, 145, 18, 65, 2, 185, 131, 19, 3, 66, 79, 86, 4, + 244, 135, 12, 6, 80, 65, 67, 73, 78, 71, 155, 249, 4, 73, 162, 2, 62, 32, + 173, 11, 10, 45, 72, 73, 82, 65, 71, 65, 78, 65, 32, 154, 2, 140, 1, 7, + 76, 69, 84, 84, 69, 82, 32, 242, 9, 86, 236, 159, 18, 10, 68, 73, 71, 82, + 65, 80, 72, 32, 75, 79, 234, 175, 1, 73, 247, 138, 1, 77, 146, 2, 186, 1, + 65, 178, 1, 66, 106, 77, 186, 2, 78, 54, 83, 226, 1, 68, 2, 71, 2, 72, 2, + 75, 2, 80, 2, 82, 2, 84, 2, 86, 2, 90, 126, 87, 46, 89, 154, 236, 21, 69, + 2, 73, 2, 79, 3, 85, 19, 60, 4, 73, 78, 85, 32, 45, 7, 82, 67, 72, 65, + 73, 67, 32, 8, 130, 7, 84, 142, 214, 21, 67, 215, 22, 80, 8, 38, 89, 170, + 206, 21, 87, 235, 36, 69, 4, 142, 243, 21, 69, 3, 73, 20, 50, 73, 194, + 242, 21, 65, 2, 69, 2, 79, 3, 85, 13, 253, 4, 9, 68, 65, 75, 85, 79, 78, + 32, 78, 71, 36, 50, 73, 218, 241, 21, 65, 2, 69, 2, 79, 3, 85, 29, 29, 5, + 78, 78, 65, 78, 32, 26, 96, 15, 78, 65, 83, 65, 76, 73, 90, 69, 68, 32, + 84, 79, 78, 69, 45, 69, 5, 84, 79, 78, 69, 45, 14, 210, 240, 21, 49, 2, + 50, 2, 51, 2, 52, 2, 53, 2, 55, 3, 56, 12, 142, 240, 21, 50, 2, 51, 2, + 52, 2, 53, 2, 55, 3, 56, 13, 210, 239, 21, 65, 2, 69, 2, 73, 2, 79, 3, + 85, 76, 76, 5, 77, 65, 76, 76, 32, 210, 238, 21, 65, 2, 69, 2, 73, 2, 79, + 3, 85, 66, 142, 1, 72, 2, 82, 54, 75, 46, 84, 30, 87, 46, 89, 254, 156, + 18, 78, 242, 142, 3, 83, 198, 27, 77, 234, 36, 65, 2, 69, 2, 73, 2, 79, + 3, 85, 10, 190, 237, 21, 65, 2, 69, 2, 73, 2, 79, 3, 85, 8, 138, 237, 21, + 65, 2, 69, 2, 79, 3, 85, 4, 222, 236, 21, 79, 3, 85, 8, 194, 236, 21, 65, + 2, 69, 2, 73, 3, 79, 6, 150, 236, 21, 65, 2, 79, 3, 85, 2, 189, 207, 19, + 5, 79, 73, 67, 69, 68, 8, 52, 5, 68, 79, 85, 66, 76, 22, 80, 38, 83, 35, + 86, 2, 251, 216, 7, 69, 2, 89, 6, 82, 79, 76, 79, 78, 71, 2, 29, 5, 69, + 77, 73, 45, 86, 2, 21, 3, 79, 73, 67, 2, 33, 6, 69, 68, 32, 83, 79, 85, + 2, 239, 157, 21, 78, 172, 1, 228, 1, 7, 76, 69, 84, 84, 69, 82, 32, 132, + 2, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 148, 3, 5, 83, 73, + 71, 78, 32, 92, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 178, 236, + 11, 68, 205, 183, 9, 3, 67, 79, 78, 94, 230, 1, 65, 214, 128, 4, 74, 154, + 253, 13, 68, 46, 84, 146, 4, 86, 214, 20, 85, 210, 200, 1, 73, 158, 190, + 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 75, 2, 80, 254, 68, 72, 2, 76, 2, + 77, 2, 82, 2, 87, 2, 89, 186, 2, 69, 3, 79, 7, 150, 230, 21, 65, 3, 73, + 22, 122, 67, 90, 68, 58, 70, 54, 83, 20, 12, 65, 76, 84, 69, 82, 78, 65, + 84, 69, 32, 83, 69, 149, 210, 20, 4, 84, 82, 73, 80, 4, 56, 8, 76, 79, + 83, 73, 78, 71, 32, 83, 203, 149, 20, 73, 2, 141, 219, 20, 2, 80, 73, 4, + 11, 79, 4, 132, 211, 20, 2, 85, 66, 151, 145, 1, 84, 4, 204, 148, 20, 5, + 73, 76, 76, 69, 68, 175, 54, 76, 6, 18, 69, 23, 80, 2, 203, 196, 10, 67, + 4, 156, 241, 3, 2, 65, 67, 195, 232, 16, 73, 10, 192, 238, 5, 2, 82, 69, + 166, 204, 1, 75, 218, 193, 10, 67, 226, 182, 1, 86, 223, 234, 1, 65, 20, + 66, 65, 134, 255, 3, 86, 170, 147, 14, 69, 2, 85, 211, 200, 1, 73, 6, + 244, 152, 16, 8, 76, 84, 69, 82, 78, 65, 84, 69, 210, 200, 5, 65, 3, 73, + 96, 148, 1, 7, 76, 69, 84, 84, 69, 82, 32, 204, 1, 5, 83, 73, 71, 78, 32, + 44, 5, 84, 79, 78, 69, 32, 92, 6, 86, 79, 87, 69, 76, 32, 247, 238, 19, + 68, 56, 154, 206, 16, 72, 190, 173, 1, 79, 230, 236, 1, 78, 246, 175, 1, + 75, 2, 80, 2, 83, 2, 84, 254, 68, 66, 2, 67, 2, 68, 2, 71, 2, 76, 2, 77, + 2, 82, 2, 86, 2, 87, 2, 89, 2, 90, 186, 2, 65, 3, 73, 4, 242, 204, 4, 67, + 201, 142, 17, 2, 83, 72, 6, 36, 5, 67, 65, 76, 89, 65, 23, 80, 5, 17, 2, + 32, 80, 2, 197, 155, 17, 3, 76, 79, 80, 10, 250, 156, 21, 69, 2, 85, 151, + 64, 79, 34, 24, 2, 76, 86, 23, 89, 2, 175, 230, 19, 73, 33, 52, 5, 66, + 79, 65, 82, 68, 37, 4, 67, 65, 80, 32, 5, 213, 172, 18, 4, 32, 65, 78, + 68, 26, 142, 197, 16, 78, 146, 134, 3, 65, 162, 34, 68, 171, 29, 84, 186, + 13, 202, 1, 65, 212, 9, 18, 73, 84, 65, 78, 32, 83, 77, 65, 76, 76, 32, + 83, 67, 82, 73, 80, 84, 32, 184, 3, 4, 77, 69, 82, 32, 204, 25, 5, 79, + 74, 75, 73, 32, 145, 6, 8, 85, 68, 65, 87, 65, 68, 73, 32, 138, 1, 56, 8, + 82, 79, 83, 72, 84, 72, 73, 32, 143, 180, 21, 78, 136, 1, 220, 1, 4, 68, + 73, 71, 73, 20, 7, 76, 69, 84, 84, 69, 82, 32, 144, 2, 7, 78, 85, 77, 66, + 69, 82, 32, 36, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 136, + 2, 5, 83, 73, 71, 78, 32, 198, 1, 86, 207, 155, 8, 70, 8, 203, 193, 15, + 84, 74, 182, 1, 75, 42, 84, 150, 229, 6, 78, 250, 135, 11, 68, 170, 160, + 3, 83, 82, 66, 2, 67, 2, 71, 2, 80, 2, 86, 254, 68, 72, 2, 74, 2, 76, 2, + 77, 2, 82, 2, 89, 2, 90, 187, 2, 65, 6, 166, 211, 21, 72, 2, 75, 187, 2, + 65, 12, 182, 237, 17, 84, 202, 229, 3, 72, 187, 2, 65, 8, 146, 149, 14, + 84, 159, 151, 2, 79, 18, 70, 67, 74, 68, 66, 76, 36, 5, 77, 65, 78, 71, + 65, 175, 131, 20, 83, 4, 26, 82, 135, 133, 20, 73, 2, 177, 132, 19, 6, + 69, 83, 67, 69, 78, 84, 6, 26, 79, 191, 254, 11, 65, 4, 134, 254, 11, 85, + 179, 213, 9, 84, 4, 246, 188, 6, 79, 199, 168, 7, 73, 2, 179, 153, 20, + 76, 12, 72, 2, 66, 65, 22, 67, 20, 2, 68, 79, 162, 162, 19, 86, 223, 234, + 1, 65, 2, 155, 213, 20, 82, 2, 255, 243, 5, 65, 4, 56, 8, 85, 66, 76, 69, + 32, 82, 73, 78, 203, 170, 19, 84, 2, 199, 170, 19, 71, 14, 44, 5, 79, 87, + 69, 76, 32, 243, 158, 19, 73, 12, 44, 5, 83, 73, 71, 78, 32, 203, 142, + 21, 76, 10, 242, 237, 3, 86, 198, 226, 17, 69, 2, 73, 2, 79, 3, 85, 174, + 7, 72, 12, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 175, 167, 7, + 70, 172, 7, 22, 66, 147, 1, 67, 128, 4, 146, 214, 7, 48, 2, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, 68, + 2, 69, 3, 70, 172, 3, 122, 68, 138, 212, 7, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 3, 67, 12, 254, 204, + 21, 48, 2, 49, 2, 50, 2, 51, 2, 52, 3, 53, 246, 2, 202, 1, 67, 240, 2, + 18, 73, 78, 68, 69, 80, 69, 78, 68, 69, 78, 84, 32, 86, 79, 87, 69, 76, + 32, 220, 2, 7, 76, 69, 84, 84, 69, 82, 32, 254, 2, 83, 208, 12, 6, 86, + 79, 87, 69, 76, 32, 195, 199, 19, 68, 70, 176, 1, 20, 79, 78, 83, 79, 78, + 65, 78, 84, 32, 83, 73, 71, 78, 32, 67, 79, 69, 78, 71, 32, 233, 232, 16, + 17, 85, 82, 82, 69, 78, 67, 89, 32, 83, 89, 77, 66, 79, 76, 32, 82, 73, + 68, 138, 1, 78, 154, 4, 67, 2, 75, 90, 80, 74, 84, 54, 68, 2, 76, 198, + 250, 20, 83, 146, 41, 77, 2, 82, 2, 86, 2, 89, 190, 28, 66, 3, 72, 8, + 190, 169, 21, 71, 2, 89, 246, 30, 65, 3, 79, 42, 82, 81, 196, 1, 11, 83, + 73, 71, 78, 32, 67, 79, 69, 78, 71, 32, 50, 76, 3, 82, 26, 82, 65, 44, 6, + 79, 79, 32, 84, 89, 80, 34, 85, 198, 191, 19, 73, 207, 134, 2, 69, 8, + 218, 198, 21, 65, 2, 73, 2, 81, 3, 85, 4, 11, 69, 4, 159, 231, 9, 32, 9, + 214, 152, 7, 85, 187, 173, 14, 75, 8, 18, 81, 31, 82, 4, 214, 197, 21, + 69, 3, 85, 4, 195, 210, 17, 89, 70, 138, 1, 67, 2, 75, 42, 78, 50, 80, + 30, 83, 46, 84, 54, 68, 2, 76, 214, 163, 21, 77, 2, 82, 2, 86, 2, 89, + 190, 28, 66, 2, 72, 3, 81, 8, 210, 1, 72, 202, 194, 21, 65, 3, 79, 8, + 254, 164, 21, 71, 2, 78, 2, 89, 247, 30, 79, 6, 122, 72, 203, 194, 21, + 79, 6, 178, 164, 21, 83, 190, 28, 72, 187, 2, 65, 12, 50, 72, 0, 2, 84, + 72, 202, 194, 21, 65, 3, 79, 4, 198, 194, 21, 65, 3, 79, 130, 1, 60, 4, + 73, 71, 78, 32, 221, 6, 6, 89, 77, 66, 79, 76, 32, 46, 202, 2, 65, 104, + 10, 83, 65, 77, 89, 79, 75, 32, 83, 65, 78, 22, 66, 118, 67, 86, 75, 74, + 82, 54, 84, 244, 191, 4, 3, 76, 69, 75, 244, 10, 6, 80, 72, 78, 65, 69, + 75, 180, 204, 11, 11, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 152, + 97, 3, 78, 73, 75, 244, 251, 2, 9, 77, 85, 85, 83, 73, 75, 65, 84, 79, + 249, 13, 4, 86, 73, 82, 73, 6, 100, 9, 86, 65, 75, 82, 65, 72, 65, 83, + 65, 152, 189, 17, 4, 84, 84, 72, 65, 153, 220, 3, 2, 72, 83, 2, 215, 187, + 21, 78, 8, 38, 65, 209, 180, 20, 3, 69, 89, 89, 6, 174, 6, 84, 216, 1, 2, + 78, 84, 189, 238, 19, 6, 82, 73, 89, 79, 79, 83, 4, 224, 244, 6, 12, 65, + 77, 78, 85, 67, 32, 80, 73, 73, 32, 75, 85, 155, 140, 12, 79, 6, 188, + 163, 11, 2, 65, 75, 230, 209, 8, 72, 245, 77, 4, 79, 79, 77, 85, 4, 130, + 163, 11, 79, 133, 208, 5, 4, 69, 65, 72, 77, 4, 136, 168, 20, 8, 79, 65, + 78, 68, 65, 75, 72, 73, 253, 2, 4, 82, 73, 73, 83, 84, 128, 1, 3, 68, 65, + 80, 92, 10, 76, 69, 75, 32, 65, 84, 84, 65, 75, 32, 182, 1, 80, 72, 5, + 84, 85, 84, 69, 89, 78, 66, 47, 77, 24, 22, 45, 223, 3, 32, 20, 30, 80, + 238, 2, 66, 47, 77, 8, 138, 3, 73, 37, 3, 82, 65, 77, 20, 50, 80, 98, 66, + 130, 221, 10, 77, 187, 139, 10, 83, 12, 36, 3, 82, 65, 77, 251, 164, 21, + 73, 11, 11, 45, 8, 42, 66, 130, 221, 10, 77, 255, 158, 8, 80, 4, 182, + 232, 20, 85, 139, 60, 69, 26, 44, 2, 65, 84, 44, 3, 82, 65, 77, 91, 73, + 2, 21, 3, 72, 65, 77, 2, 223, 237, 15, 65, 20, 18, 45, 119, 32, 16, 34, + 66, 32, 2, 80, 73, 15, 77, 8, 30, 69, 37, 3, 85, 79, 78, 4, 35, 73, 4, + 21, 3, 85, 79, 89, 4, 11, 32, 4, 34, 82, 229, 128, 21, 2, 75, 79, 2, 143, + 143, 20, 79, 42, 76, 10, 73, 78, 72, 69, 82, 69, 78, 84, 32, 65, 29, 5, + 83, 73, 71, 78, 32, 4, 138, 181, 21, 65, 3, 81, 38, 102, 65, 54, 73, 30, + 79, 38, 89, 180, 228, 2, 5, 67, 79, 69, 78, 71, 250, 150, 7, 85, 235, + 183, 11, 69, 10, 218, 142, 3, 65, 174, 165, 18, 69, 2, 73, 3, 85, 7, 210, + 179, 21, 69, 3, 73, 6, 182, 179, 21, 69, 2, 77, 3, 79, 7, 146, 179, 21, + 65, 3, 89, 130, 1, 146, 1, 68, 88, 7, 76, 69, 84, 84, 69, 82, 32, 170, 2, + 83, 164, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 226, 156, 15, + 87, 219, 80, 65, 6, 48, 6, 79, 85, 66, 76, 69, 32, 179, 220, 11, 65, 4, + 166, 248, 9, 83, 255, 227, 1, 68, 90, 234, 1, 83, 130, 5, 66, 42, 71, + 246, 230, 5, 68, 222, 137, 4, 74, 214, 208, 7, 65, 82, 84, 222, 225, 1, + 76, 246, 189, 1, 78, 126, 67, 2, 75, 2, 80, 254, 68, 72, 2, 77, 2, 81, 2, + 82, 2, 86, 2, 89, 186, 2, 69, 2, 73, 2, 79, 3, 85, 4, 26, 72, 131, 175, + 21, 65, 2, 249, 238, 20, 3, 79, 82, 84, 12, 40, 4, 73, 71, 78, 32, 191, + 245, 9, 69, 10, 58, 83, 138, 205, 15, 86, 170, 251, 1, 78, 223, 160, 3, + 65, 4, 26, 72, 243, 222, 16, 85, 2, 11, 65, 2, 203, 136, 21, 68, 18, 246, + 202, 3, 86, 238, 253, 13, 65, 142, 222, 1, 73, 206, 134, 2, 69, 2, 79, 3, + 85, 138, 1, 100, 7, 76, 69, 84, 84, 69, 82, 32, 216, 2, 5, 83, 73, 71, + 78, 32, 170, 236, 15, 86, 227, 206, 3, 68, 94, 222, 1, 66, 42, 71, 42, + 74, 206, 230, 5, 68, 230, 162, 11, 82, 206, 55, 65, 82, 84, 230, 24, 85, + 210, 200, 1, 73, 158, 190, 1, 78, 126, 67, 2, 75, 2, 80, 2, 83, 254, 68, + 72, 2, 76, 2, 77, 2, 86, 2, 89, 186, 2, 69, 3, 79, 6, 226, 167, 21, 66, + 2, 72, 187, 2, 65, 6, 186, 167, 21, 71, 2, 72, 187, 2, 65, 6, 146, 167, + 21, 72, 2, 74, 187, 2, 65, 6, 178, 200, 15, 86, 170, 251, 1, 78, 223, + 160, 3, 65, 20, 92, 2, 83, 83, 140, 245, 19, 4, 87, 73, 70, 82, 158, 44, + 80, 216, 93, 2, 77, 79, 191, 18, 84, 13, 40, 4, 73, 78, 71, 32, 187, 230, + 20, 32, 8, 96, 4, 70, 65, 67, 69, 209, 212, 13, 14, 67, 65, 84, 32, 70, + 65, 67, 69, 32, 87, 73, 84, 72, 32, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, + 198, 211, 13, 83, 115, 67, 4, 236, 210, 14, 3, 69, 69, 76, 167, 183, 6, + 79, 4, 40, 4, 82, 69, 65, 78, 207, 131, 21, 65, 2, 33, 6, 32, 83, 84, 65, + 78, 68, 2, 129, 141, 18, 2, 65, 82, 2, 11, 79, 2, 155, 253, 9, 78, 128, + 41, 154, 1, 65, 190, 216, 1, 69, 242, 56, 73, 230, 83, 79, 146, 22, 85, + 94, 89, 182, 206, 7, 82, 168, 249, 8, 5, 32, 66, 32, 66, 65, 174, 157, 1, + 76, 227, 66, 70, 130, 22, 182, 1, 66, 44, 6, 67, 82, 79, 83, 83, 69, 46, + 68, 56, 2, 79, 32, 222, 11, 82, 208, 6, 4, 83, 84, 32, 81, 76, 4, 84, 73, + 78, 32, 161, 168, 19, 8, 78, 71, 85, 65, 71, 69, 32, 84, 4, 212, 131, 14, + 2, 32, 67, 183, 149, 6, 69, 2, 153, 173, 16, 6, 32, 83, 84, 73, 67, 75, + 4, 184, 192, 12, 5, 89, 32, 66, 69, 69, 183, 163, 8, 68, 174, 1, 200, 2, + 3, 72, 79, 32, 28, 7, 76, 69, 84, 84, 69, 82, 32, 214, 5, 83, 148, 1, 9, + 84, 79, 78, 69, 32, 77, 65, 73, 32, 84, 11, 86, 79, 87, 69, 76, 32, 83, + 73, 71, 78, 32, 128, 137, 4, 2, 75, 79, 188, 211, 12, 2, 89, 65, 162, + 157, 2, 69, 250, 46, 68, 248, 132, 1, 7, 67, 65, 78, 67, 69, 76, 76, 205, + 68, 6, 78, 73, 71, 71, 65, 72, 4, 210, 255, 20, 77, 3, 78, 94, 176, 1, 3, + 70, 79, 32, 78, 75, 96, 2, 76, 79, 50, 80, 154, 1, 83, 86, 84, 30, 72, + 206, 212, 15, 78, 214, 165, 5, 66, 2, 67, 2, 68, 2, 77, 2, 82, 2, 87, 2, + 89, 247, 30, 79, 8, 42, 70, 206, 235, 14, 83, 199, 247, 4, 84, 4, 246, + 204, 20, 79, 143, 62, 65, 10, 26, 72, 147, 156, 21, 79, 8, 32, 3, 77, 85, + 32, 231, 2, 79, 4, 182, 195, 20, 78, 195, 57, 71, 7, 17, 2, 32, 76, 4, + 202, 202, 20, 73, 67, 79, 30, 52, 4, 65, 76, 73, 32, 210, 1, 72, 151, + 153, 21, 79, 24, 190, 165, 6, 68, 34, 84, 206, 6, 78, 254, 246, 12, 66, + 2, 67, 2, 71, 2, 74, 167, 213, 1, 76, 8, 52, 9, 65, 78, 83, 75, 82, 73, + 84, 32, 83, 71, 79, 4, 146, 151, 21, 72, 3, 83, 6, 26, 72, 151, 153, 21, + 79, 4, 11, 79, 4, 11, 32, 4, 250, 231, 14, 83, 199, 247, 4, 84, 6, 112, + 14, 69, 77, 73, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 137, 147, 3, + 8, 73, 71, 78, 32, 80, 65, 76, 73, 4, 174, 191, 20, 78, 195, 57, 76, 8, + 50, 84, 252, 209, 16, 2, 67, 65, 255, 193, 4, 69, 4, 154, 248, 20, 72, + 247, 30, 73, 32, 106, 65, 44, 5, 77, 65, 73, 32, 75, 226, 162, 17, 89, + 222, 35, 85, 210, 200, 1, 69, 2, 73, 207, 134, 2, 79, 11, 130, 150, 21, + 65, 2, 73, 2, 77, 3, 89, 4, 130, 198, 20, 65, 3, 79, 56, 32, 2, 71, 69, + 179, 142, 20, 73, 54, 26, 32, 231, 188, 13, 82, 50, 254, 1, 66, 44, 4, + 71, 82, 69, 69, 22, 79, 250, 1, 84, 186, 180, 11, 68, 36, 2, 85, 80, 168, + 180, 3, 12, 76, 69, 70, 84, 32, 84, 82, 73, 65, 78, 71, 76, 224, 151, 4, + 5, 80, 85, 82, 80, 76, 12, 3, 82, 69, 68, 0, 6, 89, 69, 76, 76, 79, 87, + 207, 64, 67, 10, 40, 3, 82, 79, 87, 201, 1, 2, 76, 85, 4, 251, 130, 19, + 78, 10, 48, 3, 78, 69, 32, 129, 1, 4, 82, 65, 78, 71, 4, 200, 248, 7, 5, + 68, 79, 84, 32, 79, 173, 221, 2, 18, 82, 73, 78, 71, 32, 79, 86, 69, 82, + 32, 84, 87, 79, 32, 82, 73, 78, 71, 6, 11, 69, 6, 11, 32, 6, 230, 193, + 19, 67, 226, 19, 68, 231, 26, 83, 6, 104, 3, 87, 79, 32, 161, 229, 17, + 17, 82, 73, 80, 76, 69, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, + 4, 162, 162, 17, 68, 205, 64, 19, 82, 73, 78, 71, 83, 32, 79, 86, 69, 82, + 32, 79, 78, 69, 32, 82, 73, 78, 71, 6, 53, 11, 85, 65, 82, 84, 69, 82, + 32, 77, 79, 79, 78, 7, 167, 220, 6, 32, 138, 20, 150, 1, 67, 244, 45, 18, + 69, 80, 73, 71, 82, 65, 80, 72, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, + 252, 1, 7, 76, 69, 84, 84, 69, 82, 32, 183, 13, 83, 192, 7, 56, 8, 65, + 80, 73, 84, 65, 76, 32, 76, 239, 206, 19, 82, 190, 7, 76, 6, 69, 84, 84, + 69, 82, 32, 189, 44, 8, 73, 71, 65, 84, 85, 82, 69, 32, 186, 7, 154, 2, + 65, 158, 3, 66, 154, 1, 67, 254, 1, 68, 250, 1, 69, 174, 2, 70, 82, 71, + 194, 1, 72, 146, 1, 73, 154, 2, 74, 118, 75, 126, 76, 222, 2, 77, 114, + 78, 134, 2, 79, 198, 2, 80, 102, 81, 62, 82, 174, 2, 83, 254, 2, 84, 142, + 3, 85, 234, 1, 86, 146, 1, 87, 118, 88, 50, 89, 167, 1, 90, 93, 172, 1, + 6, 32, 87, 73, 84, 72, 32, 166, 1, 69, 182, 65, 78, 166, 209, 4, 76, 236, + 154, 9, 6, 70, 82, 73, 67, 65, 78, 178, 136, 4, 86, 138, 209, 2, 65, 2, + 79, 2, 85, 3, 89, 66, 182, 64, 66, 34, 68, 108, 3, 82, 73, 78, 242, 33, + 77, 254, 21, 67, 146, 49, 72, 158, 1, 79, 198, 10, 71, 186, 2, 65, 206, + 156, 3, 73, 214, 241, 12, 84, 175, 145, 3, 83, 7, 33, 6, 32, 87, 73, 84, + 72, 32, 4, 142, 183, 1, 65, 183, 182, 3, 77, 21, 60, 6, 32, 87, 73, 84, + 72, 32, 254, 67, 82, 175, 157, 20, 69, 14, 218, 66, 84, 146, 60, 70, 202, + 56, 76, 134, 224, 15, 68, 222, 157, 2, 72, 231, 160, 1, 83, 33, 108, 6, + 32, 87, 73, 84, 72, 32, 140, 70, 7, 76, 79, 83, 69, 68, 32, 73, 54, 85, + 154, 238, 19, 79, 255, 59, 72, 20, 94, 67, 134, 180, 1, 65, 222, 215, 3, + 80, 142, 167, 14, 72, 186, 46, 66, 246, 33, 68, 187, 80, 83, 8, 134, 68, + 69, 190, 112, 73, 255, 170, 18, 65, 31, 44, 6, 32, 87, 73, 84, 72, 32, + 179, 1, 90, 24, 78, 83, 182, 15, 67, 214, 47, 84, 218, 116, 76, 134, 224, + 15, 68, 223, 157, 2, 72, 8, 92, 13, 77, 65, 76, 76, 32, 76, 69, 84, 84, + 69, 82, 32, 90, 246, 136, 1, 72, 223, 200, 19, 84, 5, 177, 72, 2, 32, 87, + 91, 104, 6, 32, 87, 73, 84, 72, 32, 152, 1, 2, 90, 72, 134, 76, 71, 194, + 191, 16, 84, 210, 242, 3, 83, 63, 78, 70, 254, 73, 67, 158, 2, 68, 194, + 16, 84, 162, 23, 77, 250, 1, 86, 234, 44, 72, 158, 1, 79, 198, 10, 71, + 186, 2, 65, 206, 156, 3, 73, 62, 66, 199, 130, 16, 83, 7, 11, 32, 4, 138, + 70, 87, 211, 8, 82, 9, 33, 6, 32, 87, 73, 84, 72, 32, 6, 246, 173, 19, + 72, 174, 80, 68, 187, 80, 83, 35, 76, 6, 32, 87, 73, 84, 72, 32, 190, 81, + 76, 138, 225, 17, 65, 227, 200, 2, 72, 20, 154, 84, 67, 250, 89, 65, 138, + 157, 3, 66, 174, 25, 77, 142, 133, 4, 79, 170, 195, 10, 72, 174, 80, 68, + 187, 80, 83, 29, 76, 6, 32, 87, 73, 84, 72, 32, 138, 126, 65, 238, 218, + 7, 87, 191, 210, 11, 69, 20, 186, 82, 66, 34, 67, 46, 68, 182, 216, 18, + 72, 231, 160, 1, 83, 59, 80, 6, 32, 87, 73, 84, 72, 32, 132, 88, 2, 78, + 83, 186, 254, 19, 79, 207, 36, 83, 40, 138, 1, 68, 162, 83, 67, 242, 1, + 77, 142, 1, 84, 130, 70, 72, 158, 1, 79, 198, 10, 71, 186, 2, 65, 206, + 156, 3, 73, 62, 66, 199, 130, 16, 83, 10, 22, 79, 191, 83, 73, 6, 234, + 120, 85, 155, 232, 17, 84, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 42, 67, + 206, 183, 17, 84, 175, 145, 3, 83, 4, 234, 169, 1, 73, 199, 205, 3, 82, + 25, 33, 6, 32, 87, 73, 84, 72, 32, 22, 182, 89, 67, 34, 68, 50, 83, 222, + 78, 65, 138, 1, 76, 186, 186, 7, 79, 171, 195, 10, 72, 37, 48, 6, 32, 87, + 73, 84, 72, 32, 163, 247, 20, 74, 32, 138, 1, 66, 36, 2, 68, 79, 52, 7, + 77, 73, 68, 68, 76, 69, 32, 38, 83, 174, 2, 67, 198, 91, 72, 226, 71, 65, + 138, 1, 76, 155, 141, 16, 84, 4, 246, 151, 12, 69, 207, 165, 8, 65, 6, + 22, 85, 135, 92, 84, 2, 205, 223, 4, 2, 66, 76, 4, 146, 180, 17, 84, 255, + 240, 2, 68, 4, 214, 2, 77, 211, 194, 20, 84, 19, 44, 6, 32, 87, 73, 84, + 72, 32, 223, 94, 73, 10, 254, 164, 1, 65, 142, 225, 15, 68, 150, 45, 84, + 203, 240, 1, 72, 33, 48, 6, 32, 87, 73, 84, 72, 32, 215, 243, 20, 74, 28, + 102, 67, 44, 2, 83, 77, 194, 96, 76, 130, 64, 71, 186, 2, 65, 102, 68, + 222, 186, 7, 79, 227, 210, 8, 84, 6, 202, 131, 1, 69, 22, 73, 131, 203, + 18, 65, 2, 249, 194, 10, 10, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 101, + 108, 6, 32, 87, 73, 84, 72, 32, 194, 103, 76, 202, 140, 4, 80, 150, 253, + 8, 77, 250, 255, 6, 73, 2, 79, 3, 85, 84, 144, 1, 2, 76, 79, 34, 77, 242, + 96, 67, 70, 68, 154, 2, 79, 38, 83, 66, 84, 106, 86, 218, 43, 72, 242, + 12, 71, 186, 2, 65, 206, 156, 3, 73, 63, 66, 4, 174, 99, 78, 199, 140, + 20, 79, 8, 170, 99, 65, 171, 141, 4, 73, 17, 33, 6, 32, 87, 73, 84, 72, + 32, 14, 146, 104, 70, 34, 83, 162, 55, 65, 234, 254, 17, 72, 175, 80, 68, + 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 230, 104, 68, 39, 83, 41, 78, 32, + 156, 1, 8, 69, 86, 69, 82, 83, 69, 68, 32, 145, 111, 3, 85, 77, 32, 28, + 40, 5, 87, 73, 84, 72, 32, 143, 112, 82, 26, 174, 78, 67, 234, 28, 68, + 170, 2, 84, 158, 48, 65, 138, 1, 76, 198, 155, 3, 73, 246, 158, 4, 79, + 143, 228, 11, 83, 8, 146, 110, 72, 218, 138, 4, 79, 162, 246, 12, 67, + 171, 253, 2, 69, 47, 136, 1, 6, 32, 87, 73, 84, 72, 32, 132, 1, 5, 77, + 65, 76, 76, 32, 156, 115, 2, 65, 76, 234, 1, 72, 152, 2, 2, 73, 71, 235, + 248, 3, 67, 30, 82, 67, 194, 111, 65, 118, 68, 126, 83, 174, 1, 86, 178, + 227, 7, 79, 171, 195, 10, 72, 10, 154, 112, 65, 218, 10, 69, 82, 79, 203, + 31, 73, 4, 200, 188, 18, 11, 81, 32, 87, 73, 84, 72, 32, 72, 79, 79, 75, + 149, 237, 1, 7, 67, 65, 80, 73, 84, 65, 76, 59, 136, 1, 6, 32, 87, 73, + 84, 72, 32, 168, 1, 6, 85, 82, 78, 69, 68, 32, 232, 122, 2, 72, 79, 176, + 1, 2, 79, 78, 74, 82, 231, 233, 19, 90, 22, 82, 67, 50, 68, 170, 152, 1, + 76, 186, 220, 3, 82, 170, 161, 14, 72, 231, 160, 1, 83, 8, 246, 119, 69, + 22, 73, 62, 79, 199, 202, 18, 65, 6, 234, 141, 1, 73, 207, 234, 15, 79, + 18, 162, 40, 73, 146, 249, 2, 65, 146, 197, 17, 72, 2, 75, 2, 76, 2, 77, + 2, 84, 3, 86, 79, 26, 32, 179, 245, 4, 80, 74, 44, 5, 87, 73, 84, 72, 32, + 251, 194, 19, 66, 72, 210, 131, 1, 67, 74, 68, 150, 2, 72, 170, 1, 77, + 134, 1, 79, 142, 1, 84, 186, 9, 71, 186, 2, 65, 206, 156, 3, 73, 62, 66, + 186, 136, 14, 82, 143, 250, 1, 83, 23, 88, 6, 32, 87, 73, 84, 72, 32, + 222, 138, 1, 73, 66, 79, 174, 202, 18, 69, 227, 141, 1, 89, 8, 142, 138, + 1, 68, 242, 151, 16, 84, 203, 240, 1, 72, 19, 48, 6, 32, 87, 73, 84, 72, + 32, 159, 132, 7, 89, 14, 234, 143, 1, 67, 18, 68, 70, 71, 186, 2, 65, + 235, 254, 17, 72, 7, 245, 139, 1, 7, 32, 87, 73, 84, 72, 32, 68, 29, 48, + 6, 32, 87, 73, 84, 72, 32, 147, 233, 16, 79, 24, 198, 142, 1, 67, 18, 68, + 70, 71, 22, 72, 42, 76, 254, 1, 65, 182, 182, 3, 77, 238, 215, 12, 84, + 175, 145, 3, 83, 25, 33, 6, 32, 87, 73, 84, 72, 32, 22, 170, 57, 67, 150, + 87, 65, 102, 68, 38, 76, 34, 83, 182, 214, 3, 80, 143, 167, 14, 72, 4, + 250, 175, 10, 73, 231, 152, 10, 79, 12, 128, 1, 5, 65, 82, 67, 72, 65, + 30, 73, 64, 9, 82, 69, 86, 69, 82, 83, 69, 68, 32, 197, 173, 10, 7, 83, + 73, 68, 69, 87, 65, 89, 2, 213, 199, 13, 2, 73, 67, 4, 136, 107, 5, 78, + 86, 69, 82, 84, 149, 156, 14, 3, 32, 76, 79, 4, 174, 221, 20, 70, 3, 80, + 138, 1, 198, 3, 65, 36, 2, 66, 73, 152, 1, 21, 73, 78, 86, 69, 82, 84, + 69, 68, 32, 71, 76, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 72, 2, 82, + 69, 222, 1, 83, 162, 28, 87, 132, 33, 3, 84, 87, 79, 204, 246, 3, 2, 68, + 69, 140, 5, 2, 76, 65, 206, 11, 71, 248, 174, 1, 21, 80, 72, 65, 82, 89, + 78, 71, 69, 65, 76, 32, 86, 79, 73, 67, 69, 68, 32, 70, 82, 73, 192, 181, + 13, 20, 86, 79, 73, 67, 69, 68, 32, 76, 65, 82, 89, 78, 71, 69, 65, 76, + 32, 83, 80, 73, 155, 116, 89, 4, 150, 169, 4, 76, 223, 224, 15, 73, 6, + 76, 7, 76, 65, 66, 73, 65, 76, 32, 29, 8, 68, 69, 78, 84, 65, 76, 32, 80, + 4, 26, 80, 143, 188, 4, 67, 2, 153, 208, 15, 6, 69, 82, 67, 85, 83, 83, + 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 134, 225, 4, 67, 231, 198, 15, 83, + 8, 104, 7, 86, 69, 82, 83, 69, 68, 32, 149, 225, 4, 13, 84, 82, 79, 70, + 76, 69, 88, 32, 67, 76, 73, 67, 75, 4, 80, 3, 69, 83, 72, 193, 61, 12, + 71, 76, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 2, 189, 132, 1, 2, 32, + 76, 96, 172, 1, 13, 77, 65, 76, 76, 32, 67, 65, 80, 73, 84, 65, 76, 32, + 220, 111, 10, 84, 82, 69, 84, 67, 72, 69, 68, 32, 67, 225, 211, 18, 10, + 73, 78, 79, 76, 79, 71, 73, 67, 65, 76, 90, 230, 1, 69, 30, 73, 22, 76, + 74, 79, 42, 82, 122, 84, 186, 164, 4, 66, 202, 41, 71, 166, 194, 15, 65, + 150, 64, 67, 2, 68, 2, 70, 2, 72, 2, 74, 2, 75, 2, 77, 2, 78, 2, 80, 2, + 81, 2, 83, 2, 85, 2, 86, 2, 87, 2, 89, 3, 90, 7, 190, 209, 20, 84, 3, 90, + 5, 191, 201, 4, 78, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 198, 199, 8, 66, + 187, 218, 11, 83, 9, 214, 94, 80, 130, 243, 19, 69, 3, 85, 11, 88, 8, 69, + 86, 69, 82, 83, 69, 68, 32, 216, 127, 5, 32, 87, 73, 84, 72, 167, 192, + 19, 85, 4, 210, 208, 20, 78, 3, 82, 13, 33, 6, 85, 82, 78, 69, 68, 32, + 10, 146, 208, 20, 69, 2, 71, 2, 75, 2, 77, 3, 82, 180, 11, 136, 1, 5, 77, + 65, 76, 76, 32, 253, 129, 1, 22, 85, 66, 83, 67, 82, 73, 80, 84, 32, 83, + 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 144, 11, 76, 15, 67, 65, + 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, 27, 76, 4, 182, 53, + 73, 3, 85, 140, 11, 76, 6, 69, 84, 84, 69, 82, 32, 161, 127, 8, 73, 71, + 65, 84, 85, 82, 69, 32, 250, 10, 182, 2, 65, 190, 5, 66, 198, 3, 67, 186, + 4, 68, 182, 4, 69, 174, 9, 70, 214, 1, 71, 162, 2, 72, 230, 2, 73, 166, + 7, 74, 182, 1, 75, 178, 2, 76, 210, 6, 77, 178, 2, 78, 218, 3, 79, 242, + 8, 80, 230, 1, 81, 174, 1, 82, 142, 8, 83, 234, 10, 84, 246, 13, 85, 218, + 9, 86, 130, 3, 87, 110, 88, 226, 2, 89, 171, 3, 90, 101, 118, 32, 198, 3, + 69, 82, 78, 132, 208, 4, 4, 76, 80, 72, 65, 190, 164, 13, 86, 138, 209, + 2, 65, 2, 79, 2, 85, 3, 89, 72, 88, 5, 87, 73, 84, 72, 32, 209, 209, 5, + 11, 82, 69, 86, 69, 82, 83, 69, 68, 45, 83, 67, 70, 150, 1, 66, 34, 68, + 54, 82, 170, 34, 77, 254, 21, 67, 146, 49, 72, 158, 1, 79, 198, 10, 71, + 186, 2, 65, 206, 156, 3, 73, 214, 241, 12, 84, 175, 145, 3, 83, 12, 161, + 105, 4, 82, 69, 86, 69, 12, 22, 79, 155, 57, 73, 8, 218, 57, 84, 223, 12, + 85, 10, 26, 73, 255, 212, 4, 69, 8, 26, 78, 131, 156, 4, 71, 6, 17, 2, + 71, 32, 6, 240, 58, 4, 65, 66, 79, 86, 159, 243, 17, 66, 9, 33, 6, 32, + 87, 73, 84, 72, 32, 6, 242, 115, 71, 186, 2, 65, 183, 182, 3, 77, 2, 133, + 160, 10, 7, 71, 76, 73, 67, 65, 78, 65, 41, 140, 1, 6, 32, 87, 73, 84, + 72, 32, 130, 1, 65, 108, 11, 76, 65, 67, 75, 76, 69, 84, 84, 69, 82, 32, + 38, 82, 242, 182, 4, 79, 191, 230, 15, 69, 18, 110, 84, 146, 60, 70, 202, + 56, 76, 170, 207, 3, 77, 174, 7, 80, 178, 137, 12, 68, 222, 157, 2, 72, + 231, 160, 1, 83, 2, 255, 7, 79, 8, 64, 5, 82, 82, 69, 68, 32, 161, 80, 6, + 83, 69, 76, 73, 78, 69, 6, 182, 32, 65, 142, 162, 20, 69, 3, 79, 6, 186, + 177, 4, 79, 227, 144, 16, 69, 2, 133, 148, 10, 4, 79, 75, 69, 78, 47, + 108, 6, 32, 87, 73, 84, 72, 32, 196, 1, 2, 72, 73, 92, 6, 76, 79, 83, 69, + 68, 32, 90, 85, 155, 238, 19, 79, 24, 102, 67, 182, 112, 65, 222, 215, 3, + 80, 230, 5, 82, 170, 161, 14, 72, 186, 46, 66, 246, 33, 68, 187, 80, 83, + 10, 54, 69, 190, 112, 73, 238, 225, 6, 85, 147, 201, 11, 65, 4, 249, 51, + 5, 68, 73, 76, 76, 65, 7, 49, 10, 32, 87, 73, 84, 72, 32, 76, 79, 87, 32, + 4, 162, 106, 82, 45, 4, 76, 69, 70, 84, 8, 34, 73, 18, 79, 227, 181, 4, + 82, 2, 163, 87, 78, 4, 210, 202, 4, 80, 199, 243, 8, 77, 4, 37, 7, 65, + 84, 82, 73, 76, 76, 79, 5, 153, 224, 12, 5, 32, 87, 73, 84, 72, 73, 96, + 6, 32, 87, 73, 84, 72, 32, 182, 1, 69, 34, 79, 178, 1, 90, 246, 194, 4, + 66, 235, 229, 15, 85, 32, 98, 83, 34, 84, 130, 33, 67, 206, 44, 77, 170, + 31, 76, 206, 199, 3, 72, 138, 15, 80, 179, 137, 12, 68, 4, 134, 67, 72, + 223, 200, 19, 84, 4, 26, 79, 167, 142, 18, 65, 2, 215, 235, 17, 80, 8, + 246, 77, 90, 195, 200, 19, 76, 16, 60, 6, 84, 76, 69, 83, 83, 32, 49, 5, + 85, 66, 76, 69, 32, 8, 26, 74, 139, 186, 20, 73, 7, 235, 179, 4, 32, 8, + 42, 87, 210, 183, 4, 82, 187, 219, 5, 84, 2, 163, 219, 6, 89, 11, 11, 32, + 8, 26, 87, 219, 179, 4, 68, 2, 169, 89, 5, 73, 84, 72, 32, 67, 119, 112, + 6, 32, 87, 73, 84, 72, 32, 214, 4, 71, 72, 2, 78, 71, 68, 2, 83, 72, 164, + 1, 2, 90, 72, 147, 189, 16, 84, 76, 182, 1, 67, 158, 2, 68, 110, 78, 214, + 15, 84, 162, 23, 77, 250, 1, 86, 194, 3, 70, 170, 41, 72, 158, 1, 79, + 198, 10, 71, 186, 2, 65, 206, 156, 3, 73, 62, 66, 186, 64, 82, 143, 194, + 15, 83, 24, 92, 6, 69, 68, 73, 76, 76, 65, 32, 9, 73, 82, 67, 85, 77, 70, + 76, 69, 88, 179, 145, 19, 65, 5, 129, 131, 4, 3, 32, 65, 78, 19, 11, 32, + 16, 40, 4, 65, 78, 68, 32, 207, 156, 18, 66, 14, 162, 85, 67, 130, 2, 72, + 226, 11, 71, 186, 2, 65, 182, 182, 3, 77, 190, 162, 4, 68, 179, 181, 8, + 84, 12, 22, 79, 227, 97, 73, 10, 28, 2, 84, 32, 243, 50, 85, 8, 192, 87, + 5, 65, 66, 79, 86, 69, 239, 195, 17, 66, 2, 183, 232, 13, 79, 4, 237, + 237, 6, 13, 89, 80, 84, 79, 76, 79, 71, 73, 67, 65, 76, 32, 65, 7, 33, 6, + 32, 87, 73, 84, 72, 32, 4, 226, 176, 4, 67, 231, 9, 80, 13, 33, 6, 32, + 87, 73, 84, 72, 32, 10, 88, 10, 68, 79, 85, 66, 76, 69, 32, 66, 65, 82, + 170, 185, 4, 80, 142, 1, 67, 219, 4, 82, 5, 157, 186, 4, 4, 32, 65, 78, + 68, 15, 11, 32, 12, 38, 82, 37, 5, 87, 73, 84, 72, 32, 2, 209, 228, 13, + 4, 69, 86, 69, 82, 10, 54, 67, 246, 183, 4, 80, 230, 5, 82, 139, 197, 13, + 84, 4, 194, 194, 7, 85, 147, 201, 11, 65, 17, 84, 6, 32, 87, 73, 84, 72, + 32, 73, 11, 69, 78, 71, 32, 68, 73, 71, 82, 65, 80, 72, 10, 202, 175, 4, + 77, 174, 7, 80, 142, 167, 14, 72, 174, 80, 68, 187, 80, 83, 5, 197, 189, + 17, 8, 32, 87, 73, 84, 72, 32, 84, 82, 37, 72, 6, 32, 87, 73, 84, 72, 32, + 126, 76, 138, 225, 17, 65, 227, 200, 2, 72, 22, 218, 3, 67, 250, 89, 65, + 138, 157, 3, 66, 174, 25, 77, 170, 33, 80, 230, 227, 3, 79, 170, 195, 10, + 72, 174, 80, 68, 187, 80, 83, 8, 33, 6, 79, 84, 84, 65, 76, 32, 8, 178, + 225, 17, 83, 202, 202, 2, 65, 2, 73, 3, 85, 39, 140, 1, 6, 32, 87, 73, + 84, 72, 32, 166, 44, 65, 216, 25, 12, 79, 79, 75, 69, 68, 32, 83, 67, 72, + 87, 65, 32, 242, 225, 3, 69, 207, 130, 16, 86, 24, 86, 66, 34, 67, 46, + 68, 214, 90, 76, 214, 214, 3, 80, 142, 167, 14, 72, 231, 160, 1, 83, 2, + 157, 229, 12, 3, 82, 69, 86, 6, 158, 58, 69, 154, 32, 73, 255, 170, 18, + 65, 8, 234, 86, 73, 178, 173, 3, 69, 203, 182, 12, 79, 75, 80, 6, 32, 87, + 73, 84, 72, 32, 222, 4, 78, 188, 1, 2, 79, 84, 251, 161, 20, 83, 48, 178, + 1, 67, 34, 68, 210, 1, 77, 64, 6, 79, 71, 79, 78, 69, 75, 78, 84, 130, + 70, 72, 226, 11, 71, 186, 2, 65, 206, 156, 3, 73, 62, 66, 136, 64, 6, 83, + 84, 82, 79, 75, 69, 51, 82, 4, 210, 87, 73, 255, 170, 18, 65, 14, 18, 73, + 47, 79, 4, 221, 26, 7, 65, 69, 82, 69, 83, 73, 83, 10, 28, 2, 84, 32, + 231, 36, 85, 8, 64, 10, 65, 66, 79, 86, 69, 32, 65, 78, 68, 32, 227, 140, + 18, 66, 6, 150, 83, 71, 186, 2, 65, 163, 142, 16, 84, 4, 29, 5, 65, 67, + 82, 79, 78, 5, 233, 35, 4, 32, 65, 78, 68, 7, 145, 72, 15, 32, 65, 78, + 68, 32, 68, 79, 84, 32, 65, 66, 79, 86, 69, 32, 4, 21, 3, 73, 76, 68, 4, + 171, 251, 4, 69, 16, 46, 83, 93, 7, 86, 69, 82, 84, 69, 68, 32, 12, 29, + 5, 85, 76, 65, 82, 32, 12, 226, 162, 20, 68, 2, 70, 2, 71, 2, 82, 2, 83, + 3, 84, 4, 26, 65, 187, 139, 20, 79, 2, 231, 173, 4, 76, 6, 150, 145, 4, + 65, 229, 162, 6, 5, 73, 70, 73, 69, 68, 13, 33, 6, 32, 87, 73, 84, 72, + 32, 10, 94, 67, 216, 161, 4, 13, 68, 79, 84, 32, 65, 66, 79, 86, 69, 32, + 65, 78, 68, 235, 206, 15, 83, 6, 178, 81, 73, 198, 205, 3, 82, 187, 221, + 14, 65, 29, 48, 6, 32, 87, 73, 84, 72, 32, 163, 157, 20, 82, 24, 98, 67, + 34, 68, 50, 83, 222, 78, 65, 138, 1, 76, 214, 214, 3, 80, 230, 227, 3, + 79, 171, 195, 10, 72, 4, 210, 47, 69, 151, 203, 18, 65, 6, 214, 69, 73, + 134, 180, 3, 69, 175, 174, 4, 79, 4, 29, 5, 84, 82, 79, 75, 69, 5, 177, + 24, 6, 32, 65, 78, 68, 32, 68, 77, 156, 1, 6, 32, 87, 73, 84, 72, 32, + 248, 3, 5, 65, 77, 66, 68, 65, 22, 69, 48, 5, 79, 78, 71, 32, 83, 194, + 161, 4, 83, 2, 90, 234, 229, 15, 85, 219, 16, 74, 50, 178, 1, 66, 86, 67, + 56, 2, 68, 79, 100, 3, 77, 73, 68, 242, 1, 72, 226, 71, 65, 138, 1, 76, + 218, 206, 3, 73, 162, 1, 82, 222, 2, 70, 130, 4, 80, 198, 182, 12, 84, + 175, 145, 3, 83, 6, 36, 3, 69, 76, 84, 147, 226, 19, 65, 5, 241, 162, 4, + 6, 32, 65, 78, 68, 32, 80, 8, 146, 43, 69, 22, 73, 242, 129, 7, 85, 147, + 201, 11, 65, 8, 38, 84, 25, 5, 85, 66, 76, 69, 32, 4, 137, 24, 2, 32, 66, + 4, 162, 154, 4, 77, 243, 220, 14, 66, 8, 36, 4, 68, 76, 69, 32, 187, 43, + 45, 6, 198, 215, 16, 84, 178, 240, 2, 82, 79, 68, 2, 139, 155, 4, 32, 6, + 222, 162, 4, 90, 161, 192, 12, 3, 78, 73, 83, 9, 33, 6, 32, 87, 73, 84, + 72, 32, 6, 18, 68, 35, 72, 4, 202, 62, 73, 215, 216, 18, 79, 2, 133, 154, + 4, 2, 73, 71, 27, 56, 6, 32, 87, 73, 84, 72, 32, 102, 73, 151, 133, 20, + 85, 16, 134, 71, 65, 250, 205, 3, 67, 186, 2, 77, 174, 7, 80, 178, 137, + 12, 68, 150, 45, 84, 203, 240, 1, 72, 6, 25, 4, 68, 68, 76, 69, 6, 76, 7, + 45, 87, 69, 76, 83, 72, 32, 141, 194, 16, 6, 32, 83, 67, 79, 84, 83, 4, + 226, 139, 19, 76, 159, 137, 1, 86, 49, 58, 32, 216, 2, 2, 71, 32, 242, + 128, 20, 85, 219, 16, 74, 40, 88, 5, 87, 73, 84, 72, 32, 193, 250, 5, 11, + 80, 82, 69, 67, 69, 68, 69, 68, 32, 66, 89, 38, 122, 67, 74, 76, 154, 36, + 77, 234, 27, 71, 186, 2, 65, 102, 68, 250, 214, 3, 80, 230, 5, 82, 130, + 222, 3, 79, 227, 210, 8, 84, 10, 166, 35, 69, 22, 73, 202, 237, 3, 82, + 170, 148, 3, 85, 147, 201, 11, 65, 6, 128, 65, 3, 79, 78, 71, 202, 2, 73, + 135, 222, 3, 69, 2, 25, 4, 87, 73, 84, 72, 2, 149, 131, 17, 5, 32, 84, + 73, 76, 68, 115, 116, 6, 32, 87, 73, 84, 72, 32, 186, 6, 76, 52, 4, 80, + 69, 78, 32, 170, 137, 13, 77, 250, 255, 6, 73, 2, 79, 3, 85, 86, 154, 1, + 67, 70, 68, 152, 1, 2, 76, 79, 86, 77, 46, 79, 38, 83, 66, 84, 106, 86, + 218, 43, 72, 242, 12, 71, 186, 2, 65, 206, 156, 3, 73, 62, 66, 187, 64, + 82, 14, 168, 48, 9, 73, 82, 67, 85, 77, 70, 76, 69, 88, 187, 186, 18, 65, + 14, 18, 73, 47, 79, 4, 233, 12, 7, 65, 69, 82, 69, 83, 73, 83, 10, 22, + 84, 167, 46, 85, 6, 11, 32, 6, 152, 12, 5, 65, 66, 79, 86, 69, 247, 232, + 17, 66, 6, 66, 78, 188, 162, 12, 6, 87, 32, 82, 73, 78, 71, 139, 234, 7, + 79, 2, 155, 20, 71, 6, 11, 65, 6, 189, 2, 4, 67, 82, 79, 78, 4, 229, 10, + 5, 71, 79, 78, 69, 75, 4, 25, 4, 84, 82, 79, 75, 4, 11, 69, 5, 209, 48, + 2, 32, 65, 8, 25, 4, 73, 76, 68, 69, 9, 29, 5, 32, 65, 78, 68, 32, 6, + 158, 46, 68, 142, 13, 65, 183, 182, 3, 77, 6, 81, 18, 69, 82, 84, 73, 67, + 65, 76, 32, 76, 73, 78, 69, 32, 66, 69, 76, 79, 87, 7, 217, 42, 4, 32, + 65, 78, 68, 2, 229, 225, 9, 8, 68, 32, 80, 79, 76, 73, 83, 72, 16, 26, + 79, 195, 147, 4, 69, 13, 48, 6, 32, 87, 73, 84, 72, 32, 211, 136, 20, 69, + 8, 206, 54, 71, 186, 2, 65, 194, 221, 3, 82, 143, 194, 15, 83, 23, 48, 6, + 32, 87, 73, 84, 72, 32, 139, 244, 19, 72, 18, 86, 70, 34, 83, 162, 55, + 65, 178, 208, 3, 77, 174, 7, 80, 142, 167, 14, 72, 175, 80, 68, 2, 181, + 135, 14, 3, 76, 79, 85, 6, 202, 27, 84, 185, 130, 12, 6, 81, 85, 73, 82, + 82, 69, 13, 48, 6, 32, 87, 73, 84, 72, 32, 191, 143, 4, 80, 8, 42, 68, + 16, 4, 72, 79, 79, 75, 23, 83, 2, 211, 44, 73, 5, 179, 216, 17, 32, 2, + 181, 26, 6, 84, 82, 79, 75, 69, 32, 77, 90, 32, 228, 4, 8, 69, 86, 69, + 82, 83, 69, 68, 32, 148, 2, 2, 85, 77, 231, 129, 4, 65, 46, 36, 4, 87, + 73, 84, 72, 235, 6, 82, 44, 26, 32, 219, 253, 14, 79, 42, 166, 1, 67, 50, + 68, 200, 1, 8, 70, 73, 83, 72, 72, 79, 79, 75, 66, 76, 34, 84, 254, 17, + 77, 162, 30, 65, 206, 156, 3, 73, 146, 59, 80, 230, 227, 3, 79, 143, 228, + 11, 83, 6, 154, 19, 69, 222, 237, 3, 82, 187, 221, 14, 65, 8, 11, 79, 8, + 24, 2, 84, 32, 111, 85, 6, 26, 66, 239, 132, 19, 65, 4, 25, 4, 69, 76, + 79, 87, 5, 29, 5, 32, 65, 78, 68, 32, 2, 247, 231, 3, 77, 2, 21, 3, 66, + 76, 69, 2, 11, 32, 2, 211, 46, 71, 7, 29, 5, 32, 65, 78, 68, 32, 4, 138, + 129, 4, 77, 175, 7, 80, 4, 206, 49, 73, 211, 218, 3, 79, 4, 238, 210, 17, + 65, 251, 22, 73, 22, 162, 1, 72, 40, 6, 79, 80, 69, 78, 32, 69, 140, 130, + 4, 8, 82, 32, 87, 73, 84, 72, 32, 70, 168, 2, 3, 83, 67, 82, 218, 129, + 14, 69, 198, 84, 67, 171, 163, 1, 75, 2, 11, 65, 2, 189, 213, 9, 2, 76, + 70, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 202, 139, 4, 82, 171, 161, 14, + 72, 5, 11, 32, 2, 11, 82, 2, 153, 168, 10, 3, 79, 84, 85, 83, 180, 1, 6, + 32, 87, 73, 84, 72, 32, 202, 4, 65, 66, 67, 218, 1, 72, 34, 73, 156, 2, + 13, 81, 85, 65, 84, 32, 82, 69, 86, 69, 82, 83, 69, 68, 173, 198, 9, 6, + 84, 73, 82, 82, 85, 80, 38, 106, 65, 34, 67, 86, 68, 126, 83, 174, 1, 86, + 210, 9, 77, 254, 245, 3, 80, 230, 227, 3, 79, 171, 195, 10, 72, 4, 193, + 1, 4, 67, 85, 84, 69, 12, 58, 65, 218, 10, 69, 82, 79, 202, 31, 73, 239, + 225, 6, 85, 4, 101, 3, 82, 79, 78, 6, 21, 3, 79, 84, 32, 6, 26, 66, 211, + 252, 18, 65, 4, 25, 4, 69, 76, 79, 87, 5, 11, 32, 2, 185, 248, 18, 3, 65, + 78, 68, 4, 22, 72, 203, 42, 87, 2, 21, 3, 79, 82, 84, 2, 17, 2, 32, 83, + 2, 11, 84, 2, 21, 3, 82, 79, 75, 2, 11, 69, 2, 17, 2, 32, 79, 2, 237, + 235, 18, 4, 86, 69, 82, 76, 2, 37, 7, 69, 82, 84, 73, 67, 65, 76, 2, 205, + 40, 2, 32, 76, 4, 46, 76, 249, 226, 18, 5, 75, 72, 65, 32, 89, 2, 247, + 12, 84, 18, 48, 3, 72, 87, 65, 97, 5, 82, 73, 80, 84, 32, 11, 33, 6, 32, + 87, 73, 84, 72, 32, 8, 222, 35, 71, 186, 2, 65, 194, 221, 3, 82, 171, + 161, 14, 72, 8, 26, 82, 147, 243, 3, 71, 5, 173, 141, 11, 5, 32, 87, 73, + 84, 72, 2, 233, 161, 16, 3, 65, 82, 80, 14, 48, 7, 68, 69, 87, 65, 89, + 83, 32, 199, 1, 71, 12, 110, 79, 56, 4, 84, 85, 82, 78, 224, 160, 10, 11, + 68, 73, 65, 69, 82, 69, 83, 73, 90, 69, 68, 135, 210, 9, 85, 7, 26, 80, + 203, 245, 3, 32, 2, 145, 203, 9, 2, 69, 78, 2, 173, 220, 12, 2, 69, 68, + 2, 209, 159, 16, 4, 77, 79, 73, 68, 2, 227, 219, 9, 32, 147, 1, 188, 1, + 6, 32, 87, 73, 84, 72, 32, 192, 3, 2, 69, 83, 70, 72, 130, 2, 79, 102, + 82, 54, 85, 242, 241, 3, 67, 202, 1, 83, 136, 210, 10, 9, 65, 73, 76, 76, + 69, 83, 83, 32, 80, 243, 163, 5, 90, 34, 110, 67, 182, 1, 68, 66, 77, + 170, 31, 76, 214, 214, 3, 80, 180, 5, 4, 72, 79, 79, 75, 50, 82, 143, + 194, 15, 83, 10, 58, 69, 22, 73, 62, 79, 182, 129, 7, 85, 147, 201, 11, + 65, 2, 195, 251, 11, 68, 2, 37, 7, 82, 67, 85, 77, 70, 76, 69, 2, 255, + 199, 17, 88, 2, 17, 2, 77, 77, 2, 215, 199, 17, 65, 8, 32, 2, 73, 65, + 215, 255, 15, 79, 4, 154, 21, 71, 215, 6, 69, 4, 17, 2, 73, 68, 4, 26, + 45, 195, 238, 3, 68, 2, 229, 252, 3, 6, 72, 69, 73, 71, 72, 84, 6, 45, 9, + 72, 32, 68, 73, 71, 82, 65, 80, 72, 7, 183, 244, 3, 32, 8, 64, 12, 32, + 87, 73, 84, 72, 32, 83, 84, 82, 73, 75, 69, 43, 79, 2, 245, 243, 15, 5, + 84, 72, 82, 79, 85, 6, 17, 2, 82, 78, 7, 41, 8, 32, 87, 73, 84, 72, 32, + 83, 84, 4, 25, 4, 82, 79, 75, 69, 5, 11, 32, 2, 213, 197, 3, 6, 84, 72, + 82, 79, 85, 71, 8, 26, 78, 143, 244, 3, 80, 6, 17, 2, 69, 32, 6, 234, + 188, 4, 83, 190, 160, 9, 84, 215, 132, 1, 70, 2, 17, 2, 69, 83, 2, 11, + 73, 2, 243, 198, 19, 76, 76, 44, 5, 82, 78, 69, 68, 32, 131, 233, 19, 77, + 74, 162, 1, 68, 22, 72, 66, 73, 54, 79, 142, 1, 82, 110, 84, 22, 86, 138, + 240, 3, 65, 50, 77, 198, 2, 89, 246, 221, 15, 85, 218, 19, 69, 2, 71, 2, + 75, 2, 76, 3, 87, 2, 191, 195, 16, 69, 7, 209, 224, 3, 11, 32, 87, 73, + 84, 72, 32, 70, 73, 83, 72, 72, 5, 11, 78, 2, 149, 181, 9, 5, 83, 85, 76, + 65, 82, 12, 66, 69, 176, 213, 3, 7, 32, 79, 80, 69, 78, 45, 79, 167, 29, + 80, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 166, 200, 17, 72, 203, 237, 1, + 83, 15, 33, 6, 32, 87, 73, 84, 72, 32, 12, 138, 230, 3, 77, 174, 7, 80, + 142, 5, 76, 226, 197, 13, 84, 163, 92, 72, 5, 203, 237, 3, 32, 7, 11, 32, + 4, 161, 5, 4, 87, 73, 84, 72, 97, 90, 32, 224, 210, 3, 6, 80, 83, 73, 76, + 79, 78, 226, 144, 16, 69, 2, 73, 2, 77, 3, 79, 82, 48, 3, 66, 65, 82, 49, + 5, 87, 73, 84, 72, 32, 5, 245, 17, 8, 32, 87, 73, 84, 72, 32, 83, 72, 78, + 142, 1, 67, 74, 68, 150, 2, 72, 170, 1, 77, 134, 1, 79, 106, 82, 38, 84, + 186, 9, 71, 82, 83, 234, 1, 65, 206, 156, 3, 73, 62, 66, 135, 66, 76, 6, + 172, 185, 4, 9, 73, 82, 67, 85, 77, 70, 76, 69, 88, 147, 132, 14, 65, 18, + 52, 8, 73, 65, 69, 82, 69, 83, 73, 83, 131, 1, 79, 13, 11, 32, 10, 40, 4, + 65, 78, 68, 32, 223, 199, 17, 66, 8, 50, 67, 226, 13, 71, 186, 2, 65, + 183, 182, 3, 77, 2, 211, 187, 18, 65, 6, 26, 85, 207, 184, 17, 84, 4, 21, + 3, 66, 76, 69, 4, 11, 32, 4, 138, 13, 71, 187, 2, 65, 14, 11, 79, 14, 28, + 2, 82, 78, 251, 75, 79, 13, 29, 5, 32, 65, 78, 68, 32, 10, 66, 72, 226, + 11, 71, 186, 2, 65, 242, 216, 7, 68, 179, 181, 8, 84, 2, 145, 75, 2, 79, + 79, 10, 29, 5, 65, 67, 82, 79, 78, 11, 29, 5, 32, 65, 78, 68, 32, 8, 50, + 68, 214, 10, 71, 186, 2, 65, 163, 142, 16, 84, 2, 171, 10, 73, 6, 29, 5, + 71, 79, 78, 69, 75, 7, 11, 32, 4, 25, 4, 65, 78, 68, 32, 4, 178, 12, 65, + 163, 142, 16, 84, 4, 222, 233, 3, 69, 131, 200, 13, 73, 6, 25, 4, 73, 76, + 68, 69, 7, 11, 32, 4, 26, 65, 191, 194, 17, 66, 2, 17, 2, 78, 68, 2, 11, + 32, 2, 139, 11, 65, 29, 84, 6, 32, 87, 73, 84, 72, 32, 162, 1, 73, 66, + 79, 174, 202, 18, 69, 227, 141, 1, 89, 14, 82, 68, 174, 225, 3, 80, 142, + 1, 67, 158, 7, 82, 158, 174, 12, 84, 203, 240, 1, 72, 4, 26, 73, 179, + 226, 7, 79, 2, 17, 2, 65, 71, 2, 189, 168, 19, 2, 79, 78, 2, 41, 8, 83, + 73, 71, 79, 84, 72, 73, 67, 2, 175, 225, 15, 32, 6, 33, 6, 76, 65, 80, + 85, 75, 32, 6, 146, 193, 19, 65, 2, 79, 3, 85, 19, 33, 6, 32, 87, 73, 84, + 72, 32, 16, 202, 4, 67, 18, 68, 70, 71, 186, 2, 65, 194, 165, 17, 82, + 171, 89, 72, 17, 33, 6, 32, 87, 73, 84, 72, 32, 14, 42, 68, 32, 2, 76, + 79, 255, 221, 3, 80, 4, 222, 3, 73, 131, 210, 18, 79, 8, 60, 11, 78, 71, + 32, 76, 69, 70, 84, 32, 76, 69, 71, 79, 87, 7, 11, 32, 4, 60, 7, 65, 78, + 68, 32, 76, 79, 87, 65, 4, 87, 73, 84, 72, 2, 17, 2, 32, 82, 2, 21, 3, + 73, 71, 72, 2, 215, 236, 10, 84, 2, 197, 210, 18, 4, 32, 83, 69, 82, 33, + 48, 6, 32, 87, 73, 84, 72, 32, 187, 219, 15, 79, 28, 110, 67, 18, 68, 70, + 71, 22, 72, 42, 76, 22, 83, 234, 1, 65, 182, 182, 3, 77, 238, 215, 12, + 84, 163, 151, 1, 82, 2, 203, 3, 73, 6, 26, 73, 251, 227, 15, 79, 2, 17, + 2, 65, 69, 2, 243, 247, 15, 82, 2, 207, 233, 17, 82, 4, 17, 2, 79, 79, 4, + 187, 246, 4, 75, 2, 191, 216, 18, 79, 4, 26, 72, 167, 161, 19, 84, 2, 21, + 3, 79, 82, 84, 2, 245, 226, 7, 6, 32, 82, 73, 71, 72, 84, 31, 33, 6, 32, + 87, 73, 84, 72, 32, 28, 98, 65, 22, 67, 82, 68, 38, 76, 34, 83, 138, 207, + 3, 77, 174, 7, 80, 230, 5, 82, 171, 161, 14, 72, 2, 175, 140, 13, 67, 6, + 42, 73, 238, 225, 6, 85, 147, 201, 11, 65, 2, 177, 158, 11, 4, 82, 67, + 85, 77, 6, 234, 169, 3, 69, 203, 182, 12, 79, 2, 11, 73, 2, 243, 137, 12, + 78, 4, 26, 87, 151, 158, 19, 84, 2, 195, 190, 16, 65, 18, 90, 70, 222, + 157, 9, 73, 172, 9, 6, 76, 79, 78, 71, 32, 83, 226, 137, 10, 83, 219, 5, + 79, 10, 34, 70, 242, 204, 19, 73, 3, 76, 7, 238, 204, 19, 73, 3, 76, 36, + 150, 1, 83, 190, 203, 19, 65, 2, 69, 2, 72, 2, 73, 2, 74, 2, 75, 2, 76, + 2, 77, 2, 78, 2, 79, 2, 80, 2, 82, 2, 84, 2, 85, 2, 86, 3, 88, 5, 139, + 212, 4, 67, 160, 5, 200, 1, 2, 65, 70, 104, 2, 70, 84, 186, 33, 79, 20, + 5, 80, 67, 72, 65, 32, 164, 8, 8, 83, 83, 45, 84, 72, 65, 78, 32, 142, + 231, 15, 68, 248, 22, 6, 86, 69, 76, 32, 83, 76, 158, 209, 2, 77, 227, + 79, 71, 4, 180, 180, 1, 14, 32, 70, 76, 85, 84, 84, 69, 82, 73, 78, 71, + 32, 73, 78, 169, 186, 11, 3, 89, 32, 71, 200, 3, 58, 32, 186, 17, 45, + 169, 1, 6, 87, 65, 82, 68, 83, 32, 218, 1, 190, 1, 65, 174, 3, 66, 202, + 1, 67, 96, 2, 68, 79, 112, 2, 72, 65, 250, 2, 76, 46, 77, 38, 79, 38, 82, + 146, 3, 83, 82, 84, 174, 1, 87, 190, 159, 8, 70, 210, 3, 78, 202, 1, 80, + 187, 11, 86, 26, 22, 78, 211, 2, 82, 20, 28, 2, 68, 32, 131, 2, 71, 14, + 72, 3, 76, 79, 87, 0, 3, 85, 80, 80, 93, 6, 82, 73, 71, 72, 84, 32, 4, + 21, 3, 69, 82, 32, 4, 132, 190, 16, 9, 65, 78, 68, 32, 82, 73, 71, 72, + 84, 175, 30, 79, 6, 50, 84, 161, 166, 17, 6, 68, 79, 85, 66, 76, 69, 4, + 138, 190, 16, 82, 131, 216, 1, 65, 6, 202, 163, 8, 69, 185, 1, 4, 76, 69, + 32, 66, 6, 26, 67, 167, 167, 8, 82, 2, 129, 167, 8, 5, 32, 76, 69, 83, + 83, 12, 40, 4, 65, 82, 66, 32, 191, 167, 8, 76, 8, 40, 4, 68, 79, 87, 78, + 1, 2, 85, 80, 4, 57, 12, 32, 82, 73, 71, 72, 84, 32, 66, 65, 82, 66, 32, + 4, 208, 176, 16, 4, 68, 79, 87, 78, 1, 2, 85, 80, 14, 130, 167, 8, 85, + 230, 21, 79, 250, 222, 2, 69, 217, 153, 2, 8, 76, 79, 83, 69, 68, 32, 69, + 78, 10, 44, 5, 85, 66, 76, 69, 32, 175, 167, 8, 84, 8, 226, 168, 8, 87, + 234, 24, 65, 198, 248, 2, 81, 151, 172, 4, 80, 26, 36, 3, 76, 70, 32, + 203, 170, 8, 78, 24, 216, 1, 6, 67, 73, 82, 67, 76, 69, 190, 167, 8, 66, + 90, 70, 34, 82, 128, 147, 8, 30, 73, 78, 86, 69, 82, 83, 69, 32, 77, 69, + 68, 73, 85, 77, 32, 83, 72, 65, 68, 69, 32, 65, 78, 68, 32, 82, 73, 71, + 72, 84, 139, 19, 77, 11, 33, 6, 32, 87, 73, 84, 72, 32, 8, 42, 84, 254, + 160, 17, 70, 175, 204, 1, 68, 4, 166, 187, 5, 72, 219, 180, 12, 87, 4, + 252, 148, 1, 2, 85, 71, 207, 147, 7, 79, 2, 161, 172, 18, 4, 85, 76, 84, + 73, 6, 214, 169, 8, 85, 215, 150, 8, 78, 30, 44, 5, 73, 71, 72, 84, 32, + 219, 170, 8, 65, 28, 152, 1, 5, 65, 82, 82, 79, 87, 132, 1, 12, 68, 79, + 85, 66, 76, 69, 32, 65, 82, 82, 79, 87, 30, 87, 218, 209, 8, 79, 234, + 215, 7, 66, 54, 83, 159, 53, 84, 11, 11, 32, 8, 72, 5, 87, 73, 84, 72, + 32, 193, 234, 17, 7, 84, 72, 82, 79, 85, 71, 72, 6, 146, 248, 15, 68, + 190, 145, 3, 86, 79, 83, 7, 197, 201, 8, 2, 32, 87, 4, 202, 220, 8, 65, + 255, 248, 7, 72, 34, 238, 168, 8, 45, 70, 69, 78, 73, 168, 1, 3, 80, 69, + 69, 26, 81, 227, 2, 85, 18, 58, 82, 246, 173, 8, 72, 178, 178, 7, 79, + 179, 169, 2, 65, 6, 40, 4, 73, 65, 78, 71, 143, 175, 8, 65, 4, 208, 227, + 4, 8, 76, 69, 32, 66, 69, 83, 73, 68, 235, 230, 11, 85, 16, 174, 177, 8, + 72, 202, 1, 73, 141, 246, 9, 2, 82, 73, 30, 90, 83, 230, 178, 8, 70, 206, + 1, 72, 130, 1, 80, 189, 3, 7, 84, 79, 45, 82, 73, 71, 72, 4, 44, 5, 73, + 68, 69, 32, 65, 171, 183, 8, 72, 2, 209, 138, 1, 2, 82, 67, 208, 1, 172, + 1, 5, 65, 82, 82, 79, 87, 134, 5, 66, 70, 72, 134, 4, 84, 178, 2, 87, + 230, 182, 8, 68, 210, 1, 70, 222, 7, 76, 26, 79, 34, 80, 50, 82, 70, 83, + 134, 136, 8, 67, 47, 81, 71, 26, 32, 247, 134, 17, 45, 66, 102, 65, 138, + 1, 84, 132, 2, 5, 87, 73, 84, 72, 32, 238, 184, 8, 70, 173, 215, 9, 4, + 79, 86, 69, 82, 12, 44, 5, 66, 79, 86, 69, 32, 219, 186, 8, 78, 10, 64, + 4, 83, 72, 79, 82, 210, 185, 8, 82, 202, 208, 4, 65, 55, 84, 2, 175, 146, + 18, 84, 12, 56, 7, 72, 82, 79, 85, 71, 72, 32, 53, 3, 79, 32, 66, 6, 242, + 135, 13, 83, 134, 155, 4, 76, 223, 142, 2, 88, 6, 32, 2, 65, 82, 199, + 187, 8, 76, 5, 221, 128, 12, 23, 32, 79, 86, 69, 82, 32, 82, 73, 71, 72, + 84, 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 36, 154, 188, 8, 68, + 98, 76, 38, 80, 30, 83, 38, 84, 210, 139, 8, 77, 38, 78, 122, 69, 226, + 148, 1, 72, 155, 160, 1, 86, 8, 194, 189, 8, 65, 224, 10, 5, 79, 84, 84, + 79, 77, 251, 129, 8, 76, 30, 26, 65, 163, 207, 16, 69, 26, 48, 6, 82, 80, + 79, 79, 78, 32, 243, 231, 18, 78, 24, 100, 10, 87, 73, 84, 72, 32, 66, + 65, 82, 66, 32, 213, 191, 8, 9, 79, 86, 69, 82, 32, 82, 73, 71, 72, 22, + 40, 4, 68, 79, 87, 78, 117, 2, 85, 80, 10, 26, 32, 251, 212, 16, 87, 8, + 226, 192, 8, 66, 188, 2, 7, 65, 66, 79, 86, 69, 32, 82, 130, 138, 8, 70, + 175, 5, 84, 12, 26, 32, 135, 212, 16, 87, 10, 60, 6, 65, 66, 79, 86, 69, + 32, 238, 203, 16, 70, 175, 5, 84, 6, 42, 76, 205, 192, 8, 4, 82, 73, 71, + 72, 4, 242, 190, 8, 69, 207, 201, 4, 79, 54, 44, 2, 82, 73, 194, 196, 8, + 79, 159, 5, 87, 34, 44, 5, 65, 78, 71, 76, 69, 247, 200, 8, 80, 30, 56, + 8, 45, 72, 69, 65, 68, 69, 68, 32, 243, 218, 16, 32, 28, 52, 5, 65, 82, + 82, 79, 87, 210, 210, 16, 68, 39, 80, 25, 11, 32, 22, 184, 197, 8, 9, 79, + 86, 69, 82, 32, 82, 73, 71, 72, 22, 87, 155, 137, 8, 84, 6, 26, 72, 131, + 203, 8, 65, 4, 45, 9, 73, 84, 69, 32, 65, 82, 82, 79, 87, 5, 165, 216, + 16, 2, 32, 87, 5, 215, 144, 18, 80, 148, 1, 252, 1, 15, 67, 79, 78, 83, + 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 124, 7, 76, 69, 84, 84, 69, + 82, 32, 236, 1, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 198, + 1, 83, 172, 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 175, 177, + 17, 68, 18, 66, 75, 22, 78, 202, 164, 19, 76, 2, 77, 2, 80, 2, 82, 3, 84, + 5, 239, 211, 18, 65, 5, 145, 170, 12, 4, 89, 73, 78, 45, 78, 194, 1, 75, + 2, 80, 198, 134, 7, 68, 250, 149, 10, 66, 2, 70, 2, 71, 2, 72, 2, 77, + 254, 14, 78, 202, 175, 1, 84, 46, 67, 2, 83, 254, 68, 74, 2, 76, 2, 82, + 2, 86, 2, 87, 2, 89, 187, 2, 65, 6, 166, 160, 19, 72, 2, 76, 187, 2, 65, + 10, 82, 84, 40, 14, 78, 89, 69, 84, 32, 84, 72, 89, 79, 79, 77, 32, 84, + 65, 43, 67, 6, 38, 65, 21, 5, 83, 72, 79, 79, 75, 2, 255, 233, 6, 45, 5, + 17, 2, 32, 67, 2, 149, 220, 14, 3, 69, 82, 45, 8, 92, 4, 73, 71, 78, 32, + 37, 15, 85, 66, 74, 79, 73, 78, 69, 68, 32, 76, 69, 84, 84, 69, 82, 4, + 202, 186, 15, 78, 151, 158, 2, 82, 4, 11, 32, 4, 170, 157, 19, 82, 3, 89, + 14, 170, 208, 15, 85, 158, 144, 1, 79, 202, 188, 2, 65, 186, 2, 69, 3, + 73, 52, 138, 1, 65, 128, 4, 11, 69, 81, 85, 65, 76, 32, 84, 79, 32, 79, + 82, 200, 1, 2, 66, 85, 42, 67, 186, 1, 79, 210, 2, 87, 175, 141, 18, 83, + 16, 40, 5, 66, 79, 86, 69, 32, 171, 4, 78, 12, 152, 1, 7, 71, 82, 69, 65, + 84, 69, 82, 110, 83, 176, 1, 19, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, + 69, 32, 69, 81, 85, 65, 76, 32, 65, 207, 170, 15, 76, 2, 181, 5, 23, 45, + 84, 72, 65, 78, 32, 65, 66, 79, 86, 69, 32, 68, 79, 85, 66, 76, 69, 45, + 76, 73, 78, 69, 6, 152, 1, 7, 73, 77, 73, 76, 65, 82, 32, 93, 26, 76, 65, + 78, 84, 69, 68, 32, 69, 81, 85, 65, 76, 32, 65, 66, 79, 86, 69, 32, 71, + 82, 69, 65, 84, 69, 82, 4, 18, 65, 59, 79, 2, 25, 4, 66, 79, 86, 69, 2, + 241, 138, 17, 2, 32, 71, 2, 227, 2, 82, 2, 145, 2, 6, 45, 84, 72, 65, 78, + 32, 4, 17, 2, 68, 32, 4, 220, 3, 5, 78, 79, 84, 32, 65, 129, 238, 12, 11, + 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, 69, 4, 253, 215, 12, 5, 84, 32, + 78, 79, 84, 4, 65, 14, 76, 79, 83, 69, 68, 32, 66, 89, 32, 67, 85, 82, + 86, 69, 5, 11, 32, 2, 61, 13, 65, 66, 79, 86, 69, 32, 83, 76, 65, 78, 84, + 69, 68, 2, 17, 2, 32, 69, 2, 183, 186, 14, 81, 18, 40, 2, 82, 32, 193, + 190, 11, 2, 86, 69, 16, 114, 65, 48, 16, 83, 76, 65, 78, 84, 69, 68, 32, + 69, 81, 85, 65, 76, 32, 84, 79, 230, 212, 12, 69, 155, 177, 4, 71, 2, + 201, 154, 9, 7, 80, 80, 82, 79, 88, 73, 77, 9, 49, 10, 32, 87, 73, 84, + 72, 32, 68, 79, 84, 32, 6, 26, 65, 175, 170, 11, 73, 4, 25, 4, 66, 79, + 86, 69, 5, 139, 198, 17, 32, 6, 25, 4, 73, 84, 72, 32, 6, 66, 67, 40, 8, + 81, 85, 69, 83, 84, 73, 79, 78, 203, 194, 18, 68, 2, 133, 169, 11, 5, 73, + 82, 67, 76, 69, 2, 17, 2, 32, 77, 2, 17, 2, 65, 82, 2, 215, 149, 18, 75, + 136, 11, 190, 1, 71, 186, 5, 77, 162, 7, 78, 168, 65, 2, 80, 83, 20, 3, + 83, 85, 32, 130, 135, 15, 82, 152, 34, 11, 86, 82, 69, 32, 84, 79, 85, + 82, 78, 79, 73, 234, 44, 79, 130, 214, 1, 90, 175, 82, 66, 44, 26, 65, + 57, 2, 72, 84, 2, 165, 142, 9, 9, 84, 85, 82, 69, 32, 79, 80, 69, 78, 42, + 38, 32, 137, 4, 4, 78, 73, 78, 71, 36, 146, 1, 69, 38, 70, 126, 82, 40, + 3, 76, 69, 70, 86, 83, 42, 84, 152, 184, 7, 3, 66, 76, 85, 134, 224, 8, + 87, 134, 36, 86, 214, 74, 71, 195, 68, 67, 2, 201, 253, 16, 4, 73, 71, + 72, 84, 8, 94, 73, 201, 201, 17, 17, 79, 85, 82, 32, 80, 79, 73, 78, 84, + 69, 68, 32, 66, 76, 65, 67, 75, 4, 221, 249, 16, 2, 86, 69, 4, 36, 3, 73, + 71, 72, 171, 224, 16, 65, 2, 241, 230, 1, 16, 84, 32, 84, 79, 82, 84, 79, + 73, 83, 69, 32, 83, 72, 69, 76, 76, 6, 138, 157, 16, 72, 242, 93, 65, 43, + 73, 4, 216, 216, 15, 2, 87, 69, 21, 3, 72, 82, 69, 7, 29, 5, 32, 77, 79, + 79, 68, 5, 163, 130, 8, 32, 138, 1, 80, 3, 66, 85, 32, 229, 136, 8, 11, + 73, 84, 69, 68, 32, 76, 73, 65, 66, 73, 76, 136, 1, 128, 1, 7, 76, 69, + 84, 84, 69, 82, 32, 218, 1, 83, 200, 2, 5, 86, 79, 87, 69, 76, 206, 173, + 12, 69, 190, 141, 4, 81, 155, 92, 68, 60, 166, 1, 71, 174, 254, 5, 84, + 174, 192, 8, 89, 214, 122, 78, 134, 135, 3, 83, 82, 66, 2, 67, 2, 68, 2, + 74, 2, 75, 2, 80, 254, 68, 72, 2, 76, 2, 77, 2, 82, 3, 87, 6, 254, 192, + 17, 89, 254, 196, 1, 72, 187, 2, 65, 32, 108, 4, 73, 71, 78, 32, 128, 1, + 12, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 193, 236, 6, 2, 85, + 66, 8, 72, 3, 75, 69, 77, 0, 3, 77, 85, 75, 32, 2, 83, 65, 227, 197, 16, + 76, 2, 149, 202, 16, 3, 80, 72, 82, 2, 207, 242, 18, 45, 18, 138, 183, + 15, 78, 158, 138, 3, 65, 182, 66, 75, 2, 76, 2, 77, 2, 80, 2, 82, 3, 84, + 20, 84, 6, 32, 83, 73, 71, 78, 32, 253, 82, 10, 45, 67, 65, 82, 82, 73, + 69, 82, 32, 76, 18, 142, 199, 5, 65, 214, 254, 10, 79, 238, 254, 1, 69, + 150, 64, 73, 3, 85, 226, 8, 22, 69, 199, 64, 75, 222, 8, 34, 32, 177, 3, + 3, 65, 82, 32, 14, 120, 12, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 78, + 32, 190, 240, 12, 70, 178, 249, 2, 83, 193, 130, 1, 4, 84, 65, 66, 85, 6, + 108, 5, 87, 73, 84, 72, 32, 157, 1, 17, 78, 79, 84, 32, 73, 78, 67, 76, + 85, 68, 73, 78, 71, 32, 84, 72, 69, 4, 76, 7, 82, 69, 67, 84, 65, 78, 71, + 1, 8, 83, 69, 77, 73, 67, 73, 82, 67, 2, 73, 16, 85, 76, 65, 82, 32, 80, + 65, 84, 72, 32, 65, 82, 79, 85, 78, 68, 2, 17, 2, 32, 80, 2, 151, 223, + 17, 79, 208, 8, 60, 8, 65, 32, 83, 73, 71, 78, 32, 65, 221, 24, 2, 66, + 32, 170, 5, 122, 49, 86, 51, 202, 2, 52, 214, 1, 53, 158, 4, 54, 142, 3, + 55, 148, 4, 2, 56, 48, 78, 66, 201, 179, 17, 3, 48, 50, 56, 6, 140, 155, + 12, 5, 48, 48, 45, 49, 48, 176, 169, 5, 2, 50, 48, 197, 19, 2, 51, 49, + 150, 1, 78, 48, 90, 49, 130, 1, 55, 210, 241, 13, 50, 2, 51, 2, 52, 2, + 53, 3, 54, 22, 178, 1, 57, 138, 252, 18, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 2, 55, 3, 56, 24, 90, 51, 138, 252, 18, 48, 2, 49, 2, 50, 2, 52, + 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 6, 134, 252, 18, 65, 2, 66, 3, 67, 4, + 226, 251, 18, 48, 3, 49, 38, 18, 48, 91, 49, 20, 162, 1, 48, 2, 49, 2, + 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 74, 48, 2, 49, + 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 2, 161, 164, 6, 2, 45, + 86, 160, 1, 102, 48, 78, 49, 62, 51, 86, 52, 70, 53, 86, 54, 206, 11, 50, + 250, 159, 2, 57, 190, 192, 11, 55, 3, 56, 16, 134, 249, 18, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 12, 186, 248, 18, 48, 2, 49, 2, + 50, 2, 51, 2, 53, 3, 54, 18, 254, 247, 18, 48, 2, 49, 2, 50, 2, 52, 2, + 53, 2, 54, 2, 55, 2, 56, 3, 57, 14, 170, 247, 18, 48, 2, 49, 2, 50, 2, + 53, 2, 55, 2, 56, 3, 57, 18, 230, 246, 18, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 2, 55, 3, 57, 12, 146, 246, 18, 51, 2, 52, 2, 53, 2, + 54, 2, 56, 3, 57, 104, 70, 48, 78, 50, 86, 51, 38, 52, 78, 54, 254, 230, + 13, 53, 243, 1, 49, 16, 142, 245, 18, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, + 54, 2, 56, 3, 57, 18, 194, 244, 18, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, + 54, 2, 55, 2, 56, 3, 57, 6, 238, 243, 18, 52, 2, 55, 3, 56, 16, 202, 243, + 18, 48, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 56, 3, 57, 10, 254, 242, + 18, 48, 2, 49, 2, 50, 2, 51, 3, 52, 44, 86, 48, 134, 2, 49, 140, 246, 1, + 2, 51, 50, 157, 232, 16, 6, 50, 54, 32, 69, 89, 89, 26, 110, 57, 194, + 193, 8, 55, 182, 6, 50, 62, 54, 218, 58, 52, 198, 148, 3, 51, 110, 56, + 202, 196, 2, 49, 215, 94, 53, 10, 26, 45, 207, 231, 17, 32, 8, 96, 2, 50, + 32, 212, 136, 12, 3, 54, 32, 76, 184, 2, 3, 52, 32, 76, 141, 145, 3, 3, + 51, 32, 76, 2, 175, 140, 12, 76, 14, 110, 49, 22, 51, 32, 3, 52, 32, 65, + 0, 2, 53, 32, 198, 147, 4, 50, 202, 181, 4, 48, 141, 209, 6, 2, 55, 32, + 2, 243, 226, 17, 32, 2, 11, 32, 2, 219, 238, 11, 79, 2, 167, 180, 17, 66, + 16, 182, 238, 18, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, + 162, 1, 22, 48, 155, 5, 49, 140, 1, 82, 49, 54, 50, 118, 51, 62, 52, 78, + 53, 86, 54, 62, 55, 70, 56, 243, 220, 13, 48, 10, 246, 236, 18, 48, 2, + 49, 2, 51, 2, 54, 3, 55, 28, 86, 49, 2, 50, 194, 70, 51, 174, 165, 18, + 48, 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 7, 234, 235, 18, 70, 3, 77, 12, + 206, 235, 18, 48, 2, 49, 2, 52, 2, 55, 2, 56, 3, 57, 16, 146, 235, 18, + 48, 2, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 198, 234, 18, + 48, 2, 49, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 12, 242, 233, + 18, 48, 2, 49, 2, 53, 2, 54, 2, 55, 3, 57, 14, 182, 233, 18, 48, 2, 51, + 2, 52, 2, 54, 2, 55, 2, 56, 3, 57, 12, 242, 232, 18, 48, 2, 49, 2, 50, 2, + 53, 2, 54, 3, 55, 22, 82, 50, 36, 2, 51, 49, 30, 56, 226, 255, 11, 49, + 206, 2, 54, 146, 1, 55, 3, 57, 6, 226, 231, 18, 48, 2, 50, 3, 51, 4, 190, + 231, 18, 65, 3, 66, 4, 162, 231, 18, 48, 3, 56, 166, 3, 116, 9, 73, 68, + 69, 79, 71, 82, 65, 77, 32, 216, 17, 10, 77, 79, 78, 79, 71, 82, 65, 77, + 32, 66, 249, 1, 2, 83, 89, 234, 1, 54, 66, 249, 15, 8, 86, 69, 83, 83, + 69, 76, 32, 66, 176, 1, 22, 49, 255, 10, 50, 126, 86, 48, 210, 3, 50, + 162, 1, 51, 86, 52, 122, 53, 114, 54, 146, 1, 55, 118, 56, 71, 57, 28, + 114, 53, 98, 54, 58, 55, 78, 56, 62, 57, 148, 247, 6, 3, 50, 32, 87, 234, + 84, 48, 237, 215, 10, 4, 52, 32, 68, 69, 6, 252, 245, 6, 2, 32, 69, 188, + 205, 10, 3, 70, 32, 77, 245, 79, 7, 77, 32, 83, 84, 65, 76, 76, 4, 224, + 233, 1, 3, 70, 32, 69, 221, 191, 15, 2, 77, 32, 4, 36, 3, 70, 32, 83, 1, + 2, 77, 32, 2, 213, 195, 11, 4, 72, 69, 45, 71, 4, 228, 250, 8, 3, 77, 32, + 66, 145, 205, 8, 3, 70, 32, 83, 4, 148, 221, 16, 4, 77, 32, 66, 85, 165, + 106, 3, 70, 32, 67, 10, 236, 243, 8, 4, 51, 32, 83, 80, 224, 10, 5, 49, + 32, 66, 65, 82, 160, 218, 4, 4, 50, 32, 79, 76, 20, 6, 53, 32, 67, 89, + 80, 69, 209, 99, 4, 48, 32, 87, 72, 6, 54, 49, 192, 178, 16, 3, 48, 32, + 79, 247, 172, 2, 50, 2, 145, 198, 17, 2, 32, 87, 10, 224, 5, 3, 53, 32, + 87, 244, 241, 8, 6, 48, 32, 66, 82, 79, 78, 172, 2, 4, 49, 32, 71, 79, + 150, 229, 9, 50, 3, 54, 16, 82, 57, 150, 226, 2, 49, 186, 251, 15, 48, 2, + 50, 2, 51, 2, 52, 2, 55, 3, 56, 2, 253, 90, 3, 32, 67, 76, 20, 184, 246, + 13, 5, 51, 32, 65, 82, 77, 204, 163, 4, 5, 50, 32, 71, 65, 82, 170, 67, + 48, 2, 49, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 202, 198, 13, + 54, 196, 150, 3, 4, 51, 32, 77, 79, 146, 255, 1, 48, 2, 49, 2, 50, 2, 52, + 2, 55, 2, 56, 3, 57, 14, 170, 219, 18, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, + 53, 3, 57, 4, 240, 157, 2, 3, 49, 32, 72, 247, 188, 16, 48, 50, 42, 50, + 110, 51, 130, 1, 52, 227, 1, 53, 4, 84, 8, 48, 32, 70, 79, 79, 84, 83, + 84, 181, 196, 6, 7, 53, 32, 66, 65, 84, 72, 84, 2, 219, 198, 17, 79, 12, + 104, 4, 51, 32, 83, 87, 248, 211, 13, 4, 48, 32, 83, 80, 130, 234, 3, 49, + 190, 154, 1, 50, 2, 52, 3, 54, 2, 223, 193, 17, 79, 16, 168, 1, 9, 48, + 32, 87, 72, 69, 69, 76, 69, 68, 2, 49, 34, 51, 240, 202, 16, 12, 50, 32, + 67, 72, 65, 82, 73, 79, 84, 32, 70, 82, 230, 139, 2, 53, 2, 54, 2, 56, 3, + 57, 2, 133, 205, 17, 3, 32, 67, 72, 2, 183, 176, 6, 32, 18, 184, 207, 17, + 3, 52, 32, 68, 134, 135, 1, 49, 2, 50, 2, 51, 2, 53, 2, 54, 2, 55, 2, 56, + 3, 57, 58, 50, 50, 204, 239, 11, 2, 49, 53, 1, 2, 51, 48, 54, 50, 50, + 250, 241, 11, 53, 230, 216, 1, 48, 3, 49, 12, 238, 212, 18, 49, 2, 50, 2, + 54, 2, 55, 2, 56, 3, 57, 12, 46, 49, 153, 12, 6, 50, 52, 55, 32, 68, 73, + 10, 50, 50, 70, 51, 181, 11, 5, 53, 54, 32, 84, 85, 4, 252, 167, 3, 3, + 55, 32, 75, 197, 140, 15, 5, 56, 32, 75, 65, 78, 4, 56, 3, 53, 32, 77, + 241, 173, 15, 5, 51, 32, 65, 82, 69, 2, 231, 201, 11, 69, 176, 1, 84, 9, + 76, 76, 65, 66, 76, 69, 32, 66, 48, 229, 12, 7, 77, 66, 79, 76, 32, 66, + 48, 148, 1, 114, 48, 142, 1, 49, 162, 1, 50, 230, 1, 51, 174, 1, 52, 162, + 1, 53, 154, 1, 54, 186, 1, 55, 198, 1, 56, 87, 57, 18, 118, 54, 250, 191, + 1, 55, 150, 8, 52, 162, 14, 57, 138, 211, 10, 53, 186, 146, 2, 56, 226, + 10, 49, 254, 2, 50, 207, 8, 51, 2, 171, 149, 17, 32, 16, 122, 54, 18, 55, + 158, 201, 1, 49, 142, 2, 50, 158, 26, 52, 196, 186, 1, 2, 53, 32, 198, + 220, 5, 48, 177, 186, 8, 2, 51, 32, 2, 135, 84, 32, 2, 159, 232, 10, 32, + 18, 166, 1, 51, 22, 54, 20, 3, 57, 32, 80, 224, 6, 2, 53, 32, 136, 168, + 3, 2, 48, 32, 228, 253, 13, 2, 55, 32, 140, 7, 2, 52, 32, 146, 89, 56, + 173, 44, 3, 49, 32, 81, 2, 151, 250, 13, 32, 2, 151, 192, 14, 32, 2, 151, + 233, 11, 85, 16, 134, 1, 48, 20, 2, 51, 32, 254, 188, 1, 55, 254, 34, 54, + 194, 233, 4, 57, 138, 148, 2, 56, 210, 154, 4, 49, 185, 180, 5, 3, 50, + 32, 81, 2, 215, 251, 13, 32, 2, 135, 1, 82, 16, 116, 2, 51, 32, 22, 53, + 242, 184, 1, 48, 222, 1, 49, 134, 6, 50, 222, 10, 52, 146, 5, 54, 233, + 180, 12, 3, 56, 32, 78, 2, 199, 246, 14, 65, 2, 171, 189, 16, 32, 18, + 130, 1, 51, 162, 185, 1, 49, 150, 1, 56, 42, 57, 102, 55, 214, 5, 48, + 158, 140, 2, 52, 200, 210, 14, 2, 50, 32, 157, 4, 2, 53, 32, 2, 159, 192, + 11, 32, 16, 132, 1, 2, 50, 32, 20, 2, 56, 32, 204, 1, 3, 54, 32, 84, 150, + 180, 1, 55, 226, 3, 57, 146, 2, 53, 158, 228, 6, 49, 163, 221, 9, 48, 2, + 191, 131, 17, 80, 2, 129, 228, 11, 2, 82, 79, 18, 172, 1, 3, 54, 32, 82, + 182, 180, 1, 55, 158, 8, 48, 142, 16, 53, 12, 3, 49, 32, 68, 228, 145, 7, + 2, 52, 32, 214, 235, 3, 50, 152, 229, 5, 3, 56, 32, 81, 241, 2, 2, 51, + 32, 2, 183, 226, 11, 65, 8, 178, 180, 1, 49, 160, 24, 3, 55, 32, 84, 172, + 230, 6, 2, 53, 32, 211, 129, 6, 48, 4, 158, 184, 12, 49, 21, 3, 48, 32, + 68, 28, 90, 52, 30, 54, 30, 56, 186, 220, 11, 53, 158, 2, 49, 30, 51, + 166, 1, 50, 175, 144, 3, 55, 4, 158, 196, 18, 55, 3, 57, 4, 130, 196, 18, + 51, 3, 52, 8, 230, 195, 18, 50, 2, 51, 2, 54, 3, 57, 4, 156, 173, 10, 9, + 69, 68, 32, 80, 65, 80, 69, 82, 67, 155, 131, 7, 32, 5, 155, 148, 17, 84, + 98, 96, 7, 76, 69, 84, 84, 69, 82, 32, 253, 219, 6, 11, 80, 85, 78, 67, + 84, 85, 65, 84, 73, 79, 78, 94, 234, 1, 84, 186, 234, 2, 68, 226, 249, 9, + 85, 222, 140, 2, 69, 22, 78, 214, 135, 3, 67, 2, 71, 2, 72, 2, 75, 2, 80, + 2, 83, 2, 89, 2, 90, 162, 7, 65, 2, 79, 222, 61, 66, 2, 70, 2, 74, 2, 76, + 2, 77, 2, 87, 2, 88, 187, 2, 73, 20, 64, 4, 79, 78, 69, 32, 154, 248, 17, + 83, 254, 68, 72, 187, 2, 65, 12, 48, 4, 77, 89, 65, 32, 229, 185, 1, 2, + 78, 65, 10, 174, 227, 3, 74, 246, 188, 14, 66, 158, 11, 84, 254, 16, 67, + 39, 78, 208, 1, 244, 1, 2, 67, 75, 132, 1, 6, 71, 73, 67, 65, 76, 32, + 236, 3, 3, 78, 71, 32, 230, 4, 84, 116, 3, 86, 69, 32, 70, 87, 144, 8, 5, + 90, 69, 78, 71, 69, 218, 212, 7, 66, 220, 204, 9, 8, 85, 68, 76, 89, 32, + 67, 82, 89, 133, 15, 4, 76, 76, 73, 80, 9, 96, 10, 73, 78, 71, 45, 83, + 72, 73, 70, 84, 32, 149, 16, 9, 32, 87, 73, 84, 72, 32, 73, 78, 75, 4, + 210, 207, 16, 90, 143, 83, 79, 28, 36, 3, 65, 78, 68, 85, 2, 79, 82, 15, + 33, 6, 32, 87, 73, 84, 72, 32, 12, 226, 1, 68, 94, 72, 58, 77, 187, 239, + 14, 85, 15, 11, 32, 12, 88, 13, 79, 86, 69, 82, 76, 65, 80, 80, 73, 78, + 71, 32, 76, 49, 5, 87, 73, 84, 72, 32, 2, 129, 172, 17, 7, 79, 71, 73, + 67, 65, 76, 32, 10, 26, 68, 94, 72, 59, 77, 6, 11, 79, 6, 44, 5, 85, 66, + 76, 69, 32, 247, 187, 17, 84, 4, 142, 240, 14, 85, 167, 47, 79, 2, 149, + 144, 15, 9, 79, 82, 73, 90, 79, 78, 84, 65, 76, 2, 213, 196, 7, 5, 73, + 68, 68, 76, 69, 34, 66, 68, 236, 1, 4, 76, 69, 70, 84, 109, 5, 82, 73, + 71, 72, 84, 6, 172, 1, 30, 65, 83, 72, 32, 70, 82, 79, 77, 32, 76, 69, + 70, 84, 32, 77, 69, 77, 66, 69, 82, 32, 79, 70, 32, 68, 79, 85, 66, 76, + 69, 196, 180, 13, 2, 73, 86, 191, 217, 3, 82, 2, 17, 2, 32, 86, 2, 181, + 172, 17, 5, 69, 82, 84, 73, 67, 16, 18, 32, 119, 87, 6, 48, 6, 82, 73, + 71, 72, 84, 32, 215, 170, 15, 84, 4, 130, 165, 15, 68, 203, 245, 1, 65, + 12, 26, 87, 215, 216, 8, 32, 10, 29, 5, 65, 82, 68, 83, 32, 10, 82, 65, + 0, 8, 68, 79, 85, 66, 76, 69, 32, 65, 153, 205, 7, 4, 83, 81, 85, 73, 4, + 25, 4, 82, 82, 79, 87, 5, 233, 211, 15, 2, 32, 70, 6, 92, 5, 73, 79, 78, + 32, 66, 144, 153, 17, 9, 32, 79, 70, 32, 70, 79, 82, 84, 85, 199, 91, 85, + 2, 131, 209, 9, 79, 4, 38, 76, 145, 209, 13, 3, 72, 79, 84, 2, 153, 251, + 16, 2, 69, 84, 118, 34, 32, 229, 1, 3, 69, 82, 32, 14, 138, 1, 66, 140, + 169, 10, 11, 68, 79, 85, 66, 76, 69, 32, 80, 82, 73, 77, 214, 246, 5, 65, + 148, 109, 6, 75, 65, 86, 89, 75, 65, 139, 10, 76, 4, 38, 82, 149, 239, 4, + 3, 65, 84, 84, 2, 213, 156, 17, 7, 73, 71, 72, 84, 78, 69, 83, 104, 152, + 1, 5, 72, 65, 76, 70, 32, 92, 5, 76, 69, 70, 84, 32, 220, 2, 6, 82, 73, + 71, 72, 84, 32, 210, 164, 15, 66, 74, 70, 154, 9, 79, 150, 13, 83, 63, + 84, 8, 208, 137, 1, 7, 73, 78, 86, 69, 82, 83, 69, 238, 180, 14, 77, 162, + 7, 66, 195, 153, 1, 67, 40, 174, 1, 66, 60, 8, 70, 79, 85, 78, 84, 65, + 73, 78, 22, 80, 52, 12, 83, 69, 77, 73, 67, 73, 82, 67, 85, 76, 65, 82, + 202, 1, 84, 232, 166, 11, 3, 67, 82, 65, 147, 144, 4, 81, 24, 56, 8, 65, + 76, 76, 80, 79, 73, 78, 84, 227, 176, 15, 76, 2, 183, 215, 9, 32, 4, 176, + 203, 14, 5, 65, 73, 78, 84, 66, 171, 109, 69, 2, 177, 173, 7, 5, 32, 65, + 78, 84, 73, 40, 78, 83, 82, 84, 158, 168, 15, 66, 238, 3, 67, 130, 9, 68, + 206, 1, 80, 39, 81, 6, 172, 172, 7, 11, 69, 77, 73, 67, 73, 82, 67, 85, + 76, 65, 82, 131, 140, 8, 72, 4, 139, 185, 15, 82, 5, 149, 136, 17, 25, + 32, 68, 73, 86, 73, 68, 69, 68, 32, 66, 89, 32, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 32, 82, 85, 6, 18, 71, 23, 78, 2, 231, 205, 13, 71, 4, + 140, 134, 17, 5, 65, 82, 32, 69, 67, 191, 100, 71, 114, 104, 12, 67, 73, + 65, 78, 32, 76, 69, 84, 84, 69, 82, 32, 228, 1, 5, 68, 73, 65, 78, 32, + 159, 157, 17, 73, 58, 206, 1, 77, 194, 130, 5, 75, 142, 175, 9, 66, 50, + 84, 178, 251, 1, 65, 2, 69, 2, 78, 130, 248, 1, 68, 2, 71, 2, 72, 2, 73, + 2, 74, 2, 76, 2, 80, 2, 81, 2, 82, 2, 83, 2, 85, 2, 87, 2, 88, 3, 90, 5, + 171, 165, 18, 77, 54, 88, 7, 76, 69, 84, 84, 69, 82, 32, 253, 177, 14, 9, + 84, 82, 73, 65, 78, 71, 85, 76, 65, 52, 198, 239, 12, 84, 254, 193, 1, + 76, 154, 239, 1, 83, 226, 11, 65, 2, 69, 2, 78, 130, 248, 1, 66, 2, 67, + 2, 68, 2, 70, 2, 71, 2, 73, 2, 75, 2, 77, 2, 79, 2, 81, 2, 82, 2, 85, 2, + 86, 3, 89, 194, 53, 162, 1, 65, 242, 103, 69, 138, 103, 73, 254, 24, 79, + 136, 112, 3, 82, 79, 32, 234, 3, 85, 164, 70, 7, 89, 65, 78, 77, 65, 82, + 32, 246, 193, 14, 86, 186, 61, 77, 27, 87, 204, 23, 186, 1, 71, 62, 72, + 130, 11, 75, 234, 3, 76, 156, 14, 2, 77, 77, 22, 78, 150, 17, 80, 118, + 82, 174, 7, 83, 194, 7, 84, 196, 36, 3, 89, 65, 78, 132, 129, 1, 3, 88, + 73, 77, 243, 151, 15, 67, 6, 156, 146, 17, 4, 73, 67, 32, 87, 226, 88, + 78, 143, 53, 69, 166, 1, 84, 6, 65, 74, 65, 78, 73, 32, 133, 3, 10, 74, + 79, 78, 71, 32, 84, 73, 76, 69, 32, 78, 38, 76, 166, 2, 83, 167, 220, 12, + 65, 72, 88, 6, 69, 84, 84, 69, 82, 32, 137, 149, 11, 10, 73, 71, 65, 84, + 85, 82, 69, 32, 83, 72, 70, 202, 173, 3, 78, 138, 208, 10, 82, 242, 55, + 68, 46, 84, 206, 160, 3, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, + 72, 2, 76, 2, 77, 2, 83, 2, 86, 186, 2, 65, 2, 69, 2, 73, 2, 79, 3, 85, + 4, 174, 227, 6, 69, 177, 211, 7, 5, 73, 71, 78, 32, 78, 88, 236, 1, 2, + 66, 65, 38, 69, 46, 70, 46, 78, 42, 79, 46, 80, 22, 83, 118, 84, 194, 1, + 87, 112, 5, 71, 82, 69, 69, 78, 0, 3, 82, 69, 68, 168, 128, 6, 3, 65, 85, + 84, 210, 21, 74, 141, 215, 10, 11, 67, 72, 82, 89, 83, 65, 78, 84, 72, + 69, 77, 4, 254, 173, 1, 77, 235, 232, 16, 67, 8, 228, 2, 4, 73, 71, 72, + 84, 195, 1, 65, 12, 172, 2, 2, 73, 86, 13, 3, 79, 85, 82, 8, 192, 1, 2, + 79, 82, 65, 2, 73, 78, 8, 218, 1, 78, 237, 197, 11, 3, 82, 67, 72, 2, + 187, 240, 16, 76, 18, 88, 2, 79, 85, 76, 4, 69, 86, 69, 78, 0, 2, 73, 88, + 162, 244, 11, 85, 235, 193, 1, 80, 2, 157, 2, 2, 84, 72, 12, 36, 3, 72, + 82, 69, 13, 2, 87, 79, 6, 11, 69, 6, 25, 4, 32, 79, 70, 32, 6, 46, 67, + 173, 238, 6, 5, 66, 65, 77, 66, 79, 4, 180, 132, 6, 2, 73, 82, 145, 148, + 10, 5, 72, 65, 82, 65, 67, 6, 50, 69, 60, 4, 72, 73, 84, 69, 163, 222, + 16, 73, 2, 17, 2, 83, 84, 2, 17, 2, 32, 87, 2, 171, 135, 17, 73, 2, 17, + 2, 32, 68, 2, 227, 221, 16, 82, 52, 52, 5, 65, 83, 65, 82, 32, 157, 206, + 14, 2, 69, 77, 50, 162, 1, 69, 40, 7, 76, 69, 84, 84, 69, 82, 32, 152, 1, + 5, 80, 65, 83, 83, 73, 32, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, + 32, 173, 136, 18, 3, 65, 78, 71, 2, 213, 159, 15, 5, 78, 68, 32, 79, 70, + 36, 162, 155, 16, 78, 242, 244, 1, 66, 2, 67, 2, 68, 2, 71, 2, 74, 2, 75, + 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 86, 2, 89, 187, 2, 65, 2, + 11, 77, 2, 227, 184, 17, 66, 8, 146, 145, 18, 69, 2, 73, 2, 79, 3, 85, + 246, 1, 80, 7, 65, 89, 65, 76, 65, 77, 32, 208, 11, 2, 69, 32, 225, 1, 3, + 84, 69, 83, 236, 1, 190, 1, 65, 22, 68, 44, 9, 70, 82, 65, 67, 84, 73, + 79, 78, 32, 240, 1, 7, 76, 69, 84, 84, 69, 82, 32, 164, 5, 7, 78, 85, 77, + 66, 69, 82, 32, 36, 5, 83, 73, 71, 78, 32, 143, 144, 13, 86, 2, 227, 142, + 13, 85, 22, 172, 146, 8, 2, 65, 84, 251, 141, 8, 73, 26, 56, 4, 79, 78, + 69, 32, 121, 6, 84, 72, 82, 69, 69, 32, 18, 82, 84, 142, 128, 5, 83, 202, + 219, 7, 70, 58, 79, 170, 176, 3, 69, 46, 72, 43, 81, 4, 254, 222, 12, 87, + 239, 174, 3, 69, 8, 166, 128, 5, 83, 174, 223, 7, 69, 110, 84, 163, 174, + 3, 81, 132, 1, 226, 1, 65, 82, 67, 158, 1, 68, 78, 84, 82, 86, 222, 221, + 12, 78, 230, 46, 76, 210, 90, 82, 130, 81, 85, 158, 144, 1, 79, 182, 56, + 73, 202, 190, 1, 83, 82, 66, 2, 71, 2, 74, 2, 75, 2, 80, 162, 7, 69, 222, + 61, 72, 2, 77, 3, 89, 11, 148, 206, 15, 7, 82, 67, 72, 65, 73, 67, 32, + 158, 188, 2, 65, 2, 73, 3, 85, 22, 26, 72, 203, 137, 18, 65, 20, 44, 5, + 73, 76, 76, 85, 32, 155, 137, 18, 65, 18, 226, 211, 12, 76, 182, 189, 3, + 78, 178, 191, 1, 82, 210, 56, 75, 2, 77, 3, 89, 10, 164, 198, 10, 4, 79, + 84, 32, 82, 238, 250, 6, 68, 254, 68, 72, 187, 2, 65, 10, 38, 84, 158, + 133, 18, 72, 187, 2, 65, 6, 154, 133, 18, 72, 2, 84, 187, 2, 65, 12, 250, + 225, 3, 69, 206, 193, 10, 79, 231, 227, 3, 65, 6, 158, 222, 12, 79, 231, + 215, 3, 84, 18, 50, 67, 114, 86, 194, 158, 14, 65, 179, 162, 3, 80, 6, + 54, 79, 120, 5, 73, 82, 67, 85, 76, 215, 158, 14, 65, 2, 185, 142, 13, 9, + 77, 66, 73, 78, 73, 78, 71, 32, 65, 6, 60, 9, 69, 82, 84, 73, 67, 65, 76, + 32, 66, 255, 193, 17, 73, 2, 17, 2, 65, 82, 2, 233, 163, 12, 2, 32, 86, + 8, 80, 12, 87, 73, 84, 72, 32, 83, 84, 82, 79, 75, 69, 32, 70, 65, 219, + 252, 16, 83, 4, 64, 10, 65, 78, 68, 32, 77, 65, 76, 69, 32, 65, 219, 252, + 16, 83, 2, 25, 4, 78, 68, 32, 70, 2, 11, 69, 2, 11, 77, 2, 199, 190, 7, + 65, 2, 231, 196, 16, 69, 2, 199, 131, 16, 79, 185, 1, 210, 1, 32, 220, 2, + 5, 68, 65, 73, 67, 32, 220, 3, 8, 73, 67, 72, 65, 69, 65, 78, 32, 222, 8, + 83, 200, 165, 2, 3, 85, 65, 76, 166, 181, 10, 65, 220, 168, 1, 8, 84, 69, + 76, 80, 73, 69, 67, 69, 147, 207, 3, 71, 12, 132, 1, 3, 73, 78, 32, 128, + 1, 5, 87, 73, 84, 72, 32, 196, 146, 2, 3, 68, 65, 78, 169, 194, 12, 8, + 65, 78, 68, 32, 87, 79, 77, 65, 4, 208, 240, 9, 19, 66, 85, 83, 73, 78, + 69, 83, 83, 32, 83, 85, 73, 84, 32, 76, 69, 86, 73, 84, 209, 148, 1, 4, + 84, 85, 88, 69, 4, 204, 195, 13, 8, 71, 85, 65, 32, 80, 73, 32, 77, 213, + 243, 2, 4, 84, 85, 82, 66, 58, 136, 1, 7, 76, 69, 84, 84, 69, 82, 32, + 230, 209, 10, 71, 176, 184, 3, 3, 86, 79, 67, 146, 70, 80, 177, 195, 2, + 6, 65, 70, 70, 82, 73, 67, 50, 82, 65, 176, 1, 2, 68, 85, 2, 85, 28, 3, + 72, 65, 76, 22, 73, 167, 180, 17, 75, 38, 154, 1, 75, 150, 198, 12, 84, + 226, 193, 1, 83, 194, 163, 3, 73, 214, 79, 66, 2, 68, 2, 71, 2, 72, 2, + 76, 2, 77, 2, 78, 2, 80, 2, 81, 2, 82, 3, 90, 5, 207, 248, 17, 83, 2, + 253, 239, 7, 2, 83, 72, 2, 159, 248, 17, 81, 4, 194, 250, 17, 78, 3, 84, + 102, 216, 1, 7, 76, 69, 84, 84, 69, 82, 32, 194, 4, 78, 80, 12, 80, 85, + 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 220, 1, 4, 83, 73, 71, 78, 185, + 172, 10, 16, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 78, 32, 77, 65, + 82, 72, 218, 1, 65, 46, 66, 38, 68, 30, 71, 30, 74, 2, 90, 30, 75, 30, + 81, 38, 83, 50, 84, 54, 88, 238, 154, 6, 76, 254, 194, 1, 82, 238, 213, + 2, 89, 154, 193, 1, 72, 166, 255, 4, 78, 254, 1, 87, 202, 103, 70, 2, 80, + 171, 4, 77, 6, 206, 180, 10, 76, 122, 65, 239, 193, 6, 89, 4, 238, 200, + 12, 72, 211, 174, 3, 69, 4, 206, 156, 6, 65, 23, 72, 4, 246, 179, 10, 72, + 15, 73, 4, 178, 180, 10, 72, 15, 65, 4, 246, 251, 11, 72, 15, 65, 4, 162, + 156, 6, 72, 199, 223, 5, 79, 8, 250, 176, 10, 83, 154, 3, 65, 191, 193, + 6, 72, 6, 158, 155, 6, 72, 186, 218, 9, 69, 247, 128, 1, 65, 4, 222, 250, + 11, 65, 3, 79, 10, 33, 6, 85, 77, 66, 69, 82, 32, 10, 186, 179, 10, 79, + 58, 84, 219, 183, 2, 70, 14, 80, 2, 68, 79, 116, 3, 76, 73, 78, 138, 159, + 5, 70, 142, 133, 11, 84, 255, 9, 83, 6, 54, 84, 13, 9, 85, 66, 76, 69, + 32, 68, 79, 84, 32, 5, 11, 32, 2, 25, 4, 87, 73, 84, 72, 2, 163, 192, 2, + 73, 2, 223, 201, 3, 69, 2, 159, 199, 16, 32, 2, 11, 32, 2, 221, 218, 17, + 2, 83, 72, 4, 92, 17, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 76, + 73, 71, 72, 84, 175, 191, 10, 76, 2, 175, 193, 14, 72, 142, 1, 142, 1, + 65, 20, 5, 67, 72, 69, 78, 32, 160, 155, 6, 4, 82, 73, 65, 71, 165, 213, + 10, 13, 84, 73, 65, 76, 32, 65, 82, 84, 83, 32, 85, 78, 73, 2, 175, 153, + 5, 67, 136, 1, 152, 1, 7, 76, 69, 84, 84, 69, 82, 32, 194, 1, 83, 236, 2, + 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 154, 157, 17, 72, 225, 5, + 4, 77, 65, 82, 75, 60, 254, 3, 84, 146, 148, 2, 68, 178, 222, 13, 78, + 246, 175, 1, 67, 2, 75, 2, 80, 2, 83, 2, 90, 254, 68, 45, 2, 66, 2, 71, + 2, 72, 2, 74, 2, 76, 2, 77, 2, 82, 2, 87, 2, 89, 187, 2, 65, 62, 96, 4, + 73, 71, 78, 32, 37, 16, 85, 66, 74, 79, 73, 78, 69, 68, 32, 76, 69, 84, + 84, 69, 82, 32, 4, 154, 133, 14, 67, 191, 161, 3, 65, 58, 182, 1, 84, + 146, 148, 2, 68, 178, 222, 13, 78, 246, 175, 1, 67, 2, 75, 2, 80, 2, 83, + 2, 90, 254, 68, 66, 2, 71, 2, 72, 2, 74, 2, 76, 2, 77, 2, 82, 2, 87, 2, + 89, 187, 2, 65, 8, 178, 162, 17, 83, 254, 68, 72, 187, 2, 65, 10, 130, + 231, 17, 65, 186, 2, 69, 2, 73, 2, 79, 3, 85, 156, 1, 120, 11, 65, 82, + 65, 77, 32, 71, 79, 78, 68, 73, 32, 236, 5, 3, 67, 85, 76, 64, 5, 75, 32, + 87, 79, 82, 163, 160, 17, 85, 150, 1, 100, 7, 76, 69, 84, 84, 69, 82, 32, + 178, 2, 82, 56, 5, 83, 73, 71, 78, 32, 82, 86, 199, 245, 15, 68, 94, 210, + 1, 74, 42, 84, 206, 252, 13, 65, 38, 68, 146, 25, 85, 210, 200, 1, 73, + 42, 76, 210, 189, 1, 75, 38, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 80, + 254, 68, 72, 2, 77, 2, 82, 2, 86, 2, 89, 186, 2, 69, 3, 79, 6, 230, 226, + 17, 78, 38, 72, 187, 2, 65, 10, 230, 157, 17, 84, 254, 68, 72, 2, 82, + 187, 2, 65, 4, 32, 2, 65, 45, 163, 240, 1, 69, 2, 131, 160, 17, 75, 10, + 174, 176, 1, 67, 202, 160, 12, 72, 242, 45, 78, 130, 182, 1, 86, 223, + 234, 1, 65, 22, 26, 79, 207, 177, 15, 73, 20, 45, 9, 87, 69, 76, 32, 83, + 73, 71, 78, 32, 20, 78, 86, 238, 253, 13, 65, 190, 21, 85, 210, 200, 1, + 73, 206, 134, 2, 69, 3, 79, 2, 201, 182, 7, 6, 79, 67, 65, 76, 73, 67, 2, + 253, 168, 17, 11, 73, 78, 69, 32, 79, 82, 68, 73, 78, 65, 76, 2, 199, + 206, 16, 75, 226, 15, 76, 10, 72, 69, 77, 65, 84, 73, 67, 65, 76, 32, + 129, 162, 14, 3, 69, 32, 68, 224, 15, 252, 1, 5, 66, 79, 76, 68, 32, 168, + 6, 14, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 75, 32, 238, 1, + 70, 164, 2, 7, 73, 84, 65, 76, 73, 67, 32, 180, 3, 10, 77, 79, 78, 79, + 83, 80, 65, 67, 69, 32, 40, 2, 82, 73, 36, 3, 76, 69, 70, 167, 1, 83, + 160, 5, 176, 1, 8, 67, 65, 80, 73, 84, 65, 76, 32, 130, 2, 83, 210, 14, + 73, 222, 3, 69, 38, 75, 38, 78, 30, 80, 98, 82, 242, 5, 84, 56, 7, 70, + 82, 65, 75, 84, 85, 82, 131, 211, 15, 68, 104, 190, 4, 68, 174, 15, 84, + 186, 4, 65, 22, 66, 2, 90, 42, 69, 98, 71, 22, 73, 22, 75, 34, 76, 22, + 79, 50, 80, 42, 82, 22, 83, 70, 85, 250, 196, 1, 67, 214, 173, 12, 77, 2, + 78, 210, 200, 1, 88, 206, 134, 2, 70, 2, 72, 2, 74, 2, 81, 2, 86, 2, 87, + 3, 89, 208, 1, 60, 5, 77, 65, 76, 76, 32, 213, 25, 5, 67, 82, 73, 80, 84, + 104, 250, 1, 68, 230, 19, 65, 22, 66, 2, 90, 42, 69, 38, 70, 62, 71, 22, + 73, 22, 75, 34, 76, 22, 79, 50, 80, 42, 82, 22, 83, 34, 84, 38, 85, 250, + 196, 1, 67, 214, 173, 12, 77, 2, 78, 210, 200, 1, 88, 206, 134, 2, 72, 2, + 74, 2, 81, 2, 86, 2, 87, 3, 89, 7, 26, 73, 191, 180, 14, 69, 2, 167, 213, + 1, 71, 110, 68, 8, 67, 65, 80, 73, 84, 65, 76, 32, 162, 23, 83, 195, 210, + 15, 68, 38, 250, 215, 17, 65, 2, 66, 2, 68, 2, 69, 2, 70, 2, 71, 2, 73, + 2, 74, 2, 75, 2, 76, 2, 77, 2, 79, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, + 88, 3, 89, 96, 52, 7, 82, 65, 75, 84, 85, 82, 32, 139, 252, 6, 65, 94, + 52, 8, 67, 65, 80, 73, 84, 65, 76, 32, 143, 21, 83, 42, 230, 213, 17, 65, + 2, 66, 2, 68, 2, 69, 2, 70, 2, 71, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, + 79, 2, 80, 2, 81, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 3, 89, 222, + 1, 100, 6, 83, 77, 65, 76, 76, 32, 222, 7, 67, 230, 2, 69, 38, 75, 38, + 78, 30, 80, 98, 82, 243, 5, 84, 104, 242, 1, 68, 198, 12, 65, 22, 66, 2, + 90, 42, 69, 38, 70, 62, 71, 22, 73, 22, 75, 34, 76, 22, 79, 50, 80, 42, + 82, 22, 83, 34, 84, 38, 85, 250, 196, 1, 67, 214, 173, 12, 77, 2, 78, + 210, 200, 1, 88, 206, 134, 2, 74, 2, 81, 2, 86, 2, 87, 3, 89, 9, 52, 7, + 79, 84, 76, 69, 83, 83, 32, 131, 173, 14, 69, 4, 154, 209, 17, 73, 3, 74, + 124, 130, 16, 67, 34, 83, 195, 210, 15, 68, 12, 32, 2, 71, 72, 179, 246, + 6, 83, 10, 17, 2, 84, 32, 10, 112, 6, 87, 72, 73, 84, 69, 32, 170, 236, + 5, 68, 234, 99, 65, 197, 164, 7, 9, 70, 76, 65, 84, 84, 69, 78, 69, 68, + 4, 254, 246, 13, 83, 39, 84, 130, 6, 84, 10, 65, 78, 83, 45, 83, 69, 82, + 73, 70, 32, 133, 14, 6, 67, 82, 73, 80, 84, 32, 176, 5, 96, 5, 66, 79, + 76, 68, 32, 176, 12, 6, 73, 84, 65, 76, 73, 67, 34, 67, 34, 83, 195, 210, + 15, 68, 204, 3, 98, 73, 122, 67, 230, 2, 69, 38, 75, 38, 78, 30, 80, 98, + 82, 30, 83, 214, 5, 84, 187, 211, 15, 68, 220, 1, 33, 6, 84, 65, 76, 73, + 67, 32, 220, 1, 74, 67, 230, 2, 69, 38, 75, 38, 78, 30, 80, 98, 82, 30, + 83, 215, 5, 84, 102, 37, 7, 65, 80, 73, 84, 65, 76, 32, 102, 250, 1, 84, + 186, 4, 65, 22, 66, 2, 90, 22, 68, 22, 69, 98, 71, 22, 73, 22, 75, 34, + 76, 22, 79, 50, 80, 42, 82, 22, 83, 70, 85, 250, 196, 1, 67, 214, 173, + 12, 77, 2, 78, 210, 200, 1, 88, 206, 134, 2, 70, 2, 72, 2, 74, 2, 81, 2, + 86, 2, 87, 3, 89, 9, 40, 4, 72, 69, 84, 65, 183, 164, 17, 65, 5, 151, + 182, 16, 32, 2, 185, 212, 15, 4, 80, 83, 73, 76, 2, 17, 2, 65, 80, 2, + 159, 7, 80, 2, 165, 166, 17, 2, 65, 66, 6, 74, 72, 168, 141, 5, 8, 65, + 82, 84, 73, 65, 76, 32, 68, 163, 167, 11, 73, 2, 199, 180, 16, 73, 2, + 177, 180, 16, 2, 72, 79, 102, 29, 5, 77, 65, 76, 76, 32, 102, 246, 1, 65, + 22, 66, 2, 90, 22, 68, 22, 69, 38, 70, 62, 71, 22, 73, 22, 75, 34, 76, + 22, 79, 50, 80, 42, 82, 22, 83, 34, 84, 38, 85, 250, 196, 1, 67, 214, + 173, 12, 77, 2, 78, 210, 200, 1, 88, 206, 134, 2, 72, 2, 74, 2, 81, 2, + 86, 2, 87, 3, 89, 5, 235, 208, 1, 76, 5, 175, 160, 17, 69, 5, 203, 160, + 14, 69, 7, 178, 212, 1, 80, 235, 237, 15, 84, 5, 11, 73, 2, 29, 5, 78, + 65, 76, 32, 83, 2, 227, 1, 73, 5, 219, 248, 14, 65, 5, 147, 159, 17, 79, + 5, 11, 65, 2, 223, 158, 14, 80, 5, 143, 160, 14, 65, 7, 11, 77, 4, 230, + 170, 1, 73, 239, 213, 15, 69, 9, 142, 175, 17, 72, 2, 83, 219, 19, 73, 5, + 203, 163, 17, 72, 5, 11, 73, 2, 143, 161, 17, 71, 7, 190, 157, 14, 72, + 231, 255, 2, 65, 5, 199, 209, 1, 80, 2, 11, 72, 2, 11, 69, 2, 11, 84, 2, + 159, 174, 16, 65, 104, 11, 32, 104, 18, 67, 35, 83, 52, 53, 5, 65, 80, + 73, 84, 65, 52, 21, 3, 77, 65, 76, 52, 183, 216, 11, 76, 82, 76, 8, 67, + 65, 80, 73, 84, 65, 76, 32, 157, 1, 6, 83, 77, 65, 76, 76, 32, 36, 222, + 191, 17, 65, 2, 67, 2, 68, 2, 71, 2, 74, 2, 75, 2, 78, 2, 79, 2, 80, 2, + 81, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 2, 89, 3, 90, 46, 194, 190, + 17, 65, 2, 66, 2, 67, 2, 68, 2, 70, 2, 72, 2, 73, 2, 74, 2, 75, 2, 76, 2, + 77, 2, 78, 2, 80, 2, 81, 2, 82, 2, 83, 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, + 2, 89, 3, 90, 40, 45, 9, 32, 78, 85, 77, 69, 82, 65, 76, 32, 40, 70, 69, + 66, 70, 70, 78, 26, 83, 66, 84, 142, 206, 15, 90, 143, 83, 79, 6, 40, 4, + 73, 71, 72, 84, 243, 224, 9, 76, 5, 231, 234, 15, 69, 8, 30, 73, 105, 3, + 79, 85, 82, 4, 202, 254, 4, 70, 139, 166, 12, 86, 4, 65, 3, 73, 78, 69, + 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 5, 191, 233, 15, 84, 10, 42, 72, + 190, 224, 9, 87, 243, 137, 7, 69, 4, 150, 253, 4, 73, 183, 208, 10, 82, + 248, 8, 234, 1, 65, 192, 4, 9, 67, 72, 65, 78, 73, 67, 65, 76, 32, 34, + 68, 180, 15, 11, 69, 84, 69, 73, 32, 77, 65, 89, 69, 75, 32, 178, 11, 76, + 34, 78, 162, 50, 82, 172, 15, 8, 83, 83, 65, 71, 69, 32, 87, 65, 20, 2, + 84, 82, 183, 183, 16, 77, 26, 72, 6, 83, 85, 82, 69, 68, 32, 249, 141, + 16, 6, 84, 32, 79, 78, 32, 66, 24, 96, 5, 65, 78, 71, 76, 69, 200, 247, + 9, 9, 82, 73, 71, 72, 84, 32, 65, 78, 71, 175, 173, 7, 66, 21, 11, 32, + 18, 212, 1, 39, 87, 73, 84, 72, 32, 79, 80, 69, 78, 32, 65, 82, 77, 32, + 69, 78, 68, 73, 78, 71, 32, 73, 78, 32, 65, 82, 82, 79, 87, 32, 80, 79, + 73, 78, 84, 73, 78, 71, 32, 161, 130, 17, 7, 79, 80, 69, 78, 73, 78, 71, + 16, 62, 68, 24, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 43, 85, 4, 73, 3, + 79, 87, 78, 4, 173, 249, 7, 5, 84, 32, 65, 78, 68, 4, 11, 80, 4, 145, + 190, 11, 3, 32, 65, 78, 4, 254, 180, 16, 65, 211, 56, 76, 250, 1, 56, 9, + 69, 70, 65, 73, 68, 82, 73, 78, 32, 159, 7, 73, 190, 1, 174, 1, 67, 52, + 6, 68, 73, 71, 73, 84, 32, 152, 1, 7, 78, 85, 77, 66, 69, 82, 32, 114, + 83, 132, 255, 6, 12, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 32, 215, + 228, 7, 70, 70, 128, 3, 5, 65, 80, 73, 84, 65, 255, 226, 14, 79, 26, 82, + 84, 48, 2, 79, 78, 194, 194, 15, 70, 30, 83, 102, 90, 130, 83, 78, 211, + 110, 69, 8, 44, 3, 72, 82, 69, 209, 176, 16, 2, 87, 79, 4, 207, 176, 16, + 69, 20, 50, 84, 226, 240, 4, 69, 46, 70, 42, 78, 31, 83, 6, 162, 242, 4, + 72, 204, 227, 4, 2, 87, 69, 215, 137, 7, 69, 70, 68, 3, 77, 65, 76, 217, + 183, 9, 8, 89, 77, 66, 79, 76, 32, 65, 73, 68, 45, 9, 76, 32, 76, 69, 84, + 84, 69, 82, 32, 68, 242, 1, 65, 38, 78, 146, 221, 3, 72, 2, 75, 162, 255, + 9, 89, 138, 143, 3, 79, 150, 64, 66, 2, 67, 2, 68, 2, 69, 2, 70, 2, 71, + 2, 73, 2, 74, 2, 76, 2, 77, 2, 80, 2, 81, 2, 82, 2, 83, 2, 84, 2, 85, 2, + 86, 2, 87, 2, 88, 3, 90, 7, 162, 237, 3, 84, 207, 190, 13, 73, 7, 202, + 171, 17, 71, 3, 89, 60, 48, 5, 69, 86, 65, 76, 32, 45, 3, 85, 77, 32, 6, + 138, 211, 10, 69, 206, 140, 4, 67, 115, 81, 54, 210, 1, 66, 46, 70, 164, + 1, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 248, 1, 11, 77, 65, 84, 72, 69, + 77, 65, 84, 73, 67, 65, 22, 83, 104, 4, 84, 72, 82, 69, 186, 212, 14, 86, + 230, 59, 69, 166, 4, 87, 207, 10, 71, 4, 164, 4, 3, 79, 76, 68, 163, 201, + 13, 76, 10, 84, 9, 76, 65, 84, 84, 69, 78, 69, 68, 32, 204, 3, 3, 79, 85, + 82, 219, 145, 15, 73, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 213, + 1, 3, 84, 32, 80, 6, 11, 84, 6, 78, 32, 41, 15, 45, 80, 79, 73, 78, 84, + 73, 78, 71, 32, 65, 78, 71, 76, 69, 4, 36, 5, 67, 85, 82, 76, 89, 59, 80, + 2, 17, 2, 32, 66, 2, 237, 163, 7, 4, 82, 65, 67, 75, 2, 153, 226, 16, 10, + 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 2, 251, 230, 16, 76, 10, 72, 4, + 77, 65, 76, 76, 154, 181, 14, 72, 188, 91, 2, 73, 88, 183, 2, 65, 2, 133, + 162, 14, 2, 32, 87, 4, 11, 69, 4, 45, 9, 32, 80, 79, 73, 78, 84, 69, 68, + 32, 4, 206, 179, 9, 80, 151, 221, 5, 66, 158, 1, 146, 1, 65, 104, 6, 67, + 72, 69, 73, 75, 72, 34, 76, 144, 6, 8, 83, 89, 76, 76, 65, 66, 76, 69, 0, + 4, 87, 79, 82, 68, 50, 86, 223, 172, 15, 68, 6, 80, 8, 72, 65, 78, 71, + 32, 75, 72, 85, 164, 6, 3, 80, 85, 78, 155, 177, 13, 78, 2, 175, 232, 15, + 68, 4, 130, 210, 16, 65, 255, 59, 69, 94, 52, 6, 69, 84, 84, 69, 82, 32, + 185, 5, 2, 85, 77, 92, 250, 1, 66, 36, 2, 67, 72, 38, 68, 50, 71, 38, 74, + 34, 75, 42, 78, 62, 80, 30, 83, 42, 84, 54, 73, 0, 3, 76, 65, 73, 0, 3, + 77, 73, 84, 230, 210, 12, 72, 166, 10, 82, 2, 87, 188, 144, 2, 2, 65, 84, + 230, 213, 1, 89, 242, 8, 85, 214, 79, 69, 3, 79, 4, 198, 229, 15, 72, + 191, 185, 1, 65, 4, 194, 149, 16, 73, 159, 137, 1, 65, 8, 238, 141, 10, + 72, 178, 135, 6, 73, 235, 65, 68, 4, 190, 141, 10, 72, 183, 141, 7, 79, + 4, 170, 228, 15, 72, 163, 48, 73, 6, 216, 1, 2, 79, 75, 163, 139, 10, 72, + 12, 178, 1, 65, 0, 3, 71, 79, 85, 182, 153, 17, 78, 3, 89, 6, 118, 65, + 179, 226, 15, 72, 6, 238, 139, 17, 65, 162, 14, 72, 3, 83, 10, 48, 2, 73, + 76, 162, 139, 10, 72, 155, 201, 6, 84, 5, 157, 177, 1, 4, 32, 76, 79, 78, + 2, 161, 152, 17, 3, 32, 73, 89, 2, 141, 178, 16, 7, 32, 82, 69, 80, 69, + 84, 73, 30, 64, 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 191, 232, 14, + 73, 28, 130, 1, 65, 44, 4, 67, 72, 69, 73, 2, 79, 0, 3, 83, 79, 85, 0, 2, + 89, 69, 22, 73, 38, 85, 206, 231, 10, 78, 187, 129, 4, 86, 8, 218, 136, + 16, 78, 170, 80, 65, 175, 64, 85, 2, 175, 136, 16, 78, 4, 154, 136, 16, + 78, 215, 144, 1, 73, 4, 246, 135, 16, 78, 215, 144, 1, 85, 4, 158, 144, + 16, 84, 183, 56, 79, 174, 3, 160, 1, 11, 68, 69, 32, 75, 73, 75, 65, 75, + 85, 73, 32, 244, 130, 16, 20, 79, 82, 65, 72, 32, 87, 73, 84, 72, 32, 78, + 73, 78, 69, 32, 66, 82, 65, 78, 67, 95, 83, 170, 3, 148, 1, 17, 67, 79, + 77, 66, 73, 78, 73, 78, 71, 32, 78, 85, 77, 66, 69, 82, 32, 164, 1, 10, + 83, 89, 76, 76, 65, 66, 76, 69, 32, 77, 199, 144, 9, 68, 14, 62, 84, 56, + 7, 72, 85, 78, 68, 82, 69, 68, 243, 177, 4, 77, 8, 26, 69, 187, 178, 4, + 72, 6, 26, 78, 187, 230, 13, 69, 4, 140, 178, 4, 2, 32, 84, 191, 226, 12, + 83, 138, 3, 22, 48, 167, 21, 49, 198, 1, 118, 48, 250, 1, 49, 210, 1, 50, + 138, 2, 51, 254, 1, 52, 150, 2, 53, 158, 2, 54, 238, 1, 55, 142, 2, 56, + 187, 2, 57, 18, 142, 1, 49, 34, 50, 22, 51, 22, 52, 218, 149, 2, 53, 142, + 230, 3, 56, 180, 149, 10, 3, 57, 32, 77, 92, 3, 55, 32, 77, 213, 90, 3, + 54, 32, 87, 2, 11, 32, 2, 147, 254, 16, 75, 2, 239, 136, 17, 32, 2, 183, + 239, 11, 32, 2, 11, 32, 2, 203, 253, 16, 87, 20, 130, 1, 49, 22, 54, 18, + 56, 22, 57, 200, 28, 2, 48, 32, 138, 161, 7, 53, 130, 190, 5, 52, 226, + 10, 55, 222, 9, 50, 199, 191, 3, 51, 2, 227, 226, 16, 32, 2, 143, 25, 32, + 2, 139, 170, 13, 32, 2, 191, 209, 12, 32, 20, 106, 49, 22, 50, 22, 51, + 22, 52, 22, 53, 22, 54, 22, 55, 22, 57, 158, 186, 11, 48, 253, 232, 1, 2, + 56, 32, 2, 155, 144, 10, 32, 2, 195, 234, 9, 32, 2, 223, 233, 16, 32, 2, + 215, 233, 11, 32, 2, 131, 191, 12, 32, 2, 215, 235, 16, 32, 2, 143, 185, + 12, 32, 2, 191, 28, 32, 20, 174, 1, 48, 16, 2, 49, 32, 20, 2, 52, 32, 20, + 2, 56, 32, 230, 186, 4, 57, 238, 51, 50, 22, 53, 188, 201, 7, 2, 54, 32, + 244, 211, 3, 3, 55, 32, 78, 213, 90, 3, 51, 32, 89, 2, 187, 37, 32, 2, + 159, 248, 16, 89, 2, 139, 248, 16, 70, 2, 155, 196, 15, 78, 20, 184, 1, + 2, 48, 32, 20, 2, 51, 32, 30, 53, 22, 56, 164, 8, 3, 52, 32, 75, 252, 21, + 3, 54, 32, 72, 230, 2, 55, 170, 205, 4, 49, 212, 164, 4, 3, 57, 32, 87, + 245, 181, 5, 3, 50, 32, 72, 2, 203, 157, 15, 72, 2, 177, 199, 16, 2, 78, + 71, 2, 223, 252, 10, 32, 2, 187, 234, 16, 32, 20, 178, 1, 48, 18, 53, 20, + 2, 54, 32, 20, 2, 56, 32, 22, 57, 172, 190, 9, 2, 50, 32, 236, 4, 2, 51, + 32, 166, 200, 1, 49, 164, 187, 3, 3, 52, 32, 76, 213, 137, 1, 3, 55, 32, + 78, 2, 143, 4, 32, 2, 183, 195, 15, 32, 2, 167, 218, 16, 71, 2, 227, 236, + 12, 78, 2, 177, 182, 15, 2, 32, 77, 20, 192, 1, 2, 50, 32, 22, 54, 242, + 25, 51, 164, 2, 3, 55, 32, 78, 52, 3, 49, 32, 87, 156, 215, 1, 2, 52, 32, + 206, 143, 3, 56, 156, 255, 4, 3, 48, 32, 78, 174, 92, 57, 137, 186, 4, 3, + 53, 32, 75, 2, 159, 216, 16, 77, 2, 195, 254, 9, 32, 20, 184, 1, 3, 52, + 32, 75, 20, 2, 53, 32, 20, 2, 55, 32, 22, 57, 178, 9, 51, 234, 11, 50, + 144, 2, 3, 49, 32, 71, 40, 3, 48, 32, 71, 144, 171, 14, 3, 54, 32, 75, + 149, 84, 3, 56, 32, 70, 2, 251, 222, 16, 80, 2, 251, 236, 16, 70, 2, 199, + 228, 16, 86, 2, 139, 171, 8, 32, 20, 228, 1, 2, 48, 32, 20, 2, 49, 32, + 20, 2, 52, 32, 22, 53, 248, 13, 6, 54, 32, 76, 79, 78, 71, 152, 12, 2, + 57, 32, 160, 167, 3, 3, 51, 32, 72, 132, 252, 8, 4, 50, 32, 78, 71, 164, + 195, 3, 3, 55, 32, 72, 165, 97, 3, 56, 32, 70, 2, 215, 234, 16, 89, 2, + 227, 148, 15, 80, 2, 207, 148, 15, 76, 2, 171, 132, 16, 32, 20, 230, 1, + 53, 164, 14, 4, 48, 32, 78, 71, 172, 8, 3, 51, 32, 71, 244, 243, 11, 2, + 55, 32, 214, 118, 57, 252, 88, 3, 50, 32, 75, 172, 184, 1, 3, 49, 32, 84, + 192, 27, 4, 56, 32, 78, 89, 148, 129, 1, 3, 52, 32, 77, 213, 34, 2, 54, + 32, 2, 155, 207, 16, 32, 196, 1, 118, 48, 154, 2, 49, 210, 2, 50, 170, 2, + 51, 222, 1, 52, 162, 2, 53, 214, 2, 54, 166, 2, 55, 238, 2, 56, 231, 2, + 57, 20, 222, 1, 49, 30, 52, 172, 11, 6, 54, 32, 76, 79, 78, 71, 164, 4, + 6, 53, 32, 76, 79, 78, 71, 24, 2, 51, 32, 162, 229, 4, 50, 230, 152, 2, + 48, 204, 249, 4, 3, 55, 32, 71, 252, 135, 3, 3, 57, 32, 89, 197, 39, 3, + 56, 32, 75, 2, 205, 180, 15, 2, 32, 70, 2, 157, 187, 14, 2, 32, 84, 20, + 208, 1, 6, 48, 32, 76, 79, 78, 71, 22, 51, 34, 54, 22, 56, 32, 2, 57, 32, + 156, 18, 4, 53, 32, 78, 71, 224, 206, 2, 2, 55, 32, 192, 145, 2, 3, 50, + 32, 75, 140, 198, 9, 3, 52, 32, 87, 145, 254, 1, 2, 49, 32, 2, 211, 216, + 15, 32, 2, 11, 32, 2, 131, 227, 16, 74, 2, 207, 240, 15, 32, 2, 11, 32, + 2, 207, 226, 16, 87, 2, 155, 236, 14, 78, 20, 230, 1, 50, 32, 2, 51, 32, + 232, 3, 3, 52, 32, 71, 182, 10, 48, 220, 147, 7, 2, 57, 32, 176, 196, 2, + 4, 56, 32, 72, 79, 248, 207, 2, 5, 55, 32, 78, 71, 71, 236, 90, 2, 53, + 32, 180, 249, 1, 3, 54, 32, 87, 129, 148, 1, 2, 49, 32, 2, 11, 32, 2, + 203, 247, 12, 77, 2, 11, 78, 2, 143, 227, 16, 68, 20, 172, 8, 3, 52, 32, + 78, 204, 2, 2, 56, 32, 224, 233, 4, 3, 50, 32, 75, 194, 195, 2, 49, 2, + 53, 216, 173, 2, 2, 55, 32, 152, 208, 4, 3, 51, 32, 70, 0, 3, 54, 32, 83, + 164, 50, 2, 48, 32, 225, 145, 1, 3, 57, 32, 87, 20, 232, 1, 3, 53, 32, + 77, 22, 54, 224, 2, 3, 57, 32, 78, 172, 4, 6, 50, 32, 76, 79, 78, 71, + 130, 196, 6, 55, 140, 151, 3, 3, 51, 32, 87, 200, 212, 2, 2, 48, 32, 220, + 60, 3, 56, 32, 71, 244, 190, 1, 3, 49, 32, 89, 1, 3, 52, 32, 86, 2, 179, + 223, 16, 66, 2, 129, 191, 15, 3, 32, 78, 71, 20, 192, 1, 2, 50, 32, 34, + 52, 26, 53, 34, 54, 36, 2, 55, 32, 244, 7, 2, 48, 32, 180, 225, 9, 3, 56, + 32, 75, 148, 182, 2, 2, 49, 32, 148, 225, 2, 5, 57, 32, 78, 71, 71, 249, + 204, 1, 2, 51, 32, 2, 11, 78, 2, 207, 238, 16, 74, 2, 213, 5, 2, 32, 77, + 2, 11, 32, 2, 247, 220, 16, 71, 2, 241, 175, 14, 4, 32, 78, 71, 71, 2, + 227, 131, 15, 74, 20, 220, 1, 2, 48, 32, 20, 6, 49, 32, 76, 79, 78, 71, + 30, 56, 204, 2, 2, 55, 32, 128, 170, 9, 3, 52, 32, 78, 200, 48, 4, 54, + 32, 71, 85, 152, 208, 4, 2, 53, 32, 148, 84, 3, 50, 32, 83, 0, 2, 51, 32, + 185, 98, 2, 57, 32, 2, 219, 173, 14, 74, 2, 221, 249, 11, 2, 32, 77, 2, + 183, 170, 12, 32, 20, 198, 1, 50, 46, 52, 40, 6, 53, 32, 76, 79, 78, 71, + 28, 3, 55, 32, 78, 34, 56, 152, 199, 11, 2, 54, 32, 156, 99, 3, 57, 32, + 75, 160, 212, 2, 3, 51, 32, 86, 156, 108, 4, 48, 32, 78, 89, 207, 53, 49, + 2, 11, 32, 2, 11, 77, 2, 183, 171, 14, 66, 2, 17, 2, 32, 77, 2, 227, 204, + 16, 66, 2, 205, 204, 16, 2, 32, 74, 2, 11, 71, 2, 231, 163, 15, 85, 2, + 147, 154, 15, 32, 20, 208, 1, 2, 48, 32, 22, 49, 22, 50, 32, 6, 51, 32, + 76, 79, 78, 71, 34, 56, 252, 241, 8, 2, 53, 32, 152, 126, 3, 52, 32, 78, + 188, 182, 2, 2, 54, 32, 228, 210, 2, 4, 55, 32, 77, 66, 145, 30, 4, 57, + 32, 77, 85, 2, 215, 168, 14, 68, 2, 215, 238, 9, 32, 2, 11, 32, 2, 147, + 213, 16, 86, 2, 253, 222, 14, 3, 32, 78, 71, 2, 17, 2, 32, 77, 2, 239, + 251, 14, 66, 16, 142, 1, 48, 32, 3, 49, 32, 78, 20, 3, 50, 32, 78, 20, 2, + 51, 32, 20, 3, 52, 32, 87, 22, 53, 20, 2, 54, 32, 169, 165, 12, 3, 55, + 32, 70, 2, 11, 32, 2, 191, 250, 14, 71, 2, 171, 250, 14, 68, 2, 227, 193, + 16, 74, 2, 215, 150, 16, 72, 2, 203, 210, 16, 85, 2, 219, 158, 15, 32, 2, + 227, 144, 1, 83, 248, 1, 68, 6, 79, 73, 84, 73, 67, 32, 250, 145, 10, 80, + 241, 70, 2, 67, 85, 244, 1, 104, 8, 67, 85, 82, 83, 73, 86, 69, 32, 221, + 10, 13, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, 67, 32, 180, 1, 96, + 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 250, 2, 76, 133, 3, 7, 78, 85, 77, + 66, 69, 82, 32, 24, 78, 69, 50, 70, 44, 4, 79, 78, 69, 32, 46, 83, 50, + 84, 61, 3, 78, 73, 78, 4, 160, 1, 2, 76, 69, 93, 4, 73, 71, 72, 84, 4, + 192, 1, 2, 73, 86, 13, 3, 79, 85, 82, 4, 232, 225, 14, 4, 84, 87, 69, 76, + 19, 72, 4, 26, 69, 93, 2, 73, 88, 2, 65, 2, 86, 69, 6, 46, 69, 12, 3, 72, + 82, 69, 13, 2, 87, 79, 2, 23, 78, 2, 11, 69, 2, 197, 227, 14, 5, 32, 84, + 87, 69, 76, 52, 76, 6, 69, 84, 84, 69, 82, 32, 137, 2, 8, 79, 71, 79, 71, + 82, 65, 77, 32, 48, 182, 1, 65, 46, 84, 146, 234, 1, 78, 2, 83, 206, 252, + 12, 72, 138, 176, 1, 75, 254, 68, 66, 2, 68, 2, 76, 2, 77, 2, 80, 2, 81, + 2, 82, 2, 87, 2, 89, 186, 2, 69, 2, 73, 3, 79, 5, 149, 139, 11, 6, 82, + 67, 72, 65, 73, 67, 6, 150, 222, 16, 65, 2, 69, 3, 79, 4, 174, 201, 4, + 73, 153, 248, 11, 2, 82, 77, 104, 92, 5, 69, 73, 71, 72, 84, 30, 70, 92, + 4, 78, 73, 78, 69, 54, 83, 78, 84, 73, 2, 79, 78, 11, 150, 1, 89, 223, 1, + 32, 24, 18, 73, 35, 79, 12, 142, 2, 86, 139, 228, 3, 70, 12, 148, 2, 2, + 85, 82, 227, 227, 3, 82, 11, 28, 2, 84, 89, 223, 1, 32, 2, 231, 141, 6, + 32, 24, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 13, 154, 1, 32, 227, 227, 3, + 84, 28, 34, 72, 50, 87, 159, 140, 6, 69, 12, 32, 2, 82, 69, 215, 227, 3, + 73, 8, 39, 69, 12, 26, 79, 215, 227, 3, 69, 9, 11, 32, 6, 194, 138, 6, + 72, 171, 167, 5, 84, 64, 96, 7, 76, 69, 84, 84, 69, 82, 32, 229, 160, 3, + 11, 83, 89, 77, 66, 79, 76, 32, 86, 73, 68, 74, 60, 174, 1, 66, 2, 82, + 22, 78, 30, 83, 38, 84, 174, 223, 14, 72, 138, 176, 1, 75, 254, 68, 68, + 2, 76, 2, 77, 2, 80, 2, 81, 2, 87, 2, 89, 186, 2, 65, 2, 69, 2, 73, 3, + 79, 4, 179, 159, 3, 65, 8, 158, 159, 3, 65, 3, 69, 6, 130, 159, 3, 65, + 139, 184, 13, 69, 10, 222, 158, 3, 65, 2, 69, 139, 184, 13, 79, 2, 175, + 252, 11, 73, 20, 44, 5, 73, 67, 65, 76, 32, 251, 213, 16, 79, 18, 116, + 10, 76, 79, 78, 71, 32, 79, 86, 69, 82, 32, 74, 80, 26, 84, 168, 1, 7, + 83, 72, 79, 82, 84, 32, 79, 187, 32, 66, 4, 188, 244, 2, 2, 83, 72, 185, + 180, 10, 7, 84, 87, 79, 32, 83, 72, 79, 2, 109, 3, 69, 78, 84, 8, 66, 69, + 34, 82, 41, 10, 87, 79, 32, 83, 72, 79, 82, 84, 83, 32, 2, 17, 2, 84, 82, + 2, 23, 65, 2, 11, 73, 2, 217, 187, 15, 2, 83, 69, 4, 26, 79, 179, 231, 7, + 74, 2, 137, 162, 10, 4, 86, 69, 82, 32, 224, 2, 100, 3, 65, 79, 32, 136, + 18, 2, 67, 82, 142, 1, 68, 118, 76, 130, 1, 78, 245, 2, 4, 82, 82, 79, + 82, 170, 2, 156, 1, 7, 76, 69, 84, 84, 69, 82, 32, 180, 10, 5, 83, 73, + 71, 78, 32, 212, 1, 5, 84, 79, 78, 69, 32, 69, 11, 86, 79, 87, 69, 76, + 32, 83, 73, 71, 78, 32, 178, 1, 214, 1, 65, 110, 66, 34, 68, 106, 71, 34, + 76, 50, 78, 106, 82, 170, 1, 83, 54, 84, 218, 1, 86, 32, 3, 89, 73, 32, + 118, 90, 238, 247, 12, 81, 230, 200, 1, 80, 242, 190, 1, 72, 2, 77, 254, + 68, 70, 2, 75, 2, 87, 3, 88, 10, 52, 7, 82, 67, 72, 65, 73, 67, 32, 179, + 206, 16, 72, 8, 254, 231, 8, 90, 170, 151, 4, 78, 211, 204, 3, 77, 4, + 162, 186, 16, 82, 219, 19, 65, 16, 50, 90, 154, 4, 76, 218, 198, 16, 68, + 187, 2, 65, 8, 206, 185, 16, 89, 162, 17, 72, 2, 90, 187, 2, 65, 6, 190, + 133, 16, 72, 183, 71, 65, 8, 238, 150, 10, 72, 174, 179, 6, 89, 187, 2, + 65, 18, 54, 65, 186, 132, 16, 71, 2, 78, 2, 89, 255, 68, 72, 5, 11, 83, + 2, 169, 159, 13, 4, 65, 76, 73, 90, 16, 60, 9, 69, 70, 79, 82, 77, 69, + 68, 32, 84, 171, 180, 16, 84, 14, 40, 4, 79, 78, 69, 45, 151, 211, 14, + 83, 12, 206, 202, 16, 49, 2, 50, 2, 52, 2, 53, 2, 54, 3, 56, 8, 186, 182, + 16, 89, 162, 17, 72, 2, 83, 187, 2, 65, 32, 78, 76, 20, 4, 79, 78, 69, + 45, 70, 83, 130, 198, 16, 84, 186, 2, 65, 3, 69, 4, 171, 147, 10, 72, 14, + 250, 200, 16, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 8, 254, 197, + 16, 72, 2, 83, 186, 2, 65, 3, 69, 4, 206, 197, 16, 70, 187, 2, 65, 16, + 70, 84, 228, 207, 14, 2, 68, 90, 250, 60, 78, 142, 184, 1, 75, 3, 80, 8, + 234, 255, 15, 83, 254, 68, 84, 187, 2, 65, 16, 50, 90, 142, 255, 15, 83, + 254, 68, 72, 187, 2, 65, 8, 218, 144, 10, 83, 174, 179, 6, 89, 187, 2, + 65, 8, 144, 1, 9, 82, 69, 70, 79, 82, 77, 69, 68, 32, 34, 65, 145, 245, + 13, 18, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 77, 79, 68, 73, 70, 73, + 69, 82, 4, 30, 65, 189, 88, 2, 86, 79, 2, 225, 230, 11, 3, 83, 80, 73, 8, + 130, 172, 14, 66, 168, 74, 3, 84, 79, 80, 182, 81, 65, 143, 82, 82, 104, + 146, 1, 65, 78, 69, 62, 73, 78, 79, 74, 85, 74, 89, 180, 250, 6, 9, 82, + 79, 85, 78, 68, 69, 68, 32, 69, 206, 134, 7, 87, 238, 70, 78, 135, 122, + 86, 19, 206, 202, 14, 78, 130, 184, 1, 69, 134, 63, 72, 146, 1, 65, 2, + 73, 3, 85, 15, 242, 222, 12, 82, 146, 235, 1, 78, 150, 248, 1, 65, 3, 73, + 23, 186, 201, 14, 65, 54, 79, 154, 247, 1, 78, 86, 69, 2, 71, 2, 73, 3, + 85, 13, 42, 69, 230, 192, 16, 71, 2, 79, 3, 85, 4, 226, 192, 16, 82, 3, + 89, 19, 166, 200, 14, 65, 202, 228, 1, 69, 134, 19, 78, 2, 79, 86, 73, 3, + 85, 7, 166, 172, 16, 85, 219, 19, 73, 12, 18, 32, 63, 79, 4, 172, 172, + 15, 4, 79, 78, 32, 85, 13, 4, 68, 65, 83, 72, 8, 190, 189, 11, 83, 158, + 216, 3, 80, 218, 34, 32, 139, 112, 66, 6, 64, 4, 68, 76, 69, 32, 173, + 215, 4, 6, 76, 73, 78, 69, 32, 72, 4, 152, 180, 5, 3, 84, 72, 73, 203, + 185, 10, 68, 8, 76, 6, 73, 84, 65, 82, 89, 32, 172, 153, 10, 3, 75, 89, + 32, 255, 156, 5, 76, 4, 26, 72, 187, 134, 12, 77, 2, 163, 170, 4, 69, 24, + 42, 73, 76, 2, 85, 83, 235, 187, 16, 89, 6, 34, 68, 22, 77, 147, 185, 14, + 66, 2, 195, 137, 6, 73, 2, 187, 212, 6, 73, 16, 46, 32, 201, 142, 10, 5, + 45, 79, 82, 45, 80, 14, 40, 4, 83, 73, 71, 78, 231, 249, 12, 84, 13, 11, + 32, 10, 44, 5, 87, 73, 84, 72, 32, 239, 153, 6, 73, 8, 66, 67, 182, 195, + 4, 68, 206, 135, 8, 82, 21, 4, 70, 65, 76, 76, 2, 129, 195, 11, 3, 79, + 77, 77, 5, 163, 181, 14, 32, 182, 9, 184, 1, 10, 66, 73, 76, 69, 32, 80, + 72, 79, 78, 69, 166, 1, 68, 190, 76, 78, 174, 27, 79, 156, 1, 3, 83, 81, + 85, 38, 84, 250, 1, 85, 242, 140, 11, 89, 217, 178, 2, 5, 86, 73, 69, 32, + 67, 7, 11, 32, 4, 108, 21, 87, 73, 84, 72, 32, 82, 73, 71, 72, 84, 87, + 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 255, 177, 1, 79, 2, 11, 32, 2, + 213, 132, 16, 2, 65, 84, 154, 6, 58, 69, 74, 73, 149, 75, 7, 85, 76, 79, + 32, 84, 87, 79, 4, 196, 230, 15, 10, 82, 78, 32, 80, 69, 78, 84, 65, 84, + 72, 159, 18, 76, 148, 6, 42, 32, 221, 1, 5, 70, 73, 69, 82, 32, 158, 1, + 88, 5, 83, 73, 71, 78, 32, 210, 172, 3, 86, 178, 146, 3, 68, 182, 1, 76, + 167, 180, 4, 65, 10, 42, 65, 234, 189, 8, 72, 203, 179, 7, 86, 4, 44, 5, + 82, 68, 72, 65, 67, 163, 239, 15, 78, 2, 201, 239, 15, 3, 65, 78, 68, + 246, 4, 92, 12, 66, 82, 69, 86, 69, 32, 87, 73, 84, 72, 32, 73, 89, 7, + 76, 69, 84, 84, 69, 82, 32, 2, 33, 6, 78, 86, 69, 82, 84, 69, 2, 21, 3, + 68, 32, 66, 2, 249, 181, 15, 2, 82, 69, 244, 4, 198, 1, 65, 82, 66, 66, + 67, 190, 13, 68, 194, 1, 69, 182, 2, 71, 82, 72, 46, 76, 230, 4, 77, 216, + 3, 7, 79, 80, 69, 78, 32, 83, 72, 22, 80, 38, 82, 182, 4, 83, 214, 33, + 84, 114, 85, 118, 86, 63, 89, 6, 38, 76, 150, 27, 67, 183, 167, 10, 80, + 2, 237, 19, 6, 86, 69, 79, 76, 65, 82, 6, 176, 19, 5, 73, 76, 65, 66, 73, + 201, 45, 4, 69, 71, 73, 78, 160, 1, 240, 1, 7, 65, 80, 73, 84, 65, 76, + 32, 192, 2, 7, 69, 78, 84, 82, 69, 68, 32, 100, 13, 72, 73, 78, 69, 83, + 69, 32, 84, 79, 78, 69, 32, 89, 108, 8, 89, 82, 73, 76, 76, 73, 67, 32, + 166, 188, 10, 73, 244, 2, 4, 82, 79, 83, 83, 191, 154, 5, 79, 56, 206, 1, + 66, 42, 82, 250, 26, 72, 198, 193, 12, 79, 138, 143, 3, 65, 150, 64, 67, + 2, 68, 2, 69, 2, 70, 2, 71, 2, 73, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, + 80, 2, 81, 2, 84, 2, 85, 2, 86, 3, 87, 5, 237, 130, 6, 5, 65, 82, 82, 69, + 68, 7, 41, 8, 69, 86, 69, 82, 83, 69, 68, 32, 4, 170, 171, 16, 69, 3, 78, + 4, 30, 76, 21, 3, 82, 73, 71, 2, 29, 2, 69, 70, 2, 11, 72, 2, 11, 84, 2, + 173, 26, 2, 32, 72, 16, 36, 3, 65, 78, 71, 1, 2, 73, 78, 8, 11, 32, 8, + 170, 226, 11, 83, 214, 246, 3, 80, 146, 44, 81, 3, 82, 78, 34, 72, 30, + 83, 175, 217, 15, 69, 2, 197, 195, 14, 2, 65, 82, 74, 40, 5, 77, 65, 76, + 76, 32, 183, 6, 79, 72, 186, 1, 66, 138, 1, 68, 38, 69, 150, 1, 80, 58, + 83, 94, 84, 34, 89, 158, 163, 15, 90, 246, 63, 73, 138, 19, 67, 2, 71, + 186, 22, 74, 2, 86, 158, 20, 72, 2, 75, 186, 2, 65, 2, 79, 3, 85, 6, 38, + 89, 186, 27, 65, 187, 139, 16, 69, 2, 221, 201, 1, 19, 69, 76, 79, 82, + 85, 83, 83, 73, 65, 78, 45, 85, 75, 82, 65, 73, 78, 73, 65, 4, 206, 190, + 6, 90, 195, 231, 9, 69, 15, 50, 83, 186, 165, 16, 70, 2, 76, 2, 77, 3, + 82, 5, 25, 4, 32, 87, 73, 84, 2, 21, 3, 72, 32, 68, 2, 11, 69, 2, 205, + 223, 12, 3, 83, 67, 69, 4, 26, 65, 191, 164, 16, 69, 2, 241, 247, 15, 2, + 76, 79, 8, 42, 84, 198, 172, 1, 67, 251, 244, 14, 72, 4, 145, 19, 8, 82, + 65, 73, 71, 72, 84, 32, 85, 4, 238, 140, 16, 83, 215, 22, 69, 6, 36, 3, + 69, 82, 85, 255, 162, 16, 85, 5, 37, 7, 32, 87, 73, 84, 72, 32, 66, 2, + 21, 3, 65, 67, 75, 2, 217, 228, 15, 2, 32, 89, 2, 191, 139, 11, 70, 16, + 18, 69, 27, 79, 2, 161, 5, 2, 78, 84, 14, 64, 2, 84, 32, 44, 5, 85, 66, + 76, 69, 32, 137, 52, 2, 87, 78, 6, 178, 192, 9, 83, 194, 144, 4, 72, 43, + 86, 4, 254, 135, 2, 65, 215, 240, 2, 80, 24, 40, 5, 88, 84, 82, 65, 45, + 139, 49, 78, 20, 52, 5, 72, 73, 71, 72, 32, 81, 4, 76, 79, 87, 32, 10, + 156, 1, 9, 69, 88, 84, 82, 65, 45, 76, 79, 87, 154, 7, 68, 70, 76, 79, + 84, 10, 76, 10, 69, 88, 84, 82, 65, 45, 72, 73, 71, 72, 154, 7, 68, 70, + 76, 79, 84, 2, 145, 8, 8, 32, 67, 79, 78, 84, 79, 85, 82, 8, 162, 9, 82, + 226, 3, 76, 237, 238, 14, 9, 69, 79, 82, 71, 73, 65, 78, 32, 78, 10, 248, + 5, 4, 73, 71, 72, 32, 135, 41, 65, 44, 46, 65, 84, 2, 79, 87, 201, 11, 2, + 69, 70, 2, 21, 3, 84, 69, 82, 2, 17, 2, 65, 76, 2, 17, 2, 32, 67, 2, 211, + 237, 14, 76, 36, 86, 32, 245, 231, 11, 15, 69, 82, 32, 82, 73, 71, 72, + 84, 32, 67, 79, 82, 78, 69, 82, 34, 158, 1, 67, 20, 2, 68, 79, 40, 4, 76, + 69, 70, 84, 82, 77, 12, 2, 82, 73, 50, 84, 178, 3, 65, 42, 71, 170, 2, + 73, 136, 196, 13, 2, 85, 80, 235, 180, 1, 86, 2, 131, 173, 10, 73, 6, + 238, 2, 84, 205, 200, 13, 2, 87, 78, 6, 28, 2, 32, 65, 247, 2, 45, 4, 25, + 4, 82, 82, 79, 87, 5, 151, 203, 13, 72, 2, 111, 65, 4, 180, 202, 13, 3, + 71, 72, 84, 255, 205, 2, 78, 4, 194, 2, 79, 155, 128, 14, 73, 18, 18, 65, + 23, 73, 2, 151, 244, 14, 67, 16, 26, 68, 163, 254, 12, 78, 14, 38, 32, + 217, 1, 4, 68, 76, 69, 32, 8, 26, 68, 70, 76, 79, 84, 4, 17, 2, 79, 84, + 4, 25, 4, 84, 69, 68, 32, 4, 18, 76, 79, 84, 2, 25, 4, 69, 70, 84, 45, 2, + 25, 4, 83, 84, 69, 77, 2, 17, 2, 32, 84, 2, 11, 79, 2, 11, 78, 2, 187, + 198, 13, 69, 6, 40, 6, 68, 79, 85, 66, 76, 69, 75, 71, 4, 11, 32, 4, 18, + 65, 43, 71, 2, 11, 67, 2, 229, 170, 10, 2, 85, 84, 2, 11, 82, 2, 179, + 170, 10, 65, 2, 207, 148, 14, 69, 4, 246, 250, 12, 76, 247, 129, 2, 82, + 26, 104, 6, 65, 73, 83, 69, 68, 32, 150, 1, 69, 216, 1, 3, 73, 71, 72, + 173, 222, 8, 5, 72, 79, 84, 73, 67, 10, 70, 68, 30, 73, 234, 186, 9, 69, + 180, 189, 5, 2, 85, 80, 199, 74, 67, 2, 129, 197, 14, 2, 79, 87, 2, 209, + 186, 9, 7, 78, 86, 69, 82, 84, 69, 68, 8, 104, 7, 86, 69, 82, 83, 69, 68, + 32, 133, 28, 14, 84, 82, 79, 70, 76, 69, 88, 32, 67, 76, 73, 67, 75, 32, + 6, 26, 71, 255, 197, 13, 67, 4, 11, 76, 4, 49, 10, 79, 84, 84, 65, 76, + 32, 83, 84, 79, 80, 5, 167, 19, 32, 6, 17, 2, 84, 32, 6, 38, 72, 250, + 133, 13, 84, 231, 59, 65, 2, 185, 168, 7, 3, 65, 76, 70, 156, 2, 138, 1, + 72, 48, 5, 77, 65, 76, 76, 32, 156, 31, 8, 84, 82, 69, 83, 83, 32, 65, + 78, 53, 11, 85, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 4, 216, 130, 8, + 3, 79, 82, 84, 251, 139, 6, 69, 144, 2, 154, 2, 65, 46, 66, 130, 1, 67, + 238, 2, 68, 238, 2, 90, 66, 69, 46, 70, 30, 71, 110, 72, 102, 77, 34, 73, + 34, 74, 98, 76, 176, 3, 7, 78, 32, 87, 73, 84, 72, 32, 30, 79, 94, 80, + 22, 82, 146, 2, 83, 190, 1, 84, 130, 8, 85, 142, 1, 86, 134, 240, 15, 75, + 2, 81, 2, 87, 2, 88, 3, 89, 9, 238, 23, 76, 210, 164, 15, 73, 215, 79, + 69, 11, 46, 65, 50, 79, 222, 8, 32, 227, 221, 15, 69, 2, 17, 2, 82, 82, + 2, 181, 227, 5, 2, 69, 68, 2, 229, 20, 4, 84, 84, 79, 77, 41, 100, 7, 65, + 80, 73, 84, 65, 76, 32, 180, 1, 6, 76, 79, 83, 69, 68, 32, 190, 17, 32, + 187, 227, 15, 72, 30, 114, 73, 214, 6, 71, 238, 16, 76, 250, 218, 15, 79, + 158, 20, 65, 186, 2, 66, 2, 72, 2, 78, 2, 82, 2, 85, 3, 89, 7, 22, 78, + 191, 11, 32, 2, 237, 220, 5, 5, 86, 69, 82, 84, 69, 4, 26, 82, 175, 136, + 9, 79, 2, 229, 20, 9, 69, 86, 69, 82, 83, 69, 68, 32, 79, 23, 104, 6, 32, + 87, 73, 84, 72, 32, 86, 69, 32, 9, 79, 84, 76, 69, 83, 83, 32, 74, 32, + 105, 3, 90, 32, 68, 6, 26, 72, 247, 217, 13, 84, 4, 21, 3, 79, 79, 75, 5, + 201, 160, 13, 3, 32, 65, 78, 4, 238, 15, 90, 131, 210, 15, 76, 4, 33, 6, + 87, 73, 84, 72, 32, 83, 4, 29, 5, 84, 82, 79, 75, 69, 5, 177, 211, 8, 4, + 32, 65, 78, 68, 6, 33, 6, 73, 71, 82, 65, 80, 72, 7, 33, 6, 32, 87, 73, + 84, 72, 32, 4, 138, 14, 67, 219, 4, 82, 11, 190, 131, 16, 83, 2, 84, 2, + 90, 63, 78, 5, 225, 13, 3, 69, 78, 71, 11, 56, 5, 82, 69, 69, 75, 32, + 162, 1, 32, 151, 183, 13, 65, 4, 26, 71, 195, 223, 10, 80, 2, 151, 184, + 13, 65, 11, 40, 6, 32, 87, 73, 84, 72, 32, 39, 69, 4, 142, 178, 14, 72, + 231, 160, 1, 83, 4, 17, 2, 78, 71, 5, 11, 32, 2, 239, 207, 8, 87, 4, 222, + 4, 32, 239, 216, 15, 79, 5, 37, 7, 32, 87, 73, 84, 72, 32, 67, 2, 11, 82, + 2, 181, 212, 13, 6, 79, 83, 83, 69, 68, 45, 25, 116, 6, 32, 87, 73, 84, + 72, 32, 226, 9, 83, 2, 90, 112, 2, 69, 90, 241, 222, 15, 8, 73, 71, 65, + 84, 85, 82, 69, 32, 12, 54, 73, 82, 77, 82, 82, 222, 6, 80, 187, 237, 3, + 66, 2, 49, 10, 78, 86, 69, 82, 84, 69, 68, 32, 76, 65, 2, 189, 172, 12, + 2, 90, 89, 2, 11, 73, 2, 17, 2, 68, 68, 2, 17, 2, 76, 69, 2, 185, 189, + 12, 2, 32, 84, 4, 61, 13, 69, 84, 82, 79, 70, 76, 69, 88, 32, 72, 79, 79, + 75, 5, 217, 12, 4, 32, 65, 78, 68, 4, 222, 11, 82, 207, 1, 76, 9, 18, 32, + 47, 80, 2, 21, 3, 87, 73, 84, 2, 139, 205, 15, 72, 4, 241, 152, 12, 2, + 69, 78, 5, 151, 233, 15, 72, 15, 80, 6, 32, 87, 73, 84, 72, 32, 62, 65, + 41, 8, 69, 86, 69, 82, 83, 69, 68, 32, 4, 26, 70, 239, 206, 13, 84, 2, + 209, 201, 8, 3, 73, 83, 72, 2, 17, 2, 77, 83, 2, 247, 212, 5, 32, 6, 38, + 71, 182, 7, 79, 203, 243, 15, 69, 2, 11, 76, 2, 129, 176, 13, 4, 79, 84, + 84, 65, 13, 72, 6, 32, 87, 73, 84, 72, 32, 34, 67, 61, 6, 73, 68, 69, 87, + 65, 89, 4, 158, 3, 67, 131, 166, 14, 72, 4, 26, 82, 203, 180, 11, 72, 2, + 221, 199, 5, 3, 73, 80, 84, 2, 159, 167, 6, 83, 51, 106, 32, 102, 67, + 116, 2, 69, 83, 44, 2, 79, 80, 42, 83, 96, 6, 85, 82, 78, 69, 68, 32, + 207, 208, 12, 72, 4, 29, 5, 87, 73, 84, 72, 32, 4, 22, 80, 231, 5, 82, 2, + 197, 197, 8, 6, 65, 76, 65, 84, 65, 76, 2, 45, 9, 32, 68, 73, 71, 82, 65, + 80, 72, 32, 2, 25, 4, 87, 73, 84, 72, 2, 17, 2, 32, 67, 2, 195, 137, 3, + 85, 2, 11, 72, 2, 157, 241, 9, 3, 32, 68, 73, 2, 177, 206, 5, 5, 32, 72, + 65, 76, 70, 4, 37, 7, 32, 68, 73, 71, 82, 65, 80, 4, 11, 72, 5, 11, 32, + 2, 153, 3, 4, 87, 73, 84, 72, 32, 86, 65, 50, 77, 74, 79, 42, 82, 214, 1, + 89, 206, 241, 15, 72, 2, 73, 2, 86, 3, 87, 7, 26, 76, 167, 244, 15, 69, + 2, 231, 252, 13, 80, 5, 41, 8, 32, 87, 73, 84, 72, 32, 76, 79, 2, 221, + 133, 4, 2, 78, 71, 2, 11, 80, 2, 189, 133, 6, 2, 69, 78, 9, 33, 6, 32, + 87, 73, 84, 72, 32, 6, 26, 76, 131, 162, 14, 72, 4, 37, 7, 79, 78, 71, + 32, 76, 69, 71, 5, 25, 4, 32, 65, 78, 68, 2, 17, 2, 32, 82, 2, 11, 69, 2, + 213, 191, 8, 7, 84, 82, 79, 70, 76, 69, 88, 5, 29, 5, 32, 87, 73, 84, 72, + 2, 245, 230, 3, 2, 32, 66, 9, 18, 32, 95, 80, 4, 40, 4, 87, 73, 84, 72, + 171, 206, 14, 66, 2, 17, 2, 32, 76, 2, 11, 69, 2, 131, 1, 70, 2, 177, + 160, 15, 2, 83, 73, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 26, 82, 231, + 158, 14, 72, 2, 21, 3, 73, 71, 72, 2, 135, 189, 8, 84, 4, 11, 68, 4, 11, + 32, 4, 182, 208, 1, 72, 35, 76, 4, 24, 2, 72, 65, 31, 84, 2, 25, 4, 76, + 70, 32, 84, 2, 43, 82, 4, 30, 82, 53, 3, 85, 82, 78, 2, 237, 157, 15, 8, + 73, 65, 78, 71, 85, 76, 65, 82, 2, 161, 144, 8, 2, 69, 68, 8, 70, 80, + 140, 245, 9, 7, 78, 65, 83, 80, 73, 82, 65, 223, 247, 5, 83, 4, 11, 32, + 4, 190, 226, 12, 84, 231, 59, 65, 4, 26, 79, 199, 210, 14, 69, 2, 11, 73, + 2, 155, 155, 15, 67, 4, 36, 3, 65, 78, 71, 1, 2, 73, 78, 2, 25, 4, 32, + 68, 69, 80, 2, 21, 3, 65, 82, 84, 2, 21, 3, 73, 78, 71, 2, 17, 2, 32, 84, + 2, 11, 79, 2, 227, 238, 5, 78, 2, 11, 32, 2, 215, 194, 14, 83, 234, 2, + 92, 2, 69, 89, 88, 7, 71, 79, 76, 73, 65, 78, 32, 210, 24, 79, 209, 222, + 11, 3, 75, 69, 89, 6, 26, 32, 251, 171, 15, 45, 4, 184, 223, 11, 6, 87, + 73, 84, 72, 32, 87, 255, 163, 2, 66, 214, 2, 194, 2, 68, 46, 70, 148, 1, + 14, 73, 78, 86, 69, 82, 84, 69, 68, 32, 66, 73, 82, 71, 65, 16, 7, 76, + 69, 84, 84, 69, 82, 32, 142, 16, 83, 132, 1, 7, 82, 79, 84, 65, 84, 69, + 68, 22, 66, 98, 84, 160, 2, 4, 86, 79, 87, 69, 158, 233, 3, 67, 164, 1, + 6, 77, 65, 78, 67, 72, 85, 196, 162, 7, 4, 78, 73, 82, 85, 171, 166, 2, + 69, 22, 236, 20, 3, 79, 85, 66, 183, 227, 13, 73, 12, 112, 19, 82, 69, + 69, 32, 86, 65, 82, 73, 65, 84, 73, 79, 78, 32, 83, 69, 76, 69, 67, 158, + 154, 13, 85, 175, 46, 79, 8, 177, 207, 9, 3, 84, 79, 82, 5, 231, 19, 32, + 136, 2, 130, 2, 65, 244, 4, 2, 67, 72, 88, 2, 77, 65, 174, 2, 83, 250, 1, + 84, 234, 3, 90, 190, 229, 13, 72, 150, 168, 1, 75, 2, 76, 162, 7, 69, 2, + 79, 2, 85, 222, 61, 66, 2, 68, 2, 70, 2, 71, 2, 74, 2, 78, 2, 80, 2, 81, + 2, 82, 2, 87, 2, 89, 187, 2, 73, 59, 56, 8, 76, 73, 32, 71, 65, 76, 73, + 32, 207, 225, 15, 78, 54, 174, 1, 65, 52, 6, 86, 73, 83, 65, 82, 71, 22, + 68, 76, 5, 72, 65, 76, 70, 32, 34, 73, 50, 85, 34, 78, 30, 84, 66, 66, + 222, 150, 15, 80, 2, 90, 242, 68, 83, 14, 67, 3, 75, 7, 48, 6, 78, 85, + 83, 86, 65, 82, 191, 224, 15, 72, 2, 131, 134, 9, 65, 8, 26, 65, 215, + 221, 15, 68, 7, 214, 222, 8, 77, 253, 190, 6, 3, 71, 65, 76, 4, 162, 221, + 15, 89, 187, 2, 85, 5, 45, 9, 78, 86, 69, 82, 84, 69, 68, 32, 85, 2, 169, + 156, 15, 3, 66, 65, 68, 4, 178, 220, 15, 71, 3, 78, 8, 60, 6, 72, 82, 69, + 69, 32, 66, 222, 150, 15, 84, 183, 71, 65, 2, 17, 2, 65, 76, 2, 247, 184, + 15, 85, 6, 26, 65, 207, 221, 15, 73, 5, 29, 5, 32, 87, 73, 84, 72, 2, + 201, 143, 14, 2, 32, 84, 41, 29, 5, 78, 67, 72, 85, 32, 38, 104, 9, 65, + 76, 73, 32, 71, 65, 76, 73, 32, 202, 228, 13, 90, 134, 245, 1, 70, 2, 75, + 2, 82, 187, 2, 73, 28, 122, 68, 166, 165, 9, 67, 158, 164, 1, 84, 142, + 154, 3, 66, 2, 71, 2, 74, 2, 76, 138, 176, 1, 90, 254, 4, 78, 247, 63, + 83, 4, 202, 227, 13, 68, 135, 245, 1, 72, 48, 52, 4, 73, 66, 69, 32, 246, + 215, 15, 72, 187, 2, 65, 44, 186, 215, 2, 84, 162, 243, 2, 71, 2, 72, + 218, 156, 6, 73, 190, 251, 1, 67, 2, 83, 246, 7, 82, 222, 158, 1, 65, + 186, 9, 90, 162, 7, 85, 222, 61, 68, 2, 70, 2, 74, 2, 75, 2, 80, 187, 2, + 69, 60, 52, 4, 79, 68, 79, 32, 254, 213, 15, 83, 187, 2, 65, 56, 250, 1, + 65, 98, 68, 34, 74, 34, 78, 176, 163, 1, 8, 76, 79, 78, 71, 32, 86, 79, + 87, 250, 174, 1, 84, 162, 243, 2, 71, 150, 152, 8, 67, 246, 7, 72, 182, + 175, 1, 79, 2, 85, 222, 61, 66, 2, 75, 2, 77, 2, 80, 2, 81, 2, 87, 2, 89, + 186, 2, 69, 3, 73, 6, 56, 8, 76, 73, 32, 71, 65, 76, 73, 32, 171, 213, + 15, 78, 4, 190, 222, 13, 90, 135, 245, 1, 84, 4, 158, 211, 15, 90, 187, + 2, 65, 4, 254, 210, 15, 73, 187, 2, 65, 2, 223, 210, 15, 73, 6, 170, 193, + 15, 72, 162, 17, 82, 187, 2, 65, 8, 128, 1, 4, 87, 73, 82, 76, 149, 181, + 4, 21, 73, 66, 69, 32, 83, 89, 76, 76, 65, 66, 76, 69, 32, 66, 79, 85, + 78, 68, 65, 82, 89, 6, 17, 2, 32, 66, 6, 25, 4, 73, 82, 71, 65, 7, 33, 6, + 32, 87, 73, 84, 72, 32, 4, 150, 2, 68, 171, 141, 15, 79, 6, 152, 1, 3, + 82, 73, 80, 56, 18, 85, 82, 78, 69, 68, 32, 83, 87, 73, 82, 76, 32, 66, + 73, 82, 71, 65, 32, 245, 190, 1, 8, 79, 68, 79, 32, 83, 79, 70, 84, 2, + 209, 141, 15, 9, 76, 69, 32, 66, 73, 82, 71, 65, 32, 2, 33, 6, 87, 73, + 84, 72, 32, 68, 2, 145, 141, 15, 5, 79, 85, 66, 76, 69, 2, 131, 192, 9, + 76, 10, 96, 9, 71, 82, 65, 77, 32, 70, 79, 82, 32, 224, 251, 3, 5, 83, + 84, 65, 66, 76, 235, 166, 9, 82, 6, 26, 89, 243, 136, 12, 69, 4, 190, + 254, 14, 65, 155, 1, 73, 8, 48, 2, 78, 32, 162, 197, 4, 68, 231, 242, 10, + 83, 4, 72, 12, 86, 73, 69, 87, 73, 78, 71, 32, 67, 69, 82, 69, 147, 136, + 12, 67, 2, 177, 174, 15, 2, 77, 79, 4, 230, 129, 12, 73, 139, 204, 3, 69, + 10, 26, 72, 69, 2, 79, 82, 2, 45, 9, 69, 82, 32, 67, 72, 82, 73, 83, 84, + 2, 147, 247, 2, 77, 8, 50, 32, 52, 4, 73, 90, 69, 68, 155, 192, 14, 87, + 4, 230, 173, 8, 66, 133, 232, 5, 4, 83, 67, 79, 79, 2, 205, 168, 3, 7, + 32, 87, 72, 69, 69, 76, 67, 18, 52, 2, 78, 84, 152, 1, 2, 83, 69, 247, + 200, 15, 84, 10, 48, 3, 65, 73, 78, 185, 224, 11, 3, 32, 70, 85, 9, 11, + 32, 6, 222, 166, 9, 82, 24, 5, 67, 65, 66, 76, 69, 137, 235, 1, 6, 66, + 73, 67, 89, 67, 76, 7, 11, 32, 4, 160, 185, 14, 2, 84, 82, 219, 83, 70, + 86, 52, 7, 76, 69, 84, 84, 69, 82, 32, 191, 211, 5, 68, 62, 198, 1, 75, + 62, 77, 34, 78, 34, 79, 30, 80, 34, 84, 246, 104, 68, 220, 231, 7, 2, 72, + 65, 2, 82, 158, 180, 1, 69, 190, 29, 83, 150, 90, 76, 246, 7, 67, 246, + 162, 4, 89, 190, 28, 66, 2, 87, 187, 2, 65, 6, 180, 154, 5, 2, 69, 65, + 182, 238, 5, 72, 231, 190, 4, 79, 4, 230, 180, 15, 65, 215, 1, 73, 4, + 158, 247, 14, 73, 255, 59, 71, 7, 210, 198, 15, 76, 3, 79, 4, 222, 178, + 15, 72, 219, 19, 65, 6, 214, 246, 8, 72, 170, 204, 6, 69, 155, 3, 65, + 204, 4, 44, 2, 76, 84, 238, 6, 83, 159, 175, 13, 67, 102, 36, 4, 65, 78, + 73, 32, 223, 2, 73, 76, 52, 7, 76, 69, 84, 84, 69, 82, 32, 211, 139, 4, + 83, 74, 210, 1, 68, 222, 82, 78, 158, 230, 1, 82, 230, 208, 1, 74, 166, + 209, 7, 84, 206, 160, 3, 66, 2, 67, 2, 71, 2, 75, 2, 80, 254, 68, 72, 2, + 76, 2, 77, 2, 83, 2, 86, 2, 89, 186, 2, 65, 2, 69, 2, 73, 3, 85, 10, 38, + 68, 162, 192, 15, 72, 187, 2, 65, 6, 158, 192, 15, 68, 2, 72, 187, 2, 65, + 26, 56, 2, 80, 76, 236, 2, 3, 83, 69, 84, 183, 174, 14, 77, 18, 50, 69, + 89, 8, 73, 67, 65, 84, 73, 79, 78, 32, 2, 41, 8, 32, 77, 85, 83, 73, 67, + 65, 76, 2, 21, 3, 32, 78, 79, 2, 155, 173, 14, 84, 16, 40, 4, 83, 73, 71, + 78, 191, 192, 15, 88, 15, 11, 32, 12, 48, 3, 73, 78, 32, 81, 5, 87, 73, + 84, 72, 32, 8, 166, 199, 3, 76, 22, 82, 140, 246, 8, 5, 68, 79, 85, 66, + 76, 235, 222, 1, 84, 4, 210, 246, 11, 85, 167, 200, 2, 68, 7, 11, 32, 4, + 232, 82, 5, 77, 85, 76, 84, 73, 207, 209, 11, 85, 226, 3, 32, 2, 73, 67, + 247, 152, 3, 72, 224, 3, 30, 32, 101, 3, 65, 76, 32, 6, 76, 4, 78, 65, + 84, 85, 200, 43, 2, 70, 76, 181, 229, 10, 4, 83, 72, 65, 82, 2, 239, 165, + 10, 82, 218, 3, 64, 8, 75, 69, 89, 66, 79, 65, 82, 68, 74, 83, 155, 239, + 3, 78, 5, 41, 8, 32, 87, 73, 84, 72, 32, 74, 65, 2, 209, 254, 14, 2, 67, + 75, 212, 3, 48, 6, 89, 77, 66, 79, 76, 32, 135, 131, 11, 67, 210, 3, 230, + 2, 66, 238, 1, 67, 226, 9, 68, 242, 2, 69, 162, 1, 70, 166, 2, 71, 112, + 9, 65, 82, 80, 69, 71, 71, 73, 65, 84, 168, 1, 2, 72, 65, 126, 75, 198, + 3, 76, 138, 1, 77, 190, 2, 78, 162, 1, 79, 218, 2, 80, 200, 2, 2, 81, 85, + 146, 2, 82, 190, 2, 83, 230, 5, 84, 182, 10, 86, 42, 88, 42, 87, 180, + 233, 8, 9, 73, 78, 86, 69, 82, 84, 69, 68, 32, 163, 151, 6, 90, 20, 36, + 5, 69, 71, 73, 78, 32, 59, 82, 8, 130, 15, 80, 30, 83, 182, 224, 7, 66, + 187, 173, 7, 84, 12, 24, 2, 65, 67, 35, 69, 4, 218, 130, 15, 75, 143, 53, + 69, 8, 26, 86, 223, 245, 14, 65, 6, 32, 2, 73, 83, 139, 183, 15, 69, 5, + 171, 26, 32, 84, 120, 2, 65, 69, 30, 76, 94, 79, 194, 7, 82, 234, 11, 32, + 224, 32, 7, 73, 82, 67, 76, 69, 32, 88, 145, 200, 5, 2, 85, 84, 2, 197, + 241, 14, 2, 83, 85, 8, 42, 73, 245, 23, 5, 85, 83, 84, 69, 82, 4, 26, 77, + 175, 152, 13, 86, 2, 207, 177, 9, 65, 64, 26, 77, 179, 178, 15, 68, 62, + 64, 7, 66, 73, 78, 73, 78, 71, 32, 185, 251, 5, 3, 77, 79, 78, 60, 202, + 1, 65, 80, 7, 77, 65, 82, 67, 65, 84, 79, 56, 2, 68, 79, 56, 2, 85, 80, + 28, 2, 70, 76, 40, 5, 72, 65, 82, 77, 79, 22, 83, 142, 2, 84, 202, 154, + 7, 66, 140, 180, 3, 2, 76, 79, 183, 222, 4, 82, 6, 76, 5, 67, 67, 69, 78, + 84, 37, 10, 85, 71, 77, 69, 78, 84, 65, 84, 73, 79, 5, 205, 2, 5, 45, 83, + 84, 65, 67, 2, 231, 160, 14, 78, 6, 52, 2, 87, 78, 168, 3, 2, 85, 66, + 199, 145, 15, 73, 2, 137, 151, 14, 2, 32, 66, 12, 136, 76, 2, 65, 71, + 231, 228, 14, 73, 2, 231, 137, 14, 78, 12, 132, 1, 9, 78, 65, 80, 32, 80, + 73, 90, 90, 73, 22, 84, 236, 187, 4, 11, 80, 82, 69, 67, 72, 71, 69, 83, + 65, 78, 71, 255, 238, 5, 77, 2, 191, 206, 11, 67, 6, 44, 5, 65, 67, 67, + 65, 84, 159, 158, 15, 69, 4, 40, 4, 73, 83, 83, 73, 203, 174, 15, 79, 2, + 211, 143, 15, 77, 10, 34, 82, 253, 225, 11, 2, 69, 78, 8, 28, 2, 73, 80, + 191, 6, 69, 2, 133, 205, 11, 6, 76, 69, 32, 84, 79, 78, 4, 22, 79, 191, + 2, 69, 2, 159, 161, 14, 73, 24, 98, 65, 142, 1, 69, 84, 6, 79, 85, 66, + 76, 69, 32, 213, 249, 9, 7, 82, 85, 77, 32, 67, 76, 69, 10, 96, 2, 32, + 67, 20, 2, 77, 80, 196, 29, 4, 83, 72, 69, 68, 233, 228, 14, 5, 76, 32, + 83, 69, 71, 2, 223, 164, 8, 65, 5, 255, 166, 13, 32, 4, 52, 3, 67, 82, + 69, 241, 201, 8, 4, 71, 82, 69, 69, 2, 157, 25, 3, 83, 67, 69, 6, 246, + 21, 83, 250, 6, 66, 131, 244, 4, 70, 14, 32, 3, 78, 68, 32, 155, 16, 73, + 10, 74, 80, 30, 83, 208, 13, 3, 79, 70, 32, 230, 210, 7, 66, 187, 173, 7, + 84, 2, 145, 153, 12, 2, 72, 82, 2, 215, 176, 14, 76, 34, 104, 6, 69, 82, + 77, 65, 84, 65, 22, 73, 122, 79, 102, 32, 144, 36, 3, 85, 83, 65, 157, + 221, 3, 2, 76, 65, 5, 195, 129, 13, 32, 10, 22, 78, 135, 34, 86, 8, 56, + 9, 71, 69, 82, 69, 68, 32, 84, 82, 69, 235, 20, 65, 6, 185, 215, 5, 4, + 77, 79, 76, 79, 6, 208, 25, 3, 85, 82, 45, 147, 201, 13, 82, 18, 54, 32, + 56, 7, 76, 73, 83, 83, 65, 78, 68, 23, 82, 6, 25, 4, 67, 76, 69, 70, 7, + 161, 13, 3, 32, 79, 84, 4, 163, 235, 5, 79, 8, 84, 9, 65, 67, 69, 32, 78, + 79, 84, 69, 32, 37, 8, 69, 71, 79, 82, 73, 65, 78, 32, 4, 132, 196, 8, 2, + 78, 79, 27, 83, 4, 250, 2, 67, 3, 70, 8, 44, 3, 76, 70, 32, 209, 8, 3, + 85, 80, 84, 6, 52, 3, 80, 69, 68, 246, 214, 3, 78, 163, 169, 3, 82, 2, + 135, 175, 5, 65, 24, 48, 6, 73, 69, 86, 65, 78, 32, 147, 255, 13, 79, 22, + 178, 1, 67, 46, 69, 68, 7, 81, 85, 65, 82, 84, 69, 82, 62, 70, 184, 211, + 3, 4, 72, 65, 76, 70, 0, 5, 87, 72, 79, 76, 69, 253, 208, 1, 9, 82, 69, + 67, 73, 84, 65, 84, 73, 86, 2, 11, 32, 2, 11, 67, 2, 171, 144, 5, 76, 6, + 64, 5, 73, 71, 72, 84, 72, 253, 235, 13, 5, 78, 68, 32, 79, 70, 4, 165, + 230, 5, 10, 32, 78, 79, 84, 69, 32, 83, 84, 69, 77, 4, 214, 14, 76, 225, + 196, 3, 4, 73, 78, 65, 76, 8, 44, 4, 79, 78, 71, 65, 213, 13, 2, 69, 70, + 7, 11, 32, 4, 28, 3, 73, 77, 80, 3, 80, 2, 197, 2, 7, 69, 82, 70, 69, 67, + 84, 65, 18, 104, 2, 65, 88, 20, 2, 69, 90, 20, 5, 73, 78, 73, 77, 65, 48, + 3, 79, 79, 78, 25, 4, 85, 76, 84, 73, 2, 135, 253, 14, 73, 2, 143, 255, + 14, 90, 7, 11, 32, 4, 146, 250, 6, 82, 171, 153, 5, 66, 4, 185, 17, 2, + 32, 78, 4, 60, 11, 80, 76, 69, 32, 77, 69, 65, 83, 85, 82, 69, 15, 32, 2, + 11, 32, 2, 139, 249, 6, 82, 10, 120, 4, 69, 66, 69, 78, 208, 26, 3, 85, + 76, 76, 148, 198, 5, 3, 65, 84, 85, 173, 176, 6, 7, 79, 84, 69, 72, 69, + 65, 68, 2, 245, 131, 14, 4, 83, 84, 73, 77, 32, 88, 2, 78, 69, 120, 14, + 82, 78, 65, 77, 69, 78, 84, 32, 83, 84, 82, 79, 75, 69, 107, 84, 6, 92, + 18, 32, 72, 85, 78, 68, 82, 69, 68, 32, 84, 87, 69, 78, 84, 89, 45, 69, + 73, 155, 20, 45, 4, 177, 13, 2, 71, 72, 22, 11, 45, 22, 250, 158, 3, 49, + 206, 250, 11, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 4, + 173, 4, 3, 84, 65, 86, 18, 96, 9, 65, 82, 69, 78, 84, 72, 69, 83, 73, 0, + 2, 76, 85, 18, 69, 142, 1, 79, 247, 145, 13, 73, 2, 239, 22, 83, 6, 68, + 4, 68, 65, 76, 32, 49, 9, 83, 32, 83, 85, 66, 80, 85, 78, 67, 4, 26, 85, + 219, 213, 14, 77, 2, 191, 213, 14, 80, 2, 247, 249, 12, 84, 6, 48, 2, 68, + 65, 237, 5, 5, 82, 82, 69, 67, 84, 2, 175, 147, 13, 84, 12, 76, 6, 65, + 82, 84, 69, 82, 32, 125, 9, 73, 78, 68, 73, 67, 69, 83, 73, 77, 8, 60, 5, + 84, 79, 78, 69, 32, 138, 200, 3, 78, 163, 169, 3, 82, 4, 26, 83, 251, + 250, 4, 70, 2, 205, 148, 15, 3, 72, 65, 82, 4, 17, 2, 65, 32, 4, 138, + 240, 11, 65, 217, 161, 3, 3, 66, 65, 83, 14, 22, 69, 167, 1, 73, 10, 72, + 4, 80, 69, 65, 84, 73, 10, 86, 69, 82, 83, 69, 32, 70, 73, 78, 65, 8, + 152, 195, 5, 9, 69, 68, 32, 70, 73, 71, 85, 82, 69, 191, 130, 8, 32, 2, + 211, 4, 76, 4, 48, 2, 71, 72, 57, 6, 78, 70, 79, 82, 90, 65, 2, 33, 6, + 84, 32, 82, 69, 80, 69, 2, 131, 251, 9, 65, 2, 155, 151, 8, 78, 48, 136, + 1, 6, 67, 65, 78, 68, 73, 67, 62, 69, 166, 1, 72, 54, 73, 252, 1, 6, 81, + 85, 65, 82, 69, 32, 204, 128, 8, 2, 85, 66, 239, 2, 79, 4, 17, 2, 85, 83, + 5, 173, 141, 13, 5, 32, 70, 76, 69, 88, 14, 32, 2, 77, 73, 195, 230, 14, + 71, 12, 64, 6, 66, 82, 69, 86, 73, 83, 1, 6, 77, 73, 78, 73, 77, 65, 6, + 11, 32, 6, 138, 13, 87, 166, 222, 6, 82, 171, 153, 5, 66, 6, 84, 3, 79, + 82, 84, 169, 211, 5, 3, 65, 82, 80, 14, 32, 4, 78, 71, 76, 69, 43, 88, 2, + 17, 2, 32, 66, 2, 155, 169, 13, 65, 12, 18, 45, 79, 84, 4, 242, 7, 76, + 213, 238, 13, 11, 83, 84, 82, 73, 78, 71, 32, 70, 82, 69, 84, 8, 52, 3, + 69, 69, 78, 1, 6, 89, 45, 70, 79, 85, 82, 4, 193, 12, 2, 84, 72, 6, 26, + 78, 135, 140, 15, 66, 4, 229, 9, 7, 79, 84, 69, 72, 69, 65, 68, 60, 132, + 1, 6, 69, 77, 80, 85, 83, 32, 154, 4, 72, 88, 2, 87, 79, 84, 7, 79, 82, + 67, 85, 76, 85, 83, 46, 82, 141, 3, 3, 85, 82, 78, 16, 232, 1, 27, 73, + 77, 80, 69, 82, 70, 69, 67, 84, 85, 77, 32, 67, 85, 77, 32, 80, 82, 79, + 76, 65, 84, 73, 79, 78, 69, 32, 129, 1, 25, 80, 69, 82, 70, 69, 67, 84, + 85, 77, 32, 67, 85, 77, 32, 80, 82, 79, 76, 65, 84, 73, 79, 78, 69, 32, + 10, 60, 10, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 131, 1, 80, 9, 169, + 184, 5, 11, 32, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 6, 60, 3, 73, 77, + 80, 41, 8, 80, 69, 82, 70, 69, 67, 84, 65, 2, 213, 226, 14, 5, 69, 82, + 70, 69, 67, 5, 145, 163, 8, 12, 32, 68, 73, 77, 73, 78, 85, 84, 73, 79, + 78, 45, 6, 72, 2, 82, 69, 249, 5, 11, 73, 82, 84, 89, 45, 83, 69, 67, 79, + 78, 68, 2, 11, 69, 2, 11, 45, 2, 11, 76, 2, 37, 7, 73, 78, 69, 32, 83, + 84, 65, 2, 147, 132, 14, 70, 5, 173, 168, 11, 6, 32, 82, 69, 83, 85, 80, + 27, 33, 6, 73, 65, 78, 71, 76, 69, 24, 128, 1, 10, 32, 78, 79, 84, 69, + 72, 69, 65, 68, 32, 61, 17, 45, 82, 79, 85, 78, 68, 32, 78, 79, 84, 69, + 72, 69, 65, 68, 32, 68, 20, 58, 68, 24, 3, 85, 80, 32, 38, 82, 25, 3, 76, + 69, 70, 4, 93, 3, 79, 87, 78, 8, 34, 82, 78, 87, 207, 247, 11, 66, 4, 21, + 3, 73, 71, 72, 4, 11, 84, 4, 11, 32, 4, 26, 87, 207, 247, 11, 66, 2, 11, + 72, 2, 187, 189, 13, 73, 7, 11, 32, 4, 222, 160, 8, 83, 223, 224, 6, 85, + 4, 36, 3, 79, 73, 68, 187, 190, 14, 73, 2, 221, 178, 12, 5, 32, 78, 79, + 84, 69, 6, 92, 4, 72, 79, 76, 69, 157, 174, 8, 13, 73, 84, 72, 32, 70, + 73, 78, 71, 69, 82, 78, 65, 73, 4, 11, 32, 4, 246, 178, 3, 78, 163, 169, + 3, 82, 192, 3, 252, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, + 73, 71, 78, 32, 254, 1, 76, 216, 14, 16, 77, 79, 68, 73, 70, 73, 69, 82, + 32, 76, 69, 84, 84, 69, 82, 32, 122, 83, 166, 10, 84, 216, 1, 11, 86, 79, + 87, 69, 76, 32, 83, 73, 71, 78, 32, 223, 241, 12, 68, 16, 66, 77, 165, 1, + 11, 83, 72, 65, 78, 32, 77, 69, 68, 73, 65, 76, 14, 80, 6, 69, 68, 73, + 65, 76, 32, 45, 10, 79, 78, 32, 77, 69, 68, 73, 65, 76, 32, 8, 238, 249, + 14, 72, 2, 82, 2, 87, 3, 89, 6, 194, 249, 14, 76, 2, 77, 3, 78, 2, 219, + 182, 10, 32, 238, 1, 104, 6, 69, 84, 84, 69, 82, 32, 189, 13, 15, 79, 71, + 79, 71, 82, 65, 77, 32, 75, 72, 65, 77, 84, 73, 32, 232, 1, 242, 1, 65, + 50, 69, 146, 1, 71, 50, 75, 254, 1, 77, 134, 1, 78, 58, 82, 86, 83, 130, + 3, 84, 198, 1, 87, 242, 133, 11, 68, 190, 4, 86, 214, 20, 85, 210, 200, + 1, 73, 42, 76, 242, 190, 1, 66, 2, 67, 2, 74, 2, 80, 254, 68, 72, 2, 89, + 187, 2, 79, 7, 140, 174, 14, 4, 73, 84, 79, 78, 207, 74, 85, 9, 77, 17, + 65, 83, 84, 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, 6, + 42, 71, 182, 178, 10, 89, 187, 138, 3, 78, 2, 179, 178, 10, 72, 6, 214, + 163, 9, 82, 142, 209, 5, 72, 187, 2, 65, 44, 32, 2, 72, 65, 203, 246, 14, + 65, 43, 25, 4, 77, 84, 73, 32, 40, 134, 1, 68, 34, 84, 162, 191, 8, 78, + 178, 238, 5, 67, 2, 72, 2, 74, 158, 37, 76, 226, 31, 70, 2, 71, 2, 82, 2, + 83, 2, 88, 3, 90, 6, 238, 173, 14, 68, 255, 68, 72, 4, 207, 173, 14, 84, + 12, 36, 3, 79, 78, 32, 203, 244, 14, 65, 10, 60, 2, 66, 66, 206, 252, 12, + 74, 134, 181, 1, 78, 187, 66, 69, 4, 134, 244, 14, 65, 3, 69, 10, 134, + 190, 8, 78, 174, 179, 6, 71, 2, 89, 187, 2, 65, 4, 196, 214, 2, 12, 85, + 77, 65, 73, 32, 80, 65, 76, 65, 85, 78, 71, 239, 156, 12, 65, 50, 90, 72, + 136, 215, 2, 9, 71, 65, 87, 32, 75, 65, 82, 69, 78, 198, 152, 12, 83, + 187, 2, 65, 44, 66, 65, 197, 1, 11, 87, 69, 32, 80, 65, 76, 65, 85, 78, + 71, 32, 41, 17, 2, 78, 32, 38, 134, 1, 78, 234, 248, 12, 74, 2, 80, 2, + 84, 138, 176, 1, 66, 2, 67, 2, 71, 2, 75, 254, 68, 68, 2, 70, 2, 72, 2, + 90, 187, 2, 65, 6, 234, 237, 14, 78, 2, 89, 187, 2, 65, 4, 190, 248, 12, + 67, 3, 83, 36, 38, 65, 134, 168, 14, 84, 255, 68, 72, 31, 41, 8, 73, 32, + 76, 65, 73, 78, 71, 32, 28, 82, 78, 142, 134, 11, 68, 250, 160, 3, 66, 2, + 71, 2, 74, 158, 37, 76, 227, 31, 70, 4, 254, 235, 14, 78, 3, 89, 6, 92, + 17, 69, 83, 84, 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, 32, + 191, 237, 14, 65, 4, 190, 168, 10, 80, 195, 205, 2, 84, 6, 170, 225, 13, + 79, 154, 60, 81, 255, 62, 72, 4, 56, 6, 75, 72, 65, 77, 84, 73, 1, 4, 83, + 72, 65, 78, 2, 29, 5, 32, 82, 69, 68, 85, 2, 133, 132, 1, 2, 80, 76, 90, + 88, 4, 73, 71, 78, 32, 232, 6, 6, 89, 77, 66, 79, 76, 32, 145, 143, 9, 3, + 72, 65, 78, 52, 202, 3, 65, 32, 12, 75, 72, 65, 77, 84, 73, 32, 84, 79, + 78, 69, 45, 30, 83, 132, 2, 15, 84, 65, 73, 32, 76, 65, 73, 78, 71, 32, + 84, 79, 78, 69, 45, 28, 22, 87, 69, 83, 84, 69, 82, 78, 32, 80, 87, 79, + 32, 75, 65, 82, 69, 78, 32, 84, 79, 78, 69, 154, 238, 2, 68, 128, 145, 5, + 19, 82, 85, 77, 65, 73, 32, 80, 65, 76, 65, 85, 78, 71, 32, 84, 79, 78, + 69, 45, 156, 151, 3, 9, 80, 65, 79, 32, 75, 65, 82, 69, 78, 160, 91, 6, + 76, 73, 84, 84, 76, 69, 159, 176, 2, 86, 4, 250, 211, 13, 83, 243, 78, + 78, 4, 170, 231, 14, 49, 3, 51, 18, 40, 4, 72, 65, 78, 32, 151, 150, 14, + 69, 16, 84, 8, 67, 79, 85, 78, 67, 73, 76, 32, 84, 5, 84, 79, 78, 69, 45, + 159, 231, 13, 83, 6, 204, 151, 11, 8, 69, 77, 80, 72, 65, 84, 73, 67, + 189, 205, 3, 4, 84, 79, 78, 69, 8, 182, 229, 14, 50, 2, 51, 2, 53, 3, 54, + 4, 138, 229, 14, 50, 3, 53, 10, 11, 45, 10, 226, 228, 14, 49, 2, 50, 2, + 51, 2, 52, 3, 53, 18, 130, 1, 65, 132, 1, 2, 76, 79, 28, 5, 83, 72, 65, + 78, 32, 232, 148, 8, 4, 71, 69, 78, 73, 201, 85, 6, 67, 79, 77, 80, 76, + 69, 8, 84, 5, 73, 84, 79, 78, 32, 217, 152, 6, 10, 70, 79, 82, 69, 77, + 69, 78, 84, 73, 79, 6, 98, 69, 130, 213, 8, 84, 223, 243, 4, 79, 2, 129, + 149, 8, 2, 67, 65, 4, 26, 69, 223, 200, 13, 79, 2, 205, 12, 4, 88, 67, + 76, 65, 24, 140, 1, 20, 79, 78, 69, 32, 77, 65, 82, 75, 32, 83, 71, 65, + 87, 32, 75, 65, 82, 69, 78, 32, 161, 139, 9, 8, 65, 73, 32, 76, 65, 73, + 78, 71, 4, 42, 72, 253, 163, 10, 4, 75, 69, 32, 80, 2, 161, 188, 9, 2, + 65, 84, 56, 154, 2, 65, 76, 9, 71, 69, 66, 65, 32, 75, 65, 82, 69, 20, 6, + 75, 65, 89, 65, 72, 32, 40, 4, 77, 79, 78, 32, 34, 83, 154, 1, 69, 40, + 18, 87, 69, 83, 84, 69, 82, 78, 32, 80, 87, 79, 32, 75, 65, 82, 69, 78, + 32, 144, 146, 9, 2, 84, 65, 246, 228, 1, 86, 214, 20, 85, 211, 200, 1, + 73, 8, 26, 73, 195, 221, 14, 65, 7, 25, 4, 84, 79, 78, 32, 4, 215, 214, + 12, 65, 2, 139, 157, 14, 78, 6, 166, 198, 14, 69, 2, 79, 215, 22, 85, 4, + 250, 200, 14, 73, 219, 19, 79, 10, 72, 10, 71, 65, 87, 32, 75, 65, 82, + 69, 78, 32, 21, 4, 72, 65, 78, 32, 2, 255, 182, 14, 69, 8, 54, 69, 20, 5, + 70, 73, 78, 65, 76, 211, 216, 14, 65, 5, 179, 222, 13, 32, 2, 191, 201, + 14, 32, 4, 138, 182, 14, 69, 151, 14, 85, 216, 17, 128, 2, 5, 45, 65, 82, + 89, 32, 214, 4, 65, 242, 16, 66, 30, 69, 206, 31, 73, 136, 1, 3, 75, 79, + 32, 154, 10, 79, 162, 24, 85, 224, 8, 22, 89, 73, 65, 75, 69, 78, 71, 32, + 80, 85, 65, 67, 72, 85, 69, 32, 72, 77, 79, 78, 71, 32, 232, 246, 13, 2, + 78, 66, 27, 76, 32, 130, 1, 67, 114, 84, 46, 83, 160, 1, 5, 85, 78, 73, + 79, 78, 108, 4, 87, 72, 73, 84, 174, 168, 11, 76, 254, 16, 73, 135, 140, + 2, 80, 8, 52, 7, 73, 82, 67, 76, 69, 68, 32, 147, 200, 13, 79, 6, 40, 2, + 80, 76, 14, 84, 167, 244, 7, 68, 2, 35, 85, 2, 21, 3, 73, 77, 69, 2, 147, + 172, 11, 83, 6, 40, 6, 81, 85, 65, 82, 69, 32, 87, 85, 4, 60, 9, 73, 78, + 84, 69, 82, 83, 69, 67, 84, 1, 2, 85, 78, 2, 255, 146, 11, 73, 2, 11, 77, + 2, 235, 168, 11, 77, 7, 69, 15, 32, 79, 80, 69, 82, 65, 84, 79, 82, 32, + 87, 73, 84, 72, 32, 4, 198, 247, 10, 80, 211, 140, 3, 68, 2, 11, 69, 2, + 145, 132, 12, 2, 32, 86, 188, 2, 170, 2, 66, 252, 4, 10, 71, 32, 77, 85, + 78, 68, 65, 82, 73, 32, 154, 4, 73, 52, 2, 78, 68, 216, 4, 7, 84, 73, 79, + 78, 65, 76, 32, 240, 206, 1, 2, 85, 83, 136, 236, 7, 5, 77, 69, 32, 66, + 65, 148, 172, 3, 7, 90, 65, 82, 32, 65, 77, 85, 196, 157, 1, 8, 82, 82, + 79, 87, 32, 78, 79, 45, 219, 62, 75, 82, 52, 7, 65, 84, 65, 69, 65, 78, + 32, 219, 206, 14, 76, 80, 160, 1, 7, 76, 69, 84, 84, 69, 82, 32, 236, 2, + 7, 78, 85, 77, 66, 69, 82, 32, 193, 207, 9, 16, 67, 82, 85, 67, 73, 70, + 79, 82, 77, 32, 78, 85, 77, 66, 69, 82, 62, 236, 1, 6, 70, 73, 78, 65, + 76, 32, 174, 253, 1, 84, 246, 118, 68, 34, 76, 50, 81, 206, 194, 1, 82, + 134, 212, 2, 65, 50, 71, 90, 90, 34, 83, 66, 89, 154, 193, 1, 72, 234, 5, + 75, 130, 76, 66, 190, 173, 4, 78, 254, 1, 87, 202, 103, 80, 171, 4, 77, + 18, 138, 244, 2, 65, 54, 76, 174, 149, 4, 83, 190, 3, 89, 130, 199, 1, + 75, 130, 76, 66, 190, 173, 4, 78, 198, 105, 72, 171, 4, 77, 16, 154, 245, + 2, 84, 186, 151, 4, 79, 143, 211, 5, 70, 84, 84, 7, 76, 69, 84, 84, 69, + 82, 32, 164, 2, 5, 83, 73, 71, 78, 32, 183, 219, 12, 68, 54, 42, 65, 50, + 69, 66, 73, 50, 79, 47, 85, 11, 254, 185, 14, 78, 202, 17, 66, 2, 72, 3, + 74, 15, 150, 211, 12, 78, 230, 110, 76, 242, 108, 84, 174, 28, 71, 3, 77, + 11, 194, 132, 14, 68, 150, 70, 72, 2, 83, 3, 84, 11, 210, 201, 14, 78, + 86, 76, 2, 80, 3, 89, 11, 250, 201, 14, 67, 2, 68, 2, 75, 3, 82, 10, 112, + 2, 77, 85, 20, 3, 83, 85, 84, 172, 165, 2, 2, 73, 75, 184, 129, 9, 2, 79, + 74, 137, 233, 2, 3, 84, 79, 89, 2, 255, 143, 14, 72, 2, 183, 199, 14, 85, + 4, 236, 137, 11, 5, 76, 32, 80, 79, 76, 231, 2, 82, 133, 1, 41, 8, 73, + 78, 65, 71, 65, 82, 73, 32, 130, 1, 140, 1, 7, 76, 69, 84, 84, 69, 82, + 32, 252, 1, 5, 83, 73, 71, 78, 32, 52, 11, 86, 79, 87, 69, 76, 32, 83, + 73, 71, 78, 32, 199, 207, 4, 72, 94, 214, 1, 86, 202, 164, 10, 82, 206, + 55, 65, 38, 68, 46, 84, 230, 24, 85, 210, 200, 1, 73, 42, 76, 246, 189, + 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, + 77, 2, 89, 186, 2, 69, 3, 79, 6, 242, 254, 4, 79, 243, 197, 9, 65, 10, + 202, 205, 9, 83, 134, 144, 1, 65, 243, 163, 3, 86, 24, 210, 213, 4, 80, + 190, 40, 86, 166, 225, 5, 65, 190, 21, 85, 210, 200, 1, 73, 206, 134, 2, + 69, 3, 79, 4, 202, 47, 68, 191, 210, 13, 80, 4, 250, 194, 14, 83, 15, 72, + 246, 4, 216, 1, 3, 71, 65, 84, 128, 7, 6, 73, 84, 72, 69, 82, 32, 194, 3, + 83, 136, 1, 2, 85, 84, 242, 1, 87, 144, 16, 3, 88, 84, 32, 140, 150, 8, + 4, 80, 84, 85, 78, 240, 239, 2, 2, 67, 75, 150, 141, 2, 82, 183, 144, 1, + 76, 154, 1, 152, 1, 4, 73, 86, 69, 32, 245, 160, 12, 27, 69, 68, 32, 68, + 79, 85, 66, 76, 69, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, 82, + 32, 68, 79, 85, 66, 152, 1, 152, 1, 8, 67, 73, 82, 67, 76, 69, 68, 32, + 216, 1, 9, 68, 73, 65, 71, 79, 78, 65, 76, 32, 196, 1, 8, 83, 81, 85, 65, + 82, 69, 68, 32, 147, 170, 8, 65, 78, 104, 5, 68, 73, 71, 73, 84, 28, 7, + 78, 85, 77, 66, 69, 82, 32, 142, 3, 76, 238, 150, 13, 84, 139, 3, 83, 2, + 189, 209, 12, 2, 32, 90, 20, 50, 84, 218, 254, 1, 69, 46, 70, 42, 78, 31, + 83, 6, 154, 128, 2, 72, 47, 87, 6, 38, 77, 234, 254, 12, 67, 191, 2, 68, + 2, 49, 10, 73, 68, 68, 76, 69, 32, 82, 73, 71, 72, 2, 17, 2, 84, 32, 2, + 25, 4, 84, 79, 32, 76, 2, 25, 4, 79, 87, 69, 82, 2, 169, 198, 11, 2, 32, + 67, 66, 118, 76, 248, 229, 2, 4, 67, 82, 79, 83, 142, 138, 9, 81, 146, + 144, 1, 65, 198, 19, 73, 2, 87, 170, 164, 1, 80, 3, 83, 52, 221, 209, 8, + 6, 65, 84, 73, 78, 32, 67, 18, 158, 1, 65, 216, 1, 17, 71, 82, 69, 65, + 84, 69, 82, 45, 84, 72, 65, 78, 32, 78, 79, 82, 32, 37, 14, 76, 69, 83, + 83, 45, 84, 72, 65, 78, 32, 78, 79, 82, 32, 6, 92, 3, 32, 83, 85, 85, 16, + 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 89, 32, 78, 79, 82, 4, 30, + 66, 1, 3, 80, 69, 82, 2, 253, 223, 6, 8, 83, 69, 84, 32, 79, 70, 32, 78, + 2, 213, 48, 5, 32, 65, 67, 84, 85, 6, 250, 246, 7, 69, 191, 177, 4, 76, + 6, 214, 246, 7, 69, 155, 177, 4, 71, 6, 26, 84, 199, 179, 12, 83, 4, 76, + 5, 73, 78, 71, 32, 68, 145, 176, 10, 8, 32, 87, 73, 84, 72, 32, 69, 71, + 2, 133, 228, 7, 2, 79, 76, 64, 40, 4, 82, 65, 76, 32, 203, 252, 13, 69, + 62, 48, 6, 67, 72, 69, 83, 83, 32, 235, 247, 13, 70, 60, 74, 75, 134, + 218, 12, 66, 38, 69, 130, 5, 80, 22, 81, 38, 82, 131, 2, 84, 20, 44, 5, + 78, 73, 71, 72, 84, 151, 219, 12, 73, 15, 195, 219, 12, 32, 246, 2, 70, + 32, 184, 8, 2, 65, 32, 248, 6, 3, 76, 73, 78, 183, 206, 3, 83, 174, 1, + 90, 77, 64, 4, 83, 72, 69, 81, 20, 8, 84, 65, 73, 32, 76, 85, 69, 32, + 183, 152, 13, 76, 4, 25, 4, 79, 79, 78, 32, 4, 234, 244, 7, 87, 171, 170, + 5, 83, 2, 183, 154, 9, 69, 166, 1, 160, 1, 7, 76, 69, 84, 84, 69, 82, 32, + 244, 2, 8, 83, 73, 71, 78, 32, 76, 65, 69, 22, 84, 76, 11, 86, 79, 87, + 69, 76, 32, 83, 73, 71, 78, 32, 191, 190, 12, 68, 102, 76, 6, 70, 73, 78, + 65, 76, 32, 68, 4, 72, 73, 71, 72, 1, 3, 76, 79, 87, 14, 198, 183, 12, + 78, 150, 248, 1, 66, 2, 68, 2, 75, 2, 77, 3, 86, 44, 11, 32, 44, 146, 1, + 75, 2, 88, 34, 83, 210, 222, 10, 78, 134, 135, 3, 84, 82, 80, 254, 68, + 66, 2, 68, 2, 70, 2, 72, 2, 76, 2, 77, 2, 81, 2, 86, 3, 89, 4, 190, 171, + 14, 86, 187, 2, 65, 4, 158, 171, 14, 85, 187, 2, 65, 5, 183, 173, 14, 86, + 6, 224, 133, 7, 3, 79, 78, 69, 253, 76, 8, 72, 65, 77, 32, 68, 73, 71, + 73, 34, 110, 65, 46, 73, 30, 79, 38, 85, 216, 231, 11, 11, 86, 79, 87, + 69, 76, 32, 83, 72, 79, 82, 84, 167, 195, 2, 69, 8, 238, 184, 10, 65, + 250, 242, 3, 69, 3, 89, 4, 186, 171, 14, 73, 3, 89, 9, 166, 184, 10, 65, + 251, 242, 3, 89, 11, 130, 184, 10, 69, 250, 242, 3, 85, 3, 89, 194, 1, + 182, 1, 68, 106, 71, 72, 7, 76, 69, 84, 84, 69, 82, 32, 214, 2, 83, 190, + 23, 80, 202, 133, 1, 86, 138, 200, 7, 65, 144, 230, 1, 5, 73, 78, 83, 69, + 82, 210, 142, 1, 67, 207, 186, 2, 79, 26, 64, 6, 79, 85, 66, 76, 69, 32, + 214, 211, 4, 65, 239, 230, 7, 73, 4, 198, 211, 4, 68, 231, 137, 7, 67, 2, + 11, 65, 2, 11, 80, 2, 17, 2, 32, 70, 2, 213, 224, 10, 2, 73, 76, 108, + 218, 1, 78, 62, 86, 254, 188, 10, 65, 38, 68, 46, 84, 230, 24, 85, 210, + 200, 1, 73, 202, 190, 1, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 76, + 2, 77, 2, 80, 2, 82, 254, 68, 72, 2, 87, 2, 89, 186, 2, 69, 3, 79, 14, + 210, 222, 13, 71, 2, 89, 254, 68, 72, 2, 78, 187, 2, 65, 10, 26, 69, 207, + 193, 10, 79, 2, 173, 246, 11, 3, 68, 73, 67, 22, 26, 73, 139, 179, 4, 65, + 20, 44, 3, 71, 78, 32, 213, 128, 9, 2, 68, 68, 18, 210, 189, 10, 65, 74, + 67, 98, 78, 230, 179, 1, 74, 228, 2, 5, 70, 73, 78, 65, 76, 50, 85, 211, + 235, 1, 86, 4, 203, 248, 13, 69, 4, 250, 200, 9, 80, 171, 193, 3, 76, 6, + 70, 78, 245, 141, 13, 11, 71, 72, 84, 32, 87, 73, 84, 72, 32, 83, 84, 4, + 156, 217, 7, 7, 69, 32, 80, 79, 73, 78, 84, 131, 199, 6, 74, 124, 152, 1, + 3, 67, 79, 77, 242, 2, 68, 78, 76, 156, 4, 4, 72, 73, 71, 72, 72, 7, 83, + 89, 77, 66, 79, 76, 32, 238, 192, 7, 69, 133, 178, 1, 3, 84, 65, 77, 20, + 52, 7, 66, 73, 78, 73, 78, 71, 32, 143, 158, 14, 77, 18, 116, 5, 76, 79, + 78, 71, 32, 76, 2, 78, 65, 20, 6, 83, 72, 79, 82, 84, 32, 165, 158, 13, + 6, 68, 79, 85, 66, 76, 69, 8, 130, 1, 72, 34, 76, 194, 207, 10, 82, 21, + 7, 68, 69, 83, 67, 69, 78, 68, 2, 155, 172, 10, 83, 6, 34, 72, 34, 76, + 195, 207, 10, 82, 2, 137, 208, 10, 3, 73, 71, 72, 2, 233, 207, 10, 2, 79, + 87, 24, 152, 1, 4, 65, 78, 84, 65, 152, 133, 12, 4, 79, 82, 79, 77, 203, + 41, 73, 70, 76, 4, 65, 74, 65, 78, 32, 6, 69, 84, 84, 69, 82, 32, 173, 3, + 2, 79, 87, 2, 185, 213, 12, 3, 89, 65, 76, 66, 228, 1, 2, 68, 65, 42, 74, + 90, 78, 206, 249, 9, 82, 158, 225, 1, 79, 198, 71, 67, 170, 183, 1, 69, + 238, 18, 71, 242, 42, 66, 2, 70, 2, 72, 2, 75, 2, 76, 2, 77, 2, 80, 2, + 83, 2, 84, 2, 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 5, 237, 248, 10, 5, + 71, 66, 65, 83, 73, 8, 40, 4, 79, 78, 65, 32, 151, 154, 14, 65, 6, 214, + 162, 12, 67, 134, 245, 1, 74, 3, 82, 11, 26, 65, 1, 2, 89, 65, 5, 173, + 193, 5, 5, 32, 87, 79, 76, 79, 2, 29, 5, 32, 84, 79, 78, 69, 2, 17, 2, + 32, 65, 2, 135, 171, 8, 80, 4, 68, 7, 71, 66, 65, 75, 85, 82, 85, 1, 6, + 79, 79, 32, 68, 69, 78, 2, 159, 199, 12, 78, 180, 1, 90, 32, 156, 3, 2, + 77, 73, 118, 78, 150, 1, 82, 238, 7, 84, 186, 203, 13, 45, 135, 40, 83, + 18, 202, 1, 66, 96, 5, 69, 78, 84, 82, 89, 22, 80, 160, 180, 2, 15, 79, + 78, 69, 32, 85, 78, 68, 69, 82, 32, 69, 73, 71, 72, 84, 220, 242, 3, 9, + 77, 79, 66, 73, 76, 69, 32, 80, 72, 181, 30, 3, 83, 77, 79, 4, 52, 4, 82, + 69, 65, 75, 173, 131, 2, 3, 73, 67, 89, 2, 17, 2, 32, 72, 2, 231, 244, + 12, 69, 5, 151, 142, 13, 32, 4, 60, 6, 69, 68, 69, 83, 84, 82, 161, 167, + 9, 3, 73, 82, 65, 2, 137, 230, 10, 2, 73, 65, 4, 36, 5, 78, 65, 76, 32, + 68, 59, 83, 2, 249, 255, 12, 9, 73, 71, 73, 84, 32, 83, 72, 65, 80, 2, + 195, 215, 10, 77, 6, 38, 45, 185, 183, 9, 3, 70, 79, 82, 4, 76, 8, 66, + 82, 69, 65, 75, 73, 78, 71, 245, 162, 2, 5, 80, 79, 84, 65, 66, 2, 129, + 201, 6, 2, 32, 72, 93, 56, 2, 84, 72, 146, 11, 77, 173, 185, 10, 3, 68, + 73, 67, 84, 78, 32, 213, 131, 11, 13, 69, 65, 83, 84, 45, 80, 79, 73, 78, + 84, 73, 78, 71, 82, 96, 5, 69, 65, 83, 84, 32, 132, 2, 6, 73, 78, 68, 73, + 67, 32, 217, 1, 5, 87, 69, 83, 84, 32, 30, 82, 65, 182, 221, 6, 80, 130, + 1, 84, 246, 160, 4, 66, 38, 68, 18, 83, 203, 43, 87, 12, 40, 4, 82, 82, + 79, 87, 175, 217, 6, 78, 11, 11, 32, 8, 80, 9, 67, 82, 79, 83, 83, 73, + 78, 71, 32, 244, 2, 2, 65, 78, 255, 216, 6, 87, 4, 218, 180, 3, 83, 207, + 166, 3, 78, 20, 50, 80, 60, 3, 81, 85, 65, 66, 82, 215, 126, 70, 2, 37, + 7, 76, 65, 67, 69, 72, 79, 76, 2, 135, 158, 4, 68, 4, 240, 157, 4, 2, 82, + 84, 237, 173, 9, 5, 78, 84, 73, 84, 89, 2, 17, 2, 85, 80, 2, 187, 144, 4, + 69, 32, 82, 65, 218, 217, 6, 80, 130, 1, 84, 246, 160, 4, 66, 38, 68, 18, + 83, 203, 43, 87, 14, 34, 78, 33, 4, 82, 82, 79, 87, 2, 229, 177, 3, 3, + 68, 32, 83, 13, 11, 32, 10, 68, 3, 84, 79, 32, 138, 213, 6, 67, 40, 3, + 65, 78, 68, 219, 2, 87, 4, 146, 214, 6, 67, 229, 228, 4, 4, 76, 79, 78, + 71, 56, 54, 32, 236, 5, 5, 67, 72, 69, 68, 32, 207, 2, 69, 38, 162, 1, + 65, 132, 2, 4, 78, 79, 82, 77, 78, 80, 46, 83, 170, 1, 84, 250, 195, 7, + 69, 196, 25, 7, 73, 68, 69, 78, 84, 73, 67, 214, 151, 4, 71, 38, 76, 243, + 77, 67, 10, 88, 3, 32, 83, 85, 52, 7, 78, 32, 69, 76, 69, 77, 69, 28, 2, + 83, 89, 139, 223, 7, 76, 4, 30, 66, 1, 3, 80, 69, 82, 2, 29, 2, 83, 69, + 2, 11, 78, 2, 243, 119, 84, 2, 37, 7, 77, 80, 84, 79, 84, 73, 67, 2, 17, + 2, 65, 76, 2, 201, 223, 7, 2, 76, 89, 4, 181, 174, 6, 14, 65, 76, 32, 83, + 85, 66, 71, 82, 79, 85, 80, 32, 79, 70, 2, 153, 223, 7, 6, 65, 82, 65, + 76, 76, 69, 6, 48, 6, 81, 85, 65, 82, 69, 32, 195, 254, 12, 73, 4, 68, 5, + 73, 77, 65, 71, 69, 1, 8, 79, 82, 73, 71, 73, 78, 65, 76, 2, 21, 3, 32, + 79, 70, 2, 183, 172, 6, 32, 4, 178, 163, 10, 82, 227, 202, 1, 73, 8, 58, + 76, 40, 4, 82, 73, 71, 72, 133, 1, 3, 85, 80, 80, 4, 36, 2, 69, 70, 133, + 1, 2, 79, 87, 2, 89, 20, 84, 32, 83, 69, 77, 73, 67, 73, 82, 67, 76, 69, + 32, 87, 73, 84, 72, 32, 84, 72, 2, 17, 2, 82, 69, 2, 207, 180, 12, 69, 2, + 11, 69, 2, 41, 8, 82, 32, 82, 73, 71, 72, 84, 45, 2, 153, 131, 3, 6, 83, + 72, 65, 68, 79, 87, 11, 34, 32, 53, 4, 66, 79, 79, 75, 4, 17, 2, 80, 65, + 4, 146, 234, 13, 71, 215, 22, 68, 5, 81, 18, 32, 87, 73, 84, 72, 32, 68, + 69, 67, 79, 82, 65, 84, 73, 86, 69, 32, 67, 2, 223, 251, 3, 79, 186, 6, + 102, 77, 176, 3, 4, 83, 72, 85, 32, 168, 157, 5, 8, 84, 32, 65, 78, 68, + 32, 66, 79, 131, 226, 7, 76, 26, 36, 4, 66, 69, 82, 32, 247, 2, 69, 24, + 58, 69, 50, 70, 42, 83, 66, 84, 57, 4, 78, 73, 78, 69, 4, 204, 1, 3, 73, + 71, 72, 21, 3, 76, 69, 86, 4, 144, 1, 2, 79, 85, 13, 2, 73, 70, 6, 34, + 73, 85, 4, 69, 86, 69, 78, 4, 82, 88, 239, 172, 13, 71, 8, 40, 2, 72, 73, + 46, 69, 21, 2, 87, 69, 2, 11, 82, 2, 17, 2, 84, 69, 2, 11, 69, 2, 143, + 175, 7, 78, 4, 248, 174, 7, 3, 76, 86, 69, 1, 3, 78, 84, 89, 2, 155, 221, + 6, 82, 154, 6, 72, 12, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, + 215, 222, 11, 73, 152, 6, 18, 49, 87, 50, 160, 2, 222, 1, 55, 2, 56, 2, + 57, 2, 65, 2, 66, 2, 67, 2, 68, 2, 69, 3, 70, 248, 3, 138, 1, 48, 2, 49, + 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, + 67, 2, 68, 2, 69, 143, 1, 70, 32, 246, 248, 13, 48, 2, 49, 2, 50, 2, 51, + 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 2, 57, 2, 65, 2, 66, 2, 67, 2, 68, 2, + 69, 3, 70, 24, 234, 247, 13, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 54, 2, 55, 2, 56, 2, 57, 2, 65, 3, 66, 142, 1, 108, 8, 67, 73, 82, 67, + 76, 69, 68, 32, 22, 76, 226, 3, 83, 160, 2, 5, 84, 79, 78, 69, 45, 223, + 129, 12, 68, 2, 211, 243, 13, 67, 92, 88, 6, 69, 84, 84, 69, 82, 32, 141, + 157, 1, 10, 79, 71, 79, 71, 82, 65, 77, 32, 78, 89, 90, 130, 2, 78, 90, + 84, 222, 188, 7, 88, 186, 116, 65, 146, 161, 1, 82, 188, 44, 2, 72, 65, + 226, 180, 1, 79, 222, 56, 68, 2, 77, 2, 80, 146, 198, 1, 69, 222, 61, 67, + 2, 70, 2, 71, 2, 75, 2, 76, 2, 81, 2, 83, 2, 86, 2, 89, 2, 90, 186, 2, + 73, 2, 85, 3, 87, 22, 86, 84, 158, 236, 11, 80, 238, 131, 2, 67, 2, 75, + 2, 81, 2, 82, 2, 89, 187, 2, 65, 6, 134, 240, 13, 83, 2, 88, 187, 2, 65, + 14, 64, 4, 73, 71, 78, 32, 185, 1, 7, 89, 76, 76, 65, 66, 76, 69, 12, 56, + 4, 70, 79, 82, 32, 137, 243, 12, 4, 88, 87, 32, 88, 10, 152, 9, 2, 76, + 79, 190, 147, 3, 84, 132, 89, 8, 73, 78, 86, 69, 82, 84, 69, 66, 154, + 168, 3, 80, 237, 86, 3, 65, 78, 73, 2, 221, 172, 11, 4, 32, 76, 69, 78, + 14, 246, 239, 13, 66, 2, 68, 2, 71, 2, 74, 2, 77, 2, 83, 3, 86, 214, 13, + 178, 2, 66, 226, 1, 67, 224, 5, 4, 70, 70, 73, 67, 54, 71, 248, 6, 4, 73, + 76, 32, 68, 22, 76, 222, 63, 78, 166, 5, 80, 214, 7, 82, 190, 10, 83, + 212, 8, 2, 84, 84, 154, 8, 85, 180, 1, 3, 86, 69, 82, 234, 159, 2, 89, + 138, 180, 5, 72, 190, 233, 1, 75, 174, 230, 1, 68, 230, 61, 77, 246, 9, + 87, 159, 137, 1, 88, 10, 132, 1, 6, 76, 73, 81, 85, 69, 32, 140, 152, 2, + 9, 83, 69, 82, 86, 69, 82, 32, 69, 89, 221, 28, 8, 74, 69, 67, 84, 32, + 82, 69, 80, 6, 160, 177, 4, 13, 65, 78, 71, 76, 69, 32, 79, 80, 69, 78, + 73, 78, 71, 191, 241, 1, 72, 28, 56, 2, 82, 32, 234, 4, 84, 229, 172, 5, + 3, 67, 85, 76, 22, 156, 1, 11, 65, 77, 79, 85, 78, 84, 32, 79, 70, 32, + 67, 22, 66, 198, 1, 67, 118, 68, 106, 70, 0, 10, 73, 78, 86, 69, 82, 84, + 69, 68, 32, 70, 175, 149, 12, 72, 2, 207, 158, 5, 72, 6, 136, 1, 15, 82, + 65, 78, 67, 72, 32, 66, 65, 78, 75, 32, 73, 68, 69, 78, 144, 233, 4, 5, + 69, 76, 84, 32, 66, 201, 225, 5, 3, 79, 87, 32, 2, 21, 3, 84, 73, 70, 2, + 11, 73, 2, 199, 187, 10, 67, 4, 92, 17, 85, 83, 84, 79, 77, 69, 82, 32, + 65, 67, 67, 79, 85, 78, 84, 32, 78, 227, 195, 1, 72, 2, 159, 135, 6, 85, + 4, 44, 5, 79, 85, 66, 76, 69, 171, 129, 12, 65, 2, 11, 32, 2, 11, 66, 2, + 181, 133, 7, 3, 65, 67, 75, 2, 247, 164, 13, 79, 4, 184, 206, 8, 4, 65, + 71, 79, 78, 209, 148, 3, 2, 79, 80, 2, 11, 69, 2, 213, 215, 7, 5, 32, 66, + 85, 73, 76, 60, 48, 4, 72, 65, 77, 32, 177, 225, 13, 2, 79, 78, 58, 122, + 70, 0, 10, 82, 69, 86, 69, 82, 83, 69, 68, 32, 70, 36, 7, 76, 69, 84, 84, + 69, 82, 32, 161, 231, 3, 3, 83, 80, 65, 2, 177, 244, 3, 4, 69, 65, 84, + 72, 52, 196, 1, 2, 65, 73, 22, 66, 2, 80, 34, 67, 36, 2, 69, 65, 64, 2, + 70, 69, 22, 71, 22, 73, 58, 76, 2, 82, 22, 78, 46, 79, 34, 83, 50, 85, + 150, 178, 1, 77, 170, 9, 68, 149, 138, 11, 3, 84, 73, 78, 2, 147, 209, + 13, 76, 2, 11, 69, 2, 199, 226, 11, 73, 4, 138, 239, 7, 69, 255, 237, 3, + 79, 6, 138, 1, 66, 2, 68, 201, 247, 3, 6, 77, 72, 65, 78, 67, 72, 2, 199, + 130, 9, 65, 2, 199, 217, 12, 79, 4, 32, 2, 79, 68, 207, 224, 12, 70, 2, + 235, 224, 7, 72, 2, 135, 195, 11, 85, 4, 176, 204, 12, 3, 71, 69, 65, + 207, 67, 73, 4, 222, 143, 13, 78, 215, 79, 82, 4, 158, 178, 11, 65, 161, + 171, 1, 3, 84, 82, 65, 6, 60, 5, 73, 76, 76, 69, 65, 162, 223, 11, 65, + 135, 255, 1, 82, 2, 207, 142, 13, 78, 2, 155, 182, 12, 82, 220, 7, 64, 7, + 32, 67, 72, 73, 75, 73, 32, 206, 6, 68, 167, 218, 12, 73, 96, 132, 1, 7, + 76, 69, 84, 84, 69, 82, 32, 148, 3, 2, 77, 85, 62, 71, 74, 80, 164, 198, + 3, 2, 82, 69, 214, 163, 8, 68, 243, 167, 1, 65, 60, 50, 65, 98, 69, 54, + 73, 50, 76, 62, 79, 51, 85, 16, 50, 65, 242, 218, 13, 78, 86, 71, 2, 76, + 3, 84, 8, 194, 219, 13, 74, 2, 75, 2, 77, 3, 87, 8, 130, 149, 13, 68, + 198, 13, 82, 210, 56, 78, 3, 80, 8, 154, 201, 13, 78, 202, 17, 72, 2, 82, + 3, 83, 12, 134, 153, 8, 65, 174, 193, 5, 69, 2, 73, 2, 79, 3, 85, 8, 202, + 189, 13, 84, 174, 28, 66, 2, 72, 3, 86, 8, 242, 137, 13, 78, 214, 79, 67, + 2, 68, 3, 89, 4, 56, 2, 45, 71, 221, 242, 11, 6, 32, 84, 84, 85, 68, 68, + 2, 217, 242, 11, 13, 65, 65, 72, 76, 65, 65, 32, 84, 84, 85, 68, 68, 65, + 6, 84, 11, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 137, 197, 6, 4, + 72, 65, 65, 82, 4, 48, 8, 68, 79, 85, 66, 76, 69, 32, 77, 3, 77, 2, 229, + 144, 13, 3, 85, 67, 65, 250, 6, 34, 32, 225, 55, 3, 69, 82, 32, 244, 6, + 240, 2, 8, 67, 72, 73, 78, 69, 83, 69, 32, 44, 10, 72, 85, 78, 71, 65, + 82, 73, 65, 78, 32, 244, 6, 7, 73, 84, 65, 76, 73, 67, 32, 212, 4, 14, + 78, 79, 82, 84, 72, 32, 65, 82, 65, 66, 73, 65, 78, 32, 196, 4, 3, 80, + 69, 82, 164, 12, 2, 83, 79, 144, 13, 14, 84, 85, 82, 75, 73, 67, 32, 76, + 69, 84, 84, 69, 82, 32, 132, 7, 7, 85, 89, 71, 72, 85, 82, 32, 151, 140, + 11, 75, 4, 166, 183, 11, 73, 205, 91, 3, 72, 79, 79, 216, 1, 96, 6, 67, + 65, 80, 73, 84, 65, 0, 4, 83, 77, 65, 76, 221, 5, 7, 78, 85, 77, 66, 69, + 82, 32, 102, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 102, 226, 1, 65, + 54, 69, 164, 2, 10, 78, 73, 75, 79, 76, 83, 66, 85, 82, 71, 0, 9, 82, 85, + 68, 73, 77, 69, 78, 84, 65, 42, 79, 34, 85, 132, 223, 3, 5, 67, 76, 79, + 83, 69, 178, 231, 7, 73, 237, 200, 1, 6, 83, 72, 79, 82, 84, 32, 11, 250, + 149, 12, 77, 146, 116, 78, 150, 70, 65, 3, 75, 63, 174, 1, 77, 22, 78, + 78, 83, 146, 218, 9, 67, 86, 71, 2, 76, 2, 84, 154, 239, 1, 90, 226, 131, + 2, 66, 2, 68, 2, 69, 2, 70, 2, 72, 2, 74, 2, 75, 2, 80, 2, 82, 3, 86, 5, + 187, 206, 13, 80, 11, 34, 84, 134, 206, 13, 67, 3, 89, 5, 165, 145, 2, 5, + 45, 83, 72, 65, 80, 5, 219, 205, 13, 90, 4, 11, 32, 4, 230, 182, 13, 79, + 3, 85, 7, 202, 182, 13, 69, 215, 22, 79, 9, 230, 201, 13, 78, 154, 3, 83, + 3, 85, 12, 210, 4, 70, 234, 237, 5, 79, 171, 137, 6, 84, 78, 80, 7, 76, + 69, 84, 84, 69, 82, 32, 169, 3, 8, 78, 85, 77, 69, 82, 65, 76, 32, 70, + 190, 1, 69, 90, 75, 50, 83, 36, 3, 78, 79, 82, 206, 249, 9, 85, 210, 200, + 1, 73, 198, 134, 1, 80, 2, 84, 254, 82, 67, 186, 22, 66, 2, 68, 2, 72, 2, + 86, 2, 89, 2, 90, 214, 22, 65, 3, 79, 23, 198, 214, 9, 83, 238, 239, 1, + 82, 146, 198, 1, 75, 210, 61, 70, 2, 76, 2, 77, 3, 78, 8, 230, 178, 13, + 72, 214, 22, 65, 2, 69, 3, 85, 4, 32, 2, 79, 85, 151, 178, 13, 72, 2, 29, + 5, 84, 72, 69, 82, 78, 2, 209, 191, 12, 2, 32, 84, 8, 38, 70, 146, 247, + 11, 84, 227, 55, 79, 4, 11, 73, 4, 130, 222, 11, 70, 163, 211, 1, 86, 64, + 76, 7, 76, 69, 84, 84, 69, 82, 32, 209, 3, 7, 78, 85, 77, 66, 69, 82, 32, + 58, 210, 1, 65, 38, 71, 38, 72, 30, 75, 38, 84, 74, 90, 246, 104, 77, + 244, 138, 3, 2, 69, 83, 218, 156, 3, 66, 2, 70, 2, 82, 2, 89, 242, 161, + 3, 78, 246, 215, 1, 76, 150, 55, 68, 146, 1, 81, 254, 2, 87, 255, 55, 83, + 4, 138, 180, 3, 76, 211, 193, 9, 73, 4, 218, 153, 12, 72, 135, 153, 1, + 69, 4, 214, 195, 13, 65, 3, 69, 4, 130, 140, 6, 72, 191, 183, 6, 65, 8, + 34, 72, 246, 194, 13, 65, 3, 69, 4, 230, 186, 12, 65, 143, 136, 1, 69, 4, + 11, 65, 4, 254, 243, 12, 73, 215, 79, 72, 6, 190, 131, 6, 84, 227, 166, + 6, 79, 178, 1, 64, 11, 77, 73, 67, 32, 76, 69, 84, 84, 69, 82, 32, 183, + 5, 83, 76, 228, 1, 2, 67, 72, 22, 68, 66, 69, 22, 73, 30, 77, 2, 78, 30, + 80, 22, 83, 70, 84, 50, 86, 38, 89, 94, 90, 218, 172, 6, 76, 2, 82, 254, + 209, 2, 71, 230, 255, 1, 79, 190, 198, 1, 66, 242, 40, 65, 242, 31, 75, + 174, 45, 72, 187, 2, 85, 2, 171, 180, 7, 69, 6, 26, 90, 219, 172, 13, 79, + 4, 138, 254, 8, 72, 219, 157, 4, 73, 5, 139, 192, 13, 70, 7, 246, 191, + 13, 65, 3, 69, 2, 249, 168, 13, 2, 69, 78, 2, 223, 174, 6, 69, 6, 26, 72, + 187, 171, 13, 73, 4, 232, 252, 8, 3, 67, 72, 79, 3, 79, 4, 26, 83, 247, + 170, 13, 65, 2, 227, 153, 13, 73, 4, 146, 252, 8, 79, 215, 137, 4, 69, + 14, 60, 2, 69, 82, 226, 136, 8, 65, 174, 163, 5, 82, 203, 17, 85, 7, 210, + 189, 13, 73, 3, 85, 4, 146, 251, 8, 72, 219, 157, 4, 65, 102, 52, 4, 73, + 65, 78, 32, 213, 153, 1, 3, 79, 78, 65, 100, 80, 7, 78, 85, 77, 66, 69, + 82, 32, 80, 5, 83, 73, 71, 78, 32, 139, 154, 10, 87, 10, 42, 84, 186, + 147, 8, 72, 147, 143, 4, 79, 6, 162, 228, 1, 87, 231, 135, 11, 69, 88, + 210, 1, 65, 86, 66, 62, 68, 98, 74, 2, 86, 30, 84, 42, 88, 226, 109, 71, + 2, 75, 2, 78, 2, 82, 250, 228, 8, 77, 214, 156, 3, 83, 206, 69, 67, 2, + 70, 2, 72, 2, 76, 2, 80, 2, 89, 2, 90, 186, 2, 73, 3, 85, 9, 45, 9, 85, + 82, 65, 77, 65, 90, 68, 65, 65, 7, 222, 213, 6, 45, 159, 225, 6, 72, 6, + 38, 65, 165, 250, 9, 3, 85, 85, 77, 5, 175, 182, 13, 71, 10, 34, 65, 178, + 184, 13, 73, 3, 85, 7, 37, 7, 72, 89, 65, 65, 85, 83, 72, 5, 179, 212, 6, + 45, 4, 242, 183, 13, 65, 3, 73, 6, 158, 181, 13, 72, 186, 2, 65, 3, 85, + 4, 132, 137, 11, 8, 83, 72, 65, 65, 89, 65, 84, 72, 171, 174, 2, 65, 144, + 1, 92, 6, 71, 68, 73, 65, 78, 32, 141, 7, 12, 85, 84, 72, 32, 65, 82, 65, + 66, 73, 65, 78, 32, 80, 58, 70, 74, 76, 145, 5, 7, 78, 85, 77, 66, 69, + 82, 32, 2, 11, 82, 2, 157, 155, 11, 10, 65, 67, 84, 73, 79, 78, 32, 79, + 78, 69, 60, 76, 6, 69, 84, 84, 69, 82, 32, 149, 4, 8, 73, 71, 65, 84, 85, + 82, 69, 32, 58, 234, 1, 65, 96, 6, 70, 73, 78, 65, 76, 32, 200, 1, 5, 82, + 69, 83, 72, 45, 230, 214, 1, 76, 178, 151, 4, 71, 90, 90, 34, 83, 66, 89, + 154, 193, 1, 72, 234, 5, 75, 130, 76, 66, 190, 173, 4, 78, 254, 1, 84, 2, + 87, 202, 103, 80, 171, 4, 77, 6, 26, 76, 243, 178, 12, 89, 4, 244, 240, + 5, 8, 84, 69, 82, 78, 65, 84, 69, 32, 239, 199, 1, 69, 18, 116, 3, 78, + 85, 78, 0, 5, 83, 65, 68, 72, 69, 0, 3, 84, 65, 87, 130, 215, 1, 65, 158, + 172, 6, 66, 131, 151, 5, 72, 5, 41, 8, 32, 87, 73, 84, 72, 32, 86, 69, 2, + 209, 199, 5, 4, 82, 84, 73, 67, 2, 193, 214, 1, 6, 65, 89, 73, 78, 45, + 68, 18, 42, 84, 158, 239, 5, 79, 143, 211, 5, 70, 10, 42, 72, 230, 215, + 1, 87, 231, 135, 11, 69, 4, 230, 194, 11, 82, 159, 2, 73, 64, 60, 7, 76, + 69, 84, 84, 69, 82, 32, 245, 3, 3, 78, 85, 77, 58, 202, 1, 65, 38, 68, + 74, 71, 34, 75, 34, 83, 78, 84, 218, 43, 90, 230, 165, 1, 76, 50, 81, + 206, 194, 1, 82, 238, 213, 2, 89, 154, 193, 1, 72, 234, 81, 66, 190, 173, + 4, 78, 254, 1, 87, 202, 103, 70, 171, 4, 77, 4, 202, 155, 3, 76, 211, + 193, 9, 89, 6, 32, 2, 72, 65, 219, 210, 1, 65, 4, 210, 254, 7, 76, 203, + 128, 5, 68, 4, 226, 44, 72, 163, 189, 5, 73, 4, 154, 178, 7, 65, 247, 75, + 72, 8, 26, 65, 239, 171, 12, 72, 6, 226, 163, 7, 77, 186, 218, 5, 68, + 143, 45, 84, 8, 166, 90, 72, 206, 209, 10, 69, 247, 128, 1, 65, 6, 56, 4, + 66, 69, 82, 32, 245, 240, 12, 4, 69, 82, 73, 67, 4, 26, 70, 223, 144, 12, + 79, 2, 207, 190, 11, 73, 146, 1, 80, 7, 79, 82, 75, 72, 79, 78, 32, 197, + 3, 8, 89, 69, 78, 73, 83, 69, 73, 32, 84, 54, 65, 202, 1, 69, 122, 73, + 30, 79, 203, 192, 11, 66, 45, 106, 69, 130, 180, 9, 83, 226, 243, 3, 66, + 2, 68, 2, 71, 2, 76, 2, 78, 2, 81, 2, 82, 2, 84, 3, 89, 20, 222, 167, 13, + 66, 2, 68, 2, 71, 2, 75, 2, 76, 2, 78, 2, 82, 2, 83, 2, 84, 3, 89, 20, + 74, 78, 142, 138, 13, 76, 158, 27, 83, 146, 1, 67, 2, 77, 2, 80, 3, 90, + 8, 182, 166, 13, 67, 2, 71, 2, 84, 3, 89, 7, 138, 166, 13, 67, 3, 81, 13, + 130, 3, 69, 238, 162, 13, 80, 2, 81, 3, 84, 62, 38, 65, 170, 1, 69, 86, + 73, 23, 79, 39, 98, 69, 166, 163, 13, 83, 62, 78, 86, 66, 2, 68, 2, 71, + 2, 76, 2, 81, 2, 82, 2, 84, 3, 89, 17, 158, 172, 11, 78, 150, 248, 1, 66, + 2, 71, 2, 75, 2, 84, 3, 89, 15, 46, 78, 178, 162, 13, 83, 146, 1, 67, 3, + 90, 6, 190, 163, 13, 67, 2, 84, 3, 89, 5, 155, 163, 13, 81, 6, 26, 69, + 239, 162, 13, 81, 5, 235, 162, 13, 75, 52, 148, 1, 10, 67, 79, 77, 66, + 73, 78, 73, 78, 71, 32, 36, 7, 76, 69, 84, 84, 69, 82, 32, 233, 1, 12, + 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 8, 146, 221, 5, 84, 243, + 213, 3, 68, 36, 170, 199, 1, 65, 178, 195, 1, 82, 214, 212, 2, 76, 58, + 90, 34, 83, 66, 89, 252, 195, 1, 6, 70, 73, 78, 65, 76, 32, 0, 6, 71, 73, + 77, 69, 76, 45, 134, 3, 75, 130, 76, 66, 190, 173, 4, 78, 254, 1, 84, 2, + 87, 202, 103, 80, 171, 4, 77, 8, 52, 4, 84, 87, 79, 32, 166, 130, 11, 70, + 179, 122, 66, 4, 150, 138, 12, 66, 71, 68, 6, 170, 180, 1, 87, 152, 140, + 3, 3, 65, 68, 85, 235, 150, 7, 77, 22, 212, 1, 34, 32, 87, 73, 84, 72, + 32, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 32, 77, 65, 82, 75, 32, + 87, 73, 84, 72, 32, 76, 69, 70, 84, 32, 82, 44, 7, 67, 79, 77, 73, 78, + 71, 32, 210, 1, 69, 239, 202, 12, 73, 2, 21, 3, 73, 71, 72, 2, 151, 197, + 9, 84, 10, 144, 1, 6, 65, 85, 84, 79, 77, 79, 20, 7, 70, 73, 82, 69, 32, + 69, 78, 20, 6, 80, 79, 76, 73, 67, 69, 184, 212, 2, 2, 84, 65, 191, 195, + 8, 66, 2, 135, 253, 10, 66, 2, 211, 129, 12, 71, 2, 135, 206, 9, 32, 8, + 70, 32, 245, 230, 11, 11, 45, 80, 73, 69, 67, 69, 32, 83, 87, 73, 77, 6, + 40, 4, 68, 79, 84, 32, 147, 234, 9, 66, 4, 26, 79, 235, 235, 9, 76, 2, + 169, 221, 2, 11, 86, 69, 82, 32, 84, 87, 79, 32, 68, 79, 84, 46, 82, 69, + 168, 6, 2, 84, 73, 148, 143, 11, 5, 72, 73, 85, 67, 72, 167, 177, 1, 80, + 36, 70, 78, 181, 5, 12, 82, 65, 84, 73, 78, 71, 32, 83, 89, 83, 84, 69, + 34, 22, 32, 247, 3, 45, 28, 108, 2, 66, 79, 32, 7, 67, 69, 78, 84, 82, + 69, 32, 114, 70, 50, 72, 42, 77, 202, 233, 6, 83, 239, 194, 3, 76, 4, + 190, 147, 13, 79, 155, 3, 88, 8, 50, 84, 238, 130, 11, 66, 222, 2, 65, + 219, 82, 67, 2, 37, 7, 69, 65, 82, 68, 82, 79, 80, 2, 207, 132, 11, 45, + 4, 180, 255, 1, 5, 73, 76, 69, 32, 70, 15, 79, 2, 17, 2, 65, 78, 2, 187, + 251, 9, 68, 4, 57, 12, 65, 73, 76, 66, 79, 88, 32, 87, 73, 84, 72, 32, 4, + 44, 3, 76, 79, 87, 21, 4, 82, 65, 73, 83, 2, 17, 2, 69, 82, 2, 205, 173, + 11, 2, 69, 68, 6, 108, 15, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, + 80, 85, 84, 32, 217, 242, 11, 6, 79, 85, 84, 76, 73, 78, 4, 18, 72, 3, + 76, 2, 229, 190, 1, 4, 45, 84, 89, 80, 2, 189, 132, 12, 6, 77, 32, 67, + 79, 77, 77, 6, 64, 2, 79, 78, 153, 177, 1, 8, 67, 65, 76, 32, 68, 73, 83, + 67, 2, 235, 250, 10, 32, 204, 1, 132, 1, 3, 65, 78, 71, 66, 73, 212, 8, + 5, 78, 65, 84, 69, 32, 192, 225, 3, 5, 84, 72, 79, 68, 79, 254, 186, 1, + 32, 227, 231, 5, 67, 6, 28, 2, 69, 32, 239, 21, 85, 4, 154, 191, 11, 66, + 211, 73, 72, 188, 1, 48, 5, 71, 73, 78, 65, 76, 21, 3, 89, 65, 32, 2, + 151, 133, 1, 32, 186, 1, 106, 65, 30, 70, 250, 1, 73, 32, 7, 76, 69, 84, + 84, 69, 82, 32, 142, 2, 83, 214, 1, 86, 243, 153, 11, 68, 4, 182, 142, 8, + 73, 3, 85, 12, 41, 8, 82, 65, 67, 84, 73, 79, 78, 32, 12, 56, 4, 79, 78, + 69, 32, 81, 6, 84, 72, 82, 69, 69, 32, 8, 42, 83, 170, 140, 11, 69, 46, + 72, 43, 81, 2, 177, 141, 11, 4, 73, 88, 84, 69, 4, 26, 83, 187, 142, 11, + 81, 2, 249, 223, 7, 4, 73, 88, 84, 69, 2, 225, 233, 11, 3, 83, 83, 72, + 104, 226, 1, 82, 166, 212, 6, 89, 150, 205, 2, 65, 38, 68, 46, 84, 46, + 86, 186, 24, 85, 210, 200, 1, 73, 42, 76, 246, 189, 1, 78, 46, 83, 82, + 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, 77, 2, 87, 186, 2, + 69, 3, 79, 6, 206, 135, 13, 72, 2, 82, 187, 2, 65, 18, 112, 20, 69, 81, + 85, 69, 78, 67, 69, 32, 70, 79, 82, 32, 76, 69, 84, 84, 69, 82, 32, 82, + 29, 4, 73, 71, 78, 32, 4, 178, 134, 13, 72, 3, 82, 14, 222, 161, 9, 65, + 74, 67, 98, 78, 234, 128, 2, 79, 227, 161, 1, 86, 26, 49, 10, 79, 87, 69, + 76, 32, 83, 73, 71, 78, 32, 26, 254, 162, 9, 65, 106, 86, 214, 20, 85, + 210, 200, 1, 73, 206, 134, 2, 69, 3, 79, 4, 242, 171, 9, 76, 27, 82, 226, + 1, 76, 4, 65, 71, 69, 32, 164, 4, 6, 77, 65, 78, 89, 65, 32, 247, 129, + 13, 67, 144, 1, 56, 6, 67, 65, 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 72, + 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 72, 194, 1, 65, 38, 69, 114, + 75, 42, 79, 22, 84, 178, 204, 6, 72, 170, 190, 4, 67, 2, 68, 2, 71, 138, + 176, 1, 83, 2, 90, 130, 3, 66, 254, 65, 76, 2, 77, 2, 78, 2, 80, 2, 87, + 186, 2, 73, 3, 85, 9, 226, 139, 11, 73, 131, 248, 1, 72, 15, 26, 72, 211, + 179, 12, 73, 10, 50, 84, 182, 139, 11, 67, 134, 245, 1, 75, 3, 80, 4, + 182, 128, 13, 83, 187, 2, 65, 6, 150, 128, 13, 72, 2, 89, 187, 2, 65, 5, + 211, 178, 12, 73, 6, 222, 186, 12, 83, 183, 71, 65, 80, 52, 7, 76, 69, + 84, 84, 69, 82, 32, 163, 147, 11, 68, 60, 246, 1, 65, 38, 67, 22, 68, 38, + 75, 34, 83, 30, 77, 130, 229, 2, 81, 174, 218, 7, 79, 204, 119, 2, 76, + 65, 156, 71, 2, 78, 85, 254, 1, 87, 138, 62, 69, 222, 61, 66, 2, 70, 2, + 71, 2, 72, 2, 74, 2, 82, 2, 84, 2, 88, 2, 89, 186, 2, 73, 3, 85, 7, 158, + 238, 2, 76, 167, 145, 10, 65, 2, 195, 129, 12, 65, 4, 178, 158, 8, 69, + 163, 222, 4, 72, 4, 206, 253, 11, 65, 227, 126, 72, 4, 26, 72, 175, 254, + 12, 65, 2, 239, 254, 11, 73, 124, 68, 11, 79, 77, 65, 78, 32, 83, 73, 89, + 65, 81, 32, 131, 197, 12, 69, 122, 172, 1, 17, 65, 76, 84, 69, 82, 78, + 65, 84, 69, 32, 78, 85, 77, 66, 69, 82, 32, 200, 1, 13, 70, 82, 65, 67, + 84, 73, 79, 78, 32, 79, 78, 69, 32, 48, 3, 77, 65, 82, 47, 78, 26, 54, + 70, 50, 83, 46, 84, 238, 225, 11, 78, 211, 110, 69, 6, 208, 187, 5, 3, + 79, 85, 82, 211, 195, 6, 73, 6, 160, 187, 5, 2, 73, 88, 171, 211, 5, 69, + 10, 138, 173, 2, 69, 12, 2, 87, 79, 183, 225, 8, 72, 4, 26, 83, 163, 250, + 10, 72, 2, 139, 251, 10, 73, 2, 11, 82, 2, 11, 65, 2, 219, 178, 11, 84, + 90, 33, 6, 85, 77, 66, 69, 82, 32, 90, 58, 69, 66, 70, 94, 78, 26, 83, + 78, 84, 131, 157, 5, 79, 10, 25, 4, 73, 71, 72, 84, 11, 138, 171, 2, 89, + 191, 165, 5, 32, 20, 18, 73, 35, 79, 10, 166, 2, 70, 147, 156, 5, 86, 10, + 134, 2, 82, 157, 156, 5, 2, 85, 82, 10, 65, 3, 73, 78, 69, 20, 40, 4, 69, + 86, 69, 78, 1, 2, 73, 88, 11, 166, 1, 84, 223, 205, 7, 32, 24, 34, 72, + 50, 87, 203, 168, 2, 69, 10, 34, 73, 197, 156, 5, 2, 82, 69, 4, 51, 82, + 10, 26, 69, 171, 156, 5, 79, 4, 11, 78, 4, 11, 84, 4, 159, 168, 2, 89, + 12, 34, 84, 133, 222, 10, 2, 78, 67, 10, 42, 66, 37, 6, 76, 73, 78, 69, + 68, 32, 2, 181, 233, 11, 4, 79, 88, 32, 84, 8, 254, 252, 2, 76, 254, 174, + 3, 87, 250, 181, 4, 66, 239, 13, 71, 12, 18, 72, 35, 76, 2, 245, 227, 11, + 3, 69, 65, 84, 10, 32, 2, 65, 80, 227, 218, 11, 73, 9, 29, 5, 80, 73, 78, + 71, 32, 6, 40, 6, 87, 72, 73, 84, 69, 32, 51, 66, 4, 44, 5, 65, 78, 68, + 32, 66, 247, 199, 9, 83, 2, 221, 199, 9, 4, 76, 65, 67, 75, 144, 13, 194, + 1, 65, 174, 65, 68, 30, 69, 194, 13, 72, 134, 25, 73, 206, 4, 76, 150, + 15, 79, 234, 8, 82, 208, 15, 15, 83, 65, 76, 84, 69, 82, 32, 80, 65, 72, + 76, 65, 86, 73, 32, 214, 5, 85, 151, 215, 11, 77, 154, 6, 134, 2, 68, 38, + 71, 212, 1, 11, 72, 65, 87, 72, 32, 72, 77, 79, 78, 71, 32, 138, 23, 76, + 130, 6, 78, 58, 82, 156, 22, 2, 83, 83, 132, 2, 10, 85, 32, 67, 73, 78, + 32, 72, 65, 85, 32, 180, 7, 3, 87, 32, 80, 172, 213, 7, 2, 67, 75, 145, + 217, 4, 4, 80, 69, 82, 67, 5, 157, 184, 1, 4, 68, 73, 78, 71, 14, 26, 69, + 191, 201, 12, 79, 13, 34, 32, 158, 238, 12, 82, 3, 83, 6, 72, 6, 87, 73, + 84, 72, 32, 67, 149, 139, 4, 6, 70, 65, 67, 73, 78, 71, 4, 50, 85, 181, + 197, 7, 6, 73, 82, 67, 76, 69, 68, 2, 255, 227, 11, 82, 254, 1, 190, 1, + 67, 160, 6, 9, 77, 65, 82, 75, 32, 67, 73, 77, 32, 160, 1, 7, 78, 85, 77, + 66, 69, 82, 32, 244, 1, 5, 83, 73, 71, 78, 32, 148, 10, 7, 86, 79, 87, + 69, 76, 32, 75, 227, 233, 10, 68, 78, 92, 9, 76, 65, 78, 32, 83, 73, 71, + 78, 32, 137, 3, 9, 79, 78, 83, 79, 78, 65, 78, 84, 32, 38, 132, 1, 2, 72, + 65, 38, 75, 46, 76, 34, 84, 82, 86, 30, 89, 148, 9, 2, 88, 89, 176, 5, 2, + 80, 72, 174, 1, 70, 165, 2, 2, 77, 85, 4, 162, 186, 2, 87, 187, 175, 10, + 77, 6, 250, 15, 72, 202, 186, 12, 79, 159, 14, 87, 4, 214, 12, 65, 231, + 158, 12, 73, 8, 22, 83, 247, 9, 72, 6, 152, 185, 2, 3, 72, 69, 69, 150, + 245, 8, 65, 3, 87, 4, 226, 184, 2, 65, 3, 87, 4, 198, 184, 2, 65, 223, + 233, 9, 69, 40, 122, 67, 38, 72, 46, 78, 60, 2, 80, 76, 2, 81, 222, 210, + 2, 76, 2, 77, 2, 82, 2, 86, 2, 88, 2, 89, 147, 238, 9, 65, 4, 230, 211, + 2, 72, 147, 238, 9, 65, 6, 194, 211, 2, 76, 2, 78, 147, 238, 9, 65, 12, + 58, 67, 22, 84, 202, 210, 2, 75, 2, 76, 147, 238, 9, 65, 2, 219, 210, 2, + 72, 4, 198, 210, 2, 72, 3, 83, 14, 42, 75, 50, 83, 38, 84, 195, 211, 12, + 72, 4, 26, 72, 143, 167, 12, 69, 2, 183, 138, 6, 65, 4, 138, 171, 11, 85, + 191, 185, 1, 79, 4, 254, 169, 11, 85, 179, 18, 65, 14, 52, 7, 72, 85, 78, + 68, 82, 69, 68, 38, 84, 79, 77, 4, 108, 2, 32, 77, 223, 226, 12, 83, 8, + 24, 2, 69, 78, 51, 82, 6, 26, 32, 243, 226, 12, 83, 4, 18, 66, 35, 84, 2, + 145, 194, 4, 3, 73, 76, 76, 2, 11, 72, 2, 137, 185, 9, 3, 79, 85, 83, 72, + 188, 1, 4, 67, 73, 77, 32, 250, 2, 72, 32, 3, 73, 66, 32, 22, 77, 86, 78, + 50, 84, 124, 4, 86, 79, 83, 32, 198, 1, 88, 208, 1, 6, 90, 87, 74, 32, + 84, 72, 150, 176, 1, 76, 219, 205, 4, 65, 16, 174, 1, 67, 84, 5, 78, 82, + 69, 83, 32, 22, 84, 148, 164, 11, 7, 80, 85, 66, 32, 68, 65, 87, 197, + 185, 1, 16, 72, 65, 73, 83, 32, 76, 85, 83, 32, 78, 84, 79, 71, 32, 78, + 84, 4, 48, 7, 85, 65, 77, 32, 84, 83, 72, 131, 4, 72, 2, 11, 79, 2, 167, + 175, 2, 79, 2, 207, 182, 1, 84, 6, 56, 3, 88, 87, 86, 157, 221, 12, 5, + 83, 79, 86, 32, 82, 5, 213, 131, 6, 4, 32, 67, 72, 87, 4, 214, 72, 78, + 171, 129, 12, 76, 2, 251, 163, 11, 89, 6, 40, 4, 69, 69, 74, 32, 171, + 159, 12, 85, 4, 128, 3, 2, 84, 83, 57, 2, 83, 85, 4, 26, 84, 231, 213, 8, + 81, 2, 251, 172, 2, 85, 6, 196, 1, 7, 88, 72, 69, 69, 74, 32, 67, 216, + 139, 8, 12, 72, 73, 82, 68, 45, 83, 84, 65, 71, 69, 32, 72, 155, 170, 4, + 65, 14, 54, 70, 22, 83, 30, 84, 190, 69, 76, 163, 212, 7, 78, 2, 191, + 200, 12, 69, 2, 177, 128, 6, 2, 69, 69, 6, 42, 72, 29, 6, 83, 72, 65, 66, + 32, 67, 4, 82, 73, 231, 200, 12, 79, 2, 223, 188, 5, 69, 14, 34, 73, 22, + 89, 191, 214, 10, 65, 2, 151, 159, 11, 65, 10, 40, 4, 69, 69, 77, 32, + 139, 186, 12, 79, 8, 84, 3, 78, 84, 88, 128, 254, 5, 2, 84, 79, 142, 158, + 2, 82, 233, 129, 3, 2, 70, 65, 2, 255, 253, 5, 73, 2, 215, 168, 2, 65, + 56, 50, 65, 66, 69, 38, 73, 2, 85, 38, 79, 39, 87, 20, 170, 1, 65, 2, 73, + 2, 85, 2, 87, 158, 214, 12, 66, 3, 86, 8, 106, 69, 158, 214, 12, 66, 3, + 86, 8, 70, 65, 158, 214, 12, 66, 3, 86, 8, 34, 79, 158, 214, 12, 66, 3, + 86, 4, 154, 214, 12, 66, 3, 86, 76, 18, 76, 23, 77, 2, 155, 152, 12, 65, + 74, 74, 32, 104, 6, 89, 82, 69, 78, 69, 32, 241, 249, 3, 4, 83, 32, 85, + 80, 8, 80, 3, 66, 82, 65, 250, 231, 10, 84, 192, 94, 4, 68, 79, 87, 78, + 1, 2, 85, 80, 2, 143, 178, 12, 78, 64, 80, 2, 76, 69, 40, 4, 82, 73, 71, + 72, 253, 2, 7, 78, 85, 77, 66, 69, 82, 32, 48, 38, 70, 89, 5, 84, 84, 69, + 82, 32, 2, 57, 12, 84, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 70, 2, + 137, 209, 5, 2, 76, 69, 46, 224, 1, 5, 70, 73, 78, 65, 76, 30, 84, 246, + 118, 68, 34, 76, 50, 81, 206, 194, 1, 82, 134, 212, 2, 65, 50, 71, 90, + 90, 34, 83, 66, 89, 154, 193, 1, 72, 234, 5, 75, 130, 76, 66, 190, 173, + 4, 78, 254, 1, 87, 202, 103, 80, 171, 4, 77, 2, 209, 208, 11, 2, 32, 78, + 4, 202, 209, 10, 69, 247, 128, 1, 65, 14, 198, 120, 84, 198, 234, 9, 70, + 143, 84, 79, 4, 32, 2, 67, 65, 183, 144, 12, 68, 2, 251, 187, 11, 75, + 184, 2, 94, 65, 216, 1, 11, 69, 78, 84, 72, 69, 83, 73, 90, 69, 68, 32, + 242, 16, 84, 243, 235, 11, 82, 14, 80, 5, 71, 82, 65, 80, 72, 48, 5, 76, + 76, 69, 76, 32, 201, 138, 6, 2, 67, 72, 6, 206, 121, 85, 198, 187, 8, 32, + 175, 219, 2, 79, 6, 44, 5, 87, 73, 84, 72, 32, 191, 174, 12, 84, 4, 214, + 165, 6, 84, 151, 138, 4, 72, 150, 2, 252, 1, 7, 72, 65, 78, 71, 85, 76, + 32, 188, 4, 10, 73, 68, 69, 79, 71, 82, 65, 80, 72, 32, 188, 7, 18, 75, + 79, 82, 69, 65, 78, 32, 67, 72, 65, 82, 65, 67, 84, 69, 82, 32, 79, 44, + 7, 78, 85, 77, 66, 69, 82, 32, 138, 187, 4, 68, 197, 154, 2, 2, 76, 65, + 58, 102, 67, 110, 72, 30, 75, 66, 77, 34, 78, 34, 80, 62, 82, 30, 83, 26, + 84, 73, 5, 73, 69, 85, 78, 71, 10, 34, 72, 33, 4, 73, 69, 85, 67, 4, 141, + 3, 4, 73, 69, 85, 67, 7, 11, 32, 4, 206, 201, 12, 65, 3, 85, 4, 197, 2, + 3, 73, 69, 85, 8, 168, 2, 5, 72, 73, 69, 85, 75, 13, 5, 73, 89, 69, 79, + 75, 4, 245, 1, 4, 73, 69, 85, 77, 4, 213, 1, 4, 73, 69, 85, 78, 8, 168, + 1, 5, 72, 73, 69, 85, 80, 13, 4, 73, 69, 85, 80, 4, 121, 4, 73, 69, 85, + 76, 4, 93, 3, 73, 79, 83, 8, 56, 5, 72, 73, 69, 85, 84, 13, 5, 73, 75, + 69, 85, 84, 4, 11, 72, 5, 167, 196, 12, 32, 72, 148, 1, 2, 65, 76, 30, + 67, 74, 69, 82, 70, 112, 2, 76, 65, 22, 77, 38, 78, 32, 2, 82, 69, 78, + 83, 138, 2, 84, 50, 87, 134, 215, 10, 72, 159, 79, 79, 2, 225, 233, 7, 2, + 76, 73, 4, 32, 2, 79, 78, 199, 192, 10, 65, 2, 137, 212, 7, 4, 71, 82, + 65, 84, 6, 42, 78, 246, 253, 8, 65, 239, 155, 3, 73, 2, 169, 4, 5, 84, + 69, 82, 80, 82, 10, 58, 73, 156, 186, 11, 5, 69, 83, 84, 73, 86, 231, 16, + 79, 6, 208, 2, 3, 78, 65, 78, 158, 170, 12, 82, 3, 86, 2, 179, 138, 12, + 66, 4, 174, 245, 9, 69, 239, 253, 1, 79, 4, 194, 169, 11, 73, 195, 1, 65, + 8, 38, 83, 170, 178, 11, 80, 195, 109, 65, 4, 182, 179, 6, 79, 219, 142, + 6, 84, 18, 58, 69, 34, 79, 22, 80, 34, 84, 50, 85, 163, 180, 11, 73, 4, + 186, 240, 10, 86, 235, 79, 76, 2, 231, 212, 7, 67, 2, 11, 69, 2, 247, + 161, 4, 67, 4, 26, 85, 247, 145, 11, 79, 2, 247, 174, 12, 68, 4, 26, 80, + 147, 192, 12, 78, 2, 21, 3, 69, 82, 86, 2, 131, 183, 11, 73, 6, 162, 211, + 10, 72, 238, 156, 1, 69, 227, 48, 87, 4, 206, 157, 9, 79, 155, 235, 1, + 65, 4, 166, 253, 7, 32, 137, 242, 3, 2, 74, 69, 22, 42, 69, 46, 70, 42, + 78, 30, 83, 51, 84, 4, 216, 1, 3, 73, 71, 72, 243, 225, 4, 76, 4, 160, 1, + 2, 79, 85, 13, 2, 73, 70, 2, 133, 1, 3, 73, 78, 69, 4, 34, 73, 73, 4, 69, + 86, 69, 78, 2, 71, 88, 8, 34, 72, 46, 87, 247, 236, 11, 69, 2, 11, 73, 2, + 11, 82, 2, 219, 235, 10, 84, 4, 11, 69, 4, 198, 210, 10, 78, 179, 109, + 76, 18, 128, 1, 3, 73, 65, 76, 216, 1, 3, 89, 32, 80, 144, 141, 8, 6, 78, + 69, 82, 83, 72, 73, 189, 167, 3, 6, 32, 65, 76, 84, 69, 82, 12, 62, 32, + 189, 122, 10, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 10, 38, 68, 41, 5, + 76, 73, 78, 69, 32, 2, 157, 155, 4, 5, 73, 70, 70, 69, 82, 8, 134, 186, + 3, 68, 242, 45, 70, 20, 4, 66, 65, 67, 75, 243, 209, 8, 85, 2, 235, 222, + 3, 79, 10, 98, 69, 52, 9, 73, 86, 69, 45, 80, 85, 76, 76, 45, 89, 9, 80, + 79, 82, 84, 32, 67, 79, 78, 84, 4, 182, 165, 11, 68, 145, 62, 5, 78, 71, + 69, 82, 32, 4, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 233, 155, 5, 6, + 45, 79, 85, 84, 80, 85, 2, 227, 164, 11, 82, 114, 192, 1, 12, 71, 76, 79, + 84, 84, 65, 76, 32, 83, 84, 79, 80, 62, 76, 160, 3, 3, 82, 73, 83, 36, + 14, 77, 73, 68, 45, 76, 69, 86, 69, 76, 32, 84, 79, 78, 69, 57, 7, 83, + 65, 78, 68, 72, 73, 32, 7, 11, 32, 4, 206, 5, 70, 197, 166, 11, 4, 86, + 65, 82, 73, 82, 72, 6, 69, 84, 84, 69, 82, 32, 213, 2, 7, 79, 87, 45, 70, + 65, 76, 76, 74, 206, 1, 70, 226, 241, 6, 73, 2, 85, 166, 242, 1, 78, 214, + 135, 3, 67, 2, 75, 2, 80, 2, 84, 254, 68, 66, 2, 68, 2, 71, 2, 72, 2, 76, + 2, 77, 2, 82, 2, 83, 2, 86, 2, 90, 186, 2, 65, 2, 69, 3, 79, 20, 44, 5, + 73, 78, 65, 76, 32, 223, 178, 12, 65, 18, 198, 186, 10, 78, 150, 248, 1, + 75, 2, 76, 2, 77, 2, 80, 2, 84, 2, 87, 3, 89, 8, 157, 1, 5, 73, 78, 71, + 32, 84, 7, 11, 32, 4, 192, 1, 5, 76, 79, 78, 71, 32, 15, 70, 12, 66, 84, + 73, 12, 71, 76, 79, 84, 84, 65, 76, 32, 83, 84, 79, 80, 8, 21, 3, 79, 78, + 69, 9, 11, 32, 6, 32, 4, 76, 79, 78, 71, 27, 70, 5, 11, 32, 2, 11, 70, 2, + 135, 181, 3, 73, 2, 223, 161, 4, 82, 4, 222, 175, 12, 70, 3, 73, 80, 130, + 1, 65, 122, 78, 162, 1, 82, 222, 9, 83, 44, 3, 84, 82, 73, 254, 16, 68, + 173, 192, 11, 9, 79, 80, 76, 69, 32, 72, 85, 71, 71, 12, 50, 67, 50, 78, + 218, 204, 6, 32, 135, 225, 5, 82, 6, 190, 255, 10, 79, 190, 27, 69, 147, + 147, 1, 72, 2, 199, 153, 11, 85, 10, 118, 71, 20, 3, 83, 73, 86, 190, + 171, 1, 84, 224, 172, 4, 10, 32, 79, 86, 69, 82, 32, 83, 84, 65, 77, 175, + 167, 4, 67, 2, 147, 173, 11, 85, 2, 167, 239, 11, 69, 48, 186, 1, 32, + 116, 10, 80, 69, 78, 68, 73, 67, 85, 76, 65, 82, 42, 83, 198, 136, 7, 67, + 224, 10, 10, 77, 65, 78, 69, 78, 84, 32, 80, 65, 80, 153, 234, 1, 8, 70, + 79, 82, 77, 73, 78, 71, 32, 6, 34, 77, 30, 84, 223, 163, 11, 83, 2, 153, + 230, 1, 2, 73, 76, 2, 189, 196, 10, 8, 69, 78, 32, 84, 72, 79, 85, 83, 5, + 129, 215, 8, 5, 32, 87, 73, 84, 72, 32, 60, 2, 79, 78, 182, 75, 80, 213, + 213, 10, 4, 69, 86, 69, 82, 28, 22, 32, 243, 5, 65, 26, 216, 2, 10, 68, + 79, 73, 78, 71, 32, 67, 65, 82, 84, 32, 3, 73, 78, 32, 108, 5, 87, 73, + 84, 72, 32, 208, 185, 7, 4, 70, 82, 79, 87, 200, 13, 27, 82, 65, 73, 83, + 73, 78, 71, 32, 66, 79, 84, 72, 32, 72, 65, 78, 68, 83, 32, 73, 78, 32, + 67, 69, 76, 69, 66, 128, 141, 4, 5, 67, 76, 73, 77, 66, 201, 45, 11, 66, + 79, 87, 73, 78, 71, 32, 68, 69, 69, 80, 2, 11, 87, 2, 179, 169, 3, 72, 4, + 76, 7, 83, 84, 69, 65, 77, 89, 32, 217, 211, 11, 6, 76, 79, 84, 85, 83, + 32, 2, 197, 148, 12, 2, 82, 79, 12, 154, 1, 66, 212, 134, 2, 3, 80, 79, + 85, 160, 157, 1, 2, 67, 82, 196, 214, 5, 6, 70, 79, 76, 68, 69, 68, 177, + 168, 2, 8, 72, 69, 65, 68, 83, 67, 65, 82, 4, 36, 3, 76, 79, 78, 159, + 159, 10, 65, 2, 11, 68, 2, 11, 32, 2, 11, 72, 2, 11, 65, 2, 203, 234, 11, + 73, 2, 21, 3, 76, 32, 67, 2, 161, 236, 10, 4, 79, 77, 80, 85, 4, 232, + 230, 8, 2, 69, 84, 251, 180, 2, 79, 2, 217, 227, 8, 2, 32, 68, 140, 2, + 66, 65, 180, 19, 9, 73, 76, 73, 80, 80, 73, 78, 69, 32, 47, 79, 204, 1, + 108, 6, 71, 83, 45, 80, 65, 32, 189, 7, 16, 73, 83, 84, 79, 83, 32, 68, + 73, 83, 67, 32, 83, 73, 71, 78, 32, 112, 100, 7, 76, 69, 84, 84, 69, 82, + 32, 248, 4, 5, 77, 65, 82, 75, 32, 30, 83, 33, 4, 68, 79, 85, 66, 96, + 138, 2, 65, 138, 1, 67, 50, 68, 42, 83, 64, 5, 86, 79, 73, 67, 69, 174, + 204, 8, 71, 218, 134, 3, 78, 82, 84, 46, 75, 2, 80, 2, 90, 162, 7, 69, + 222, 61, 66, 2, 70, 2, 72, 2, 74, 2, 76, 2, 77, 2, 81, 2, 82, 2, 87, 2, + 88, 2, 89, 186, 2, 73, 2, 79, 3, 85, 7, 80, 8, 76, 84, 69, 82, 78, 65, + 84, 69, 21, 8, 83, 80, 73, 82, 65, 84, 69, 68, 2, 163, 154, 12, 32, 2, + 11, 32, 2, 167, 154, 12, 70, 6, 26, 65, 251, 153, 12, 72, 5, 159, 182, 8, + 78, 6, 226, 153, 12, 68, 2, 90, 187, 2, 65, 6, 236, 135, 8, 4, 77, 65, + 76, 76, 206, 145, 4, 72, 187, 2, 65, 4, 34, 68, 21, 4, 76, 69, 83, 83, 2, + 211, 163, 10, 32, 2, 243, 247, 8, 32, 4, 130, 212, 11, 68, 59, 83, 10, + 28, 3, 73, 78, 71, 31, 85, 2, 241, 205, 11, 2, 76, 69, 8, 58, 66, 225, + 206, 11, 8, 80, 69, 82, 70, 73, 88, 69, 68, 6, 229, 150, 8, 13, 74, 79, + 73, 78, 69, 68, 32, 76, 69, 84, 84, 69, 82, 92, 238, 1, 66, 146, 1, 67, + 172, 2, 2, 68, 79, 38, 71, 66, 72, 64, 2, 76, 73, 32, 2, 77, 65, 66, 80, + 162, 1, 82, 38, 83, 150, 1, 84, 70, 87, 168, 203, 5, 2, 70, 76, 172, 224, + 1, 2, 79, 88, 188, 193, 3, 2, 69, 65, 142, 7, 65, 135, 1, 86, 10, 52, 2, + 69, 69, 22, 79, 205, 40, 4, 85, 76, 76, 83, 5, 199, 142, 7, 72, 4, 32, 2, + 79, 77, 175, 150, 12, 87, 2, 11, 69, 2, 219, 189, 11, 82, 16, 34, 65, 86, + 72, 22, 76, 23, 79, 6, 194, 200, 5, 80, 200, 192, 3, 8, 82, 80, 69, 78, + 84, 82, 89, 32, 223, 140, 3, 84, 2, 255, 175, 2, 73, 2, 219, 218, 10, 85, + 6, 26, 76, 33, 2, 77, 66, 2, 11, 85, 2, 239, 196, 11, 77, 5, 37, 7, 73, + 78, 73, 78, 71, 32, 79, 2, 237, 172, 9, 5, 66, 76, 73, 81, 85, 4, 222, + 235, 10, 76, 175, 145, 1, 86, 4, 42, 82, 245, 182, 10, 4, 65, 85, 78, 84, + 2, 195, 220, 10, 65, 6, 42, 69, 198, 180, 7, 79, 155, 209, 2, 73, 2, 183, + 221, 11, 76, 4, 242, 128, 12, 76, 203, 17, 68, 4, 40, 2, 78, 65, 181, + 169, 9, 2, 84, 84, 2, 159, 233, 8, 67, 8, 52, 2, 69, 68, 50, 76, 237, + 136, 7, 3, 65, 80, 89, 2, 25, 4, 69, 83, 84, 82, 2, 211, 201, 10, 73, 4, + 184, 167, 4, 2, 85, 77, 229, 211, 2, 3, 65, 78, 69, 4, 230, 132, 10, 79, + 255, 250, 1, 65, 12, 108, 2, 72, 73, 154, 145, 11, 65, 154, 45, 76, 128, + 19, 3, 84, 82, 65, 165, 39, 7, 77, 65, 76, 76, 32, 65, 88, 4, 146, 170, + 2, 69, 151, 229, 9, 80, 6, 200, 165, 4, 5, 65, 84, 84, 79, 79, 250, 164, + 7, 73, 195, 36, 85, 4, 246, 196, 7, 79, 221, 187, 3, 5, 65, 86, 89, 32, + 66, 4, 218, 232, 1, 83, 25, 4, 68, 79, 85, 66, 60, 56, 8, 69, 78, 73, 67, + 73, 65, 78, 32, 183, 138, 10, 76, 58, 92, 7, 76, 69, 84, 84, 69, 82, 32, + 160, 3, 7, 78, 85, 77, 66, 69, 82, 32, 199, 248, 5, 87, 44, 234, 1, 65, + 34, 68, 22, 72, 22, 81, 22, 83, 58, 84, 202, 246, 1, 87, 150, 212, 5, 90, + 130, 157, 1, 89, 200, 188, 1, 2, 82, 79, 128, 92, 3, 71, 65, 77, 134, 8, + 75, 130, 1, 78, 132, 58, 3, 76, 65, 77, 138, 17, 66, 186, 30, 80, 171, 4, + 77, 4, 198, 137, 11, 76, 187, 49, 73, 2, 151, 172, 3, 69, 4, 171, 213, 6, + 69, 2, 255, 136, 11, 79, 6, 130, 253, 9, 65, 186, 141, 1, 72, 165, 124, + 2, 69, 77, 4, 214, 228, 11, 65, 191, 8, 69, 12, 186, 49, 84, 187, 151, 4, + 79, 40, 104, 2, 67, 75, 66, 71, 62, 76, 90, 78, 178, 1, 83, 32, 7, 84, + 67, 72, 70, 79, 82, 75, 243, 132, 12, 69, 5, 17, 2, 85, 80, 2, 21, 3, 32, + 84, 82, 2, 155, 217, 10, 85, 7, 11, 32, 4, 26, 78, 179, 202, 11, 70, 2, + 183, 254, 10, 79, 6, 52, 4, 69, 32, 79, 70, 238, 90, 67, 247, 171, 11, + 76, 2, 11, 32, 2, 139, 198, 9, 80, 14, 68, 2, 67, 72, 46, 69, 186, 149, + 4, 87, 242, 232, 6, 75, 219, 98, 65, 4, 144, 140, 3, 2, 69, 68, 211, 235, + 7, 73, 4, 28, 2, 32, 68, 195, 71, 65, 2, 185, 241, 4, 2, 69, 67, 4, 174, + 241, 10, 67, 139, 1, 84, 5, 165, 186, 9, 10, 32, 87, 73, 84, 72, 32, 84, + 69, 69, 32, 218, 1, 38, 65, 218, 9, 85, 179, 250, 11, 68, 176, 1, 78, 67, + 128, 1, 12, 78, 67, 75, 32, 67, 79, 78, 83, 84, 65, 78, 84, 83, 89, 6, + 44, 5, 69, 32, 79, 70, 32, 179, 236, 10, 65, 4, 56, 6, 73, 78, 84, 69, + 82, 69, 189, 173, 11, 2, 87, 79, 2, 231, 235, 6, 83, 5, 45, 9, 32, 79, + 86, 69, 82, 32, 84, 87, 79, 2, 11, 32, 2, 159, 238, 11, 80, 166, 1, 96, + 9, 73, 78, 71, 32, 67, 65, 82, 68, 32, 149, 151, 4, 9, 71, 82, 79, 85, + 78, 68, 32, 83, 76, 164, 1, 182, 1, 66, 44, 3, 82, 69, 68, 0, 5, 87, 72, + 73, 84, 69, 42, 70, 74, 75, 38, 69, 34, 83, 36, 3, 81, 85, 69, 14, 84, + 92, 2, 65, 67, 0, 3, 78, 73, 78, 13, 4, 74, 65, 67, 75, 4, 40, 4, 76, 65, + 67, 75, 203, 208, 10, 65, 2, 17, 2, 32, 74, 2, 203, 225, 1, 79, 18, 30, + 79, 249, 1, 2, 73, 86, 10, 128, 2, 2, 85, 82, 175, 243, 10, 79, 16, 34, + 78, 185, 1, 3, 73, 78, 71, 8, 181, 1, 4, 73, 71, 72, 84, 16, 32, 2, 69, + 86, 117, 2, 73, 88, 8, 91, 69, 66, 78, 69, 12, 3, 72, 82, 69, 12, 2, 87, + 79, 161, 1, 5, 82, 85, 77, 80, 45, 8, 23, 78, 8, 11, 69, 8, 25, 4, 32, + 79, 70, 32, 8, 88, 3, 67, 76, 85, 20, 3, 83, 80, 65, 158, 207, 8, 72, + 137, 3, 5, 68, 73, 65, 77, 79, 2, 255, 189, 11, 66, 2, 219, 231, 10, 68, + 42, 90, 50, 250, 192, 9, 49, 214, 185, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, + 2, 56, 3, 57, 7, 202, 250, 11, 48, 3, 49, 41, 46, 83, 160, 4, 2, 84, 79, + 239, 189, 8, 78, 26, 52, 5, 32, 83, 73, 71, 78, 221, 223, 8, 2, 45, 77, + 25, 11, 32, 22, 64, 3, 73, 78, 32, 124, 5, 87, 73, 84, 72, 32, 219, 235, + 3, 65, 6, 34, 76, 22, 82, 247, 212, 10, 84, 2, 41, 2, 69, 70, 2, 21, 3, + 73, 71, 72, 2, 133, 169, 10, 6, 84, 32, 72, 65, 76, 70, 14, 162, 1, 68, + 34, 83, 204, 221, 9, 4, 84, 73, 76, 68, 140, 117, 5, 66, 76, 65, 67, 75, + 185, 35, 16, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 32, 65, 67, 67, 69, + 78, 2, 11, 79, 2, 231, 207, 9, 84, 4, 54, 77, 165, 157, 5, 7, 85, 66, 83, + 67, 82, 73, 80, 2, 197, 231, 8, 3, 65, 76, 76, 11, 33, 6, 32, 70, 79, 82, + 77, 32, 8, 154, 136, 10, 70, 71, 84, 58, 232, 1, 5, 76, 73, 67, 69, 32, + 122, 80, 136, 1, 11, 82, 84, 65, 66, 76, 69, 32, 83, 84, 69, 82, 22, 83, + 158, 1, 84, 146, 1, 85, 196, 1, 4, 87, 69, 82, 32, 202, 231, 6, 79, 245, + 204, 4, 11, 67, 75, 69, 84, 32, 67, 65, 76, 67, 85, 76, 6, 52, 3, 67, 65, + 82, 141, 234, 3, 4, 79, 70, 70, 73, 5, 173, 221, 9, 11, 83, 32, 82, 69, + 86, 79, 76, 86, 73, 78, 71, 6, 76, 13, 32, 68, 73, 82, 69, 67, 84, 73, + 79, 78, 65, 76, 32, 187, 203, 1, 67, 4, 166, 117, 73, 185, 162, 6, 6, 70, + 79, 82, 77, 65, 84, 2, 191, 210, 11, 69, 12, 40, 2, 69, 73, 22, 84, 195, + 246, 4, 73, 2, 147, 161, 11, 68, 8, 36, 3, 65, 76, 32, 163, 228, 10, 66, + 6, 130, 202, 1, 72, 217, 180, 6, 4, 77, 65, 82, 75, 8, 66, 65, 210, 247, + 1, 32, 173, 238, 8, 6, 84, 69, 68, 32, 80, 76, 4, 26, 66, 179, 208, 11, + 84, 2, 29, 5, 76, 69, 32, 87, 65, 2, 135, 47, 84, 12, 108, 4, 76, 84, 82, + 89, 28, 7, 82, 73, 78, 71, 32, 76, 73, 28, 2, 84, 73, 250, 135, 10, 78, + 199, 228, 1, 67, 2, 165, 168, 11, 2, 32, 76, 2, 209, 156, 5, 2, 81, 85, + 4, 197, 137, 10, 2, 78, 71, 8, 24, 2, 79, 78, 47, 83, 4, 128, 218, 10, 4, + 45, 79, 70, 70, 15, 32, 4, 160, 213, 8, 3, 76, 69, 69, 219, 132, 2, 89, + 140, 1, 74, 69, 162, 10, 73, 234, 2, 79, 237, 139, 9, 6, 65, 89, 69, 82, + 32, 66, 102, 132, 1, 6, 71, 78, 65, 78, 84, 32, 66, 83, 156, 167, 5, 4, + 67, 69, 68, 69, 144, 193, 1, 5, 86, 73, 79, 85, 83, 157, 33, 2, 84, 90, + 6, 42, 87, 146, 151, 5, 80, 243, 139, 5, 77, 2, 235, 160, 7, 79, 70, 176, + 1, 27, 69, 78, 84, 65, 84, 73, 79, 78, 32, 70, 79, 82, 77, 32, 70, 79, + 82, 32, 86, 69, 82, 84, 73, 67, 65, 76, 32, 241, 162, 8, 10, 67, 82, 73, + 80, 84, 73, 79, 78, 32, 84, 68, 198, 1, 67, 22, 69, 46, 72, 50, 73, 94, + 76, 188, 1, 6, 82, 73, 71, 72, 84, 32, 192, 2, 6, 87, 65, 86, 89, 32, 76, + 202, 136, 4, 83, 192, 171, 4, 9, 84, 87, 79, 32, 68, 79, 84, 32, 76, 163, + 99, 81, 4, 203, 170, 2, 79, 6, 138, 252, 5, 88, 214, 194, 2, 77, 3, 78, + 2, 233, 215, 8, 7, 79, 82, 73, 90, 79, 78, 84, 4, 49, 10, 68, 69, 79, 71, + 82, 65, 80, 72, 73, 67, 4, 11, 32, 4, 206, 154, 9, 67, 35, 70, 22, 40, 4, + 69, 70, 84, 32, 191, 128, 10, 79, 20, 112, 6, 87, 72, 73, 84, 69, 32, + 142, 1, 66, 42, 68, 218, 93, 67, 146, 6, 65, 218, 164, 7, 80, 154, 2, 83, + 39, 84, 4, 162, 2, 67, 159, 93, 76, 22, 110, 66, 42, 68, 36, 6, 87, 72, + 73, 84, 69, 32, 182, 93, 67, 146, 6, 65, 218, 164, 7, 80, 154, 2, 83, 39, + 84, 2, 177, 94, 6, 76, 65, 67, 75, 32, 76, 2, 209, 99, 5, 79, 85, 66, 76, + 69, 6, 74, 67, 17, 14, 76, 69, 78, 84, 73, 67, 85, 76, 65, 82, 32, 66, + 82, 65, 2, 131, 93, 79, 4, 198, 143, 11, 67, 177, 29, 2, 75, 67, 2, 235, + 252, 9, 79, 22, 46, 78, 156, 1, 2, 86, 65, 171, 201, 11, 77, 10, 34, 84, + 173, 171, 6, 2, 67, 69, 6, 26, 32, 53, 2, 69, 82, 2, 21, 3, 83, 67, 82, + 2, 253, 235, 9, 2, 69, 69, 5, 17, 2, 32, 73, 2, 175, 144, 11, 67, 10, 60, + 5, 67, 89, 32, 77, 69, 29, 6, 84, 69, 32, 85, 83, 69, 2, 241, 132, 7, 2, + 83, 83, 8, 26, 32, 191, 175, 6, 45, 4, 146, 210, 5, 84, 223, 243, 4, 79, + 14, 130, 1, 74, 30, 80, 228, 32, 5, 72, 73, 66, 73, 84, 148, 176, 8, 6, + 66, 73, 78, 71, 32, 67, 133, 210, 1, 5, 83, 69, 82, 80, 73, 2, 181, 144, + 5, 2, 69, 67, 6, 64, 6, 79, 82, 84, 73, 79, 78, 197, 195, 10, 4, 69, 82, + 84, 89, 5, 179, 182, 5, 65, 58, 172, 1, 15, 70, 79, 85, 82, 32, 68, 79, + 84, 83, 32, 87, 73, 84, 72, 32, 32, 7, 76, 69, 84, 84, 69, 82, 32, 230, + 2, 78, 178, 31, 83, 1, 8, 84, 85, 82, 78, 69, 68, 32, 83, 4, 210, 157, + 10, 67, 187, 109, 68, 36, 166, 1, 65, 22, 68, 34, 76, 22, 77, 50, 87, + 238, 150, 4, 71, 90, 90, 34, 83, 66, 89, 154, 193, 1, 72, 234, 5, 75, + 130, 76, 66, 190, 173, 4, 78, 254, 1, 84, 203, 103, 80, 2, 207, 151, 4, + 76, 2, 11, 65, 2, 251, 171, 6, 76, 2, 235, 151, 4, 65, 2, 25, 4, 69, 77, + 45, 81, 2, 195, 223, 5, 79, 2, 37, 7, 65, 87, 45, 65, 89, 73, 78, 2, 141, + 194, 1, 2, 45, 82, 14, 33, 6, 85, 77, 66, 69, 82, 32, 14, 42, 84, 186, + 151, 4, 79, 187, 217, 2, 70, 8, 42, 87, 250, 234, 9, 72, 239, 156, 1, 69, + 4, 182, 237, 9, 69, 131, 234, 1, 79, 18, 252, 1, 4, 78, 67, 84, 85, 106, + 82, 56, 19, 84, 32, 76, 73, 84, 84, 69, 82, 32, 73, 78, 32, 73, 84, 83, + 32, 80, 76, 65, 170, 140, 1, 83, 140, 42, 20, 66, 76, 73, 67, 32, 65, 68, + 68, 82, 69, 83, 83, 32, 76, 79, 85, 68, 83, 80, 69, 194, 157, 10, 49, 3, + 50, 4, 80, 9, 83, 32, 69, 76, 69, 86, 65, 84, 85, 137, 150, 11, 5, 65, + 84, 73, 79, 78, 2, 135, 147, 11, 83, 4, 32, 2, 80, 76, 183, 189, 11, 83, + 2, 227, 204, 10, 69, 2, 11, 67, 2, 215, 192, 10, 69, 40, 98, 65, 148, 6, + 6, 69, 83, 84, 73, 79, 78, 214, 231, 5, 79, 253, 216, 4, 5, 73, 78, 67, + 85, 78, 30, 104, 2, 68, 82, 208, 4, 9, 84, 69, 82, 78, 73, 79, 78, 32, + 73, 48, 4, 82, 84, 69, 82, 223, 170, 10, 79, 24, 56, 4, 65, 78, 84, 32, + 253, 3, 5, 85, 80, 76, 69, 32, 20, 44, 6, 85, 80, 80, 69, 82, 32, 131, 2, + 76, 16, 56, 4, 76, 69, 70, 84, 249, 1, 5, 82, 73, 71, 72, 84, 11, 29, 5, + 32, 65, 78, 68, 32, 8, 108, 6, 76, 79, 87, 69, 82, 32, 53, 17, 85, 80, + 80, 69, 82, 32, 82, 73, 71, 72, 84, 32, 65, 78, 68, 32, 76, 4, 184, 1, 5, + 76, 69, 70, 84, 32, 195, 163, 11, 82, 4, 11, 79, 4, 11, 87, 4, 241, 163, + 11, 2, 69, 82, 7, 69, 15, 32, 65, 78, 68, 32, 76, 79, 87, 69, 82, 32, 76, + 69, 70, 84, 5, 11, 32, 2, 21, 3, 65, 78, 68, 2, 229, 255, 9, 6, 32, 76, + 79, 87, 69, 82, 4, 22, 73, 155, 37, 80, 2, 133, 163, 8, 7, 78, 84, 69, + 71, 82, 65, 76, 2, 17, 2, 32, 78, 2, 195, 136, 10, 79, 6, 34, 32, 185, + 165, 5, 2, 69, 68, 4, 198, 244, 4, 69, 211, 150, 6, 77, 152, 9, 114, 65, + 182, 7, 69, 224, 27, 6, 72, 73, 78, 79, 67, 69, 34, 73, 182, 78, 76, 46, + 79, 246, 18, 85, 151, 198, 10, 83, 60, 110, 67, 104, 2, 68, 73, 130, 1, + 73, 202, 4, 84, 160, 210, 7, 4, 66, 66, 73, 84, 130, 185, 3, 90, 223, 56, + 77, 6, 40, 4, 73, 78, 71, 32, 211, 184, 8, 67, 4, 140, 251, 9, 7, 77, 79, + 84, 79, 82, 67, 89, 203, 44, 67, 8, 66, 79, 245, 255, 7, 10, 67, 65, 76, + 32, 83, 89, 77, 66, 79, 76, 7, 200, 145, 6, 4, 65, 67, 84, 73, 197, 133, + 4, 2, 32, 66, 34, 60, 5, 76, 87, 65, 89, 32, 46, 78, 21, 4, 83, 69, 68, + 32, 4, 228, 189, 8, 2, 84, 82, 247, 231, 1, 67, 5, 203, 173, 10, 66, 26, + 156, 1, 3, 68, 79, 84, 34, 73, 48, 4, 72, 65, 78, 68, 182, 1, 77, 198, + 139, 7, 70, 186, 237, 1, 67, 226, 170, 1, 83, 197, 18, 7, 66, 65, 67, 75, + 32, 79, 70, 5, 29, 5, 84, 69, 68, 32, 73, 2, 165, 39, 8, 78, 84, 69, 82, + 80, 79, 76, 65, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 130, 27, 70, 201, + 176, 2, 28, 80, 65, 82, 84, 32, 66, 69, 84, 87, 69, 69, 78, 32, 77, 73, + 68, 68, 76, 69, 32, 65, 78, 68, 32, 82, 73, 78, 71, 6, 182, 189, 10, 67, + 2, 68, 3, 82, 5, 135, 165, 11, 73, 248, 1, 226, 1, 67, 232, 3, 2, 68, 32, + 64, 2, 71, 73, 144, 1, 5, 74, 65, 78, 71, 32, 254, 4, 76, 32, 8, 77, 73, + 78, 68, 69, 82, 32, 82, 34, 80, 106, 83, 136, 1, 5, 84, 85, 82, 78, 32, + 42, 86, 225, 184, 1, 5, 70, 69, 82, 69, 78, 24, 114, 69, 32, 3, 89, 67, + 76, 158, 176, 5, 79, 181, 237, 3, 13, 82, 69, 65, 84, 73, 79, 78, 65, 76, + 32, 86, 69, 72, 2, 11, 73, 2, 211, 164, 11, 80, 18, 78, 69, 53, 15, 73, + 78, 71, 32, 83, 89, 77, 66, 79, 76, 32, 70, 79, 82, 32, 2, 29, 5, 68, 32, + 80, 65, 80, 2, 239, 223, 9, 69, 16, 100, 5, 84, 89, 80, 69, 45, 157, 237, + 4, 14, 71, 69, 78, 69, 82, 73, 67, 32, 77, 65, 84, 69, 82, 73, 14, 58, + 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 2, 229, 177, 5, 6, 32, 80, + 76, 65, 83, 84, 4, 42, 65, 229, 233, 4, 4, 71, 73, 70, 84, 2, 143, 173, + 3, 80, 54, 120, 4, 83, 84, 69, 82, 165, 212, 5, 20, 79, 78, 65, 76, 32, + 73, 78, 68, 73, 67, 65, 84, 79, 82, 32, 83, 89, 77, 66, 79, 2, 135, 215, + 9, 69, 74, 128, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, + 71, 78, 32, 44, 7, 76, 69, 84, 84, 69, 82, 32, 150, 2, 83, 35, 86, 8, + 174, 195, 9, 78, 150, 248, 1, 72, 3, 82, 46, 154, 1, 77, 34, 78, 166, + 183, 11, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, 80, 2, + 82, 2, 83, 2, 84, 2, 87, 2, 89, 187, 2, 65, 4, 194, 183, 11, 66, 187, 2, + 65, 12, 54, 89, 158, 234, 7, 71, 210, 204, 3, 68, 187, 2, 65, 4, 234, + 182, 11, 74, 187, 2, 65, 2, 11, 69, 2, 223, 207, 10, 67, 18, 64, 10, 79, + 87, 69, 76, 32, 83, 73, 71, 78, 32, 171, 134, 9, 73, 16, 54, 69, 190, + 247, 10, 65, 174, 64, 73, 2, 79, 3, 85, 7, 230, 183, 11, 65, 3, 85, 2, + 137, 167, 10, 3, 73, 69, 86, 2, 201, 231, 10, 3, 73, 66, 66, 2, 41, 8, + 76, 65, 67, 69, 77, 69, 78, 84, 2, 17, 2, 32, 67, 2, 253, 255, 9, 5, 72, + 65, 82, 65, 67, 8, 32, 2, 84, 82, 187, 217, 6, 80, 6, 168, 134, 6, 16, + 73, 67, 84, 69, 68, 32, 76, 69, 70, 84, 32, 69, 78, 84, 82, 89, 243, 158, + 5, 79, 6, 162, 162, 10, 83, 142, 104, 76, 31, 82, 70, 64, 4, 69, 82, 83, + 69, 173, 228, 3, 6, 79, 76, 86, 73, 78, 71, 68, 30, 32, 169, 3, 2, 68, + 32, 20, 184, 1, 6, 67, 72, 69, 67, 75, 69, 28, 2, 76, 73, 108, 7, 83, 79, + 76, 73, 68, 85, 83, 196, 193, 7, 16, 84, 73, 76, 68, 69, 32, 79, 80, 69, + 82, 65, 84, 79, 82, 32, 65, 147, 203, 2, 73, 2, 221, 155, 10, 2, 82, 32, + 4, 136, 194, 3, 18, 71, 72, 84, 32, 70, 79, 85, 82, 32, 80, 79, 73, 78, + 84, 69, 68, 32, 80, 239, 221, 1, 78, 9, 11, 32, 6, 200, 135, 5, 9, 80, + 82, 69, 67, 69, 68, 73, 78, 71, 226, 255, 2, 79, 167, 140, 1, 87, 48, + 232, 2, 5, 65, 78, 71, 76, 69, 20, 7, 68, 79, 85, 66, 76, 69, 32, 118, + 78, 20, 5, 70, 79, 82, 75, 69, 70, 80, 82, 82, 214, 1, 83, 102, 84, 212, + 201, 6, 30, 72, 65, 78, 68, 32, 87, 73, 84, 72, 32, 77, 73, 68, 68, 76, + 69, 32, 70, 73, 78, 71, 69, 82, 32, 69, 88, 84, 69, 78, 68, 158, 148, 2, + 67, 114, 81, 212, 61, 3, 86, 73, 67, 157, 36, 6, 69, 77, 80, 84, 89, 32, + 5, 159, 213, 3, 32, 6, 40, 3, 80, 82, 73, 41, 3, 83, 84, 82, 4, 17, 2, + 77, 69, 5, 195, 166, 3, 32, 2, 29, 5, 79, 75, 69, 32, 78, 2, 147, 150, 6, + 79, 2, 49, 10, 68, 32, 80, 65, 82, 65, 71, 82, 65, 80, 2, 175, 4, 72, 4, + 36, 3, 73, 76, 67, 151, 148, 10, 82, 2, 11, 82, 2, 253, 164, 10, 2, 79, + 87, 6, 156, 1, 17, 65, 73, 83, 69, 68, 32, 72, 65, 78, 68, 32, 87, 73, + 84, 72, 32, 70, 252, 96, 8, 79, 84, 65, 84, 69, 68, 32, 70, 229, 149, 6, + 4, 73, 71, 72, 84, 2, 185, 102, 9, 73, 78, 71, 69, 82, 83, 32, 83, 80, 4, + 132, 124, 17, 65, 78, 83, 45, 83, 69, 82, 73, 70, 32, 67, 65, 80, 73, 84, + 65, 76, 151, 248, 6, 69, 10, 88, 4, 73, 76, 68, 69, 28, 7, 82, 73, 80, + 76, 69, 32, 80, 173, 251, 6, 3, 72, 85, 77, 5, 189, 214, 4, 2, 32, 69, 2, + 187, 144, 10, 82, 2, 11, 82, 2, 171, 234, 10, 79, 213, 3, 228, 1, 4, 66, + 66, 79, 78, 164, 1, 3, 67, 69, 32, 60, 3, 71, 72, 84, 236, 71, 2, 78, 71, + 252, 1, 23, 83, 73, 78, 71, 32, 68, 73, 65, 71, 79, 78, 65, 76, 32, 67, + 82, 79, 83, 83, 73, 78, 71, 32, 134, 195, 5, 65, 143, 246, 3, 70, 19, 37, + 7, 32, 65, 82, 82, 79, 87, 32, 16, 80, 3, 76, 69, 70, 0, 4, 82, 73, 71, + 72, 22, 85, 213, 249, 10, 3, 68, 79, 87, 4, 175, 234, 1, 84, 4, 223, 249, + 10, 80, 4, 26, 67, 131, 160, 9, 66, 2, 133, 135, 1, 3, 82, 65, 67, 162, + 3, 110, 32, 158, 31, 45, 132, 8, 11, 72, 65, 78, 68, 32, 73, 78, 84, 69, + 82, 73, 29, 6, 87, 65, 82, 68, 83, 32, 176, 1, 198, 1, 65, 132, 6, 2, 66, + 76, 62, 67, 184, 1, 2, 68, 79, 242, 1, 70, 60, 2, 72, 65, 212, 2, 2, 76, + 79, 66, 78, 82, 79, 122, 80, 168, 1, 2, 82, 65, 58, 83, 154, 6, 84, 194, + 3, 86, 143, 1, 87, 28, 22, 78, 163, 4, 82, 22, 24, 2, 68, 32, 39, 71, 4, + 214, 41, 76, 21, 3, 85, 80, 80, 18, 26, 69, 17, 2, 76, 69, 2, 175, 23, + 82, 17, 11, 32, 14, 154, 1, 66, 44, 8, 68, 79, 84, 84, 69, 68, 32, 83, 2, + 83, 112, 5, 87, 73, 84, 72, 32, 189, 253, 9, 12, 86, 65, 82, 73, 65, 78, + 84, 32, 87, 73, 84, 72, 4, 133, 252, 9, 6, 82, 65, 67, 75, 69, 84, 2, 37, + 7, 85, 66, 83, 84, 73, 84, 85, 2, 25, 4, 84, 73, 79, 78, 2, 21, 3, 32, + 77, 65, 2, 243, 128, 1, 82, 4, 68, 11, 68, 79, 87, 78, 87, 65, 82, 68, + 83, 32, 90, 203, 171, 8, 65, 2, 141, 131, 10, 5, 73, 71, 90, 65, 71, 6, + 18, 67, 79, 82, 2, 41, 8, 32, 71, 82, 69, 65, 84, 69, 82, 2, 189, 20, 4, + 45, 84, 72, 65, 4, 41, 8, 79, 87, 32, 87, 73, 84, 72, 32, 4, 132, 191, 7, + 7, 67, 73, 82, 67, 76, 69, 68, 207, 141, 2, 83, 4, 25, 4, 65, 67, 75, 32, + 4, 194, 22, 76, 243, 172, 7, 84, 12, 38, 85, 230, 21, 79, 251, 222, 2, + 69, 8, 53, 11, 82, 76, 89, 32, 66, 82, 65, 67, 75, 69, 84, 9, 11, 32, 6, + 44, 4, 77, 73, 68, 68, 138, 8, 76, 23, 85, 2, 129, 229, 9, 2, 76, 69, 12, + 38, 84, 41, 5, 85, 66, 76, 69, 32, 2, 173, 14, 6, 84, 69, 68, 32, 83, 85, + 10, 50, 65, 94, 87, 174, 145, 3, 81, 151, 172, 4, 80, 4, 206, 25, 78, + 217, 149, 3, 15, 82, 82, 79, 87, 32, 87, 73, 84, 72, 32, 82, 79, 85, 78, + 68, 2, 203, 19, 73, 6, 26, 73, 227, 241, 2, 76, 4, 146, 146, 8, 86, 163, + 88, 83, 14, 32, 3, 76, 70, 32, 223, 1, 78, 12, 42, 66, 90, 70, 34, 82, + 139, 166, 8, 77, 6, 11, 76, 6, 40, 4, 65, 67, 75, 32, 231, 231, 9, 79, 4, + 166, 199, 9, 67, 167, 11, 83, 2, 11, 79, 2, 147, 242, 8, 76, 2, 33, 6, + 85, 78, 78, 73, 78, 71, 2, 131, 204, 6, 32, 2, 149, 145, 1, 16, 68, 32, + 84, 69, 76, 69, 80, 72, 79, 78, 69, 32, 82, 69, 67, 69, 2, 241, 193, 10, + 11, 87, 32, 80, 65, 82, 65, 80, 72, 82, 65, 83, 2, 197, 4, 16, 79, 82, + 77, 65, 76, 32, 70, 65, 67, 84, 79, 82, 32, 83, 69, 77, 8, 74, 85, 214, + 150, 8, 78, 237, 178, 1, 8, 80, 69, 78, 32, 83, 81, 85, 65, 2, 201, 147, + 10, 6, 84, 69, 82, 32, 74, 79, 8, 49, 10, 65, 82, 69, 78, 84, 72, 69, 83, + 73, 83, 9, 11, 32, 6, 34, 76, 22, 85, 147, 248, 8, 69, 2, 37, 2, 79, 87, + 2, 17, 2, 80, 80, 2, 169, 223, 3, 2, 69, 82, 2, 249, 8, 10, 73, 83, 69, + 68, 32, 79, 77, 73, 83, 83, 40, 62, 45, 70, 69, 78, 73, 68, 2, 80, 69, + 126, 81, 227, 2, 85, 2, 153, 208, 7, 12, 83, 72, 65, 80, 69, 68, 32, 66, + 65, 71, 32, 68, 4, 26, 77, 199, 160, 8, 86, 2, 205, 128, 10, 7, 73, 68, + 73, 82, 69, 67, 84, 4, 134, 136, 3, 78, 193, 180, 7, 8, 68, 69, 87, 65, + 89, 83, 32, 85, 8, 32, 4, 65, 75, 69, 82, 67, 69, 7, 33, 6, 32, 87, 73, + 84, 72, 32, 4, 186, 237, 3, 79, 75, 84, 2, 201, 4, 2, 67, 72, 20, 57, 12, + 85, 65, 82, 69, 32, 66, 82, 65, 67, 75, 69, 84, 21, 11, 32, 18, 84, 3, + 76, 79, 87, 0, 3, 85, 80, 80, 28, 5, 87, 73, 84, 72, 32, 223, 242, 8, 69, + 2, 133, 216, 3, 2, 69, 82, 12, 96, 8, 84, 73, 67, 75, 32, 73, 78, 32, + 162, 5, 81, 214, 189, 7, 85, 158, 97, 68, 195, 183, 2, 83, 4, 132, 215, + 3, 6, 66, 79, 84, 84, 79, 77, 1, 3, 84, 79, 80, 2, 197, 2, 6, 66, 83, 84, + 73, 84, 85, 20, 54, 72, 162, 1, 82, 146, 177, 7, 79, 179, 169, 2, 65, 8, + 54, 73, 60, 5, 79, 85, 71, 72, 84, 131, 155, 8, 82, 2, 201, 197, 1, 10, + 82, 68, 32, 87, 72, 73, 84, 69, 32, 82, 2, 11, 32, 2, 205, 250, 2, 3, 66, + 85, 66, 8, 34, 65, 89, 4, 73, 65, 78, 71, 2, 33, 6, 78, 83, 80, 79, 83, + 73, 2, 11, 84, 2, 17, 2, 73, 79, 2, 191, 181, 10, 78, 6, 32, 2, 76, 69, + 183, 154, 8, 85, 5, 41, 8, 32, 65, 66, 79, 86, 69, 32, 76, 2, 161, 232, + 8, 2, 69, 70, 4, 45, 9, 69, 82, 84, 73, 67, 65, 76, 32, 66, 4, 68, 9, 65, + 82, 32, 87, 73, 84, 72, 32, 81, 245, 236, 9, 2, 79, 88, 2, 215, 149, 8, + 85, 14, 22, 72, 203, 1, 73, 12, 25, 4, 73, 84, 69, 32, 12, 54, 67, 54, + 76, 182, 170, 7, 80, 154, 2, 83, 39, 84, 4, 26, 79, 215, 168, 7, 85, 2, + 65, 3, 82, 78, 69, 2, 41, 8, 69, 78, 84, 73, 67, 85, 76, 65, 2, 231, 177, + 10, 82, 2, 221, 167, 6, 6, 71, 71, 76, 89, 32, 70, 30, 82, 70, 206, 1, + 72, 130, 1, 80, 250, 1, 83, 197, 1, 6, 84, 79, 45, 76, 69, 70, 8, 33, 6, + 65, 67, 73, 78, 71, 32, 8, 144, 1, 14, 65, 82, 77, 69, 78, 73, 65, 78, + 32, 69, 84, 69, 82, 78, 144, 196, 3, 11, 83, 86, 65, 83, 84, 73, 32, 83, + 73, 71, 78, 151, 133, 3, 70, 2, 239, 227, 7, 73, 2, 81, 18, 65, 78, 68, + 69, 68, 32, 73, 78, 84, 69, 82, 76, 65, 67, 69, 68, 32, 80, 2, 21, 3, 69, + 78, 84, 2, 171, 199, 9, 65, 8, 41, 8, 79, 73, 78, 84, 73, 78, 71, 32, 8, + 140, 1, 6, 67, 85, 82, 86, 69, 68, 22, 65, 224, 247, 2, 6, 68, 79, 85, + 66, 76, 69, 253, 239, 6, 10, 77, 65, 71, 78, 73, 70, 89, 73, 78, 71, 2, + 17, 2, 32, 65, 2, 11, 78, 2, 157, 172, 10, 2, 71, 76, 4, 46, 72, 85, 7, + 73, 68, 69, 32, 65, 82, 67, 2, 17, 2, 65, 68, 2, 17, 2, 69, 68, 2, 165, + 222, 9, 6, 32, 87, 72, 73, 84, 69, 2, 11, 32, 2, 193, 168, 8, 8, 67, 76, + 79, 67, 75, 87, 73, 83, 8, 17, 2, 84, 32, 8, 86, 73, 40, 4, 79, 86, 69, + 82, 196, 238, 4, 5, 69, 77, 66, 69, 68, 187, 204, 5, 77, 2, 17, 2, 83, + 79, 2, 207, 129, 1, 76, 2, 179, 146, 3, 82, 2, 249, 236, 9, 2, 79, 82, + 210, 1, 160, 1, 5, 65, 82, 82, 79, 87, 182, 8, 66, 86, 68, 210, 1, 70, + 122, 72, 230, 6, 76, 26, 79, 34, 80, 50, 82, 70, 83, 94, 84, 202, 8, 87, + 226, 254, 7, 67, 47, 81, 71, 26, 32, 159, 205, 8, 45, 66, 94, 65, 170, 2, + 70, 82, 84, 184, 1, 5, 87, 73, 84, 72, 32, 149, 152, 1, 4, 79, 86, 69, + 82, 12, 40, 5, 66, 79, 86, 69, 32, 143, 1, 78, 10, 70, 82, 208, 155, 1, + 5, 83, 72, 79, 82, 84, 250, 180, 3, 65, 55, 84, 4, 37, 7, 69, 86, 69, 82, + 83, 69, 32, 4, 158, 208, 4, 65, 55, 84, 2, 61, 13, 68, 32, 85, 80, 80, + 69, 82, 32, 65, 78, 68, 32, 76, 2, 17, 2, 79, 87, 2, 137, 142, 8, 2, 69, + 82, 4, 37, 7, 82, 79, 77, 32, 66, 65, 82, 5, 189, 1, 6, 32, 84, 79, 32, + 66, 76, 10, 56, 7, 72, 82, 79, 85, 71, 72, 32, 65, 3, 79, 32, 66, 6, 144, + 203, 4, 3, 83, 85, 80, 130, 156, 4, 71, 131, 143, 2, 88, 4, 26, 76, 235, + 188, 10, 65, 2, 213, 171, 9, 3, 65, 67, 75, 38, 140, 1, 6, 67, 79, 82, + 78, 69, 82, 26, 68, 98, 76, 38, 80, 30, 83, 38, 84, 210, 139, 8, 77, 38, + 78, 122, 69, 226, 148, 1, 72, 155, 160, 1, 86, 2, 213, 18, 2, 32, 68, 4, + 11, 79, 4, 40, 4, 84, 84, 69, 68, 203, 177, 7, 85, 2, 17, 2, 32, 83, 2, + 247, 224, 10, 84, 4, 150, 140, 8, 65, 247, 237, 1, 79, 2, 249, 203, 8, 2, + 76, 85, 6, 218, 140, 8, 77, 135, 182, 2, 84, 10, 206, 16, 73, 171, 3, 65, + 8, 58, 65, 128, 12, 5, 79, 84, 84, 79, 77, 219, 128, 8, 76, 2, 145, 2, 2, + 67, 75, 14, 48, 6, 79, 85, 66, 76, 69, 32, 235, 154, 8, 65, 12, 40, 5, + 65, 82, 82, 79, 87, 135, 19, 68, 11, 26, 32, 183, 195, 8, 45, 6, 26, 87, + 243, 144, 8, 70, 4, 25, 4, 73, 84, 72, 32, 4, 190, 191, 10, 86, 79, 83, + 4, 40, 4, 82, 79, 78, 84, 143, 140, 8, 73, 2, 141, 139, 8, 14, 45, 84, + 73, 76, 84, 69, 68, 32, 83, 72, 65, 68, 79, 87, 30, 26, 65, 195, 143, 8, + 69, 26, 48, 6, 82, 80, 79, 79, 78, 32, 147, 168, 10, 78, 24, 88, 8, 79, + 86, 69, 82, 32, 76, 69, 70, 45, 10, 87, 73, 84, 72, 32, 66, 65, 82, 66, + 32, 2, 237, 219, 7, 6, 84, 87, 65, 82, 68, 83, 22, 44, 4, 68, 79, 87, 78, + 173, 1, 2, 85, 80, 10, 26, 32, 247, 148, 8, 87, 8, 76, 8, 65, 66, 79, 86, + 69, 32, 76, 69, 18, 66, 190, 140, 8, 70, 175, 5, 84, 2, 227, 2, 70, 2, + 185, 201, 4, 7, 69, 76, 79, 87, 32, 76, 79, 12, 26, 32, 203, 147, 8, 87, + 10, 60, 6, 65, 66, 79, 86, 69, 32, 178, 139, 8, 70, 175, 5, 84, 6, 22, + 76, 155, 1, 82, 4, 32, 2, 69, 70, 247, 199, 4, 79, 2, 233, 135, 2, 24, + 84, 87, 65, 82, 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, + 72, 32, 66, 65, 82, 66, 2, 21, 3, 73, 71, 72, 2, 105, 24, 84, 87, 65, 82, + 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, 72, 32, 66, 65, + 82, 66, 2, 11, 32, 2, 163, 232, 1, 68, 2, 141, 1, 2, 69, 70, 2, 221, 141, + 8, 3, 80, 69, 78, 4, 218, 145, 8, 65, 221, 199, 1, 3, 85, 83, 72, 4, 36, + 3, 73, 71, 72, 187, 148, 10, 79, 2, 11, 84, 2, 171, 1, 45, 6, 32, 2, 81, + 85, 235, 136, 8, 65, 4, 26, 73, 131, 137, 8, 65, 2, 245, 144, 8, 2, 71, + 71, 54, 38, 79, 60, 2, 82, 73, 227, 4, 87, 2, 11, 80, 2, 11, 32, 2, 149, + 129, 8, 4, 83, 72, 65, 68, 34, 40, 5, 65, 78, 71, 76, 69, 255, 3, 80, 30, + 56, 8, 45, 72, 69, 65, 68, 69, 68, 32, 251, 149, 8, 32, 28, 52, 5, 65, + 82, 82, 79, 87, 218, 141, 8, 68, 39, 80, 25, 11, 32, 22, 64, 8, 79, 86, + 69, 82, 32, 76, 69, 70, 22, 87, 155, 137, 8, 84, 2, 203, 136, 8, 84, 18, + 25, 4, 73, 84, 72, 32, 18, 128, 1, 7, 68, 79, 85, 66, 76, 69, 32, 36, 7, + 76, 79, 78, 71, 32, 84, 73, 246, 136, 8, 66, 158, 1, 77, 34, 78, 34, 86, + 35, 72, 4, 186, 196, 8, 72, 255, 236, 1, 86, 4, 11, 80, 4, 11, 32, 4, 18, + 68, 35, 85, 2, 197, 137, 8, 3, 79, 87, 78, 2, 167, 137, 8, 80, 4, 21, 3, + 76, 69, 32, 4, 138, 3, 68, 183, 195, 9, 65, 18, 11, 79, 18, 56, 8, 45, + 72, 69, 65, 68, 69, 68, 32, 191, 139, 8, 32, 16, 76, 6, 65, 82, 82, 79, + 87, 32, 213, 1, 8, 84, 82, 73, 80, 76, 69, 32, 68, 14, 44, 5, 87, 73, 84, + 72, 32, 203, 255, 7, 70, 12, 42, 84, 206, 156, 7, 68, 191, 145, 3, 86, 8, + 26, 65, 131, 139, 8, 82, 6, 17, 2, 73, 76, 7, 33, 6, 32, 87, 73, 84, 72, + 32, 4, 246, 155, 7, 68, 191, 145, 3, 86, 2, 153, 127, 2, 65, 83, 8, 58, + 65, 21, 10, 72, 73, 84, 69, 32, 65, 82, 82, 79, 87, 2, 227, 135, 8, 86, + 7, 11, 32, 4, 164, 185, 2, 4, 70, 82, 79, 77, 147, 212, 5, 87, 19, 66, + 32, 136, 1, 6, 69, 68, 32, 80, 76, 65, 21, 3, 73, 78, 71, 12, 82, 66, 22, + 80, 132, 180, 4, 2, 73, 78, 26, 69, 214, 252, 2, 79, 187, 173, 2, 65, 2, + 195, 201, 10, 85, 2, 11, 79, 2, 231, 151, 10, 73, 2, 215, 165, 10, 78, 2, + 189, 190, 3, 2, 32, 66, 4, 24, 2, 70, 65, 75, 83, 2, 17, 2, 76, 76, 2, + 21, 3, 73, 78, 71, 2, 205, 222, 1, 2, 32, 68, 2, 225, 164, 3, 2, 79, 85, + 8, 178, 217, 10, 69, 2, 73, 2, 77, 3, 79, 124, 136, 2, 2, 67, 75, 20, 2, + 76, 76, 134, 2, 79, 56, 4, 77, 65, 78, 32, 192, 8, 2, 83, 69, 20, 6, 84, + 65, 84, 69, 68, 32, 152, 3, 3, 85, 78, 68, 230, 169, 3, 87, 228, 189, 3, + 15, 65, 83, 84, 69, 68, 32, 83, 87, 69, 69, 84, 32, 80, 79, 84, 165, 253, + 1, 2, 66, 79, 5, 207, 186, 10, 69, 10, 130, 1, 69, 64, 4, 32, 79, 70, 32, + 101, 21, 73, 78, 71, 32, 79, 78, 32, 84, 72, 69, 32, 70, 76, 79, 79, 82, + 32, 76, 65, 85, 71, 6, 60, 9, 68, 45, 85, 80, 32, 78, 69, 87, 83, 33, 2, + 82, 32, 2, 11, 80, 2, 207, 250, 1, 65, 4, 28, 3, 67, 79, 65, 23, 83, 2, + 151, 158, 9, 83, 2, 239, 89, 75, 2, 199, 131, 10, 72, 72, 140, 1, 6, 67, + 69, 78, 84, 85, 82, 22, 68, 100, 3, 81, 85, 73, 28, 8, 78, 85, 77, 69, + 82, 65, 76, 32, 182, 4, 83, 114, 85, 159, 179, 7, 65, 2, 223, 187, 5, 73, + 6, 98, 69, 232, 5, 5, 85, 80, 79, 78, 68, 61, 12, 73, 77, 73, 68, 73, 65, + 32, 83, 69, 88, 84, 85, 2, 229, 5, 3, 78, 65, 82, 48, 142, 1, 70, 136, 1, + 3, 79, 78, 69, 134, 1, 83, 66, 84, 152, 14, 10, 82, 69, 86, 69, 82, 83, + 69, 68, 32, 79, 142, 229, 2, 69, 235, 193, 6, 78, 14, 26, 73, 155, 216, + 9, 79, 12, 36, 3, 70, 84, 89, 167, 246, 2, 86, 7, 11, 32, 4, 158, 168, 5, + 84, 185, 169, 4, 5, 69, 65, 82, 76, 89, 11, 11, 32, 8, 50, 72, 41, 8, 84, + 72, 79, 85, 83, 65, 78, 68, 4, 185, 1, 6, 85, 78, 68, 82, 69, 68, 5, 205, + 245, 3, 2, 32, 67, 6, 32, 2, 73, 88, 223, 225, 8, 69, 5, 221, 207, 9, 2, + 32, 76, 10, 42, 69, 190, 244, 2, 87, 135, 237, 5, 72, 4, 11, 78, 5, 11, + 32, 2, 223, 165, 5, 84, 10, 46, 69, 197, 145, 7, 5, 73, 76, 73, 81, 85, + 8, 60, 2, 77, 85, 40, 5, 83, 84, 69, 82, 84, 21, 2, 88, 84, 2, 17, 2, 78, + 67, 2, 239, 144, 7, 73, 2, 231, 178, 7, 73, 4, 18, 65, 23, 85, 2, 203, + 178, 7, 78, 2, 159, 144, 7, 76, 5, 191, 135, 9, 84, 10, 166, 2, 70, 32, + 11, 72, 69, 65, 86, 89, 32, 66, 76, 65, 67, 75, 52, 24, 76, 73, 71, 72, + 84, 32, 70, 79, 85, 82, 32, 80, 79, 73, 78, 84, 69, 68, 32, 66, 76, 65, + 67, 75, 0, 18, 87, 72, 73, 84, 69, 32, 70, 79, 85, 82, 32, 80, 79, 73, + 78, 84, 69, 68, 169, 53, 8, 67, 65, 80, 73, 84, 65, 76, 32, 2, 29, 5, 76, + 79, 82, 65, 76, 2, 217, 236, 8, 8, 32, 72, 69, 65, 82, 84, 32, 66, 2, + 225, 132, 9, 2, 32, 67, 16, 74, 32, 89, 14, 69, 68, 32, 83, 89, 77, 66, + 79, 76, 32, 70, 79, 82, 32, 4, 24, 2, 80, 85, 43, 84, 2, 11, 83, 2, 141, + 200, 9, 2, 72, 80, 2, 175, 210, 3, 65, 12, 68, 2, 83, 72, 242, 135, 6, + 67, 254, 153, 4, 70, 2, 76, 147, 17, 88, 4, 40, 4, 85, 65, 78, 71, 195, + 161, 10, 79, 2, 207, 178, 10, 88, 136, 2, 226, 1, 66, 20, 3, 71, 66, 89, + 40, 5, 76, 69, 45, 68, 69, 40, 3, 77, 73, 32, 154, 5, 78, 156, 26, 26, + 83, 83, 73, 65, 78, 32, 65, 83, 84, 82, 79, 76, 79, 71, 73, 67, 65, 76, + 32, 83, 89, 77, 66, 79, 76, 32, 247, 252, 4, 80, 2, 211, 172, 8, 76, 2, + 205, 191, 8, 5, 32, 70, 79, 79, 84, 2, 11, 76, 2, 161, 228, 5, 2, 65, 89, + 62, 68, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 102, 78, 195, 190, 2, 68, + 8, 40, 4, 79, 78, 69, 32, 203, 229, 8, 84, 6, 34, 84, 150, 194, 8, 72, + 43, 81, 2, 191, 195, 8, 72, 36, 33, 6, 85, 77, 66, 69, 82, 32, 36, 76, 5, + 69, 73, 71, 72, 84, 38, 70, 92, 2, 78, 73, 22, 79, 18, 83, 83, 84, 4, + 158, 129, 3, 32, 139, 192, 7, 89, 8, 18, 73, 35, 79, 4, 130, 2, 86, 251, + 212, 8, 70, 4, 136, 2, 2, 85, 82, 211, 212, 8, 82, 4, 77, 2, 78, 69, 2, + 167, 1, 78, 8, 40, 4, 69, 86, 69, 78, 1, 2, 73, 88, 4, 206, 255, 2, 32, + 195, 174, 7, 84, 10, 34, 72, 50, 87, 143, 239, 9, 69, 4, 32, 2, 82, 69, + 215, 212, 8, 73, 2, 39, 69, 4, 26, 79, 199, 212, 8, 69, 2, 187, 254, 2, + 32, 182, 1, 32, 3, 73, 67, 32, 147, 25, 78, 178, 1, 220, 1, 6, 66, 69, + 76, 71, 84, 72, 20, 4, 67, 82, 79, 83, 20, 7, 76, 69, 84, 84, 69, 82, 32, + 210, 22, 83, 24, 6, 77, 85, 76, 84, 73, 80, 188, 141, 7, 5, 65, 82, 76, + 65, 85, 205, 183, 1, 7, 84, 86, 73, 77, 65, 68, 85, 2, 151, 220, 8, 79, + 2, 167, 143, 7, 83, 166, 1, 202, 4, 65, 110, 67, 98, 68, 126, 69, 82, 70, + 222, 1, 71, 104, 2, 72, 65, 50, 73, 220, 1, 5, 74, 69, 82, 65, 78, 34, + 75, 58, 76, 234, 1, 79, 128, 1, 13, 82, 65, 73, 68, 79, 32, 82, 65, 68, + 32, 82, 69, 73, 34, 83, 176, 2, 16, 66, 69, 82, 75, 65, 78, 65, 78, 32, + 66, 69, 79, 82, 67, 32, 66, 144, 1, 12, 78, 65, 85, 68, 73, 90, 32, 78, + 89, 68, 32, 78, 110, 84, 194, 1, 87, 244, 83, 7, 85, 82, 85, 90, 32, 85, + 82, 208, 187, 2, 10, 77, 65, 78, 78, 65, 90, 32, 77, 65, 78, 184, 60, 13, + 80, 69, 82, 84, 72, 79, 32, 80, 69, 79, 82, 84, 72, 218, 246, 2, 89, 166, + 227, 3, 81, 2, 86, 2, 88, 3, 90, 8, 222, 4, 69, 202, 158, 6, 67, 0, 4, + 78, 83, 85, 90, 249, 135, 3, 9, 76, 71, 73, 90, 32, 69, 79, 76, 72, 11, + 46, 69, 30, 65, 197, 239, 6, 3, 87, 69, 79, 4, 26, 65, 247, 181, 10, 78, + 2, 147, 143, 9, 76, 11, 84, 6, 79, 84, 84, 69, 68, 45, 209, 219, 3, 9, + 65, 71, 65, 90, 32, 68, 65, 69, 71, 6, 134, 181, 10, 76, 2, 78, 3, 80, + 11, 228, 70, 7, 72, 87, 65, 90, 32, 69, 72, 174, 181, 9, 65, 194, 55, 84, + 63, 78, 12, 120, 13, 82, 65, 78, 75, 83, 32, 67, 65, 83, 75, 69, 84, 32, + 233, 253, 6, 11, 69, 72, 85, 32, 70, 69, 79, 72, 32, 70, 69, 10, 46, 65, + 154, 245, 9, 73, 2, 79, 195, 60, 69, 4, 26, 69, 207, 178, 10, 67, 2, 235, + 139, 9, 83, 9, 26, 69, 207, 249, 9, 65, 4, 52, 7, 66, 79, 32, 71, 89, 70, + 85, 231, 177, 10, 82, 2, 143, 177, 10, 32, 4, 236, 8, 2, 69, 71, 13, 4, + 71, 76, 65, 90, 12, 156, 1, 2, 78, 71, 20, 9, 83, 65, 90, 32, 73, 83, 32, + 73, 83, 20, 5, 87, 65, 90, 32, 69, 136, 247, 9, 10, 67, 69, 76, 65, 78, + 68, 73, 67, 45, 89, 3, 79, 5, 131, 185, 6, 87, 2, 231, 239, 9, 83, 2, + 199, 174, 10, 79, 2, 11, 32, 2, 183, 175, 10, 74, 7, 21, 3, 65, 85, 78, + 4, 242, 171, 10, 32, 155, 3, 65, 12, 120, 15, 65, 85, 75, 65, 90, 32, 76, + 65, 71, 85, 32, 76, 79, 71, 82, 21, 11, 79, 78, 71, 45, 66, 82, 65, 78, + 67, 72, 45, 2, 211, 164, 9, 32, 10, 64, 3, 65, 82, 32, 158, 4, 72, 62, + 77, 66, 79, 179, 239, 9, 89, 2, 195, 150, 10, 65, 15, 150, 5, 83, 0, 12, + 84, 72, 65, 76, 65, 78, 32, 69, 84, 72, 69, 76, 224, 167, 10, 4, 80, 69, + 78, 45, 14, 69, 2, 78, 3, 79, 2, 11, 68, 2, 167, 243, 9, 32, 26, 150, 1, + 72, 244, 2, 18, 73, 71, 69, 76, 32, 76, 79, 78, 71, 45, 66, 82, 65, 78, + 67, 72, 45, 83, 228, 212, 6, 5, 79, 87, 73, 76, 79, 195, 139, 2, 84, 21, + 45, 9, 79, 82, 84, 45, 84, 87, 73, 71, 45, 18, 102, 66, 58, 72, 62, 77, + 30, 78, 38, 79, 42, 83, 186, 1, 84, 156, 146, 6, 2, 65, 82, 183, 219, 3, + 89, 2, 33, 6, 74, 65, 82, 75, 65, 78, 2, 235, 238, 8, 32, 2, 25, 4, 65, + 71, 65, 76, 2, 11, 76, 2, 195, 167, 10, 32, 2, 253, 145, 3, 2, 65, 68, 2, + 205, 216, 9, 4, 65, 85, 68, 32, 2, 17, 2, 83, 83, 2, 247, 136, 10, 32, 2, + 11, 79, 2, 215, 212, 6, 76, 4, 116, 15, 72, 85, 82, 73, 83, 65, 90, 32, + 84, 72, 85, 82, 83, 32, 84, 33, 10, 73, 87, 65, 90, 32, 84, 73, 82, 32, + 84, 2, 11, 72, 2, 167, 200, 5, 79, 2, 17, 2, 89, 82, 2, 223, 137, 10, 32, + 5, 41, 8, 85, 78, 74, 79, 32, 87, 89, 78, 2, 11, 78, 2, 175, 167, 9, 32, + 2, 21, 3, 73, 78, 71, 2, 169, 248, 6, 2, 76, 69, 4, 204, 191, 8, 16, 73, + 78, 71, 32, 83, 72, 73, 82, 84, 32, 87, 73, 84, 72, 32, 83, 219, 172, 1, + 69, 12, 120, 3, 66, 73, 78, 2, 78, 28, 2, 81, 85, 0, 3, 86, 73, 71, 134, + 234, 6, 83, 249, 154, 1, 6, 84, 82, 69, 68, 69, 67, 2, 149, 133, 8, 2, + 79, 86, 2, 237, 132, 8, 2, 73, 78, 214, 37, 244, 1, 2, 32, 73, 22, 65, + 238, 25, 67, 138, 5, 69, 146, 7, 72, 186, 33, 73, 186, 233, 1, 75, 154, + 2, 76, 130, 9, 77, 170, 21, 78, 174, 2, 79, 142, 39, 80, 180, 11, 2, 81, + 85, 158, 67, 83, 38, 84, 142, 16, 85, 150, 35, 87, 186, 1, 89, 187, 251, + 4, 71, 2, 131, 253, 8, 78, 196, 2, 140, 2, 5, 70, 69, 84, 89, 32, 36, 4, + 71, 73, 84, 84, 30, 76, 112, 8, 77, 65, 82, 73, 84, 65, 78, 32, 142, 14, + 78, 190, 3, 84, 100, 2, 85, 82, 132, 236, 2, 2, 73, 76, 198, 87, 88, 180, + 209, 5, 15, 75, 69, 32, 66, 79, 84, 84, 76, 69, 32, 65, 78, 68, 32, 67, + 143, 98, 82, 4, 234, 250, 1, 86, 151, 164, 7, 80, 2, 205, 201, 3, 2, 65, + 82, 6, 18, 84, 75, 85, 4, 36, 3, 32, 83, 72, 163, 253, 8, 73, 2, 11, 65, + 2, 211, 223, 9, 75, 2, 151, 149, 9, 84, 122, 184, 1, 7, 76, 69, 84, 84, + 69, 82, 32, 198, 3, 77, 248, 2, 12, 80, 85, 78, 67, 84, 85, 65, 84, 73, + 79, 78, 32, 132, 4, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 155, + 137, 4, 65, 44, 202, 1, 66, 32, 2, 68, 65, 22, 73, 38, 75, 22, 76, 34, + 83, 46, 84, 182, 2, 65, 208, 204, 5, 2, 71, 65, 134, 139, 1, 82, 210, + 237, 1, 90, 190, 78, 77, 172, 1, 2, 81, 85, 118, 78, 218, 6, 89, 235, + 101, 70, 4, 214, 253, 9, 73, 247, 25, 65, 2, 147, 134, 9, 76, 6, 206, + 153, 10, 78, 2, 84, 3, 89, 2, 147, 152, 9, 65, 2, 11, 65, 2, 187, 133, 9, + 66, 4, 152, 7, 3, 73, 78, 71, 171, 202, 8, 72, 6, 178, 151, 9, 65, 238, + 100, 73, 229, 10, 5, 83, 65, 65, 68, 73, 18, 96, 4, 65, 82, 75, 32, 165, + 1, 15, 79, 68, 73, 70, 73, 69, 82, 32, 76, 69, 84, 84, 69, 82, 32, 12, + 82, 68, 40, 2, 73, 78, 90, 69, 242, 2, 78, 173, 249, 7, 5, 79, 67, 67, + 76, 85, 2, 17, 2, 65, 71, 2, 163, 177, 8, 69, 5, 17, 2, 45, 65, 2, 255, + 148, 9, 76, 6, 46, 69, 180, 6, 2, 83, 72, 163, 143, 10, 73, 2, 145, 156, + 9, 11, 80, 69, 78, 84, 72, 69, 84, 73, 67, 32, 89, 28, 130, 1, 65, 154, + 1, 66, 22, 78, 30, 83, 130, 1, 90, 238, 155, 3, 84, 200, 208, 6, 9, 77, + 69, 76, 79, 68, 73, 67, 32, 81, 3, 81, 10, 76, 3, 70, 83, 65, 34, 78, 28, + 2, 84, 77, 145, 238, 9, 4, 82, 75, 65, 65, 2, 11, 65, 2, 179, 147, 10, + 81, 4, 26, 78, 199, 179, 5, 71, 2, 11, 65, 2, 143, 238, 9, 65, 2, 177, + 132, 3, 2, 69, 81, 4, 64, 4, 72, 73, 89, 89, 41, 8, 79, 70, 32, 77, 65, + 83, 72, 70, 2, 17, 2, 65, 65, 2, 167, 162, 8, 76, 2, 139, 254, 8, 65, 4, + 34, 65, 221, 161, 8, 2, 73, 81, 2, 151, 144, 9, 69, 30, 92, 5, 76, 79, + 78, 71, 32, 54, 79, 66, 83, 146, 206, 4, 65, 174, 193, 5, 69, 2, 73, 3, + 85, 10, 130, 207, 4, 65, 174, 193, 5, 69, 2, 73, 3, 85, 7, 41, 8, 86, 69, + 82, 76, 79, 78, 71, 32, 4, 163, 206, 4, 65, 4, 26, 72, 183, 192, 5, 85, + 2, 153, 251, 5, 3, 79, 82, 84, 10, 68, 8, 83, 45, 83, 69, 82, 73, 70, 32, + 145, 236, 9, 3, 68, 87, 73, 8, 44, 6, 72, 69, 65, 86, 89, 32, 139, 2, 73, + 6, 48, 3, 68, 79, 85, 81, 5, 76, 79, 87, 32, 68, 4, 11, 66, 4, 21, 3, 76, + 69, 32, 4, 84, 6, 84, 85, 82, 78, 69, 68, 23, 67, 2, 21, 3, 79, 85, 66, + 2, 17, 2, 76, 69, 2, 17, 2, 32, 67, 2, 33, 6, 79, 77, 77, 65, 32, 81, 2, + 153, 197, 8, 3, 85, 79, 84, 2, 169, 200, 9, 10, 78, 84, 69, 82, 82, 79, + 66, 65, 78, 71, 6, 48, 6, 69, 76, 76, 73, 84, 69, 135, 173, 5, 85, 5, 25, + 4, 32, 65, 78, 84, 2, 251, 232, 6, 69, 166, 1, 52, 7, 65, 83, 72, 84, 82, + 65, 32, 163, 169, 4, 79, 164, 1, 180, 1, 7, 76, 69, 84, 84, 69, 82, 32, + 212, 1, 5, 83, 73, 71, 78, 32, 186, 17, 68, 156, 244, 2, 16, 67, 79, 78, + 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 72, 251, 138, 2, 86, 100, + 150, 160, 6, 65, 38, 68, 46, 84, 46, 86, 186, 24, 85, 158, 144, 1, 79, + 182, 56, 73, 42, 76, 246, 189, 1, 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, + 74, 2, 75, 2, 80, 162, 7, 69, 222, 61, 72, 2, 77, 2, 82, 3, 89, 8, 234, + 160, 6, 67, 190, 161, 3, 65, 239, 1, 86, 52, 66, 65, 32, 4, 72, 79, 79, + 76, 46, 79, 74, 82, 143, 133, 10, 73, 4, 190, 242, 8, 76, 215, 18, 82, 5, + 165, 165, 5, 6, 32, 83, 65, 84, 67, 72, 6, 36, 3, 82, 80, 73, 227, 206, + 8, 79, 4, 214, 181, 9, 79, 135, 18, 85, 36, 66, 69, 72, 4, 73, 80, 84, + 32, 166, 243, 1, 85, 175, 140, 6, 79, 4, 36, 3, 87, 68, 82, 207, 180, 9, + 69, 2, 11, 73, 2, 179, 198, 9, 86, 28, 80, 8, 67, 65, 80, 73, 84, 65, 76, + 32, 86, 76, 81, 6, 83, 77, 65, 76, 76, 32, 18, 170, 131, 10, 66, 2, 69, + 2, 70, 2, 72, 2, 73, 2, 76, 2, 77, 2, 80, 3, 82, 2, 37, 7, 73, 71, 65, + 84, 85, 82, 69, 2, 11, 32, 2, 205, 190, 9, 2, 69, 84, 8, 134, 130, 10, + 69, 2, 71, 2, 76, 3, 79, 64, 250, 1, 65, 30, 67, 74, 69, 36, 5, 71, 77, + 69, 78, 84, 28, 2, 77, 73, 174, 1, 82, 158, 1, 83, 68, 2, 84, 32, 200, + 245, 4, 8, 87, 73, 78, 71, 32, 78, 69, 69, 172, 237, 1, 6, 80, 65, 82, + 65, 84, 69, 178, 122, 88, 202, 99, 68, 149, 159, 1, 2, 76, 70, 4, 222, + 255, 9, 76, 3, 84, 6, 34, 84, 157, 200, 5, 2, 79, 78, 4, 194, 165, 6, 73, + 143, 161, 3, 79, 4, 238, 216, 1, 68, 223, 131, 1, 45, 23, 181, 169, 4, 2, + 69, 68, 6, 128, 77, 28, 68, 73, 82, 69, 67, 84, 32, 80, 82, 79, 68, 85, + 67, 84, 32, 87, 73, 84, 72, 32, 66, 79, 84, 84, 79, 77, 32, 67, 172, 147, + 7, 3, 83, 69, 88, 151, 206, 1, 67, 4, 120, 2, 86, 73, 217, 171, 2, 22, + 73, 79, 85, 83, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 83, 89, 77, + 66, 79, 76, 83, 2, 11, 67, 2, 207, 186, 9, 69, 4, 52, 7, 81, 85, 73, 81, + 85, 65, 68, 155, 198, 8, 65, 2, 91, 82, 4, 64, 10, 84, 82, 65, 78, 83, + 77, 73, 84, 32, 83, 147, 158, 6, 77, 2, 11, 84, 2, 179, 182, 8, 65, 240, + 2, 102, 65, 254, 19, 73, 102, 79, 250, 10, 69, 70, 82, 184, 202, 8, 5, + 85, 70, 70, 76, 69, 143, 143, 1, 89, 176, 2, 164, 1, 12, 68, 79, 87, 69, + 68, 32, 87, 72, 73, 84, 69, 32, 68, 9, 76, 76, 79, 87, 32, 80, 65, 78, + 32, 62, 82, 206, 9, 86, 172, 133, 7, 2, 77, 82, 183, 224, 1, 75, 6, 38, + 76, 134, 169, 8, 67, 167, 11, 83, 2, 249, 185, 8, 2, 65, 84, 2, 17, 2, + 79, 70, 2, 17, 2, 32, 70, 2, 227, 213, 6, 79, 194, 1, 40, 4, 65, 68, 65, + 32, 135, 247, 9, 75, 192, 1, 162, 1, 68, 42, 69, 110, 72, 34, 76, 246, 1, + 83, 208, 2, 6, 86, 79, 87, 69, 76, 32, 226, 175, 4, 65, 196, 213, 1, 7, + 67, 79, 78, 84, 73, 78, 85, 235, 217, 3, 79, 24, 158, 32, 79, 66, 65, + 239, 230, 7, 73, 4, 84, 15, 88, 84, 82, 65, 32, 83, 72, 79, 82, 84, 32, + 86, 79, 87, 69, 163, 187, 8, 75, 2, 163, 179, 9, 76, 2, 189, 196, 9, 3, + 69, 65, 68, 96, 33, 6, 69, 84, 84, 69, 82, 32, 96, 178, 139, 6, 65, 38, + 68, 46, 84, 46, 86, 186, 24, 85, 210, 200, 1, 73, 42, 76, 246, 189, 1, + 78, 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, + 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, 30, 70, 65, 38, 69, 56, 4, 73, 71, + 78, 32, 141, 236, 8, 3, 85, 84, 82, 2, 177, 176, 9, 4, 78, 68, 72, 73, 6, + 132, 202, 2, 5, 67, 84, 73, 79, 78, 231, 142, 4, 80, 20, 102, 73, 182, + 249, 4, 83, 134, 144, 1, 65, 74, 67, 98, 78, 230, 179, 1, 74, 150, 3, 85, + 211, 235, 1, 86, 2, 37, 7, 78, 86, 69, 82, 84, 69, 68, 2, 213, 137, 6, 2, + 32, 67, 30, 60, 6, 77, 79, 68, 73, 70, 73, 21, 5, 83, 73, 71, 78, 32, 2, + 227, 252, 5, 69, 28, 86, 80, 226, 137, 6, 65, 106, 86, 214, 20, 85, 210, + 200, 1, 73, 206, 134, 2, 69, 3, 79, 2, 57, 12, 82, 73, 83, 72, 84, 72, + 65, 77, 65, 84, 82, 65, 2, 167, 215, 9, 32, 98, 72, 3, 69, 68, 32, 21, + 11, 73, 65, 78, 32, 76, 69, 84, 84, 69, 82, 32, 2, 171, 176, 9, 73, 96, + 158, 2, 65, 120, 3, 67, 72, 85, 22, 69, 70, 72, 46, 73, 46, 76, 22, 77, + 38, 79, 94, 80, 18, 82, 22, 83, 38, 84, 64, 2, 87, 79, 36, 2, 89, 69, + 208, 221, 4, 2, 74, 85, 162, 186, 2, 68, 202, 13, 90, 150, 84, 70, 182, + 6, 71, 210, 43, 66, 218, 11, 75, 206, 20, 86, 246, 25, 78, 143, 128, 1, + 85, 16, 82, 82, 198, 177, 9, 73, 222, 25, 68, 162, 8, 71, 2, 87, 198, 21, + 83, 147, 1, 72, 4, 166, 222, 8, 82, 239, 139, 1, 69, 2, 199, 199, 9, 82, + 8, 38, 65, 230, 176, 9, 82, 255, 55, 71, 4, 178, 233, 9, 82, 3, 84, 4, + 216, 241, 7, 2, 65, 45, 211, 166, 1, 85, 6, 150, 153, 9, 65, 130, 57, 67, + 215, 22, 70, 2, 143, 228, 7, 79, 4, 178, 136, 5, 69, 167, 200, 3, 73, 12, + 70, 79, 166, 222, 8, 73, 242, 108, 85, 150, 25, 65, 154, 3, 78, 3, 82, 2, + 235, 208, 9, 90, 2, 163, 13, 69, 2, 243, 196, 8, 79, 4, 230, 198, 8, 85, + 163, 160, 1, 79, 6, 26, 72, 159, 202, 9, 79, 4, 186, 238, 5, 73, 199, + 230, 3, 69, 4, 134, 221, 8, 79, 159, 137, 1, 69, 4, 254, 229, 9, 65, 3, + 87, 10, 78, 69, 222, 214, 3, 70, 192, 121, 6, 78, 84, 79, 32, 83, 72, + 251, 148, 5, 80, 2, 255, 158, 9, 76, 44, 236, 1, 2, 79, 84, 32, 6, 80, + 80, 73, 78, 71, 32, 72, 2, 82, 84, 180, 8, 7, 85, 76, 68, 69, 82, 69, 68, + 208, 240, 1, 24, 67, 75, 69, 68, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, + 32, 69, 88, 80, 76, 79, 68, 73, 78, 71, 199, 171, 7, 87, 2, 145, 208, 7, + 3, 73, 78, 71, 4, 36, 3, 84, 82, 79, 239, 220, 5, 66, 2, 11, 76, 2, 247, + 203, 7, 76, 32, 102, 32, 248, 5, 12, 72, 65, 78, 68, 32, 70, 79, 82, 77, + 65, 84, 32, 206, 149, 6, 67, 255, 197, 3, 83, 20, 154, 2, 66, 92, 11, 83, + 76, 65, 78, 84, 69, 68, 32, 78, 79, 82, 196, 1, 22, 82, 73, 71, 72, 84, + 87, 65, 82, 68, 83, 32, 65, 82, 82, 79, 87, 32, 65, 66, 79, 86, 69, 28, + 7, 85, 80, 32, 84, 65, 67, 75, 128, 1, 4, 76, 69, 70, 84, 133, 160, 2, 9, + 68, 79, 87, 78, 32, 84, 65, 67, 75, 4, 88, 14, 65, 67, 75, 83, 76, 65, + 78, 84, 69, 68, 32, 83, 79, 85, 33, 4, 69, 78, 84, 32, 2, 11, 84, 2, 255, + 195, 8, 72, 2, 213, 37, 37, 65, 82, 82, 79, 87, 32, 80, 79, 73, 78, 84, + 73, 78, 71, 32, 68, 79, 87, 78, 87, 65, 82, 68, 83, 32, 84, 72, 69, 78, + 32, 78, 79, 82, 84, 72, 32, 69, 2, 189, 237, 5, 2, 32, 76, 7, 11, 32, 4, + 76, 13, 65, 66, 79, 86, 69, 32, 83, 72, 79, 82, 84, 32, 68, 191, 131, 2, + 87, 2, 11, 79, 2, 11, 87, 2, 11, 78, 2, 11, 32, 2, 191, 209, 6, 84, 8, + 120, 10, 67, 79, 78, 84, 73, 78, 85, 73, 78, 71, 0, 6, 76, 69, 84, 84, + 69, 82, 44, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 245, 201, 8, 6, 32, 79, + 86, 69, 82, 76, 2, 21, 3, 32, 83, 84, 2, 251, 217, 9, 69, 2, 25, 4, 32, + 79, 80, 69, 2, 167, 205, 8, 78, 4, 26, 73, 215, 216, 9, 85, 2, 155, 217, + 9, 77, 159, 14, 174, 1, 68, 132, 20, 2, 71, 78, 232, 181, 1, 6, 77, 73, + 76, 65, 82, 32, 158, 2, 78, 198, 24, 88, 225, 171, 6, 15, 76, 72, 79, 85, + 69, 84, 84, 69, 32, 79, 70, 32, 74, 65, 80, 200, 1, 64, 5, 68, 72, 65, + 77, 32, 225, 17, 6, 69, 87, 65, 89, 83, 32, 184, 1, 194, 1, 68, 106, 69, + 68, 7, 76, 69, 84, 84, 69, 82, 32, 172, 4, 15, 82, 69, 80, 69, 84, 73, + 84, 73, 79, 78, 32, 77, 65, 82, 75, 50, 83, 165, 8, 11, 86, 79, 87, 69, + 76, 32, 83, 73, 71, 78, 32, 4, 18, 79, 67, 65, 2, 11, 85, 2, 11, 66, 2, + 25, 4, 76, 69, 32, 68, 2, 11, 65, 2, 247, 175, 9, 78, 2, 37, 7, 78, 68, + 32, 79, 70, 32, 84, 2, 129, 138, 9, 2, 69, 88, 102, 210, 1, 65, 98, 84, + 198, 233, 5, 68, 90, 86, 186, 24, 85, 210, 200, 1, 73, 158, 190, 1, 78, + 46, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, 76, 2, + 77, 2, 82, 2, 89, 186, 2, 69, 3, 79, 11, 72, 8, 76, 84, 69, 82, 78, 65, + 84, 69, 134, 210, 9, 65, 2, 73, 3, 85, 2, 155, 173, 9, 32, 14, 134, 1, + 72, 196, 212, 5, 19, 87, 79, 45, 67, 73, 82, 67, 76, 69, 32, 65, 76, 84, + 69, 82, 78, 65, 84, 69, 242, 180, 3, 84, 183, 71, 65, 4, 224, 144, 9, 20, + 82, 69, 69, 45, 67, 73, 82, 67, 76, 69, 32, 65, 76, 84, 69, 82, 78, 65, + 84, 69, 135, 64, 65, 6, 11, 45, 6, 234, 207, 9, 49, 2, 50, 3, 51, 44, 38, + 69, 181, 7, 4, 73, 71, 78, 32, 32, 96, 11, 67, 84, 73, 79, 78, 32, 77, + 65, 82, 75, 32, 177, 6, 8, 80, 65, 82, 65, 84, 79, 82, 32, 28, 80, 11, + 68, 79, 85, 66, 76, 69, 32, 82, 73, 78, 71, 57, 5, 87, 73, 84, 72, 32, 5, + 11, 32, 2, 225, 162, 8, 6, 87, 73, 84, 72, 32, 82, 24, 212, 1, 12, 67, + 73, 82, 67, 76, 69, 83, 32, 65, 78, 68, 32, 116, 5, 81, 85, 65, 68, 82, + 0, 4, 83, 69, 80, 84, 12, 16, 82, 65, 89, 83, 32, 65, 78, 68, 32, 68, 79, + 84, 84, 69, 68, 32, 46, 68, 45, 3, 84, 82, 73, 6, 60, 4, 70, 79, 85, 82, + 0, 3, 84, 87, 79, 163, 160, 8, 82, 2, 169, 160, 6, 8, 32, 69, 78, 67, 76, + 79, 83, 85, 2, 83, 85, 6, 42, 68, 28, 3, 84, 82, 73, 215, 1, 67, 2, 197, + 1, 3, 79, 85, 66, 2, 171, 1, 80, 6, 52, 9, 68, 69, 78, 84, 32, 65, 78, + 68, 32, 103, 80, 4, 116, 6, 68, 79, 84, 84, 69, 68, 49, 14, 85, 45, 83, + 72, 65, 80, 69, 68, 32, 79, 82, 78, 65, 77, 2, 17, 2, 76, 69, 2, 17, 2, + 32, 67, 2, 25, 4, 82, 69, 83, 67, 2, 151, 186, 1, 69, 4, 226, 165, 8, 66, + 255, 81, 68, 12, 246, 208, 4, 83, 206, 144, 1, 67, 98, 78, 222, 160, 3, + 65, 239, 1, 86, 26, 74, 65, 94, 86, 226, 246, 5, 85, 210, 200, 1, 73, + 206, 134, 2, 69, 3, 79, 10, 184, 247, 5, 10, 76, 84, 69, 82, 78, 65, 84, + 69, 32, 85, 158, 207, 3, 65, 2, 73, 3, 85, 4, 11, 79, 4, 33, 6, 67, 65, + 76, 73, 67, 32, 4, 167, 226, 5, 82, 16, 56, 5, 66, 76, 65, 67, 75, 1, 5, + 87, 72, 73, 84, 69, 8, 11, 32, 8, 70, 82, 24, 3, 76, 69, 70, 12, 4, 68, + 79, 87, 78, 1, 2, 85, 80, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 225, 92, 6, + 32, 80, 79, 73, 78, 84, 194, 10, 96, 8, 87, 82, 73, 84, 73, 78, 71, 32, + 217, 238, 1, 10, 32, 79, 70, 32, 84, 72, 69, 32, 72, 79, 192, 10, 136, 3, + 4, 65, 73, 82, 32, 192, 1, 2, 66, 82, 102, 67, 138, 1, 68, 218, 4, 69, + 242, 6, 70, 244, 3, 4, 87, 65, 76, 76, 138, 1, 72, 238, 77, 76, 224, 6, + 2, 77, 79, 222, 42, 78, 230, 1, 82, 202, 7, 83, 162, 5, 84, 180, 10, 5, + 71, 82, 65, 83, 80, 184, 5, 30, 85, 80, 80, 69, 82, 32, 66, 79, 68, 89, + 32, 84, 73, 76, 84, 73, 78, 71, 32, 70, 82, 79, 77, 32, 72, 73, 80, 32, + 74, 79, 211, 179, 4, 80, 8, 48, 4, 66, 76, 79, 87, 29, 4, 83, 85, 67, 75, + 4, 58, 32, 195, 207, 4, 73, 4, 30, 32, 61, 3, 73, 78, 71, 2, 157, 158, 1, + 10, 83, 77, 65, 76, 76, 32, 82, 79, 84, 65, 2, 251, 190, 8, 32, 10, 52, + 5, 69, 65, 84, 72, 32, 149, 170, 1, 2, 85, 83, 4, 152, 163, 2, 2, 69, 88, + 1, 2, 73, 78, 10, 40, 6, 72, 69, 69, 75, 83, 32, 63, 79, 6, 170, 107, 83, + 146, 38, 78, 153, 204, 3, 4, 80, 85, 70, 70, 4, 246, 236, 8, 76, 211, 46, + 77, 28, 108, 15, 82, 69, 65, 77, 89, 32, 69, 89, 69, 66, 82, 79, 87, 83, + 32, 165, 1, 7, 89, 78, 65, 77, 73, 67, 32, 8, 64, 4, 68, 79, 87, 78, 0, + 2, 85, 80, 29, 4, 78, 69, 85, 84, 2, 169, 143, 1, 2, 32, 78, 4, 21, 3, + 82, 65, 76, 4, 11, 32, 4, 194, 58, 68, 247, 255, 8, 85, 20, 180, 1, 11, + 69, 86, 69, 82, 89, 32, 79, 84, 72, 69, 82, 30, 70, 22, 83, 144, 122, 9, + 65, 82, 82, 79, 87, 72, 69, 65, 68, 138, 39, 82, 232, 186, 3, 2, 84, 69, + 21, 4, 71, 82, 65, 68, 2, 137, 161, 8, 2, 32, 84, 2, 135, 241, 5, 65, 6, + 68, 11, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, 83, 235, 157, 8, 76, 5, + 251, 151, 1, 32, 54, 64, 2, 89, 69, 188, 208, 4, 4, 88, 67, 73, 84, 167, + 216, 3, 65, 50, 166, 1, 32, 56, 15, 66, 82, 79, 87, 83, 32, 83, 84, 82, + 65, 73, 71, 72, 84, 32, 44, 5, 71, 65, 90, 69, 45, 140, 2, 7, 76, 65, 83, + 72, 69, 83, 32, 65, 2, 83, 32, 6, 140, 151, 1, 5, 66, 76, 73, 78, 75, + 131, 224, 4, 87, 6, 186, 53, 68, 170, 84, 78, 207, 171, 8, 85, 18, 100, + 11, 70, 76, 79, 79, 82, 80, 76, 65, 78, 69, 32, 25, 10, 87, 65, 76, 76, + 80, 76, 65, 78, 69, 32, 8, 82, 83, 207, 45, 67, 10, 18, 67, 43, 83, 4, + 254, 45, 85, 241, 95, 3, 73, 82, 67, 6, 37, 7, 84, 82, 65, 73, 71, 72, + 84, 7, 11, 32, 4, 250, 163, 1, 65, 55, 68, 6, 130, 51, 68, 196, 154, 4, + 4, 70, 76, 85, 84, 179, 229, 4, 85, 14, 112, 5, 72, 65, 76, 70, 32, 26, + 67, 28, 4, 87, 73, 68, 69, 246, 92, 79, 233, 244, 3, 6, 83, 81, 85, 69, + 69, 90, 4, 22, 67, 147, 93, 79, 2, 205, 229, 2, 2, 76, 79, 4, 162, 67, + 32, 233, 61, 4, 78, 73, 78, 71, 38, 204, 1, 28, 65, 67, 69, 32, 68, 73, + 82, 69, 67, 84, 73, 79, 78, 32, 80, 79, 83, 73, 84, 73, 79, 78, 32, 78, + 79, 83, 69, 32, 138, 1, 73, 82, 76, 176, 1, 8, 79, 82, 69, 72, 69, 65, + 68, 32, 163, 225, 6, 85, 6, 88, 10, 85, 80, 32, 79, 82, 32, 68, 79, 87, + 78, 13, 8, 70, 79, 82, 87, 65, 82, 68, 32, 5, 11, 32, 2, 169, 212, 4, 3, + 84, 73, 76, 12, 248, 210, 3, 11, 76, 76, 32, 77, 79, 68, 73, 70, 73, 69, + 82, 171, 163, 2, 78, 12, 44, 4, 73, 67, 75, 32, 29, 3, 79, 79, 82, 10, + 174, 141, 1, 76, 35, 83, 2, 169, 176, 8, 20, 80, 76, 65, 78, 69, 32, 83, + 72, 79, 85, 76, 68, 69, 82, 32, 72, 73, 80, 32, 77, 6, 182, 89, 87, 222, + 38, 67, 47, 78, 156, 4, 34, 65, 137, 75, 3, 69, 65, 68, 140, 4, 36, 3, + 78, 68, 45, 211, 242, 8, 73, 138, 4, 92, 5, 65, 78, 71, 76, 69, 138, 5, + 67, 150, 10, 70, 186, 42, 72, 241, 12, 4, 79, 86, 65, 76, 37, 11, 32, 34, + 188, 1, 5, 73, 78, 68, 69, 88, 176, 1, 7, 76, 73, 84, 84, 76, 69, 32, + 136, 1, 5, 82, 73, 78, 71, 32, 173, 66, 18, 77, 73, 68, 68, 76, 69, 32, + 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, 17, 11, 32, 14, 128, 1, 7, + 77, 73, 68, 68, 76, 69, 32, 228, 24, 11, 82, 73, 78, 71, 32, 76, 73, 84, + 84, 76, 69, 241, 42, 5, 84, 72, 85, 77, 66, 4, 178, 70, 76, 183, 144, 8, + 82, 8, 44, 5, 73, 78, 68, 69, 88, 135, 167, 9, 85, 7, 145, 24, 18, 32, + 84, 72, 85, 77, 66, 32, 73, 78, 68, 69, 88, 32, 84, 72, 85, 77, 66, 4, + 108, 22, 68, 79, 87, 78, 32, 77, 73, 68, 68, 76, 69, 32, 84, 72, 85, 77, + 66, 32, 73, 78, 68, 69, 159, 68, 76, 2, 207, 231, 7, 88, 88, 64, 5, 73, + 82, 67, 76, 69, 184, 3, 3, 76, 65, 87, 183, 2, 85, 35, 11, 32, 32, 116, + 5, 73, 78, 68, 69, 88, 200, 1, 7, 76, 73, 84, 84, 76, 69, 32, 36, 7, 77, + 73, 68, 68, 76, 69, 32, 167, 64, 82, 21, 11, 32, 18, 72, 6, 77, 73, 68, + 68, 76, 69, 198, 26, 72, 246, 38, 82, 195, 158, 8, 66, 13, 11, 32, 10, + 64, 5, 67, 82, 79, 83, 83, 194, 64, 84, 90, 76, 183, 144, 8, 82, 4, 138, + 65, 32, 167, 155, 8, 69, 4, 170, 253, 7, 73, 239, 164, 1, 85, 6, 252, 47, + 10, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 247, 241, 8, 85, 17, 11, 32, + 14, 144, 2, 28, 77, 73, 68, 68, 76, 69, 32, 82, 73, 78, 71, 32, 76, 73, + 84, 84, 76, 69, 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 176, 49, 2, 70, + 79, 194, 11, 78, 170, 1, 84, 237, 118, 23, 73, 78, 68, 69, 88, 32, 84, + 72, 85, 77, 66, 32, 67, 85, 82, 86, 69, 32, 84, 72, 85, 77, 66, 5, 163, + 181, 1, 32, 38, 46, 80, 149, 2, 6, 82, 76, 73, 67, 85, 69, 31, 11, 32, + 28, 188, 1, 5, 73, 78, 68, 69, 88, 56, 19, 70, 73, 86, 69, 32, 70, 73, + 78, 71, 69, 82, 83, 32, 83, 80, 82, 69, 65, 68, 196, 50, 7, 77, 73, 68, + 68, 76, 69, 32, 18, 79, 214, 7, 78, 171, 1, 84, 9, 11, 32, 6, 40, 5, 84, + 72, 85, 77, 66, 247, 58, 82, 5, 215, 46, 32, 9, 11, 32, 6, 72, 5, 73, 78, + 68, 69, 88, 0, 6, 77, 73, 68, 68, 76, 69, 195, 71, 79, 2, 133, 204, 8, + 13, 32, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, 32, 172, 2, 44, 3, + 73, 83, 84, 177, 33, 3, 76, 65, 84, 247, 1, 11, 32, 244, 1, 160, 2, 5, + 73, 78, 68, 69, 88, 192, 16, 7, 76, 73, 84, 84, 76, 69, 32, 196, 2, 7, + 77, 73, 68, 68, 76, 69, 32, 200, 4, 5, 82, 73, 78, 71, 32, 132, 2, 5, 84, + 72, 85, 77, 66, 138, 2, 72, 205, 9, 22, 70, 79, 85, 82, 32, 70, 73, 78, + 71, 69, 82, 83, 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 137, 1, 11, 32, + 134, 1, 232, 1, 4, 66, 69, 78, 84, 36, 6, 72, 73, 78, 71, 69, 68, 76, 6, + 77, 73, 68, 68, 76, 69, 168, 7, 2, 67, 85, 64, 6, 84, 72, 85, 77, 66, 32, + 160, 5, 16, 85, 80, 32, 77, 73, 68, 68, 76, 69, 32, 72, 73, 78, 71, 69, + 68, 151, 4, 82, 5, 217, 45, 5, 32, 79, 86, 69, 82, 9, 11, 32, 6, 252, 20, + 8, 77, 73, 68, 68, 76, 69, 32, 85, 251, 230, 7, 76, 71, 11, 32, 68, 236, + 1, 4, 66, 69, 78, 84, 42, 67, 244, 1, 10, 85, 80, 32, 83, 80, 82, 69, 65, + 68, 32, 100, 6, 72, 73, 78, 71, 69, 68, 46, 82, 80, 5, 84, 72, 85, 77, + 66, 188, 28, 14, 83, 84, 82, 65, 73, 71, 72, 84, 32, 84, 72, 85, 77, 66, + 231, 17, 76, 5, 229, 92, 6, 32, 84, 72, 85, 77, 66, 28, 68, 8, 79, 78, + 74, 79, 73, 78, 69, 68, 233, 1, 4, 82, 79, 83, 83, 23, 11, 32, 20, 144, + 1, 6, 67, 85, 80, 80, 69, 68, 28, 6, 84, 72, 85, 77, 66, 32, 68, 5, 72, + 73, 78, 71, 69, 166, 22, 73, 165, 7, 6, 77, 73, 68, 68, 76, 69, 5, 11, + 32, 2, 203, 27, 84, 8, 160, 1, 4, 83, 73, 68, 69, 235, 61, 70, 6, 22, 69, + 163, 47, 32, 4, 223, 15, 68, 5, 241, 30, 7, 32, 83, 80, 82, 69, 65, 68, + 8, 32, 3, 73, 78, 71, 247, 19, 65, 7, 11, 32, 4, 138, 36, 67, 199, 168, + 8, 66, 19, 11, 32, 16, 64, 6, 65, 78, 71, 76, 69, 68, 22, 67, 106, 72, + 231, 202, 8, 66, 5, 207, 188, 5, 32, 6, 74, 85, 230, 7, 73, 241, 25, 10, + 79, 78, 74, 79, 73, 78, 69, 68, 32, 72, 2, 217, 174, 4, 2, 80, 80, 4, + 194, 33, 73, 233, 26, 2, 79, 79, 40, 164, 1, 7, 65, 78, 71, 76, 69, 68, + 32, 46, 67, 220, 1, 14, 70, 79, 82, 87, 65, 82, 68, 32, 73, 78, 68, 69, + 88, 32, 32, 4, 72, 79, 79, 75, 53, 4, 83, 73, 68, 69, 4, 128, 1, 2, 73, + 78, 1, 3, 79, 85, 84, 12, 36, 5, 73, 82, 67, 76, 69, 15, 85, 5, 47, 68, + 8, 32, 4, 80, 80, 69, 68, 39, 82, 2, 221, 40, 5, 32, 77, 73, 68, 68, 6, + 56, 9, 86, 69, 32, 84, 72, 85, 77, 66, 32, 143, 37, 76, 4, 206, 160, 1, + 73, 219, 164, 4, 85, 4, 218, 84, 83, 183, 242, 7, 66, 7, 157, 8, 9, 69, + 68, 32, 77, 73, 68, 68, 76, 69, 15, 11, 32, 12, 92, 6, 73, 78, 68, 69, + 88, 32, 156, 13, 5, 84, 72, 85, 77, 66, 193, 8, 4, 66, 79, 84, 72, 4, 26, + 72, 183, 197, 8, 66, 2, 207, 212, 7, 73, 7, 37, 7, 32, 84, 72, 85, 77, + 66, 32, 4, 178, 28, 67, 251, 129, 1, 83, 22, 88, 4, 68, 79, 87, 78, 186, + 1, 84, 158, 6, 82, 130, 21, 73, 170, 167, 8, 66, 147, 67, 85, 9, 11, 32, + 6, 80, 9, 79, 84, 72, 69, 82, 83, 32, 67, 73, 25, 7, 82, 73, 80, 80, 76, + 69, 32, 2, 241, 51, 2, 82, 67, 4, 22, 67, 187, 80, 83, 2, 11, 85, 2, 185, + 166, 4, 2, 82, 86, 4, 192, 35, 6, 79, 85, 67, 72, 69, 83, 39, 72, 30, + 134, 1, 82, 28, 6, 84, 72, 85, 77, 66, 32, 138, 3, 85, 134, 1, 68, 214, + 30, 76, 161, 188, 7, 9, 66, 69, 78, 84, 32, 79, 86, 69, 82, 4, 238, 4, + 65, 235, 29, 73, 16, 80, 7, 65, 78, 71, 76, 69, 68, 32, 126, 67, 124, 4, + 72, 79, 79, 75, 151, 32, 76, 6, 60, 10, 79, 85, 84, 32, 73, 78, 68, 69, + 88, 32, 215, 1, 73, 4, 26, 67, 211, 130, 9, 85, 2, 241, 182, 2, 3, 82, + 79, 83, 6, 76, 12, 73, 82, 67, 76, 69, 68, 32, 73, 78, 68, 69, 88, 45, 3, + 85, 80, 80, 4, 11, 32, 4, 150, 21, 72, 191, 236, 8, 85, 2, 25, 4, 69, 68, + 32, 73, 2, 229, 30, 4, 78, 68, 69, 88, 4, 11, 80, 5, 175, 15, 32, 18, + 102, 68, 20, 6, 77, 73, 68, 68, 76, 69, 42, 82, 194, 29, 84, 90, 76, 182, + 188, 7, 73, 239, 164, 1, 85, 2, 223, 174, 7, 79, 7, 11, 32, 4, 206, 3, + 82, 179, 16, 67, 2, 11, 65, 2, 37, 7, 73, 83, 69, 68, 32, 75, 78, 2, 11, + 85, 2, 11, 67, 2, 211, 221, 7, 75, 35, 11, 32, 32, 148, 1, 8, 66, 69, 84, + 87, 69, 69, 78, 32, 102, 72, 20, 5, 79, 86, 69, 82, 32, 120, 4, 83, 73, + 68, 69, 100, 6, 85, 78, 68, 69, 82, 32, 223, 40, 70, 8, 80, 12, 73, 78, + 68, 69, 88, 32, 77, 73, 68, 68, 76, 69, 246, 20, 77, 159, 6, 82, 5, 151, + 70, 32, 2, 131, 156, 4, 69, 4, 52, 6, 70, 79, 85, 82, 32, 82, 161, 2, 2, + 84, 87, 2, 11, 65, 2, 133, 81, 9, 73, 83, 69, 68, 32, 75, 78, 85, 67, 6, + 11, 32, 6, 38, 68, 190, 15, 67, 199, 168, 8, 66, 2, 25, 4, 73, 65, 71, + 79, 2, 215, 241, 7, 78, 10, 54, 73, 34, 84, 48, 4, 70, 79, 85, 82, 255, + 22, 76, 2, 161, 7, 4, 78, 68, 69, 88, 4, 34, 87, 13, 4, 72, 82, 69, 69, + 2, 11, 79, 2, 153, 235, 7, 5, 32, 70, 73, 78, 71, 55, 11, 32, 52, 194, 1, + 70, 172, 3, 4, 72, 69, 69, 76, 192, 1, 6, 83, 80, 76, 73, 84, 32, 236, 1, + 6, 84, 72, 85, 77, 66, 32, 153, 231, 4, 16, 66, 69, 84, 87, 69, 69, 78, + 32, 80, 65, 76, 77, 32, 70, 65, 67, 24, 140, 1, 18, 73, 86, 69, 32, 70, + 73, 78, 71, 69, 82, 83, 32, 83, 80, 82, 69, 65, 68, 165, 1, 11, 79, 85, + 82, 32, 70, 73, 78, 71, 69, 82, 83, 15, 11, 32, 12, 68, 6, 72, 73, 78, + 71, 69, 68, 42, 84, 186, 2, 70, 143, 176, 8, 66, 7, 11, 32, 4, 190, 4, + 84, 151, 15, 78, 2, 205, 35, 6, 72, 85, 77, 66, 32, 70, 11, 11, 32, 8, + 72, 9, 67, 79, 78, 74, 79, 73, 78, 69, 68, 154, 8, 72, 175, 169, 8, 66, + 5, 153, 216, 8, 3, 32, 83, 80, 11, 11, 32, 8, 96, 19, 70, 73, 86, 69, 32, + 70, 73, 78, 71, 69, 82, 83, 32, 83, 80, 82, 69, 65, 68, 151, 2, 84, 7, + 11, 32, 4, 26, 70, 143, 176, 8, 66, 2, 21, 3, 79, 85, 82, 2, 167, 1, 32, + 10, 72, 6, 67, 69, 78, 84, 82, 69, 96, 5, 73, 78, 68, 69, 88, 171, 16, + 76, 7, 49, 10, 32, 84, 72, 85, 77, 66, 32, 83, 73, 68, 4, 11, 69, 5, 11, + 32, 2, 203, 174, 8, 66, 2, 11, 32, 2, 11, 84, 2, 197, 135, 1, 5, 72, 85, + 77, 66, 32, 6, 130, 31, 70, 170, 104, 83, 207, 166, 7, 66, 82, 48, 4, 73, + 78, 71, 69, 181, 9, 3, 79, 79, 75, 63, 11, 32, 60, 206, 1, 70, 172, 1, 5, + 73, 78, 68, 69, 88, 196, 2, 6, 76, 73, 84, 84, 76, 69, 80, 6, 77, 73, 68, + 68, 76, 69, 30, 79, 64, 4, 82, 73, 78, 71, 124, 6, 84, 72, 85, 77, 66, + 32, 154, 6, 78, 215, 128, 4, 83, 4, 92, 19, 73, 86, 69, 32, 70, 73, 78, + 71, 69, 82, 83, 32, 83, 80, 82, 69, 65, 68, 32, 19, 79, 2, 207, 25, 79, + 2, 249, 1, 11, 85, 82, 32, 70, 73, 78, 71, 69, 82, 83, 32, 23, 11, 32, + 20, 86, 72, 40, 7, 77, 73, 68, 68, 76, 69, 32, 104, 5, 84, 72, 85, 77, + 66, 223, 9, 82, 2, 11, 73, 2, 249, 140, 4, 2, 78, 71, 6, 36, 4, 82, 73, + 78, 71, 207, 10, 76, 5, 11, 32, 2, 11, 67, 2, 21, 3, 79, 78, 74, 2, 191, + 33, 79, 11, 11, 32, 8, 34, 83, 226, 22, 79, 203, 39, 76, 4, 146, 222, 6, + 73, 187, 8, 77, 9, 11, 32, 6, 22, 73, 195, 8, 84, 4, 25, 4, 78, 68, 69, + 88, 5, 151, 8, 32, 5, 11, 32, 2, 175, 8, 82, 8, 21, 3, 80, 69, 78, 9, 11, + 32, 6, 174, 7, 78, 171, 1, 84, 5, 97, 22, 32, 68, 79, 87, 78, 32, 73, 78, + 68, 69, 88, 32, 84, 72, 85, 77, 66, 32, 72, 79, 79, 75, 2, 205, 77, 2, + 32, 77, 6, 68, 9, 66, 69, 84, 87, 69, 69, 78, 32, 77, 53, 4, 83, 73, 68, + 69, 2, 29, 5, 73, 68, 68, 76, 69, 2, 235, 134, 4, 32, 5, 33, 6, 32, 84, + 79, 85, 67, 72, 2, 145, 194, 7, 3, 73, 78, 71, 21, 11, 32, 18, 172, 1, 4, + 67, 85, 82, 76, 28, 18, 73, 78, 68, 69, 88, 32, 82, 73, 78, 71, 32, 76, + 73, 84, 84, 76, 69, 32, 48, 7, 77, 73, 68, 68, 76, 69, 32, 221, 2, 4, 82, + 73, 78, 71, 2, 229, 132, 5, 2, 73, 67, 6, 254, 159, 5, 85, 234, 203, 2, + 79, 239, 41, 73, 8, 104, 21, 82, 73, 78, 71, 32, 76, 73, 84, 84, 76, 69, + 32, 67, 79, 78, 74, 79, 73, 78, 69, 68, 139, 2, 84, 7, 231, 213, 2, 32, + 17, 11, 32, 14, 130, 1, 76, 66, 78, 78, 82, 94, 84, 136, 154, 2, 15, 70, + 73, 86, 69, 32, 70, 73, 78, 71, 69, 82, 83, 32, 83, 80, 131, 162, 5, 73, + 2, 21, 3, 73, 84, 84, 2, 17, 2, 76, 69, 2, 215, 236, 7, 32, 2, 11, 79, 2, + 11, 32, 2, 11, 84, 2, 11, 72, 2, 209, 167, 7, 2, 85, 77, 2, 11, 73, 2, + 21, 3, 78, 71, 32, 2, 11, 76, 2, 11, 73, 2, 11, 84, 2, 239, 191, 7, 84, + 4, 29, 5, 72, 85, 77, 66, 32, 4, 206, 14, 70, 171, 104, 83, 17, 11, 32, + 14, 56, 8, 77, 79, 86, 69, 77, 69, 78, 84, 199, 221, 7, 82, 12, 26, 45, + 207, 144, 7, 32, 10, 100, 11, 70, 76, 79, 79, 82, 80, 76, 65, 78, 69, 32, + 25, 10, 87, 65, 76, 76, 80, 76, 65, 78, 69, 32, 4, 62, 67, 235, 40, 83, + 6, 38, 67, 28, 2, 84, 73, 207, 40, 83, 2, 241, 225, 7, 2, 85, 82, 2, 239, + 193, 8, 76, 38, 50, 73, 225, 3, 7, 79, 67, 65, 84, 73, 79, 78, 22, 32, 3, + 77, 66, 32, 171, 1, 80, 16, 56, 4, 67, 79, 77, 66, 29, 6, 76, 69, 78, 71, + 84, 72, 2, 189, 176, 5, 2, 73, 78, 14, 11, 45, 14, 202, 220, 8, 49, 2, + 50, 2, 51, 2, 52, 2, 53, 2, 54, 3, 55, 6, 58, 32, 153, 1, 9, 83, 32, 80, + 82, 69, 83, 83, 69, 68, 4, 116, 12, 76, 79, 87, 69, 82, 32, 79, 86, 69, + 82, 32, 85, 213, 193, 7, 11, 85, 80, 80, 69, 82, 32, 79, 86, 69, 82, 32, + 2, 11, 80, 2, 231, 156, 8, 80, 2, 29, 5, 32, 84, 79, 71, 69, 2, 11, 84, + 2, 167, 156, 8, 72, 16, 22, 32, 215, 1, 45, 12, 140, 1, 2, 72, 69, 48, 3, + 84, 79, 82, 152, 217, 6, 3, 68, 69, 80, 0, 3, 87, 73, 68, 241, 106, 10, + 76, 73, 77, 66, 83, 32, 68, 73, 71, 73, 4, 216, 13, 4, 65, 68, 32, 78, + 175, 160, 8, 73, 2, 167, 185, 8, 83, 4, 52, 5, 70, 76, 79, 79, 82, 1, 4, + 87, 65, 76, 76, 2, 149, 153, 8, 5, 80, 76, 65, 78, 69, 156, 3, 64, 4, 85, + 84, 72, 32, 161, 5, 7, 86, 69, 77, 69, 78, 84, 45, 54, 186, 1, 67, 88, 5, + 70, 82, 79, 87, 78, 0, 5, 83, 77, 73, 76, 69, 56, 4, 75, 73, 83, 83, 36, + 5, 79, 80, 69, 78, 32, 192, 1, 5, 84, 69, 78, 83, 69, 165, 29, 5, 87, 82, + 73, 78, 75, 8, 48, 6, 76, 79, 83, 69, 68, 32, 243, 166, 7, 79, 6, 222, 2, + 70, 142, 38, 67, 47, 78, 7, 11, 32, 4, 22, 79, 203, 1, 87, 2, 179, 131, + 7, 80, 7, 11, 32, 4, 166, 1, 87, 83, 70, 18, 100, 4, 79, 86, 65, 76, 0, + 9, 82, 69, 67, 84, 65, 78, 71, 76, 69, 42, 87, 82, 70, 139, 131, 7, 67, + 7, 11, 32, 4, 26, 87, 183, 129, 7, 89, 2, 25, 4, 82, 73, 78, 75, 2, 131, + 243, 3, 76, 7, 11, 32, 4, 18, 70, 43, 83, 2, 17, 2, 79, 82, 2, 155, 187, + 7, 87, 2, 17, 2, 85, 67, 2, 147, 242, 3, 75, 230, 2, 192, 1, 9, 68, 73, + 65, 71, 79, 78, 65, 76, 32, 148, 1, 11, 70, 76, 79, 79, 82, 80, 76, 65, + 78, 69, 32, 184, 14, 6, 72, 73, 78, 71, 69, 32, 189, 2, 10, 87, 65, 76, + 76, 80, 76, 65, 78, 69, 32, 32, 56, 8, 66, 69, 84, 87, 69, 69, 78, 32, + 22, 65, 31, 84, 16, 18, 65, 31, 84, 8, 229, 28, 3, 87, 65, 89, 8, 201, + 28, 6, 79, 87, 65, 82, 68, 83, 150, 1, 208, 2, 24, 65, 82, 77, 32, 67, + 73, 82, 67, 76, 69, 32, 72, 73, 84, 84, 73, 78, 71, 32, 87, 65, 76, 76, + 32, 38, 66, 34, 67, 224, 1, 8, 70, 73, 78, 71, 69, 82, 32, 67, 52, 5, 72, + 85, 77, 80, 32, 184, 3, 5, 76, 79, 79, 80, 32, 198, 1, 83, 108, 7, 84, + 82, 73, 80, 76, 69, 32, 110, 87, 206, 12, 68, 198, 2, 80, 154, 6, 90, + 159, 175, 7, 74, 12, 178, 7, 76, 154, 9, 77, 39, 83, 8, 150, 17, 79, 243, + 172, 7, 69, 28, 86, 72, 20, 5, 85, 82, 86, 69, 32, 196, 29, 5, 79, 82, + 78, 69, 82, 195, 239, 6, 82, 2, 163, 156, 7, 69, 18, 80, 4, 67, 79, 77, + 66, 158, 8, 72, 230, 15, 76, 198, 157, 2, 77, 243, 178, 1, 83, 2, 11, 73, + 2, 187, 234, 3, 78, 6, 128, 9, 6, 73, 82, 67, 76, 69, 83, 239, 20, 79, + 18, 56, 8, 72, 73, 84, 84, 73, 78, 71, 32, 167, 231, 3, 83, 16, 72, 8, + 67, 69, 73, 76, 73, 78, 71, 32, 101, 6, 70, 76, 79, 79, 82, 32, 8, 56, 5, + 76, 65, 82, 71, 69, 1, 5, 83, 77, 65, 76, 76, 4, 11, 32, 4, 238, 54, 84, + 135, 2, 68, 8, 88, 4, 83, 77, 65, 76, 12, 5, 76, 65, 82, 71, 69, 17, 7, + 84, 82, 73, 80, 76, 69, 32, 2, 11, 76, 2, 255, 18, 32, 4, 56, 5, 76, 65, + 82, 71, 69, 1, 5, 83, 77, 65, 76, 76, 2, 157, 53, 2, 32, 84, 18, 56, 8, + 72, 73, 84, 84, 73, 78, 71, 32, 239, 227, 3, 83, 16, 64, 7, 67, 69, 73, + 76, 73, 78, 71, 1, 5, 70, 76, 79, 79, 82, 8, 11, 32, 8, 22, 76, 191, 9, + 83, 4, 249, 22, 4, 65, 82, 71, 69, 12, 44, 6, 72, 65, 75, 73, 78, 71, + 243, 16, 73, 2, 21, 3, 32, 80, 65, 2, 149, 227, 3, 4, 82, 65, 76, 76, 8, + 76, 12, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, 32, 138, 18, 87, 63, + 83, 4, 134, 18, 87, 159, 21, 77, 18, 80, 4, 65, 86, 69, 32, 169, 1, 11, + 82, 73, 83, 84, 32, 67, 73, 82, 67, 76, 69, 14, 30, 72, 102, 83, 171, 20, + 76, 8, 37, 7, 73, 84, 84, 73, 78, 71, 32, 8, 252, 2, 4, 67, 69, 73, 76, + 25, 5, 70, 76, 79, 79, 82, 4, 138, 251, 4, 78, 195, 193, 1, 77, 4, 209, + 5, 10, 32, 72, 73, 84, 84, 73, 78, 71, 32, 87, 14, 112, 3, 85, 80, 32, + 184, 1, 6, 68, 79, 87, 78, 32, 83, 245, 183, 5, 10, 83, 73, 68, 69, 32, + 84, 79, 32, 83, 73, 10, 40, 5, 68, 79, 87, 78, 32, 143, 1, 83, 8, 68, 8, + 65, 76, 84, 69, 82, 78, 65, 84, 230, 17, 76, 143, 203, 3, 83, 4, 21, 3, + 73, 78, 71, 4, 11, 32, 4, 190, 17, 76, 143, 203, 3, 83, 2, 219, 30, 69, + 162, 1, 148, 2, 11, 65, 82, 77, 32, 67, 73, 82, 67, 76, 69, 32, 98, 66, + 54, 67, 174, 4, 68, 100, 8, 70, 73, 78, 71, 69, 82, 32, 67, 64, 5, 72, + 85, 77, 80, 32, 60, 5, 76, 79, 79, 80, 32, 102, 80, 34, 83, 216, 1, 7, + 84, 82, 73, 80, 76, 69, 32, 218, 1, 87, 202, 2, 90, 159, 175, 7, 74, 8, + 18, 77, 39, 83, 4, 225, 13, 5, 69, 68, 73, 85, 77, 4, 11, 77, 4, 177, 13, + 3, 65, 76, 76, 12, 34, 79, 185, 13, 3, 69, 78, 68, 6, 183, 13, 88, 46, + 100, 6, 79, 82, 78, 69, 82, 32, 88, 4, 85, 82, 86, 69, 232, 11, 4, 72, + 69, 67, 75, 195, 239, 6, 82, 8, 54, 82, 194, 12, 76, 158, 152, 2, 77, + 243, 178, 1, 83, 2, 11, 79, 2, 223, 140, 5, 84, 30, 50, 32, 137, 2, 7, + 68, 32, 67, 82, 79, 83, 83, 26, 66, 72, 68, 2, 84, 72, 133, 5, 7, 81, 85, + 65, 82, 84, 69, 82, 12, 196, 5, 10, 65, 76, 70, 45, 67, 73, 82, 67, 76, + 69, 159, 14, 73, 6, 96, 2, 69, 78, 29, 18, 82, 69, 69, 45, 81, 85, 65, + 82, 84, 69, 82, 32, 67, 73, 82, 67, 76, 69, 2, 11, 32, 2, 131, 1, 83, 4, + 11, 32, 4, 242, 161, 2, 77, 243, 178, 1, 83, 8, 33, 6, 79, 85, 66, 76, + 69, 32, 8, 30, 83, 150, 4, 65, 75, 87, 2, 253, 138, 8, 3, 84, 82, 65, 6, + 32, 3, 73, 82, 67, 151, 9, 79, 4, 173, 7, 3, 76, 69, 83, 10, 142, 8, 76, + 178, 8, 72, 238, 143, 2, 77, 243, 178, 1, 83, 12, 68, 5, 83, 77, 65, 76, + 76, 142, 7, 76, 178, 8, 72, 239, 143, 2, 77, 5, 11, 32, 2, 239, 36, 68, + 6, 181, 6, 4, 69, 65, 75, 83, 12, 22, 73, 243, 36, 72, 10, 29, 5, 78, 71, + 76, 69, 32, 10, 52, 8, 83, 84, 82, 65, 73, 71, 72, 84, 207, 1, 87, 8, 11, + 32, 8, 42, 76, 198, 157, 2, 77, 243, 178, 1, 83, 4, 25, 4, 65, 82, 71, + 69, 5, 191, 149, 8, 83, 8, 26, 65, 74, 87, 63, 83, 4, 49, 10, 76, 84, 69, + 82, 78, 65, 84, 73, 78, 71, 5, 17, 2, 32, 87, 2, 29, 5, 82, 73, 83, 84, + 32, 2, 237, 139, 7, 2, 70, 76, 2, 37, 7, 84, 82, 65, 73, 71, 72, 84, 2, + 171, 20, 32, 26, 104, 4, 65, 86, 69, 32, 185, 1, 17, 82, 73, 83, 84, 32, + 67, 73, 82, 67, 76, 69, 32, 70, 82, 79, 78, 84, 22, 108, 6, 67, 85, 82, + 86, 69, 32, 140, 1, 13, 68, 73, 65, 71, 79, 78, 65, 76, 32, 80, 65, 84, + 72, 235, 8, 72, 12, 48, 4, 68, 79, 85, 66, 1, 4, 84, 82, 73, 80, 6, 85, + 2, 76, 69, 4, 11, 32, 4, 222, 30, 68, 43, 83, 6, 29, 5, 73, 71, 90, 65, + 71, 6, 11, 32, 6, 42, 76, 158, 152, 2, 77, 243, 178, 1, 83, 2, 143, 240, + 6, 65, 10, 40, 4, 79, 83, 69, 32, 215, 253, 6, 69, 8, 26, 67, 46, 78, 35, + 87, 2, 11, 79, 2, 157, 157, 7, 3, 78, 84, 65, 2, 161, 162, 7, 3, 69, 85, + 84, 4, 36, 2, 73, 71, 21, 3, 82, 73, 78, 2, 191, 130, 5, 71, 2, 171, 130, + 5, 75, 72, 56, 7, 79, 84, 65, 84, 73, 79, 78, 225, 22, 2, 85, 66, 66, 60, + 10, 32, 77, 79, 68, 73, 70, 73, 69, 82, 45, 155, 1, 45, 30, 82, 49, 154, + 169, 8, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 14, 150, + 169, 8, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, 36, 104, 11, 70, + 76, 79, 79, 82, 80, 76, 65, 78, 69, 32, 133, 2, 10, 87, 65, 76, 76, 80, + 76, 65, 78, 69, 32, 18, 100, 4, 68, 79, 85, 66, 0, 4, 83, 73, 78, 71, 21, + 11, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, 6, 17, 2, 76, 69, 7, 45, + 9, 32, 72, 73, 84, 84, 73, 78, 71, 32, 4, 32, 2, 67, 69, 33, 2, 70, 76, + 2, 11, 73, 2, 147, 213, 7, 76, 2, 155, 237, 7, 79, 18, 88, 8, 65, 76, 84, + 69, 82, 78, 65, 84, 44, 4, 68, 79, 85, 66, 1, 4, 83, 73, 78, 71, 6, 72, + 4, 73, 78, 71, 32, 191, 164, 8, 69, 6, 17, 2, 76, 69, 7, 11, 32, 4, 11, + 72, 4, 11, 73, 4, 33, 6, 84, 84, 73, 78, 71, 32, 4, 44, 2, 67, 72, 21, 5, + 70, 82, 79, 78, 84, 2, 135, 220, 4, 69, 2, 253, 158, 6, 2, 32, 87, 30, + 172, 1, 8, 72, 79, 85, 76, 68, 69, 82, 32, 196, 1, 7, 81, 85, 69, 69, 90, + 69, 32, 240, 1, 7, 85, 82, 70, 65, 67, 69, 32, 240, 10, 5, 84, 82, 73, + 75, 69, 243, 221, 4, 69, 6, 100, 4, 72, 73, 80, 32, 173, 232, 3, 15, 84, + 73, 76, 84, 73, 78, 71, 32, 70, 82, 79, 77, 32, 87, 65, 4, 48, 4, 80, 79, + 83, 73, 181, 135, 7, 2, 83, 80, 2, 11, 84, 2, 177, 242, 4, 2, 73, 79, 12, + 48, 6, 70, 76, 73, 67, 75, 32, 18, 76, 35, 83, 2, 211, 16, 65, 4, 129, 1, + 4, 65, 82, 71, 69, 6, 34, 69, 65, 4, 77, 65, 76, 76, 2, 17, 2, 81, 85, 2, + 21, 3, 69, 78, 84, 2, 207, 149, 7, 73, 4, 11, 32, 4, 214, 11, 77, 187, 4, + 83, 4, 22, 83, 135, 11, 66, 2, 201, 204, 1, 4, 89, 77, 66, 79, 82, 58, + 69, 218, 2, 79, 137, 8, 6, 82, 65, 86, 69, 76, 45, 20, 76, 3, 69, 84, 72, + 185, 1, 11, 78, 83, 69, 32, 67, 72, 69, 69, 75, 83, 32, 15, 11, 32, 12, + 56, 3, 79, 78, 32, 86, 77, 177, 5, 4, 66, 73, 84, 69, 8, 56, 4, 76, 73, + 80, 83, 1, 6, 84, 79, 78, 71, 85, 69, 5, 11, 32, 2, 11, 77, 2, 245, 180, + 3, 2, 79, 86, 6, 50, 77, 252, 162, 4, 2, 72, 73, 131, 222, 2, 76, 2, 157, + 149, 3, 2, 73, 68, 28, 76, 5, 78, 71, 85, 69, 32, 196, 4, 4, 82, 83, 79, + 45, 129, 2, 2, 85, 67, 16, 192, 2, 7, 67, 69, 78, 84, 82, 69, 32, 52, 14, + 73, 78, 83, 73, 68, 69, 32, 77, 79, 85, 84, 72, 32, 82, 36, 4, 84, 73, + 80, 32, 88, 7, 76, 73, 67, 75, 73, 78, 71, 128, 244, 6, 14, 83, 84, 73, + 67, 75, 73, 78, 71, 32, 79, 85, 84, 32, 70, 133, 159, 1, 17, 77, 79, 86, + 69, 83, 32, 65, 71, 65, 73, 78, 83, 84, 32, 67, 72, 69, 4, 214, 1, 73, + 193, 166, 3, 5, 83, 84, 73, 67, 75, 2, 225, 183, 3, 4, 69, 76, 65, 88, 4, + 84, 7, 66, 69, 84, 87, 69, 69, 78, 41, 10, 84, 79, 85, 67, 72, 73, 78, + 71, 32, 73, 2, 11, 32, 2, 189, 246, 4, 2, 76, 73, 2, 237, 167, 3, 5, 78, + 83, 73, 68, 69, 6, 120, 10, 87, 65, 76, 76, 80, 76, 65, 78, 69, 32, 169, + 186, 3, 14, 70, 76, 79, 79, 82, 80, 76, 65, 78, 69, 32, 84, 87, 73, 4, + 108, 8, 67, 85, 82, 86, 69, 68, 32, 66, 241, 200, 1, 13, 83, 84, 82, 65, + 73, 71, 72, 84, 32, 83, 84, 82, 69, 2, 139, 134, 7, 69, 6, 11, 72, 6, 11, + 32, 6, 30, 66, 34, 77, 187, 4, 83, 2, 157, 194, 6, 3, 69, 84, 87, 2, 149, + 2, 3, 85, 76, 84, 34, 100, 11, 70, 76, 79, 79, 82, 80, 76, 65, 78, 69, + 32, 29, 10, 87, 65, 76, 76, 80, 76, 65, 78, 69, 32, 14, 178, 1, 82, 151, + 2, 83, 20, 72, 11, 65, 82, 77, 32, 83, 80, 73, 82, 65, 76, 32, 78, 82, + 151, 2, 83, 6, 30, 84, 134, 2, 68, 43, 83, 2, 11, 82, 2, 11, 73, 2, 183, + 239, 6, 80, 12, 41, 8, 79, 84, 65, 84, 73, 79, 78, 45, 12, 52, 5, 70, 76, + 79, 79, 82, 1, 4, 87, 65, 76, 76, 6, 33, 6, 80, 76, 65, 78, 69, 32, 6, + 26, 65, 54, 68, 43, 83, 2, 29, 5, 76, 84, 69, 82, 78, 2, 247, 180, 3, 65, + 2, 17, 2, 79, 85, 2, 183, 237, 6, 66, 2, 139, 237, 6, 73, 2, 11, 72, 2, + 247, 178, 3, 65, 2, 11, 73, 2, 243, 249, 6, 78, 10, 100, 6, 65, 66, 79, + 86, 69, 32, 162, 1, 79, 197, 133, 2, 10, 77, 73, 78, 85, 83, 32, 83, 73, + 77, 73, 4, 60, 7, 71, 82, 69, 65, 84, 69, 82, 1, 4, 76, 69, 83, 83, 2, + 37, 7, 45, 84, 72, 65, 78, 32, 65, 2, 25, 4, 66, 79, 86, 69, 2, 157, 228, + 1, 2, 32, 69, 4, 203, 252, 5, 82, 250, 1, 64, 3, 71, 76, 69, 212, 4, 5, + 72, 65, 76, 65, 32, 135, 102, 69, 20, 50, 32, 221, 137, 8, 6, 45, 83, 72, + 73, 70, 84, 16, 138, 1, 67, 0, 9, 71, 82, 65, 80, 72, 73, 67, 32, 67, + 116, 2, 72, 73, 74, 76, 36, 4, 82, 73, 71, 72, 145, 208, 4, 4, 83, 72, + 73, 70, 2, 41, 8, 72, 65, 82, 65, 67, 84, 69, 82, 2, 37, 7, 32, 73, 78, + 84, 82, 79, 68, 2, 11, 85, 2, 143, 203, 7, 67, 2, 25, 4, 71, 72, 45, 82, + 2, 185, 1, 7, 69, 86, 69, 82, 83, 69, 68, 4, 32, 2, 69, 70, 109, 2, 79, + 87, 2, 49, 10, 84, 45, 80, 79, 73, 78, 84, 73, 78, 71, 2, 21, 3, 32, 65, + 78, 2, 17, 2, 71, 76, 2, 31, 69, 2, 17, 2, 45, 57, 2, 11, 32, 2, 11, 81, + 2, 205, 161, 2, 2, 85, 79, 228, 1, 168, 2, 8, 65, 82, 67, 72, 65, 73, 67, + 32, 224, 1, 15, 67, 79, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, + 32, 114, 76, 188, 8, 5, 83, 73, 71, 78, 32, 144, 1, 11, 86, 79, 87, 69, + 76, 32, 83, 73, 71, 78, 32, 229, 212, 2, 17, 80, 85, 78, 67, 84, 85, 65, + 84, 73, 79, 78, 32, 75, 85, 78, 68, 68, 40, 46, 68, 109, 7, 78, 85, 77, + 66, 69, 82, 32, 18, 25, 4, 73, 71, 73, 84, 18, 11, 32, 18, 146, 150, 6, + 70, 30, 83, 42, 84, 190, 83, 78, 14, 79, 199, 110, 69, 22, 150, 218, 2, + 79, 134, 189, 3, 69, 30, 70, 42, 78, 38, 83, 39, 84, 6, 18, 82, 63, 89, + 4, 56, 6, 65, 75, 65, 65, 82, 65, 245, 254, 7, 2, 69, 80, 2, 241, 254, 7, + 3, 65, 78, 83, 138, 1, 60, 6, 69, 84, 84, 69, 82, 32, 217, 171, 2, 3, 73, + 84, 72, 118, 246, 1, 65, 106, 69, 34, 73, 62, 85, 34, 77, 220, 1, 4, 68, + 65, 78, 84, 58, 79, 28, 8, 83, 65, 78, 89, 65, 75, 65, 32, 50, 70, 2, 72, + 2, 82, 2, 86, 2, 89, 32, 8, 84, 65, 65, 76, 85, 74, 65, 32, 29, 9, 75, + 65, 78, 84, 65, 74, 65, 32, 78, 34, 102, 69, 204, 1, 2, 76, 80, 144, 2, + 5, 77, 66, 65, 32, 66, 14, 65, 2, 73, 2, 85, 175, 216, 4, 89, 4, 230, 3, + 69, 175, 216, 4, 89, 12, 46, 76, 2, 82, 154, 3, 73, 175, 216, 4, 89, 4, + 11, 85, 4, 138, 3, 85, 175, 216, 4, 89, 28, 42, 65, 177, 1, 5, 85, 85, + 82, 68, 72, 22, 32, 2, 72, 65, 203, 218, 4, 89, 20, 41, 8, 65, 80, 82, + 65, 65, 78, 65, 32, 20, 70, 84, 138, 1, 68, 22, 66, 2, 67, 2, 71, 2, 74, + 2, 75, 3, 80, 4, 154, 1, 84, 15, 65, 6, 25, 4, 65, 74, 65, 32, 6, 102, + 76, 2, 78, 3, 83, 4, 86, 79, 175, 216, 4, 89, 8, 26, 68, 22, 71, 3, 74, + 4, 18, 68, 15, 65, 2, 11, 65, 2, 171, 216, 4, 89, 6, 26, 78, 21, 2, 83, + 65, 2, 89, 2, 65, 65, 4, 68, 11, 78, 89, 79, 79, 71, 65, 32, 78, 65, 65, + 75, 163, 215, 4, 89, 2, 185, 246, 7, 4, 83, 73, 75, 89, 8, 66, 65, 150, + 146, 4, 67, 193, 227, 3, 6, 86, 73, 83, 65, 82, 71, 4, 220, 113, 5, 76, + 45, 76, 65, 75, 245, 131, 7, 6, 78, 85, 83, 86, 65, 82, 34, 56, 5, 68, + 73, 71, 65, 32, 62, 71, 82, 75, 155, 2, 65, 12, 58, 71, 48, 4, 75, 79, + 77, 66, 118, 65, 26, 73, 19, 80, 4, 11, 65, 4, 236, 2, 3, 69, 84, 84, 67, + 89, 2, 11, 85, 2, 131, 244, 7, 86, 16, 52, 5, 69, 84, 84, 73, 32, 85, 4, + 79, 77, 66, 85, 6, 26, 65, 26, 73, 19, 80, 2, 213, 1, 2, 69, 68, 2, 203, + 1, 83, 2, 175, 1, 65, 10, 40, 2, 86, 65, 173, 198, 7, 2, 32, 68, 9, 29, + 5, 32, 72, 65, 65, 32, 6, 62, 65, 0, 6, 68, 73, 71, 65, 32, 65, 85, 3, + 71, 65, 89, 2, 17, 2, 69, 76, 2, 11, 65, 2, 17, 2, 45, 80, 2, 11, 73, 2, + 183, 209, 7, 76, 2, 193, 202, 5, 5, 65, 78, 85, 75, 73, 12, 84, 2, 32, + 80, 206, 2, 45, 137, 223, 5, 10, 84, 69, 69, 78, 32, 80, 79, 73, 78, 84, + 8, 140, 1, 23, 69, 84, 65, 76, 76, 69, 68, 32, 66, 76, 65, 67, 75, 32, + 65, 78, 68, 32, 87, 72, 73, 84, 69, 49, 7, 79, 73, 78, 84, 69, 68, 32, 2, + 25, 4, 32, 70, 76, 79, 2, 207, 172, 6, 82, 6, 78, 80, 150, 221, 5, 66, + 217, 129, 1, 9, 83, 84, 65, 82, 32, 87, 73, 84, 72, 2, 21, 3, 73, 78, 87, + 2, 149, 221, 5, 4, 72, 69, 69, 76, 2, 179, 194, 3, 80, 12, 46, 73, 102, + 85, 213, 215, 6, 3, 65, 84, 69, 4, 56, 8, 32, 65, 78, 68, 32, 83, 75, 73, + 163, 182, 7, 69, 2, 17, 2, 32, 66, 2, 175, 158, 7, 79, 6, 32, 2, 76, 76, + 143, 235, 7, 78, 5, 11, 32, 2, 49, 10, 65, 78, 68, 32, 67, 82, 79, 83, + 83, 66, 2, 11, 79, 2, 247, 217, 6, 78, 42, 46, 65, 198, 4, 69, 210, 1, + 73, 155, 1, 79, 14, 64, 5, 78, 84, 69, 68, 32, 253, 219, 5, 5, 86, 79, + 78, 73, 67, 12, 148, 1, 12, 69, 81, 85, 65, 76, 32, 84, 79, 32, 79, 82, + 32, 229, 1, 19, 78, 79, 82, 84, 72, 32, 65, 82, 82, 79, 87, 32, 87, 73, + 84, 72, 32, 72, 79, 8, 60, 7, 71, 82, 69, 65, 84, 69, 82, 1, 4, 76, 69, + 83, 83, 4, 29, 5, 45, 84, 72, 65, 78, 5, 11, 32, 2, 25, 4, 87, 73, 84, + 72, 2, 25, 4, 32, 68, 79, 84, 2, 17, 2, 32, 73, 2, 11, 78, 2, 11, 83, 2, + 243, 220, 5, 73, 4, 24, 2, 79, 75, 43, 82, 2, 17, 2, 69, 68, 2, 135, 155, + 5, 32, 2, 29, 5, 73, 90, 79, 78, 84, 2, 11, 65, 2, 203, 187, 5, 76, 12, + 80, 2, 69, 80, 180, 214, 7, 9, 85, 84, 72, 32, 79, 82, 32, 83, 80, 203, + 17, 68, 8, 40, 4, 73, 78, 71, 32, 191, 170, 7, 89, 6, 152, 187, 4, 8, 65, + 67, 67, 79, 77, 77, 79, 68, 190, 153, 2, 83, 255, 85, 70, 6, 76, 9, 67, + 69, 32, 79, 70, 32, 80, 73, 90, 21, 6, 71, 72, 84, 76, 89, 32, 2, 247, + 227, 7, 90, 4, 196, 162, 6, 2, 70, 82, 145, 16, 3, 83, 77, 73, 10, 18, + 80, 75, 84, 6, 140, 186, 4, 9, 73, 78, 71, 32, 76, 65, 82, 71, 69, 199, + 171, 3, 69, 4, 26, 32, 243, 228, 7, 72, 2, 11, 77, 2, 193, 203, 6, 3, 65, + 67, 72, 148, 1, 34, 65, 210, 12, 73, 159, 8, 79, 114, 32, 2, 76, 76, 227, + 212, 6, 83, 112, 30, 32, 193, 11, 2, 69, 82, 108, 178, 2, 65, 44, 3, 66, + 76, 85, 0, 5, 79, 82, 65, 78, 71, 20, 2, 67, 79, 158, 1, 68, 22, 69, 140, + 2, 11, 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 67, 28, 2, 76, 69, 34, 82, + 218, 3, 83, 22, 84, 36, 4, 86, 69, 69, 32, 208, 238, 1, 3, 71, 82, 69, + 34, 72, 138, 4, 80, 154, 79, 78, 202, 203, 2, 70, 83, 81, 6, 226, 167, 4, + 77, 218, 44, 73, 187, 124, 83, 2, 151, 151, 6, 69, 12, 68, 7, 78, 84, 65, + 73, 78, 83, 32, 218, 243, 1, 77, 231, 156, 5, 76, 6, 36, 4, 65, 83, 32, + 77, 175, 1, 87, 2, 11, 69, 2, 11, 77, 2, 251, 161, 7, 66, 2, 235, 243, 1, + 79, 12, 84, 9, 76, 69, 77, 69, 78, 84, 32, 79, 70, 178, 243, 1, 81, 42, + 88, 215, 194, 2, 77, 7, 17, 2, 32, 87, 4, 25, 4, 73, 84, 72, 32, 4, 26, + 86, 223, 196, 4, 79, 2, 181, 192, 5, 21, 69, 82, 84, 73, 67, 65, 76, 32, + 66, 65, 82, 32, 65, 84, 32, 69, 78, 68, 32, 79, 70, 2, 129, 146, 5, 2, + 32, 67, 8, 130, 1, 70, 255, 245, 1, 83, 40, 96, 3, 73, 71, 72, 64, 13, + 79, 77, 65, 78, 32, 78, 85, 77, 69, 82, 65, 76, 32, 155, 201, 5, 69, 6, + 17, 2, 84, 32, 6, 170, 255, 3, 67, 134, 2, 80, 191, 2, 84, 32, 62, 69, + 50, 70, 62, 79, 46, 84, 238, 236, 5, 83, 231, 83, 78, 4, 26, 76, 171, + 176, 7, 73, 2, 255, 237, 5, 69, 8, 26, 73, 251, 225, 6, 79, 6, 154, 26, + 86, 175, 214, 5, 70, 6, 11, 78, 6, 11, 69, 7, 203, 177, 2, 32, 8, 42, 87, + 134, 237, 5, 72, 239, 156, 1, 69, 4, 26, 69, 171, 217, 7, 79, 2, 227, + 220, 6, 76, 2, 183, 163, 4, 69, 4, 178, 235, 3, 87, 211, 215, 1, 73, 2, + 11, 87, 2, 21, 3, 73, 84, 72, 2, 11, 32, 2, 211, 143, 4, 85, 4, 29, 5, + 32, 84, 72, 65, 78, 5, 11, 32, 2, 11, 79, 2, 223, 176, 1, 82, 32, 34, 76, + 161, 207, 6, 2, 82, 75, 30, 40, 4, 73, 78, 71, 32, 255, 214, 7, 69, 28, + 112, 14, 67, 65, 84, 32, 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 65, 10, + 70, 65, 67, 69, 32, 87, 73, 84, 72, 32, 4, 30, 79, 157, 1, 2, 72, 69, 2, + 213, 231, 2, 3, 80, 69, 78, 24, 86, 72, 104, 10, 79, 80, 69, 78, 32, 77, + 79, 85, 84, 72, 178, 2, 83, 159, 205, 2, 84, 6, 34, 69, 50, 79, 207, 177, + 7, 65, 2, 189, 2, 8, 65, 82, 84, 45, 83, 72, 65, 80, 2, 135, 166, 4, 82, + 9, 29, 5, 32, 65, 78, 68, 32, 6, 26, 67, 58, 83, 63, 84, 2, 17, 2, 79, + 76, 2, 253, 174, 3, 4, 68, 32, 83, 87, 2, 11, 77, 2, 11, 73, 2, 11, 76, + 2, 117, 3, 73, 78, 71, 2, 37, 7, 73, 71, 72, 84, 76, 89, 45, 2, 11, 67, + 2, 21, 3, 76, 79, 83, 2, 17, 2, 69, 68, 2, 149, 190, 6, 3, 32, 69, 89, 8, + 64, 11, 77, 73, 76, 73, 78, 71, 32, 69, 89, 69, 83, 175, 1, 85, 7, 29, 5, + 32, 65, 78, 68, 32, 4, 52, 4, 72, 65, 78, 68, 57, 5, 84, 72, 82, 69, 69, + 2, 169, 226, 2, 9, 32, 67, 79, 86, 69, 82, 73, 78, 71, 2, 225, 163, 4, 2, + 32, 72, 2, 17, 2, 78, 71, 2, 241, 187, 6, 4, 76, 65, 83, 83, 2, 195, 183, + 4, 75, 16, 42, 65, 32, 2, 69, 69, 21, 2, 79, 87, 4, 210, 197, 6, 73, 203, + 114, 75, 2, 199, 198, 6, 90, 10, 100, 7, 32, 67, 65, 80, 80, 69, 68, 28, + 3, 77, 65, 78, 212, 203, 2, 3, 66, 79, 65, 195, 144, 1, 70, 2, 233, 135, + 4, 2, 32, 77, 5, 49, 10, 32, 87, 73, 84, 72, 79, 85, 84, 32, 83, 2, 247, + 178, 6, 78, 151, 3, 162, 2, 67, 48, 2, 70, 84, 228, 1, 6, 71, 68, 73, 65, + 78, 32, 244, 10, 3, 76, 73, 68, 140, 2, 12, 79, 78, 32, 87, 73, 84, 72, + 32, 82, 73, 71, 72, 20, 11, 82, 65, 32, 83, 79, 77, 80, 69, 78, 71, 32, + 238, 2, 85, 172, 8, 6, 89, 79, 77, 66, 79, 32, 162, 169, 6, 77, 234, 134, + 1, 72, 3, 83, 4, 128, 214, 2, 3, 67, 69, 82, 247, 182, 4, 75, 10, 70, 32, + 124, 9, 87, 65, 82, 69, 45, 70, 85, 78, 67, 155, 196, 5, 66, 6, 58, 72, + 44, 6, 73, 67, 69, 32, 67, 82, 231, 133, 6, 83, 2, 11, 89, 2, 11, 80, 2, + 135, 248, 5, 72, 2, 171, 143, 6, 69, 2, 11, 84, 2, 251, 211, 5, 73, 84, + 248, 1, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 168, 2, 13, 73, 78, + 68, 69, 80, 69, 78, 68, 69, 78, 84, 32, 83, 20, 7, 76, 69, 84, 84, 69, + 82, 32, 188, 3, 7, 78, 85, 77, 66, 69, 82, 32, 113, 12, 80, 85, 78, 67, + 84, 85, 65, 84, 73, 79, 78, 32, 22, 140, 1, 3, 72, 79, 79, 20, 4, 76, 79, + 78, 71, 50, 83, 58, 84, 242, 213, 3, 68, 216, 199, 1, 4, 82, 69, 83, 72, + 249, 13, 4, 67, 85, 82, 86, 4, 199, 172, 5, 75, 2, 25, 4, 32, 72, 79, 79, + 2, 147, 158, 5, 75, 2, 21, 3, 84, 82, 79, 2, 11, 75, 2, 219, 157, 5, 69, + 4, 189, 208, 1, 2, 87, 79, 2, 211, 196, 6, 72, 42, 190, 1, 65, 50, 71, + 34, 76, 56, 5, 82, 69, 83, 72, 45, 2, 90, 34, 83, 66, 89, 154, 193, 1, + 72, 234, 5, 75, 130, 76, 66, 2, 70, 190, 173, 4, 78, 254, 1, 84, 2, 87, + 202, 103, 80, 171, 4, 77, 4, 26, 76, 231, 194, 6, 89, 2, 215, 200, 1, 69, + 2, 11, 73, 2, 167, 225, 2, 77, 4, 26, 65, 183, 220, 5, 69, 2, 189, 194, + 1, 2, 77, 69, 2, 11, 65, 2, 235, 193, 6, 89, 6, 26, 65, 191, 193, 6, 72, + 4, 178, 185, 1, 77, 187, 218, 5, 68, 2, 195, 193, 1, 79, 8, 18, 79, 59, + 84, 4, 11, 78, 4, 11, 69, 5, 11, 32, 2, 227, 151, 2, 72, 4, 230, 213, 5, + 87, 187, 154, 1, 69, 10, 66, 67, 0, 6, 72, 65, 76, 70, 32, 67, 53, 4, 84, + 87, 79, 32, 2, 21, 3, 73, 82, 67, 2, 201, 193, 4, 2, 76, 69, 6, 100, 13, + 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, 82, 83, 13, 8, 67, 73, 82, + 67, 76, 69, 83, 32, 5, 11, 32, 2, 153, 240, 5, 4, 87, 73, 84, 72, 8, 30, + 32, 189, 1, 2, 85, 83, 4, 93, 21, 81, 85, 73, 76, 84, 32, 83, 81, 85, 65, + 82, 69, 32, 79, 82, 78, 65, 77, 69, 78, 84, 5, 11, 32, 2, 11, 73, 2, 17, + 2, 78, 32, 2, 11, 66, 2, 173, 155, 6, 4, 76, 65, 67, 75, 5, 173, 162, 4, + 7, 32, 87, 73, 84, 72, 32, 79, 2, 251, 227, 3, 84, 70, 52, 7, 76, 69, 84, + 84, 69, 82, 32, 207, 204, 5, 68, 50, 190, 1, 69, 32, 2, 77, 65, 30, 78, + 38, 66, 2, 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, 80, 2, 82, 2, + 83, 2, 84, 2, 86, 2, 89, 186, 183, 7, 65, 2, 73, 2, 79, 3, 85, 4, 150, + 184, 7, 69, 147, 1, 72, 4, 134, 185, 7, 69, 3, 72, 6, 34, 71, 2, 89, 187, + 183, 7, 65, 2, 183, 183, 7, 65, 54, 104, 3, 84, 72, 32, 197, 233, 5, 17, + 78, 68, 32, 82, 69, 67, 79, 82, 68, 73, 78, 71, 32, 67, 79, 80, 89, 52, + 60, 5, 69, 65, 83, 84, 32, 237, 2, 5, 87, 69, 83, 84, 32, 28, 96, 5, 65, + 82, 82, 79, 87, 162, 4, 80, 130, 1, 84, 246, 160, 4, 66, 38, 68, 18, 83, + 203, 43, 87, 11, 11, 32, 8, 52, 2, 65, 78, 38, 67, 120, 2, 84, 79, 139, + 2, 87, 2, 237, 2, 5, 68, 32, 83, 79, 85, 2, 37, 7, 82, 79, 83, 83, 73, + 78, 71, 2, 17, 2, 32, 78, 2, 17, 2, 79, 82, 2, 221, 209, 4, 5, 84, 72, + 32, 69, 65, 2, 17, 2, 32, 67, 2, 239, 219, 3, 79, 24, 96, 5, 65, 82, 82, + 79, 87, 182, 1, 80, 130, 1, 84, 246, 160, 4, 66, 38, 68, 18, 83, 203, 43, + 87, 7, 11, 32, 4, 36, 5, 65, 78, 68, 32, 78, 75, 87, 2, 17, 2, 79, 82, 2, + 21, 3, 84, 72, 32, 2, 201, 207, 4, 2, 87, 69, 2, 21, 3, 73, 84, 72, 2, + 11, 32, 2, 183, 225, 5, 72, 6, 41, 8, 79, 73, 78, 84, 73, 78, 71, 32, 6, + 42, 86, 154, 253, 3, 76, 215, 137, 2, 66, 2, 17, 2, 73, 78, 2, 239, 252, + 3, 69, 4, 89, 20, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 68, + 32, 65, 82, 82, 79, 87, 5, 11, 32, 2, 147, 214, 4, 84, 166, 1, 212, 3, + 23, 67, 76, 85, 83, 84, 69, 82, 45, 73, 78, 73, 84, 73, 65, 76, 32, 76, + 69, 84, 84, 69, 82, 32, 40, 21, 70, 73, 78, 65, 76, 32, 67, 79, 78, 83, + 79, 78, 65, 78, 84, 32, 83, 73, 71, 78, 32, 114, 71, 32, 27, 72, 69, 65, + 68, 32, 77, 65, 82, 75, 32, 87, 73, 84, 72, 32, 77, 79, 79, 78, 32, 65, + 78, 68, 32, 83, 85, 78, 104, 7, 76, 69, 84, 84, 69, 82, 32, 180, 1, 5, + 77, 65, 82, 75, 32, 54, 83, 100, 8, 84, 69, 82, 77, 73, 78, 65, 76, 41, + 6, 86, 79, 87, 69, 76, 32, 8, 246, 228, 6, 83, 254, 68, 76, 3, 82, 24, + 162, 184, 3, 83, 206, 251, 1, 78, 222, 245, 1, 45, 186, 2, 66, 2, 68, 2, + 71, 2, 75, 2, 76, 2, 77, 3, 82, 2, 157, 166, 6, 3, 69, 77, 73, 7, 29, 5, + 32, 65, 78, 68, 32, 4, 50, 70, 1, 8, 84, 82, 73, 80, 76, 69, 32, 70, 2, + 187, 158, 5, 76, 82, 234, 174, 2, 68, 206, 178, 4, 75, 38, 78, 46, 83, + 38, 84, 46, 66, 2, 67, 2, 71, 2, 74, 2, 80, 2, 90, 254, 68, 45, 2, 72, 2, + 76, 2, 77, 2, 82, 2, 86, 2, 89, 187, 2, 65, 8, 158, 153, 3, 80, 214, 200, + 3, 68, 58, 83, 63, 84, 10, 40, 4, 73, 71, 78, 32, 211, 229, 6, 85, 8, + 146, 246, 4, 74, 158, 2, 86, 122, 85, 231, 233, 1, 65, 4, 233, 247, 1, 5, + 32, 77, 65, 82, 75, 22, 44, 5, 83, 73, 71, 78, 32, 251, 228, 6, 76, 20, + 88, 7, 86, 79, 67, 65, 76, 73, 67, 226, 229, 6, 65, 26, 79, 2, 85, 150, + 64, 69, 3, 73, 4, 11, 32, 4, 254, 165, 7, 76, 3, 82, 61, 166, 1, 65, 142, + 1, 69, 136, 5, 13, 72, 69, 82, 73, 67, 65, 76, 32, 65, 78, 71, 76, 69, + 82, 73, 220, 1, 12, 76, 65, 83, 72, 73, 78, 71, 32, 83, 87, 69, 65, 23, + 79, 13, 60, 4, 71, 72, 69, 84, 20, 3, 82, 75, 76, 151, 141, 7, 67, 2, + 163, 144, 7, 84, 6, 26, 73, 239, 159, 5, 69, 2, 165, 156, 6, 2, 78, 71, + 18, 52, 2, 65, 75, 250, 3, 69, 69, 4, 83, 77, 73, 76, 12, 70, 45, 64, 2, + 69, 82, 173, 2, 8, 73, 78, 71, 32, 72, 69, 65, 68, 2, 221, 139, 5, 11, + 78, 79, 45, 69, 86, 73, 76, 32, 77, 79, 78, 9, 33, 6, 32, 87, 73, 84, 72, + 32, 6, 26, 67, 78, 79, 75, 84, 2, 33, 6, 65, 78, 67, 69, 76, 76, 2, 245, + 240, 6, 5, 65, 84, 73, 79, 78, 2, 41, 8, 78, 69, 32, 83, 79, 85, 78, 68, + 2, 133, 184, 5, 2, 32, 87, 2, 25, 4, 72, 82, 69, 69, 2, 157, 140, 6, 10, + 32, 83, 79, 85, 78, 68, 32, 87, 65, 86, 2, 11, 32, 2, 245, 218, 5, 9, 73, + 78, 32, 83, 73, 76, 72, 79, 85, 4, 34, 68, 241, 232, 2, 2, 67, 72, 2, 11, + 66, 2, 255, 138, 6, 79, 2, 211, 151, 6, 79, 7, 45, 9, 32, 79, 80, 69, 78, + 73, 78, 71, 32, 4, 138, 243, 6, 76, 227, 42, 85, 10, 44, 3, 68, 69, 82, + 41, 4, 82, 65, 76, 32, 5, 17, 2, 32, 87, 2, 239, 226, 5, 69, 6, 80, 8, + 67, 65, 76, 69, 78, 68, 65, 82, 0, 4, 78, 79, 84, 69, 29, 2, 83, 72, 2, + 137, 214, 6, 2, 32, 80, 2, 223, 151, 5, 69, 2, 235, 136, 6, 84, 10, 90, + 79, 60, 7, 85, 84, 73, 78, 71, 32, 87, 128, 228, 2, 3, 82, 84, 83, 223, + 130, 3, 78, 4, 144, 84, 7, 76, 32, 79, 70, 32, 84, 72, 251, 198, 6, 78, + 2, 11, 72, 2, 159, 249, 5, 65, 206, 5, 26, 65, 255, 211, 6, 73, 204, 5, + 28, 2, 82, 69, 175, 66, 84, 202, 5, 30, 32, 129, 44, 2, 68, 32, 218, 3, + 246, 1, 65, 116, 2, 86, 32, 58, 66, 158, 1, 67, 170, 1, 68, 102, 69, 194, + 2, 70, 74, 71, 222, 1, 72, 214, 2, 73, 94, 75, 206, 4, 76, 102, 77, 210, + 5, 78, 94, 79, 178, 1, 80, 222, 3, 82, 154, 3, 83, 186, 1, 84, 74, 87, + 218, 6, 89, 175, 158, 6, 85, 14, 114, 32, 152, 71, 2, 78, 80, 236, 142, + 2, 3, 82, 85, 72, 238, 51, 65, 240, 43, 2, 80, 65, 250, 224, 3, 77, 3, + 85, 2, 21, 3, 79, 86, 69, 2, 11, 82, 2, 219, 133, 7, 32, 14, 98, 65, 36, + 4, 85, 83, 83, 89, 178, 136, 3, 73, 212, 64, 2, 79, 82, 202, 39, 69, 207, + 164, 3, 81, 4, 32, 2, 65, 82, 155, 149, 7, 82, 2, 175, 136, 3, 69, 22, + 98, 65, 30, 79, 230, 18, 77, 204, 128, 7, 7, 32, 79, 86, 69, 82, 32, 75, + 74, 85, 14, 67, 3, 68, 4, 158, 148, 7, 76, 3, 80, 5, 17, 2, 82, 80, 2, + 247, 181, 2, 79, 20, 82, 65, 234, 17, 77, 142, 195, 2, 69, 174, 49, 79, + 234, 140, 4, 66, 2, 74, 3, 76, 5, 207, 20, 65, 18, 66, 69, 22, 82, 236, + 23, 5, 83, 85, 75, 85, 85, 183, 250, 6, 86, 2, 235, 162, 5, 75, 12, 52, + 7, 65, 32, 78, 65, 77, 69, 32, 235, 145, 7, 71, 10, 132, 1, 4, 72, 69, + 73, 83, 20, 5, 84, 65, 73, 83, 89, 224, 20, 3, 77, 69, 73, 240, 182, 2, + 3, 82, 69, 73, 1, 4, 83, 89, 79, 85, 2, 135, 253, 6, 69, 2, 227, 235, 6, + 79, 6, 26, 79, 159, 144, 7, 77, 4, 128, 226, 5, 2, 85, 82, 239, 145, 1, + 79, 24, 102, 65, 46, 73, 188, 12, 5, 85, 82, 65, 77, 85, 178, 139, 3, 72, + 186, 244, 3, 80, 186, 2, 66, 3, 89, 6, 166, 191, 6, 82, 210, 46, 78, 147, + 33, 76, 6, 42, 82, 150, 210, 4, 78, 231, 185, 2, 71, 2, 229, 158, 5, 2, + 85, 68, 30, 130, 1, 65, 22, 69, 54, 79, 62, 85, 226, 202, 1, 80, 196, + 184, 5, 10, 73, 82, 65, 71, 65, 78, 65, 32, 72, 79, 234, 8, 71, 3, 90, 5, + 207, 232, 1, 73, 4, 184, 11, 3, 75, 85, 84, 129, 221, 1, 2, 82, 85, 6, + 26, 79, 175, 140, 7, 78, 4, 194, 231, 6, 82, 235, 36, 78, 6, 54, 73, 160, + 17, 4, 65, 82, 65, 68, 131, 179, 5, 82, 2, 203, 191, 3, 73, 14, 54, 78, + 228, 12, 4, 77, 65, 71, 69, 167, 254, 6, 85, 7, 190, 199, 2, 73, 243, + 175, 4, 84, 58, 230, 1, 65, 64, 2, 89, 85, 20, 3, 73, 82, 79, 78, 77, 90, + 79, 60, 2, 85, 82, 144, 8, 2, 69, 69, 202, 135, 3, 72, 202, 237, 2, 67, + 208, 120, 3, 32, 79, 72, 162, 14, 80, 186, 2, 66, 2, 71, 2, 75, 2, 76, 2, + 84, 2, 86, 3, 87, 9, 18, 73, 23, 82, 2, 143, 245, 6, 82, 4, 22, 79, 143, + 20, 65, 2, 159, 204, 4, 82, 9, 252, 16, 3, 77, 69, 69, 248, 2, 2, 87, 65, + 169, 161, 2, 3, 71, 85, 82, 9, 11, 32, 6, 22, 67, 199, 14, 83, 4, 22, 65, + 179, 6, 85, 2, 209, 185, 4, 2, 80, 73, 4, 18, 79, 23, 82, 2, 251, 231, 6, + 80, 2, 151, 204, 5, 85, 4, 176, 154, 5, 4, 85, 90, 69, 73, 239, 66, 79, + 12, 62, 79, 244, 13, 2, 69, 70, 230, 247, 6, 77, 2, 78, 3, 88, 4, 202, + 209, 5, 90, 143, 180, 1, 71, 82, 162, 1, 32, 70, 65, 122, 66, 22, 69, 54, + 73, 110, 77, 68, 2, 85, 32, 78, 86, 2, 87, 162, 137, 3, 72, 214, 237, 2, + 79, 230, 134, 1, 80, 186, 2, 71, 2, 76, 3, 83, 10, 34, 79, 242, 2, 67, + 139, 8, 83, 6, 198, 10, 86, 207, 232, 6, 72, 13, 54, 73, 44, 2, 78, 83, + 146, 82, 82, 159, 185, 4, 72, 4, 252, 150, 5, 2, 75, 85, 175, 199, 1, 82, + 2, 135, 179, 6, 89, 5, 243, 160, 2, 32, 6, 28, 2, 71, 65, 251, 10, 69, 5, + 191, 178, 6, 84, 8, 42, 75, 20, 2, 82, 73, 207, 129, 7, 76, 2, 211, 221, + 5, 85, 5, 11, 66, 2, 11, 65, 2, 203, 244, 2, 65, 7, 11, 32, 4, 22, 67, + 139, 8, 83, 2, 11, 85, 2, 175, 161, 2, 66, 16, 218, 128, 7, 65, 2, 70, 2, + 71, 2, 76, 2, 77, 2, 83, 2, 86, 3, 87, 5, 11, 32, 2, 11, 77, 2, 191, 189, + 6, 69, 16, 70, 65, 238, 10, 79, 178, 244, 6, 70, 2, 77, 2, 83, 2, 86, 3, + 87, 5, 167, 224, 6, 78, 12, 78, 78, 20, 7, 82, 73, 71, 73, 78, 65, 76, + 170, 171, 2, 79, 255, 210, 4, 86, 2, 207, 217, 6, 83, 6, 21, 3, 32, 79, + 70, 7, 25, 4, 32, 79, 82, 32, 4, 214, 86, 78, 51, 69, 46, 118, 65, 82, + 69, 94, 73, 74, 79, 150, 234, 6, 80, 218, 16, 67, 2, 70, 2, 72, 2, 77, 2, + 82, 2, 83, 2, 86, 3, 87, 9, 38, 65, 221, 220, 3, 3, 32, 65, 77, 4, 236, + 1, 2, 83, 69, 227, 213, 6, 84, 8, 34, 69, 22, 78, 231, 220, 6, 83, 2, + 147, 232, 6, 90, 4, 230, 215, 1, 73, 139, 255, 4, 83, 6, 34, 75, 233, 3, + 3, 65, 83, 85, 4, 166, 238, 2, 85, 235, 140, 4, 79, 6, 34, 73, 22, 78, + 21, 2, 83, 73, 2, 191, 174, 3, 78, 2, 191, 219, 6, 68, 2, 133, 193, 6, 4, + 84, 73, 79, 78, 22, 60, 2, 65, 68, 114, 69, 62, 73, 134, 1, 85, 227, 166, + 6, 79, 7, 21, 3, 32, 79, 86, 4, 25, 4, 69, 82, 32, 83, 5, 17, 2, 32, 83, + 2, 11, 81, 2, 153, 153, 2, 2, 85, 65, 4, 36, 3, 78, 84, 79, 191, 211, 6, + 77, 2, 175, 167, 5, 71, 6, 40, 2, 71, 72, 62, 84, 243, 244, 6, 82, 2, + 181, 205, 3, 10, 84, 32, 79, 80, 69, 78, 32, 66, 79, 88, 2, 189, 234, 2, + 2, 84, 79, 4, 172, 1, 2, 85, 66, 195, 185, 4, 80, 14, 82, 65, 72, 3, 69, + 78, 84, 128, 178, 2, 3, 73, 82, 73, 202, 195, 4, 82, 3, 86, 4, 48, 2, 73, + 75, 225, 162, 2, 4, 78, 84, 73, 73, 2, 243, 232, 2, 85, 4, 198, 245, 6, + 73, 3, 79, 6, 42, 65, 146, 254, 2, 72, 159, 167, 3, 79, 2, 241, 191, 6, + 2, 82, 71, 34, 50, 65, 20, 4, 73, 84, 72, 32, 159, 244, 6, 66, 2, 167, + 168, 3, 84, 30, 222, 1, 66, 40, 3, 68, 73, 65, 0, 5, 79, 82, 84, 72, 79, + 84, 2, 72, 79, 42, 76, 126, 84, 28, 6, 85, 80, 80, 69, 82, 32, 186, 1, + 86, 190, 227, 3, 82, 225, 241, 1, 13, 67, 79, 78, 84, 79, 85, 82, 69, 68, + 32, 79, 85, 84, 2, 209, 231, 3, 5, 79, 84, 84, 79, 77, 2, 165, 129, 4, + 16, 71, 79, 78, 65, 76, 32, 67, 82, 79, 83, 83, 72, 65, 84, 67, 72, 2, + 149, 3, 6, 82, 73, 90, 79, 78, 84, 6, 44, 5, 79, 87, 69, 82, 32, 211, + 229, 3, 69, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 189, 1, 3, 84, + 32, 68, 2, 177, 229, 3, 2, 79, 80, 8, 60, 5, 76, 69, 70, 84, 32, 37, 6, + 82, 73, 71, 72, 84, 32, 4, 70, 68, 253, 241, 3, 2, 84, 79, 4, 34, 68, + 205, 253, 3, 2, 84, 79, 2, 141, 228, 3, 7, 73, 65, 71, 79, 78, 65, 76, 2, + 29, 5, 69, 82, 84, 73, 67, 2, 185, 253, 3, 2, 65, 76, 6, 32, 2, 65, 65, + 183, 166, 5, 85, 4, 254, 200, 6, 82, 247, 5, 68, 240, 1, 226, 1, 67, 174, + 9, 68, 34, 70, 88, 3, 82, 73, 83, 142, 1, 72, 66, 75, 106, 76, 166, 1, + 77, 38, 78, 34, 79, 94, 80, 34, 83, 190, 2, 84, 156, 1, 5, 69, 73, 71, + 72, 84, 22, 85, 90, 86, 166, 199, 4, 65, 222, 105, 87, 207, 96, 73, 90, + 128, 1, 21, 74, 75, 32, 85, 78, 73, 70, 73, 69, 68, 32, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 134, 216, 5, 79, 219, 146, 1, 76, 86, 68, 2, 52, + 69, 82, 53, 206, 2, 54, 150, 2, 55, 166, 1, 56, 95, 57, 10, 50, 48, 234, + 4, 65, 154, 190, 5, 56, 207, 96, 50, 4, 222, 233, 6, 48, 3, 57, 30, 150, + 1, 50, 42, 51, 38, 52, 48, 2, 53, 66, 0, 2, 68, 69, 22, 57, 164, 4, 2, + 56, 70, 162, 143, 3, 66, 248, 172, 2, 2, 70, 56, 205, 96, 2, 49, 56, 6, + 214, 4, 55, 194, 157, 6, 49, 3, 52, 4, 150, 148, 3, 70, 143, 173, 2, 67, + 4, 26, 48, 159, 148, 3, 51, 2, 195, 231, 6, 56, 2, 175, 231, 6, 54, 4, + 242, 147, 3, 50, 243, 208, 3, 49, 24, 86, 50, 46, 51, 50, 53, 34, 54, 16, + 2, 55, 48, 28, 2, 70, 49, 129, 2, 2, 69, 56, 6, 70, 57, 238, 145, 3, 53, + 203, 153, 2, 52, 4, 26, 53, 199, 146, 3, 48, 2, 215, 229, 6, 53, 4, 202, + 2, 66, 211, 143, 3, 57, 2, 171, 2, 50, 4, 146, 229, 6, 56, 3, 57, 2, 247, + 228, 6, 52, 12, 74, 53, 38, 57, 12, 2, 49, 50, 20, 2, 68, 52, 157, 225, + 6, 2, 65, 55, 4, 170, 144, 3, 51, 227, 210, 2, 49, 2, 11, 56, 2, 231, + 227, 6, 49, 2, 211, 227, 6, 50, 6, 50, 57, 20, 2, 68, 55, 209, 143, 3, 2, + 67, 65, 2, 159, 143, 3, 69, 2, 247, 226, 6, 48, 4, 204, 156, 6, 2, 49, + 52, 221, 67, 2, 48, 52, 2, 11, 79, 2, 251, 183, 3, 84, 10, 84, 3, 65, 76, + 76, 104, 4, 79, 85, 82, 32, 240, 5, 3, 73, 86, 69, 179, 238, 4, 82, 2, + 57, 12, 73, 78, 71, 32, 68, 73, 65, 71, 79, 78, 65, 76, 2, 11, 32, 2, 11, + 83, 2, 191, 251, 4, 76, 4, 210, 179, 3, 68, 131, 173, 3, 75, 8, 192, 181, + 3, 2, 73, 45, 158, 242, 2, 68, 210, 56, 67, 3, 86, 8, 56, 8, 65, 84, 65, + 75, 65, 78, 65, 32, 239, 205, 6, 69, 6, 150, 172, 6, 75, 202, 28, 68, + 159, 20, 83, 60, 36, 5, 65, 84, 73, 78, 32, 79, 79, 54, 164, 5, 12, 83, + 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 227, 112, 67, 6, 178, 178, 3, + 71, 157, 149, 2, 3, 83, 83, 76, 4, 234, 218, 4, 73, 251, 130, 2, 86, 4, + 174, 223, 5, 69, 147, 126, 71, 4, 140, 3, 15, 78, 69, 32, 72, 85, 78, 68, + 82, 69, 68, 32, 84, 87, 69, 78, 147, 218, 6, 75, 4, 158, 2, 80, 187, 215, + 4, 76, 20, 110, 69, 146, 1, 72, 20, 2, 73, 88, 198, 200, 4, 65, 150, 66, + 77, 130, 47, 81, 234, 98, 79, 210, 61, 68, 3, 83, 4, 56, 7, 67, 79, 78, + 68, 32, 83, 67, 21, 3, 86, 69, 78, 2, 247, 137, 5, 82, 2, 29, 5, 32, 80, + 79, 73, 78, 2, 11, 84, 2, 143, 177, 5, 32, 2, 163, 218, 6, 86, 2, 17, 2, + 84, 89, 2, 239, 217, 6, 32, 8, 44, 4, 72, 82, 69, 69, 22, 87, 243, 4, 73, + 2, 163, 147, 6, 32, 4, 68, 13, 69, 78, 84, 89, 45, 84, 87, 79, 32, 80, + 79, 73, 78, 19, 79, 2, 215, 75, 84, 2, 179, 213, 6, 32, 4, 48, 6, 80, 32, + 87, 73, 84, 72, 243, 145, 6, 72, 2, 17, 2, 32, 69, 2, 235, 108, 88, 4, + 202, 145, 6, 79, 151, 70, 83, 2, 201, 183, 5, 6, 32, 66, 76, 65, 67, 75, + 6, 146, 215, 6, 50, 2, 51, 3, 65, 85, 134, 1, 65, 138, 7, 69, 236, 1, 10, + 73, 67, 75, 32, 70, 73, 71, 85, 82, 69, 182, 1, 79, 90, 82, 234, 2, 85, + 130, 200, 6, 83, 3, 88, 38, 92, 6, 70, 70, 32, 79, 70, 32, 106, 77, 80, + 2, 78, 68, 90, 82, 206, 3, 84, 175, 167, 5, 68, 4, 60, 8, 65, 69, 83, 67, + 85, 76, 65, 80, 21, 3, 72, 69, 82, 2, 219, 209, 4, 73, 2, 211, 192, 5, + 77, 2, 21, 3, 80, 69, 68, 2, 17, 2, 32, 69, 2, 173, 210, 1, 4, 78, 86, + 69, 76, 2, 21, 3, 73, 78, 71, 2, 17, 2, 32, 80, 2, 11, 69, 2, 11, 82, 2, + 171, 131, 6, 83, 24, 42, 32, 205, 1, 5, 84, 32, 79, 70, 32, 12, 82, 69, + 54, 79, 240, 224, 1, 8, 65, 78, 68, 32, 67, 82, 69, 83, 131, 229, 1, 87, + 2, 17, 2, 81, 85, 2, 11, 65, 2, 135, 148, 6, 76, 4, 44, 5, 70, 32, 68, + 65, 86, 143, 167, 3, 80, 2, 255, 138, 6, 73, 12, 66, 71, 30, 83, 40, 4, + 80, 82, 79, 84, 142, 66, 72, 155, 102, 84, 2, 89, 4, 85, 65, 82, 68, 4, + 26, 69, 155, 239, 1, 84, 2, 11, 76, 2, 21, 3, 69, 67, 84, 2, 29, 5, 69, + 68, 32, 65, 82, 2, 135, 205, 6, 69, 4, 144, 229, 4, 10, 85, 69, 32, 79, + 70, 32, 76, 73, 66, 69, 187, 154, 1, 73, 8, 92, 2, 65, 77, 112, 9, 78, + 79, 71, 82, 65, 80, 72, 73, 67, 193, 203, 1, 4, 84, 72, 79, 83, 4, 54, + 32, 173, 196, 5, 7, 73, 78, 71, 32, 66, 79, 87, 2, 33, 6, 76, 79, 67, 79, + 77, 79, 2, 135, 197, 1, 84, 2, 137, 130, 4, 2, 32, 70, 11, 11, 32, 8, 60, + 5, 87, 73, 84, 72, 32, 193, 153, 2, 4, 76, 69, 65, 78, 4, 32, 4, 65, 82, + 77, 83, 51, 68, 2, 25, 4, 32, 82, 65, 73, 2, 167, 236, 1, 83, 2, 143, + 181, 5, 82, 4, 44, 4, 67, 75, 32, 67, 21, 3, 80, 87, 65, 2, 139, 196, 5, + 72, 2, 211, 168, 6, 84, 12, 66, 65, 108, 10, 69, 83, 83, 32, 79, 85, 84, + 76, 73, 78, 79, 73, 6, 44, 4, 73, 71, 72, 84, 45, 3, 87, 66, 69, 4, 188, + 130, 3, 2, 32, 82, 243, 176, 2, 78, 2, 147, 61, 82, 2, 17, 2, 69, 68, 2, + 17, 2, 32, 87, 2, 145, 182, 4, 4, 72, 73, 84, 69, 4, 52, 4, 78, 71, 32, + 84, 233, 7, 4, 67, 84, 76, 89, 2, 17, 2, 69, 82, 2, 169, 143, 6, 3, 77, + 73, 78, 6, 100, 8, 68, 73, 79, 32, 77, 73, 67, 82, 20, 9, 70, 70, 69, 68, + 32, 70, 76, 65, 84, 207, 196, 6, 80, 2, 215, 157, 5, 79, 2, 11, 66, 2, + 231, 248, 3, 82, 202, 2, 150, 1, 66, 196, 2, 5, 67, 67, 69, 69, 68, 192, + 3, 8, 77, 77, 65, 84, 73, 79, 78, 32, 70, 78, 132, 15, 3, 80, 69, 82, + 148, 11, 2, 82, 70, 47, 83, 63, 11, 83, 60, 72, 6, 67, 82, 73, 80, 84, + 32, 124, 3, 69, 84, 32, 93, 3, 84, 73, 84, 30, 222, 22, 69, 162, 1, 80, + 150, 208, 2, 77, 202, 1, 76, 26, 82, 222, 237, 1, 70, 30, 83, 42, 84, 62, + 90, 130, 83, 78, 15, 79, 28, 56, 6, 65, 66, 79, 86, 69, 32, 246, 25, 79, + 159, 3, 87, 6, 142, 24, 83, 203, 139, 5, 82, 2, 235, 254, 4, 85, 22, 11, + 83, 23, 11, 32, 20, 128, 1, 6, 65, 66, 79, 86, 69, 32, 156, 1, 7, 66, 85, + 84, 32, 78, 79, 84, 32, 2, 79, 82, 229, 255, 2, 5, 85, 78, 68, 69, 82, + 12, 100, 4, 78, 79, 84, 32, 28, 12, 83, 73, 78, 71, 76, 69, 45, 76, 73, + 78, 69, 32, 218, 24, 65, 39, 69, 4, 242, 24, 65, 167, 1, 69, 4, 250, 24, + 69, 83, 78, 2, 93, 5, 32, 69, 81, 85, 73, 4, 17, 2, 32, 69, 4, 17, 2, 81, + 85, 4, 22, 73, 167, 25, 65, 2, 173, 25, 6, 86, 65, 76, 69, 78, 84, 6, + 202, 246, 2, 66, 228, 196, 1, 4, 87, 73, 84, 72, 147, 139, 1, 84, 161, 1, + 166, 1, 32, 72, 7, 68, 65, 78, 69, 83, 69, 32, 200, 12, 4, 82, 73, 83, + 69, 200, 166, 2, 14, 83, 69, 84, 32, 79, 86, 69, 82, 32, 66, 85, 73, 76, + 68, 255, 240, 2, 70, 4, 50, 87, 197, 146, 5, 6, 66, 69, 72, 73, 78, 68, + 2, 247, 255, 5, 73, 146, 1, 198, 2, 65, 20, 17, 67, 79, 78, 83, 79, 78, + 65, 78, 84, 32, 83, 73, 71, 78, 32, 80, 65, 172, 1, 7, 76, 69, 84, 84, + 69, 82, 32, 188, 3, 18, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, + 66, 73, 78, 68, 85, 32, 228, 1, 5, 83, 73, 71, 78, 32, 200, 1, 13, 86, + 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 80, 65, 255, 195, 4, 68, 2, 235, + 211, 2, 86, 10, 68, 2, 77, 73, 40, 2, 78, 89, 33, 7, 83, 65, 78, 71, 65, + 78, 32, 2, 17, 2, 78, 71, 2, 167, 176, 5, 75, 4, 142, 5, 65, 163, 146, 1, + 73, 4, 226, 182, 6, 77, 3, 87, 76, 246, 1, 65, 58, 70, 78, 76, 2, 82, 34, + 83, 202, 230, 2, 69, 246, 215, 1, 78, 246, 175, 1, 66, 2, 75, 254, 68, + 67, 2, 68, 2, 71, 2, 72, 2, 74, 2, 77, 2, 80, 2, 81, 2, 84, 2, 86, 2, 87, + 2, 88, 2, 89, 2, 90, 186, 2, 73, 2, 79, 3, 85, 7, 128, 247, 5, 6, 82, 67, + 72, 65, 73, 67, 135, 64, 69, 6, 44, 5, 73, 78, 65, 76, 32, 163, 182, 6, + 65, 4, 158, 182, 6, 75, 3, 77, 4, 154, 145, 6, 69, 235, 36, 65, 4, 170, + 179, 6, 89, 187, 2, 65, 16, 90, 66, 2, 68, 2, 75, 12, 3, 76, 69, 85, 38, + 67, 34, 80, 189, 177, 6, 3, 83, 85, 82, 2, 11, 65, 2, 137, 94, 5, 32, 83, + 65, 84, 65, 2, 11, 65, 2, 247, 239, 5, 75, 4, 168, 3, 3, 65, 78, 71, 141, + 238, 5, 3, 85, 82, 78, 10, 28, 2, 80, 65, 211, 82, 86, 8, 28, 3, 77, 65, + 65, 23, 78, 2, 143, 178, 6, 69, 6, 18, 71, 71, 89, 4, 38, 76, 177, 236, + 5, 3, 87, 73, 83, 2, 165, 144, 5, 2, 65, 89, 2, 141, 175, 6, 2, 69, 67, + 12, 18, 77, 23, 78, 2, 179, 244, 2, 69, 10, 96, 3, 69, 85, 76, 34, 79, + 22, 89, 140, 220, 1, 3, 71, 72, 85, 157, 152, 2, 4, 65, 69, 76, 65, 2, + 11, 69, 2, 147, 224, 5, 85, 2, 139, 244, 3, 76, 2, 203, 142, 1, 85, 5, + 173, 130, 3, 13, 32, 79, 86, 69, 82, 32, 77, 79, 85, 78, 84, 65, 73, 72, + 54, 83, 166, 195, 4, 72, 241, 64, 4, 86, 73, 76, 76, 68, 56, 6, 67, 82, + 73, 80, 84, 32, 173, 2, 3, 69, 84, 32, 34, 118, 69, 34, 76, 130, 1, 80, + 150, 208, 2, 77, 226, 1, 82, 222, 237, 1, 70, 30, 83, 42, 84, 62, 90, + 130, 83, 78, 15, 79, 4, 226, 66, 81, 235, 192, 5, 73, 6, 96, 18, 65, 84, + 73, 78, 32, 83, 77, 65, 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 135, 210, + 2, 69, 4, 138, 173, 6, 73, 3, 78, 2, 155, 147, 3, 76, 34, 148, 1, 6, 65, + 66, 79, 86, 69, 32, 96, 7, 66, 69, 83, 73, 68, 69, 32, 162, 1, 79, 158, + 3, 87, 153, 148, 4, 9, 80, 82, 69, 67, 69, 68, 73, 78, 71, 6, 26, 83, + 231, 187, 2, 76, 4, 11, 85, 4, 26, 80, 191, 194, 4, 66, 2, 185, 194, 4, + 2, 69, 82, 4, 108, 23, 65, 78, 68, 32, 74, 79, 73, 78, 69, 68, 32, 66, + 89, 32, 68, 65, 83, 72, 32, 87, 73, 84, 72, 23, 83, 2, 17, 2, 32, 83, 2, + 153, 193, 4, 2, 85, 66, 16, 11, 70, 17, 11, 32, 14, 120, 6, 65, 66, 79, + 86, 69, 32, 132, 1, 4, 87, 73, 84, 72, 181, 166, 5, 11, 79, 82, 32, 69, + 81, 85, 65, 76, 32, 84, 79, 8, 34, 65, 38, 69, 18, 84, 67, 78, 2, 11, 76, + 2, 113, 3, 77, 79, 83, 2, 187, 60, 81, 2, 21, 3, 73, 76, 68, 2, 147, 253, + 2, 69, 2, 17, 2, 32, 78, 2, 11, 79, 2, 11, 84, 2, 11, 32, 2, 11, 69, 2, + 17, 2, 81, 85, 2, 11, 65, 2, 11, 76, 2, 179, 218, 2, 32, 6, 25, 4, 73, + 84, 72, 32, 6, 96, 2, 80, 76, 24, 14, 77, 85, 76, 84, 73, 80, 76, 73, 67, + 65, 84, 73, 79, 78, 231, 212, 5, 68, 2, 11, 85, 2, 11, 83, 2, 169, 254, + 3, 5, 32, 83, 73, 71, 78, 4, 196, 160, 4, 2, 65, 67, 211, 203, 1, 69, 4, + 60, 9, 80, 69, 78, 83, 73, 79, 78, 32, 82, 167, 144, 6, 72, 2, 21, 3, 65, + 73, 76, 2, 247, 151, 5, 87, 8, 26, 65, 98, 73, 35, 85, 4, 44, 5, 83, 72, + 32, 65, 77, 135, 163, 6, 78, 2, 173, 223, 5, 7, 80, 69, 82, 83, 65, 78, + 68, 2, 11, 77, 2, 231, 228, 5, 77, 2, 129, 250, 2, 2, 78, 71, 230, 2, 92, + 11, 76, 79, 84, 73, 32, 78, 65, 71, 82, 73, 32, 226, 5, 77, 182, 15, 78, + 97, 2, 82, 73, 90, 180, 1, 7, 76, 69, 84, 84, 69, 82, 32, 168, 2, 11, 80, + 79, 69, 84, 82, 89, 32, 77, 65, 82, 75, 56, 5, 83, 73, 71, 78, 32, 145, + 1, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 64, 174, 1, 68, 46, + 82, 34, 84, 154, 89, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 246, 165, 5, + 72, 2, 76, 2, 77, 2, 78, 2, 83, 246, 30, 65, 2, 69, 2, 73, 2, 79, 3, 85, + 8, 226, 89, 68, 246, 165, 5, 72, 247, 30, 79, 4, 170, 255, 5, 82, 247, + 30, 79, 8, 150, 89, 84, 246, 165, 5, 72, 247, 30, 79, 8, 11, 45, 8, 198, + 157, 6, 49, 2, 50, 2, 51, 3, 52, 8, 46, 65, 70, 72, 213, 215, 5, 3, 68, + 86, 73, 4, 64, 10, 76, 84, 69, 82, 78, 65, 84, 69, 32, 72, 203, 215, 5, + 78, 2, 129, 137, 2, 2, 65, 83, 10, 150, 253, 5, 79, 246, 30, 65, 2, 69, + 2, 73, 3, 85, 82, 60, 8, 66, 79, 76, 32, 70, 79, 82, 32, 213, 14, 2, 77, + 69, 80, 238, 2, 66, 48, 2, 67, 65, 118, 68, 222, 1, 69, 130, 2, 70, 56, + 8, 72, 79, 82, 73, 90, 79, 78, 84, 0, 6, 86, 69, 82, 84, 73, 67, 44, 3, + 76, 73, 78, 52, 9, 77, 65, 82, 75, 83, 32, 67, 72, 65, 22, 78, 90, 65, + 68, 3, 82, 69, 67, 32, 5, 71, 82, 79, 85, 80, 0, 4, 85, 78, 73, 84, 22, + 83, 205, 3, 15, 84, 89, 80, 69, 32, 65, 32, 69, 76, 69, 67, 84, 82, 79, + 78, 4, 242, 147, 4, 69, 133, 198, 1, 3, 65, 67, 75, 4, 44, 3, 82, 82, 73, + 237, 182, 1, 2, 78, 67, 2, 33, 6, 65, 71, 69, 32, 82, 69, 2, 11, 84, 2, + 135, 185, 1, 85, 14, 24, 2, 65, 84, 55, 69, 2, 161, 3, 9, 65, 32, 76, 73, + 78, 75, 32, 69, 83, 12, 76, 12, 86, 73, 67, 69, 32, 67, 79, 78, 84, 82, + 79, 76, 157, 8, 2, 76, 69, 8, 11, 32, 8, 222, 174, 1, 70, 154, 250, 2, + 84, 203, 83, 79, 12, 22, 78, 207, 1, 83, 10, 48, 5, 68, 32, 79, 70, 32, + 137, 1, 2, 81, 85, 8, 18, 77, 31, 84, 2, 193, 236, 4, 2, 69, 68, 6, 64, + 11, 82, 65, 78, 83, 77, 73, 83, 83, 73, 79, 78, 159, 108, 69, 5, 143, + 171, 3, 32, 2, 155, 7, 73, 2, 205, 206, 4, 2, 67, 65, 4, 36, 2, 73, 76, + 73, 3, 79, 82, 77, 2, 191, 2, 69, 2, 129, 162, 1, 6, 65, 76, 32, 84, 65, + 66, 2, 11, 69, 2, 17, 2, 32, 70, 2, 223, 178, 1, 69, 2, 191, 219, 4, 80, + 6, 26, 69, 175, 141, 4, 85, 4, 56, 8, 71, 65, 84, 73, 86, 69, 32, 65, + 247, 247, 4, 87, 2, 21, 3, 67, 75, 78, 2, 21, 3, 79, 87, 76, 2, 191, 136, + 1, 69, 2, 11, 79, 2, 17, 2, 82, 68, 2, 191, 247, 2, 32, 18, 176, 1, 7, + 65, 77, 65, 82, 73, 84, 65, 60, 3, 72, 73, 70, 52, 8, 84, 65, 82, 84, 32, + 79, 70, 32, 64, 7, 85, 66, 83, 84, 73, 84, 85, 204, 1, 3, 89, 78, 67, + 255, 206, 5, 80, 2, 25, 4, 78, 32, 83, 79, 2, 11, 85, 2, 219, 209, 5, 82, + 4, 17, 2, 84, 32, 4, 226, 148, 5, 79, 239, 41, 73, 4, 22, 72, 155, 102, + 84, 2, 17, 2, 69, 65, 2, 223, 188, 5, 68, 4, 11, 84, 4, 11, 69, 5, 11, + 32, 2, 25, 4, 70, 79, 82, 77, 2, 17, 2, 32, 84, 2, 251, 237, 5, 87, 2, + 137, 207, 5, 2, 73, 67, 2, 11, 84, 2, 235, 250, 5, 82, 7, 38, 67, 145, + 171, 2, 3, 65, 71, 79, 2, 141, 134, 1, 9, 72, 82, 79, 78, 79, 85, 83, 32, + 73, 180, 1, 36, 3, 65, 67, 32, 163, 215, 4, 78, 178, 1, 150, 3, 65, 52, + 4, 66, 65, 82, 82, 32, 2, 67, 79, 80, 13, 68, 79, 84, 84, 69, 68, 32, 90, + 76, 65, 77, 65, 32, 118, 69, 90, 72, 204, 2, 7, 76, 69, 84, 84, 69, 82, + 32, 236, 9, 9, 79, 66, 76, 73, 81, 85, 69, 32, 76, 28, 4, 80, 84, 72, 65, + 0, 4, 90, 81, 65, 80, 110, 82, 88, 2, 83, 85, 174, 2, 84, 216, 205, 4, 3, + 77, 85, 83, 228, 21, 7, 70, 69, 77, 73, 78, 73, 78, 229, 136, 1, 5, 81, + 85, 83, 72, 83, 2, 11, 66, 2, 197, 158, 5, 5, 66, 82, 69, 86, 73, 2, 11, + 69, 2, 167, 134, 6, 75, 6, 38, 78, 165, 17, 4, 76, 79, 78, 32, 2, 17, 2, + 84, 82, 2, 151, 182, 5, 65, 4, 28, 3, 65, 78, 71, 35, 72, 2, 11, 85, 2, + 255, 227, 4, 76, 2, 11, 79, 2, 185, 184, 3, 5, 82, 73, 90, 79, 78, 6, 60, + 10, 78, 68, 32, 79, 70, 32, 80, 65, 82, 65, 151, 14, 83, 2, 201, 11, 2, + 71, 82, 14, 104, 8, 65, 82, 75, 76, 69, 65, 78, 32, 132, 1, 4, 66, 65, + 83, 65, 65, 7, 79, 82, 73, 90, 79, 78, 84, 6, 60, 5, 65, 83, 84, 69, 82, + 40, 4, 77, 69, 84, 79, 3, 79, 2, 17, 2, 73, 83, 2, 219, 128, 4, 67, 2, + 181, 166, 2, 2, 66, 69, 6, 164, 11, 8, 45, 69, 83, 65, 83, 65, 32, 68, + 159, 223, 3, 32, 2, 197, 178, 5, 2, 65, 76, 92, 154, 2, 68, 102, 72, 32, + 3, 76, 65, 77, 34, 77, 204, 1, 2, 80, 69, 142, 1, 82, 78, 83, 144, 1, 8, + 70, 73, 78, 65, 76, 32, 83, 69, 106, 65, 14, 75, 2, 81, 34, 84, 40, 5, + 71, 65, 77, 65, 76, 40, 4, 89, 85, 68, 72, 146, 75, 66, 166, 130, 4, 90, + 154, 43, 78, 254, 1, 87, 159, 126, 69, 4, 76, 14, 79, 84, 76, 69, 83, 83, + 32, 68, 65, 76, 65, 84, 72, 32, 139, 3, 65, 2, 139, 193, 2, 82, 4, 11, + 69, 5, 159, 254, 5, 84, 2, 11, 65, 2, 255, 253, 5, 68, 24, 60, 9, 65, 76, + 65, 89, 65, 76, 65, 77, 32, 231, 237, 5, 73, 22, 78, 76, 22, 78, 158, + 134, 4, 66, 242, 210, 1, 84, 138, 34, 83, 14, 74, 3, 82, 4, 199, 247, 3, + 76, 8, 182, 84, 78, 234, 166, 5, 71, 3, 89, 9, 33, 6, 82, 83, 73, 65, 78, + 32, 6, 50, 66, 16, 3, 68, 72, 65, 17, 3, 71, 72, 65, 2, 131, 79, 72, 2, + 147, 2, 76, 2, 143, 243, 4, 77, 4, 52, 7, 69, 86, 69, 82, 83, 69, 68, + 211, 150, 4, 73, 2, 251, 182, 4, 32, 14, 142, 1, 69, 40, 7, 79, 71, 68, + 73, 65, 78, 32, 64, 12, 85, 80, 69, 82, 83, 67, 82, 73, 80, 84, 32, 65, + 166, 250, 4, 72, 177, 82, 2, 65, 68, 2, 17, 2, 77, 75, 2, 175, 251, 3, + 65, 6, 42, 90, 32, 2, 75, 72, 131, 227, 5, 70, 2, 195, 206, 4, 72, 2, 11, + 76, 2, 11, 65, 2, 183, 248, 5, 80, 6, 36, 3, 69, 84, 72, 255, 250, 4, 65, + 5, 237, 85, 6, 32, 71, 65, 82, 83, 72, 5, 215, 203, 5, 32, 4, 225, 223, + 3, 2, 73, 78, 6, 21, 3, 72, 65, 32, 6, 42, 68, 186, 223, 3, 66, 223, 155, + 1, 65, 2, 17, 2, 79, 84, 2, 155, 152, 1, 84, 8, 58, 66, 210, 144, 2, 87, + 217, 189, 1, 4, 85, 75, 75, 65, 4, 173, 204, 3, 2, 65, 83, 14, 88, 8, 66, + 76, 73, 78, 69, 65, 82, 32, 113, 10, 80, 82, 65, 76, 73, 78, 69, 65, 82, + 32, 8, 44, 5, 67, 79, 76, 79, 78, 227, 170, 3, 70, 7, 11, 32, 4, 29, 5, + 83, 75, 69, 87, 69, 4, 171, 202, 5, 68, 6, 44, 5, 67, 79, 76, 79, 78, + 243, 169, 3, 70, 5, 185, 194, 5, 7, 32, 83, 75, 69, 87, 69, 68, 8, 62, + 72, 25, 11, 87, 79, 32, 86, 69, 82, 84, 73, 67, 65, 76, 4, 21, 3, 82, 69, + 69, 4, 25, 4, 32, 68, 79, 84, 4, 239, 218, 3, 83, 148, 41, 102, 45, 58, + 65, 166, 106, 69, 254, 45, 72, 174, 46, 73, 254, 72, 79, 182, 20, 82, + 226, 16, 85, 191, 9, 87, 4, 32, 2, 83, 72, 203, 205, 4, 82, 2, 179, 235, + 4, 73, 244, 26, 182, 1, 66, 82, 71, 192, 17, 2, 73, 32, 182, 29, 75, 152, + 5, 9, 76, 76, 89, 32, 77, 65, 82, 75, 32, 34, 77, 226, 37, 78, 156, 13, + 3, 80, 69, 32, 94, 85, 150, 233, 4, 67, 159, 11, 88, 5, 249, 123, 16, 76, + 69, 32, 84, 69, 78, 78, 73, 83, 32, 80, 65, 68, 68, 76, 69, 144, 2, 78, + 32, 224, 11, 5, 65, 76, 79, 71, 32, 253, 2, 6, 66, 65, 78, 87, 65, 32, + 190, 1, 158, 1, 65, 102, 67, 186, 1, 68, 58, 69, 98, 71, 118, 72, 46, 76, + 222, 3, 80, 54, 81, 62, 82, 106, 83, 194, 77, 78, 166, 213, 1, 84, 166, + 118, 70, 159, 177, 1, 86, 6, 42, 80, 170, 180, 2, 77, 147, 169, 1, 83, 2, + 17, 2, 79, 83, 2, 197, 192, 5, 4, 84, 82, 79, 80, 8, 18, 73, 63, 79, 2, + 25, 4, 82, 67, 85, 77, 2, 213, 2, 4, 70, 76, 69, 88, 6, 26, 77, 231, 156, + 5, 76, 4, 11, 77, 4, 228, 216, 4, 7, 69, 82, 67, 73, 65, 76, 32, 211, + 147, 1, 65, 22, 26, 79, 207, 253, 3, 73, 2, 11, 76, 2, 175, 85, 76, 4, + 18, 81, 43, 88, 2, 17, 2, 85, 65, 2, 207, 209, 2, 76, 2, 221, 129, 5, 4, + 67, 76, 65, 77, 4, 11, 82, 4, 18, 65, 55, 69, 2, 11, 86, 2, 11, 69, 2, + 209, 121, 3, 32, 65, 67, 2, 137, 4, 4, 65, 84, 69, 82, 2, 129, 141, 2, 6, + 89, 80, 72, 69, 78, 45, 114, 38, 65, 246, 2, 69, 183, 129, 4, 79, 104, + 25, 4, 84, 73, 78, 32, 104, 34, 67, 33, 4, 83, 77, 65, 76, 52, 29, 5, 65, + 80, 73, 84, 65, 52, 41, 8, 76, 32, 76, 69, 84, 84, 69, 82, 52, 11, 32, + 52, 254, 231, 5, 65, 2, 66, 2, 67, 2, 68, 2, 69, 2, 70, 2, 71, 2, 72, 2, + 73, 2, 74, 2, 75, 2, 76, 2, 77, 2, 78, 2, 79, 2, 80, 2, 81, 2, 82, 2, 83, + 2, 84, 2, 85, 2, 86, 2, 87, 2, 88, 2, 89, 3, 90, 8, 22, 83, 195, 1, 70, + 2, 11, 83, 2, 145, 64, 3, 45, 84, 72, 4, 26, 69, 247, 203, 2, 76, 2, 185, + 68, 2, 82, 67, 4, 11, 85, 4, 26, 79, 235, 154, 3, 69, 2, 227, 251, 4, 84, + 8, 36, 3, 73, 71, 72, 159, 210, 3, 69, 6, 17, 2, 84, 32, 6, 238, 135, 2, + 67, 134, 2, 80, 155, 2, 83, 6, 174, 174, 2, 69, 202, 165, 1, 79, 155, + 211, 1, 80, 46, 80, 7, 76, 69, 84, 84, 69, 82, 32, 208, 1, 5, 83, 73, 71, + 78, 32, 159, 2, 86, 38, 162, 1, 65, 218, 146, 2, 78, 210, 204, 3, 66, 2, + 68, 2, 71, 2, 72, 2, 75, 2, 76, 2, 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, + 2, 89, 186, 2, 73, 3, 85, 5, 145, 151, 5, 6, 82, 67, 72, 65, 73, 67, 4, + 18, 80, 51, 86, 2, 25, 4, 65, 77, 85, 68, 2, 159, 191, 2, 80, 2, 247, + 174, 3, 73, 36, 48, 7, 76, 69, 84, 84, 69, 82, 32, 147, 1, 86, 32, 158, + 145, 2, 78, 210, 204, 3, 66, 2, 68, 2, 71, 2, 75, 2, 76, 2, 77, 2, 80, 2, + 83, 2, 84, 2, 87, 2, 89, 186, 2, 65, 2, 73, 3, 85, 4, 41, 8, 79, 87, 69, + 76, 32, 83, 73, 71, 4, 11, 78, 4, 179, 158, 5, 32, 212, 3, 112, 10, 76, + 69, 32, 76, 69, 84, 84, 69, 82, 32, 248, 2, 5, 84, 72, 65, 77, 32, 193, + 18, 5, 86, 73, 69, 84, 32, 70, 186, 1, 65, 34, 69, 30, 84, 214, 140, 2, + 78, 138, 144, 1, 79, 206, 247, 1, 75, 2, 80, 162, 7, 85, 222, 61, 70, 2, + 72, 2, 76, 2, 77, 2, 81, 2, 83, 2, 86, 2, 88, 2, 89, 187, 2, 73, 7, 194, + 197, 5, 85, 215, 22, 73, 7, 246, 219, 5, 69, 3, 72, 18, 60, 3, 79, 78, + 69, 234, 147, 5, 83, 254, 68, 72, 187, 2, 65, 10, 11, 45, 10, 142, 219, + 5, 50, 2, 51, 2, 52, 2, 53, 3, 54, 254, 1, 196, 1, 2, 67, 79, 240, 3, 4, + 72, 79, 82, 65, 0, 4, 84, 72, 65, 77, 28, 7, 76, 69, 84, 84, 69, 82, 32, + 220, 4, 5, 83, 73, 71, 78, 32, 217, 5, 11, 86, 79, 87, 69, 76, 32, 83, + 73, 71, 78, 32, 20, 164, 1, 13, 78, 83, 79, 78, 65, 78, 84, 32, 83, 73, + 71, 78, 32, 237, 198, 4, 21, 77, 66, 73, 78, 73, 78, 71, 32, 67, 82, 89, + 80, 84, 79, 71, 82, 65, 77, 77, 73, 67, 18, 148, 1, 6, 70, 73, 78, 65, + 76, 32, 22, 76, 56, 16, 72, 73, 71, 72, 32, 82, 65, 84, 72, 65, 32, 79, + 82, 32, 76, 79, 22, 77, 186, 211, 5, 66, 3, 83, 2, 151, 148, 5, 78, 4, + 54, 79, 149, 151, 1, 7, 65, 32, 84, 65, 78, 71, 32, 2, 167, 216, 1, 87, + 6, 48, 6, 69, 68, 73, 65, 76, 32, 191, 213, 5, 65, 4, 130, 211, 5, 76, 3, + 82, 20, 129, 231, 3, 2, 32, 68, 106, 188, 1, 2, 71, 82, 44, 5, 72, 73, + 71, 72, 32, 94, 76, 222, 1, 82, 198, 129, 2, 85, 210, 200, 1, 73, 166, + 15, 78, 182, 216, 1, 79, 162, 8, 69, 158, 20, 66, 2, 68, 2, 77, 2, 87, + 187, 2, 65, 2, 21, 3, 69, 65, 84, 2, 231, 208, 5, 32, 32, 242, 1, 75, 42, + 82, 250, 136, 5, 83, 82, 67, 2, 80, 2, 84, 254, 68, 70, 2, 72, 3, 89, 36, + 60, 3, 79, 87, 32, 234, 145, 5, 65, 194, 41, 85, 159, 20, 76, 28, 86, 75, + 42, 82, 202, 137, 5, 67, 2, 80, 2, 84, 254, 68, 70, 2, 72, 2, 83, 3, 89, + 6, 234, 206, 5, 72, 2, 88, 187, 2, 65, 2, 189, 217, 3, 2, 65, 84, 8, 26, + 65, 243, 185, 5, 85, 7, 138, 206, 5, 78, 3, 84, 50, 182, 1, 72, 34, 75, + 176, 1, 4, 77, 65, 73, 32, 82, 82, 136, 1, 2, 83, 65, 92, 5, 87, 73, 65, + 78, 71, 152, 27, 4, 84, 79, 78, 69, 224, 100, 3, 68, 79, 75, 177, 242, 3, + 2, 67, 65, 4, 130, 254, 4, 65, 167, 63, 79, 14, 52, 4, 72, 85, 69, 78, + 134, 3, 65, 139, 177, 4, 69, 8, 80, 6, 32, 84, 79, 78, 69, 45, 145, 134, + 4, 8, 45, 76, 85, 69, 32, 75, 65, 82, 6, 194, 205, 5, 51, 2, 52, 3, 53, + 8, 56, 4, 75, 65, 78, 71, 194, 136, 1, 89, 235, 138, 3, 83, 5, 243, 141, + 1, 32, 4, 92, 3, 65, 32, 72, 21, 16, 69, 86, 69, 82, 83, 69, 68, 32, 82, + 79, 84, 65, 84, 69, 68, 32, 2, 179, 146, 4, 65, 2, 171, 162, 3, 82, 8, + 48, 3, 84, 75, 65, 226, 131, 4, 87, 139, 119, 75, 4, 17, 2, 65, 78, 5, + 251, 219, 3, 75, 5, 133, 156, 3, 2, 87, 65, 38, 90, 65, 36, 4, 77, 65, + 73, 32, 22, 79, 46, 84, 86, 85, 242, 193, 3, 73, 207, 134, 2, 69, 9, 242, + 201, 5, 65, 2, 69, 3, 73, 2, 255, 181, 4, 83, 11, 218, 176, 3, 65, 226, + 152, 2, 79, 3, 89, 4, 42, 65, 129, 138, 1, 4, 72, 65, 77, 32, 2, 17, 2, + 76, 76, 2, 135, 217, 3, 32, 9, 166, 136, 5, 85, 151, 64, 69, 144, 1, 184, + 1, 7, 76, 69, 84, 84, 69, 82, 32, 188, 2, 5, 77, 65, 73, 32, 75, 32, 7, + 83, 89, 77, 66, 79, 76, 32, 124, 9, 84, 79, 78, 69, 32, 77, 65, 73, 32, + 81, 6, 86, 79, 87, 69, 76, 32, 96, 44, 4, 72, 73, 71, 72, 1, 3, 76, 79, + 87, 48, 11, 32, 48, 154, 1, 75, 30, 67, 2, 80, 2, 84, 34, 78, 214, 165, + 5, 66, 2, 68, 2, 70, 2, 71, 2, 72, 2, 76, 2, 77, 2, 82, 2, 83, 2, 86, 2, + 89, 247, 30, 79, 6, 26, 72, 235, 196, 5, 79, 4, 242, 165, 5, 72, 247, 30, + 79, 6, 210, 165, 5, 71, 2, 89, 247, 30, 79, 4, 178, 243, 4, 65, 183, 52, + 72, 10, 72, 2, 75, 79, 110, 78, 164, 128, 1, 4, 72, 79, 32, 72, 235, 136, + 3, 83, 4, 140, 129, 1, 3, 73, 32, 75, 167, 194, 4, 78, 8, 58, 78, 178, + 134, 1, 84, 186, 255, 1, 83, 203, 185, 2, 69, 2, 151, 134, 3, 85, 26, 50, + 65, 58, 85, 30, 73, 174, 193, 5, 69, 3, 79, 10, 170, 171, 5, 85, 214, 22, + 65, 2, 77, 2, 78, 3, 89, 9, 26, 69, 175, 193, 5, 65, 5, 171, 193, 5, 65, + 138, 1, 52, 3, 82, 73, 32, 173, 180, 4, 4, 69, 79, 85, 84, 136, 1, 82, + 65, 20, 7, 76, 69, 84, 84, 69, 82, 32, 170, 2, 83, 78, 86, 227, 206, 3, + 68, 2, 163, 213, 1, 66, 88, 214, 1, 65, 254, 157, 1, 82, 242, 55, 68, 46, + 84, 230, 24, 85, 210, 200, 1, 73, 158, 190, 1, 78, 126, 66, 2, 67, 2, 71, + 2, 74, 2, 75, 2, 80, 2, 83, 254, 68, 72, 2, 76, 2, 77, 2, 86, 2, 89, 186, + 2, 69, 3, 79, 11, 176, 149, 3, 7, 82, 67, 72, 65, 73, 67, 32, 230, 168, + 2, 65, 2, 73, 3, 85, 8, 25, 4, 73, 71, 78, 32, 8, 226, 215, 1, 78, 222, + 160, 3, 65, 239, 1, 86, 18, 49, 10, 79, 87, 69, 76, 32, 83, 73, 71, 78, + 32, 18, 238, 215, 1, 65, 190, 21, 85, 210, 200, 1, 73, 206, 134, 2, 69, + 3, 79, 4, 226, 51, 70, 139, 239, 3, 79, 188, 6, 36, 3, 73, 76, 32, 147, + 154, 4, 65, 186, 6, 170, 3, 65, 102, 67, 194, 2, 68, 72, 3, 87, 69, 84, + 48, 9, 70, 82, 65, 67, 84, 73, 79, 78, 32, 136, 8, 9, 73, 78, 32, 80, 79, + 83, 83, 69, 83, 22, 76, 204, 2, 7, 78, 85, 77, 66, 69, 82, 32, 152, 1, + 18, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 32, 69, 78, 68, 32, 79, + 70, 54, 82, 42, 83, 188, 14, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, + 32, 78, 84, 228, 1, 2, 89, 69, 184, 143, 4, 5, 77, 79, 78, 84, 72, 147, + 118, 79, 6, 76, 5, 83, 32, 65, 66, 79, 206, 55, 85, 149, 154, 3, 5, 78, + 68, 32, 79, 68, 2, 219, 159, 3, 86, 52, 80, 9, 79, 78, 83, 79, 78, 65, + 78, 84, 32, 192, 21, 3, 85, 82, 82, 143, 10, 82, 48, 130, 1, 75, 22, 76, + 22, 78, 46, 84, 170, 193, 1, 83, 170, 16, 82, 166, 227, 3, 67, 2, 72, 2, + 74, 2, 77, 2, 80, 2, 86, 3, 89, 5, 247, 247, 4, 83, 7, 151, 185, 4, 76, + 11, 158, 189, 3, 78, 130, 248, 1, 71, 3, 89, 5, 243, 180, 5, 84, 26, 68, + 2, 82, 89, 172, 29, 2, 69, 66, 234, 248, 1, 65, 247, 175, 1, 73, 2, 213, + 201, 1, 7, 32, 67, 85, 76, 84, 73, 86, 42, 168, 1, 4, 79, 78, 69, 32, + 252, 4, 6, 84, 72, 82, 69, 69, 32, 165, 172, 5, 22, 68, 79, 87, 78, 83, + 67, 65, 76, 73, 78, 71, 32, 70, 65, 67, 84, 79, 82, 32, 75, 73, 73, 30, + 112, 5, 69, 73, 71, 72, 84, 34, 70, 40, 3, 72, 65, 76, 18, 79, 88, 4, 83, + 73, 88, 84, 110, 84, 187, 175, 3, 81, 4, 242, 3, 73, 215, 173, 5, 72, 4, + 188, 3, 2, 79, 82, 191, 173, 3, 73, 4, 171, 1, 70, 2, 133, 3, 18, 78, 69, + 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, 83, 73, 88, 6, 64, 5, + 69, 69, 78, 84, 72, 165, 233, 1, 5, 89, 45, 70, 79, 85, 4, 11, 45, 4, + 198, 175, 5, 49, 3, 50, 8, 38, 72, 138, 1, 87, 239, 174, 3, 69, 4, 132, + 1, 18, 82, 69, 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, + 84, 87, 249, 242, 3, 8, 73, 82, 84, 89, 45, 83, 69, 67, 2, 17, 2, 69, 78, + 2, 17, 2, 84, 73, 2, 207, 174, 3, 69, 10, 58, 69, 28, 4, 83, 73, 88, 84, + 82, 84, 163, 174, 3, 81, 2, 129, 1, 3, 73, 71, 72, 4, 50, 69, 149, 175, + 3, 6, 89, 45, 70, 79, 85, 82, 2, 145, 175, 3, 2, 69, 78, 2, 21, 3, 87, + 69, 78, 2, 221, 174, 3, 3, 84, 73, 69, 2, 247, 209, 1, 83, 72, 48, 6, 69, + 84, 84, 69, 82, 32, 187, 197, 3, 65, 70, 198, 1, 78, 138, 24, 84, 222, + 22, 76, 210, 90, 82, 206, 55, 65, 182, 25, 85, 158, 144, 1, 79, 182, 56, + 73, 202, 190, 1, 83, 242, 7, 69, 222, 61, 67, 2, 72, 2, 74, 2, 75, 2, 77, + 2, 80, 2, 86, 3, 89, 10, 46, 78, 234, 166, 5, 71, 2, 89, 187, 2, 65, 4, + 230, 166, 5, 78, 187, 2, 65, 8, 38, 79, 230, 215, 3, 84, 167, 74, 83, 4, + 11, 78, 4, 17, 2, 69, 32, 4, 18, 72, 31, 84, 2, 213, 72, 3, 85, 78, 68, + 2, 229, 238, 1, 3, 72, 79, 85, 2, 17, 2, 32, 84, 2, 11, 69, 2, 155, 139, + 5, 88, 2, 17, 2, 85, 80, 2, 199, 143, 3, 69, 194, 4, 152, 1, 5, 65, 76, + 84, 32, 80, 20, 4, 73, 71, 78, 32, 206, 4, 80, 28, 9, 84, 65, 82, 84, 73, + 78, 71, 32, 70, 41, 8, 89, 76, 76, 65, 66, 76, 69, 32, 2, 207, 175, 3, + 65, 40, 90, 65, 48, 3, 67, 69, 86, 34, 75, 80, 2, 77, 85, 102, 85, 14, + 80, 118, 86, 163, 65, 78, 4, 216, 2, 4, 65, 90, 72, 65, 195, 221, 4, 78, + 2, 11, 73, 2, 215, 255, 4, 84, 6, 38, 85, 157, 255, 4, 3, 65, 65, 67, 4, + 18, 90, 87, 82, 2, 151, 144, 5, 72, 6, 60, 4, 75, 75, 85, 82, 16, 2, 84, + 72, 21, 3, 85, 86, 85, 2, 163, 83, 85, 2, 203, 241, 2, 65, 2, 75, 90, 8, + 26, 65, 255, 210, 4, 79, 6, 34, 84, 230, 232, 3, 65, 15, 78, 2, 11, 72, + 2, 17, 2, 65, 75, 2, 163, 253, 4, 75, 10, 38, 65, 210, 82, 69, 143, 140, + 4, 73, 4, 176, 103, 3, 82, 65, 65, 213, 202, 2, 6, 75, 65, 73, 89, 65, + 82, 2, 11, 69, 2, 159, 10, 78, 2, 17, 2, 82, 79, 2, 243, 153, 4, 77, 148, + 4, 122, 75, 170, 1, 76, 174, 1, 78, 194, 1, 82, 90, 83, 186, 1, 84, 86, + 67, 2, 72, 2, 74, 2, 77, 2, 80, 2, 86, 3, 89, 46, 88, 2, 83, 83, 150, + 186, 1, 65, 190, 21, 85, 158, 144, 1, 79, 182, 56, 73, 187, 198, 1, 69, + 24, 154, 182, 1, 65, 182, 25, 85, 158, 144, 1, 79, 182, 56, 73, 187, 198, + 1, 69, 66, 82, 76, 246, 184, 1, 65, 190, 21, 85, 158, 144, 1, 79, 182, + 56, 73, 187, 198, 1, 69, 44, 250, 4, 76, 250, 179, 1, 65, 190, 21, 85, + 158, 144, 1, 79, 182, 56, 73, 187, 198, 1, 69, 110, 102, 78, 190, 3, 71, + 2, 89, 250, 179, 1, 65, 190, 21, 85, 158, 144, 1, 79, 182, 56, 73, 187, + 198, 1, 69, 44, 186, 3, 78, 250, 179, 1, 65, 190, 21, 85, 158, 144, 1, + 79, 182, 56, 73, 187, 198, 1, 69, 44, 226, 2, 82, 250, 179, 1, 65, 190, + 21, 85, 158, 144, 1, 79, 182, 56, 73, 187, 198, 1, 69, 68, 94, 72, 174, + 1, 83, 250, 179, 1, 65, 190, 21, 85, 158, 144, 1, 79, 182, 56, 73, 187, + 198, 1, 69, 24, 162, 181, 1, 65, 190, 21, 85, 158, 144, 1, 79, 230, 2, + 82, 210, 53, 73, 187, 198, 1, 69, 44, 82, 84, 250, 179, 1, 65, 190, 21, + 85, 158, 144, 1, 79, 182, 56, 73, 187, 198, 1, 69, 22, 246, 179, 1, 65, + 190, 21, 85, 158, 144, 1, 79, 182, 56, 73, 187, 198, 1, 69, 6, 68, 2, 79, + 84, 33, 11, 82, 65, 68, 73, 84, 73, 79, 78, 65, 76, 32, 2, 11, 65, 2, + 199, 144, 4, 76, 4, 24, 2, 67, 82, 55, 78, 2, 17, 2, 69, 68, 2, 11, 73, + 2, 247, 143, 4, 84, 2, 11, 85, 2, 17, 2, 77, 66, 2, 23, 69, 2, 11, 65, 2, + 171, 143, 4, 82, 184, 13, 36, 5, 65, 66, 65, 84, 65, 35, 71, 2, 11, 32, + 2, 135, 169, 3, 84, 182, 13, 54, 69, 20, 3, 83, 65, 32, 241, 6, 3, 85, + 84, 32, 2, 215, 251, 3, 82, 178, 1, 52, 7, 76, 69, 84, 84, 69, 82, 32, + 143, 166, 3, 68, 158, 1, 210, 1, 65, 58, 70, 54, 72, 62, 76, 58, 77, 54, + 78, 50, 83, 126, 85, 114, 69, 2, 73, 2, 79, 2, 86, 158, 198, 4, 84, 82, + 67, 2, 68, 2, 71, 2, 75, 2, 80, 254, 68, 66, 2, 82, 2, 87, 2, 88, 2, 89, + 3, 90, 16, 174, 4, 87, 162, 142, 5, 67, 2, 81, 2, 88, 3, 90, 4, 168, 193, + 4, 5, 73, 78, 65, 76, 32, 239, 80, 65, 6, 26, 84, 203, 145, 5, 65, 4, + 142, 143, 5, 84, 187, 2, 65, 4, 192, 236, 3, 5, 79, 78, 71, 32, 85, 231, + 164, 1, 65, 10, 238, 144, 5, 65, 2, 67, 2, 81, 2, 88, 3, 90, 8, 130, 142, + 5, 71, 2, 72, 2, 89, 187, 2, 65, 8, 26, 72, 243, 143, 5, 65, 6, 40, 4, + 79, 82, 84, 32, 199, 143, 5, 65, 4, 208, 152, 1, 2, 85, 69, 229, 234, 2, + 2, 65, 87, 32, 58, 73, 54, 69, 162, 142, 5, 67, 2, 81, 2, 88, 3, 90, 16, + 50, 85, 162, 142, 5, 67, 2, 81, 2, 88, 3, 90, 8, 158, 142, 5, 67, 2, 81, + 2, 88, 3, 90, 130, 12, 64, 10, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, + 143, 241, 2, 73, 128, 12, 70, 48, 178, 1, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 95, 55, 198, 1, 86, 48, 242, 1, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, + 54, 2, 55, 2, 56, 3, 57, 18, 130, 140, 5, 49, 2, 50, 2, 51, 2, 52, 2, 53, + 2, 54, 2, 55, 2, 56, 3, 57, 200, 1, 150, 1, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 138, 1, 58, 48, 2, 49, 2, 50, 2, + 51, 2, 52, 2, 53, 95, 54, 20, 146, 138, 5, 48, 2, 49, 2, 50, 2, 51, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 18, 182, 137, 5, 48, 2, 49, 2, 50, + 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 3, 56, 4, 48, 6, 67, 65, 82, 84, 82, + 73, 21, 2, 68, 82, 2, 187, 212, 3, 68, 2, 215, 139, 4, 73, 2, 155, 133, + 3, 82, 142, 3, 154, 1, 65, 152, 2, 5, 68, 68, 89, 32, 66, 22, 76, 234, + 14, 78, 144, 1, 5, 83, 84, 32, 84, 85, 21, 12, 84, 82, 65, 71, 82, 65, + 77, 32, 70, 79, 82, 32, 10, 68, 9, 67, 85, 80, 32, 87, 73, 84, 72, 79, + 58, 82, 171, 181, 4, 80, 2, 33, 6, 85, 84, 32, 72, 65, 78, 2, 195, 228, + 3, 68, 6, 72, 9, 45, 79, 70, 70, 32, 67, 65, 76, 69, 29, 5, 68, 82, 79, + 80, 45, 2, 221, 226, 3, 2, 78, 68, 4, 234, 243, 2, 83, 245, 112, 4, 66, + 65, 82, 66, 2, 147, 226, 3, 69, 216, 1, 38, 69, 225, 2, 4, 85, 71, 85, + 32, 16, 52, 6, 80, 72, 79, 78, 69, 32, 246, 1, 83, 35, 86, 12, 132, 1, 3, + 82, 69, 67, 252, 151, 1, 3, 76, 79, 67, 242, 227, 2, 83, 165, 116, 13, + 79, 78, 32, 84, 79, 80, 32, 79, 70, 32, 77, 79, 68, 6, 36, 5, 69, 73, 86, + 69, 82, 51, 79, 5, 29, 5, 32, 87, 73, 84, 72, 2, 159, 39, 32, 2, 243, + 221, 2, 82, 2, 11, 67, 2, 211, 188, 3, 79, 2, 247, 231, 2, 73, 200, 1, + 162, 1, 65, 40, 15, 70, 82, 65, 67, 84, 73, 79, 78, 32, 68, 73, 71, 73, + 84, 32, 164, 2, 2, 76, 69, 156, 4, 5, 83, 73, 71, 78, 32, 198, 2, 86, + 175, 136, 3, 68, 2, 11, 73, 2, 245, 189, 4, 2, 32, 76, 14, 74, 84, 40, 2, + 79, 78, 81, 10, 90, 69, 82, 79, 32, 70, 79, 82, 32, 79, 8, 36, 3, 72, 82, + 69, 13, 2, 87, 79, 4, 11, 69, 4, 29, 5, 32, 70, 79, 82, 32, 4, 34, 79, + 21, 4, 69, 86, 69, 78, 2, 17, 2, 68, 68, 2, 49, 10, 32, 80, 79, 87, 69, + 82, 83, 32, 79, 70, 2, 201, 22, 2, 32, 70, 114, 44, 5, 84, 84, 69, 82, + 32, 159, 187, 4, 78, 112, 214, 1, 68, 54, 76, 38, 78, 106, 82, 34, 84, + 242, 144, 1, 65, 126, 86, 186, 24, 85, 158, 144, 1, 79, 182, 56, 73, 202, + 190, 1, 83, 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 162, 7, 69, 222, + 61, 72, 2, 77, 3, 89, 10, 234, 179, 4, 68, 254, 68, 72, 2, 90, 187, 2, + 65, 6, 198, 244, 2, 76, 167, 134, 2, 65, 10, 42, 65, 230, 247, 4, 71, 2, + 78, 3, 89, 5, 41, 8, 75, 65, 65, 82, 65, 32, 80, 79, 2, 163, 37, 76, 6, + 194, 89, 82, 159, 160, 4, 65, 10, 138, 178, 4, 84, 254, 68, 72, 2, 83, + 187, 2, 65, 20, 86, 67, 194, 1, 83, 248, 35, 3, 84, 85, 85, 142, 108, 65, + 170, 1, 78, 203, 162, 3, 86, 6, 60, 9, 79, 77, 66, 73, 78, 73, 78, 71, + 32, 219, 145, 1, 65, 4, 70, 65, 185, 250, 3, 11, 67, 65, 78, 68, 82, 65, + 66, 73, 78, 68, 85, 2, 33, 6, 78, 85, 83, 86, 65, 82, 2, 147, 250, 3, 65, + 2, 11, 73, 2, 169, 189, 3, 3, 68, 68, 72, 30, 49, 10, 79, 87, 69, 76, 32, + 83, 73, 71, 78, 32, 30, 186, 145, 1, 65, 106, 86, 214, 20, 85, 158, 144, + 1, 79, 182, 56, 73, 187, 198, 1, 69, 6, 80, 10, 78, 73, 83, 32, 82, 65, + 67, 81, 85, 69, 150, 221, 2, 71, 219, 151, 2, 84, 2, 11, 84, 2, 25, 4, + 32, 65, 78, 68, 2, 251, 239, 2, 32, 2, 219, 221, 4, 66, 162, 1, 210, 2, + 65, 134, 1, 66, 174, 1, 67, 130, 3, 68, 198, 3, 69, 154, 2, 70, 182, 1, + 71, 198, 1, 72, 64, 8, 89, 79, 85, 84, 72, 70, 85, 76, 52, 2, 73, 78, 46, + 75, 98, 76, 146, 1, 77, 134, 1, 79, 62, 80, 142, 1, 82, 210, 1, 83, 224, + 1, 14, 86, 65, 83, 84, 78, 69, 83, 83, 32, 79, 82, 32, 87, 65, 12, 2, 87, + 65, 202, 94, 85, 143, 234, 3, 74, 8, 88, 4, 67, 67, 85, 77, 22, 83, 132, + 21, 2, 68, 86, 157, 175, 1, 5, 71, 71, 82, 65, 86, 2, 183, 176, 1, 85, 2, + 183, 173, 4, 67, 6, 92, 7, 79, 76, 68, 32, 82, 69, 83, 32, 5, 82, 65, 78, + 67, 72, 221, 230, 3, 3, 65, 82, 82, 2, 153, 159, 4, 3, 79, 76, 85, 2, 11, + 73, 2, 133, 157, 1, 3, 78, 71, 32, 22, 54, 72, 20, 3, 76, 79, 83, 102, + 79, 211, 248, 1, 69, 2, 219, 186, 3, 65, 6, 26, 69, 143, 206, 3, 85, 4, + 26, 68, 207, 215, 3, 78, 2, 21, 3, 32, 77, 79, 2, 243, 238, 2, 85, 12, + 28, 3, 77, 80, 76, 35, 78, 4, 242, 17, 73, 143, 139, 4, 69, 8, 32, 4, 83, + 84, 65, 78, 23, 84, 2, 183, 219, 4, 67, 6, 46, 69, 20, 3, 82, 65, 82, + 211, 221, 3, 65, 2, 247, 155, 4, 78, 2, 171, 129, 3, 73, 20, 80, 4, 65, + 82, 75, 69, 22, 69, 206, 1, 73, 74, 85, 237, 204, 4, 3, 79, 85, 66, 2, + 199, 154, 4, 78, 6, 132, 1, 19, 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, + 83, 32, 79, 82, 32, 68, 73, 83, 84, 34, 80, 133, 7, 6, 67, 73, 83, 73, + 86, 69, 2, 11, 79, 2, 211, 153, 4, 82, 2, 17, 2, 65, 82, 2, 143, 10, 84, + 8, 68, 6, 70, 70, 73, 67, 85, 76, 34, 77, 161, 12, 4, 86, 69, 82, 71, 2, + 11, 84, 2, 171, 213, 3, 73, 4, 140, 1, 2, 73, 78, 243, 150, 4, 77, 14, + 100, 5, 77, 66, 69, 76, 76, 34, 78, 124, 4, 88, 72, 65, 85, 236, 106, 3, + 84, 69, 82, 239, 242, 2, 65, 2, 189, 164, 4, 3, 73, 83, 72, 6, 80, 4, 68, + 69, 65, 86, 20, 4, 76, 65, 82, 71, 129, 233, 2, 4, 67, 79, 85, 78, 2, + 175, 238, 3, 79, 2, 183, 163, 4, 69, 2, 135, 150, 4, 83, 12, 70, 79, 76, + 3, 85, 76, 76, 196, 5, 3, 65, 73, 76, 147, 181, 4, 76, 4, 18, 76, 35, 83, + 2, 225, 148, 4, 3, 76, 79, 87, 2, 205, 4, 2, 84, 69, 4, 142, 150, 3, 32, + 211, 56, 78, 10, 96, 8, 65, 84, 72, 69, 82, 73, 78, 71, 22, 79, 64, 3, + 82, 69, 65, 65, 5, 85, 65, 82, 68, 69, 5, 227, 228, 3, 32, 2, 41, 8, 73, + 78, 71, 32, 84, 79, 32, 77, 2, 211, 174, 4, 69, 2, 75, 84, 4, 48, 2, 65, + 82, 33, 6, 79, 76, 68, 73, 78, 71, 2, 11, 68, 2, 187, 204, 3, 78, 2, 11, + 32, 2, 195, 216, 1, 66, 4, 26, 67, 211, 164, 4, 78, 2, 143, 5, 82, 4, 60, + 7, 69, 69, 80, 73, 78, 71, 32, 225, 140, 4, 2, 73, 78, 2, 11, 83, 2, 151, + 221, 2, 77, 6, 18, 65, 107, 69, 4, 60, 3, 66, 79, 85, 21, 8, 87, 32, 79, + 82, 32, 77, 79, 68, 2, 243, 143, 4, 82, 2, 187, 215, 3, 69, 2, 139, 144, + 4, 71, 6, 26, 65, 30, 69, 47, 73, 2, 153, 143, 4, 2, 83, 83, 2, 11, 65, + 2, 11, 83, 2, 191, 191, 3, 85, 2, 11, 82, 2, 171, 153, 4, 69, 4, 204, + 162, 3, 7, 78, 32, 84, 72, 69, 32, 86, 139, 107, 80, 8, 54, 65, 64, 4, + 69, 78, 69, 84, 165, 98, 2, 85, 82, 4, 22, 84, 243, 2, 67, 2, 17, 2, 84, + 69, 2, 183, 142, 4, 82, 2, 195, 177, 1, 82, 12, 30, 69, 157, 1, 2, 73, + 84, 10, 34, 76, 22, 83, 231, 186, 4, 65, 2, 251, 204, 1, 69, 6, 18, 73, + 51, 80, 4, 30, 68, 137, 1, 2, 83, 84, 2, 147, 1, 69, 2, 11, 79, 2, 199, + 211, 3, 78, 2, 255, 210, 3, 85, 10, 34, 69, 64, 2, 73, 78, 23, 84, 2, 11, + 86, 2, 17, 2, 69, 82, 2, 11, 65, 2, 211, 158, 4, 78, 2, 183, 138, 4, 75, + 6, 42, 79, 237, 219, 2, 4, 82, 69, 78, 71, 4, 26, 80, 131, 196, 4, 86, 2, + 11, 80, 2, 211, 166, 3, 65, 2, 39, 83, 4, 26, 73, 231, 183, 4, 84, 2, + 147, 137, 4, 84, 224, 2, 86, 65, 180, 31, 2, 69, 82, 246, 1, 73, 206, 1, + 79, 100, 3, 82, 69, 69, 179, 8, 85, 146, 2, 44, 4, 65, 78, 65, 32, 145, + 10, 2, 73, 32, 100, 122, 65, 38, 69, 76, 7, 76, 69, 84, 84, 69, 82, 32, + 154, 7, 79, 76, 3, 73, 66, 73, 0, 3, 85, 66, 85, 45, 2, 83, 85, 4, 184, + 8, 3, 65, 66, 65, 3, 66, 6, 58, 66, 0, 3, 69, 66, 69, 245, 7, 4, 89, 66, + 69, 89, 2, 243, 7, 69, 78, 202, 1, 65, 42, 68, 82, 70, 2, 81, 14, 71, 50, + 72, 38, 75, 62, 76, 32, 3, 77, 69, 69, 20, 2, 67, 72, 2, 74, 2, 80, 18, + 78, 42, 83, 94, 84, 102, 86, 2, 87, 42, 90, 130, 225, 2, 66, 2, 82, 3, + 89, 4, 252, 1, 2, 76, 73, 191, 174, 4, 73, 6, 30, 65, 29, 3, 72, 65, 65, + 4, 218, 2, 65, 255, 1, 86, 2, 227, 175, 4, 76, 2, 123, 65, 6, 110, 65, + 86, 78, 245, 173, 4, 3, 72, 65, 73, 4, 178, 228, 2, 72, 147, 237, 1, 65, + 4, 26, 65, 247, 227, 2, 72, 2, 11, 65, 2, 199, 174, 4, 70, 4, 18, 65, 35, + 72, 2, 11, 65, 2, 147, 174, 4, 77, 2, 211, 1, 65, 4, 224, 173, 4, 2, 79, + 79, 191, 34, 65, 8, 32, 2, 65, 65, 18, 72, 23, 69, 2, 163, 16, 68, 4, 18, + 69, 87, 65, 2, 243, 172, 4, 69, 10, 62, 65, 16, 3, 72, 65, 65, 190, 225, + 2, 84, 203, 239, 1, 79, 2, 131, 1, 86, 5, 155, 172, 4, 76, 2, 17, 2, 65, + 65, 2, 243, 171, 4, 86, 6, 26, 65, 175, 208, 4, 79, 4, 26, 86, 147, 208, + 4, 65, 2, 21, 3, 73, 89, 65, 2, 159, 188, 4, 78, 6, 48, 3, 65, 66, 79, + 14, 66, 1, 3, 79, 66, 79, 2, 23, 65, 2, 11, 79, 2, 11, 70, 2, 11, 73, 2, + 167, 187, 4, 76, 2, 211, 206, 3, 75, 174, 1, 26, 67, 159, 224, 2, 68, + 154, 1, 132, 1, 9, 72, 65, 82, 65, 67, 84, 69, 82, 32, 245, 162, 4, 17, + 85, 82, 82, 69, 78, 67, 89, 32, 83, 89, 77, 66, 79, 76, 32, 66, 65, 152, + 1, 176, 2, 6, 66, 79, 32, 66, 65, 73, 16, 6, 67, 72, 79, 32, 67, 72, 56, + 3, 68, 79, 32, 44, 2, 70, 79, 76, 3, 72, 79, 32, 66, 75, 190, 1, 76, 138, + 1, 77, 252, 1, 7, 65, 78, 71, 75, 72, 65, 78, 46, 78, 158, 1, 80, 234, 1, + 82, 70, 83, 238, 2, 84, 224, 2, 3, 87, 79, 32, 34, 89, 145, 226, 3, 2, + 79, 32, 2, 143, 12, 77, 8, 204, 210, 2, 2, 65, 78, 170, 167, 1, 73, 155, + 58, 79, 4, 164, 165, 4, 3, 67, 72, 65, 227, 33, 68, 6, 32, 2, 32, 70, 21, + 2, 78, 71, 4, 219, 209, 2, 65, 2, 147, 130, 3, 77, 4, 40, 4, 78, 79, 75, + 72, 223, 199, 4, 72, 2, 239, 197, 4, 85, 14, 40, 2, 72, 79, 229, 9, 3, + 79, 32, 75, 12, 26, 32, 239, 206, 3, 77, 10, 36, 2, 75, 72, 57, 3, 82, + 65, 75, 8, 158, 9, 87, 150, 171, 3, 85, 254, 67, 79, 255, 59, 65, 2, 135, + 239, 3, 72, 8, 76, 2, 79, 32, 224, 11, 8, 65, 75, 75, 72, 65, 78, 71, 89, + 139, 187, 4, 85, 4, 32, 2, 67, 72, 207, 245, 3, 76, 2, 171, 164, 4, 85, + 16, 28, 2, 65, 73, 235, 52, 79, 14, 42, 32, 176, 1, 3, 84, 65, 73, 19, + 89, 10, 76, 4, 67, 72, 65, 84, 44, 5, 72, 65, 78, 45, 65, 22, 84, 191, + 193, 4, 69, 2, 11, 84, 2, 11, 65, 2, 195, 194, 4, 87, 2, 151, 177, 3, 75, + 4, 222, 165, 4, 72, 159, 11, 82, 2, 203, 2, 75, 2, 193, 154, 4, 2, 65, + 77, 8, 60, 3, 71, 79, 32, 32, 3, 73, 75, 72, 29, 3, 79, 32, 78, 2, 11, + 78, 2, 211, 158, 4, 71, 2, 237, 166, 4, 2, 65, 72, 4, 182, 243, 3, 69, + 215, 79, 85, 12, 68, 6, 65, 73, 89, 65, 78, 78, 22, 72, 249, 159, 4, 3, + 79, 32, 80, 2, 203, 174, 4, 79, 8, 36, 3, 73, 78, 84, 21, 2, 79, 32, 2, + 255, 156, 4, 72, 6, 44, 2, 80, 72, 161, 5, 4, 83, 65, 77, 80, 4, 182, + 240, 3, 85, 155, 1, 65, 4, 32, 2, 79, 32, 227, 192, 4, 85, 2, 11, 82, 2, + 155, 190, 4, 85, 36, 44, 4, 65, 82, 65, 32, 225, 1, 2, 79, 32, 28, 62, + 65, 130, 1, 85, 134, 184, 2, 73, 206, 134, 2, 69, 3, 79, 13, 64, 6, 73, + 32, 77, 65, 73, 77, 142, 191, 4, 65, 2, 69, 3, 77, 4, 26, 65, 191, 247, + 2, 85, 2, 11, 76, 2, 139, 171, 4, 65, 9, 186, 254, 3, 69, 151, 64, 85, 8, + 24, 2, 82, 85, 23, 83, 2, 187, 170, 4, 83, 6, 230, 155, 4, 65, 226, 31, + 85, 187, 2, 79, 18, 30, 72, 133, 2, 2, 79, 32, 14, 48, 6, 65, 78, 84, 72, + 65, 75, 21, 2, 79, 32, 2, 175, 169, 3, 72, 12, 80, 8, 78, 65, 78, 71, 77, + 79, 78, 84, 20, 4, 80, 72, 85, 84, 13, 2, 84, 72, 2, 163, 157, 4, 72, 2, + 123, 72, 8, 34, 65, 234, 234, 3, 79, 3, 85, 4, 158, 244, 2, 72, 183, 199, + 1, 78, 4, 38, 84, 165, 140, 2, 3, 80, 65, 84, 2, 147, 156, 4, 65, 2, 11, + 87, 2, 243, 233, 2, 65, 6, 30, 65, 45, 3, 79, 32, 89, 2, 21, 3, 77, 65, + 75, 2, 231, 242, 2, 75, 4, 154, 233, 3, 73, 215, 77, 65, 10, 30, 69, 145, + 1, 2, 77, 79, 6, 18, 32, 107, 70, 4, 84, 11, 68, 79, 69, 83, 32, 78, 79, + 84, 32, 69, 88, 201, 164, 3, 4, 69, 88, 73, 83, 2, 147, 113, 73, 2, 171, + 152, 3, 79, 4, 46, 77, 157, 145, 3, 5, 68, 89, 78, 65, 77, 2, 187, 129, + 3, 69, 10, 18, 78, 95, 82, 8, 26, 32, 191, 175, 3, 75, 6, 26, 83, 255, + 177, 2, 71, 4, 218, 165, 2, 65, 211, 212, 1, 80, 2, 21, 3, 68, 32, 80, 2, + 25, 4, 76, 65, 67, 69, 2, 17, 2, 32, 77, 2, 143, 163, 3, 69, 4, 56, 4, + 85, 71, 72, 84, 173, 162, 3, 4, 78, 71, 32, 83, 2, 185, 164, 1, 5, 32, + 66, 65, 76, 76, 46, 22, 32, 199, 3, 45, 30, 154, 1, 68, 90, 76, 114, 82, + 130, 131, 1, 66, 86, 67, 242, 5, 83, 170, 149, 1, 80, 253, 21, 15, 78, + 69, 84, 87, 79, 82, 75, 69, 68, 32, 67, 79, 77, 80, 85, 4, 64, 10, 73, + 77, 69, 78, 83, 73, 79, 78, 65, 76, 219, 134, 1, 79, 2, 131, 146, 3, 32, + 6, 76, 12, 73, 78, 69, 83, 32, 67, 79, 78, 86, 69, 82, 71, 237, 127, 2, + 69, 70, 4, 217, 135, 4, 3, 73, 78, 71, 10, 36, 4, 65, 89, 83, 32, 147, + 127, 73, 8, 230, 153, 2, 66, 222, 155, 1, 65, 242, 81, 76, 31, 82, 16, + 44, 2, 68, 32, 254, 3, 80, 131, 133, 1, 69, 12, 196, 2, 12, 84, 79, 80, + 45, 76, 73, 71, 72, 84, 69, 68, 32, 80, 17, 76, 69, 70, 84, 45, 76, 73, + 71, 72, 84, 69, 68, 32, 68, 79, 87, 78, 0, 16, 82, 73, 71, 72, 84, 45, + 76, 73, 71, 72, 84, 69, 68, 32, 85, 80, 209, 223, 1, 25, 66, 79, 84, 84, + 79, 77, 45, 76, 73, 71, 72, 84, 69, 68, 32, 82, 73, 71, 72, 84, 87, 65, + 82, 68, 83, 6, 76, 4, 76, 69, 70, 84, 69, 11, 82, 73, 71, 72, 84, 87, 65, + 82, 68, 83, 32, 2, 11, 87, 2, 25, 4, 65, 82, 68, 83, 2, 181, 200, 1, 2, + 32, 69, 4, 154, 200, 1, 69, 139, 23, 65, 2, 129, 239, 3, 5, 69, 82, 45, + 69, 77, 8, 34, 77, 85, 4, 78, 68, 69, 82, 4, 21, 3, 66, 83, 32, 4, 38, + 85, 149, 182, 2, 3, 68, 79, 87, 2, 199, 165, 3, 80, 4, 212, 128, 3, 10, + 32, 67, 76, 79, 85, 68, 32, 65, 78, 68, 141, 45, 2, 83, 84, 230, 5, 204, + 1, 6, 66, 69, 84, 65, 78, 32, 240, 45, 6, 69, 32, 79, 86, 69, 82, 72, 7, + 70, 73, 78, 65, 71, 72, 32, 150, 9, 71, 152, 1, 3, 76, 68, 69, 248, 2, 2, + 77, 69, 56, 2, 78, 89, 78, 82, 223, 154, 3, 67, 160, 3, 228, 2, 18, 65, + 83, 84, 82, 79, 76, 79, 71, 73, 67, 65, 76, 32, 83, 73, 71, 78, 32, 172, + 1, 18, 67, 65, 78, 84, 73, 76, 76, 65, 84, 73, 79, 78, 32, 83, 73, 71, + 78, 32, 208, 1, 6, 68, 73, 71, 73, 84, 32, 100, 9, 75, 85, 32, 82, 85, + 32, 75, 72, 65, 26, 76, 204, 3, 5, 77, 65, 82, 75, 32, 246, 18, 83, 181, + 15, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 6, 46, 83, 129, 41, + 6, 45, 75, 72, 89, 85, 68, 4, 104, 8, 68, 79, 78, 71, 32, 84, 83, 72, + 229, 21, 13, 71, 82, 65, 32, 71, 67, 65, 78, 32, 45, 67, 72, 65, 2, 159, + 32, 85, 8, 144, 1, 5, 72, 69, 65, 86, 89, 0, 5, 76, 73, 71, 72, 84, 40, + 7, 83, 66, 85, 66, 32, 45, 67, 189, 255, 3, 8, 67, 65, 78, 71, 32, 84, + 69, 45, 2, 17, 2, 32, 66, 2, 231, 144, 3, 69, 2, 251, 154, 3, 72, 40, + 156, 182, 2, 4, 72, 65, 76, 70, 82, 70, 30, 83, 42, 84, 62, 90, 130, 83, + 78, 14, 79, 199, 110, 69, 5, 245, 10, 2, 32, 66, 92, 96, 6, 69, 84, 84, + 69, 82, 32, 181, 2, 13, 79, 71, 79, 84, 89, 80, 69, 32, 83, 73, 71, 78, + 32, 88, 226, 1, 75, 50, 82, 208, 213, 3, 10, 70, 73, 88, 69, 68, 45, 70, + 79, 82, 77, 202, 1, 68, 86, 78, 46, 83, 38, 84, 46, 66, 2, 67, 2, 71, 2, + 80, 2, 90, 254, 68, 45, 2, 72, 2, 74, 2, 76, 2, 77, 2, 87, 2, 89, 187, 2, + 65, 8, 134, 158, 4, 83, 14, 72, 2, 75, 187, 2, 65, 4, 226, 157, 4, 82, + 187, 2, 65, 4, 248, 25, 3, 76, 72, 65, 13, 4, 67, 72, 65, 68, 80, 250, 2, + 66, 176, 1, 8, 77, 78, 89, 65, 77, 32, 89, 73, 114, 67, 172, 2, 13, 89, + 73, 71, 32, 77, 71, 79, 32, 84, 83, 72, 69, 71, 190, 1, 71, 212, 2, 9, + 65, 78, 71, 32, 75, 72, 65, 78, 71, 58, 72, 48, 2, 73, 78, 246, 1, 78, + 220, 1, 2, 80, 65, 30, 82, 118, 83, 46, 84, 36, 4, 76, 69, 65, 68, 233, + 250, 1, 17, 68, 69, 76, 73, 77, 73, 84, 69, 82, 32, 84, 83, 72, 69, 71, + 32, 66, 10, 52, 9, 75, 65, 45, 32, 83, 72, 79, 71, 32, 27, 83, 4, 142, 1, + 71, 67, 89, 6, 34, 75, 229, 21, 3, 68, 85, 83, 4, 56, 6, 65, 45, 32, 83, + 72, 79, 89, 4, 85, 82, 32, 89, 2, 21, 3, 71, 32, 71, 2, 41, 8, 73, 32, + 77, 71, 79, 32, 82, 71, 2, 163, 211, 2, 89, 2, 221, 2, 2, 73, 71, 12, 84, + 5, 65, 82, 69, 84, 32, 240, 1, 2, 72, 69, 29, 7, 76, 79, 83, 73, 78, 71, + 32, 6, 112, 12, 45, 68, 90, 85, 68, 32, 82, 84, 65, 71, 83, 32, 97, 12, + 89, 73, 71, 32, 77, 71, 79, 32, 80, 72, 85, 82, 4, 42, 66, 37, 6, 77, 69, + 32, 76, 79, 78, 2, 33, 6, 90, 72, 73, 32, 77, 73, 2, 231, 22, 71, 2, 225, + 3, 3, 32, 83, 72, 2, 137, 142, 2, 2, 32, 77, 4, 68, 13, 66, 82, 68, 65, + 32, 82, 78, 89, 73, 78, 71, 32, 89, 3, 89, 2, 213, 5, 11, 73, 71, 32, 77, + 71, 79, 32, 83, 71, 65, 66, 12, 68, 4, 84, 69, 82, 32, 141, 2, 8, 85, 71, + 32, 82, 84, 65, 71, 83, 8, 56, 8, 89, 73, 71, 32, 77, 71, 79, 32, 211, + 207, 3, 84, 6, 68, 4, 45, 85, 77, 32, 117, 9, 84, 82, 85, 78, 67, 65, 84, + 69, 68, 4, 88, 7, 82, 78, 65, 77, 32, 66, 67, 245, 2, 10, 71, 84, 69, 82, + 32, 84, 83, 72, 69, 71, 2, 241, 2, 2, 65, 68, 2, 203, 145, 4, 32, 4, 21, + 3, 32, 71, 89, 4, 130, 196, 3, 79, 135, 18, 65, 2, 17, 2, 65, 76, 2, 213, + 238, 3, 2, 65, 78, 6, 92, 6, 73, 84, 73, 65, 76, 32, 165, 204, 3, 11, 84, + 69, 82, 83, 89, 76, 76, 65, 66, 73, 67, 4, 68, 13, 66, 82, 68, 65, 32, + 82, 78, 89, 73, 78, 71, 32, 89, 3, 89, 2, 53, 11, 73, 71, 32, 77, 71, 79, + 32, 77, 68, 85, 78, 2, 151, 240, 3, 32, 10, 72, 10, 71, 65, 83, 32, 66, + 90, 85, 78, 71, 32, 77, 4, 89, 73, 83, 32, 4, 56, 3, 83, 71, 79, 245, + 237, 3, 5, 78, 89, 73, 32, 90, 2, 151, 10, 82, 6, 44, 5, 84, 83, 72, 69, + 71, 163, 201, 3, 83, 5, 147, 201, 3, 32, 2, 233, 234, 3, 2, 76, 85, 4, + 212, 200, 3, 8, 71, 89, 65, 32, 71, 82, 65, 77, 1, 14, 73, 78, 32, 67, + 72, 69, 78, 32, 83, 80, 85, 78, 71, 83, 4, 224, 199, 3, 4, 66, 82, 85, + 76, 39, 72, 6, 32, 4, 82, 65, 73, 76, 55, 83, 2, 225, 7, 9, 73, 78, 71, + 32, 77, 67, 72, 65, 78, 4, 56, 5, 65, 32, 45, 80, 72, 165, 198, 3, 3, 72, + 69, 71, 2, 255, 231, 3, 82, 156, 1, 84, 4, 73, 71, 78, 32, 228, 6, 9, 85, + 66, 74, 79, 73, 78, 69, 68, 32, 143, 4, 89, 42, 176, 1, 4, 71, 82, 85, + 32, 96, 2, 76, 67, 30, 77, 36, 11, 78, 89, 73, 32, 90, 76, 65, 32, 78, + 65, 65, 22, 82, 252, 2, 2, 89, 65, 130, 4, 73, 165, 4, 5, 83, 78, 65, 32, + 76, 4, 40, 3, 67, 65, 78, 1, 3, 77, 69, 68, 2, 25, 4, 32, 82, 71, 89, 2, + 169, 4, 2, 73, 78, 4, 238, 3, 73, 179, 4, 69, 4, 136, 4, 2, 65, 82, 231, + 3, 67, 2, 159, 228, 3, 32, 20, 116, 4, 68, 69, 76, 32, 240, 1, 10, 74, + 69, 83, 32, 83, 85, 32, 78, 71, 65, 137, 192, 3, 6, 78, 65, 77, 32, 66, + 67, 16, 52, 5, 68, 75, 65, 82, 32, 53, 4, 78, 65, 71, 32, 8, 94, 71, 129, + 161, 2, 6, 82, 68, 69, 76, 32, 78, 8, 42, 71, 69, 6, 82, 68, 69, 76, 32, + 68, 6, 46, 67, 228, 233, 1, 2, 78, 89, 251, 116, 83, 2, 251, 133, 4, 73, + 2, 147, 228, 2, 75, 2, 147, 154, 2, 32, 4, 18, 78, 71, 82, 2, 11, 71, 2, + 21, 3, 32, 82, 84, 2, 11, 65, 2, 255, 199, 3, 71, 2, 17, 2, 32, 84, 2, + 187, 241, 2, 83, 94, 68, 7, 76, 69, 84, 84, 69, 82, 32, 145, 2, 5, 83, + 73, 71, 78, 32, 88, 220, 1, 10, 70, 73, 88, 69, 68, 45, 70, 79, 82, 77, + 234, 185, 3, 68, 50, 75, 38, 78, 46, 83, 38, 84, 46, 66, 2, 67, 2, 71, 2, + 80, 2, 90, 254, 68, 45, 2, 72, 2, 74, 2, 76, 2, 77, 2, 82, 2, 87, 2, 89, + 187, 2, 65, 6, 11, 32, 6, 166, 128, 4, 82, 2, 87, 3, 89, 6, 38, 73, 50, + 77, 33, 3, 76, 67, 69, 2, 45, 9, 78, 86, 69, 82, 84, 69, 68, 32, 77, 2, + 11, 67, 2, 45, 2, 72, 85, 2, 25, 4, 32, 84, 83, 65, 2, 11, 32, 2, 231, + 185, 2, 67, 20, 60, 6, 76, 76, 65, 66, 76, 69, 21, 5, 77, 66, 79, 76, 32, + 2, 227, 239, 3, 32, 18, 104, 4, 68, 82, 73, 76, 32, 6, 78, 79, 82, 32, + 66, 85, 130, 1, 80, 93, 7, 82, 68, 79, 32, 82, 74, 69, 2, 11, 32, 2, 211, + 218, 3, 66, 9, 11, 32, 6, 72, 4, 66, 90, 72, 73, 0, 4, 71, 83, 85, 77, 1, + 4, 78, 89, 73, 83, 2, 217, 209, 1, 5, 32, 45, 75, 72, 89, 4, 52, 6, 65, + 68, 77, 65, 32, 71, 21, 3, 72, 85, 82, 2, 187, 182, 2, 68, 2, 251, 88, + 32, 5, 245, 195, 2, 6, 32, 82, 71, 89, 65, 32, 30, 120, 8, 82, 69, 86, + 69, 82, 83, 69, 68, 182, 24, 86, 214, 20, 85, 158, 144, 1, 79, 182, 56, + 73, 186, 198, 1, 69, 223, 61, 65, 4, 213, 245, 1, 2, 32, 73, 2, 25, 4, + 32, 73, 78, 70, 2, 11, 73, 2, 11, 78, 2, 223, 145, 2, 73, 118, 216, 1, 9, + 67, 79, 78, 83, 79, 78, 65, 78, 84, 20, 7, 76, 69, 84, 84, 69, 82, 32, + 236, 6, 20, 77, 79, 68, 73, 70, 73, 69, 82, 32, 76, 69, 84, 84, 69, 82, + 32, 76, 65, 66, 73, 37, 8, 83, 69, 80, 65, 82, 65, 84, 79, 2, 211, 187, + 3, 32, 112, 106, 65, 108, 17, 66, 69, 82, 66, 69, 82, 32, 65, 67, 65, 68, + 69, 77, 89, 32, 89, 65, 30, 84, 223, 1, 89, 4, 84, 6, 89, 69, 82, 32, 89, + 65, 241, 246, 3, 9, 72, 65, 71, 71, 65, 82, 32, 89, 65, 2, 251, 246, 3, + 71, 4, 246, 247, 3, 72, 3, 74, 18, 92, 11, 65, 87, 69, 76, 76, 69, 77, + 69, 84, 32, 89, 33, 8, 85, 65, 82, 69, 71, 32, 89, 65, 2, 11, 65, 2, 239, + 246, 3, 90, 16, 62, 71, 190, 2, 75, 210, 242, 3, 90, 62, 78, 86, 72, 3, + 81, 4, 154, 246, 3, 72, 3, 78, 86, 54, 65, 210, 2, 69, 250, 242, 3, 73, + 2, 79, 3, 85, 77, 190, 1, 68, 30, 71, 2, 75, 14, 66, 2, 72, 22, 83, 30, + 84, 30, 90, 242, 15, 82, 150, 226, 3, 67, 146, 1, 65, 2, 70, 2, 74, 2, + 76, 2, 77, 2, 78, 2, 80, 2, 81, 2, 86, 2, 87, 3, 89, 9, 38, 68, 227, 243, + 3, 72, 7, 11, 72, 5, 223, 243, 3, 72, 7, 202, 243, 3, 72, 3, 83, 7, 174, + 243, 3, 72, 3, 84, 7, 146, 243, 3, 72, 3, 90, 5, 247, 242, 3, 89, 2, 189, + 137, 3, 4, 65, 76, 73, 90, 2, 135, 177, 3, 82, 6, 76, 2, 69, 82, 21, 13, + 72, 84, 32, 84, 82, 73, 70, 79, 76, 73, 65, 84, 69, 5, 211, 180, 3, 32, + 2, 33, 6, 32, 83, 78, 79, 87, 70, 2, 167, 43, 76, 19, 11, 32, 16, 72, 8, + 79, 80, 69, 82, 65, 84, 79, 82, 229, 1, 5, 87, 73, 84, 72, 32, 11, 11, + 32, 8, 38, 65, 97, 5, 87, 73, 84, 72, 32, 4, 25, 4, 66, 79, 86, 69, 4, + 11, 32, 4, 26, 76, 231, 207, 2, 82, 2, 249, 207, 2, 2, 69, 70, 4, 26, 82, + 219, 238, 2, 68, 2, 17, 2, 73, 83, 2, 173, 161, 2, 3, 73, 78, 71, 6, 26, + 68, 183, 196, 1, 82, 4, 11, 79, 4, 207, 213, 1, 84, 6, 22, 82, 155, 98, + 83, 2, 11, 32, 2, 175, 133, 1, 67, 5, 21, 3, 32, 84, 87, 2, 21, 3, 79, + 32, 68, 2, 249, 63, 3, 79, 84, 83, 170, 1, 100, 5, 72, 85, 84, 65, 32, + 156, 9, 11, 79, 78, 73, 65, 78, 32, 83, 73, 71, 78, 32, 223, 210, 2, 69, + 164, 1, 178, 1, 65, 88, 7, 76, 69, 84, 84, 69, 82, 32, 232, 2, 2, 83, 73, + 140, 2, 11, 86, 79, 87, 69, 76, 32, 83, 73, 71, 78, 32, 142, 247, 1, 68, + 216, 149, 1, 2, 71, 86, 239, 71, 79, 4, 18, 66, 51, 78, 2, 29, 5, 66, 82, + 69, 86, 73, 2, 203, 16, 65, 2, 215, 214, 3, 74, 94, 202, 1, 65, 38, 68, + 46, 84, 46, 86, 186, 24, 85, 210, 200, 1, 73, 158, 190, 1, 78, 46, 83, + 82, 66, 2, 67, 2, 71, 2, 74, 2, 75, 2, 80, 254, 68, 72, 2, 76, 2, 77, 2, + 82, 2, 89, 186, 2, 69, 3, 79, 9, 206, 232, 3, 65, 2, 73, 3, 85, 8, 246, + 160, 3, 68, 254, 68, 72, 187, 2, 65, 8, 202, 160, 3, 84, 254, 68, 72, + 187, 2, 65, 10, 238, 3, 79, 231, 227, 3, 65, 12, 21, 3, 71, 78, 32, 12, + 42, 65, 74, 67, 98, 78, 203, 162, 3, 86, 4, 26, 86, 247, 161, 3, 78, 2, + 21, 3, 65, 71, 82, 2, 255, 238, 1, 65, 2, 11, 65, 2, 11, 78, 2, 25, 4, + 68, 82, 65, 66, 2, 11, 73, 2, 11, 78, 2, 243, 192, 3, 68, 2, 11, 85, 2, + 239, 192, 3, 75, 30, 78, 65, 38, 83, 70, 86, 214, 20, 85, 210, 200, 1, + 73, 206, 134, 2, 69, 3, 79, 6, 214, 228, 3, 65, 2, 73, 3, 85, 4, 25, 4, + 72, 79, 82, 84, 4, 11, 32, 4, 138, 228, 3, 69, 3, 79, 8, 11, 79, 8, 33, + 6, 67, 65, 76, 73, 67, 32, 8, 26, 82, 139, 231, 2, 76, 5, 163, 227, 3, + 82, 4, 128, 174, 3, 8, 67, 65, 80, 73, 84, 65, 76, 32, 227, 24, 69, 138, + 1, 210, 1, 77, 18, 78, 34, 79, 80, 2, 80, 32, 152, 9, 23, 82, 84, 79, 73, + 83, 69, 32, 83, 72, 69, 76, 76, 32, 66, 82, 65, 67, 75, 69, 84, 69, 68, + 32, 130, 4, 84, 198, 246, 1, 73, 169, 67, 5, 75, 89, 79, 32, 84, 2, 239, + 20, 65, 2, 11, 71, 2, 135, 202, 3, 85, 6, 32, 2, 84, 72, 131, 212, 2, 76, + 5, 11, 66, 2, 11, 82, 2, 239, 250, 1, 85, 40, 140, 1, 4, 65, 82, 67, 32, + 162, 2, 67, 44, 2, 72, 65, 218, 1, 80, 126, 76, 22, 82, 138, 1, 83, 38, + 84, 81, 7, 87, 73, 84, 72, 32, 85, 80, 6, 180, 1, 19, 65, 78, 84, 73, 67, + 76, 79, 67, 75, 87, 73, 83, 69, 32, 65, 82, 82, 79, 87, 73, 21, 67, 76, + 79, 67, 75, 87, 73, 83, 69, 32, 65, 82, 82, 79, 87, 32, 87, 73, 84, 72, + 32, 5, 29, 5, 32, 87, 73, 84, 72, 2, 17, 2, 32, 80, 2, 143, 218, 1, 76, + 2, 11, 77, 2, 227, 217, 1, 73, 2, 11, 85, 2, 213, 137, 3, 3, 82, 76, 89, + 12, 36, 3, 76, 70, 32, 247, 219, 3, 84, 10, 50, 66, 46, 76, 26, 82, 114, + 83, 143, 214, 1, 73, 2, 11, 76, 2, 145, 140, 2, 3, 65, 67, 75, 2, 11, 69, + 2, 35, 70, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 17, 2, 32, 80, 2, 33, 6, + 65, 82, 69, 78, 84, 72, 2, 167, 189, 1, 69, 2, 11, 69, 2, 11, 67, 2, 11, + 84, 2, 11, 73, 2, 191, 227, 1, 79, 6, 41, 2, 69, 70, 6, 21, 3, 73, 71, + 72, 6, 17, 2, 84, 32, 6, 42, 67, 249, 133, 3, 4, 72, 65, 76, 70, 4, 26, + 79, 191, 223, 2, 82, 2, 211, 154, 3, 82, 2, 185, 133, 3, 4, 81, 85, 65, + 82, 2, 11, 79, 2, 149, 133, 3, 12, 82, 84, 79, 73, 83, 69, 32, 83, 72, + 69, 76, 76, 2, 29, 5, 87, 65, 82, 68, 83, 2, 17, 2, 32, 65, 2, 141, 218, + 2, 4, 82, 82, 79, 87, 20, 188, 1, 22, 67, 74, 75, 32, 85, 78, 73, 70, 73, + 69, 68, 32, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 161, 2, 19, 76, 65, + 84, 73, 78, 32, 67, 65, 80, 73, 84, 65, 76, 32, 76, 69, 84, 84, 69, 18, + 40, 2, 52, 69, 34, 53, 54, 54, 87, 55, 4, 202, 1, 48, 203, 172, 2, 56, 4, + 30, 50, 141, 1, 2, 66, 56, 2, 159, 142, 3, 68, 6, 48, 2, 50, 53, 22, 53, + 249, 172, 2, 2, 55, 50, 2, 235, 211, 3, 51, 2, 67, 53, 4, 32, 2, 48, 66, + 21, 2, 54, 68, 2, 167, 211, 3, 57, 2, 147, 211, 3, 55, 2, 11, 82, 2, 163, + 149, 3, 32, 64, 48, 6, 65, 76, 32, 82, 85, 78, 21, 2, 79, 32, 2, 235, + 216, 2, 79, 62, 72, 7, 76, 69, 84, 84, 69, 82, 32, 229, 2, 6, 83, 73, 71, + 78, 32, 82, 60, 202, 1, 66, 102, 73, 22, 78, 138, 144, 1, 69, 198, 71, + 67, 170, 183, 1, 65, 222, 61, 68, 2, 71, 2, 72, 2, 74, 2, 75, 2, 76, 2, + 77, 2, 80, 2, 82, 2, 83, 2, 84, 2, 87, 2, 89, 186, 2, 79, 3, 85, 12, 52, + 7, 82, 69, 65, 84, 72, 89, 32, 203, 207, 3, 65, 10, 42, 73, 158, 144, 1, + 69, 175, 168, 2, 65, 5, 155, 207, 3, 85, 4, 206, 204, 3, 71, 187, 2, 65, + 2, 17, 2, 73, 83, 2, 21, 3, 73, 78, 71, 2, 11, 32, 2, 135, 165, 2, 84, + 98, 46, 65, 138, 2, 73, 246, 11, 79, 195, 1, 85, 16, 66, 67, 36, 2, 68, + 69, 34, 77, 32, 2, 78, 83, 243, 252, 2, 73, 4, 222, 200, 1, 75, 239, 203, + 1, 84, 2, 153, 16, 4, 32, 77, 65, 82, 5, 11, 32, 2, 175, 170, 2, 67, 4, + 44, 2, 80, 76, 33, 5, 86, 69, 82, 83, 65, 2, 11, 85, 2, 147, 173, 3, 84, + 2, 231, 48, 76, 66, 156, 1, 3, 65, 78, 71, 176, 3, 8, 68, 69, 78, 84, 32, + 69, 77, 66, 20, 9, 71, 82, 65, 77, 32, 70, 79, 82, 32, 140, 2, 4, 80, 76, + 69, 32, 255, 244, 2, 67, 16, 48, 2, 76, 69, 245, 1, 5, 85, 76, 65, 82, + 32, 10, 44, 6, 32, 87, 73, 84, 72, 32, 163, 1, 45, 8, 80, 9, 83, 69, 82, + 73, 70, 83, 32, 65, 84, 54, 85, 150, 136, 2, 82, 147, 64, 68, 2, 17, 2, + 32, 66, 2, 145, 184, 3, 3, 79, 84, 84, 2, 173, 47, 2, 78, 68, 2, 177, + 168, 2, 4, 72, 69, 65, 68, 6, 68, 9, 70, 76, 65, 71, 32, 79, 78, 32, 80, + 34, 82, 131, 235, 1, 66, 2, 11, 79, 2, 155, 171, 3, 83, 2, 11, 85, 2, + 199, 137, 3, 76, 2, 231, 180, 3, 76, 16, 66, 69, 34, 72, 34, 76, 22, 77, + 46, 84, 42, 87, 227, 179, 1, 70, 2, 11, 65, 2, 171, 199, 1, 82, 2, 11, + 69, 2, 163, 217, 1, 65, 2, 163, 150, 3, 65, 2, 21, 3, 79, 85, 78, 2, 159, + 154, 2, 84, 2, 17, 2, 72, 85, 2, 183, 161, 1, 78, 4, 198, 142, 2, 65, + 239, 40, 73, 30, 176, 2, 3, 67, 79, 76, 24, 20, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 32, 66, 65, 82, 32, 87, 73, 84, 72, 32, 98, 80, 34, 84, + 20, 13, 86, 69, 82, 84, 73, 67, 65, 76, 32, 66, 65, 82, 32, 44, 9, 83, + 79, 76, 73, 68, 85, 83, 32, 66, 232, 8, 2, 68, 65, 224, 168, 1, 6, 78, + 69, 83, 84, 69, 68, 163, 11, 73, 2, 145, 24, 2, 79, 78, 4, 34, 68, 33, 4, + 84, 82, 73, 80, 2, 17, 2, 79, 85, 2, 11, 66, 2, 133, 145, 3, 2, 76, 69, + 4, 218, 190, 1, 76, 143, 107, 82, 2, 171, 171, 1, 73, 8, 42, 66, 74, 68, + 198, 161, 1, 82, 111, 87, 2, 29, 5, 73, 78, 65, 82, 89, 2, 21, 3, 32, 82, + 69, 2, 251, 19, 76, 2, 25, 4, 69, 76, 73, 77, 2, 183, 137, 2, 73, 10, 24, + 2, 76, 76, 35, 80, 5, 229, 188, 1, 3, 69, 89, 66, 6, 44, 5, 73, 67, 65, + 76, 32, 191, 173, 3, 72, 4, 18, 68, 47, 70, 2, 11, 82, 2, 11, 73, 2, 191, + 187, 3, 78, 2, 167, 217, 1, 73, 6, 18, 69, 79, 77, 5, 205, 153, 3, 14, + 32, 76, 73, 71, 72, 84, 32, 77, 79, 79, 78, 32, 65, 82, 2, 195, 136, 3, + 80, 56, 80, 3, 71, 82, 73, 22, 82, 148, 165, 2, 5, 77, 66, 76, 69, 82, + 151, 150, 1, 76, 2, 255, 181, 2, 75, 50, 50, 75, 84, 4, 78, 69, 68, 32, + 171, 154, 2, 84, 4, 48, 6, 73, 83, 72, 32, 76, 73, 167, 170, 3, 69, 2, + 11, 82, 2, 247, 180, 2, 65, 44, 238, 1, 65, 80, 6, 66, 76, 65, 67, 75, + 32, 40, 7, 87, 72, 73, 84, 69, 32, 83, 22, 67, 50, 68, 96, 2, 78, 79, 32, + 2, 79, 75, 30, 83, 185, 146, 3, 21, 71, 82, 69, 69, 75, 32, 83, 77, 65, + 76, 76, 32, 76, 69, 84, 84, 69, 82, 32, 73, 79, 4, 26, 77, 147, 152, 2, + 78, 2, 17, 2, 80, 69, 2, 11, 82, 2, 179, 171, 2, 83, 4, 18, 80, 23, 83, + 2, 223, 129, 2, 69, 2, 207, 131, 2, 72, 4, 144, 3, 5, 65, 80, 73, 84, 65, + 167, 106, 79, 6, 30, 65, 33, 3, 73, 71, 73, 2, 11, 71, 2, 147, 250, 2, + 71, 4, 129, 203, 1, 3, 84, 32, 84, 6, 162, 2, 82, 183, 174, 2, 84, 2, + 177, 209, 1, 2, 32, 72, 14, 128, 1, 18, 65, 78, 83, 45, 83, 69, 82, 73, + 70, 32, 67, 65, 80, 73, 84, 65, 76, 32, 38, 69, 32, 3, 77, 65, 76, 33, 2, + 79, 85, 6, 254, 181, 3, 71, 2, 76, 3, 89, 2, 11, 77, 2, 203, 229, 2, 73, + 2, 11, 76, 2, 163, 180, 2, 32, 4, 21, 3, 84, 72, 32, 4, 32, 2, 69, 65, 1, + 2, 87, 69, 2, 53, 11, 83, 84, 32, 80, 79, 73, 78, 84, 73, 78, 71, 2, 17, + 2, 32, 76, 2, 251, 178, 2, 69, 36, 58, 69, 52, 8, 73, 83, 84, 69, 68, 32, + 82, 73, 63, 79, 2, 17, 2, 76, 86, 2, 209, 159, 1, 3, 69, 32, 80, 2, 17, + 2, 71, 72, 2, 153, 93, 6, 84, 87, 65, 82, 68, 83, 32, 30, 32, 249, 9, 2, + 45, 69, 30, 200, 2, 24, 65, 83, 84, 69, 82, 73, 83, 75, 83, 32, 65, 76, + 73, 71, 78, 69, 68, 32, 86, 69, 82, 84, 73, 67, 34, 66, 86, 67, 116, 3, + 68, 79, 84, 226, 1, 72, 44, 14, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, + 78, 71, 32, 76, 92, 6, 74, 79, 73, 78, 69, 68, 64, 8, 76, 79, 71, 73, 67, + 65, 76, 32, 98, 77, 0, 3, 87, 79, 77, 119, 83, 2, 11, 65, 2, 171, 140, 3, + 76, 2, 29, 5, 85, 84, 84, 79, 78, 2, 17, 2, 32, 77, 2, 11, 79, 2, 147, + 166, 2, 85, 2, 93, 21, 79, 78, 83, 69, 67, 85, 84, 73, 86, 69, 32, 69, + 81, 85, 65, 76, 83, 32, 83, 73, 71, 2, 195, 240, 2, 78, 6, 18, 32, 55, + 83, 4, 22, 76, 131, 1, 80, 2, 225, 137, 1, 2, 69, 65, 2, 53, 11, 32, 79, + 86, 69, 82, 32, 79, 78, 69, 32, 68, 2, 11, 79, 2, 11, 84, 2, 17, 2, 32, + 80, 2, 29, 5, 85, 78, 67, 84, 85, 2, 239, 219, 2, 65, 2, 11, 69, 2, 11, + 65, 2, 243, 151, 2, 82, 4, 17, 2, 79, 71, 4, 25, 4, 73, 67, 65, 76, 4, + 11, 32, 4, 214, 157, 2, 65, 147, 85, 79, 2, 17, 2, 32, 83, 2, 21, 3, 81, + 85, 65, 2, 139, 151, 2, 82, 4, 30, 79, 13, 3, 65, 78, 68, 2, 11, 82, 2, + 11, 32, 2, 11, 79, 2, 11, 80, 2, 183, 17, 69, 2, 11, 69, 2, 45, 9, 78, + 32, 72, 79, 76, 68, 73, 78, 71, 2, 11, 32, 2, 11, 72, 2, 11, 65, 2, 207, + 204, 1, 78, 2, 49, 10, 80, 69, 69, 67, 72, 32, 66, 85, 66, 66, 2, 239, + 148, 2, 76, 2, 11, 77, 2, 133, 195, 1, 2, 32, 68, 140, 3, 140, 1, 8, 71, + 65, 82, 73, 84, 73, 67, 32, 148, 6, 7, 77, 66, 82, 69, 76, 76, 65, 166, + 1, 78, 154, 8, 80, 174, 148, 1, 82, 135, 131, 2, 83, 62, 48, 7, 76, 69, + 84, 84, 69, 82, 32, 159, 5, 87, 60, 206, 1, 65, 28, 2, 81, 79, 22, 66, + 22, 68, 50, 71, 44, 2, 72, 79, 22, 75, 34, 76, 32, 2, 82, 65, 22, 83, 74, + 84, 74, 89, 22, 90, 186, 161, 2, 78, 178, 91, 80, 246, 5, 87, 202, 12, + 77, 174, 18, 73, 3, 85, 4, 26, 76, 143, 213, 2, 73, 2, 167, 162, 3, 80, + 2, 255, 255, 2, 69, 4, 26, 69, 247, 154, 2, 72, 2, 207, 255, 2, 76, 4, + 214, 248, 1, 72, 153, 137, 1, 2, 65, 77, 5, 163, 161, 3, 84, 4, 186, 162, + 2, 65, 215, 126, 72, 2, 11, 65, 2, 151, 254, 2, 77, 2, 203, 171, 1, 83, + 8, 38, 65, 146, 163, 2, 72, 215, 90, 83, 4, 246, 139, 3, 68, 239, 13, 77, + 6, 38, 72, 218, 133, 3, 69, 175, 28, 79, 2, 11, 65, 2, 179, 231, 1, 78, + 2, 207, 219, 2, 79, 4, 130, 253, 2, 69, 207, 36, 85, 2, 21, 3, 79, 82, + 68, 2, 25, 4, 32, 68, 73, 86, 2, 139, 125, 73, 7, 11, 32, 4, 84, 4, 79, + 78, 32, 71, 45, 13, 87, 73, 84, 72, 32, 82, 65, 73, 78, 32, 68, 82, 79, + 2, 11, 82, 2, 11, 79, 2, 143, 146, 2, 85, 2, 139, 226, 2, 80, 32, 160, 1, + 3, 65, 77, 85, 20, 7, 67, 69, 82, 84, 65, 73, 78, 34, 68, 62, 73, 241, 5, + 18, 77, 65, 82, 82, 73, 69, 68, 32, 80, 65, 82, 84, 78, 69, 82, 83, 72, + 73, 2, 227, 141, 2, 83, 2, 11, 84, 2, 155, 151, 2, 89, 4, 26, 69, 199, + 138, 2, 79, 2, 11, 82, 2, 151, 130, 3, 84, 22, 60, 2, 79, 78, 230, 3, 84, + 106, 86, 201, 43, 3, 67, 79, 82, 15, 11, 32, 12, 160, 1, 6, 65, 66, 79, + 86, 69, 32, 108, 22, 66, 69, 83, 73, 68, 69, 32, 65, 78, 68, 32, 74, 79, + 73, 78, 69, 68, 32, 87, 73, 84, 72, 41, 5, 87, 73, 84, 72, 32, 4, 52, 9, + 66, 65, 82, 32, 65, 66, 79, 86, 69, 23, 73, 2, 17, 2, 32, 73, 2, 229, 39, + 4, 78, 84, 69, 82, 2, 17, 2, 32, 85, 2, 139, 202, 2, 78, 6, 66, 77, 58, + 79, 217, 224, 2, 8, 76, 79, 71, 73, 67, 65, 76, 32, 2, 11, 73, 2, 11, 78, + 2, 11, 85, 2, 223, 146, 2, 83, 2, 11, 86, 2, 229, 73, 2, 69, 82, 4, 18, + 32, 67, 69, 2, 11, 83, 2, 17, 2, 69, 80, 2, 11, 65, 2, 219, 223, 2, 82, + 2, 171, 133, 2, 68, 2, 57, 12, 69, 82, 83, 65, 76, 32, 82, 69, 67, 89, + 67, 76, 2, 17, 2, 73, 78, 2, 199, 132, 2, 71, 2, 179, 132, 2, 80, 164, 2, + 170, 1, 32, 128, 8, 10, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 248, 3, + 4, 80, 69, 82, 32, 168, 29, 8, 83, 73, 68, 69, 45, 68, 79, 87, 21, 6, 87, + 65, 82, 68, 83, 32, 38, 140, 1, 5, 65, 82, 82, 79, 87, 240, 1, 5, 66, 65, + 82, 66, 32, 228, 1, 5, 68, 79, 87, 78, 32, 210, 1, 70, 30, 82, 89, 4, 84, + 65, 67, 75, 8, 60, 7, 32, 84, 72, 82, 79, 85, 71, 21, 4, 72, 69, 65, 68, + 2, 143, 197, 1, 72, 7, 11, 32, 4, 112, 22, 66, 69, 84, 87, 69, 69, 78, + 32, 84, 87, 79, 32, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 159, 134, 2, + 73, 2, 181, 254, 1, 2, 32, 66, 8, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, + 72, 4, 57, 12, 84, 32, 68, 79, 87, 78, 32, 66, 65, 82, 66, 32, 4, 44, 3, + 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 11, 84, 2, 25, 4, 32, 72, 65, 82, 2, + 11, 80, 2, 207, 193, 2, 79, 14, 76, 5, 65, 82, 82, 79, 87, 62, 66, 38, + 68, 18, 83, 202, 43, 87, 215, 9, 84, 5, 37, 7, 32, 87, 73, 84, 72, 32, + 66, 2, 175, 135, 2, 65, 2, 209, 245, 1, 4, 76, 65, 67, 75, 2, 147, 44, + 79, 2, 131, 50, 65, 2, 11, 73, 2, 155, 98, 83, 2, 53, 11, 73, 71, 72, 84, + 32, 68, 73, 65, 71, 79, 78, 2, 225, 113, 4, 65, 76, 32, 69, 5, 29, 5, 32, + 87, 73, 84, 72, 2, 33, 6, 32, 67, 73, 82, 67, 76, 2, 159, 145, 2, 69, 14, + 96, 8, 77, 73, 76, 73, 84, 65, 82, 89, 20, 6, 83, 77, 65, 76, 76, 32, 22, + 65, 66, 82, 35, 84, 2, 37, 2, 32, 65, 4, 18, 65, 67, 82, 2, 11, 73, 2, + 11, 82, 2, 17, 2, 80, 76, 2, 179, 243, 1, 65, 2, 11, 69, 2, 199, 232, 1, + 68, 4, 37, 7, 82, 73, 65, 78, 71, 76, 69, 4, 11, 32, 4, 11, 87, 4, 25, 4, + 73, 84, 72, 32, 4, 18, 76, 27, 82, 2, 11, 69, 2, 35, 70, 2, 21, 3, 73, + 71, 72, 2, 11, 84, 2, 17, 2, 32, 72, 2, 21, 3, 65, 76, 70, 2, 17, 2, 32, + 66, 2, 11, 76, 2, 207, 219, 1, 65, 110, 172, 1, 4, 65, 78, 68, 32, 186, + 2, 66, 74, 70, 36, 5, 72, 65, 76, 70, 32, 148, 3, 5, 76, 69, 70, 84, 32, + 226, 5, 79, 60, 6, 82, 73, 71, 72, 84, 32, 218, 12, 83, 63, 84, 8, 34, + 76, 53, 4, 82, 73, 71, 72, 6, 48, 2, 69, 70, 149, 1, 5, 79, 87, 69, 82, + 32, 2, 53, 11, 84, 32, 65, 78, 68, 32, 76, 79, 87, 69, 82, 2, 217, 25, + 19, 32, 84, 82, 73, 65, 78, 71, 85, 76, 65, 82, 32, 84, 72, 82, 69, 69, + 32, 81, 4, 28, 2, 84, 82, 179, 29, 79, 2, 205, 3, 7, 73, 65, 78, 71, 85, + 76, 65, 2, 17, 2, 76, 65, 2, 17, 2, 68, 69, 2, 177, 208, 1, 3, 32, 83, + 67, 2, 17, 2, 73, 86, 2, 191, 22, 69, 12, 96, 5, 66, 76, 79, 67, 75, 108, + 8, 73, 78, 86, 69, 82, 83, 69, 32, 254, 19, 77, 227, 160, 1, 67, 5, 209, + 20, 23, 32, 65, 78, 68, 32, 76, 79, 87, 69, 82, 32, 72, 65, 76, 70, 32, + 73, 78, 86, 69, 82, 83, 69, 4, 100, 21, 77, 69, 68, 73, 85, 77, 32, 83, + 72, 65, 68, 69, 32, 65, 78, 68, 32, 76, 79, 87, 69, 51, 87, 2, 11, 82, 2, + 141, 26, 5, 32, 72, 65, 76, 70, 2, 21, 3, 72, 73, 84, 2, 147, 179, 1, 69, + 34, 106, 66, 238, 3, 67, 54, 84, 176, 9, 13, 79, 82, 32, 76, 79, 87, 69, + 82, 32, 82, 73, 71, 72, 143, 1, 81, 22, 65, 14, 76, 79, 67, 75, 32, 68, + 73, 65, 71, 79, 78, 65, 76, 32, 22, 144, 1, 6, 76, 79, 87, 69, 82, 32, + 173, 6, 24, 85, 80, 80, 69, 82, 32, 77, 73, 68, 68, 76, 69, 32, 76, 69, + 70, 84, 32, 84, 79, 32, 85, 80, 80, 18, 176, 1, 10, 67, 69, 78, 84, 82, + 69, 32, 84, 79, 32, 36, 8, 76, 69, 70, 84, 32, 84, 79, 32, 169, 8, 18, + 77, 73, 68, 68, 76, 69, 32, 76, 69, 70, 84, 32, 84, 79, 32, 85, 80, 80, + 6, 70, 76, 193, 6, 3, 85, 80, 80, 6, 34, 76, 153, 7, 3, 85, 80, 80, 2, + 217, 7, 2, 79, 87, 2, 29, 5, 79, 82, 78, 69, 82, 2, 139, 218, 1, 32, 6, + 22, 79, 187, 12, 82, 2, 129, 12, 11, 32, 76, 79, 87, 69, 82, 32, 82, 73, + 71, 72, 4, 11, 78, 4, 17, 2, 69, 32, 4, 150, 15, 81, 139, 4, 69, 40, 128, + 1, 2, 66, 76, 186, 6, 68, 100, 12, 79, 82, 32, 76, 79, 87, 69, 82, 32, + 76, 69, 70, 106, 80, 38, 81, 104, 2, 83, 72, 51, 84, 22, 61, 13, 79, 67, + 75, 32, 68, 73, 65, 71, 79, 78, 65, 76, 32, 22, 140, 1, 24, 76, 79, 87, + 69, 82, 32, 77, 73, 68, 68, 76, 69, 32, 76, 69, 70, 84, 32, 84, 79, 32, + 76, 79, 87, 57, 6, 85, 80, 80, 69, 82, 32, 4, 21, 3, 69, 82, 32, 4, 246, + 3, 67, 211, 202, 2, 82, 18, 176, 1, 10, 67, 69, 78, 84, 82, 69, 32, 84, + 79, 32, 92, 8, 76, 69, 70, 84, 32, 84, 79, 32, 141, 1, 18, 77, 73, 68, + 68, 76, 69, 32, 76, 69, 70, 84, 32, 84, 79, 32, 76, 79, 87, 6, 32, 3, 76, + 79, 87, 139, 1, 85, 4, 21, 3, 69, 82, 32, 4, 142, 2, 77, 171, 202, 2, 82, + 6, 28, 3, 76, 79, 87, 51, 85, 4, 21, 3, 69, 82, 32, 4, 142, 1, 67, 43, + 77, 2, 17, 2, 80, 80, 2, 17, 2, 69, 82, 2, 117, 2, 32, 77, 6, 21, 3, 69, + 82, 32, 6, 34, 67, 42, 77, 171, 202, 2, 82, 2, 11, 69, 2, 241, 212, 1, 2, + 78, 84, 2, 25, 4, 73, 68, 68, 76, 2, 203, 166, 1, 69, 2, 65, 14, 82, 79, + 80, 45, 83, 72, 65, 68, 79, 87, 69, 68, 32, 87, 2, 225, 181, 1, 3, 72, + 73, 84, 2, 69, 15, 84, 32, 67, 85, 82, 76, 89, 32, 66, 82, 65, 67, 75, + 69, 84, 2, 11, 32, 2, 179, 162, 2, 83, 2, 11, 69, 2, 249, 69, 2, 78, 67, + 2, 81, 18, 85, 65, 68, 82, 65, 78, 84, 32, 67, 73, 82, 67, 85, 76, 65, + 82, 32, 65, 2, 163, 203, 1, 82, 4, 245, 97, 8, 65, 68, 79, 87, 69, 68, + 32, 87, 6, 18, 79, 107, 82, 2, 49, 10, 32, 76, 79, 87, 69, 82, 32, 76, + 69, 70, 2, 11, 84, 2, 11, 32, 2, 11, 70, 2, 163, 108, 73, 4, 25, 4, 73, + 65, 78, 71, 4, 40, 4, 85, 76, 65, 82, 171, 217, 2, 76, 2, 17, 2, 32, 77, + 2, 41, 8, 69, 68, 73, 85, 77, 32, 83, 72, 2, 199, 98, 65, 2, 17, 2, 69, + 86, 2, 17, 2, 69, 78, 2, 117, 2, 32, 69, 6, 52, 2, 72, 82, 129, 1, 6, 82, + 73, 65, 78, 71, 85, 4, 21, 3, 69, 69, 32, 4, 18, 69, 35, 81, 2, 65, 5, + 73, 71, 72, 84, 72, 2, 33, 6, 85, 65, 82, 84, 69, 82, 2, 231, 4, 83, 2, + 45, 9, 76, 65, 82, 32, 79, 78, 69, 32, 81, 2, 165, 4, 6, 85, 65, 82, 84, + 69, 82, 2, 203, 175, 2, 78, 128, 1, 146, 1, 65, 174, 6, 66, 154, 1, 68, + 50, 70, 82, 72, 146, 4, 67, 46, 81, 42, 82, 22, 83, 102, 84, 142, 7, 80, + 173, 3, 6, 87, 72, 73, 84, 69, 32, 32, 34, 78, 33, 4, 82, 82, 79, 87, 2, + 11, 67, 2, 207, 166, 2, 79, 31, 11, 32, 28, 134, 1, 65, 180, 1, 14, 76, + 69, 70, 84, 87, 65, 82, 68, 83, 32, 79, 70, 32, 68, 32, 5, 87, 73, 84, + 72, 32, 214, 8, 70, 175, 5, 84, 2, 41, 8, 78, 68, 32, 82, 73, 71, 72, 84, + 2, 17, 2, 32, 79, 2, 25, 4, 78, 69, 32, 69, 2, 29, 5, 73, 71, 72, 84, 72, + 2, 11, 32, 2, 11, 66, 2, 11, 76, 2, 239, 185, 1, 79, 2, 233, 200, 1, 3, + 79, 87, 78, 20, 74, 68, 58, 76, 42, 77, 38, 78, 58, 83, 66, 69, 246, 12, + 84, 139, 59, 72, 2, 21, 3, 79, 85, 66, 2, 11, 76, 2, 131, 183, 2, 69, 2, + 11, 65, 2, 233, 23, 3, 82, 71, 69, 2, 205, 23, 5, 69, 68, 73, 85, 77, 2, + 25, 4, 79, 84, 67, 72, 2, 11, 69, 2, 247, 56, 68, 4, 11, 77, 4, 25, 4, + 65, 76, 76, 32, 4, 22, 69, 203, 22, 84, 2, 237, 22, 10, 81, 85, 73, 76, + 65, 84, 69, 82, 65, 76, 4, 11, 76, 4, 25, 4, 65, 67, 75, 32, 4, 44, 5, + 67, 73, 82, 67, 76, 143, 202, 1, 65, 2, 25, 4, 69, 68, 32, 87, 2, 11, 72, + 2, 229, 14, 2, 73, 84, 4, 22, 79, 187, 13, 65, 2, 169, 14, 2, 85, 66, 2, + 11, 73, 2, 37, 7, 78, 71, 69, 82, 45, 80, 79, 2, 205, 200, 1, 2, 83, 84, + 20, 88, 17, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, 72, 32, 66, 65, 82, + 66, 32, 255, 2, 69, 16, 56, 4, 76, 69, 70, 84, 245, 1, 5, 82, 73, 71, 72, + 84, 10, 22, 32, 231, 9, 87, 8, 60, 7, 66, 69, 83, 73, 68, 69, 32, 206, 1, + 70, 175, 5, 84, 4, 40, 4, 68, 79, 87, 78, 1, 2, 85, 80, 2, 193, 146, 1, + 23, 87, 65, 82, 68, 83, 32, 72, 65, 82, 80, 79, 79, 78, 32, 87, 73, 84, + 72, 32, 66, 65, 82, 66, 6, 22, 32, 243, 7, 87, 4, 22, 70, 175, 5, 84, 2, + 229, 15, 3, 82, 79, 77, 4, 25, 4, 65, 86, 89, 32, 4, 26, 67, 191, 196, 1, + 65, 2, 185, 10, 7, 79, 77, 80, 82, 69, 83, 83, 2, 133, 9, 6, 85, 65, 68, + 82, 85, 80, 2, 195, 139, 2, 79, 4, 30, 65, 53, 3, 81, 85, 65, 2, 153, + 195, 1, 8, 78, 83, 45, 83, 69, 82, 73, 70, 2, 255, 8, 82, 36, 36, 2, 82, + 73, 225, 7, 2, 87, 79, 30, 40, 5, 65, 78, 71, 76, 69, 151, 7, 80, 28, 52, + 8, 45, 72, 69, 65, 68, 69, 68, 32, 199, 13, 32, 26, 48, 5, 65, 82, 82, + 79, 87, 170, 5, 68, 39, 80, 23, 11, 32, 20, 92, 17, 76, 69, 70, 84, 87, + 65, 82, 68, 83, 32, 79, 70, 32, 68, 79, 87, 78, 98, 84, 19, 87, 2, 37, 7, + 87, 65, 82, 68, 83, 32, 84, 2, 37, 7, 82, 73, 65, 78, 71, 76, 69, 2, 215, + 5, 45, 2, 187, 10, 79, 16, 25, 4, 73, 84, 72, 32, 16, 114, 66, 28, 6, 76, + 79, 78, 71, 32, 84, 130, 1, 77, 34, 78, 34, 86, 34, 72, 149, 57, 6, 68, + 79, 85, 66, 76, 69, 2, 149, 2, 3, 79, 76, 68, 4, 17, 2, 73, 80, 4, 11, + 32, 4, 34, 76, 21, 4, 82, 73, 71, 72, 2, 17, 2, 69, 70, 2, 11, 84, 2, 11, + 87, 2, 135, 123, 65, 2, 121, 5, 69, 68, 73, 85, 77, 2, 89, 5, 65, 82, 82, + 79, 87, 2, 29, 5, 69, 82, 89, 32, 72, 2, 25, 4, 69, 65, 86, 89, 2, 237, + 171, 2, 4, 32, 83, 72, 65, 2, 11, 65, 2, 249, 1, 2, 83, 72, 2, 11, 65, 2, + 25, 4, 73, 82, 69, 68, 2, 29, 5, 32, 65, 82, 82, 79, 2, 239, 151, 2, 87, + 2, 11, 76, 2, 227, 186, 1, 69, 6, 74, 32, 61, 14, 45, 72, 69, 65, 68, 69, + 68, 32, 65, 82, 82, 79, 87, 32, 2, 25, 4, 72, 69, 65, 68, 2, 11, 69, 2, + 219, 185, 1, 68, 4, 42, 87, 129, 132, 1, 4, 70, 82, 79, 77, 2, 33, 6, 73, + 84, 72, 32, 84, 82, 2, 61, 13, 73, 65, 78, 71, 76, 69, 32, 65, 82, 82, + 79, 87, 72, 2, 169, 118, 2, 69, 65, 18, 88, 5, 65, 82, 82, 79, 87, 133, + 4, 12, 68, 79, 85, 66, 76, 69, 32, 65, 82, 82, 79, 87, 15, 11, 32, 12, + 104, 8, 70, 82, 79, 77, 32, 66, 65, 82, 40, 11, 79, 78, 32, 80, 69, 68, + 69, 83, 84, 65, 76, 183, 1, 87, 5, 93, 7, 32, 87, 73, 84, 72, 32, 72, 7, + 33, 6, 32, 87, 73, 84, 72, 32, 4, 18, 72, 43, 86, 2, 69, 7, 79, 82, 73, + 90, 79, 78, 84, 2, 29, 5, 69, 82, 84, 73, 67, 2, 17, 2, 65, 76, 2, 11, + 32, 2, 151, 173, 1, 66, 2, 29, 5, 73, 84, 72, 73, 78, 2, 17, 2, 32, 84, + 2, 37, 7, 82, 73, 65, 78, 71, 76, 69, 2, 11, 32, 2, 11, 65, 2, 25, 4, 82, + 82, 79, 87, 2, 11, 72, 2, 239, 135, 2, 69, 5, 45, 9, 32, 79, 78, 32, 80, + 69, 68, 69, 83, 2, 163, 196, 1, 84, 226, 15, 86, 65, 254, 16, 83, 174, 3, + 69, 162, 42, 73, 178, 8, 79, 134, 2, 84, 21, 2, 85, 76, 218, 8, 116, 2, + 73, 32, 128, 16, 17, 82, 73, 65, 84, 73, 79, 78, 32, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 173, 42, 2, 77, 80, 216, 4, 54, 67, 34, 70, 82, 81, 40, + 2, 83, 89, 243, 91, 68, 2, 11, 79, 2, 135, 170, 2, 77, 2, 11, 85, 2, 11, + 76, 2, 11, 76, 2, 11, 32, 2, 11, 83, 2, 195, 209, 1, 84, 2, 17, 2, 85, + 69, 2, 135, 225, 1, 83, 190, 4, 68, 7, 76, 76, 65, 66, 76, 69, 32, 197, + 11, 5, 77, 66, 79, 76, 32, 164, 4, 214, 1, 68, 70, 66, 2, 83, 2, 84, 2, + 90, 70, 71, 122, 72, 82, 75, 134, 1, 76, 130, 1, 77, 86, 78, 134, 3, 67, + 2, 70, 2, 74, 2, 80, 2, 82, 2, 86, 2, 89, 78, 87, 50, 69, 34, 79, 158, + 70, 65, 2, 73, 3, 85, 42, 66, 72, 162, 8, 79, 238, 254, 1, 69, 150, 64, + 65, 2, 73, 3, 85, 28, 230, 7, 72, 58, 79, 238, 254, 1, 69, 150, 64, 65, + 2, 73, 3, 85, 34, 62, 66, 202, 6, 69, 86, 79, 130, 191, 2, 65, 2, 73, 3, + 85, 18, 106, 79, 222, 5, 69, 214, 191, 2, 65, 2, 73, 3, 85, 24, 50, 79, + 222, 5, 69, 214, 71, 65, 2, 73, 3, 85, 7, 174, 197, 2, 78, 3, 79, 34, 70, + 80, 206, 5, 79, 130, 71, 65, 238, 183, 1, 69, 150, 64, 73, 3, 85, 18, + 246, 4, 69, 86, 79, 130, 71, 65, 130, 248, 1, 73, 3, 85, 16, 54, 69, 218, + 4, 79, 130, 191, 2, 65, 2, 73, 3, 85, 7, 26, 78, 191, 195, 2, 69, 2, 21, + 3, 71, 84, 72, 2, 183, 133, 2, 69, 42, 214, 3, 66, 0, 2, 71, 66, 58, 79, + 238, 254, 1, 69, 150, 64, 65, 2, 73, 3, 85, 90, 90, 68, 174, 1, 71, 126, + 74, 2, 89, 58, 79, 238, 254, 1, 69, 150, 64, 65, 2, 73, 3, 85, 24, 54, + 79, 150, 129, 2, 69, 150, 64, 65, 2, 73, 3, 85, 15, 36, 3, 76, 69, 32, + 131, 193, 2, 79, 10, 54, 83, 214, 161, 2, 68, 190, 28, 70, 2, 75, 3, 77, + 2, 211, 161, 2, 79, 25, 42, 71, 182, 240, 1, 65, 2, 69, 3, 79, 16, 50, + 69, 86, 79, 130, 191, 2, 65, 2, 73, 3, 85, 7, 210, 191, 2, 69, 3, 78, 14, + 54, 79, 238, 254, 1, 69, 150, 64, 65, 2, 73, 3, 85, 5, 255, 190, 2, 79, + 28, 46, 69, 34, 79, 158, 70, 65, 2, 73, 3, 85, 9, 186, 70, 69, 131, 248, + 1, 78, 9, 154, 70, 79, 131, 248, 1, 78, 26, 66, 68, 62, 70, 30, 74, 22, + 75, 50, 78, 22, 84, 199, 227, 1, 66, 6, 26, 79, 179, 236, 1, 65, 4, 174, + 236, 1, 79, 251, 49, 45, 4, 74, 69, 251, 185, 2, 65, 2, 243, 235, 1, 79, + 4, 26, 69, 199, 235, 1, 85, 2, 195, 235, 1, 69, 2, 195, 168, 2, 73, 6, + 154, 235, 1, 73, 2, 79, 183, 78, 65, 128, 4, 74, 49, 94, 50, 98, 51, 2, + 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 223, 1, 182, 1, 48, 2, 49, 2, 50, + 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, 3, 57, 137, 1, 90, 48, 2, 49, + 2, 50, 2, 51, 2, 52, 94, 53, 250, 184, 2, 54, 2, 55, 2, 56, 3, 57, 23, + 210, 185, 2, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, 2, 55, 2, 56, + 3, 57, 17, 246, 184, 2, 48, 2, 49, 2, 50, 2, 51, 2, 52, 2, 53, 3, 54, + 180, 1, 116, 4, 68, 73, 67, 32, 222, 19, 82, 208, 148, 1, 13, 67, 84, 79, + 82, 32, 79, 82, 32, 67, 82, 79, 83, 83, 195, 106, 83, 86, 60, 5, 83, 73, + 71, 78, 32, 153, 10, 5, 84, 79, 78, 69, 32, 48, 218, 2, 65, 216, 1, 17, + 68, 79, 85, 66, 76, 69, 32, 65, 78, 85, 83, 86, 65, 82, 65, 32, 65, 98, + 74, 52, 6, 78, 73, 72, 83, 72, 86, 22, 82, 240, 1, 8, 72, 69, 88, 73, 70, + 79, 82, 77, 22, 76, 52, 4, 84, 73, 82, 89, 22, 85, 60, 8, 86, 73, 83, 65, + 82, 71, 65, 32, 237, 6, 17, 89, 65, 74, 85, 82, 86, 69, 68, 73, 67, 32, + 77, 73, 68, 76, 73, 78, 14, 76, 8, 78, 85, 83, 86, 65, 82, 65, 32, 212, + 1, 3, 84, 73, 75, 151, 2, 82, 10, 134, 1, 65, 24, 4, 66, 65, 72, 73, 24, + 9, 85, 66, 72, 65, 89, 65, 84, 79, 32, 201, 4, 10, 86, 65, 77, 65, 71, + 79, 77, 85, 75, 72, 2, 21, 3, 78, 84, 65, 2, 21, 3, 82, 71, 79, 2, 11, + 77, 2, 163, 9, 85, 2, 151, 239, 1, 82, 2, 33, 6, 73, 72, 86, 65, 77, 85, + 2, 151, 3, 76, 2, 235, 174, 2, 65, 8, 144, 1, 15, 69, 86, 69, 82, 83, 69, + 68, 32, 86, 73, 83, 65, 82, 71, 65, 36, 9, 79, 84, 65, 84, 69, 68, 32, + 65, 82, 57, 5, 84, 72, 65, 78, 71, 4, 11, 32, 4, 218, 6, 65, 23, 85, 2, + 25, 4, 68, 72, 65, 86, 2, 245, 236, 1, 2, 73, 83, 2, 17, 2, 32, 76, 2, + 21, 3, 79, 78, 71, 2, 145, 234, 1, 2, 32, 65, 2, 203, 171, 2, 65, 2, 37, + 7, 80, 65, 68, 72, 77, 65, 78, 2, 203, 171, 2, 73, 10, 40, 3, 65, 78, 85, + 2, 85, 179, 9, 83, 4, 25, 4, 68, 65, 84, 84, 4, 11, 65, 5, 25, 4, 32, 87, + 73, 84, 2, 11, 72, 2, 11, 32, 2, 11, 84, 2, 11, 65, 2, 215, 163, 1, 73, + 38, 128, 2, 5, 67, 65, 78, 68, 82, 16, 2, 68, 79, 96, 2, 75, 65, 136, 1, + 4, 80, 82, 69, 78, 16, 2, 82, 73, 106, 84, 164, 1, 11, 89, 65, 74, 85, + 82, 86, 69, 68, 73, 67, 32, 180, 1, 12, 65, 84, 72, 65, 82, 86, 65, 86, + 69, 68, 73, 67, 213, 224, 1, 2, 83, 72, 4, 251, 17, 65, 6, 40, 5, 85, 66, + 76, 69, 32, 191, 3, 84, 4, 22, 82, 211, 5, 83, 2, 11, 73, 2, 251, 1, 78, + 4, 56, 3, 82, 83, 72, 17, 7, 84, 72, 65, 75, 65, 32, 65, 2, 235, 110, 65, + 2, 17, 2, 78, 85, 2, 17, 2, 68, 65, 2, 171, 132, 2, 84, 2, 167, 49, 75, + 4, 82, 78, 237, 2, 15, 71, 86, 69, 68, 73, 67, 32, 75, 65, 83, 72, 77, + 73, 82, 73, 2, 139, 171, 1, 71, 6, 42, 72, 24, 4, 82, 73, 80, 76, 19, 87, + 2, 49, 3, 82, 69, 69, 2, 219, 2, 69, 2, 11, 79, 2, 25, 4, 32, 68, 79, 84, + 2, 11, 83, 2, 11, 32, 2, 159, 14, 66, 8, 176, 1, 10, 65, 71, 71, 82, 65, + 86, 65, 84, 69, 68, 22, 73, 105, 27, 75, 65, 84, 72, 65, 75, 65, 32, 73, + 78, 68, 69, 80, 69, 78, 68, 69, 78, 84, 32, 83, 86, 65, 82, 73, 84, 65, + 2, 17, 2, 32, 73, 2, 49, 10, 78, 68, 69, 80, 69, 78, 68, 69, 78, 84, 2, + 17, 2, 32, 83, 2, 221, 255, 1, 3, 86, 65, 82, 5, 37, 7, 32, 83, 67, 72, + 82, 79, 69, 2, 143, 230, 1, 68, 90, 62, 83, 16, 6, 84, 73, 67, 65, 76, + 32, 221, 13, 2, 89, 32, 2, 171, 84, 73, 62, 208, 2, 4, 66, 65, 82, 32, + 166, 3, 69, 62, 70, 36, 11, 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 67, + 48, 12, 75, 65, 78, 65, 32, 82, 69, 80, 69, 65, 84, 32, 252, 1, 4, 76, + 73, 78, 69, 238, 1, 77, 88, 17, 79, 78, 69, 32, 69, 73, 71, 72, 84, 72, + 32, 66, 76, 79, 67, 75, 45, 62, 84, 192, 73, 3, 83, 73, 88, 241, 32, 5, + 90, 73, 71, 90, 65, 8, 108, 6, 66, 69, 83, 73, 68, 69, 60, 8, 68, 79, 85, + 66, 76, 69, 32, 76, 20, 4, 84, 82, 73, 80, 139, 1, 87, 2, 17, 2, 32, 82, + 2, 21, 3, 73, 71, 72, 2, 187, 123, 84, 2, 69, 2, 69, 70, 2, 25, 4, 76, + 69, 32, 82, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 29, 5, 32, 84, 85, 82, + 78, 2, 11, 83, 2, 11, 84, 2, 219, 124, 73, 2, 21, 3, 73, 84, 72, 2, 17, + 2, 32, 72, 2, 153, 237, 1, 7, 79, 82, 73, 90, 79, 78, 84, 2, 25, 4, 76, + 76, 73, 80, 2, 11, 83, 2, 155, 223, 1, 73, 2, 11, 79, 2, 129, 79, 2, 85, + 82, 2, 17, 2, 32, 73, 2, 237, 178, 1, 2, 84, 69, 10, 120, 4, 77, 65, 82, + 75, 45, 22, 87, 73, 84, 72, 32, 86, 79, 73, 67, 69, 68, 32, 83, 79, 85, + 78, 68, 32, 77, 65, 82, 75, 7, 11, 32, 4, 50, 85, 21, 3, 76, 79, 87, 5, + 17, 2, 32, 85, 2, 17, 2, 80, 80, 2, 17, 2, 69, 82, 2, 129, 26, 2, 32, 72, + 11, 11, 32, 8, 38, 69, 49, 5, 87, 73, 84, 72, 32, 2, 25, 4, 88, 84, 69, + 78, 2, 255, 200, 1, 83, 6, 40, 4, 67, 73, 82, 67, 207, 135, 1, 77, 4, 11, + 76, 4, 11, 69, 4, 11, 32, 4, 26, 66, 223, 155, 1, 65, 2, 11, 69, 2, 159, + 126, 76, 2, 65, 14, 65, 76, 69, 32, 87, 73, 84, 72, 32, 83, 84, 82, 79, + 75, 2, 239, 144, 1, 69, 12, 194, 151, 2, 50, 2, 51, 2, 52, 2, 53, 2, 54, + 3, 55, 10, 32, 2, 65, 66, 106, 73, 19, 82, 6, 18, 32, 35, 85, 2, 11, 75, + 2, 251, 132, 2, 69, 4, 33, 6, 76, 65, 84, 73, 79, 78, 5, 199, 45, 32, 2, + 135, 9, 76, 2, 29, 5, 65, 70, 70, 73, 67, 2, 249, 234, 1, 2, 32, 76, 26, + 80, 6, 72, 69, 65, 86, 89, 32, 176, 5, 3, 77, 85, 67, 233, 9, 3, 66, 79, + 76, 20, 62, 69, 190, 1, 70, 38, 82, 82, 83, 246, 1, 87, 207, 10, 71, 4, + 25, 4, 73, 71, 72, 84, 4, 11, 32, 4, 22, 80, 223, 2, 83, 2, 25, 4, 79, + 73, 78, 84, 2, 17, 2, 69, 68, 2, 17, 2, 32, 66, 2, 25, 4, 76, 65, 67, 75, + 2, 11, 32, 2, 139, 79, 83, 2, 11, 73, 2, 185, 1, 2, 86, 69, 2, 11, 69, 2, + 29, 5, 86, 69, 82, 83, 69, 2, 17, 2, 32, 83, 2, 231, 1, 79, 6, 30, 65, + 42, 73, 147, 1, 79, 2, 11, 76, 2, 11, 84, 2, 147, 113, 73, 2, 11, 88, 2, + 11, 32, 2, 11, 83, 2, 21, 3, 80, 79, 75, 2, 17, 2, 69, 68, 2, 11, 32, 2, + 11, 65, 2, 11, 83, 2, 129, 78, 3, 84, 69, 82, 2, 165, 13, 3, 76, 73, 68, + 4, 21, 3, 72, 73, 84, 4, 11, 69, 4, 11, 32, 4, 190, 64, 67, 199, 46, 83, + 4, 11, 72, 4, 11, 32, 4, 18, 71, 39, 76, 2, 69, 6, 82, 69, 65, 84, 69, + 82, 2, 11, 69, 2, 11, 83, 2, 11, 83, 2, 17, 2, 45, 84, 2, 239, 70, 72, + 160, 1, 140, 1, 9, 66, 82, 65, 84, 73, 79, 78, 32, 77, 34, 67, 32, 3, 68, + 69, 79, 126, 69, 218, 1, 79, 22, 82, 21, 7, 84, 72, 75, 85, 81, 73, 32, + 2, 11, 79, 2, 159, 246, 1, 68, 2, 221, 126, 4, 84, 79, 82, 89, 6, 30, 32, + 77, 3, 67, 65, 83, 4, 18, 67, 43, 71, 2, 17, 2, 65, 77, 2, 195, 199, 1, + 69, 2, 143, 116, 65, 2, 147, 71, 83, 6, 168, 1, 31, 84, 78, 65, 77, 69, + 83, 69, 32, 65, 76, 84, 69, 82, 78, 65, 84, 69, 32, 82, 69, 65, 68, 73, + 78, 71, 32, 77, 65, 82, 75, 32, 193, 105, 5, 87, 68, 65, 84, 65, 4, 26, + 78, 199, 135, 2, 67, 2, 143, 126, 72, 2, 175, 138, 1, 76, 2, 227, 234, 1, + 71, 140, 1, 56, 6, 67, 65, 80, 73, 84, 65, 1, 4, 83, 77, 65, 76, 70, 45, + 9, 76, 32, 76, 69, 84, 84, 69, 82, 32, 70, 230, 1, 66, 34, 69, 22, 73, + 22, 76, 34, 78, 254, 133, 1, 67, 2, 68, 2, 83, 2, 84, 214, 56, 72, 226, + 48, 70, 2, 74, 2, 77, 2, 80, 2, 82, 2, 86, 2, 88, 2, 90, 158, 20, 71, 2, + 75, 2, 81, 186, 2, 65, 2, 79, 2, 85, 3, 89, 4, 150, 240, 1, 66, 215, 22, + 69, 5, 203, 134, 2, 73, 5, 227, 239, 1, 74, 4, 234, 131, 2, 76, 187, 2, + 65, 4, 174, 239, 1, 74, 215, 22, 69, 8, 28, 3, 73, 68, 69, 59, 76, 2, 21, + 3, 68, 32, 71, 2, 177, 71, 4, 82, 69, 69, 75, 6, 46, 67, 20, 3, 76, 69, + 89, 41, 2, 85, 77, 2, 203, 219, 1, 65, 2, 11, 66, 2, 11, 65, 2, 147, 123, + 76, 2, 11, 69, 2, 17, 2, 32, 73, 2, 201, 122, 4, 78, 84, 69, 71, 5, 223, + 131, 2, 83, 40, 70, 67, 45, 13, 71, 65, 82, 32, 70, 82, 65, 67, 84, 73, + 79, 78, 32, 2, 11, 65, 2, 11, 78, 2, 155, 197, 1, 85, 38, 106, 70, 96, 4, + 79, 78, 69, 32, 174, 2, 84, 80, 7, 83, 69, 86, 69, 78, 32, 69, 145, 33, + 3, 90, 69, 82, 6, 56, 4, 73, 86, 69, 32, 249, 3, 5, 79, 85, 82, 32, 70, + 4, 158, 3, 69, 113, 3, 83, 73, 88, 18, 66, 69, 28, 2, 70, 73, 18, 72, 30, + 78, 14, 81, 30, 83, 55, 84, 2, 193, 1, 3, 73, 71, 72, 2, 167, 1, 70, 2, + 11, 65, 2, 131, 127, 76, 2, 111, 73, 2, 165, 73, 3, 85, 65, 82, 4, 24, 2, + 69, 86, 15, 73, 2, 43, 69, 2, 43, 88, 4, 18, 69, 35, 72, 2, 11, 78, 2, + 243, 253, 1, 84, 2, 155, 104, 73, 10, 48, 5, 72, 82, 69, 69, 32, 93, 3, + 87, 79, 32, 6, 26, 69, 26, 81, 67, 70, 2, 109, 3, 73, 71, 72, 2, 21, 3, + 85, 65, 82, 2, 151, 111, 84, 4, 22, 70, 211, 32, 84, 2, 11, 73, 2, 11, + 70, 2, 205, 191, 1, 2, 84, 72, 156, 6, 86, 65, 242, 23, 69, 158, 3, 72, + 142, 66, 73, 234, 8, 79, 134, 6, 82, 167, 144, 1, 74, 204, 2, 122, 78, + 220, 5, 2, 88, 73, 158, 1, 82, 210, 10, 84, 194, 1, 86, 252, 70, 2, 70, + 70, 233, 78, 6, 83, 84, 69, 66, 65, 83, 122, 36, 4, 67, 72, 79, 32, 183, + 5, 73, 118, 100, 7, 76, 69, 84, 84, 69, 82, 32, 252, 3, 3, 78, 71, 85, + 16, 5, 84, 79, 78, 69, 32, 243, 7, 68, 88, 210, 1, 65, 38, 79, 34, 69, + 22, 73, 22, 76, 50, 78, 42, 84, 50, 85, 22, 89, 138, 175, 1, 75, 2, 80, + 2, 83, 254, 68, 66, 2, 67, 2, 68, 2, 70, 2, 71, 2, 72, 2, 74, 2, 77, 2, + 82, 2, 86, 2, 87, 3, 90, 13, 34, 65, 206, 247, 1, 78, 87, 85, 7, 11, 78, + 5, 147, 248, 1, 71, 5, 255, 247, 1, 78, 5, 151, 247, 1, 78, 4, 26, 76, + 191, 247, 1, 65, 2, 131, 245, 1, 72, 6, 238, 244, 1, 71, 2, 89, 187, 2, + 65, 8, 198, 244, 1, 72, 2, 82, 2, 83, 187, 2, 65, 5, 251, 166, 1, 69, 4, + 170, 245, 1, 73, 147, 1, 65, 2, 179, 111, 78, 8, 40, 3, 75, 79, 73, 1, 3, + 84, 85, 80, 5, 135, 226, 1, 78, 4, 21, 3, 78, 71, 32, 4, 76, 8, 67, 82, + 69, 83, 67, 69, 78, 84, 1, 7, 71, 73, 66, 66, 79, 85, 83, 2, 21, 3, 32, + 77, 79, 2, 11, 79, 2, 175, 97, 78, 170, 1, 72, 9, 65, 78, 71, 32, 67, 73, + 84, 73, 32, 249, 108, 4, 78, 73, 78, 71, 168, 1, 128, 1, 6, 67, 65, 80, + 73, 84, 65, 0, 4, 83, 77, 65, 76, 190, 4, 68, 156, 2, 7, 78, 85, 77, 66, + 69, 82, 32, 171, 219, 1, 79, 64, 45, 9, 76, 32, 76, 69, 84, 84, 69, 82, + 32, 64, 174, 1, 65, 38, 69, 42, 72, 74, 78, 50, 79, 22, 83, 50, 85, 30, + 89, 170, 42, 84, 248, 107, 2, 86, 73, 206, 51, 66, 2, 80, 246, 5, 75, + 158, 11, 73, 2, 87, 162, 17, 68, 3, 71, 9, 162, 240, 1, 78, 86, 77, 3, + 84, 7, 11, 78, 4, 198, 240, 1, 78, 3, 89, 8, 38, 79, 210, 151, 1, 73, + 231, 31, 65, 4, 178, 183, 1, 82, 223, 25, 76, 4, 26, 71, 223, 158, 1, 85, + 2, 143, 237, 1, 65, 5, 159, 169, 1, 68, 4, 26, 83, 175, 219, 1, 73, 2, + 155, 202, 1, 85, 4, 238, 238, 1, 67, 3, 85, 8, 34, 85, 178, 238, 1, 65, + 3, 79, 5, 175, 238, 1, 74, 20, 11, 73, 20, 11, 71, 20, 17, 2, 73, 84, 20, + 11, 32, 20, 66, 70, 30, 83, 42, 84, 62, 90, 130, 83, 78, 14, 79, 199, + 110, 69, 4, 218, 112, 73, 131, 4, 79, 4, 22, 69, 227, 96, 73, 2, 247, 27, + 86, 4, 26, 72, 207, 205, 1, 87, 2, 11, 82, 2, 223, 213, 1, 69, 2, 11, 69, + 2, 159, 205, 1, 82, 18, 42, 69, 30, 70, 42, 78, 38, 83, 39, 84, 2, 221, + 1, 3, 73, 71, 72, 4, 22, 73, 139, 1, 79, 2, 171, 1, 70, 2, 17, 2, 73, 78, + 2, 135, 1, 69, 4, 92, 2, 69, 86, 25, 2, 73, 88, 6, 34, 72, 26, 87, 187, + 154, 1, 69, 2, 11, 73, 2, 35, 82, 2, 11, 69, 2, 11, 78, 2, 171, 216, 1, + 84, 12, 32, 2, 69, 82, 175, 232, 1, 67, 10, 34, 32, 173, 153, 1, 2, 77, + 69, 8, 80, 3, 67, 76, 79, 22, 87, 224, 197, 1, 5, 66, 85, 70, 70, 65, 1, + 2, 80, 79, 2, 183, 179, 1, 83, 2, 235, 107, 65, 20, 60, 2, 69, 32, 124, + 4, 73, 78, 71, 32, 161, 1, 2, 89, 32, 6, 182, 2, 68, 157, 186, 1, 23, 65, + 82, 82, 79, 87, 32, 80, 79, 73, 78, 84, 73, 78, 71, 32, 68, 73, 82, 69, + 67, 84, 76, 89, 6, 64, 5, 66, 76, 65, 67, 75, 0, 5, 87, 72, 73, 84, 69, + 55, 72, 2, 17, 2, 32, 70, 2, 11, 76, 2, 171, 229, 1, 65, 2, 11, 65, 2, + 11, 78, 2, 235, 94, 68, 8, 26, 68, 34, 76, 43, 79, 2, 11, 65, 2, 139, + 228, 1, 83, 4, 22, 79, 223, 75, 73, 2, 183, 75, 87, 2, 11, 86, 2, 11, 69, + 2, 155, 75, 82, 14, 48, 3, 65, 82, 89, 70, 68, 70, 73, 171, 1, 83, 4, 11, + 32, 4, 32, 2, 67, 65, 219, 166, 1, 70, 2, 191, 166, 1, 84, 4, 26, 71, + 175, 146, 1, 68, 2, 149, 67, 6, 69, 45, 84, 65, 73, 76, 4, 116, 17, 69, + 82, 83, 84, 82, 65, 83, 83, 32, 69, 76, 76, 73, 80, 84, 73, 67, 185, 43, + 7, 71, 72, 84, 32, 76, 73, 70, 2, 17, 2, 32, 70, 2, 157, 145, 1, 2, 85, + 78, 2, 37, 7, 84, 32, 83, 89, 82, 73, 65, 2, 179, 35, 67, 180, 2, 52, 3, + 69, 69, 76, 100, 3, 73, 84, 69, 219, 62, 65, 7, 60, 7, 32, 79, 70, 32, + 68, 72, 65, 21, 4, 67, 72, 65, 73, 2, 143, 191, 1, 82, 2, 251, 76, 82, + 172, 2, 54, 32, 181, 63, 8, 45, 70, 69, 65, 84, 72, 69, 82, 170, 2, 148, + 2, 18, 65, 82, 82, 79, 87, 32, 83, 72, 65, 70, 84, 32, 87, 73, 68, 84, + 72, 32, 114, 66, 46, 67, 194, 15, 68, 166, 5, 69, 50, 70, 178, 3, 72, + 222, 3, 76, 218, 3, 77, 226, 1, 78, 34, 80, 146, 1, 81, 78, 82, 250, 1, + 83, 142, 12, 84, 228, 3, 2, 85, 80, 217, 3, 3, 86, 69, 82, 4, 22, 84, + 251, 67, 79, 2, 11, 87, 2, 21, 3, 79, 32, 84, 2, 17, 2, 72, 73, 2, 11, + 82, 2, 247, 158, 1, 68, 2, 11, 85, 2, 11, 76, 2, 143, 167, 1, 76, 92, + 146, 1, 72, 168, 10, 5, 73, 82, 67, 76, 69, 162, 3, 76, 25, 20, 79, 78, + 67, 65, 86, 69, 45, 83, 73, 68, 69, 68, 32, 68, 73, 65, 77, 79, 78, 68, + 66, 25, 4, 69, 83, 83, 32, 66, 66, 66, 38, 69, 118, 75, 142, 4, 80, 22, + 81, 38, 82, 131, 2, 84, 6, 241, 5, 5, 73, 83, 72, 79, 80, 4, 45, 9, 81, + 85, 73, 72, 79, 80, 80, 69, 82, 5, 17, 2, 32, 82, 2, 129, 6, 8, 79, 84, + 65, 84, 69, 68, 32, 78, 26, 38, 73, 25, 5, 78, 73, 71, 72, 84, 6, 177, 4, + 2, 78, 71, 21, 22, 32, 151, 3, 45, 12, 41, 8, 82, 79, 84, 65, 84, 69, 68, + 32, 12, 104, 2, 70, 79, 0, 15, 79, 78, 69, 32, 72, 85, 78, 68, 82, 69, + 68, 32, 84, 72, 73, 18, 84, 215, 3, 78, 2, 207, 1, 82, 6, 148, 1, 11, 87, + 79, 32, 72, 85, 78, 68, 82, 69, 68, 32, 133, 3, 20, 72, 82, 69, 69, 32, + 72, 85, 78, 68, 82, 69, 68, 32, 70, 73, 70, 84, 69, 69, 78, 4, 36, 4, 84, + 87, 69, 78, 175, 2, 83, 2, 217, 2, 7, 84, 89, 45, 70, 73, 86, 69, 6, 166, + 3, 66, 94, 81, 47, 82, 6, 41, 2, 65, 87, 6, 21, 3, 85, 69, 69, 6, 35, 78, + 6, 21, 3, 79, 79, 75, 7, 45, 9, 32, 82, 79, 84, 65, 84, 69, 68, 32, 4, + 70, 78, 25, 13, 84, 87, 79, 32, 72, 85, 78, 68, 82, 69, 68, 32, 83, 2, + 49, 3, 73, 78, 69, 2, 25, 4, 69, 86, 69, 78, 2, 17, 2, 84, 89, 2, 253, + 62, 6, 32, 68, 69, 71, 82, 69, 12, 33, 6, 85, 82, 78, 69, 68, 32, 12, 42, + 66, 30, 75, 34, 80, 34, 81, 47, 82, 2, 225, 88, 3, 73, 83, 72, 4, 222, + 128, 1, 73, 159, 38, 78, 2, 11, 65, 2, 203, 129, 1, 87, 2, 11, 85, 2, 11, + 69, 2, 159, 129, 1, 69, 2, 255, 166, 1, 79, 19, 11, 32, 16, 100, 16, 67, + 79, 78, 84, 65, 73, 78, 73, 78, 71, 32, 66, 76, 65, 67, 75, 121, 5, 87, + 73, 84, 72, 32, 2, 17, 2, 32, 83, 2, 11, 77, 2, 21, 3, 65, 76, 76, 2, 11, + 32, 2, 11, 67, 2, 11, 73, 2, 11, 82, 2, 203, 45, 67, 14, 56, 2, 68, 79, + 70, 84, 148, 30, 2, 76, 79, 231, 1, 85, 4, 18, 84, 35, 87, 2, 11, 32, 2, + 179, 163, 1, 82, 2, 179, 51, 78, 2, 11, 87, 2, 11, 79, 2, 11, 32, 2, 155, + 57, 68, 2, 141, 26, 2, 85, 66, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 148, + 29, 2, 76, 69, 49, 2, 82, 73, 28, 76, 6, 73, 65, 77, 79, 78, 68, 216, 2, + 3, 79, 87, 78, 177, 1, 2, 82, 65, 15, 11, 32, 12, 160, 1, 17, 67, 79, 78, + 84, 65, 73, 78, 73, 78, 71, 32, 66, 76, 65, 67, 75, 32, 128, 1, 9, 87, + 73, 84, 72, 32, 67, 69, 78, 84, 198, 22, 83, 173, 18, 2, 73, 78, 6, 74, + 83, 0, 6, 86, 69, 82, 89, 32, 83, 29, 6, 77, 69, 68, 73, 85, 77, 2, 25, + 4, 77, 65, 76, 76, 2, 181, 14, 2, 32, 68, 2, 11, 82, 2, 11, 69, 2, 179, + 56, 68, 10, 96, 10, 32, 80, 79, 73, 78, 84, 73, 78, 71, 32, 53, 10, 45, + 80, 79, 73, 78, 84, 73, 78, 71, 32, 6, 250, 34, 66, 24, 5, 76, 69, 70, + 84, 32, 51, 73, 4, 138, 36, 83, 51, 84, 4, 33, 6, 85, 71, 72, 84, 83, 32, + 4, 22, 77, 191, 118, 75, 2, 223, 119, 65, 2, 29, 5, 88, 67, 76, 65, 77, + 2, 155, 14, 65, 14, 74, 76, 144, 2, 11, 79, 85, 82, 32, 80, 79, 73, 78, + 84, 69, 68, 71, 82, 8, 28, 2, 65, 71, 175, 1, 79, 5, 149, 1, 34, 32, 87, + 73, 84, 72, 32, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 32, 77, 73, 68, + 68, 76, 69, 32, 66, 76, 65, 67, 75, 32, 83, 84, 82, 73, 2, 155, 174, 1, + 80, 4, 26, 82, 227, 134, 1, 87, 2, 17, 2, 69, 84, 2, 215, 173, 1, 84, 4, + 11, 32, 4, 18, 67, 23, 83, 2, 223, 195, 1, 85, 2, 187, 33, 84, 2, 183, + 59, 79, 16, 34, 65, 150, 1, 69, 219, 1, 79, 2, 25, 4, 82, 68, 32, 83, 2, + 45, 9, 72, 69, 76, 76, 32, 70, 76, 79, 80, 2, 17, 2, 80, 89, 2, 17, 2, + 32, 68, 2, 11, 73, 2, 135, 191, 1, 83, 10, 22, 65, 247, 10, 88, 8, 30, + 82, 29, 3, 86, 89, 32, 4, 11, 84, 5, 183, 14, 32, 4, 74, 67, 41, 14, 83, + 65, 76, 84, 73, 82, 69, 32, 87, 73, 84, 72, 32, 82, 2, 21, 3, 72, 69, 67, + 2, 155, 127, 75, 2, 139, 18, 79, 4, 152, 30, 10, 82, 73, 90, 79, 78, 84, + 65, 76, 32, 69, 229, 10, 2, 85, 82, 18, 170, 1, 65, 116, 3, 69, 70, 84, + 165, 9, 31, 79, 90, 69, 78, 71, 69, 32, 67, 79, 78, 84, 65, 73, 78, 73, + 78, 71, 32, 66, 76, 65, 67, 75, 32, 83, 77, 65, 76, 76, 32, 76, 4, 24, 2, + 82, 71, 19, 84, 2, 199, 29, 69, 2, 11, 73, 2, 11, 78, 2, 17, 2, 32, 67, + 2, 11, 82, 2, 159, 39, 79, 12, 58, 32, 77, 10, 45, 80, 79, 73, 78, 84, + 73, 78, 71, 32, 6, 44, 6, 76, 65, 78, 69, 32, 77, 223, 22, 80, 2, 11, 69, + 2, 219, 8, 82, 6, 30, 80, 166, 24, 83, 51, 84, 2, 187, 5, 79, 12, 68, 6, + 69, 68, 73, 85, 77, 32, 121, 7, 79, 79, 78, 32, 83, 69, 76, 10, 30, 68, + 54, 83, 211, 6, 76, 2, 11, 73, 2, 11, 65, 2, 11, 77, 2, 163, 45, 79, 6, + 202, 24, 84, 186, 1, 77, 59, 81, 2, 11, 69, 2, 139, 184, 1, 78, 2, 11, + 73, 2, 163, 186, 1, 66, 6, 18, 65, 87, 69, 2, 37, 7, 82, 65, 76, 76, 69, + 76, 79, 2, 11, 71, 2, 11, 82, 2, 227, 168, 1, 65, 4, 11, 78, 4, 154, 2, + 84, 191, 45, 78, 2, 21, 3, 85, 69, 83, 2, 145, 117, 9, 84, 73, 79, 78, + 32, 77, 65, 82, 75, 14, 36, 4, 73, 71, 72, 84, 179, 22, 69, 12, 60, 10, + 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 195, 17, 32, 8, 30, 80, 178, 19, + 83, 51, 84, 4, 18, 69, 55, 79, 2, 11, 78, 2, 11, 84, 2, 11, 65, 2, 147, + 103, 71, 2, 11, 73, 2, 11, 78, 2, 235, 120, 84, 56, 118, 67, 32, 3, 69, + 83, 65, 18, 72, 58, 77, 170, 1, 80, 68, 5, 81, 85, 65, 82, 69, 168, 6, 2, + 85, 78, 163, 10, 84, 2, 133, 39, 4, 73, 83, 83, 79, 2, 155, 36, 77, 2, + 21, 3, 79, 71, 73, 2, 137, 120, 4, 32, 80, 73, 69, 8, 32, 4, 65, 76, 76, + 32, 119, 73, 6, 18, 76, 71, 83, 2, 11, 79, 2, 11, 90, 2, 11, 69, 2, 11, + 78, 2, 159, 157, 1, 71, 4, 182, 17, 84, 243, 1, 81, 2, 187, 43, 76, 2, + 21, 3, 65, 68, 69, 2, 11, 32, 2, 11, 83, 2, 203, 150, 1, 85, 29, 11, 32, + 26, 114, 66, 36, 17, 67, 79, 78, 84, 65, 73, 78, 73, 78, 71, 32, 66, 76, + 65, 67, 75, 32, 73, 5, 87, 73, 84, 72, 32, 2, 17, 2, 85, 84, 2, 251, 97, + 84, 6, 184, 16, 4, 86, 69, 82, 89, 22, 83, 37, 6, 77, 69, 68, 73, 85, 77, + 18, 150, 1, 76, 50, 82, 214, 1, 85, 144, 1, 17, 86, 69, 82, 84, 73, 67, + 65, 76, 32, 66, 73, 83, 69, 67, 84, 73, 78, 221, 18, 6, 67, 69, 78, 84, + 82, 69, 6, 18, 69, 15, 79, 2, 67, 70, 4, 247, 1, 87, 4, 18, 73, 115, 79, + 2, 17, 2, 71, 72, 2, 33, 6, 84, 87, 65, 82, 68, 83, 2, 11, 32, 2, 11, 84, + 2, 11, 73, 2, 179, 171, 1, 67, 2, 29, 5, 85, 78, 68, 69, 68, 2, 21, 3, + 32, 67, 79, 2, 181, 31, 2, 82, 78, 4, 17, 2, 80, 80, 4, 21, 3, 69, 82, + 32, 4, 44, 3, 76, 69, 70, 1, 4, 82, 73, 71, 72, 2, 33, 6, 84, 32, 81, 85, + 65, 68, 2, 163, 35, 82, 2, 159, 19, 71, 11, 11, 32, 8, 84, 12, 66, 69, + 72, 73, 78, 68, 32, 67, 76, 79, 85, 68, 69, 5, 87, 73, 84, 72, 32, 5, 29, + 5, 32, 87, 73, 84, 72, 2, 17, 2, 32, 82, 2, 243, 43, 65, 4, 38, 82, 29, + 5, 83, 77, 65, 76, 76, 2, 11, 65, 2, 155, 109, 89, 2, 25, 4, 32, 67, 76, + 79, 2, 171, 100, 85, 10, 38, 79, 54, 69, 62, 82, 203, 1, 87, 2, 49, 10, + 85, 67, 72, 84, 79, 78, 69, 32, 84, 69, 2, 17, 2, 76, 69, 2, 11, 80, 2, + 11, 72, 2, 147, 16, 79, 4, 148, 1, 4, 65, 80, 69, 90, 33, 28, 73, 65, 78, + 71, 76, 69, 32, 67, 79, 78, 84, 65, 73, 78, 73, 78, 71, 32, 83, 77, 65, + 76, 76, 32, 87, 72, 73, 84, 2, 11, 73, 2, 155, 151, 1, 85, 2, 255, 3, 69, + 2, 11, 79, 2, 85, 19, 45, 87, 65, 89, 32, 76, 69, 70, 84, 32, 87, 65, 89, + 32, 84, 82, 65, 70, 70, 2, 11, 73, 2, 223, 166, 1, 67, 12, 62, 32, 185, + 1, 10, 45, 80, 79, 73, 78, 84, 73, 78, 71, 32, 4, 11, 80, 4, 41, 8, 79, + 73, 78, 84, 73, 78, 71, 32, 4, 18, 66, 75, 73, 2, 21, 3, 65, 67, 75, 2, + 25, 4, 72, 65, 78, 68, 2, 17, 2, 32, 73, 2, 17, 2, 78, 68, 2, 215, 24, + 69, 8, 68, 4, 67, 72, 69, 86, 18, 83, 73, 7, 84, 82, 73, 65, 78, 71, 76, + 2, 171, 84, 82, 2, 25, 4, 77, 65, 76, 76, 2, 17, 2, 32, 84, 2, 129, 2, 2, + 82, 73, 4, 11, 69, 5, 11, 32, 2, 11, 87, 2, 145, 18, 3, 73, 84, 72, 8, + 44, 6, 84, 73, 67, 65, 76, 32, 183, 1, 89, 6, 26, 66, 18, 69, 51, 82, 2, + 215, 105, 65, 2, 11, 76, 2, 17, 2, 76, 73, 2, 131, 25, 80, 2, 11, 69, 2, + 17, 2, 67, 84, 2, 11, 65, 2, 11, 78, 2, 11, 71, 2, 207, 138, 1, 76, 2, + 17, 2, 32, 83, 2, 11, 77, 2, 21, 3, 65, 76, 76, 2, 17, 2, 32, 83, 2, 11, + 81, 2, 11, 85, 2, 11, 65, 2, 203, 137, 1, 82, 2, 11, 69, 2, 11, 68, 2, + 17, 2, 32, 82, 2, 21, 3, 73, 71, 72, 2, 11, 84, 2, 11, 87, 2, 241, 4, 4, + 65, 82, 68, 83, 100, 140, 1, 10, 68, 69, 45, 72, 69, 65, 68, 69, 68, 32, + 132, 4, 4, 71, 71, 76, 89, 124, 6, 76, 84, 69, 68, 32, 70, 42, 78, 189, + 1, 2, 82, 69, 80, 128, 1, 3, 76, 69, 70, 0, 4, 82, 73, 71, 72, 12, 4, 68, + 79, 87, 78, 0, 2, 85, 80, 32, 3, 78, 79, 82, 1, 3, 83, 79, 85, 10, 11, + 84, 10, 109, 5, 87, 65, 82, 68, 83, 20, 21, 3, 84, 72, 32, 20, 32, 2, 69, + 65, 1, 2, 87, 69, 10, 17, 2, 83, 84, 10, 11, 32, 10, 110, 72, 0, 6, 86, + 69, 82, 89, 32, 72, 28, 5, 76, 73, 71, 72, 84, 0, 6, 77, 69, 68, 73, 85, + 77, 23, 66, 2, 25, 4, 69, 65, 86, 89, 2, 17, 2, 32, 66, 2, 21, 3, 65, 82, + 66, 2, 11, 32, 2, 11, 65, 2, 11, 82, 2, 11, 82, 2, 251, 27, 79, 2, 17, 2, + 32, 86, 2, 11, 69, 2, 33, 6, 82, 84, 73, 67, 65, 76, 2, 11, 32, 2, 11, + 76, 2, 11, 73, 2, 191, 130, 1, 78, 2, 11, 76, 2, 11, 79, 2, 135, 91, 87, + 12, 46, 68, 106, 69, 186, 15, 75, 139, 136, 1, 71, 6, 22, 32, 131, 26, + 79, 4, 44, 2, 67, 72, 217, 15, 4, 66, 76, 79, 87, 2, 11, 73, 2, 255, 128, + 1, 77, 2, 11, 32, 2, 121, 3, 71, 76, 65, 4, 36, 5, 68, 32, 75, 69, 89, + 51, 76, 2, 17, 2, 66, 79, 2, 11, 65, 2, 191, 80, 82, 2, 11, 69, 2, 231, + 88, 83, 30, 66, 77, 158, 3, 82, 226, 11, 78, 214, 64, 79, 129, 9, 2, 76, + 70, 14, 36, 2, 65, 78, 161, 2, 2, 69, 78, 13, 72, 12, 32, 87, 73, 84, 72, + 32, 66, 85, 78, 78, 89, 32, 29, 2, 83, 32, 2, 11, 69, 2, 167, 6, 65, 8, + 48, 2, 66, 79, 28, 2, 67, 76, 54, 72, 19, 83, 2, 11, 79, 2, 195, 86, 84, + 2, 11, 79, 2, 11, 84, 2, 11, 72, 2, 143, 86, 69, 2, 163, 119, 65, 2, 17, + 2, 65, 78, 2, 131, 10, 68, 2, 11, 83, 2, 11, 32, 2, 11, 83, 2, 11, 89, 2, + 17, 2, 77, 66, 2, 187, 9, 79, 10, 72, 2, 68, 32, 156, 1, 3, 76, 68, 32, + 32, 2, 82, 73, 195, 144, 1, 77, 4, 56, 9, 83, 69, 80, 65, 82, 65, 84, 79, + 82, 191, 83, 74, 2, 17, 2, 32, 77, 2, 21, 3, 73, 68, 68, 2, 11, 76, 2, + 11, 69, 2, 11, 32, 2, 195, 64, 68, 2, 11, 77, 2, 199, 144, 1, 65, 2, 11, + 69, 2, 159, 83, 68, 10, 56, 7, 65, 80, 80, 69, 68, 32, 80, 30, 69, 163, + 1, 73, 2, 201, 76, 3, 82, 69, 83, 6, 48, 2, 65, 84, 80, 3, 83, 84, 76, + 163, 108, 78, 2, 11, 72, 2, 11, 32, 2, 11, 80, 2, 25, 4, 82, 79, 68, 85, + 2, 171, 114, 67, 2, 11, 69, 2, 235, 80, 82, 2, 11, 84, 2, 11, 73, 2, 17, + 2, 78, 71, 2, 17, 2, 32, 72, 2, 11, 65, 2, 203, 71, 78, 34, 76, 2, 32, + 73, 138, 1, 45, 28, 7, 73, 65, 78, 71, 81, 73, 32, 143, 83, 79, 2, 53, + 11, 78, 32, 65, 32, 82, 69, 67, 84, 65, 78, 71, 2, 11, 76, 2, 11, 69, 2, + 11, 32, 2, 11, 66, 2, 11, 79, 2, 139, 140, 1, 88, 2, 11, 82, 2, 163, 122, + 65, 28, 48, 5, 66, 76, 65, 67, 75, 1, 3, 82, 69, 68, 14, 11, 32, 14, 130, + 1, 67, 72, 4, 69, 76, 69, 80, 28, 4, 71, 69, 78, 69, 46, 72, 36, 4, 83, + 79, 76, 68, 169, 9, 6, 77, 65, 78, 68, 65, 82, 4, 24, 2, 65, 78, 19, 72, + 2, 155, 58, 78, 2, 189, 57, 3, 65, 82, 73, 2, 11, 72, 2, 179, 70, 65, 2, + 11, 82, 2, 11, 65, 2, 155, 137, 1, 76, 2, 17, 2, 79, 82, 2, 159, 114, 83, + 2, 131, 75, 73, 242, 19, 50, 65, 58, 69, 218, 11, 73, 217, 35, 2, 79, 45, + 2, 17, 2, 87, 78, 2, 11, 73, 2, 229, 74, 2, 78, 71, 98, 60, 4, 76, 76, + 79, 87, 62, 78, 53, 5, 90, 73, 68, 73, 32, 2, 17, 2, 32, 72, 2, 11, 69, + 2, 11, 65, 2, 203, 106, 82, 2, 11, 32, 2, 11, 83, 2, 11, 73, 2, 239, 54, + 71, 94, 112, 10, 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 76, 5, 72, 89, + 80, 72, 69, 17, 7, 76, 69, 84, 84, 69, 82, 32, 4, 44, 3, 77, 65, 68, 13, + 4, 72, 65, 77, 90, 2, 11, 68, 2, 203, 67, 65, 2, 207, 27, 78, 88, 250, 1, + 67, 50, 77, 18, 68, 42, 69, 58, 72, 30, 75, 22, 71, 2, 81, 32, 3, 76, 65, + 77, 98, 78, 18, 80, 30, 83, 66, 84, 28, 2, 86, 65, 118, 87, 14, 79, 18, + 88, 52, 3, 89, 79, 84, 154, 1, 90, 130, 53, 82, 226, 48, 66, 254, 5, 85, + 162, 14, 70, 3, 74, 6, 22, 72, 251, 113, 73, 4, 22, 72, 227, 113, 73, 2, + 223, 113, 73, 4, 11, 65, 4, 154, 130, 1, 68, 3, 76, 8, 42, 76, 130, 50, + 89, 214, 79, 84, 3, 87, 2, 71, 73, 4, 254, 111, 65, 147, 15, 72, 4, 18, + 72, 15, 65, 2, 11, 65, 2, 139, 129, 1, 70, 5, 11, 32, 2, 11, 87, 2, 21, + 3, 73, 84, 72, 2, 17, 2, 32, 68, 2, 11, 79, 2, 179, 3, 84, 2, 195, 48, + 85, 4, 178, 105, 72, 215, 22, 69, 8, 46, 72, 234, 47, 73, 194, 9, 65, + 151, 70, 69, 2, 231, 47, 73, 4, 214, 104, 72, 215, 22, 65, 5, 37, 7, 32, + 65, 76, 84, 69, 82, 78, 2, 21, 3, 65, 84, 69, 2, 11, 32, 2, 11, 70, 2, + 11, 79, 2, 211, 109, 82, 2, 11, 65, 2, 143, 126, 87, 4, 22, 72, 235, 125, + 65, 2, 11, 69, 2, 135, 46, 89, 5, 37, 7, 32, 87, 73, 84, 72, 32, 67, 2, + 45, 9, 73, 82, 67, 85, 77, 70, 76, 69, 88, 2, 11, 32, 2, 11, 65, 2, 11, + 66, 2, 11, 79, 2, 239, 101, 86, 6, 22, 65, 159, 124, 69, 5, 155, 124, 76, + 140, 19, 34, 32, 161, 35, 3, 78, 32, 89, 138, 19, 88, 8, 82, 65, 68, 73, + 67, 65, 76, 32, 181, 7, 9, 83, 89, 76, 76, 65, 66, 76, 69, 32, 110, 170, + 1, 66, 42, 67, 86, 68, 42, 71, 74, 72, 66, 74, 66, 75, 30, 76, 30, 77, + 26, 78, 74, 80, 26, 83, 74, 84, 30, 86, 30, 89, 30, 90, 246, 35, 81, 186, + 49, 87, 235, 30, 79, 4, 22, 66, 243, 64, 85, 2, 147, 93, 85, 12, 42, 85, + 18, 89, 162, 98, 72, 203, 22, 73, 2, 247, 120, 79, 7, 242, 120, 80, 3, + 84, 4, 22, 68, 199, 120, 85, 2, 243, 63, 85, 10, 42, 71, 222, 91, 79, + 162, 28, 69, 15, 65, 4, 146, 89, 85, 235, 30, 79, 8, 22, 88, 227, 88, 77, + 6, 222, 88, 85, 202, 2, 73, 163, 28, 79, 8, 22, 74, 151, 119, 79, 6, 230, + 90, 85, 218, 5, 73, 215, 22, 89, 4, 190, 90, 73, 175, 28, 69, 6, 186, 54, + 73, 199, 7, 89, 4, 166, 118, 79, 15, 73, 8, 30, 89, 26, 90, 183, 90, 66, + 4, 238, 117, 73, 3, 79, 2, 215, 117, 85, 4, 166, 89, 85, 3, 89, 10, 22, + 72, 207, 97, 83, 8, 210, 60, 85, 166, 28, 65, 162, 28, 79, 15, 89, 4, + 198, 88, 65, 175, 28, 85, 4, 134, 60, 85, 199, 56, 69, 4, 142, 88, 73, + 175, 28, 79, 10, 54, 85, 220, 62, 2, 90, 73, 226, 24, 79, 175, 28, 65, 4, + 230, 115, 80, 3, 82, 156, 18, 134, 2, 66, 134, 1, 67, 162, 1, 68, 110, + 70, 50, 71, 150, 1, 72, 138, 3, 73, 134, 1, 74, 98, 75, 54, 76, 62, 77, + 134, 1, 78, 234, 4, 80, 54, 81, 2, 89, 46, 82, 162, 1, 83, 134, 1, 84, + 102, 86, 82, 87, 58, 88, 50, 90, 140, 2, 2, 85, 79, 66, 65, 2, 79, 107, + 69, 132, 1, 66, 66, 238, 21, 85, 150, 1, 69, 26, 73, 42, 65, 2, 79, 67, + 89, 64, 234, 21, 85, 150, 1, 69, 26, 73, 42, 65, 2, 79, 3, 89, 122, 66, + 72, 238, 20, 85, 150, 1, 69, 26, 73, 42, 65, 2, 79, 67, 89, 54, 46, 85, + 146, 22, 65, 2, 69, 2, 79, 67, 89, 19, 142, 22, 79, 106, 82, 214, 88, 80, + 3, 88, 106, 58, 68, 138, 15, 85, 134, 5, 73, 94, 69, 66, 65, 3, 79, 54, + 210, 19, 85, 58, 73, 94, 69, 66, 65, 3, 79, 42, 182, 20, 79, 66, 65, 2, + 73, 2, 89, 67, 85, 116, 58, 71, 214, 15, 85, 146, 4, 73, 42, 65, 2, 69, + 3, 79, 56, 50, 73, 162, 15, 85, 186, 4, 65, 2, 69, 3, 79, 13, 150, 19, + 69, 254, 89, 84, 3, 88, 246, 1, 78, 73, 30, 76, 58, 77, 54, 78, 110, 88, + 50, 85, 254, 15, 69, 66, 65, 3, 79, 6, 198, 19, 69, 215, 88, 84, 64, 238, + 16, 85, 58, 73, 94, 69, 2, 79, 66, 65, 67, 89, 58, 182, 16, 85, 58, 73, + 158, 1, 65, 2, 79, 35, 89, 42, 46, 79, 34, 85, 202, 16, 69, 26, 73, 43, + 65, 6, 226, 106, 80, 2, 84, 3, 88, 6, 238, 17, 79, 215, 88, 84, 46, 46, + 85, 254, 15, 69, 26, 73, 42, 65, 3, 79, 8, 187, 16, 79, 19, 42, 84, 130, + 16, 69, 190, 89, 80, 3, 88, 5, 11, 69, 2, 11, 82, 2, 11, 65, 2, 11, 84, + 2, 11, 73, 2, 11, 79, 2, 187, 39, 78, 106, 50, 74, 190, 10, 85, 146, 4, + 73, 42, 79, 67, 89, 50, 158, 13, 85, 174, 1, 73, 42, 79, 3, 89, 56, 242, + 12, 85, 58, 73, 158, 1, 65, 2, 69, 3, 79, 70, 218, 9, 85, 250, 3, 69, 26, + 73, 42, 65, 2, 79, 67, 89, 106, 70, 71, 218, 8, 85, 158, 3, 73, 158, 1, + 65, 2, 79, 2, 89, 107, 69, 44, 186, 11, 85, 150, 1, 69, 66, 65, 2, 79, + 105, 2, 73, 69, 248, 2, 102, 66, 54, 68, 94, 71, 90, 74, 46, 82, 50, 89, + 78, 90, 134, 7, 85, 58, 73, 94, 65, 2, 69, 67, 79, 54, 202, 10, 73, 158, + 1, 65, 2, 79, 66, 85, 3, 89, 46, 46, 73, 198, 10, 69, 66, 65, 2, 79, 67, + 85, 13, 234, 11, 69, 214, 88, 80, 2, 84, 3, 88, 34, 60, 2, 85, 79, 218, + 9, 69, 0, 2, 73, 69, 66, 65, 3, 79, 7, 210, 99, 84, 3, 88, 50, 230, 1, + 85, 242, 7, 73, 42, 79, 67, 89, 46, 146, 9, 79, 66, 65, 2, 69, 66, 85, 3, + 89, 38, 30, 85, 222, 8, 73, 43, 79, 15, 194, 8, 79, 254, 89, 80, 2, 84, + 3, 88, 56, 62, 85, 206, 4, 79, 178, 2, 73, 158, 1, 65, 66, 89, 43, 69, + 15, 254, 8, 79, 2, 82, 214, 88, 80, 3, 88, 60, 150, 6, 85, 58, 73, 158, + 1, 65, 2, 79, 67, 89, 56, 254, 2, 85, 146, 4, 73, 42, 79, 67, 89, 100, + 58, 82, 254, 4, 85, 150, 1, 69, 66, 65, 2, 79, 67, 89, 48, 46, 85, 162, + 6, 69, 2, 79, 66, 89, 43, 65, 17, 134, 7, 79, 2, 82, 214, 88, 80, 2, 84, + 3, 88, 176, 1, 70, 83, 158, 3, 72, 50, 85, 58, 73, 94, 69, 66, 65, 2, 79, + 67, 89, 56, 130, 4, 73, 94, 69, 66, 65, 2, 79, 2, 85, 67, 89, 56, 46, 85, + 158, 3, 73, 94, 69, 66, 65, 3, 79, 21, 182, 4, 79, 106, 82, 214, 88, 80, + 2, 84, 3, 88, 60, 54, 69, 166, 3, 73, 42, 65, 2, 79, 66, 85, 3, 89, 4, + 134, 93, 80, 3, 88, 28, 38, 85, 206, 2, 69, 2, 79, 67, 65, 9, 203, 2, 79, + 40, 210, 2, 73, 42, 79, 66, 89, 41, 2, 85, 79, 178, 1, 66, 72, 50, 85, + 58, 73, 42, 90, 54, 69, 66, 65, 2, 79, 67, 89, 54, 46, 85, 214, 1, 65, 2, + 69, 2, 79, 67, 89, 19, 146, 1, 79, 170, 1, 82, 214, 88, 80, 2, 84, 3, 88, + 15, 90, 69, 254, 89, 80, 2, 84, 3, 88, 58, 50, 69, 2, 79, 26, 73, 42, 65, + 34, 85, 35, 89, 7, 250, 89, 80, 3, 88, 17, 38, 69, 190, 89, 80, 2, 84, 3, + 88, 9, 186, 89, 80, 2, 84, 3, 88, 11, 70, 82, 214, 88, 80, 3, 88, 13, 38, + 82, 214, 88, 80, 2, 84, 3, 88, 5, 211, 88, 88, 2, 215, 7, 65, 2, 191, 57, + 89, 180, 4, 252, 1, 10, 32, 78, 79, 84, 65, 84, 73, 79, 78, 32, 220, 6, + 16, 65, 78, 65, 66, 65, 90, 65, 82, 32, 83, 81, 85, 65, 82, 69, 32, 210, + 15, 69, 180, 2, 6, 73, 80, 80, 69, 82, 45, 96, 8, 78, 65, 77, 69, 78, 78, + 89, 32, 176, 33, 3, 79, 77, 66, 235, 26, 87, 26, 144, 1, 9, 66, 65, 71, + 32, 77, 69, 77, 66, 69, 38, 82, 104, 6, 68, 79, 77, 65, 73, 78, 60, 3, + 76, 69, 70, 154, 1, 83, 145, 2, 3, 84, 89, 80, 2, 11, 82, 2, 209, 83, 2, + 83, 72, 8, 100, 4, 65, 78, 71, 69, 60, 3, 73, 71, 72, 221, 1, 11, 69, 76, + 65, 84, 73, 79, 78, 65, 76, 32, 67, 2, 173, 3, 11, 32, 65, 78, 84, 73, + 82, 69, 83, 84, 82, 73, 4, 17, 2, 84, 32, 4, 60, 4, 73, 77, 65, 71, 13, + 7, 66, 73, 78, 68, 73, 78, 71, 2, 11, 69, 2, 25, 4, 32, 66, 82, 65, 2, + 11, 67, 2, 175, 29, 75, 8, 44, 6, 67, 72, 69, 77, 65, 32, 211, 1, 80, 6, + 18, 67, 71, 80, 2, 17, 2, 79, 77, 2, 11, 80, 2, 11, 79, 2, 11, 83, 2, + 107, 73, 4, 30, 73, 41, 3, 82, 79, 74, 2, 11, 80, 2, 11, 73, 2, 151, 80, + 78, 2, 11, 69, 2, 11, 67, 2, 11, 84, 2, 87, 73, 2, 255, 51, 79, 2, 11, + 69, 2, 11, 32, 2, 11, 67, 2, 11, 79, 2, 11, 76, 2, 11, 79, 2, 211, 79, + 78, 144, 1, 240, 1, 2, 67, 76, 68, 7, 73, 78, 73, 84, 73, 65, 76, 204, 2, + 14, 70, 73, 78, 65, 76, 32, 67, 79, 78, 83, 79, 78, 65, 78, 16, 7, 76, + 69, 84, 84, 69, 82, 32, 148, 3, 5, 77, 65, 82, 75, 32, 206, 1, 83, 181, + 3, 6, 86, 79, 87, 69, 76, 32, 14, 64, 5, 79, 83, 73, 78, 71, 137, 1, 6, + 85, 83, 84, 69, 82, 45, 4, 11, 32, 4, 64, 12, 68, 79, 85, 66, 76, 69, 45, + 76, 73, 78, 69, 68, 23, 72, 2, 17, 2, 32, 72, 2, 17, 2, 69, 65, 2, 215, + 10, 68, 10, 96, 13, 70, 73, 78, 65, 76, 32, 76, 69, 84, 84, 69, 82, 32, + 41, 7, 73, 78, 73, 84, 73, 65, 76, 8, 226, 72, 76, 2, 82, 2, 86, 3, 89, + 2, 37, 7, 32, 76, 69, 84, 84, 69, 82, 2, 151, 6, 32, 2, 131, 9, 84, 82, + 166, 1, 68, 50, 75, 38, 78, 46, 83, 38, 84, 46, 66, 2, 67, 2, 71, 2, 80, + 2, 90, 254, 68, 45, 2, 72, 2, 74, 2, 76, 2, 77, 2, 82, 2, 86, 2, 89, 187, + 2, 65, 12, 206, 1, 68, 2, 90, 254, 68, 72, 187, 2, 65, 6, 142, 70, 83, + 14, 72, 187, 2, 65, 8, 246, 69, 71, 2, 78, 2, 89, 187, 2, 65, 6, 202, 69, + 72, 2, 83, 187, 2, 65, 12, 42, 83, 2, 84, 254, 68, 72, 187, 2, 65, 4, + 250, 68, 72, 187, 2, 65, 8, 50, 68, 58, 83, 40, 4, 76, 79, 78, 71, 23, + 84, 2, 29, 5, 79, 85, 66, 76, 69, 2, 11, 32, 2, 11, 83, 2, 11, 72, 2, 11, + 65, 2, 147, 70, 68, 2, 17, 2, 32, 84, 2, 17, 2, 83, 72, 2, 135, 69, 69, + 14, 36, 4, 73, 71, 78, 32, 255, 2, 85, 12, 54, 65, 72, 6, 67, 65, 78, 68, + 82, 65, 167, 1, 86, 2, 11, 78, 2, 11, 85, 2, 17, 2, 83, 86, 2, 11, 65, 2, + 251, 65, 82, 6, 36, 5, 66, 73, 78, 68, 85, 15, 32, 5, 11, 32, 2, 25, 4, + 87, 73, 84, 72, 2, 17, 2, 32, 79, 2, 21, 3, 82, 78, 65, 2, 11, 77, 2, 11, + 69, 2, 227, 38, 78, 4, 11, 73, 4, 18, 82, 19, 83, 2, 207, 33, 65, 2, 11, + 65, 2, 11, 82, 2, 255, 63, 71, 2, 151, 4, 66, 20, 38, 76, 109, 5, 83, 73, + 71, 78, 32, 2, 17, 2, 69, 78, 2, 11, 71, 2, 11, 84, 2, 11, 72, 2, 11, 32, + 2, 11, 77, 2, 11, 65, 2, 251, 61, 82, 18, 86, 65, 26, 79, 2, 85, 16, 8, + 82, 69, 86, 69, 82, 83, 69, 68, 134, 64, 69, 3, 73, 4, 170, 64, 73, 3, + 85, 5, 147, 64, 69, 2, 171, 44, 32, 12, 72, 2, 66, 82, 16, 9, 82, 79, 32, + 87, 73, 68, 84, 72, 32, 203, 1, 85, 2, 147, 2, 65, 8, 32, 2, 78, 79, 86, + 83, 31, 74, 4, 26, 45, 73, 2, 78, 45, 2, 29, 5, 66, 82, 69, 65, 75, 2, + 11, 32, 2, 11, 83, 2, 163, 1, 80, 2, 11, 74, 2, 11, 79, 2, 11, 73, 2, 11, + 78, 2, 143, 5, 69, 2, 207, 61, 83, 2, 21, 3, 77, 79, 85, 2, 17, 2, 84, + 72, 2, 11, 32, 2, 11, 70, 2, 11, 65, 2, 155, 38, 67, 242, 2, 168, 1, 10, + 67, 79, 77, 66, 73, 78, 73, 78, 71, 32, 212, 18, 6, 78, 69, 85, 77, 69, + 32, 181, 38, 17, 80, 82, 73, 90, 78, 65, 75, 32, 77, 79, 68, 73, 70, 73, + 69, 82, 32, 128, 1, 144, 2, 17, 76, 79, 87, 69, 82, 32, 84, 79, 78, 65, + 76, 32, 82, 65, 78, 71, 69, 88, 5, 77, 65, 82, 75, 32, 148, 3, 18, 65, + 84, 84, 65, 67, 72, 73, 78, 71, 32, 86, 69, 82, 84, 73, 67, 65, 76, 221, + 11, 17, 84, 79, 78, 65, 76, 32, 82, 65, 78, 71, 69, 32, 77, 65, 82, 75, + 32, 2, 33, 6, 32, 73, 78, 68, 73, 67, 2, 11, 65, 2, 11, 84, 2, 11, 79, 2, + 207, 56, 82, 118, 182, 2, 67, 142, 1, 68, 104, 8, 71, 79, 82, 65, 90, 68, + 79, 32, 34, 78, 106, 75, 114, 79, 72, 2, 80, 79, 140, 2, 8, 77, 65, 76, + 79, 32, 80, 79, 86, 100, 2, 82, 65, 50, 83, 186, 1, 84, 108, 7, 86, 89, + 83, 79, 75, 79, 32, 234, 1, 90, 224, 10, 2, 76, 79, 224, 22, 4, 85, 68, + 65, 82, 129, 6, 4, 66, 79, 82, 90, 6, 60, 6, 72, 65, 83, 72, 75, 65, 29, + 5, 85, 82, 86, 69, 68, 5, 185, 47, 3, 32, 80, 79, 2, 17, 2, 32, 79, 2, + 11, 77, 2, 223, 24, 69, 4, 228, 10, 13, 69, 77, 69, 83, 84, 86, 69, 78, + 78, 89, 32, 90, 65, 217, 14, 6, 86, 79, 69, 84, 79, 67, 10, 30, 78, 89, + 3, 86, 89, 83, 8, 29, 5, 73, 90, 75, 79, 32, 8, 152, 8, 8, 83, 32, 75, + 82, 89, 90, 72, 69, 35, 79, 2, 155, 20, 79, 8, 56, 4, 82, 89, 90, 72, + 138, 6, 65, 233, 39, 2, 85, 80, 5, 21, 3, 32, 79, 78, 2, 11, 32, 2, 191, + 7, 76, 6, 208, 5, 3, 84, 83, 69, 200, 13, 5, 66, 76, 65, 67, 72, 131, 31, + 78, 18, 22, 68, 247, 1, 86, 6, 60, 7, 67, 72, 65, 83, 72, 73, 69, 189, + 22, 3, 86, 69, 82, 5, 29, 5, 32, 87, 73, 84, 72, 2, 17, 2, 32, 86, 2, 29, + 5, 69, 82, 84, 73, 67, 2, 17, 2, 65, 76, 2, 11, 32, 2, 11, 83, 2, 11, 84, + 2, 11, 82, 2, 11, 79, 2, 131, 25, 75, 12, 29, 5, 89, 83, 72, 69, 32, 12, + 22, 83, 251, 3, 79, 8, 154, 3, 32, 229, 2, 4, 84, 82, 65, 78, 4, 28, 2, + 90, 83, 183, 5, 86, 2, 219, 37, 69, 10, 136, 1, 2, 75, 79, 16, 16, 84, + 82, 65, 78, 78, 79, 32, 77, 65, 76, 79, 32, 80, 79, 86, 89, 236, 1, 5, + 82, 69, 68, 78, 69, 231, 26, 79, 2, 239, 42, 66, 2, 11, 83, 2, 183, 22, + 72, 10, 50, 79, 16, 5, 83, 65, 84, 65, 32, 139, 36, 73, 2, 187, 28, 67, + 6, 158, 1, 79, 201, 24, 3, 83, 32, 75, 10, 24, 2, 83, 32, 95, 79, 6, 11, + 75, 6, 44, 6, 72, 79, 75, 72, 76, 79, 247, 24, 82, 4, 11, 77, 4, 17, 2, + 32, 79, 4, 11, 78, 4, 11, 32, 4, 18, 76, 31, 82, 2, 11, 69, 2, 179, 14, + 70, 2, 11, 73, 2, 11, 71, 2, 139, 14, 72, 6, 18, 65, 31, 69, 2, 249, 25, + 3, 68, 69, 82, 4, 22, 86, 239, 10, 76, 2, 199, 38, 79, 6, 60, 5, 77, 82, + 65, 67, 72, 18, 83, 1, 4, 84, 82, 69, 83, 2, 155, 10, 78, 2, 17, 2, 86, + 69, 2, 155, 6, 84, 232, 1, 128, 2, 2, 67, 72, 38, 68, 218, 1, 70, 28, 10, + 71, 79, 76, 85, 66, 67, 72, 73, 75, 32, 158, 1, 75, 160, 2, 6, 77, 69, + 67, 72, 73, 75, 184, 1, 2, 78, 69, 18, 79, 138, 2, 80, 146, 2, 82, 114, + 83, 180, 20, 9, 86, 82, 65, 75, 72, 73, 89, 65, 32, 151, 2, 90, 4, 246, + 11, 69, 209, 10, 2, 65, 83, 10, 74, 69, 98, 85, 16, 9, 86, 65, 32, 86, + 32, 67, 72, 69, 76, 187, 27, 79, 4, 76, 2, 82, 66, 213, 2, 12, 77, 69, + 83, 84, 86, 69, 78, 78, 89, 32, 75, 76, 2, 195, 34, 73, 2, 203, 34, 68, + 2, 11, 78, 2, 231, 36, 85, 2, 11, 73, 2, 147, 34, 84, 10, 78, 84, 38, 83, + 240, 3, 5, 77, 82, 65, 67, 72, 145, 14, 4, 66, 79, 82, 90, 4, 32, 3, 82, + 69, 83, 251, 1, 73, 2, 21, 3, 86, 69, 84, 2, 231, 17, 76, 14, 76, 4, 72, + 65, 77, 73, 18, 76, 40, 3, 79, 66, 89, 16, 2, 82, 89, 87, 85, 2, 219, 3, + 76, 2, 11, 89, 2, 11, 85, 2, 151, 33, 67, 2, 223, 31, 76, 6, 28, 2, 85, + 75, 219, 32, 90, 5, 21, 3, 32, 84, 73, 2, 11, 75, 2, 251, 15, 72, 2, 11, + 70, 2, 11, 73, 2, 11, 83, 2, 215, 30, 77, 11, 11, 32, 8, 44, 7, 75, 76, + 89, 85, 67, 72, 69, 83, 80, 6, 64, 9, 78, 69, 80, 79, 83, 84, 79, 89, 65, + 14, 80, 163, 14, 86, 2, 39, 78, 2, 25, 4, 79, 86, 79, 68, 2, 143, 14, 78, + 2, 223, 22, 77, 14, 40, 2, 66, 76, 41, 4, 83, 79, 75, 65, 2, 11, 65, 2, + 11, 75, 2, 243, 30, 79, 13, 11, 32, 10, 30, 75, 142, 26, 84, 39, 83, 6, + 104, 11, 76, 89, 85, 67, 72, 69, 86, 65, 89, 65, 32, 185, 25, 10, 82, 89, + 85, 75, 79, 86, 65, 89, 65, 32, 4, 202, 16, 78, 251, 8, 83, 14, 58, 65, + 88, 8, 69, 82, 69, 86, 79, 68, 75, 65, 27, 79, 6, 44, 3, 82, 65, 75, 222, + 19, 76, 211, 5, 85, 2, 11, 76, 2, 11, 73, 2, 171, 28, 84, 5, 153, 15, 2, + 32, 78, 4, 68, 5, 68, 67, 72, 65, 83, 245, 9, 7, 76, 75, 85, 76, 73, 90, + 77, 2, 11, 72, 2, 219, 4, 73, 4, 64, 11, 69, 86, 69, 82, 83, 69, 68, 32, + 67, 72, 69, 139, 26, 79, 2, 25, 4, 76, 89, 85, 83, 2, 215, 17, 84, 126, + 96, 9, 75, 65, 77, 69, 89, 84, 83, 65, 32, 148, 2, 8, 76, 79, 90, 72, 73, + 84, 73, 69, 119, 84, 22, 128, 1, 13, 68, 86, 79, 69, 67, 72, 69, 76, 78, + 65, 89, 65, 32, 44, 7, 75, 76, 89, 85, 67, 72, 69, 74, 84, 218, 18, 77, + 119, 83, 8, 218, 10, 75, 110, 78, 178, 8, 80, 75, 83, 6, 40, 5, 86, 65, + 89, 65, 32, 243, 10, 78, 4, 178, 15, 84, 183, 4, 83, 4, 162, 15, 73, 147, + 4, 82, 9, 11, 32, 6, 48, 2, 83, 32, 25, 6, 90, 65, 75, 82, 89, 84, 4, + 166, 4, 75, 95, 90, 2, 11, 79, 2, 211, 22, 69, 96, 92, 4, 65, 84, 89, 65, + 172, 4, 6, 79, 80, 73, 84, 83, 65, 189, 1, 5, 82, 69, 76, 65, 32, 23, 11, + 32, 20, 76, 2, 83, 32, 236, 2, 9, 90, 65, 75, 82, 89, 84, 65, 89, 65, + 159, 5, 78, 14, 160, 1, 14, 68, 86, 85, 77, 89, 65, 32, 90, 65, 80, 89, + 65, 84, 89, 28, 7, 75, 82, 89, 90, 72, 69, 77, 24, 2, 82, 79, 17, 8, 90, + 65, 80, 89, 65, 84, 79, 89, 2, 11, 77, 2, 215, 19, 73, 5, 189, 1, 2, 32, + 73, 2, 203, 2, 71, 7, 21, 3, 32, 73, 32, 4, 54, 75, 37, 9, 80, 79, 68, + 67, 72, 65, 83, 72, 73, 2, 11, 82, 2, 21, 3, 89, 90, 72, 2, 211, 1, 69, + 5, 17, 2, 32, 83, 2, 17, 2, 32, 90, 2, 29, 5, 65, 80, 89, 65, 84, 2, 11, + 79, 2, 199, 17, 89, 7, 11, 32, 4, 68, 6, 83, 32, 79, 67, 72, 75, 29, 7, + 87, 73, 84, 72, 32, 83, 79, 2, 11, 79, 2, 215, 16, 77, 2, 45, 9, 82, 79, + 67, 72, 89, 65, 32, 78, 79, 2, 11, 90, 2, 163, 7, 72, 68, 140, 1, 9, 68, + 86, 79, 69, 67, 72, 69, 76, 78, 162, 1, 75, 78, 78, 174, 1, 71, 152, 3, + 8, 77, 82, 65, 67, 72, 78, 79, 84, 42, 80, 75, 84, 10, 18, 79, 71, 65, 6, + 64, 7, 80, 79, 86, 79, 68, 78, 65, 189, 5, 4, 75, 82, 89, 90, 4, 17, 2, + 89, 65, 5, 17, 2, 32, 75, 2, 145, 5, 4, 76, 89, 85, 67, 26, 48, 6, 76, + 89, 85, 67, 72, 69, 77, 2, 82, 89, 4, 22, 78, 203, 6, 80, 2, 157, 8, 9, + 69, 80, 79, 83, 84, 79, 89, 65, 78, 22, 48, 7, 85, 75, 79, 86, 65, 89, + 65, 195, 3, 90, 21, 11, 32, 18, 54, 71, 236, 2, 5, 84, 82, 89, 65, 83, + 179, 2, 80, 14, 21, 3, 82, 79, 77, 14, 32, 4, 78, 65, 89, 65, 47, 79, 5, + 237, 1, 7, 32, 87, 73, 84, 72, 32, 83, 10, 92, 10, 75, 82, 89, 90, 72, + 69, 86, 65, 89, 65, 17, 9, 80, 79, 86, 79, 68, 78, 65, 89, 65, 5, 175, 2, + 32, 7, 33, 6, 32, 87, 73, 84, 72, 32, 4, 24, 2, 68, 79, 23, 83, 2, 41, 2, + 85, 66, 2, 21, 3, 73, 78, 71, 2, 133, 6, 6, 76, 69, 32, 90, 65, 80, 2, + 175, 6, 75, 2, 237, 5, 3, 72, 69, 86, 2, 11, 73, 2, 11, 75, 2, 187, 5, + 72, 6, 22, 79, 187, 3, 82, 4, 28, 2, 76, 85, 187, 1, 86, 2, 163, 1, 80, + 8, 80, 5, 82, 89, 65, 83, 79, 153, 2, 10, 73, 75, 72, 65, 89, 65, 32, 80, + 85, 84, 6, 62, 80, 44, 4, 83, 84, 82, 69, 173, 1, 4, 71, 76, 65, 83, 2, + 17, 2, 79, 86, 2, 193, 1, 2, 79, 68, 2, 171, 1, 76, 16, 88, 12, 75, 76, + 89, 85, 67, 72, 69, 86, 65, 89, 65, 32, 38, 77, 46, 80, 38, 84, 39, 83, + 8, 34, 77, 46, 80, 38, 84, 39, 83, 2, 25, 4, 82, 65, 67, 72, 2, 247, 1, + 78, 2, 11, 82, 2, 205, 1, 2, 79, 83, 2, 11, 82, 2, 11, 69, 2, 11, 83, 2, + 157, 1, 4, 86, 69, 84, 76, 6, 30, 65, 121, 3, 77, 69, 89, 4, 32, 4, 78, + 79, 90, 72, 31, 80, 2, 11, 69, 2, 151, 3, 75, 2, 17, 2, 89, 65, 2, 11, + 84, 2, 11, 65, 2, 35, 89, 2, 11, 84, 2, 11, 83, 2, 183, 2, 65, 10, 108, + 11, 68, 73, 82, 69, 67, 84, 73, 79, 78, 32, 70, 28, 3, 75, 82, 89, 28, 5, + 76, 69, 86, 69, 76, 35, 82, 2, 11, 76, 2, 159, 1, 73, 2, 11, 90, 2, 143, + 1, 72, 4, 11, 45, 4, 114, 50, 3, 51, 2, 11, 79, 2, 83, 71, 8, 26, 78, 34, + 83, 15, 74, 4, 18, 66, 27, 74, 2, 11, 83, 2, 11, 80, 3, 0, }; -/* code->name phrasebook */ -#define phrasebook_shift 7 -#define phrasebook_short 190 -static const unsigned char phrasebook[] = { - 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, 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, - 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, 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, 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, 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, - 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, 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, 150, 200, 197, 17, - 169, 200, 197, 17, 175, 200, 197, 17, 171, 200, 197, 17, 178, 200, 197, - 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, 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, - 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, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, - 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, 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, 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, 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, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, - 14, 7, 200, 25, 14, 7, 200, 24, 14, 7, 200, 23, 14, 7, 200, 22, 14, 7, - 200, 21, 14, 7, 200, 20, 14, 7, 200, 19, 14, 7, 200, 18, 14, 7, 200, 17, - 14, 7, 200, 16, 14, 7, 200, 15, 14, 7, 200, 14, 14, 7, 200, 13, 14, 7, - 200, 12, 14, 7, 200, 11, 14, 7, 200, 10, 14, 7, 200, 9, 14, 7, 200, 8, - 14, 7, 200, 7, 14, 7, 200, 6, 14, 7, 200, 5, 14, 7, 200, 4, 14, 7, 200, - 3, 14, 7, 200, 2, 14, 7, 200, 1, 14, 7, 200, 0, 14, 7, 199, 255, 14, 7, - 199, 254, 14, 7, 199, 253, 14, 7, 196, 217, 14, 7, 196, 216, 14, 7, 196, - 215, 14, 7, 196, 214, 14, 7, 196, 213, 14, 7, 196, 212, 14, 7, 196, 211, - 14, 7, 196, 210, 14, 7, 196, 209, 14, 7, 196, 208, 14, 7, 196, 207, 14, - 7, 196, 206, 14, 7, 196, 205, 14, 7, 196, 204, 14, 7, 196, 203, 14, 7, - 196, 202, 14, 7, 196, 201, 14, 7, 196, 200, 14, 7, 196, 199, 14, 7, 196, - 198, 14, 7, 196, 197, 14, 7, 196, 196, 14, 7, 196, 195, 14, 7, 196, 194, - 14, 7, 196, 193, 14, 7, 196, 192, 14, 7, 196, 191, 14, 7, 196, 190, 14, - 7, 196, 189, 14, 7, 196, 188, 14, 7, 196, 187, 14, 7, 196, 186, 14, 7, - 196, 185, 14, 7, 196, 184, 14, 7, 196, 183, 14, 7, 196, 182, 14, 7, 196, - 181, 14, 7, 196, 180, 14, 7, 196, 179, 14, 7, 196, 178, 14, 7, 196, 177, - 14, 7, 196, 176, 14, 7, 196, 175, 14, 7, 196, 174, 14, 7, 196, 173, 14, - 7, 196, 172, 14, 7, 196, 171, 14, 7, 196, 11, 14, 7, 196, 10, 14, 7, 196, - 9, 14, 7, 196, 8, 14, 7, 196, 7, 14, 7, 196, 6, 14, 7, 196, 5, 14, 7, - 196, 4, 14, 7, 196, 3, 14, 7, 196, 2, 14, 7, 196, 1, 14, 7, 196, 0, 14, - 7, 195, 255, 14, 7, 195, 254, 14, 7, 195, 253, 14, 7, 195, 252, 14, 7, - 195, 251, 14, 7, 195, 250, 14, 7, 195, 249, 14, 7, 195, 248, 14, 7, 195, - 247, 14, 7, 195, 246, 14, 7, 195, 245, 14, 7, 195, 244, 14, 7, 195, 243, - 14, 7, 195, 242, 14, 7, 195, 240, 14, 7, 195, 239, 14, 7, 195, 238, 14, - 7, 195, 237, 14, 7, 195, 236, 14, 7, 195, 235, 14, 7, 195, 234, 14, 7, - 195, 233, 14, 7, 195, 232, 14, 7, 195, 231, 14, 7, 195, 230, 14, 7, 195, - 229, 14, 7, 195, 228, 14, 7, 195, 227, 14, 7, 195, 226, 14, 7, 195, 225, - 14, 7, 195, 224, 14, 7, 195, 223, 14, 7, 195, 222, 14, 7, 195, 221, 14, - 7, 195, 220, 14, 7, 195, 219, 14, 7, 195, 218, 14, 7, 195, 217, 14, 7, - 195, 216, 14, 7, 195, 215, 14, 7, 195, 214, 14, 7, 195, 213, 14, 7, 195, - 212, 14, 7, 195, 211, 14, 7, 195, 210, 14, 7, 195, 209, 14, 7, 195, 208, - 14, 7, 195, 207, 14, 7, 195, 206, 14, 7, 195, 205, 14, 7, 195, 204, 14, - 7, 195, 203, 14, 7, 195, 202, 14, 7, 195, 201, 14, 7, 195, 200, 14, 7, - 195, 199, 14, 7, 195, 198, 14, 7, 195, 197, 14, 7, 195, 196, 14, 7, 195, - 195, 14, 7, 195, 194, 14, 7, 195, 193, 14, 7, 195, 192, 14, 7, 195, 191, - 14, 7, 195, 190, 14, 7, 193, 223, 14, 7, 193, 222, 14, 7, 193, 221, 14, - 7, 193, 220, 14, 7, 193, 219, 14, 7, 193, 218, 14, 7, 193, 217, 14, 7, - 193, 216, 14, 7, 193, 215, 14, 7, 193, 214, 14, 7, 193, 213, 14, 7, 193, - 212, 14, 7, 193, 211, 14, 7, 193, 210, 14, 7, 193, 209, 14, 7, 193, 208, - 14, 7, 193, 207, 14, 7, 193, 206, 14, 7, 193, 205, 14, 7, 193, 204, 14, - 7, 193, 203, 14, 7, 193, 202, 14, 7, 193, 201, 14, 7, 193, 200, 14, 7, - 193, 199, 14, 7, 193, 198, 14, 7, 193, 197, 14, 7, 193, 196, 14, 7, 193, - 195, 14, 7, 193, 194, 14, 7, 193, 193, 14, 7, 193, 192, 14, 7, 192, 232, - 14, 7, 192, 231, 14, 7, 192, 230, 14, 7, 192, 229, 14, 7, 192, 228, 14, - 7, 192, 227, 14, 7, 192, 226, 14, 7, 192, 225, 14, 7, 192, 224, 14, 7, - 192, 223, 14, 7, 192, 222, 14, 7, 192, 221, 14, 7, 192, 157, 14, 7, 192, - 156, 14, 7, 192, 155, 14, 7, 192, 154, 14, 7, 192, 153, 14, 7, 192, 152, - 14, 7, 192, 151, 14, 7, 192, 150, 14, 7, 192, 149, 14, 7, 191, 165, 14, - 7, 191, 164, 14, 7, 191, 163, 14, 7, 191, 162, 14, 7, 191, 161, 14, 7, - 191, 160, 14, 7, 191, 159, 14, 7, 191, 158, 14, 7, 191, 157, 14, 7, 191, - 156, 14, 7, 191, 155, 14, 7, 191, 154, 14, 7, 191, 153, 14, 7, 191, 152, - 14, 7, 191, 151, 14, 7, 191, 150, 14, 7, 191, 149, 14, 7, 191, 148, 14, - 7, 191, 147, 14, 7, 191, 146, 14, 7, 191, 145, 14, 7, 191, 144, 14, 7, - 191, 143, 14, 7, 191, 142, 14, 7, 191, 141, 14, 7, 191, 140, 14, 7, 191, - 139, 14, 7, 191, 138, 14, 7, 191, 137, 14, 7, 191, 136, 14, 7, 191, 135, - 14, 7, 191, 134, 14, 7, 191, 133, 14, 7, 191, 132, 14, 7, 191, 131, 14, - 7, 191, 130, 14, 7, 191, 129, 14, 7, 191, 128, 14, 7, 191, 127, 14, 7, - 191, 126, 14, 7, 191, 125, 14, 7, 252, 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, - 41, 2, 27, 246, 214, 41, 2, 27, 246, 213, 41, 2, 27, 246, 212, 41, 2, 27, - 246, 211, 41, 2, 27, 246, 210, 41, 2, 27, 246, 209, 41, 2, 27, 246, 208, - 41, 2, 27, 246, 207, 41, 2, 27, 246, 206, 41, 2, 27, 246, 205, 41, 2, 27, - 246, 204, 41, 2, 27, 246, 203, 41, 2, 27, 246, 202, 41, 2, 27, 246, 201, - 41, 2, 27, 246, 200, 41, 2, 27, 246, 199, 41, 2, 27, 246, 198, 41, 2, 27, - 246, 197, 41, 2, 27, 246, 196, 41, 2, 27, 246, 195, 41, 2, 27, 246, 194, - 41, 2, 27, 246, 193, 41, 2, 27, 246, 192, 41, 2, 27, 246, 191, 41, 2, 27, - 246, 190, 41, 2, 27, 246, 189, 41, 2, 27, 246, 188, 41, 2, 27, 246, 187, - 41, 2, 27, 246, 186, 41, 2, 27, 246, 185, 41, 2, 27, 246, 184, 41, 2, 27, - 246, 183, 41, 2, 27, 246, 182, 41, 2, 27, 246, 181, 41, 2, 27, 246, 180, - 41, 2, 27, 246, 179, 41, 2, 27, 246, 178, 41, 2, 27, 246, 177, 41, 2, 27, - 246, 176, 41, 2, 27, 246, 175, 41, 2, 27, 246, 174, 41, 2, 27, 246, 173, - 41, 2, 27, 246, 172, 41, 2, 27, 246, 171, 41, 2, 27, 246, 170, 41, 2, 27, - 246, 169, 41, 2, 27, 246, 168, 41, 2, 27, 246, 167, 41, 2, 27, 246, 166, - 41, 2, 27, 246, 165, 41, 2, 27, 246, 164, 41, 2, 27, 246, 163, 41, 2, 27, - 246, 162, 41, 2, 27, 246, 161, 41, 2, 27, 246, 160, 41, 2, 27, 246, 159, - 41, 2, 27, 246, 158, 41, 2, 27, 246, 157, 41, 2, 27, 246, 156, 41, 2, 27, - 246, 155, 41, 2, 27, 246, 154, 41, 2, 27, 246, 153, 41, 2, 27, 246, 152, - 41, 2, 27, 246, 151, 41, 2, 27, 246, 150, 41, 2, 27, 246, 149, 41, 2, 27, - 246, 148, 41, 2, 27, 246, 147, 41, 2, 27, 246, 146, 41, 2, 27, 246, 145, - 41, 2, 27, 246, 144, 41, 2, 27, 246, 143, 41, 2, 27, 246, 142, 41, 2, 27, - 246, 141, 41, 2, 27, 246, 140, 41, 2, 27, 246, 139, 41, 2, 27, 246, 138, - 41, 2, 27, 246, 137, 41, 2, 27, 246, 136, 41, 2, 27, 246, 135, 41, 2, 27, - 246, 134, 41, 2, 27, 246, 133, 41, 2, 27, 246, 132, 41, 2, 27, 246, 131, - 41, 2, 27, 246, 130, 41, 2, 27, 246, 129, 41, 2, 27, 246, 128, 41, 2, 27, - 246, 127, 41, 2, 27, 246, 126, 41, 2, 27, 246, 125, 41, 2, 27, 246, 124, - 41, 2, 27, 246, 123, 41, 2, 27, 246, 122, 41, 2, 27, 246, 121, 41, 2, 27, - 246, 120, 41, 2, 27, 246, 119, 41, 2, 27, 246, 118, 41, 2, 27, 246, 117, - 41, 2, 27, 246, 116, 41, 2, 27, 246, 115, 41, 2, 27, 246, 114, 41, 2, 27, - 246, 113, 41, 2, 27, 246, 112, 41, 2, 27, 246, 111, 41, 2, 27, 246, 110, - 41, 2, 27, 246, 109, 41, 2, 27, 246, 108, 41, 2, 27, 246, 107, 41, 2, 27, - 246, 106, 41, 2, 27, 246, 105, 41, 2, 27, 246, 104, 41, 2, 27, 246, 103, - 41, 2, 27, 246, 102, 41, 2, 27, 246, 101, 41, 2, 27, 246, 100, 41, 2, 27, - 246, 99, 41, 2, 27, 246, 98, 41, 2, 27, 246, 97, 41, 2, 27, 246, 96, 41, - 2, 27, 246, 95, 41, 2, 27, 246, 94, 41, 2, 27, 246, 93, 41, 2, 27, 246, - 92, 41, 2, 27, 246, 91, 41, 2, 27, 246, 90, 41, 2, 27, 246, 89, 41, 2, - 27, 246, 88, 41, 2, 27, 246, 87, 41, 2, 27, 246, 86, 41, 2, 27, 246, 85, - 41, 2, 27, 246, 84, 41, 2, 27, 246, 83, 41, 2, 27, 246, 82, 41, 2, 27, - 246, 81, 41, 2, 27, 246, 80, 41, 2, 27, 246, 79, 41, 2, 27, 246, 78, 41, - 2, 27, 246, 77, 41, 2, 27, 246, 76, 41, 2, 27, 246, 75, 41, 2, 27, 246, - 74, 41, 2, 27, 246, 73, 41, 2, 27, 246, 72, 41, 2, 27, 246, 71, 41, 2, - 27, 246, 70, 41, 2, 27, 246, 69, 41, 2, 27, 246, 68, 41, 2, 27, 246, 67, - 41, 2, 27, 246, 66, 41, 2, 27, 246, 65, 41, 2, 27, 246, 64, 41, 2, 27, - 246, 63, 41, 2, 27, 246, 62, 41, 2, 27, 246, 61, 41, 2, 27, 246, 60, 41, - 2, 27, 246, 59, 41, 2, 27, 246, 58, 41, 2, 27, 246, 57, 41, 2, 27, 246, - 56, 41, 2, 27, 246, 55, 41, 2, 27, 246, 54, 41, 2, 27, 246, 53, 41, 2, - 27, 246, 52, 41, 2, 27, 246, 51, 41, 2, 27, 246, 50, 41, 2, 27, 246, 49, - 41, 2, 27, 246, 48, 41, 2, 27, 246, 47, 41, 2, 27, 246, 46, 41, 2, 27, - 246, 45, 41, 2, 27, 246, 44, 41, 2, 27, 246, 43, 41, 2, 27, 246, 42, 41, - 2, 27, 246, 41, 41, 2, 27, 246, 40, 41, 2, 27, 246, 39, 41, 2, 27, 246, - 38, 41, 2, 27, 246, 37, 41, 2, 27, 246, 36, 41, 2, 27, 246, 35, 41, 2, - 27, 246, 34, 41, 2, 27, 246, 33, 41, 2, 27, 246, 32, 41, 2, 27, 246, 31, - 41, 2, 27, 246, 30, 41, 2, 27, 246, 29, 41, 2, 27, 246, 28, 41, 2, 27, - 246, 27, 41, 2, 27, 246, 26, 41, 2, 27, 246, 25, 41, 2, 27, 246, 24, 41, - 2, 27, 246, 23, 41, 2, 27, 246, 22, 41, 2, 27, 246, 21, 41, 2, 27, 246, - 20, 41, 2, 27, 246, 19, 41, 2, 27, 246, 18, 41, 2, 27, 246, 17, 41, 2, - 27, 246, 16, 41, 2, 27, 246, 15, 41, 2, 27, 246, 14, 41, 2, 27, 246, 13, - 41, 2, 27, 246, 12, 41, 2, 27, 246, 11, 41, 2, 27, 246, 10, 41, 2, 27, - 246, 9, 41, 2, 27, 246, 8, 41, 2, 27, 246, 7, 41, 2, 27, 246, 6, 41, 2, - 27, 246, 5, 41, 2, 27, 246, 4, 41, 2, 27, 246, 3, 41, 2, 27, 246, 2, 41, - 2, 27, 246, 1, 41, 2, 27, 246, 0, 41, 2, 27, 245, 255, 41, 2, 27, 245, - 254, 41, 2, 27, 245, 253, 41, 2, 27, 245, 252, 41, 2, 27, 245, 251, 41, - 2, 27, 245, 250, 41, 2, 27, 245, 249, 41, 2, 27, 245, 248, 41, 2, 27, - 245, 247, 41, 2, 27, 245, 246, 41, 2, 27, 245, 245, 41, 2, 27, 245, 244, - 41, 2, 27, 245, 243, 41, 2, 27, 245, 242, 41, 2, 27, 245, 241, 41, 2, 27, - 245, 240, 41, 2, 27, 245, 239, 41, 2, 27, 245, 238, 41, 2, 27, 245, 237, - 41, 2, 27, 245, 236, 41, 2, 27, 245, 235, 41, 2, 27, 245, 234, 41, 2, 27, - 245, 233, 41, 2, 27, 245, 232, 41, 2, 27, 245, 231, 41, 2, 27, 245, 230, - 41, 2, 27, 245, 229, 41, 2, 27, 245, 228, 41, 2, 27, 245, 227, 41, 2, 27, - 245, 226, 41, 2, 27, 245, 225, 41, 2, 27, 245, 224, 41, 2, 27, 245, 223, - 41, 2, 27, 245, 222, 41, 2, 27, 245, 221, 41, 2, 27, 245, 220, 41, 2, 27, - 245, 219, 41, 2, 27, 245, 218, 41, 2, 27, 245, 217, 41, 2, 27, 245, 216, - 41, 2, 27, 245, 215, 41, 2, 27, 245, 214, 41, 2, 27, 245, 213, 41, 2, 27, - 245, 212, 41, 2, 27, 245, 211, 41, 2, 27, 245, 210, 41, 2, 27, 245, 209, - 41, 2, 27, 245, 208, 41, 2, 27, 245, 207, 41, 2, 27, 245, 206, 41, 2, 27, - 245, 205, 41, 2, 27, 245, 204, 41, 2, 27, 245, 203, 41, 2, 27, 245, 202, - 41, 2, 27, 245, 201, 41, 2, 27, 245, 200, 41, 2, 27, 245, 199, 41, 2, 27, - 245, 198, 41, 2, 27, 245, 197, 41, 2, 27, 245, 196, 41, 2, 27, 245, 195, - 41, 2, 27, 245, 194, 41, 2, 27, 245, 193, 41, 2, 27, 245, 192, 41, 2, 27, - 245, 191, 41, 2, 27, 245, 190, 41, 2, 27, 245, 189, 41, 2, 27, 245, 188, - 41, 2, 27, 245, 187, 41, 2, 27, 245, 186, 41, 2, 27, 245, 185, 41, 2, 27, - 245, 184, 41, 2, 27, 245, 183, 41, 2, 27, 245, 182, 41, 2, 27, 245, 181, - 41, 2, 27, 245, 180, 41, 2, 27, 245, 179, 41, 2, 27, 245, 178, 41, 2, 27, - 245, 177, 41, 2, 27, 245, 176, 41, 2, 27, 245, 175, 41, 2, 27, 245, 174, - 41, 2, 27, 245, 173, 41, 2, 27, 245, 172, 41, 2, 27, 245, 171, 41, 2, 27, - 245, 170, 41, 2, 27, 245, 169, 41, 2, 27, 245, 168, 41, 2, 27, 245, 167, - 41, 2, 27, 245, 166, 41, 2, 27, 245, 165, 41, 2, 27, 245, 164, 41, 2, 27, - 245, 163, 41, 2, 27, 245, 162, 41, 2, 27, 245, 161, 41, 2, 27, 245, 160, - 41, 2, 27, 245, 159, 41, 2, 27, 245, 158, 41, 2, 27, 245, 157, 41, 2, 27, - 245, 156, 41, 2, 27, 245, 155, 41, 2, 27, 245, 154, 41, 2, 27, 245, 153, - 41, 2, 27, 245, 152, 41, 2, 27, 245, 151, 41, 2, 27, 245, 150, 41, 2, 27, - 245, 149, 41, 2, 27, 245, 148, 41, 2, 27, 245, 147, 41, 2, 27, 245, 146, - 41, 2, 27, 245, 145, 41, 2, 27, 245, 144, 41, 2, 27, 245, 143, 41, 2, 27, - 245, 142, 41, 2, 27, 245, 141, 41, 2, 27, 245, 140, 41, 2, 27, 245, 139, - 41, 2, 27, 245, 138, 41, 2, 27, 245, 137, 41, 2, 27, 245, 136, 41, 2, 27, - 245, 135, 41, 2, 27, 245, 134, 41, 2, 27, 245, 133, 41, 2, 27, 245, 132, - 41, 2, 27, 245, 131, 41, 2, 27, 245, 130, 41, 2, 27, 245, 129, 41, 2, 27, - 245, 128, 41, 2, 27, 245, 127, 41, 2, 27, 245, 126, 41, 2, 27, 245, 125, - 41, 2, 27, 245, 124, 41, 2, 27, 245, 123, 41, 2, 27, 245, 122, 41, 2, 27, - 245, 121, 41, 2, 27, 245, 120, 41, 2, 27, 245, 119, 41, 2, 27, 245, 118, - 41, 2, 27, 245, 117, 41, 2, 27, 245, 116, 41, 2, 27, 245, 115, 41, 2, 27, - 245, 114, 41, 2, 27, 245, 113, 41, 2, 27, 245, 112, 41, 2, 27, 245, 111, - 41, 2, 27, 245, 110, 41, 2, 27, 245, 109, 41, 2, 27, 245, 108, 41, 2, 27, - 245, 107, 41, 2, 27, 245, 106, 41, 2, 27, 245, 105, 41, 2, 27, 245, 104, - 41, 2, 27, 245, 103, 41, 2, 27, 245, 102, 41, 2, 27, 245, 101, 41, 2, 27, - 245, 100, 41, 2, 27, 245, 99, 41, 2, 27, 245, 98, 41, 2, 27, 245, 97, 41, - 2, 27, 245, 96, 41, 2, 27, 245, 95, 41, 2, 27, 245, 94, 41, 2, 27, 245, - 93, 41, 2, 27, 245, 92, 41, 2, 27, 245, 91, 41, 2, 27, 245, 90, 41, 2, - 27, 245, 89, 41, 2, 27, 245, 88, 41, 2, 27, 245, 87, 41, 2, 27, 245, 86, - 41, 2, 27, 245, 85, 41, 2, 27, 245, 84, 41, 2, 27, 245, 83, 41, 2, 27, - 245, 82, 41, 2, 27, 245, 81, 41, 2, 27, 245, 80, 41, 2, 27, 245, 79, 41, - 2, 27, 245, 78, 41, 2, 27, 245, 77, 41, 2, 27, 245, 76, 41, 2, 27, 245, - 75, 41, 2, 27, 245, 74, 41, 2, 27, 245, 73, 41, 2, 27, 245, 72, 41, 2, - 27, 245, 71, 41, 2, 27, 245, 70, 41, 2, 27, 245, 69, 41, 2, 27, 245, 68, - 41, 2, 27, 245, 67, 41, 2, 27, 245, 66, 41, 2, 27, 245, 65, 41, 2, 27, - 245, 64, 41, 2, 27, 245, 63, 41, 2, 27, 245, 62, 41, 2, 27, 245, 61, 41, - 2, 27, 245, 60, 41, 2, 27, 245, 59, 41, 2, 27, 245, 58, 41, 2, 27, 245, - 57, 41, 2, 27, 245, 56, 41, 2, 27, 245, 55, 41, 2, 27, 245, 54, 41, 2, - 27, 245, 53, 41, 2, 27, 245, 52, 41, 2, 27, 245, 51, 41, 2, 27, 245, 50, - 41, 2, 27, 245, 49, 41, 2, 27, 245, 48, 41, 2, 27, 245, 47, 41, 2, 27, - 245, 46, 41, 2, 27, 245, 45, 41, 2, 27, 245, 44, 41, 2, 27, 245, 43, 41, - 2, 27, 245, 42, 41, 2, 27, 245, 41, 41, 2, 27, 245, 40, 41, 2, 27, 245, - 39, 41, 2, 27, 245, 38, 41, 2, 27, 245, 37, 41, 2, 27, 245, 36, 41, 2, - 27, 245, 35, 41, 2, 27, 245, 34, 41, 2, 27, 245, 33, 41, 2, 27, 245, 32, - 41, 2, 27, 245, 31, 41, 2, 27, 245, 30, 41, 2, 27, 245, 29, 41, 2, 27, - 245, 28, 41, 2, 27, 245, 27, 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, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, 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, - 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, 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, 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, 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 int dawg_pos_to_codepoint[] = { + 8448, 129687, 983053, 983052, 180, 10655, 8301, 8299, 9190, 125185, + 125197, 125214, 125208, 125204, 125187, 125201, 125216, 125213, 125200, + 125211, 125209, 125189, 125217, 125207, 125186, 125205, 125215, 125184, + 125191, 125188, 125198, 125202, 125199, 125210, 125190, 125194, 125206, + 125192, 125212, 125193, 125195, 125196, 125203, 125256, 125219, 125231, + 125248, 125242, 125238, 125221, 125235, 125250, 125247, 125234, 125245, + 125243, 125223, 125251, 125241, 125220, 125239, 125249, 125218, 125225, + 125222, 125232, 125236, 125233, 125244, 125224, 125228, 125240, 125226, + 125246, 125227, 125229, 125230, 125237, 125257, 125254, 125278, 125279, + 125259, 125258, 125255, 125252, 125253, 125269, 125268, 125271, 125270, + 125267, 125266, 125264, 125273, 125265, 125272, 11237, 127903, 129657, + 8449, 129489, 9772, 65852, 65853, 65854, 65855, 65848, 65851, 65849, + 65850, 65847, 65792, 65793, 65806, 65815, 65842, 65824, 65833, 65812, + 65839, 65803, 65821, 65830, 65811, 65838, 65802, 65820, 65829, 65807, + 65816, 65843, 65825, 65834, 65805, 65814, 65841, 65823, 65832, 65804, + 65813, 65840, 65822, 65831, 65810, 65837, 65801, 65819, 65828, 65809, + 65836, 65800, 65818, 65827, 65808, 65835, 65799, 65817, 65826, 65794, + 128673, 71455, 71453, 71454, 71442, 71450, 71446, 71429, 71492, 71491, + 71444, 71443, 71490, 71489, 71436, 71428, 71494, 71438, 71426, 71493, + 71440, 71427, 71448, 71432, 71435, 71488, 71447, 71445, 71449, 71434, + 71425, 71424, 71431, 71430, 71441, 71433, 71437, 71439, 71484, 71485, + 71467, 71486, 71487, 71456, 71457, 71465, 71466, 71463, 71460, 71461, + 71458, 71459, 71462, 71464, 71483, 71482, 71477, 71476, 71479, 71478, + 71475, 71474, 71472, 71481, 71473, 71480, 9992, 128747, 128748, 128874, + 128822, 128823, 128837, 128776, 128777, 128774, 128775, 128773, 128811, + 128859, 128829, 128826, 128855, 128769, 128875, 128876, 128830, 128834, + 128835, 128836, 128783, 128857, 128848, 128846, 128844, 128805, 128800, + 128803, 128804, 128798, 128869, 128870, 128871, 128872, 128873, 128787, + 128865, 128866, 128864, 128880, 128794, 128841, 128883, 128882, 128854, + 128878, 128796, 128797, 128801, 128810, 128851, 128784, 128785, 128786, + 128824, 128881, 128789, 128879, 128782, 128843, 128858, 128856, 128868, + 128867, 128863, 128768, 128833, 128818, 128816, 128817, 128799, 128819, + 128820, 128821, 128827, 128828, 128877, 128792, 128793, 128788, 128806, + 128813, 128825, 128850, 128860, 128861, 128814, 128807, 128812, 128802, + 128862, 128781, 128839, 128795, 128852, 128847, 128831, 128832, 128840, + 128809, 128849, 128845, 128778, 128815, 128779, 128780, 128790, 128791, + 128808, 128772, 128842, 128853, 128771, 128838, 128770, 9879, 8501, + 983054, 8780, 9006, 983203, 8776, 10863, 8778, 9095, 9941, 128126, 9200, + 38, 127994, 127944, 128657, 10815, 82970, 82971, 82964, 82965, 82966, + 82967, 82968, 82969, 82972, 82973, 82974, 82994, 82995, 82996, 82987, + 82988, 82992, 82993, 82986, 82989, 82990, 82991, 82997, 82998, 82999, + 83016, 83017, 83018, 83019, 83010, 83011, 83012, 83013, 83014, 83015, + 83020, 83021, 83022, 83050, 83051, 83052, 83053, 83043, 83044, 83045, + 83046, 83047, 83048, 83049, 83054, 82984, 82985, 82975, 82976, 82977, + 82978, 82979, 82980, 82981, 82982, 82983, 82953, 82954, 82955, 82956, + 82957, 82958, 82959, 82960, 82961, 82962, 82963, 82944, 82945, 82946, + 82947, 82948, 82949, 82950, 82951, 82952, 83000, 83001, 83002, 83003, + 83004, 83005, 83006, 83007, 83008, 83009, 83023, 83024, 83025, 83026, + 83027, 83028, 83029, 83030, 83031, 83032, 83033, 83034, 83035, 83036, + 83037, 83038, 83039, 83040, 83041, 83042, 83062, 83063, 83064, 83065, + 83070, 83071, 83072, 83073, 83066, 83067, 83068, 83055, 83056, 83057, + 83058, 83059, 83060, 83061, 83069, 83074, 83075, 83076, 83077, 83078, + 83083, 83084, 83079, 83080, 83081, 83082, 83085, 83086, 83087, 83088, + 83094, 83095, 83089, 83090, 83091, 83092, 83093, 83096, 83097, 83098, + 83099, 83105, 83106, 83100, 83101, 83102, 83103, 83104, 83107, 83108, + 83109, 83110, 83111, 83112, 83113, 83114, 83115, 83116, 83117, 83118, + 83119, 83120, 83121, 83122, 83123, 83124, 83125, 83126, 83127, 83128, + 83129, 83130, 83131, 83132, 83133, 83134, 83135, 83136, 83137, 83138, + 83139, 83140, 83141, 83142, 83143, 83144, 83145, 83146, 83147, 83148, + 83149, 83150, 83151, 83152, 83153, 83154, 83155, 83156, 83157, 83158, + 83159, 83160, 83161, 83162, 83163, 83164, 83165, 83166, 83167, 83168, + 83169, 83170, 83173, 83174, 83175, 83180, 83181, 83183, 83184, 83171, + 83172, 83176, 83177, 83178, 83179, 83182, 83190, 83191, 83192, 83193, + 83185, 83186, 83187, 83188, 83189, 83194, 83195, 83196, 83274, 83275, + 83280, 83281, 83270, 83271, 83272, 83273, 83276, 83277, 83278, 83279, + 83268, 83269, 83259, 83260, 83261, 83262, 83263, 83264, 83265, 83266, + 83267, 83204, 83205, 83197, 83198, 83199, 83200, 83201, 83202, 83203, + 83206, 83207, 83245, 83246, 83238, 83239, 83240, 83241, 83242, 83243, + 83244, 83247, 83248, 83208, 83209, 83210, 83211, 83212, 83213, 83214, + 83215, 83216, 83217, 83218, 83219, 83220, 83221, 83222, 83223, 83224, + 83225, 83226, 83227, 83228, 83229, 83230, 83231, 83232, 83233, 83234, + 83235, 83236, 83237, 83249, 83250, 83251, 83252, 83253, 83254, 83255, + 83256, 83257, 83258, 83291, 83292, 83282, 83283, 83284, 83285, 83286, + 83287, 83288, 83289, 83290, 83312, 83313, 83303, 83304, 83305, 83306, + 83307, 83308, 83309, 83310, 83311, 83348, 83349, 83339, 83340, 83341, + 83342, 83343, 83344, 83345, 83346, 83347, 83322, 83323, 83324, 83325, + 83316, 83317, 83318, 83314, 83315, 83319, 83320, 83321, 83326, 83327, + 83328, 83354, 83355, 83359, 83360, 83350, 83351, 83352, 83353, 83356, + 83357, 83358, 83361, 83377, 83378, 83374, 83375, 83381, 83382, 83373, + 83376, 83379, 83380, 83383, 83384, 83385, 83389, 83386, 83387, 83388, + 83390, 83391, 83392, 83393, 83394, 83395, 83363, 83364, 83362, 83365, + 83366, 83367, 83368, 83369, 83370, 83371, 83372, 83293, 83294, 83295, + 83296, 83297, 83298, 83299, 83300, 83301, 83302, 83329, 83330, 83331, + 83332, 83333, 83334, 83335, 83336, 83337, 83338, 83406, 83407, 83408, + 83409, 83410, 83411, 83412, 83413, 83414, 83415, 83416, 83447, 83448, + 83455, 83456, 83449, 83450, 83451, 83452, 83453, 83454, 83457, 83458, + 83489, 83490, 83491, 83492, 83493, 83494, 83495, 83496, 83396, 83397, + 83398, 83399, 83400, 83401, 83402, 83403, 83404, 83405, 83417, 83418, + 83419, 83420, 83421, 83422, 83423, 83424, 83425, 83426, 83427, 83428, + 83429, 83430, 83431, 83432, 83433, 83434, 83435, 83436, 83437, 83438, + 83439, 83440, 83441, 83442, 83443, 83444, 83445, 83446, 83459, 83460, + 83461, 83462, 83463, 83464, 83465, 83466, 83467, 83468, 83469, 83470, + 83471, 83472, 83473, 83474, 83475, 83476, 83477, 83478, 83479, 83480, + 83481, 83482, 83483, 83484, 83485, 83486, 83487, 83488, 83526, 83497, + 83498, 83499, 83500, 83501, 83502, 83503, 83504, 83505, 83506, 83507, + 83508, 83509, 83510, 83511, 83512, 83513, 83514, 83515, 83516, 83517, + 83518, 83519, 83520, 83521, 83522, 83523, 83524, 83525, 129728, 8736, + 10654, 10660, 128551, 8491, 128162, 128544, 128028, 11150, 11148, 11149, + 11151, 11119, 8630, 10560, 8755, 128260, 10226, 8634, 10769, 128246, + 9875, 10193, 9765, 9021, 9055, 9061, 9033, 9052, 9022, 9066, 9058, 9067, + 9042, 9049, 9035, 9034, 9038, 9062, 9073, 9046, 9050, 9075, 9080, 9014, + 9082, 9078, 9077, 9081, 9060, 9051, 9063, 9029, 9109, 9020, 9056, 9017, + 9018, 9036, 9047, 9044, 9037, 9043, 9040, 9027, 9031, 9072, 9071, 9016, + 9026, 9025, 9028, 9032, 9019, 9054, 9048, 9030, 9076, 9070, 9023, 9059, + 9069, 9015, 9079, 9024, 9074, 9057, 9041, 9045, 9053, 9039, 9065, 9064, + 9068, 39, 11236, 8773, 8786, 10864, 8774, 8784, 983195, 983196, 2277, + 2280, 2276, 2279, 2278, 2281, 1548, 1615, 65144, 65145, 2302, 1612, + 65138, 1549, 2206, 2299, 2300, 2274, 1643, 1771, 1770, 1757, 1565, 1614, + 1630, 2293, 2292, 65142, 65143, 1611, 65136, 1538, 1645, 1748, 2207, + 1621, 1620, 1616, 2294, 65146, 65147, 1613, 65140, 2258, 2255, 2254, + 2257, 2236, 2244, 2235, 2237, 1593, 1886, 2227, 1696, 1887, 1885, 65226, + 65227, 65225, 65228, 1575, 2165, 2176, 2173, 2161, 2174, 2171, 2167, + 2177, 2169, 2166, 2168, 2178, 2164, 2160, 2162, 2175, 2172, 1571, 65156, + 65155, 1573, 65160, 65159, 1651, 1650, 1908, 1907, 1570, 65154, 65153, + 2163, 2170, 1649, 64337, 64336, 1609, 65264, 65263, 65166, 65165, 1749, + 1576, 2230, 1878, 2208, 1874, 1875, 1872, 1876, 1877, 1873, 2209, 65168, + 65169, 65167, 65170, 1664, 64347, 64348, 64346, 64349, 1659, 64339, + 64340, 64338, 64341, 1583, 1674, 1675, 1882, 1774, 1679, 2222, 1881, + 1680, 1673, 65194, 65193, 1676, 64389, 64388, 1590, 1787, 65214, 65215, + 65213, 65216, 1677, 64387, 64386, 1672, 64393, 64392, 1646, 1697, 1647, + 1668, 64371, 64372, 64370, 64373, 1678, 64391, 64390, 1740, 1911, 1910, + 1909, 1599, 1598, 1597, 64509, 64510, 64508, 64511, 1601, 1699, 2212, + 1698, 1889, 1701, 1888, 65234, 65235, 65233, 65236, 1711, 1716, 1714, + 1712, 2224, 64403, 64404, 64402, 64405, 1594, 2243, 1788, 65230, 65231, + 65229, 65232, 1715, 64407, 64408, 64406, 64409, 2248, 1581, 1916, 2186, + 1903, 1906, 1902, 1880, 1669, 1666, 1879, 1665, 65186, 65187, 65185, + 65188, 1569, 65152, 1607, 1729, 1730, 64423, 64424, 64422, 64425, 1791, + 1728, 64421, 64420, 1726, 64427, 64428, 64426, 64429, 65258, 65259, + 65257, 65260, 1652, 1653, 1656, 1654, 1580, 2210, 2246, 2245, 65182, + 65183, 65181, 65184, 1688, 64395, 64394, 1603, 1919, 1710, 2228, 1708, + 1707, 65242, 65243, 65241, 65244, 1568, 1705, 1892, 1596, 1891, 2189, + 1595, 2242, 1890, 64399, 64400, 64398, 64401, 1733, 64481, 64480, 1737, + 64483, 64482, 1582, 65190, 65191, 65189, 65192, 1604, 2214, 1718, 2247, + 1717, 1720, 1719, 1898, 65246, 65247, 65245, 65248, 2221, 1605, 2215, + 1894, 1893, 65250, 65251, 65249, 65252, 1564, 1709, 1713, 64411, 64412, + 64410, 64413, 64468, 64469, 64467, 64470, 1667, 64375, 64376, 64374, + 64377, 1606, 1722, 64415, 64414, 1896, 1897, 1725, 1895, 2185, 1721, + 1724, 65254, 65255, 65253, 65256, 1662, 2231, 2238, 64343, 64344, 64342, + 64345, 1702, 64367, 64368, 64366, 64369, 1602, 2213, 2229, 1703, 1704, + 65238, 65239, 65237, 65240, 1585, 1905, 2233, 1682, 1685, 1883, 1899, + 1687, 1775, 1900, 1689, 1684, 1686, 2218, 1683, 65198, 65197, 1681, + 64397, 64396, 1723, 64417, 64418, 64416, 64419, 2220, 1589, 2223, 1694, + 1693, 65210, 65211, 65209, 65212, 1587, 1690, 1918, 1904, 1691, 1692, + 1901, 1884, 1917, 65202, 65203, 65201, 65204, 1588, 1786, 65206, 65207, + 65205, 65208, 1648, 2225, 1706, 1591, 2211, 2188, 1695, 2187, 65218, + 65219, 65217, 65220, 1670, 2241, 1727, 64379, 64380, 64378, 64381, 1671, + 64383, 64384, 64382, 64385, 1578, 1577, 65172, 65171, 1731, 65176, 2232, + 2239, 1661, 1660, 65174, 65175, 65173, 1663, 64355, 64356, 64354, 64357, + 1584, 65196, 65195, 1579, 65178, 65179, 65177, 65180, 2182, 1657, 2240, + 64359, 64360, 64358, 64361, 1658, 64351, 64352, 64350, 64353, 1735, 1655, + 64477, 64472, 64471, 64488, 64489, 1739, 1700, 64363, 64364, 64362, + 64365, 64479, 64478, 1608, 2219, 1743, 1913, 1912, 1572, 65158, 65157, + 1738, 1732, 65262, 65261, 1610, 1746, 1915, 1914, 1747, 64433, 64432, + 64431, 64430, 1574, 65162, 65163, 65161, 65164, 1742, 2216, 2234, 2217, + 1741, 1745, 65266, 65267, 65265, 65268, 1736, 64476, 64475, 1734, 64474, + 64473, 1592, 65222, 65223, 65221, 65224, 1586, 65200, 65199, 2226, 1744, + 64485, 64486, 64484, 64487, 2297, 2295, 64888, 64887, 64886, 64950, + 64699, 64554, 64964, 64885, 64698, 64553, 64787, 64759, 64788, 64760, + 64842, 64839, 64841, 64840, 64845, 65015, 64656, 64605, 64828, 64829, + 65010, 65011, 65023, 64962, 64669, 64518, 64672, 64738, 64926, 64670, + 64519, 64622, 64521, 64668, 64517, 64620, 64671, 64520, 64737, 64621, + 64619, 64618, 64623, 64522, 65021, 64878, 64939, 64693, 64547, 64880, + 64879, 64694, 64548, 64803, 64775, 64692, 64546, 64695, 64549, 64812, + 64784, 64804, 64776, 64893, 64892, 64704, 64559, 64636, 64561, 64702, + 64557, 64961, 64705, 64560, 64703, 64558, 64637, 64562, 64889, 64891, + 64890, 64701, 64556, 64789, 64761, 64700, 64555, 64790, 64762, 64859, + 64858, 64682, 64536, 64795, 64767, 64959, 64681, 64535, 64796, 64768, + 64915, 64916, 64728, 64594, 64595, 64596, 64727, 64593, 64729, 64934, + 64958, 64679, 64533, 64857, 64856, 64935, 64933, 64680, 64534, 64797, + 64769, 64798, 64770, 65019, 64643, 64573, 64640, 64567, 64708, 64568, + 64641, 64711, 64571, 64747, 64710, 64570, 64709, 64569, 64963, 64955, + 64951, 64642, 64712, 64572, 64748, 64644, 64574, 64538, 64799, 64771, + 64683, 64537, 64684, 64539, 64800, 64772, 65272, 65271, 65274, 65273, + 65270, 65269, 64646, 64579, 65276, 65275, 64898, 64949, 64896, 64897, + 64714, 64576, 64717, 64899, 64900, 64954, 64956, 64940, 64713, 64575, + 64902, 64901, 64715, 64577, 64904, 64903, 64941, 64645, 64716, 64578, + 64749, 64647, 64580, 64585, 64648, 64905, 64906, 64907, 64719, 64582, + 64910, 64911, 64953, 64720, 64583, 64909, 64914, 64908, 64960, 64718, + 64581, 64945, 64649, 64721, 64584, 64586, 65012, 64918, 64917, 64947, + 64723, 64588, 64726, 64751, 64952, 64957, 64921, 64920, 64919, 64967, + 64722, 64587, 64923, 64922, 64652, 64725, 64590, 64750, 64654, 64591, + 64653, 64651, 64724, 64589, 64650, 64655, 64592, 64895, 64948, 64894, + 64946, 64707, 64564, 64638, 64565, 64706, 64563, 64639, 64566, 65009, + 64843, 64833, 64835, 64836, 64837, 64834, 64832, 64847, 65014, 64604, + 64869, 64868, 64937, 64689, 64544, 64965, 64870, 64691, 64545, 64801, + 64773, 64690, 64811, 64783, 64802, 64774, 65013, 64975, 65008, 65017, + 65018, 64844, 64838, 64860, 64686, 64541, 64821, 64817, 64744, 64862, + 64861, 64685, 64540, 64820, 64936, 64966, 64687, 64542, 64822, 64864, + 64863, 64865, 64867, 64866, 64688, 64543, 64743, 64791, 64763, 64810, + 64782, 64792, 64764, 64606, 64609, 64755, 64607, 64610, 64756, 64611, + 64608, 64754, 64818, 64746, 64872, 64871, 64938, 64806, 64814, 64778, + 64824, 64873, 64805, 64813, 64777, 64823, 64875, 64874, 64877, 64876, + 64808, 64816, 64780, 64745, 64793, 64765, 64807, 64815, 64779, 64825, + 64809, 64781, 64794, 64766, 65022, 64846, 64882, 64881, 64883, 64884, + 64819, 64551, 64826, 64785, 64757, 64696, 64550, 64786, 64758, 64851, + 64850, 64849, 64674, 64524, 64677, 64740, 64930, 64852, 64929, 64675, + 64525, 64928, 64848, 64927, 64673, 64523, 64932, 64853, 64855, 64854, + 64931, 64626, 64676, 64526, 64739, 64628, 64527, 64627, 64625, 64624, + 64629, 64528, 64603, 64529, 64634, 64531, 64632, 64678, 64530, 64741, + 64633, 64631, 64630, 64635, 64532, 64742, 65016, 64661, 64601, 64616, + 64515, 64491, 64490, 64493, 64492, 64503, 64504, 64502, 64667, 64736, + 64664, 64513, 64663, 64512, 64665, 64614, 64666, 64514, 64735, 64615, + 64499, 64498, 64495, 64494, 64617, 64516, 64501, 64500, 64613, 64612, + 64497, 64496, 64942, 64731, 64598, 64734, 64753, 64660, 64658, 64943, + 64730, 64597, 64732, 64599, 64925, 64924, 64944, 64659, 64733, 64600, + 64752, 64657, 64662, 64602, 64506, 64507, 64505, 64697, 64552, 64827, + 2204, 1619, 1624, 2303, 126492, 126494, 126493, 126495, 126644, 126638, + 126641, 126647, 126648, 126646, 126632, 126645, 126630, 126650, 126626, + 126636, 126631, 126625, 126640, 126643, 126633, 126651, 126637, 126635, + 126649, 126627, 126642, 126639, 126629, 126489, 126467, 126518, 126517, + 126516, 126510, 126513, 126503, 126500, 126519, 126506, 126498, 126508, + 126497, 126512, 126505, 126523, 126509, 126507, 126514, 126511, 126521, + 126612, 126606, 126609, 126615, 126592, 126607, 126599, 126596, 126616, + 126614, 126600, 126613, 126598, 126618, 126594, 126604, 126593, 126608, + 126611, 126601, 126619, 126605, 126603, 126617, 126595, 126610, 126597, + 126475, 126704, 126705, 126588, 126590, 126585, 126582, 126568, 126581, + 126580, 126574, 126577, 126567, 126564, 126583, 126570, 126562, 126572, + 126586, 126561, 126576, 126569, 126587, 126573, 126578, 126575, 126484, + 126478, 126481, 126557, 126559, 126553, 126548, 126542, 126545, 126551, + 126530, 126535, 126537, 126555, 126541, 126539, 126546, 126543, 126472, + 126488, 126486, 126485, 126464, 126479, 126487, 126474, 126470, 126490, + 126466, 126476, 126471, 126465, 126480, 126483, 126473, 126491, 126477, + 126482, 126469, 1541, 1536, 2290, 2289, 2288, 1550, 2192, 1769, 2193, + 1642, 2184, 1544, 1629, 2296, 2301, 2298, 1772, 2183, 1623, 983633, + 983635, 983640, 983634, 983638, 983636, 983639, 983637, 983641, 1563, + 1617, 65148, 65149, 1554, 1555, 1552, 1537, 1539, 1540, 1790, 1789, 1553, + 1551, 1556, 2249, 1560, 1761, 2250, 2272, 1558, 983202, 1751, 1750, 1753, + 1752, 1762, 1764, 1768, 2264, 2273, 1756, 2261, 1755, 1557, 2200, 2260, + 2266, 2268, 2267, 2269, 2252, 2271, 2270, 2291, 1767, 2251, 1760, 1759, + 1559, 2253, 1754, 2263, 2262, 2265, 2202, 2201, 69375, 2203, 69373, + 69374, 2259, 1773, 1763, 1562, 1561, 1766, 1765, 1622, 1618, 65150, + 65151, 2256, 2205, 64444, 64435, 64434, 64441, 64440, 64439, 64438, + 64446, 64445, 64437, 64436, 64449, 64448, 64443, 64442, 64450, 64447, + 1758, 1600, 2179, 2180, 65137, 2181, 65139, 2285, 2282, 2286, 2283, 2287, + 2284, 1566, 2275, 1644, 1627, 1626, 1628, 2190, 1631, 1567, 1625, 1545, + 1546, 1542, 1543, 1637, 1636, 1639, 1638, 1635, 1634, 1632, 1641, 1633, + 1640, 1375, 1370, 1359, 1337, 1349, 1362, 1347, 1353, 1342, 1361, 1360, + 1356, 1333, 1335, 1336, 1346, 1331, 1355, 1345, 1364, 1343, 1363, 1354, + 1351, 1357, 1329, 1358, 1352, 1340, 1366, 1341, 1339, 1330, 1348, 1350, + 1338, 1334, 1344, 1332, 1365, 1373, 1371, 1372, 1395, 1401, 1390, 1409, + 1408, 1404, 1381, 1383, 1384, 1394, 1379, 1403, 1393, 1412, 1391, 1411, + 1402, 1399, 1405, 1376, 1407, 1385, 1377, 1406, 1400, 1397, 1416, 1410, + 1388, 1414, 1389, 1387, 1378, 1396, 1398, 1386, 1382, 1392, 1380, 1413, + 1415, 64279, 64277, 64275, 64276, 64278, 1369, 1418, 1423, 1417, 1374, + 129201, 10549, 10548, 129200, 10550, 10551, 129968, 128667, 127912, 9800, + 8978, 9738, 65948, 42, 8727, 8258, 128562, 11225, 9954, 8771, 8870, + 128095, 9883, 128663, 127975, 128762, 8371, 127814, 68352, 68353, 68357, + 68355, 68358, 68359, 68356, 68354, 68373, 68374, 68372, 68393, 68405, + 68388, 68387, 68386, 68391, 68390, 68389, 68371, 68370, 68369, 68403, + 68401, 68404, 68399, 68394, 68395, 68378, 68381, 68377, 68366, 68367, + 68362, 68363, 68364, 68365, 68385, 68384, 68380, 68379, 68402, 68400, + 68360, 68361, 68375, 68383, 68376, 68368, 68398, 68392, 68382, 68397, + 68396, 68409, 129361, 1547, 129518, 8525, 9810, 129683, 128118, 128036, + 127868, 128124, 128700, 128281, 128386, 11101, 11099, 983056, 10155, + 128043, 129363, 127992, 129441, 129366, 129391, 128708, 7005, 7007, 7006, + 6917, 6918, 6987, 6988, 6928, 6953, 6954, 6936, 6937, 6948, 6944, 6943, + 6949, 6984, 6927, 6933, 6934, 6919, 6920, 6929, 6930, 6921, 6922, 6938, + 6939, 6931, 6981, 6932, 6982, 6958, 6925, 6926, 6950, 6945, 6935, 6940, + 6951, 6952, 6957, 6923, 6924, 6962, 6960, 6961, 6946, 6942, 6941, 6947, + 6983, 6985, 6986, 6963, 6955, 6959, 6956, 7022, 7025, 7021, 7024, 7023, + 7026, 7020, 7019, 7027, 7012, 7013, 7018, 7015, 7017, 7016, 7010, 7014, + 7009, 7011, 7032, 7036, 7033, 7034, 7035, 7031, 7030, 7029, 7028, 7003, + 7038, 7008, 7002, 7037, 6915, 6913, 6912, 6916, 6914, 6964, 6972, 6973, + 6970, 6971, 6968, 6969, 6974, 6975, 6977, 6976, 6965, 6978, 6979, 6966, + 6967, 6980, 7004, 6997, 6996, 6999, 6998, 6995, 6994, 6992, 7001, 6993, + 7000, 127880, 10057, 9744, 128503, 128505, 128499, 128501, 11197, 9745, + 9746, 128502, 128500, 10007, 129526, 129648, 42737, 42736, 42741, 42740, + 42733, 42699, 42713, 42712, 42692, 42706, 42683, 42719, 42734, 42735, + 42682, 42729, 42657, 42725, 42659, 42670, 42718, 42666, 42716, 42701, + 42675, 42671, 42722, 42720, 42727, 42723, 42702, 42726, 42677, 42707, + 42708, 42709, 42686, 42694, 42674, 42731, 42695, 42685, 42684, 42691, + 42673, 42664, 42715, 42703, 92193, 92188, 92161, 92199, 92240, 92179, + 92211, 92219, 92213, 92243, 92207, 92216, 92183, 92184, 92238, 92171, + 92174, 92203, 92186, 92210, 92230, 92175, 92221, 92232, 92246, 92198, + 92214, 92190, 92176, 92197, 92196, 92164, 92245, 92212, 92201, 92160, + 92182, 92173, 92229, 92227, 92180, 92237, 92241, 92223, 92185, 92194, + 92178, 92239, 92225, 92233, 92167, 92191, 92231, 92244, 92204, 92226, + 92236, 92200, 92189, 92187, 92162, 92163, 92169, 92170, 92202, 92205, + 92222, 92168, 92165, 92215, 92224, 92208, 92220, 92235, 92177, 92181, + 92195, 92234, 92209, 92166, 92172, 92206, 92192, 92228, 92217, 92242, + 92218, 92262, 92271, 92272, 92270, 92294, 92253, 92301, 92256, 92273, + 92259, 92251, 92297, 92300, 92296, 92295, 92255, 92252, 92292, 92286, + 92268, 92290, 92281, 92267, 92284, 92287, 92282, 92283, 92277, 92298, + 92276, 92302, 92247, 92299, 92288, 92269, 92260, 92261, 92257, 92274, + 92289, 92263, 92279, 92265, 92266, 92250, 92249, 92285, 92248, 92264, + 92280, 92258, 92254, 92278, 92291, 92293, 92275, 92310, 92320, 92312, + 92394, 92393, 92319, 92384, 92321, 92386, 92361, 92373, 92366, 92328, + 92329, 92357, 92342, 92397, 92365, 92376, 92339, 92382, 92363, 92318, + 92387, 92383, 92315, 92385, 92354, 92311, 92381, 92343, 92326, 92364, + 92324, 92391, 92344, 92390, 92338, 92396, 92308, 92349, 92375, 92378, + 92317, 92331, 92362, 92336, 92341, 92370, 92347, 92307, 92303, 92309, + 92395, 92368, 92356, 92367, 92360, 92389, 92333, 92359, 92374, 92351, + 92325, 92371, 92350, 92345, 92372, 92314, 92340, 92323, 92304, 92313, + 92316, 92398, 92399, 92380, 92330, 92379, 92392, 92335, 92332, 92346, + 92400, 92358, 92334, 92353, 92337, 92306, 92369, 92388, 92322, 92305, + 92327, 92377, 92352, 92348, 92355, 92436, 92517, 92488, 92434, 92415, + 92431, 92454, 92460, 92420, 92489, 92422, 92474, 92479, 92449, 92502, + 92439, 92484, 92495, 92464, 92511, 92406, 92446, 92497, 92426, 92482, + 92448, 92515, 92401, 92478, 92427, 92496, 92458, 92424, 92445, 92404, + 92466, 92444, 92438, 92442, 92441, 92510, 92499, 92425, 92437, 92440, + 92471, 92465, 92409, 92483, 92475, 92467, 92485, 92457, 92432, 92476, + 92435, 92412, 92414, 92430, 92407, 92403, 92405, 92487, 92418, 92486, + 92408, 92447, 92459, 92480, 92472, 92505, 92514, 92450, 92463, 92410, + 92493, 92507, 92503, 92462, 92506, 92443, 92509, 92469, 92461, 92490, + 92512, 92494, 92455, 92417, 92501, 92413, 92508, 92500, 92504, 92473, + 92419, 92498, 92423, 92516, 92428, 92452, 92451, 92481, 92416, 92456, + 92433, 92477, 92492, 92491, 92513, 92411, 92402, 92421, 92453, 92468, + 92470, 92429, 92661, 92626, 92616, 92596, 92612, 92603, 92673, 92651, + 92627, 92597, 92585, 92578, 92615, 92565, 92552, 92602, 92674, 92570, + 92646, 92599, 92532, 92587, 92538, 92620, 92670, 92665, 92575, 92521, + 92633, 92595, 92523, 92556, 92539, 92664, 92653, 92667, 92600, 92542, + 92555, 92668, 92520, 92582, 92591, 92581, 92551, 92654, 92611, 92614, + 92666, 92671, 92617, 92637, 92562, 92518, 92592, 92558, 92528, 92607, + 92535, 92557, 92563, 92550, 92624, 92640, 92657, 92531, 92601, 92553, + 92543, 92619, 92598, 92541, 92544, 92579, 92658, 92554, 92628, 92648, + 92547, 92527, 92545, 92540, 92604, 92622, 92589, 92608, 92583, 92609, + 92662, 92613, 92584, 92625, 92634, 92524, 92536, 92605, 92647, 92548, + 92663, 92593, 92621, 92568, 92610, 92576, 92529, 92618, 92649, 92561, + 92656, 92526, 92655, 92546, 92534, 92560, 92580, 92659, 92660, 92638, + 92571, 92525, 92549, 92559, 92635, 92577, 92530, 92636, 92669, 92572, + 92672, 92537, 92519, 92630, 92586, 92569, 92566, 92573, 92652, 92522, + 92574, 92650, 92533, 92567, 92623, 92606, 92639, 92564, 92590, 92642, + 92643, 92594, 92641, 92645, 92644, 92588, 92629, 92632, 92631, 92710, + 92695, 92694, 92726, 92675, 92719, 92677, 92718, 92682, 92717, 92689, + 92720, 92724, 92685, 92722, 92723, 92711, 92712, 92698, 92688, 92697, + 92696, 92702, 92687, 92704, 92681, 92708, 92703, 92706, 92714, 92709, + 92679, 92721, 92684, 92683, 92707, 92691, 92713, 92700, 92693, 92727, + 92690, 92692, 92686, 92680, 92725, 92699, 92701, 92705, 92716, 92728, + 92678, 92715, 92676, 42693, 42698, 42711, 42696, 42667, 42717, 42704, + 42661, 42721, 42669, 42668, 42705, 42700, 42680, 42678, 42710, 42688, + 42681, 42732, 42676, 42679, 42730, 42728, 42672, 42662, 42724, 42687, + 42689, 42690, 42697, 42714, 42660, 42656, 42665, 42663, 42658, 42738, + 42742, 42739, 42743, 127974, 128183, 128180, 128182, 128181, 127820, + 129685, 128202, 129532, 128136, 129530, 127936, 92916, 92912, 92915, + 92913, 92914, 92887, 92894, 92908, 92880, 92907, 92893, 92886, 92888, + 92881, 92906, 92896, 92891, 92902, 92900, 92885, 92890, 92884, 92904, + 92905, 92899, 92889, 92897, 92892, 92895, 92882, 92898, 92883, 92901, + 92903, 92909, 92917, 9918, 129415, 7152, 7153, 7124, 7108, 7114, 7130, + 7139, 7127, 7138, 7133, 7136, 7113, 7111, 7117, 7119, 7107, 7135, 7125, + 7112, 7123, 7129, 7116, 7132, 7105, 7126, 7128, 7110, 7109, 7137, 7121, + 7118, 7106, 7120, 7134, 7122, 7115, 7131, 7104, 7140, 7141, 7154, 7155, + 7167, 7165, 7166, 7164, 7142, 7150, 7151, 7144, 7147, 7149, 7143, 7145, + 7146, 7148, 128704, 128705, 128267, 127900, 127901, 9835, 9836, 129492, + 128059, 127958, 128147, 129451, 129752, 127866, 129714, 983055, 128276, + 129745, 128277, 9086, 128718, 2519, 2557, 2432, 2548, 2552, 2551, 2550, + 2549, 2553, 2454, 2510, 983661, 2453, 2480, 2545, 2544, 2525, 2524, 2556, + 2443, 2528, 2444, 2529, 2527, 2479, 2437, 2438, 2448, 2452, 2466, 2465, + 2471, 2470, 2464, 2463, 2469, 2468, 2441, 2442, 2439, 2440, 2457, 2467, + 2462, 2472, 2486, 2487, 2488, 2477, 2476, 2459, 2458, 2456, 2455, 2461, + 2460, 2475, 2474, 2489, 2482, 2478, 2447, 2451, 2547, 2546, 983651, + 983650, 983652, 2558, 2493, 2434, 2433, 2492, 2509, 2435, 2554, 2494, + 2504, 2508, 2499, 2500, 2530, 2531, 2497, 2498, 2495, 2496, 2503, 2507, + 2539, 2538, 2541, 2540, 2537, 2536, 2534, 2543, 2535, 2542, 2555, 11102, + 127857, 9004, 9187, 8812, 8502, 8757, 129475, 128719, 72710, 72711, + 72712, 72746, 72704, 72705, 72715, 72717, 72731, 72730, 72736, 72735, + 72729, 72728, 72734, 72733, 72708, 72709, 72706, 72707, 72722, 72732, + 72727, 72737, 72747, 72748, 72749, 72741, 72740, 72724, 72723, 72721, + 72720, 72726, 72725, 72719, 72718, 72739, 72738, 72750, 72745, 72742, + 72744, 72743, 72714, 72716, 72801, 72810, 72806, 72797, 72807, 72798, + 72802, 72811, 72800, 72809, 72799, 72808, 72796, 72805, 72804, 72795, + 72803, 72794, 72768, 72765, 72764, 72767, 72766, 72756, 72757, 72758, + 72751, 72761, 72763, 72754, 72755, 72752, 72753, 72760, 72762, 72770, + 72769, 72789, 72788, 72791, 72790, 72787, 72786, 72784, 72793, 72785, + 72792, 72771, 72772, 72773, 72812, 128692, 128690, 10745, 10744, 129506, + 127921, 127874, 128038, 8383, 129766, 9763, 128089, 129452, 9679, 9864, + 10733, 9865, 9210, 11176, 11177, 11178, 11179, 11180, 11182, 11181, + 11183, 9960, 10028, 9821, 129554, 129596, 129609, 129612, 9818, 129551, + 129593, 9822, 129543, 129564, 129585, 129597, 129606, 129555, 129619, + 129617, 129618, 9823, 129556, 129598, 9819, 129552, 129594, 9820, 129553, + 129595, 129575, 129572, 129576, 129577, 129573, 129574, 9827, 9670, + 11201, 10070, 10730, 11230, 9830, 128419, 128899, 9196, 9662, 9660, + 11167, 127778, 9922, 9923, 10047, 9873, 10022, 128447, 128420, 9829, + 11042, 128426, 11052, 10711, 9194, 9198, 128896, 9668, 9666, 9664, 11164, + 8268, 9944, 128412, 9754, 9699, 9698, 10731, 11044, 11035, 9207, 11206, + 11045, 9204, 11207, 11047, 9205, 11208, 9206, 11205, 128921, 128927, + 9726, 9724, 9912, 128392, 9648, 11039, 127986, 9193, 9197, 9654, 9199, + 128898, 11091, 9658, 9656, 10145, 10148, 11166, 8269, 128413, 9755, + 127990, 9644, 11049, 11050, 11089, 9642, 9787, 9632, 11200, 9209, 128306, + 9728, 128369, 9927, 9984, 128900, 128909, 9986, 9751, 9824, 9733, 128919, + 128925, 128908, 9951, 128383, 9742, 9942, 128418, 128897, 9195, 9652, + 9650, 9700, 9701, 11165, 9851, 11054, 9646, 128920, 128926, 11037, 11204, + 10707, 10002, 10067, 8493, 8460, 8465, 8476, 8488, 10164, 10166, 10165, + 9250, 129792, 129794, 129798, 129806, 129821, 129836, 129813, 129844, + 129829, 129802, 129817, 129848, 129832, 129810, 129840, 129825, 129796, + 129804, 129819, 129850, 129834, 129842, 129827, 129800, 129815, 129846, + 129831, 129808, 129838, 129823, 129793, 129797, 129805, 129820, 129851, + 129835, 129812, 129843, 129828, 129801, 129816, 129847, 129809, 129839, + 129824, 129795, 129803, 129818, 129849, 129833, 129811, 129841, 129826, + 129799, 129814, 129845, 129830, 129807, 129837, 129822, 127804, 128033, + 128216, 128153, 129744, 128939, 128951, 128957, 128945, 128902, 128912, + 128932, 128366, 128278, 128209, 128218, 129667, 12731, 12727, 12726, + 12724, 12725, 12570, 12574, 12718, 12576, 12719, 12578, 12580, 12713, + 12735, 12720, 12584, 12715, 12572, 12579, 12581, 12709, 12708, 12573, + 12575, 12582, 12557, 12728, 12588, 12707, 12732, 12583, 12714, 12723, + 12589, 12716, 12712, 12585, 12555, 12587, 12717, 12591, 12571, 12722, + 12711, 12590, 12734, 12721, 12710, 12577, 12567, 12563, 12705, 12730, + 12558, 12733, 12568, 12564, 12556, 12729, 12569, 12565, 12549, 12704, + 12560, 12706, 12553, 12552, 12559, 12551, 12550, 12561, 12566, 12554, + 12586, 12562, 11211, 11867, 11868, 8993, 9141, 9142, 10555, 9183, 9181, + 8990, 8973, 11812, 8991, 8972, 11813, 9185, 127870, 128144, 127893, + 128335, 129379, 127923, 8904, 10705, 10706, 127993, 9574, 9559, 9556, + 9577, 9565, 9562, 9553, 9580, 9571, 9568, 9552, 9511, 9490, 9503, 9486, + 9537, 9520, 9513, 9489, 9505, 9485, 9543, 9519, 9558, 9555, 9573, 9557, + 9554, 9572, 9592, 9598, 9593, 9599, 9499, 9531, 9495, 9551, 9549, 9595, + 9523, 9491, 9487, 9483, 9481, 9479, 9477, 9475, 9547, 9515, 9507, 9473, + 9594, 9541, 9525, 9517, 9533, 9530, 9522, 9546, 9539, 9582, 9581, 9583, + 9584, 129959, 129964, 129954, 129958, 129965, 129955, 129952, 129956, + 129963, 129960, 129953, 129961, 129957, 129962, 9586, 9585, 9587, 129966, + 9550, 9548, 9591, 9516, 9488, 9484, 9588, 9596, 9482, 9480, 9478, 9476, + 9589, 9597, 9524, 9496, 9492, 9474, 9532, 9508, 9500, 9472, 129967, 9590, + 9542, 9526, 9518, 9534, 9529, 9521, 9545, 9540, 9536, 9510, 9498, 9502, + 9494, 9528, 9544, 9514, 9497, 9506, 9493, 9527, 9564, 9561, 9576, 9563, + 9560, 9575, 9570, 9567, 9579, 9538, 9512, 9504, 9535, 9509, 9501, 9569, + 9566, 9578, 129354, 983263, 128163, 128102, 128713, 128023, 129460, + 69649, 69685, 69749, 69745, 69746, 69687, 69686, 69637, 69638, 69648, + 69650, 69664, 69663, 69669, 69668, 69662, 69661, 69667, 69666, 69643, + 69644, 69645, 69646, 69679, 69641, 69642, 69639, 69640, 69684, 69678, + 69655, 69665, 69660, 69670, 69680, 69681, 69682, 69674, 69673, 69657, + 69656, 69654, 69653, 69659, 69658, 69652, 69651, 69672, 69671, 69683, + 69675, 69677, 69676, 69647, 69721, 69730, 69726, 69717, 69727, 69718, + 69722, 69731, 69720, 69729, 69719, 69728, 69716, 69725, 69724, 69715, + 69723, 69714, 69732, 69733, 69759, 69709, 69707, 69706, 69705, 69708, + 69744, 69632, 69635, 69634, 69636, 69633, 69700, 69747, 69748, 69689, + 69688, 69699, 69701, 69694, 69695, 69696, 69697, 69692, 69693, 69690, + 69691, 69698, 69702, 69704, 69703, 69739, 69738, 69741, 69740, 69737, + 69736, 69734, 69743, 69735, 69742, 10241, 10243, 10247, 10255, 10271, + 10303, 10367, 10495, 10431, 10335, 10463, 10399, 10287, 10351, 10479, + 10415, 10319, 10447, 10383, 10263, 10295, 10359, 10487, 10423, 10327, + 10455, 10391, 10279, 10343, 10471, 10407, 10311, 10439, 10375, 10251, + 10267, 10299, 10363, 10491, 10427, 10331, 10459, 10395, 10283, 10347, + 10475, 10411, 10315, 10443, 10379, 10259, 10291, 10355, 10483, 10419, + 10323, 10451, 10387, 10275, 10339, 10467, 10403, 10307, 10435, 10371, + 10245, 10253, 10269, 10301, 10365, 10493, 10429, 10333, 10461, 10397, + 10285, 10349, 10477, 10413, 10317, 10445, 10381, 10261, 10293, 10357, + 10485, 10421, 10325, 10453, 10389, 10277, 10341, 10469, 10405, 10309, + 10437, 10373, 10249, 10265, 10297, 10361, 10489, 10425, 10329, 10457, + 10393, 10281, 10345, 10473, 10409, 10313, 10441, 10377, 10257, 10289, + 10353, 10481, 10417, 10321, 10449, 10385, 10273, 10337, 10465, 10401, + 10305, 10433, 10369, 10242, 10246, 10254, 10270, 10302, 10366, 10494, + 10430, 10334, 10462, 10398, 10286, 10350, 10478, 10414, 10318, 10446, + 10382, 10262, 10294, 10358, 10486, 10422, 10326, 10454, 10390, 10278, + 10342, 10470, 10406, 10310, 10438, 10374, 10250, 10266, 10298, 10362, + 10490, 10426, 10330, 10458, 10394, 10282, 10346, 10474, 10410, 10314, + 10442, 10378, 10258, 10290, 10354, 10482, 10418, 10322, 10450, 10386, + 10274, 10338, 10466, 10402, 10306, 10434, 10370, 10244, 10252, 10268, + 10300, 10364, 10492, 10428, 10332, 10460, 10396, 10284, 10348, 10476, + 10412, 10316, 10444, 10380, 10260, 10292, 10356, 10484, 10420, 10324, + 10452, 10388, 10276, 10340, 10468, 10404, 10308, 10436, 10372, 10248, + 10264, 10296, 10360, 10488, 10424, 10328, 10456, 10392, 10280, 10344, + 10472, 10408, 10312, 10440, 10376, 10256, 10288, 10352, 10480, 10416, + 10320, 10448, 10384, 10272, 10336, 10464, 10400, 10304, 10432, 10368, + 10240, 129504, 983125, 129329, 127838, 728, 127753, 128112, 128188, + 129650, 129521, 9099, 166, 128148, 129382, 129294, 129529, 129483, + 129767, 128027, 6663, 6662, 6659, 6658, 6671, 6670, 6667, 6666, 6661, + 6668, 6665, 6657, 6678, 6669, 6656, 6674, 6660, 6673, 6676, 6664, 6675, + 6672, 6677, 6683, 6681, 6679, 6682, 6680, 6687, 6686, 5957, 5960, 5962, + 5959, 5956, 5969, 5955, 5966, 5963, 5961, 5965, 5968, 5958, 5967, 5964, + 5952, 5953, 5954, 5970, 5971, 8226, 8729, 128363, 128364, 9678, 128652, + 128101, 128100, 128655, 129480, 129419, 127959, 127791, 129699, 118939, + 118940, 118944, 118943, 118941, 118942, 118938, 118945, 118882, 118876, + 118824, 118835, 118797, 118866, 118957, 118801, 118802, 118865, 118818, + 118916, 118819, 118917, 118899, 118935, 119018, 119022, 119021, 119020, + 119023, 119019, 119017, 118986, 118984, 118985, 118843, 118887, 118808, + 118870, 119003, 119002, 119004, 119005, 118937, 118991, 118995, 118990, + 118992, 118994, 118993, 118930, 118933, 118931, 118932, 119014, 118918, + 118912, 119015, 118785, 118831, 118907, 118966, 118900, 118880, 118798, + 118888, 118884, 118869, 118960, 118959, 118958, 118836, 118969, 118977, + 118978, 118971, 118976, 118975, 118973, 118970, 118987, 118979, 118980, + 118972, 118983, 983272, 118982, 118974, 118988, 118981, 119000, 119001, + 118929, 118928, 118806, 119029, 118927, 118898, 118964, 118965, 118853, + 118968, 118837, 118967, 118936, 118956, 118810, 118854, 118847, 118839, + 118906, 118791, 118800, 119024, 119026, 118862, 118812, 119025, 119027, + 118863, 118811, 118820, 119028, 118911, 118842, 118850, 118921, 118858, + 118913, 118914, 118915, 118834, 118860, 118868, 118796, 118881, 118922, + 118926, 118925, 118924, 118923, 118830, 118877, 118949, 118947, 118948, + 118963, 118955, 118962, 118946, 118961, 118953, 118952, 118951, 118950, + 118954, 118871, 118805, 118855, 118828, 118901, 118787, 118788, 118856, + 118816, 118875, 118845, 118879, 118793, 118846, 118878, 118814, 118822, + 118873, 118859, 118857, 118849, 118840, 118861, 118786, 118895, 118841, + 118874, 118892, 118897, 118807, 118784, 118821, 118844, 118825, 118889, + 119010, 119012, 119013, 119011, 119006, 119008, 119009, 119007, 118910, + 118815, 118852, 119016, 118826, 118885, 118827, 118803, 118886, 118792, + 118813, 118920, 118799, 118833, 118829, 118904, 118902, 118903, 118905, + 118804, 118934, 118919, 118832, 118893, 118838, 118851, 118883, 118894, + 118891, 118896, 118823, 118789, 118790, 118872, 118817, 118809, 118908, + 118909, 118996, 118998, 118997, 118999, 118989, 118794, 118795, 118867, + 118864, 118848, 118890, 983262, 983126, 983057, 9764, 8454, 129305, + 128197, 128247, 128248, 127957, 983098, 5130, 5131, 5122, 6322, 5148, + 5551, 5310, 5382, 5166, 6321, 5759, 5559, 5556, 5557, 5558, 5567, 5564, + 5565, 5566, 5563, 5560, 5561, 5562, 5555, 5552, 5553, 5554, 5384, 5439, + 6387, 6388, 5281, 5264, 6382, 6389, 5203, 5674, 5675, 5677, 5676, 5673, + 5672, 5706, 5707, 5709, 5708, 5705, 5704, 5204, 5574, 5575, 5577, 5576, + 5573, 5572, 6384, 6381, 5620, 6383, 5617, 5618, 5619, 5616, 5615, 5195, + 5592, 5593, 5595, 5594, 5591, 5590, 5174, 5175, 5129, 5703, 5662, 5663, + 5665, 5664, 5661, 5660, 5655, 5656, 6386, 5659, 5657, 5654, 5652, 5633, + 5629, 5630, 5632, 5631, 5628, 5627, 5623, 5624, 5626, 5625, 5622, 5621, + 5636, 5637, 5639, 5329, 5638, 5635, 5634, 5722, 5718, 5719, 5721, 5720, + 5717, 5716, 5712, 5713, 5715, 5714, 5711, 5710, 5614, 5610, 5611, 5613, + 5612, 5609, 5608, 5702, 5698, 5699, 5701, 5700, 5697, 5696, 5686, 5687, + 5689, 5688, 5685, 5684, 5692, 5693, 5695, 5694, 5691, 5690, 5737, 5738, + 5740, 5739, 5736, 5735, 5604, 5605, 5607, 5606, 5603, 5602, 5598, 5599, + 5601, 5600, 5597, 5596, 5725, 5726, 5728, 5727, 5724, 5723, 5680, 5681, + 5683, 5682, 5679, 5678, 5668, 5669, 5671, 5670, 5667, 5666, 5731, 5732, + 5734, 5733, 5730, 5729, 5642, 5643, 5645, 5644, 5641, 5640, 5580, 5581, + 5583, 5582, 5579, 5578, 5586, 5587, 5589, 5588, 5585, 5584, 5648, 5649, + 5651, 5650, 5647, 5646, 5128, 5265, 5258, 5276, 5278, 5272, 5274, 5268, + 5270, 5266, 5741, 5261, 5262, 5259, 5260, 5257, 5121, 6364, 5163, 5469, + 5465, 5466, 5460, 5461, 5158, 5157, 5162, 5155, 5156, 6367, 6366, 5160, + 5152, 5151, 5153, 5154, 5161, 5159, 5462, 5742, 5463, 5464, 5467, 5459, + 5120, 5501, 5123, 5124, 5164, 5251, 5252, 5246, 5248, 6329, 5242, 5244, + 5238, 5240, 5236, 5234, 5235, 5228, 6328, 5231, 5232, 5229, 5230, 5227, + 5354, 5542, 5540, 5541, 5538, 5539, 5536, 5537, 5338, 5339, 5332, 6333, + 5350, 5352, 5346, 5348, 5342, 5344, 5340, 5335, 5336, 5333, 5334, 5331, + 5307, 5283, 5356, 5458, 5287, 5288, 5385, 5290, 5291, 5284, 6330, 5302, + 5304, 5298, 5300, 5294, 5296, 5292, 5285, 5286, 5309, 5328, 5473, 5475, + 5471, 5319, 5386, 5390, 5391, 5388, 5389, 5380, 5387, 5142, 5147, 5280, + 5250, 5306, 5327, 5221, 5437, 72372, 72373, 72370, 72371, 72368, 72369, + 72378, 72379, 72376, 72377, 72374, 72375, 5320, 5313, 6332, 5525, 5523, + 5524, 5518, 5744, 5521, 5522, 5519, 5520, 5526, 5749, 5750, 5747, 5748, + 5745, 5746, 5499, 5497, 5498, 5495, 5496, 5493, 5494, 5492, 5500, 5316, + 5317, 6331, 5323, 5325, 6346, 6348, 6342, 6344, 5321, 5314, 5315, 5312, + 5330, 5509, 5507, 5508, 5502, 5743, 5505, 5506, 5503, 5504, 5125, 6361, + 6347, 6349, 6343, 6345, 6362, 6363, 6359, 6358, 6360, 6356, 6357, 5165, + 5126, 6320, 5193, 5184, 5186, 6326, 5188, 5190, 5180, 5182, 5178, 5176, + 5177, 5168, 6325, 5171, 5172, 6324, 5169, 5170, 5167, 5456, 6368, 5443, + 6355, 5454, 6353, 6354, 6351, 6352, 6350, 5451, 5452, 5445, 6341, 5448, + 5449, 5446, 5447, 5442, 5381, 5364, 6335, 5570, 6380, 5571, 5568, 5569, + 5653, 6385, 5658, 5529, 6379, 6378, 5530, 5527, 5528, 5441, 5282, 5311, + 5365, 5358, 5413, 5405, 5407, 6338, 5409, 5411, 5401, 5403, 5399, 5395, + 5396, 6336, 5397, 5398, 6337, 5393, 5394, 5392, 5361, 5256, 5253, 5254, + 5255, 5362, 6334, 5383, 5376, 5378, 5372, 5374, 5368, 5370, 5366, 72383, + 72380, 72381, 72382, 5359, 5360, 5357, 5222, 5482, 5550, 5548, 5549, + 5546, 5547, 5544, 5545, 5543, 6372, 5480, 6371, 5478, 5479, 5476, 5477, + 5472, 5474, 5470, 5512, 6377, 6376, 5513, 5510, 5511, 5487, 5486, 6375, + 5485, 6374, 6373, 5483, 5484, 5226, 5223, 5224, 5225, 5205, 5206, 5197, + 6327, 5217, 5219, 5213, 5215, 5209, 5211, 5207, 5491, 5488, 5489, 5490, + 5200, 5201, 5198, 5199, 5196, 5132, 5355, 5351, 5353, 5347, 5349, 5343, + 5345, 5341, 5453, 6370, 5450, 6369, 5444, 5308, 5303, 5305, 5299, 5301, + 5295, 5297, 5293, 5194, 5189, 5191, 5185, 5187, 5181, 5183, 5179, 5440, + 5434, 5436, 5430, 5432, 5426, 5428, 5424, 5324, 5326, 5322, 5457, 5455, + 5517, 5514, 5515, 5516, 5410, 5412, 5406, 5408, 5402, 5404, 5400, 5377, + 5379, 5373, 5375, 5369, 5371, 5367, 5277, 5279, 5273, 5275, 5269, 5271, + 5267, 5247, 5249, 5243, 5245, 5239, 5241, 5237, 5481, 5218, 5220, 5214, + 5216, 5210, 5212, 5208, 5468, 5144, 5146, 5139, 5141, 5135, 5137, 5133, + 6365, 5138, 5140, 5535, 5756, 5757, 5754, 5755, 5752, 5753, 5751, 5534, + 5531, 5532, 5533, 5758, 5143, 5145, 6323, 5134, 5136, 5438, 5192, 5173, + 5263, 5233, 5337, 5289, 5318, 5363, 5202, 5420, 5127, 5149, 5421, 5422, + 5415, 6340, 5418, 5419, 6339, 5433, 5435, 5429, 5431, 5425, 5427, 5423, + 5416, 5417, 5414, 5150, 983097, 983171, 917631, 128473, 9803, 128367, + 127852, 129387, 128758, 11839, 9809, 128199, 128450, 128451, 8248, 8257, + 8453, 66225, 66246, 66211, 66214, 66254, 66218, 66250, 66251, 66252, + 66253, 66229, 66238, 66244, 66227, 66224, 66222, 66223, 66242, 66243, + 66232, 66221, 66247, 66230, 66226, 66239, 66212, 66248, 66256, 66235, + 66208, 66215, 66210, 66220, 66234, 66255, 66240, 66241, 66236, 66237, + 66231, 66209, 66213, 66249, 66233, 66245, 66217, 66219, 66216, 66228, + 127904, 711, 127887, 129690, 983073, 129365, 9936, 128008, 128049, + 128569, 128572, 66888, 66864, 66912, 66882, 66873, 66902, 66889, 66890, + 66911, 66891, 66895, 66901, 66881, 66867, 66870, 66868, 66904, 66866, + 66876, 66910, 66879, 66883, 66897, 66915, 66884, 66878, 66885, 66914, + 66903, 66877, 66896, 66909, 66906, 66908, 66899, 66872, 66913, 66874, + 66871, 66875, 66869, 66893, 66887, 66892, 66907, 66900, 66894, 66905, + 66880, 66898, 66865, 66886, 66927, 9761, 127797, 9963, 8373, 184, 65102, + 65098, 8452, 162, 128328, 9907, 9939, 129681, 69908, 69907, 69913, 69912, + 69899, 69909, 69904, 69914, 69906, 69905, 69911, 69910, 69920, 69921, + 69918, 69917, 69901, 69900, 69898, 69897, 69903, 69902, 69896, 69895, + 69956, 69923, 69916, 69915, 69926, 69919, 69922, 69925, 69959, 69924, + 69891, 69894, 69892, 69893, 69888, 69890, 69889, 69952, 69927, 69957, + 69933, 69935, 69930, 69931, 69932, 69958, 69928, 69929, 69934, 69936, + 69939, 69954, 69953, 69947, 69946, 69949, 69948, 69945, 69944, 69942, + 69951, 69943, 69950, 69955, 69940, 69938, 69937, 43587, 43597, 43596, + 43573, 43572, 43574, 43571, 43590, 43586, 43595, 43588, 43585, 43584, + 43594, 43591, 43593, 43589, 43592, 43530, 43531, 43536, 43538, 43537, + 43543, 43544, 43551, 43552, 43548, 43547, 43546, 43553, 43550, 43549, + 43545, 43542, 43541, 43558, 43559, 43520, 43524, 43533, 43532, 43529, + 43528, 43535, 43534, 43527, 43526, 43540, 43539, 43560, 43556, 43555, + 43557, 43554, 43523, 43521, 43525, 43522, 43612, 43614, 43613, 43615, + 43561, 43568, 43569, 43562, 43563, 43567, 43566, 43565, 43570, 43564, + 43605, 43604, 43607, 43606, 43603, 43602, 43600, 43609, 43601, 43608, + 983058, 983140, 983137, 8256, 128200, 128185, 128201, 128638, 129941, + 10003, 129472, 128227, 5084, 5075, 5077, 5079, 5081, 5082, 5083, 5055, + 5037, 5038, 5039, 5040, 5041, 5042, 5054, 5056, 5057, 5058, 5059, 5060, + 5061, 5069, 5068, 5070, 5071, 5072, 5073, 5074, 5085, 5086, 5087, 5088, + 5089, 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5076, 5078, 5080, 5030, + 5032, 5033, 5034, 5035, 5036, 5043, 5044, 5045, 5046, 5047, 5048, 5049, + 5050, 5051, 5052, 5053, 5109, 5062, 5063, 5064, 5065, 5066, 5067, 5097, + 5098, 5099, 5100, 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108, 5031, + 5024, 5025, 5026, 5027, 5028, 5029, 43948, 43939, 43941, 43943, 43945, + 43946, 43947, 43919, 43901, 43902, 43903, 43904, 43905, 43906, 43918, + 43920, 43921, 43922, 43923, 43924, 43925, 43933, 43932, 43934, 43935, + 43936, 43937, 43938, 43949, 43950, 43951, 43952, 43953, 43954, 43955, + 43956, 43957, 43958, 43959, 43960, 43940, 43942, 43944, 43894, 43896, + 43897, 43898, 43899, 43900, 43907, 43908, 43909, 43910, 43911, 43912, + 43913, 43914, 43915, 43916, 43917, 5117, 43926, 43927, 43928, 43929, + 43930, 43931, 43961, 43962, 43963, 43964, 43965, 43966, 43967, 5112, + 5113, 5114, 5115, 5116, 43895, 43888, 43889, 43890, 43891, 43892, 43893, + 127800, 127826, 127792, 127937, 129490, 128696, 9767, 128063, 128020, + 9911, 69559, 69553, 69567, 69571, 69556, 69564, 69570, 69552, 69568, + 69555, 69560, 69562, 69557, 69561, 69563, 69554, 69566, 69572, 69558, + 69569, 69565, 69578, 69574, 69575, 69577, 69573, 69579, 69576, 129378, + 127851, 127876, 9962, 127910, 9680, 9682, 10690, 10683, 10691, 9684, + 9683, 9685, 9677, 9681, 10677, 10682, 10684, 127246, 8859, 11199, 10687, + 129282, 129280, 129281, 128320, 9938, 127342, 127341, 127277, 8856, + 10808, 9316, 9315, 9318, 9317, 9314, 9313, 9450, 9320, 9312, 9319, + 127247, 8857, 8861, 12905, 12919, 12904, 12918, 12903, 12917, 12926, + 12909, 12923, 12906, 12920, 12896, 12910, 12900, 12914, 12897, 12911, + 12908, 12922, 12901, 12915, 12899, 12913, 12902, 12916, 12907, 12921, + 12898, 12912, 9097, 10162, 127343, 12975, 127569, 12959, 127568, 12963, + 12951, 12962, 12965, 12973, 12943, 12957, 12935, 12950, 12939, 12932, + 12955, 12931, 12964, 12946, 12869, 12871, 12952, 12966, 12967, 12969, + 12942, 12954, 12938, 12976, 12936, 12948, 12868, 12974, 12961, 12970, + 12968, 12953, 12934, 12972, 12956, 12944, 12870, 12947, 12949, 12971, + 12945, 12933, 12930, 12937, 12929, 12941, 12940, 12960, 12958, 12928, + 127275, 127276, 128712, 13033, 13036, 13034, 13037, 13035, 13013, 13016, + 13014, 13017, 13015, 13038, 13041, 13039, 13042, 13040, 13028, 13031, + 13029, 13032, 13030, 13046, 13049, 13047, 13050, 13048, 13018, 13021, + 13019, 13022, 13020, 13023, 13026, 13024, 13027, 13025, 13051, 13053, + 13052, 13054, 13043, 13045, 13044, 13008, 13011, 13009, 13012, 13010, + 12925, 12924, 9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, + 9408, 9409, 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, + 9420, 9421, 9422, 9423, 9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, + 9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441, 9442, 9443, + 9444, 9445, 9446, 9447, 9448, 9449, 10688, 10806, 8854, 12879, 9329, + 9322, 12991, 12876, 9326, 12981, 12875, 12982, 12986, 12985, 12988, + 12987, 12984, 12983, 12990, 12989, 9325, 12878, 9328, 12877, 9327, 9321, + 12872, 12890, 12874, 12891, 12895, 12894, 12978, 12977, 12893, 12892, + 12980, 12979, 9324, 9331, 12873, 12881, 12885, 12884, 12887, 12886, + 12883, 12882, 12889, 12888, 9323, 9330, 10050, 12342, 10679, 10681, 8853, + 8858, 10680, 128981, 9098, 8855, 10686, 10026, 127278, 127245, 8860, + 10678, 10689, 128983, 11198, 94, 10768, 127914, 127961, 127750, 195088, + 195089, 195090, 195091, 195092, 195093, 195094, 195095, 195096, 195097, + 195098, 195099, 195100, 195101, 195072, 195073, 195074, 195075, 195076, + 195077, 195078, 195079, 195080, 195081, 195082, 195083, 195084, 195085, + 195086, 195087, 194560, 194561, 194562, 194563, 194564, 194565, 194566, + 194567, 194568, 194569, 194570, 194571, 194572, 194573, 194574, 194575, + 194576, 194577, 194578, 194579, 194580, 194581, 194582, 194583, 194584, + 194585, 194586, 194587, 194588, 194589, 194590, 194591, 194592, 194593, + 194594, 194595, 194596, 194597, 194598, 194599, 194600, 194601, 194602, + 194603, 194604, 194605, 194606, 194607, 194608, 194609, 194610, 194611, + 194612, 194613, 194614, 194615, 194616, 194617, 194618, 194619, 194620, + 194621, 194622, 194623, 194624, 194625, 194626, 194627, 194628, 194629, + 194630, 194631, 194632, 194633, 194634, 194635, 194636, 194637, 194638, + 194639, 194640, 194641, 194642, 194643, 194644, 194645, 194646, 194647, + 194648, 194649, 194650, 194651, 194652, 194653, 194654, 194655, 194656, + 194657, 194658, 194659, 194660, 194661, 194662, 194663, 194664, 194665, + 194666, 194667, 194668, 194669, 194670, 194671, 194672, 194673, 194674, + 194675, 194676, 194677, 194678, 194679, 194680, 194681, 194682, 194683, + 194684, 194685, 194686, 194687, 194688, 194689, 194690, 194691, 194692, + 194693, 194694, 194695, 194696, 194697, 194698, 194699, 194700, 194701, + 194702, 194703, 194704, 194705, 194706, 194707, 194708, 194709, 194710, + 194711, 194712, 194713, 194714, 194715, 194716, 194717, 194718, 194719, + 194720, 194721, 194722, 194723, 194724, 194725, 194726, 194727, 194728, + 194729, 194730, 194731, 194732, 194733, 194734, 194735, 194736, 194737, + 194738, 194739, 194740, 194741, 194742, 194743, 194744, 194745, 194746, + 194747, 194748, 194749, 194750, 194751, 194752, 194753, 194754, 194755, + 194756, 194757, 194758, 194759, 194760, 194761, 194762, 194763, 194764, + 194765, 194766, 194767, 194768, 194769, 194770, 194771, 194772, 194773, + 194774, 194775, 194776, 194777, 194778, 194779, 194780, 194781, 194782, + 194783, 194784, 194785, 194786, 194787, 194788, 194789, 194790, 194791, + 194792, 194793, 194794, 194795, 194796, 194797, 194798, 194799, 194800, + 194801, 194802, 194803, 194804, 194805, 194806, 194807, 194808, 194809, + 194810, 194811, 194812, 194813, 194814, 194815, 194816, 194817, 194818, + 194819, 194820, 194821, 194822, 194823, 194824, 194825, 194826, 194827, + 194828, 194829, 194830, 194831, 194832, 194833, 194834, 194835, 194836, + 194837, 194838, 194839, 194840, 194841, 194842, 194843, 194844, 194845, + 194846, 194847, 194848, 194849, 194850, 194851, 194852, 194853, 194854, + 194855, 194856, 194857, 194858, 194859, 194860, 194861, 194862, 194863, + 194864, 194865, 194866, 194867, 194868, 194869, 194870, 194871, 194872, + 194873, 194874, 194875, 194876, 194877, 194878, 194879, 194880, 194881, + 194882, 194883, 194884, 194885, 194886, 194887, 194888, 194889, 194890, + 194891, 194892, 194893, 194894, 194895, 194896, 194897, 194898, 194899, + 194900, 194901, 194902, 194903, 194904, 194905, 194906, 194907, 194908, + 194909, 194910, 194911, 194912, 194913, 194914, 194915, 194916, 194917, + 194918, 194919, 194920, 194921, 194922, 194923, 194924, 194925, 194926, + 194927, 194928, 194929, 194930, 194931, 194932, 194933, 194934, 194935, + 194936, 194937, 194938, 194939, 194940, 194941, 194942, 194943, 194944, + 194945, 194946, 194947, 194948, 194949, 194950, 194951, 194952, 194953, + 194954, 194955, 194956, 194957, 194958, 194959, 194960, 194961, 194962, + 194963, 194964, 194965, 194966, 194967, 194968, 194969, 194970, 194971, + 194972, 194973, 194974, 194975, 194976, 194977, 194978, 194979, 194980, + 194981, 194982, 194983, 194984, 194985, 194986, 194987, 194988, 194989, + 194990, 194991, 194992, 194993, 194994, 194995, 194996, 194997, 194998, + 194999, 195000, 195001, 195002, 195003, 195004, 195005, 195006, 195007, + 195008, 195009, 195010, 195011, 195012, 195013, 195014, 195015, 195016, + 195017, 195018, 195019, 195020, 195021, 195022, 195023, 195024, 195025, + 195026, 195027, 195028, 195029, 195030, 195031, 195032, 195033, 195034, + 195035, 195036, 195037, 195038, 195039, 195040, 195041, 195042, 195043, + 195044, 195045, 195046, 195047, 195048, 195049, 195050, 195051, 195052, + 195053, 195054, 195055, 195056, 195057, 195058, 195059, 195060, 195061, + 195062, 195063, 195064, 195065, 195066, 195067, 195068, 195069, 195070, + 195071, 64096, 64097, 64098, 64099, 64100, 64101, 64102, 64103, 64104, + 64105, 64106, 64107, 64108, 64109, 64000, 64001, 64002, 64003, 64004, + 64005, 64006, 64007, 64008, 64009, 64010, 64011, 64012, 64013, 64014, + 64015, 64016, 64017, 64018, 64019, 64020, 64021, 64022, 64023, 64024, + 64025, 64026, 64027, 64028, 64029, 64030, 64031, 64032, 64033, 64034, + 64035, 64036, 64037, 64038, 64039, 64040, 64041, 64042, 64043, 64044, + 64045, 64046, 64047, 64048, 64049, 64050, 64051, 64052, 64053, 64054, + 64055, 64056, 64057, 64058, 64059, 64060, 64061, 64062, 64063, 64064, + 64065, 64066, 64067, 64068, 64069, 64070, 64071, 64072, 64073, 64074, + 64075, 64076, 64077, 64078, 64079, 64080, 64081, 64082, 64083, 64084, + 64085, 64086, 64087, 64088, 64089, 64090, 64091, 64092, 64093, 64094, + 64095, 64112, 64113, 64114, 64115, 64116, 64117, 64118, 64119, 64120, + 64121, 64122, 64123, 64124, 64125, 64126, 64127, 64128, 64129, 64130, + 64131, 64132, 64133, 64134, 64135, 64136, 64137, 64138, 64139, 64140, + 64141, 64142, 64143, 64144, 64145, 64146, 64147, 64148, 64149, 64150, + 64151, 64152, 64153, 64154, 64155, 64156, 64157, 64158, 64159, 64160, + 64161, 64162, 64163, 64164, 64165, 64166, 64167, 64168, 64169, 64170, + 64171, 64172, 64173, 64174, 64175, 64176, 64177, 64178, 64179, 64180, + 64181, 64182, 64183, 64184, 64185, 64186, 64187, 64188, 64189, 64190, + 64191, 64192, 64193, 64194, 64195, 64196, 64197, 64198, 64199, 64200, + 64201, 64202, 64203, 64204, 64205, 64206, 64207, 64208, 64209, 64210, + 64211, 64212, 64213, 64214, 64215, 64216, 64217, 63744, 63745, 63746, + 63747, 63748, 63749, 63750, 63751, 63752, 63753, 63754, 63755, 63756, + 63757, 63758, 63759, 63760, 63761, 63762, 63763, 63764, 63765, 63766, + 63767, 63768, 63769, 63770, 63771, 63772, 63773, 63774, 63775, 63776, + 63777, 63778, 63779, 63780, 63781, 63782, 63783, 63784, 63785, 63786, + 63787, 63788, 63789, 63790, 63791, 63792, 63793, 63794, 63795, 63796, + 63797, 63798, 63799, 63800, 63801, 63802, 63803, 63804, 63805, 63806, + 63807, 63808, 63809, 63810, 63811, 63812, 63813, 63814, 63815, 63816, + 63817, 63818, 63819, 63820, 63821, 63822, 63823, 63824, 63825, 63826, + 63827, 63828, 63829, 63830, 63831, 63832, 63833, 63834, 63835, 63836, + 63837, 63838, 63839, 63840, 63841, 63842, 63843, 63844, 63845, 63846, + 63847, 63848, 63849, 63850, 63851, 63852, 63853, 63854, 63855, 63856, + 63857, 63858, 63859, 63860, 63861, 63862, 63863, 63864, 63865, 63866, + 63867, 63868, 63869, 63870, 63871, 63872, 63873, 63874, 63875, 63876, + 63877, 63878, 63879, 63880, 63881, 63882, 63883, 63884, 63885, 63886, + 63887, 63888, 63889, 63890, 63891, 63892, 63893, 63894, 63895, 63896, + 63897, 63898, 63899, 63900, 63901, 63902, 63903, 63904, 63905, 63906, + 63907, 63908, 63909, 63910, 63911, 63912, 63913, 63914, 63915, 63916, + 63917, 63918, 63919, 63920, 63921, 63922, 63923, 63924, 63925, 63926, + 63927, 63928, 63929, 63930, 63931, 63932, 63933, 63934, 63935, 63936, + 63937, 63938, 63939, 63940, 63941, 63942, 63943, 63944, 63945, 63946, + 63947, 63948, 63949, 63950, 63951, 63952, 63953, 63954, 63955, 63956, + 63957, 63958, 63959, 63960, 63961, 63962, 63963, 63964, 63965, 63966, + 63967, 63968, 63969, 63970, 63971, 63972, 63973, 63974, 63975, 63976, + 63977, 63978, 63979, 63980, 63981, 63982, 63983, 63984, 63985, 63986, + 63987, 63988, 63989, 63990, 63991, 63992, 63993, 63994, 63995, 63996, + 63997, 63998, 63999, 11946, 12003, 11910, 11963, 11962, 11950, 11992, + 12012, 12000, 12005, 11996, 12010, 11984, 11988, 11994, 11987, 11952, + 12007, 11977, 11976, 11973, 12019, 11993, 12014, 11995, 12016, 12006, + 12002, 11979, 11936, 11983, 11905, 11970, 11943, 11931, 11914, 11934, + 11944, 11999, 11998, 11997, 11960, 11947, 11939, 11978, 11968, 11967, + 11966, 12004, 11927, 11926, 12001, 11975, 11928, 12018, 12013, 12015, + 12011, 11945, 11986, 11985, 11921, 11920, 11919, 11918, 11964, 11957, + 11990, 11989, 11935, 11965, 11933, 11941, 11940, 11909, 11991, 11959, + 11929, 11904, 11908, 11907, 11906, 11915, 11942, 11974, 11980, 12008, + 12009, 11951, 11925, 11924, 11922, 11949, 11948, 11917, 11916, 11958, + 11932, 12017, 11911, 11923, 11969, 11982, 11981, 11938, 11937, 11972, + 11971, 11956, 11955, 11954, 11953, 11913, 11912, 11961, 12752, 12743, + 12748, 12757, 12741, 12750, 12769, 12747, 12749, 12744, 12742, 12746, + 12768, 12758, 12754, 12763, 12770, 12764, 12753, 12740, 12767, 12760, + 12759, 12745, 12766, 12762, 12755, 12761, 12736, 12765, 12739, 12737, + 12738, 12756, 12751, 12771, 128079, 127916, 127963, 128385, 129346, + 127867, 128203, 128346, 128358, 128343, 128355, 128340, 128352, 128339, + 128351, 128344, 128356, 128336, 128348, 128342, 128354, 128341, 128353, + 128345, 128357, 128347, 128359, 128337, 128349, 128338, 128350, 10561, + 8754, 128259, 10227, 128472, 128257, 128258, 8631, 11118, 8635, 8753, + 10959, 10961, 10960, 10962, 127746, 10828, 10832, 128234, 128235, 128272, + 128213, 10829, 8272, 9729, 127786, 127785, 127784, 127783, 129313, 9114, + 129715, 127864, 129381, 58, 8788, 8353, 128165, 7625, 7623, 769, 791, + 833, 8410, 8404, 8423, 857, 8432, 7677, 844, 774, 7627, 814, 810, 838, + 70459, 780, 812, 784, 8409, 8405, 787, 789, 806, 65062, 65069, 42609, + 1160, 11774, 11744, 11768, 11747, 11757, 11765, 42654, 11751, 11752, + 11753, 11756, 42613, 11775, 11772, 42655, 11767, 11754, 42619, 11763, + 11762, 42618, 42615, 42612, 42617, 11770, 42614, 11771, 11773, 11769, + 11759, 42616, 11760, 11758, 11748, 11749, 11761, 11746, 11764, 11755, + 11745, 11750, 11766, 42621, 1156, 1158, 1159, 1157, 42608, 42610, 1155, + 65070, 65071, 1161, 42620, 123023, 42607, 770, 813, 807, 43248, 43244, + 43245, 43246, 43247, 43242, 43243, 43249, 43237, 43236, 43239, 43238, + 43235, 43234, 43232, 43241, 43233, 43240, 7675, 776, 6833, 804, 775, + 7672, 856, 803, 7674, 7617, 7616, 861, 860, 865, 7676, 862, 863, 6840, + 831, 6858, 6857, 6844, 866, 858, 864, 65058, 65059, 8422, 840, 782, 779, + 783, 819, 7629, 6832, 798, 6835, 8413, 8416, 8418, 8414, 8419, 8420, + 8415, 839, 850, 8412, 122892, 122884, 122891, 122890, 122921, 122919, + 122889, 122916, 122900, 122907, 122910, 122901, 122908, 122880, 122920, + 122881, 122909, 122903, 122922, 122883, 122895, 122894, 122896, 122898, + 122899, 122882, 122885, 122912, 122911, 122913, 122918, 122915, 122888, + 122886, 122904, 122902, 122897, 122893, 70508, 70507, 70506, 70505, + 70504, 70502, 70503, 70515, 70513, 70514, 70516, 70512, 768, 790, 832, + 7624, 7621, 847, 119363, 119362, 119364, 835, 834, 837, 836, 777, 843, + 795, 785, 815, 826, 811, 6855, 6834, 7632, 12442, 12441, 7671, 7670, + 7643, 7646, 7647, 7649, 7650, 867, 7666, 7655, 7636, 7637, 7638, 872, + 7639, 868, 7663, 7641, 7659, 7635, 869, 7640, 6860, 6861, 6862, 7645, + 7660, 7653, 870, 7667, 7661, 871, 7668, 7664, 876, 7651, 7626, 877, 6848, + 7652, 7658, 7656, 7657, 7665, 6847, 873, 7642, 874, 7644, 875, 7648, + 7662, 878, 879, 7654, 852, 7678, 8430, 8406, 841, 794, 6849, 6851, 796, + 849, 8400, 792, 845, 8417, 8429, 8426, 65056, 65063, 65057, 65064, 6841, + 8427, 824, 822, 8402, 818, 772, 65060, 65067, 65061, 65068, 817, 7622, + 7620, 7628, 800, 6854, 842, 66424, 66425, 66423, 66426, 66422, 6839, 808, + 7630, 773, 6846, 6845, 6843, 801, 799, 6856, 8421, 788, 802, 7679, 854, + 848, 853, 8431, 8407, 825, 855, 8401, 6850, 6852, 793, 8428, 8408, 805, + 778, 7631, 859, 823, 821, 8403, 6853, 827, 6842, 7619, 7618, 828, 8411, + 771, 65065, 65066, 820, 816, 6859, 8424, 6836, 786, 846, 797, 7669, 7633, + 7634, 809, 781, 830, 7673, 8425, 6838, 6837, 851, 829, 8274, 64, 44, + 128476, 9092, 8705, 129517, 9732, 127882, 128533, 128534, 128119, 128679, + 8715, 8883, 8885, 8954, 8955, 8957, 8750, 127899, 983187, 9089, 127978, + 9010, 9740, 10861, 127859, 127850, 127834, 11505, 11504, 11503, 11464, + 11392, 11506, 11499, 11501, 11446, 11452, 11458, 11466, 11442, 11448, + 11450, 11398, 1006, 1002, 11396, 1000, 11406, 998, 11436, 11412, 11420, + 996, 11434, 11472, 11414, 11422, 11478, 11468, 11470, 11476, 11474, + 11482, 11460, 11480, 11454, 11462, 11444, 11486, 11488, 11484, 11490, + 11440, 1004, 994, 11456, 11402, 11428, 11408, 11430, 11404, 11394, 11438, + 11424, 11410, 11426, 11400, 11416, 11418, 11432, 66272, 66298, 66289, + 66295, 66286, 66294, 66285, 66299, 66290, 66291, 66297, 66288, 66296, + 66287, 66293, 66284, 66292, 66283, 66282, 66277, 66276, 66279, 66278, + 66275, 66274, 66281, 66273, 66280, 11517, 11518, 11514, 11515, 11516, + 11513, 11465, 11393, 11507, 11500, 11502, 11447, 11453, 11459, 11467, + 11443, 11449, 11451, 11399, 1007, 1003, 11397, 1001, 11407, 999, 11437, + 11413, 11421, 997, 11435, 11473, 11415, 11423, 11479, 11469, 11471, + 11477, 11475, 11483, 11461, 11481, 11455, 11463, 11445, 11487, 11489, + 11485, 11491, 11441, 1005, 995, 11457, 11403, 11429, 11409, 11431, 11405, + 11395, 11439, 11425, 11411, 11427, 11401, 11417, 11419, 11433, 11497, + 11492, 11493, 11494, 11498, 11495, 11496, 11519, 127279, 169, 11855, + 8792, 129720, 9012, 9013, 119661, 119660, 119663, 119662, 119659, 119658, + 119665, 119657, 119664, 119652, 119651, 119654, 119653, 119650, 119649, + 119656, 119648, 119655, 128715, 128145, 128004, 128046, 9904, 129689, + 129509, 983074, 128179, 127769, 129431, 127951, 9769, 9768, 11857, 11856, + 128322, 128321, 10060, 127370, 127884, 9876, 9932, 128010, 129360, + 128081, 8354, 129660, 128575, 128546, 128302, 129408, 8731, 74794, 74771, + 74861, 74780, 74820, 74821, 74765, 74758, 74853, 74856, 74855, 74854, + 74791, 74801, 74844, 74836, 74837, 74809, 74755, 74829, 74777, 74786, + 74768, 74858, 74762, 74834, 74835, 74808, 74812, 74814, 74815, 74813, + 74754, 74828, 74776, 74785, 74790, 74800, 74767, 74857, 74761, 74839, + 74838, 74822, 74825, 74823, 74824, 74795, 74772, 74862, 74781, 74766, + 74759, 74849, 74850, 74840, 74847, 74848, 74851, 74831, 74804, 74773, + 74782, 74845, 74842, 74796, 74852, 74818, 74819, 74817, 74793, 74770, + 74860, 74779, 74764, 74757, 74802, 74803, 74792, 74756, 74830, 74769, + 74859, 74778, 74816, 74763, 74806, 74807, 74833, 74788, 74789, 74798, + 74799, 74810, 74811, 74753, 74827, 74775, 74784, 74760, 74752, 74826, + 74832, 74805, 74841, 74774, 74783, 74787, 74797, 74846, 74843, 74867, + 74868, 74866, 74865, 74864, 73728, 73734, 73731, 73733, 73735, 73736, + 73730, 73732, 73729, 73738, 73742, 73741, 73744, 73745, 74881, 73747, + 73748, 73740, 73739, 74608, 74880, 73746, 73743, 73749, 73750, 73753, + 73752, 73754, 73755, 73751, 74609, 73756, 74882, 73757, 73759, 73758, + 73760, 73765, 73766, 73762, 73763, 73768, 73761, 73767, 73764, 73770, + 73769, 73771, 74610, 73772, 73773, 73776, 73777, 73775, 73774, 73778, + 73780, 73781, 73782, 73784, 73788, 73789, 73787, 73785, 73786, 73791, + 73790, 73783, 73779, 73737, 73792, 73793, 74883, 73795, 74884, 74885, + 74886, 73796, 73797, 73798, 73799, 73800, 73794, 73801, 73804, 73803, + 73802, 73805, 74887, 73806, 73807, 73808, 73809, 73810, 73811, 73812, + 73813, 73814, 73815, 73816, 73817, 73818, 73819, 73820, 73821, 73822, + 73823, 73825, 73826, 73829, 73830, 73831, 73828, 73836, 74611, 73837, + 73833, 73835, 73827, 73832, 73834, 73824, 74889, 74612, 73839, 73840, + 73841, 74888, 73838, 73842, 73844, 74891, 74890, 73845, 73846, 74892, + 73847, 73848, 73849, 74613, 73843, 73850, 73852, 73853, 73851, 73854, + 73855, 74614, 73856, 73857, 74894, 74895, 74893, 74896, 74897, 74900, + 74901, 74902, 74899, 74908, 74909, 74907, 74906, 74911, 74912, 74910, + 74913, 74914, 74915, 74916, 74920, 74919, 74898, 74905, 74903, 74904, + 74917, 74918, 73858, 73860, 73861, 73862, 73863, 73864, 73865, 73859, + 73866, 73868, 73867, 73869, 73873, 73874, 73870, 73871, 74922, 74921, + 73872, 73875, 73879, 73883, 73884, 73880, 73881, 73882, 73885, 73887, + 74923, 73886, 73888, 74924, 73889, 74927, 74930, 74931, 74925, 74928, + 74929, 74932, 74926, 73890, 73891, 73892, 73893, 73895, 73896, 73900, + 73901, 73902, 73903, 73904, 73905, 73906, 74616, 74933, 73907, 73908, + 73899, 73897, 73898, 74615, 73894, 73877, 73876, 73878, 73909, 73911, + 73912, 73914, 73913, 73916, 74617, 73917, 74618, 73918, 73915, 74934, + 73920, 73919, 73921, 73922, 73924, 73925, 74935, 74936, 74937, 73926, + 73923, 73929, 73930, 73927, 73928, 74938, 74939, 73932, 74941, 74940, + 73931, 73933, 73934, 73935, 73936, 73937, 74942, 73938, 73939, 73941, + 73940, 73943, 73942, 73945, 73944, 73946, 73947, 74943, 73948, 73949, + 74944, 74945, 74946, 73950, 74947, 73951, 74948, 74949, 74950, 73952, + 73953, 73957, 73958, 73959, 74951, 73955, 73956, 73960, 73962, 73963, + 73964, 73961, 74952, 73954, 73965, 73966, 74953, 73967, 73968, 73969, + 73970, 73971, 73972, 73974, 73975, 73978, 73977, 73976, 73910, 73979, + 73980, 73981, 73973, 73982, 73983, 74954, 74619, 73984, 73985, 73986, + 73987, 73988, 73990, 73989, 73994, 73995, 73998, 73996, 73997, 73999, + 73992, 73993, 74001, 74955, 74004, 74003, 74005, 74002, 74000, 73991, + 74620, 74006, 74008, 74009, 74010, 74956, 74012, 74011, 74013, 74014, + 74957, 74015, 74016, 74017, 74019, 74020, 74021, 74024, 74023, 74022, + 74007, 74018, 74025, 74026, 74958, 74027, 74028, 74029, 74030, 74959, + 74031, 74033, 74036, 74035, 74032, 74034, 74037, 74038, 74039, 74040, + 74043, 74044, 74042, 74041, 74045, 74046, 74621, 74047, 74050, 74052, + 74051, 74053, 74054, 74058, 74057, 74055, 74056, 74059, 74060, 74061, + 74062, 74064, 74065, 74063, 74066, 74067, 74048, 74070, 74049, 74068, + 74069, 74071, 74072, 74073, 74074, 74622, 74075, 74623, 74077, 74076, + 74078, 74079, 74960, 74080, 74081, 74082, 74085, 74086, 74084, 74083, + 74087, 74624, 74090, 74089, 74088, 74091, 74092, 74625, 74093, 74094, + 74096, 74097, 74961, 74095, 74099, 74627, 74098, 74100, 74101, 74103, + 74102, 74104, 74105, 74115, 74629, 74114, 74112, 74113, 74110, 74111, + 74117, 74116, 74118, 74630, 74119, 74962, 74963, 74631, 74122, 74123, + 74120, 74121, 74626, 74107, 74106, 74628, 74108, 74109, 74124, 74125, + 74126, 74131, 74132, 74128, 74129, 74130, 74133, 74134, 74135, 74136, + 74137, 74138, 74139, 74140, 74141, 74142, 74607, 74127, 74144, 74146, + 74147, 74145, 74152, 74153, 74150, 74151, 74148, 74149, 74154, 74155, + 74157, 74158, 74163, 74164, 74165, 74160, 74161, 74156, 74159, 74162, + 74143, 74166, 74167, 74168, 74169, 74170, 74171, 74172, 74175, 74173, + 74174, 74176, 74177, 74182, 74183, 74180, 74181, 74632, 74186, 74184, + 74185, 74188, 74190, 74189, 74187, 74194, 74195, 74193, 74191, 74192, + 74196, 74197, 74198, 74199, 74200, 74201, 74202, 74205, 74206, 74207, + 74208, 74204, 74209, 74211, 74210, 74212, 74213, 74215, 74214, 74216, + 74218, 74217, 74964, 74178, 74179, 74203, 74219, 74220, 74223, 74224, + 74221, 74222, 74966, 74967, 74974, 74973, 74972, 74969, 74970, 74971, + 74975, 74968, 74965, 74977, 74976, 74980, 74981, 74982, 74984, 74985, + 74978, 74979, 74983, 74986, 74987, 74988, 74989, 74990, 74991, 74993, + 74997, 74996, 74998, 74995, 74994, 74992, 74999, 75000, 75003, 75004, + 75005, 75006, 75001, 75002, 75009, 75015, 75016, 75019, 75017, 75018, + 75013, 75012, 75010, 75011, 75014, 75021, 75030, 75029, 75027, 75024, + 75025, 75028, 75022, 75026, 75023, 75008, 75020, 75031, 75032, 75007, + 74226, 74227, 74228, 74229, 74230, 74225, 74231, 74233, 74234, 74232, + 74235, 74237, 74258, 74259, 75033, 74261, 74633, 74260, 74240, 74634, + 74241, 74243, 75035, 74246, 74247, 74245, 74248, 74249, 74250, 74251, + 75036, 75037, 74254, 74255, 74635, 74256, 75038, 74242, 74252, 74253, + 75034, 74238, 74239, 74244, 74257, 74263, 74265, 74264, 74266, 74269, + 74270, 74271, 74236, 74262, 74267, 74268, 74272, 74273, 74274, 74278, + 74279, 74275, 74276, 74277, 74280, 74281, 74636, 74282, 75039, 74283, + 74284, 74290, 74294, 74295, 75041, 75040, 74292, 74293, 74291, 74296, + 74297, 74298, 74299, 74300, 74637, 74301, 74286, 74287, 74285, 74289, + 74288, 74302, 74304, 74307, 74305, 74306, 74308, 74310, 74309, 74311, + 74303, 74638, 74312, 74314, 74313, 74315, 74316, 74319, 74321, 74320, + 74639, 74322, 74324, 74325, 74323, 74642, 75043, 74326, 75044, 75046, + 75047, 74327, 75048, 74329, 74328, 75049, 74330, 74332, 74333, 74331, + 75050, 75051, 74334, 75052, 74335, 75042, 74641, 75045, 74640, 74317, + 74336, 74318, 74337, 74338, 983266, 983265, 74643, 74339, 74347, 74348, + 74342, 74343, 74341, 74344, 74340, 74346, 74345, 74349, 74355, 74354, + 74350, 74352, 74358, 74359, 74353, 74357, 74351, 74356, 74360, 74361, + 74362, 74363, 74364, 74365, 74366, 74644, 74367, 74375, 74376, 74368, + 74369, 74373, 74374, 74370, 74371, 74372, 74377, 74378, 74379, 74380, + 74381, 74382, 74645, 74383, 74384, 74385, 74386, 74387, 74389, 74408, + 75053, 74388, 74646, 74395, 74394, 75055, 74400, 74399, 75056, 74401, + 74406, 74402, 74403, 74404, 74405, 74391, 74392, 74396, 74398, 75054, + 74397, 74393, 74390, 74407, 74409, 74410, 74411, 74412, 74413, 74414, + 74421, 74422, 74419, 74417, 74420, 74416, 74418, 74415, 74423, 75057, + 74424, 74425, 74426, 75058, 74428, 74429, 75059, 75060, 75061, 74427, + 74432, 74434, 74433, 74430, 74431, 74435, 74437, 74436, 74438, 74441, + 74440, 74444, 74445, 74446, 74448, 74447, 74443, 74449, 74442, 74439, + 74451, 74453, 74452, 74450, 74454, 74455, 74456, 74457, 75063, 75062, + 74458, 74459, 75064, 74460, 74461, 74462, 74463, 74465, 74464, 74466, + 74468, 74469, 74471, 74472, 74473, 74474, 74467, 74470, 74475, 74477, + 74478, 74479, 74476, 74480, 74481, 74482, 74483, 74488, 74486, 74487, + 74485, 74489, 74484, 74490, 75065, 74491, 74494, 74497, 74499, 74500, + 74498, 74495, 74647, 74496, 74501, 74504, 75066, 75067, 74505, 74506, + 74502, 74503, 74492, 74493, 74507, 74510, 74512, 74511, 74649, 74509, + 74508, 74515, 74516, 74522, 74523, 74519, 74520, 74517, 74518, 74521, + 74524, 74534, 74535, 74525, 74526, 74648, 74527, 74528, 74529, 74531, + 74532, 74533, 74530, 74536, 74538, 74537, 74539, 75068, 74540, 74541, + 74542, 74545, 74546, 74547, 75069, 74544, 74543, 74549, 74550, 74551, + 74552, 74553, 75070, 74555, 74556, 74558, 74557, 74559, 74560, 74562, + 74564, 74563, 75072, 74566, 75071, 74570, 74569, 74572, 74574, 74573, + 74554, 74567, 74571, 74565, 74561, 74568, 74575, 74576, 74548, 74577, + 74581, 74579, 74580, 74578, 74584, 74583, 74582, 74586, 74587, 74588, + 74585, 74513, 74514, 74589, 74591, 74590, 74593, 75073, 74592, 74595, + 74598, 74599, 74596, 74601, 74597, 74600, 74602, 75074, 74603, 75075, + 74604, 74605, 74606, 74594, 9982, 129380, 11232, 129473, 8911, 8910, + 10160, 9130, 129356, 128177, 164, 127835, 10081, 127854, 128707, 129362, + 129385, 67594, 67595, 67596, 67597, 67598, 67599, 67600, 67601, 67602, + 67603, 67604, 67605, 67606, 67607, 67608, 67609, 67610, 67611, 67612, + 67613, 67614, 67615, 67616, 67617, 67618, 67619, 67620, 67621, 67622, + 67623, 67624, 67625, 67626, 67627, 67628, 67629, 67630, 67631, 67632, + 67633, 67634, 67635, 67636, 67637, 67589, 67592, 67644, 67647, 67639, + 67640, 67584, 67585, 67586, 67587, 67588, 77712, 77713, 77714, 77715, + 77716, 77717, 77718, 77719, 77722, 77723, 77720, 77721, 77724, 77725, + 77726, 77727, 77728, 77729, 77730, 77731, 77732, 77733, 77734, 77735, + 77736, 77737, 77738, 77739, 77740, 77741, 77742, 77743, 77744, 77745, + 77746, 77747, 77748, 77749, 77750, 77751, 77752, 77753, 77754, 77755, + 77756, 77757, 77758, 77773, 77774, 77768, 77769, 77770, 77771, 77772, + 77775, 77776, 77777, 77788, 77789, 77790, 77791, 77792, 77793, 77794, + 77795, 77796, 77759, 77760, 77761, 77762, 77763, 77764, 77765, 77766, + 77767, 77778, 77779, 77780, 77781, 77782, 77783, 77784, 77785, 77786, + 77787, 77797, 77798, 77799, 77800, 77801, 77802, 77803, 77804, 77805, + 77806, 77807, 77808, 77809, 77810, 1126, 1033, 1300, 42574, 1034, 1055, + 1190, 1316, 1136, 1146, 42564, 42592, 42580, 1296, 1302, 1058, 42634, + 1196, 1035, 42640, 42638, 1062, 42642, 42636, 1059, 1266, 1264, 1262, + 1144, 1028, 1040, 1234, 1232, 1212, 1214, 1248, 1192, 1310, 1256, 1258, + 1184, 42602, 1130, 42572, 42586, 1030, 1041, 1063, 1268, 1206, 1208, + 42584, 42650, 42630, 1026, 42568, 42604, 42648, 1029, 42562, 1322, 42632, + 1039, 42626, 1324, 42624, 1044, 1069, 1051, 1312, 1326, 1221, 1298, 1053, + 1314, 1186, 1320, 1225, 1223, 1056, 1166, 1260, 1057, 1194, 1052, 1229, + 1060, 1043, 1172, 1168, 1270, 1170, 1274, 1027, 1061, 1202, 1276, 1278, + 1066, 42644, 1048, 1252, 1037, 1250, 1045, 1024, 1238, 1025, 42588, 1128, + 1132, 42578, 42582, 1124, 42566, 1140, 1142, 1050, 1178, 1219, 1180, + 1182, 1286, 1282, 1280, 1288, 1290, 1292, 1294, 1284, 1152, 1227, 1036, + 1134, 42600, 42570, 1054, 1120, 1148, 1254, 1150, 1240, 1242, 1049, 1162, + 1038, 1210, 1318, 1065, 42646, 1064, 42596, 42598, 1068, 42594, 1198, + 1200, 1164, 1071, 1304, 1122, 1067, 1272, 42576, 1031, 42590, 1070, 1047, + 1246, 1176, 42560, 1046, 1244, 1174, 1217, 42628, 1138, 1032, 1042, 1308, + 1306, 1236, 1204, 1188, 42622, 42606, 1216, 7467, 42623, 1072, 1235, + 1233, 1213, 1215, 1249, 1193, 1311, 1257, 1259, 1185, 42603, 1131, 42573, + 42587, 1110, 1073, 1095, 1269, 1207, 1209, 42585, 42651, 42631, 1106, + 42569, 42605, 42649, 1109, 42563, 1323, 42633, 1119, 42627, 1325, 42625, + 1076, 1101, 1083, 1313, 1327, 1222, 1299, 1085, 1315, 1187, 1321, 1226, + 1224, 1088, 1167, 1261, 1089, 1195, 1084, 1230, 1092, 1075, 1173, 1169, + 1271, 1171, 1275, 1107, 1093, 1203, 1277, 1279, 1098, 42645, 1080, 1253, + 1117, 1251, 1077, 1104, 1239, 1105, 42589, 1129, 1133, 42579, 42583, + 1125, 42567, 1141, 1143, 1082, 1179, 1220, 1181, 1183, 1287, 1283, 1281, + 1289, 1291, 1293, 1295, 1285, 1153, 1228, 1116, 1135, 1127, 7297, 1113, + 1301, 42601, 42571, 42575, 7298, 1114, 1086, 1121, 1149, 1255, 1151, + 1087, 1191, 1317, 1231, 1137, 42565, 42593, 42581, 1297, 1147, 7296, + 1303, 1241, 1243, 1081, 1163, 1118, 1211, 1319, 1097, 42647, 1096, 42597, + 42599, 1100, 42595, 1199, 1201, 1165, 7302, 7303, 7300, 1090, 42635, + 1197, 1115, 42641, 42639, 1094, 7301, 42643, 42637, 1091, 1267, 1265, + 1263, 1145, 1108, 7304, 7299, 1309, 1103, 1305, 1123, 1099, 1273, 42577, + 1111, 42591, 1102, 1079, 1247, 1177, 42561, 1078, 1245, 1175, 1218, + 42629, 1139, 1112, 1074, 1307, 1237, 1205, 1189, 122984, 122962, 122986, + 122985, 122965, 122976, 122971, 122974, 122964, 122983, 122977, 122981, + 122982, 122980, 122978, 122967, 122968, 122969, 122966, 122979, 122973, + 122963, 122970, 122961, 122972, 122975, 1154, 9005, 127744, 983201, + 983188, 983172, 8224, 11830, 11831, 128481, 128131, 127841, 128374, 9619, + 11843, 128168, 10143, 65101, 65097, 8504, 983081, 983084, 983086, 983088, + 983090, 983162, 127795, 9110, 9192, 128475, 8451, 176, 8457, 983120, + 128666, 8796, 983119, 9161, 9159, 9153, 9156, 9162, 9160, 9154, 9157, + 9163, 9150, 9158, 9164, 9151, 9152, 9155, 127980, 9739, 66589, 66591, + 66596, 66597, 66587, 66585, 66594, 66595, 66593, 66599, 66562, 66563, + 66564, 66565, 66561, 66560, 66568, 66569, 66570, 66571, 66567, 66566, + 66598, 66573, 66588, 66579, 66592, 66590, 66581, 66578, 66580, 66582, + 66577, 66586, 66575, 66584, 66583, 66574, 66572, 66576, 66629, 66631, + 66636, 66637, 66627, 66625, 66634, 66635, 66633, 66639, 66602, 66603, + 66604, 66605, 66601, 66600, 66608, 66609, 66610, 66611, 66607, 66606, + 66638, 66613, 66628, 66619, 66632, 66630, 66621, 66618, 66620, 66622, + 66617, 66626, 66615, 66624, 66623, 66614, 66612, 66616, 127964, 127965, + 128421, 128468, 2388, 2416, 43258, 2387, 43257, 72448, 72449, 43259, + 2309, 2310, 2320, 2324, 2421, 43262, 2330, 2418, 2317, 2321, 2331, 2396, + 2430, 2338, 2337, 2343, 2342, 2429, 2394, 2328, 2427, 2327, 2426, 2361, + 2350, 2424, 2308, 2318, 2322, 2358, 2359, 2360, 2323, 2420, 2419, 2431, + 2349, 2348, 2333, 2428, 2332, 2393, 2326, 2325, 2397, 2353, 2352, 2399, + 2351, 2313, 2314, 2423, 2422, 2345, 2339, 2329, 2334, 2344, 2356, 2355, + 2354, 2336, 2335, 2341, 2340, 2315, 2400, 2316, 2401, 2357, 2311, 2312, + 2347, 2346, 2425, 2395, 2398, 2392, 2319, 983644, 983643, 983646, 983647, + 983649, 983648, 983642, 983645, 72450, 72451, 72452, 72453, 2305, 43255, + 43251, 43254, 43253, 72455, 72454, 72456, 43256, 43250, 43260, 43252, + 2304, 2365, 2306, 72457, 2364, 2417, 2381, 2307, 2386, 2385, 2366, 2376, + 2380, 2383, 43263, 2389, 2373, 2377, 2379, 2363, 2362, 2382, 2369, 2370, + 2391, 2390, 2374, 2378, 2371, 2372, 2402, 2403, 2367, 2368, 2375, 2405, + 2404, 2411, 2410, 2413, 2412, 2409, 2408, 2406, 2415, 2407, 2414, 43261, + 2384, 983089, 983161, 983087, 983085, 983083, 127962, 129487, 129420, + 11033, 11032, 11030, 11031, 128924, 128160, 8900, 8960, 168, 9856, 9857, + 9858, 9859, 9860, 9861, 128754, 53, 127238, 9356, 52, 127237, 9355, 57, + 127242, 9360, 49, 127234, 9352, 55, 127240, 9358, 54, 127239, 9357, 51, + 127236, 9354, 50, 127235, 9353, 48, 127233, 127232, 56, 127241, 9359, + 119557, 119556, 119555, 9868, 9871, 9870, 9869, 119553, 119554, 10131, + 10126, 10125, 10128, 10127, 10124, 10123, 127244, 10130, 10122, 10129, + 10111, 10106, 10105, 10108, 10107, 10104, 10103, 10110, 10102, 10109, + 10121, 10116, 10115, 10118, 10117, 10114, 10113, 127243, 10120, 10112, + 10119, 9107, 127919, 128549, 128542, 9933, 9090, 129400, 72004, 72021, + 72020, 72023, 72022, 72019, 72018, 72016, 72025, 72017, 72024, 71964, + 71958, 71963, 71974, 71973, 71936, 71937, 71961, 71960, 71966, 71965, + 71940, 71941, 71938, 71939, 71982, 71976, 71952, 71962, 71957, 71967, + 71978, 71979, 71980, 71971, 71970, 71954, 71953, 71951, 71950, 71949, + 71948, 71969, 71968, 71981, 71955, 71972, 71975, 71977, 71983, 71942, + 71945, 71997, 71996, 72003, 71995, 71984, 71991, 71987, 71988, 71985, + 71986, 71989, 71992, 71998, 72002, 72000, 72005, 72006, 71999, 72001, + 8725, 247, 8903, 129343, 8739, 9902, 129684, 128171, 128565, 12291, 8783, + 9009, 128462, 128441, 128442, 128443, 8939, 8941, 8716, 8740, 10990, + 8832, 8928, 8876, 8833, 8929, 8878, 128021, 71723, 71716, 71680, 71681, + 71687, 71689, 71703, 71702, 71708, 71707, 71701, 71700, 71706, 71705, + 71684, 71685, 71682, 71683, 71694, 71704, 71699, 71709, 71719, 71720, + 71721, 71713, 71712, 71696, 71695, 71693, 71692, 71698, 71697, 71691, + 71690, 71711, 71710, 71722, 71717, 71714, 71718, 71715, 71686, 71688, + 71729, 71730, 71724, 71732, 71734, 71727, 71728, 71725, 71726, 71731, + 71733, 71739, 71738, 71735, 71737, 71736, 128054, 128044, 36, 127025, + 127026, 127027, 127028, 127029, 127030, 127031, 127032, 127033, 127034, + 127035, 127036, 127037, 127038, 127039, 127040, 127041, 127042, 127043, + 127044, 127045, 127046, 127047, 127048, 127049, 127050, 127051, 127052, + 127053, 127054, 127055, 127056, 127057, 127058, 127059, 127060, 127061, + 127062, 127063, 127064, 127065, 127066, 127067, 127068, 127069, 127070, + 127071, 127072, 127073, 127024, 127075, 127076, 127077, 127078, 127079, + 127080, 127081, 127082, 127083, 127084, 127085, 127086, 127087, 127088, + 127089, 127090, 127091, 127092, 127093, 127094, 127095, 127096, 127097, + 127098, 127099, 127100, 127101, 127102, 127103, 127104, 127105, 127106, + 127107, 127108, 127109, 127110, 127111, 127112, 127113, 127114, 127115, + 127116, 127117, 127118, 127119, 127120, 127121, 127122, 127123, 127074, + 129743, 8363, 8724, 8760, 8901, 729, 9676, 8284, 11850, 11034, 129765, + 11795, 11784, 10649, 11798, 9470, 9465, 9464, 9467, 9466, 9463, 9462, + 9469, 9461, 9468, 10175, 10868, 10986, 8225, 8223, 11840, 8914, 8748, + 11842, 8222, 8215, 10835, 10836, 10645, 10913, 10915, 10914, 10939, 8243, + 12318, 10746, 10830, 10831, 11849, 10988, 11844, 10940, 8913, 8912, + 11005, 10987, 8915, 9208, 10981, 8875, 10979, 8214, 11799, 10646, 733, + 8252, 8263, 65100, 10908, 10907, 11002, 11001, 10906, 10905, 8510, 8473, + 8511, 8450, 8461, 8469, 8474, 8477, 8484, 8518, 8519, 8520, 8521, 8517, + 8509, 8508, 8512, 10719, 9890, 9891, 11260, 127849, 8868, 10993, 10623, + 8945, 8964, 128315, 128317, 10728, 10729, 129288, 129290, 129289, 129291, + 8595, 8629, 8671, 129035, 129031, 129179, 129043, 129027, 129047, 8626, + 8627, 10504, 8693, 129975, 8615, 10515, 11796, 11107, 11139, 11123, + 129067, 11168, 11169, 129063, 129059, 129075, 129071, 11133, 11085, + 11117, 11143, 129171, 10507, 8609, 11247, 8681, 129175, 8623, 11147, + 11015, 8659, 8675, 129079, 10597, 10607, 10593, 10585, 8643, 10589, + 10581, 8642, 129091, 129095, 129087, 10225, 128623, 129107, 129083, 8650, + 128687, 128330, 128682, 129444, 8367, 10139, 128009, 128050, 128042, + 129656, 128167, 129316, 129345, 9946, 128087, 113784, 113788, 113785, + 113783, 113782, 113786, 113787, 113795, 113798, 113793, 113800, 113781, + 113794, 113792, 113799, 113797, 113796, 113776, 113808, 113817, 113811, + 113814, 113809, 113816, 113779, 113810, 113815, 113813, 113812, 113778, + 113777, 113780, 113729, 113733, 113672, 113677, 113683, 113735, 113739, + 113746, 113668, 113678, 113674, 113726, 113691, 113699, 113700, 113695, + 113709, 113712, 113713, 113705, 113711, 113669, 113725, 113679, 113684, + 113670, 113743, 113749, 113687, 113689, 113693, 113707, 113697, 113703, + 113690, 113694, 113708, 113698, 113704, 113764, 113763, 113762, 113761, + 113732, 113753, 113731, 113755, 113754, 113666, 113766, 113765, 113676, + 113675, 113741, 113750, 113680, 113688, 113692, 113696, 113710, 113727, + 113728, 113716, 113717, 113714, 113715, 113701, 113702, 113724, 113723, + 113706, 113742, 113740, 113767, 113769, 113730, 113768, 113682, 113685, + 113752, 113737, 113667, 113719, 113718, 113681, 113745, 113748, 113751, + 113738, 113673, 113770, 113720, 113757, 113760, 113722, 113759, 113756, + 113721, 113758, 113665, 113747, 113664, 113686, 113734, 113736, 113744, + 113671, 113821, 113822, 113823, 113820, 129375, 129414, 129516, 128192, + 983082, 128066, 127805, 127806, 129467, 9793, 127758, 127759, 127757, + 9178, 9841, 129413, 11790, 77830, 77831, 77832, 77828, 77829, 77824, + 77825, 77826, 77827, 77833, 77834, 77835, 77840, 77841, 77844, 77845, + 77836, 77837, 77838, 77839, 77842, 77843, 77846, 77847, 77869, 77870, + 77872, 77873, 77874, 77875, 77877, 77878, 77871, 77876, 77879, 77880, + 77881, 77882, 77860, 77861, 77858, 77859, 77862, 77863, 77864, 77865, + 77866, 77867, 77868, 77903, 77848, 77849, 77850, 77851, 77852, 77853, + 77854, 77855, 77856, 77857, 77883, 77884, 77885, 77886, 77887, 77888, + 77889, 77890, 77891, 77892, 77893, 77894, 77895, 77896, 77897, 77898, + 77899, 77900, 77901, 77902, 78867, 78868, 78869, 78861, 78862, 78863, + 78864, 78865, 78866, 78870, 78871, 78892, 78893, 78894, 78872, 78873, + 78874, 78875, 78876, 78877, 78878, 78879, 78880, 78881, 78882, 78883, + 78884, 78885, 78886, 78887, 78888, 78889, 78890, 78891, 78903, 78910, + 78908, 77908, 77909, 77904, 77905, 77906, 77907, 77910, 77911, 77912, + 77913, 77915, 77916, 77917, 77918, 77914, 77919, 77920, 77921, 77922, + 77923, 77924, 77925, 77926, 77927, 77928, 77929, 77930, 77931, 77932, + 77933, 77934, 77935, 77936, 77937, 77938, 77939, 77940, 77941, 77949, + 77950, 77942, 77943, 77944, 77945, 77946, 77947, 77948, 77951, 77974, + 77975, 77978, 77979, 77973, 77976, 77977, 77980, 77981, 77982, 77983, + 77984, 77991, 77992, 77994, 77995, 77985, 77986, 77987, 77988, 77989, + 77990, 77993, 77996, 77997, 77998, 77999, 78000, 78001, 78002, 78003, + 78004, 78005, 78006, 78008, 78009, 78011, 78012, 78007, 78010, 78013, + 78014, 78015, 78016, 78017, 78025, 78026, 78027, 78028, 78029, 78030, + 78031, 78032, 78033, 78018, 78019, 78020, 78021, 78022, 78023, 78024, + 77969, 77970, 77962, 77963, 77964, 77965, 77966, 77967, 77968, 77971, + 77972, 77952, 77953, 77954, 77955, 77956, 77957, 77958, 77959, 77960, + 77961, 78041, 78042, 78043, 78044, 78034, 78035, 78036, 78037, 78038, + 78039, 78040, 78057, 78058, 78066, 78067, 78059, 78060, 78061, 78062, + 78063, 78064, 78065, 78068, 78073, 78074, 78069, 78070, 78071, 78072, + 78075, 78076, 78077, 78051, 78052, 78053, 78054, 78045, 78046, 78047, + 78048, 78049, 78050, 78055, 78056, 78904, 78911, 78909, 78078, 78079, + 78080, 78081, 78082, 78083, 78084, 78085, 78086, 78087, 78091, 78092, + 78088, 78089, 78090, 78093, 78094, 78095, 78096, 78097, 78098, 78111, + 78112, 78118, 78119, 78120, 78121, 78110, 78113, 78114, 78115, 78116, + 78117, 78122, 78128, 78129, 78130, 78131, 78132, 78133, 78123, 78124, + 78125, 78126, 78127, 78134, 78135, 78137, 78138, 78139, 78140, 78136, + 78141, 78142, 78100, 78101, 78099, 78102, 78103, 78104, 78105, 78106, + 78107, 78108, 78109, 78913, 78150, 78151, 78152, 78148, 78149, 78143, + 78144, 78145, 78146, 78147, 78153, 78154, 78156, 78157, 78155, 78158, + 78159, 78160, 78161, 78162, 78163, 78164, 78165, 78184, 78185, 78186, + 78187, 78178, 78179, 78180, 78181, 78182, 78183, 78188, 78189, 78193, + 78194, 78196, 78197, 78190, 78191, 78192, 78195, 78198, 78199, 78200, + 78201, 78166, 78167, 78173, 78174, 78168, 78169, 78170, 78171, 78172, + 78175, 78176, 78177, 78202, 78203, 78204, 78205, 78206, 78212, 78213, + 78207, 78208, 78209, 78210, 78211, 78214, 78215, 78914, 78916, 78897, + 78220, 78221, 78225, 78226, 78216, 78217, 78218, 78219, 78222, 78223, + 78224, 78227, 78228, 78229, 78230, 78231, 78232, 78233, 78234, 78907, + 78901, 78899, 78906, 78900, 78898, 78905, 78244, 78245, 78249, 78250, + 78243, 78246, 78247, 78248, 78251, 78252, 78915, 78253, 78254, 78255, + 78257, 78258, 78256, 78259, 78260, 78261, 78262, 78263, 78264, 78268, + 78269, 78270, 78271, 78272, 78273, 78274, 78275, 78276, 78265, 78266, + 78279, 78280, 78281, 78282, 78283, 78284, 78267, 78277, 78278, 78285, + 78286, 78289, 78290, 78292, 78293, 78297, 78298, 78287, 78288, 78291, + 78294, 78295, 78296, 78299, 78304, 78305, 78306, 78301, 78302, 78300, + 78303, 78307, 78308, 78309, 78310, 78311, 78312, 78313, 78314, 78315, + 78316, 78317, 78318, 78933, 78928, 78920, 78924, 78932, 78926, 78921, + 78929, 78925, 78923, 78931, 78919, 78927, 78922, 78930, 78912, 78336, + 78337, 78338, 78328, 78329, 78330, 78331, 78332, 78333, 78334, 78335, + 78339, 78354, 78355, 78356, 78357, 78358, 78359, 78361, 78362, 78351, + 78352, 78353, 78360, 78363, 78364, 78345, 78346, 78340, 78341, 78342, + 78343, 78344, 78347, 78348, 78349, 78350, 78365, 78366, 78367, 78319, + 78320, 78321, 78322, 78323, 78324, 78325, 78326, 78327, 78372, 78373, + 78368, 78369, 78370, 78371, 78374, 78375, 78376, 78377, 78385, 78386, + 78378, 78379, 78380, 78381, 78382, 78383, 78384, 78387, 78388, 78389, + 78399, 78400, 78401, 78402, 78409, 78410, 78403, 78404, 78405, 78406, + 78407, 78408, 78411, 78414, 78415, 78412, 78413, 78390, 78391, 78392, + 78393, 78394, 78395, 78396, 78397, 78398, 78423, 78424, 78425, 78426, + 78427, 78428, 78429, 78416, 78417, 78421, 78422, 78418, 78419, 78420, + 78430, 78431, 78432, 78433, 78434, 78435, 78436, 78445, 78446, 78437, + 78438, 78439, 78440, 78441, 78442, 78443, 78444, 78447, 78448, 78452, + 78453, 78454, 78455, 78459, 78460, 78449, 78450, 78451, 78456, 78457, + 78458, 78469, 78470, 78471, 78472, 78473, 78461, 78462, 78465, 78466, + 78463, 78464, 78467, 78468, 78474, 78475, 78476, 78487, 78488, 78489, + 78490, 78477, 78478, 78479, 78480, 78481, 78482, 78483, 78484, 78485, + 78486, 78902, 78491, 78492, 78494, 78495, 78493, 78496, 78497, 78498, + 78499, 78500, 78501, 78502, 78503, 78514, 78515, 78516, 78512, 78513, + 78511, 78517, 78518, 78519, 78520, 78521, 78522, 78523, 78524, 78530, + 78531, 78525, 78526, 78527, 78528, 78529, 78532, 78533, 78534, 78535, + 78536, 78537, 78538, 78539, 78540, 78541, 78542, 78543, 78544, 78546, + 78547, 78551, 78552, 78545, 78548, 78549, 78550, 78553, 78554, 78555, + 78560, 78561, 78562, 78565, 78566, 78556, 78557, 78558, 78559, 78563, + 78564, 78567, 78568, 78575, 78576, 78577, 78569, 78570, 78571, 78572, + 78573, 78574, 78578, 78579, 78580, 78586, 78587, 78581, 78582, 78583, + 78584, 78585, 78588, 78589, 78590, 78591, 78592, 78593, 78594, 78595, + 78596, 78597, 78598, 78601, 78602, 78606, 78607, 78608, 78609, 78610, + 78611, 78599, 78600, 78603, 78604, 78605, 78613, 78614, 78619, 78620, + 78612, 78615, 78616, 78617, 78618, 78621, 78622, 78623, 78636, 78637, + 78638, 78639, 78634, 78635, 78640, 78641, 78642, 78624, 78625, 78626, + 78627, 78628, 78629, 78630, 78631, 78632, 78633, 78917, 78648, 78649, + 78650, 78643, 78644, 78645, 78646, 78647, 78651, 78652, 78653, 78667, + 78668, 78674, 78675, 78664, 78665, 78666, 78669, 78670, 78671, 78672, + 78673, 78678, 78679, 78676, 78677, 78680, 78681, 78682, 78683, 78684, + 78685, 78686, 78687, 78688, 78689, 78654, 78655, 78656, 78657, 78658, + 78659, 78660, 78661, 78662, 78663, 78706, 78707, 78708, 78690, 78691, + 78692, 78693, 78694, 78695, 78696, 78697, 78698, 78699, 78700, 78701, + 78702, 78703, 78704, 78705, 78709, 78710, 78712, 78713, 78714, 78715, + 78895, 78716, 78717, 78718, 78711, 78719, 78720, 78721, 78722, 78723, + 78724, 78725, 78726, 78727, 78728, 78729, 78730, 78731, 78732, 78733, + 78734, 78735, 78736, 78737, 78738, 78741, 78742, 78747, 78748, 78749, + 78750, 78739, 78740, 78743, 78744, 78745, 78746, 78751, 78752, 78753, + 78754, 78756, 78757, 78761, 78762, 78755, 78758, 78759, 78760, 78763, + 78764, 78765, 78766, 78896, 78769, 78770, 78776, 78777, 78767, 78768, + 78771, 78772, 78773, 78774, 78775, 78778, 78779, 78783, 78784, 78787, + 78788, 78789, 78790, 78780, 78781, 78782, 78785, 78786, 78791, 78796, + 78797, 78792, 78793, 78794, 78795, 78798, 78918, 78802, 78803, 78804, + 78806, 78807, 78809, 78810, 78799, 78800, 78801, 78805, 78808, 78811, + 78812, 78813, 78814, 78815, 78816, 78817, 78818, 78819, 78821, 78822, + 78823, 78824, 78825, 78826, 78827, 78828, 78829, 78830, 78831, 78832, + 78820, 78833, 78834, 78835, 78836, 78842, 78843, 78844, 78845, 78846, + 78847, 78848, 78849, 78850, 78851, 78852, 78853, 78854, 78855, 78856, + 78857, 78858, 78859, 78860, 78837, 78838, 78839, 78840, 78841, 78235, + 78236, 78237, 78238, 78239, 78240, 78241, 78242, 78504, 78505, 78506, + 78507, 78508, 78509, 78510, 129370, 10037, 10039, 10036, 10049, 10058, + 10035, 9834, 66854, 66853, 66827, 66826, 66833, 66832, 66821, 66837, + 66836, 66835, 66842, 66841, 66824, 66823, 66819, 66818, 66822, 66820, + 66855, 66831, 66844, 66843, 66846, 66845, 66852, 66851, 66817, 66825, + 66828, 66830, 66834, 66839, 66840, 66848, 66849, 66816, 66829, 66838, + 66847, 66850, 128268, 128294, 128161, 8961, 9191, 8712, 8946, 8953, 8947, + 8952, 8950, 8949, 10969, 10194, 128024, 128727, 69608, 69621, 69603, + 69611, 69618, 69619, 69600, 69615, 69602, 69606, 69614, 69617, 69620, + 69609, 69604, 69607, 69610, 69601, 69613, 69605, 69616, 69612, 69622, + 129501, 983101, 129456, 129457, 129459, 129458, 127995, 127996, 127997, + 127998, 127999, 128453, 128454, 128455, 129721, 128460, 128461, 8709, + 10675, 10676, 10674, 10673, 128459, 9091, 8193, 8212, 8195, 8192, 8211, + 8194, 983179, 8718, 983178, 983135, 983099, 983048, 983095, 983046, + 983064, 128282, 983051, 983050, 9993, 128388, 128233, 9094, 983067, + 983100, 983049, 8926, 8927, 8925, 8924, 8797, 8917, 61, 10865, 10867, + 11072, 10609, 10723, 10724, 10926, 11257, 10871, 10854, 10862, 8789, + 10872, 8781, 8794, 10738, 10736, 10734, 10739, 10737, 10735, 11249, + 11248, 9003, 8998, 983105, 983104, 8494, 8793, 983136, 4957, 4959, 4958, + 4963, 4965, 4978, 4988, 4980, 4979, 4987, 4985, 4982, 4981, 4986, 4984, + 4983, 4968, 4966, 4964, 4960, 4999, 4998, 4711, 4997, 43816, 43819, + 43821, 43820, 43818, 43822, 43817, 4704, 4707, 4710, 11653, 4709, 4708, + 4706, 4705, 43808, 43811, 43813, 43812, 43810, 43814, 43809, 11704, + 11707, 11709, 11708, 11706, 11710, 11705, 11688, 11691, 11693, 11692, + 11690, 11694, 11689, 4904, 4907, 4910, 11664, 4909, 4908, 4911, 4906, + 4905, 4728, 4731, 4734, 11655, 4733, 4732, 4735, 4730, 4729, 43789, + 43788, 43787, 43786, 43790, 43785, 4856, 4859, 4862, 11661, 4861, 4860, + 4863, 4858, 4857, 43797, 43796, 43795, 43794, 43798, 43793, 4848, 4851, + 4854, 11660, 4853, 4852, 4855, 4850, 4849, 5003, 5002, 4943, 5001, 4936, + 4939, 4941, 4940, 4954, 4938, 4942, 4937, 4873, 124916, 124915, 124924, + 124923, 124910, 124909, 124926, 124925, 124922, 124921, 124920, 124919, + 124918, 124917, 124914, 124913, 124912, 124904, 11667, 4895, 11670, + 11669, 11668, 4888, 4891, 4893, 4892, 4890, 4894, 4889, 4768, 4771, 4774, + 11658, 4773, 4772, 4775, 4770, 4769, 4880, 4883, 4885, 4884, 4882, 11736, + 11739, 11741, 11740, 11738, 11742, 11737, 4872, 4875, 4878, 4879, 4877, + 4876, 4874, 124907, 124906, 4631, 124905, 124896, 124899, 124901, 124900, + 124898, 124902, 124897, 4624, 4627, 4629, 4628, 4626, 4630, 4625, 4608, + 4611, 4614, 4615, 4613, 4612, 4610, 4609, 4800, 4803, 4805, 4804, 4802, + 4792, 4795, 4797, 4796, 4794, 4798, 4793, 4784, 4787, 4789, 4788, 4786, + 11720, 11723, 11725, 11724, 11722, 11726, 11721, 4776, 4779, 4782, 4783, + 4781, 4780, 4778, 4777, 4995, 4994, 4639, 4993, 4632, 4635, 4638, 11649, + 4637, 4636, 4953, 4634, 4633, 4760, 4763, 4766, 11657, 4765, 4764, 4767, + 4762, 4761, 4752, 4755, 4758, 11656, 4757, 4756, 4759, 4754, 4753, 4912, + 4816, 4819, 4821, 4820, 4818, 4822, 4817, 4915, 4918, 11665, 4917, 4916, + 4919, 4914, 4913, 5007, 5006, 4951, 5005, 4944, 4947, 4950, 11666, 4949, + 4948, 4946, 4945, 4696, 4699, 4701, 4700, 4698, 4688, 4691, 4693, 4692, + 4690, 4694, 4689, 4680, 4683, 4685, 4684, 4682, 11712, 11715, 11717, + 11716, 11714, 11718, 11713, 4672, 4675, 4678, 4679, 4677, 4676, 4674, + 4673, 4648, 4651, 4654, 11650, 4653, 4652, 4655, 4952, 4650, 4649, 4661, + 4996, 5000, 4992, 5004, 4660, 4664, 4667, 4670, 11652, 4669, 4668, 4671, + 4666, 4665, 4640, 4643, 4645, 4644, 4647, 4642, 4646, 4641, 11680, 11683, + 11685, 11684, 11682, 11686, 11681, 4656, 4659, 4662, 11651, 4663, 4658, + 4657, 4896, 4899, 4902, 11663, 4901, 4900, 4903, 4898, 4897, 43781, + 43780, 43779, 43778, 43782, 43777, 4928, 4931, 4934, 4935, 4933, 4932, + 4930, 4929, 4920, 4923, 4925, 4924, 4927, 4922, 4926, 4921, 4720, 4723, + 4726, 11654, 4725, 4724, 4727, 4722, 4721, 4864, 4867, 4870, 11662, 4869, + 4868, 4871, 4866, 4865, 4616, 4619, 4622, 11648, 4621, 4620, 4623, 4618, + 4617, 4808, 4811, 4814, 4815, 4813, 4812, 4810, 4809, 4840, 4843, 4846, + 4847, 4845, 4844, 4842, 4841, 4744, 4747, 4749, 4748, 4746, 11728, 11731, + 11733, 11732, 11730, 11734, 11729, 4736, 4739, 4742, 4743, 4741, 4740, + 4738, 4737, 4832, 4835, 4837, 4836, 4839, 4834, 4838, 4833, 11696, 11699, + 11701, 11700, 11698, 11702, 11697, 4824, 4827, 4830, 11659, 4829, 4828, + 4831, 4826, 4825, 4712, 4715, 4717, 4716, 4719, 4714, 4718, 4713, 5009, + 5016, 5012, 5015, 5013, 5017, 5010, 5011, 5014, 5008, 4973, 4972, 4975, + 4974, 4971, 4970, 4977, 4969, 4976, 4962, 4967, 4961, 983096, 983047, + 127984, 127972, 8352, 8364, 8455, 8265, 33, 8761, 128942, 128954, 128948, + 128905, 128915, 128935, 128125, 1781, 1780, 1783, 1782, 1779, 1778, 1776, + 1785, 1777, 1784, 128529, 128065, 128083, 128064, 128231, 9167, 127794, + 983180, 128523, 128561, 129312, 128531, 129301, 128567, 129488, 128582, + 128558, 129326, 128560, 129762, 129320, 128581, 129395, 129763, 129402, + 128539, 128540, 128541, 128514, 129298, 129323, 128580, 128548, 129764, + 129396, 128566, 129318, 128134, 128536, 129401, 8507, 127981, 10540, + 10543, 9950, 127810, 129478, 128439, 128224, 128106, 9771, 127877, + 129498, 129718, 128552, 170, 9792, 127905, 9972, 129338, 8210, 8199, + 128193, 128452, 983107, 128253, 127902, 128293, 128658, 129519, 127879, + 127878, 129512, 9789, 127771, 127763, 8296, 129351, 128031, 127907, 9673, + 127845, 128074, 8281, 11821, 127953, 10765, 129407, 129747, 9189, 9971, + 129449, 128170, 9884, 10086, 9880, 8277, 127924, 128190, 128563, 129672, + 129712, 129359, 128760, 128389, 127787, 127745, 129709, 128448, 129462, + 128099, 127860, 127869, 11792, 10972, 983071, 8704, 8873, 129376, 10021, + 11156, 8280, 8283, 10019, 127808, 10018, 128966, 8732, 8197, 9970, + 129749, 129418, 8260, 8543, 128444, 128446, 128445, 127839, 8355, 129398, + 10156, 128037, 8994, 128550, 128056, 127844, 127773, 127765, 10199, 9608, + 46, 65342, 65312, 65292, 65306, 65504, 65371, 65375, 65288, 65339, 65308, + 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, + 65323, 65324, 65325, 65326, 65327, 65328, 65329, 65330, 65331, 65332, + 65333, 65334, 65335, 65336, 65337, 65338, 65345, 65346, 65347, 65348, + 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, + 65359, 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, + 65369, 65370, 65343, 65506, 65283, 65505, 65285, 65291, 65373, 65376, + 65289, 65341, 65340, 65307, 65295, 65509, 65507, 65287, 65286, 65290, + 65284, 65301, 65300, 65303, 65302, 65299, 65298, 65296, 65305, 65297, + 65304, 65309, 65281, 65344, 65310, 65293, 65282, 65311, 65510, 65374, + 65508, 65294, 65372, 8289, 9905, 9981, 9179, 983215, 983216, 983217, + 983219, 983108, 983236, 983072, 129476, 127922, 9881, 9965, 9966, 128142, + 9802, 8782, 8785, 8762, 4301, 4256, 4288, 4292, 4290, 4293, 4289, 4281, + 4285, 4284, 4282, 4278, 4258, 4287, 4283, 4277, 4265, 4276, 4270, 4280, + 4273, 4271, 4262, 4263, 4274, 4266, 4272, 4257, 4267, 4286, 4268, 4279, + 4261, 4259, 4260, 4264, 4269, 4275, 4295, 4291, 11565, 11520, 11552, + 11556, 11554, 11557, 11553, 11545, 11549, 11548, 11546, 11542, 11522, + 11551, 11547, 11541, 11529, 11540, 11534, 11544, 11537, 11535, 11526, + 11527, 11538, 11530, 11536, 11521, 11531, 11550, 11532, 11543, 11525, + 11523, 11524, 11528, 11533, 11539, 11559, 11555, 983955, 4323, 4349, + 4346, 4304, 4329, 4333, 4332, 4330, 4344, 4308, 4326, 4306, 4340, 4350, + 4336, 4338, 4341, 4337, 4335, 4331, 4325, 4313, 4351, 4314, 4324, 4318, + 4328, 4321, 4345, 4311, 4322, 4319, 4310, 4320, 4305, 4315, 4334, 4316, + 4327, 4309, 4307, 4312, 4317, 4343, 4339, 4342, 7357, 7354, 7312, 7337, + 7341, 7340, 7338, 7352, 7316, 7334, 7314, 7348, 7358, 7344, 7346, 7349, + 7345, 7343, 7339, 7333, 7321, 7359, 7322, 7332, 7326, 7336, 7329, 7353, + 7319, 7330, 7327, 7318, 7328, 7313, 7323, 7342, 7324, 7335, 7317, 7315, + 7320, 7325, 7331, 7351, 7347, 7350, 4347, 8368, 12307, 129502, 8503, + 129754, 128103, 128714, 129426, 11264, 11304, 11265, 11311, 11293, 11276, + 11268, 11271, 11287, 11306, 11267, 11275, 11274, 11305, 11303, 11307, + 11273, 11310, 11278, 11279, 11280, 11281, 11289, 11282, 11290, 11283, + 11291, 11308, 11294, 11284, 11298, 11300, 11301, 11285, 11309, 11292, + 11266, 11269, 11296, 11295, 11297, 11302, 11299, 11272, 11270, 11288, + 11286, 11277, 11312, 11352, 11313, 11359, 11341, 11324, 11316, 11319, + 11335, 11354, 11315, 11323, 11322, 11353, 11351, 11355, 11321, 11358, + 11326, 11327, 11328, 11329, 11337, 11330, 11338, 11331, 11339, 11356, + 11342, 11332, 11346, 11348, 11349, 11333, 11357, 11340, 11314, 11317, + 11344, 11343, 11345, 11350, 11347, 11320, 11318, 11336, 11334, 11325, + 129371, 127760, 127775, 129508, 10726, 129349, 128016, 66356, 66352, + 66376, 66359, 66358, 66375, 66378, 66369, 66365, 66368, 66357, 66370, + 66360, 66372, 66373, 66367, 66374, 66353, 66377, 66355, 66364, 66371, + 66361, 66363, 66366, 66354, 66362, 129405, 129421, 128893, 129727, + 127948, 127891, 70495, 70494, 70411, 70496, 70412, 70497, 70453, 70405, + 70406, 70416, 70420, 70434, 70433, 70439, 70438, 70432, 70431, 70437, + 70436, 70409, 70410, 70407, 70408, 70451, 70450, 70425, 70435, 70430, + 70440, 70454, 70455, 70456, 70445, 70444, 70427, 70426, 70424, 70423, + 70429, 70428, 70422, 70421, 70443, 70442, 70419, 70415, 70457, 70446, + 70448, 70447, 70400, 70401, 70493, 70461, 70402, 70460, 70477, 70403, + 70462, 70472, 70476, 70467, 70468, 70498, 70499, 70465, 70466, 70463, + 70464, 70475, 70471, 70487, 70480, 96, 127815, 10896, 10894, 10900, + 10892, 10898, 10616, 10890, 10888, 10917, 8935, 8809, 10878, 10882, + 10884, 10880, 10886, 8819, 8805, 8823, 10916, 8807, 8923, 10919, 10921, + 10874, 10876, 8919, 62, 65860, 65863, 65878, 65866, 65873, 65859, 65861, + 65868, 65875, 65862, 65870, 65864, 65871, 65867, 65874, 65857, 65869, + 65876, 65856, 65858, 65865, 65877, 65872, 65879, 65903, 65885, 65904, + 65907, 65908, 65900, 65883, 65886, 65896, 65890, 65882, 65880, 65891, + 65902, 65906, 65897, 65899, 65893, 65892, 65884, 65881, 65898, 65905, + 65887, 65901, 65894, 65895, 65888, 65889, 903, 65927, 65926, 913, 7945, + 7949, 8077, 7947, 8075, 7951, 8079, 8073, 7944, 7948, 8076, 7946, 8074, + 7950, 8078, 8072, 8124, 8120, 8122, 8123, 902, 8121, 882, 919, 7977, + 7981, 8093, 7979, 8091, 7983, 8095, 8089, 7976, 7980, 8092, 7978, 8090, + 7982, 8094, 8088, 8140, 8139, 8138, 905, 917, 7961, 7965, 7963, 7960, + 7964, 7962, 8137, 8136, 904, 921, 7993, 7999, 7997, 7995, 938, 7992, + 7998, 7996, 7994, 8152, 8154, 8155, 906, 8153, 937, 8041, 8045, 8109, + 8043, 8107, 8047, 8111, 8105, 8040, 8044, 8108, 8042, 8106, 8046, 8110, + 8104, 8188, 8187, 8186, 911, 927, 8009, 8013, 8011, 8008, 8012, 8010, + 8185, 8184, 908, 929, 8172, 931, 1018, 1015, 933, 8025, 8031, 8029, 8027, + 939, 8168, 8170, 8171, 910, 8169, 886, 934, 936, 928, 920, 932, 916, 922, + 915, 935, 914, 880, 918, 923, 895, 924, 925, 926, 1017, 1023, 1021, 1022, + 975, 1012, 8129, 8174, 8173, 901, 65915, 8190, 8159, 8158, 8157, 65920, + 65919, 119325, 119331, 119332, 119333, 119334, 119335, 119336, 119337, + 119326, 119338, 119339, 119340, 119341, 119342, 119343, 119344, 119345, + 119346, 119347, 119348, 119349, 119327, 119350, 119351, 119352, 119353, + 119354, 119355, 119356, 119328, 119357, 119358, 119359, 119360, 119361, + 119329, 119330, 65933, 1008, 983, 8125, 65922, 7466, 7464, 7462, 43877, + 7465, 7463, 992, 986, 984, 990, 988, 1011, 885, 1010, 1013, 65923, 884, + 65921, 119365, 65925, 65909, 65910, 65931, 8189, 65924, 65916, 8126, + 8127, 8143, 8142, 8141, 8128, 981, 982, 1020, 1009, 1014, 945, 8112, + 8048, 8114, 7937, 7941, 8069, 7943, 8071, 7939, 8067, 8065, 7936, 7940, + 8068, 7942, 8070, 7938, 8066, 8064, 8118, 8119, 8049, 8116, 8115, 940, + 8113, 985, 883, 989, 948, 949, 7953, 7957, 7955, 7952, 7956, 7954, 8051, + 8050, 941, 951, 7969, 7973, 8085, 7975, 8087, 7971, 8083, 8081, 7968, + 7972, 8084, 7974, 8086, 7970, 8082, 8080, 8134, 8135, 8053, 8132, 8052, + 8130, 8131, 942, 953, 7985, 7991, 7989, 7987, 970, 8151, 8147, 8146, 912, + 7984, 7990, 7988, 7986, 8150, 8144, 8054, 8055, 943, 8145, 965, 8017, + 8023, 8021, 8019, 971, 8167, 8163, 8162, 944, 8016, 8022, 8020, 8018, + 8166, 8160, 8058, 8059, 973, 8161, 954, 991, 969, 8033, 8037, 8101, 8039, + 8103, 8035, 8099, 8097, 8032, 8036, 8100, 8038, 8102, 8034, 8098, 8096, + 8182, 8183, 8061, 8180, 8060, 8178, 8179, 974, 959, 8001, 8005, 8003, + 8000, 8004, 8002, 8057, 8056, 972, 887, 966, 968, 960, 961, 8165, 8164, + 993, 1019, 987, 963, 1016, 952, 964, 962, 947, 967, 946, 881, 950, 955, + 956, 957, 958, 893, 891, 892, 7527, 7530, 7529, 7528, 7526, 65952, 65932, + 65918, 65912, 977, 65929, 65917, 65911, 900, 65914, 979, 980, 978, 8175, + 119297, 119315, 119316, 119317, 119318, 119319, 119300, 119320, 119321, + 119322, 119323, 119324, 119296, 119305, 119306, 119307, 119308, 119309, + 119310, 119311, 119312, 119313, 119314, 119298, 119299, 119301, 119302, + 119303, 119304, 890, 65913, 976, 65928, 65930, 894, 127823, 128215, + 128154, 129367, 129654, 128512, 129322, 128513, 129321, 128568, 128556, + 983110, 11218, 128151, 8370, 128130, 127928, 129454, 2693, 2694, 2704, + 2708, 2722, 2721, 2727, 2726, 2720, 2719, 2725, 2724, 2699, 2784, 2700, + 2785, 2741, 2697, 2698, 2695, 2696, 2739, 2738, 2809, 2713, 2723, 2718, + 2728, 2742, 2743, 2744, 2733, 2732, 2715, 2714, 2712, 2711, 2717, 2716, + 2710, 2709, 2731, 2730, 2745, 2734, 2736, 2735, 2703, 2707, 2814, 2689, + 2812, 2815, 2813, 2811, 2810, 2749, 2690, 2748, 2765, 2691, 2757, 2761, + 2750, 2760, 2764, 2755, 2756, 2786, 2787, 2753, 2754, 2751, 2752, 2759, + 2763, 2701, 2705, 2800, 2801, 2795, 2794, 2797, 2796, 2793, 2792, 2790, + 2799, 2791, 2798, 2768, 73056, 73057, 73064, 73067, 73091, 73090, 73081, + 73080, 73086, 73085, 73076, 73075, 73060, 73061, 73092, 73082, 73058, + 73059, 73087, 73077, 73071, 73070, 73084, 73083, 73079, 73078, 73089, + 73088, 73074, 73073, 73094, 73093, 73066, 73063, 73095, 73072, 73096, + 73097, 73069, 73068, 73110, 73109, 73098, 73105, 73108, 73101, 73102, + 73099, 73100, 73107, 73104, 73111, 73125, 73124, 73127, 73126, 73123, + 73122, 73120, 73129, 73121, 73128, 73112, 2678, 2673, 2650, 2584, 2583, + 2649, 2582, 2581, 2652, 2608, 2565, 2566, 2576, 2580, 2594, 2593, 2599, + 2598, 2592, 2591, 2597, 2596, 2569, 2570, 2567, 2568, 2611, 2610, 2585, + 2595, 2590, 2600, 2605, 2604, 2587, 2586, 2589, 2588, 2603, 2602, 2614, + 2616, 2579, 2575, 2654, 2617, 2606, 2613, 2607, 2651, 983656, 983655, + 983654, 983653, 983658, 983657, 2561, 2562, 2641, 2620, 2677, 2637, 2563, + 2622, 2632, 2636, 2625, 2626, 2623, 2624, 2635, 2631, 2672, 2674, 2676, + 2667, 2666, 2669, 2668, 2665, 2664, 2662, 2671, 2663, 2670, 2675, 128123, + 983111, 129710, 8202, 128135, 65467, 65441, 65443, 65444, 65445, 65446, + 65469, 65458, 65460, 65449, 65454, 65455, 65452, 65451, 65450, 65456, + 65453, 65465, 65442, 65459, 65448, 65462, 65461, 65483, 65482, 65476, + 65477, 65499, 65490, 65495, 65466, 65464, 65479, 65478, 65498, 65500, + 65463, 65457, 65468, 65447, 65493, 65492, 65485, 65486, 65494, 65470, + 65474, 65475, 65484, 65487, 65491, 65440, 65388, 65390, 65389, 65391, + 65383, 65386, 65384, 65387, 65385, 65403, 65406, 65404, 65407, 65405, + 65437, 65413, 65416, 65414, 65417, 65415, 65418, 65421, 65419, 65422, + 65420, 65398, 65401, 65399, 65402, 65400, 65423, 65426, 65424, 65427, + 65425, 65431, 65434, 65432, 65435, 65433, 65408, 65411, 65409, 65412, + 65410, 65428, 65430, 65429, 65436, 65382, 65393, 65396, 65394, 65397, + 65395, 65439, 65438, 65381, 65392, 65378, 65513, 65379, 65515, 65514, + 65512, 65380, 65377, 65517, 65518, 65516, 128296, 128736, 9773, 9874, + 128057, 129708, 127828, 129310, 129776, 129342, 128092, 129309, 4366, + 4434, 4435, 4431, 4413, 4412, 4436, 4430, 4433, 4415, 4414, 4437, 4432, + 4364, 4429, 4363, 4427, 4420, 4422, 43382, 4425, 4424, 4419, 4426, 4418, + 4417, 43383, 4421, 4379, 4439, 4395, 4396, 4381, 4352, 4442, 4367, 4358, + 43375, 4380, 43376, 43377, 4354, 4444, 4371, 4374, 4373, 4445, 4443, + 4369, 4438, 43386, 4359, 4385, 43378, 4387, 4390, 4386, 4388, 4389, 4394, + 43379, 4382, 4392, 4391, 4393, 4384, 4383, 43380, 4416, 4357, 43371, + 43374, 43364, 43365, 43370, 43367, 43372, 43368, 43373, 4376, 43369, + 43366, 4378, 4361, 4402, 4403, 4410, 4404, 4400, 4408, 4397, 4407, 4406, + 4401, 4409, 4399, 4398, 4411, 4405, 4365, 43384, 4362, 43381, 4377, + 43385, 4356, 43388, 4353, 4372, 4360, 4440, 4423, 4355, 4446, 43360, + 43363, 4375, 43361, 43362, 4368, 4428, 4441, 4370, 43387, 4447, 12335, + 12334, 4541, 55288, 55287, 4542, 4546, 4598, 4599, 4597, 4600, 4540, + 4591, 4588, 4589, 55261, 4596, 4582, 4578, 4520, 4605, 4547, 4522, 4548, + 4604, 4602, 4603, 4606, 4543, 4535, 4572, 55265, 4575, 55263, 4574, 4573, + 4571, 4576, 55266, 4570, 55262, 4577, 4523, 55243, 55244, 4524, 4553, + 4550, 4549, 4525, 4552, 4551, 4587, 55284, 55283, 4545, 55291, 4595, + 55290, 4536, 4579, 55268, 4537, 55271, 4580, 55273, 55272, 55269, 55267, + 4581, 4527, 4528, 55254, 4556, 4565, 4568, 4529, 4561, 55256, 4562, 4530, + 55258, 55257, 4564, 4563, 4533, 4567, 55253, 4566, 4531, 4558, 4559, + 4532, 4569, 55260, 55259, 4557, 4534, 4538, 55275, 4583, 4585, 55280, + 55279, 4586, 55278, 55274, 55281, 4584, 55282, 4560, 55255, 55245, 55246, + 983213, 4539, 55276, 55277, 55264, 55289, 4521, 4607, 55270, 4590, 4526, + 4555, 55248, 55249, 55252, 55251, 55250, 4554, 55247, 4544, 4592, 983214, + 983211, 983212, 4593, 55285, 55286, 4594, 4601, 4449, 4510, 55238, 4511, + 55237, 4513, 4512, 4515, 4470, 4471, 4450, 4454, 4453, 4476, 4474, 4475, + 4467, 55227, 55226, 4502, 55225, 55228, 4501, 4469, 4504, 4509, 4505, + 55229, 55230, 55232, 55231, 55234, 55235, 4506, 55233, 4508, 55236, 4507, + 4514, 4457, 4482, 55217, 4481, 55216, 4518, 4519, 4480, 4479, 4483, 4460, + 4462, 4492, 55221, 55222, 4491, 4489, 4490, 4493, 4451, 4473, 4472, 4516, + 4452, 4456, 4455, 4517, 4477, 4478, 4468, 4503, 4461, 4484, 4485, 4486, + 55218, 55219, 55220, 4488, 4487, 4466, 4498, 4497, 4496, 4495, 4494, + 55223, 4500, 55224, 4499, 4464, 4463, 4458, 4459, 4465, 4448, 12623, + 12685, 12686, 12624, 12618, 12616, 12628, 12627, 12641, 12643, 12615, + 12676, 12664, 12665, 12657, 12619, 12593, 12595, 12609, 12654, 12656, + 12655, 12596, 12597, 12646, 12598, 12648, 12647, 12610, 12612, 12660, + 12661, 12663, 12659, 12662, 12658, 12621, 12671, 12601, 12602, 12649, + 12603, 12607, 12604, 12651, 12652, 12606, 12650, 12653, 12608, 12605, + 12620, 12599, 12613, 12670, 12666, 12667, 12669, 12668, 12617, 12594, + 12645, 12611, 12600, 12677, 12614, 12672, 12638, 12637, 12632, 12633, + 12639, 12630, 12629, 12678, 12673, 12675, 12674, 12635, 12679, 12680, + 12681, 12640, 12683, 12682, 12684, 12625, 12626, 12642, 12622, 12631, + 12634, 12636, 12644, 12323, 12346, 12345, 12322, 12344, 12325, 12324, + 12327, 12326, 12329, 12321, 12328, 68875, 68874, 68887, 68889, 68872, + 68881, 68868, 68867, 68877, 68876, 68890, 68891, 68885, 68880, 68879, + 68865, 68870, 68873, 68882, 68871, 68869, 68883, 68884, 68866, 68892, + 68886, 68888, 68878, 68864, 68899, 68898, 68901, 68903, 68902, 68900, + 68893, 68896, 68894, 68897, 68895, 68917, 68916, 68919, 68918, 68915, + 68914, 68912, 68921, 68913, 68920, 5925, 5928, 5930, 5927, 5924, 5937, + 5923, 5934, 5931, 5929, 5933, 5936, 5926, 5935, 5932, 5920, 5921, 5922, + 5940, 5938, 5939, 128587, 128035, 67808, 67823, 67814, 67816, 67829, + 67819, 67826, 67811, 67810, 67822, 67825, 67828, 67817, 67812, 67815, + 67818, 67809, 67821, 67813, 67824, 67820, 67835, 67839, 67838, 67837, + 67836, 128891, 128436, 11233, 129702, 9980, 127911, 127892, 128157, + 128152, 128159, 129782, 128585, 129180, 129183, 129182, 129181, 128628, + 10033, 10008, 10149, 10150, 10084, 10167, 10169, 10168, 10054, 10004, + 11096, 9955, 11095, 11097, 10152, 10144, 10135, 129055, 129051, 10077, + 10078, 128178, 128977, 10040, 128975, 10059, 128958, 10071, 10082, + 129008, 10020, 128970, 128946, 129943, 10083, 11093, 128327, 10096, + 10094, 129052, 129048, 10080, 10079, 10157, 128627, 10006, 10134, 10012, + 11094, 10030, 10097, 10095, 10137, 129054, 129050, 10140, 128635, 128940, + 10075, 10076, 128972, 128952, 128607, 128615, 10136, 128605, 128613, + 128625, 10056, 128606, 128614, 10138, 128604, 128612, 10051, 10045, + 10171, 10142, 128980, 128979, 129053, 129049, 10158, 9947, 128903, + 128913, 10132, 10173, 128633, 10133, 10074, 10010, 1442, 1453, 1447, + 1436, 1437, 1438, 1445, 1446, 1443, 1444, 1433, 1441, 1425, 1439, 1448, + 1426, 1427, 1449, 1440, 1435, 1430, 1450, 1434, 1428, 1429, 1432, 1454, + 1431, 1451, 1452, 1488, 64304, 64302, 64303, 64288, 64297, 1506, 1489, + 64332, 64305, 1499, 64333, 64315, 1508, 64334, 64324, 1498, 64314, 1507, + 64323, 1509, 1503, 1501, 1511, 64327, 1492, 64308, 1495, 1504, 64320, + 1494, 64310, 1505, 64321, 1513, 64329, 64300, 64301, 64298, 64299, 1512, + 64328, 1496, 64312, 1514, 64330, 1510, 64326, 1491, 64307, 1490, 64306, + 1500, 64316, 1502, 64318, 1493, 64331, 64309, 64293, 64289, 64296, 64295, + 64290, 64292, 64291, 64294, 1497, 64285, 64313, 64335, 1520, 1522, 64287, + 1521, 1477, 1476, 1455, 1468, 1458, 1459, 1457, 1460, 1465, 1466, 1463, + 64286, 1464, 1479, 1467, 1471, 1462, 1473, 1456, 1474, 1461, 1469, 1524, + 1523, 1472, 1475, 1478, 1470, 1519, 9937, 9096, 11263, 128641, 110597, + 110594, 110595, 110596, 110778, 110779, 110780, 110781, 110782, 110783, + 110784, 110785, 110750, 110759, 110760, 110751, 110752, 110753, 110754, + 110755, 110756, 110757, 110758, 110768, 110769, 110770, 110771, 110772, + 110773, 110774, 110775, 110776, 110777, 110761, 110762, 110763, 110764, + 110765, 110766, 110767, 110615, 110624, 110625, 110626, 110616, 110617, + 110618, 110619, 110620, 110621, 110622, 110623, 110651, 110648, 110649, + 110650, 110627, 110628, 110629, 110630, 110631, 110632, 110633, 110634, + 110642, 110643, 110644, 110645, 110646, 110647, 110635, 110636, 110637, + 110638, 110639, 110640, 110641, 110806, 110804, 110805, 110807, 110808, + 110809, 110810, 110811, 110812, 110786, 110787, 110788, 110789, 110790, + 110791, 110792, 110793, 110794, 110795, 110796, 110797, 110798, 110799, + 110800, 110801, 110802, 110803, 110744, 110738, 110739, 110740, 110741, + 110742, 110743, 110734, 110727, 110728, 110729, 110730, 110731, 110732, + 110733, 110718, 110719, 110720, 110721, 110722, 110723, 110724, 110725, + 110726, 110745, 110746, 110747, 110748, 110749, 110735, 110736, 110737, + 110877, 110878, 110850, 110851, 110852, 110853, 110854, 110855, 110840, + 110841, 110842, 110843, 110844, 110845, 110833, 110834, 110835, 110836, + 110837, 110838, 110839, 110829, 110830, 110831, 110832, 110846, 110847, + 110848, 110849, 110652, 110653, 110654, 110655, 110656, 110657, 110658, + 110659, 110666, 110667, 110668, 110669, 110670, 110671, 110672, 110673, + 110660, 110661, 110662, 110663, 110664, 110665, 110674, 110675, 110676, + 110677, 110678, 110679, 110680, 110681, 110682, 110683, 110684, 110685, + 110702, 110703, 110704, 110705, 110706, 110707, 110708, 110709, 110710, + 110717, 110711, 110712, 110713, 110714, 110715, 110716, 110701, 110697, + 110698, 110699, 110700, 110690, 110691, 110692, 110693, 110694, 110695, + 110696, 110686, 110687, 110688, 110689, 110856, 110857, 110858, 110859, + 110860, 110861, 110862, 110863, 110864, 110865, 110870, 110871, 110872, + 110873, 110874, 110875, 110876, 110866, 110867, 110868, 110869, 110818, + 110813, 110814, 110815, 110816, 110817, 110823, 110824, 110825, 110826, + 110827, 110828, 110819, 110820, 110821, 110822, 983271, 110607, 110608, + 110609, 110610, 110611, 110602, 110603, 110604, 110605, 110606, 110612, + 110613, 110614, 110598, 110599, 110600, 110601, 8889, 127807, 19922, + 19966, 19958, 19967, 19924, 19946, 19923, 19909, 19947, 19944, 19943, + 19956, 19906, 19962, 19935, 19939, 19920, 19916, 19948, 19917, 19937, + 19931, 19929, 19925, 19911, 19964, 19928, 19945, 19934, 19918, 19930, + 19942, 19950, 19941, 19949, 19938, 19914, 19927, 19936, 19952, 19965, + 19912, 19915, 19926, 19954, 19910, 19932, 19953, 19904, 19933, 19940, + 19905, 19951, 19959, 19957, 19960, 19955, 19961, 19913, 19908, 19921, + 19963, 19907, 19919, 129428, 128262, 9889, 983123, 128644, 128645, + 128096, 12447, 12354, 110879, 110593, 12430, 110929, 110928, 110930, + 12419, 12423, 12421, 12437, 12438, 110898, 12387, 12353, 12359, 12355, + 12361, 12357, 12373, 12379, 12375, 12381, 12377, 12403, 983997, 984000, + 983998, 984001, 983999, 12400, 12409, 12412, 12406, 12435, 12394, 12397, + 12395, 12398, 12396, 12384, 12391, 12386, 12393, 12389, 12364, 12370, + 12366, 12372, 12368, 12399, 12408, 12402, 12411, 12405, 12363, 12369, + 12365, 12371, 12367, 12414, 12417, 12415, 12418, 12416, 12401, 12410, + 12404, 12413, 12407, 12425, 12428, 12426, 12429, 12427, 12383, 12390, + 12385, 12392, 12388, 12374, 12380, 12376, 12382, 12378, 12431, 12433, + 12432, 12434, 12420, 12424, 12422, 12436, 12360, 12356, 12362, 12358, + 12446, 12445, 9964, 128725, 129406, 127802, 129435, 128616, 128617, + 128371, 128029, 127855, 11203, 11043, 8213, 9135, 129921, 129910, 129911, + 129912, 129913, 129914, 129915, 9146, 9147, 9148, 9149, 983059, 983141, + 983138, 11134, 128677, 8230, 9897, 128014, 127943, 128052, 127798, 9749, + 9832, 127789, 127976, 8987, 9203, 8962, 127969, 127968, 127960, 127973, + 128298, 8763, 129693, 983124, 983060, 983142, 983139, 128559, 128175, + 129303, 128726, 8208, 11802, 8259, 8231, 45, 11794, 9102, 11226, 129723, + 8372, 127848, 129482, 127954, 9976, 8801, 10725, 10855, 129706, 12696, + 12700, 12693, 12697, 12695, 12703, 12692, 12699, 12691, 12694, 12688, + 12698, 12690, 12689, 12701, 12702, 12294, 12289, 12275, 12273, 12274, + 12272, 12283, 12282, 12285, 12279, 12280, 12281, 12278, 12277, 12284, + 12783, 12287, 12276, 12286, 12332, 12295, 119670, 119669, 119668, 119667, + 119666, 12999, 12995, 13309, 13310, 13292, 13282, 13299, 13304, 13303, + 13306, 13305, 13302, 13301, 13308, 13300, 13307, 13291, 13281, 13289, + 13287, 13297, 13290, 13294, 13284, 13283, 13293, 13288, 13298, 13286, + 13296, 13285, 13295, 13280, 13003, 13164, 13168, 13167, 13166, 13165, + 13156, 13146, 13157, 13147, 13154, 13152, 13162, 13155, 13159, 13149, + 13148, 13158, 13153, 13163, 13151, 13161, 13150, 13160, 13144, 13145, + 12992, 12997, 12998, 12993, 12994, 12996, 13002, 13000, 13001, 12343, + 12351, 12333, 12331, 12330, 12350, 12290, 12293, 12288, 8887, 8787, + 128127, 67676, 67673, 67675, 67679, 67674, 67672, 67677, 67678, 67656, + 67669, 67651, 67659, 67666, 67667, 67648, 67663, 67650, 67654, 67662, + 67665, 67668, 67657, 67652, 67655, 67658, 67649, 67661, 67653, 67664, + 67660, 67671, 128232, 10716, 128474, 10721, 8710, 983130, 983129, 129781, + 126132, 126112, 126126, 126125, 126127, 126131, 126130, 126129, 126113, + 126114, 126110, 126111, 126072, 126081, 126108, 126090, 126099, 126078, + 126105, 126069, 126087, 126096, 126077, 126104, 126068, 126086, 126095, + 126073, 126082, 126109, 126091, 126100, 126071, 126080, 126107, 126089, + 126098, 126070, 126079, 126106, 126088, 126097, 126076, 126103, 126067, + 126085, 126094, 126075, 126102, 126066, 126084, 126093, 126074, 126101, + 126119, 126118, 126121, 126120, 126117, 126116, 126123, 126115, 126122, + 126065, 126083, 126092, 126128, 126124, 8377, 8734, 10718, 983106, + 983109, 983112, 983115, 8505, 128129, 8300, 8298, 128288, 128289, 128292, + 128291, 128290, 68456, 68466, 68448, 68451, 68459, 68460, 68453, 68450, + 68454, 68462, 68464, 68465, 68457, 68452, 68455, 68458, 68449, 68461, + 68463, 68477, 68473, 68474, 68476, 68472, 68478, 68479, 68475, 68424, + 68437, 68419, 68427, 68434, 68435, 68416, 68431, 68418, 68422, 68430, + 68433, 68436, 68425, 68420, 68423, 68426, 68417, 68429, 68421, 68432, + 68428, 68445, 68441, 68442, 68444, 68440, 68446, 68447, 68443, 9088, + 8747, 10767, 10773, 10776, 10780, 10778, 10775, 10777, 10779, 10766, + 9134, 65529, 65531, 65530, 9892, 8745, 10825, 10823, 10820, 10819, 10816, + 10827, 8253, 8890, 10812, 129942, 129969, 129972, 9689, 129936, 9688, + 11800, 11845, 11846, 8766, 9959, 161, 8487, 8276, 191, 8290, 8292, 8291, + 128229, 127982, 129311, 127875, 127983, 127971, 12292, 9979, 127886, + 128122, 128121, 128304, 43453, 43454, 43455, 43457, 43421, 43422, 43426, + 43427, 43398, 43397, 43399, 43407, 43408, 43409, 43412, 43402, 43403, + 43418, 43416, 43428, 43423, 43431, 43432, 43413, 43414, 43410, 43411, + 43429, 43430, 43401, 43435, 43436, 43441, 43439, 43440, 43424, 43425, + 43419, 43420, 43415, 43417, 43396, 43405, 43442, 43437, 43433, 43438, + 43434, 43404, 43406, 43400, 43458, 43466, 43467, 43459, 43465, 43461, + 43464, 43468, 43463, 43486, 43462, 43487, 43460, 43471, 43456, 43469, + 43393, 43443, 43392, 43395, 43394, 43448, 43449, 43444, 43450, 43445, + 43446, 43447, 43452, 43451, 43477, 43476, 43479, 43478, 43475, 43474, + 43472, 43481, 43473, 43480, 129753, 129724, 128086, 128377, 10781, + 129337, 9795, 9909, 129513, 69786, 69787, 69785, 69793, 69792, 69763, + 69764, 69770, 69772, 69784, 69783, 69791, 69790, 69767, 69768, 69765, + 69766, 69777, 69789, 69782, 69794, 69804, 69805, 69806, 69798, 69797, + 69779, 69778, 69776, 69775, 69781, 69780, 69774, 69773, 69796, 69795, + 69788, 69801, 69807, 69802, 69799, 69803, 69800, 69769, 69771, 69760, + 69818, 69761, 69817, 69762, 69822, 69823, 69825, 69824, 69826, 69808, + 69814, 69816, 69811, 69812, 69809, 69810, 69813, 69815, 69821, 69837, + 69819, 69820, 12142, 12164, 12060, 12157, 12100, 12149, 12184, 12191, + 12227, 12068, 12174, 12234, 12205, 12134, 12168, 12219, 12189, 12088, + 12090, 12096, 12160, 12182, 12224, 12190, 12147, 12114, 12118, 12058, + 12176, 12075, 12112, 12045, 12170, 12124, 12070, 12194, 12109, 12229, + 12196, 12139, 12056, 12099, 12034, 12084, 12136, 12120, 12044, 12111, + 12094, 12125, 12243, 12238, 12082, 12159, 12063, 12215, 12062, 12042, + 12241, 12067, 12235, 12043, 12140, 12119, 12207, 12123, 12133, 12222, + 12117, 12226, 12245, 12214, 12217, 12236, 12155, 12188, 12113, 12065, + 12198, 12066, 12146, 12171, 12225, 12200, 12121, 12093, 12095, 12221, + 12092, 12216, 12231, 12054, 12218, 12179, 12037, 12173, 12072, 12046, + 12127, 12152, 12049, 12074, 12107, 12208, 12212, 12041, 12210, 12131, + 12033, 12039, 12199, 12085, 12128, 12161, 12162, 12233, 12165, 12192, + 12077, 12201, 12061, 12105, 12040, 12240, 12102, 12153, 12032, 12080, + 12167, 12048, 12156, 12059, 12126, 12158, 12050, 12183, 12204, 12097, + 12239, 12053, 12078, 12150, 12071, 12187, 12186, 12223, 12228, 12104, + 12098, 12064, 12036, 12057, 12163, 12178, 12185, 12154, 12083, 12203, + 12087, 12135, 12151, 12202, 12035, 12122, 12141, 12180, 12144, 12076, + 12052, 12115, 12091, 12108, 12169, 12143, 12148, 12130, 12089, 12211, + 12073, 12101, 12138, 12103, 12209, 12047, 12220, 12172, 12129, 12166, + 12242, 12237, 12145, 12106, 12081, 12244, 12038, 12086, 12055, 12181, + 12197, 12193, 12175, 12116, 12110, 12177, 12137, 12230, 12213, 12195, + 12069, 12079, 12206, 12051, 12232, 12132, 129432, 983205, 3251, 3250, + 3240, 3293, 3225, 3235, 3230, 3249, 3248, 3205, 3206, 3216, 3220, 3234, + 3233, 3239, 3238, 3232, 3231, 3237, 3236, 3211, 3296, 3212, 3297, 3253, + 3209, 3210, 3218, 3219, 3207, 3208, 3254, 3255, 3256, 3245, 3244, 3227, + 3226, 3224, 3223, 3229, 3228, 3222, 3221, 3243, 3242, 3214, 3215, 3294, + 3257, 3246, 3247, 3285, 3315, 3201, 3200, 3204, 3261, 3202, 3260, 3313, + 3314, 3277, 3203, 3286, 3262, 3272, 3276, 3267, 3268, 3298, 3299, 3265, + 3266, 3274, 3275, 3263, 3264, 3270, 3271, 3307, 3306, 3309, 3308, 3305, + 3304, 3302, 3311, 3303, 3310, 12450, 984009, 984008, 984007, 984010, + 110881, 110880, 110882, 110592, 12499, 984002, 984005, 984003, 984006, + 984004, 12496, 12505, 12508, 12502, 12511, 110583, 110584, 110585, + 110586, 110587, 110589, 110590, 110576, 110577, 110578, 110579, 110581, + 110582, 12510, 12513, 12514, 12512, 12531, 12490, 12493, 12491, 12494, + 12492, 12789, 12792, 12790, 12793, 12791, 12795, 12798, 12796, 12799, + 12797, 12533, 12534, 110933, 12784, 12787, 12483, 12526, 110949, 110948, + 110950, 12515, 12519, 12517, 110951, 12788, 12785, 12786, 12794, 12449, + 12455, 12451, 12457, 12453, 12469, 12475, 12471, 12477, 12473, 12480, + 12487, 12482, 12489, 12485, 12460, 12466, 12462, 12468, 12464, 12495, + 12504, 12498, 12507, 12501, 12459, 12465, 12461, 12467, 12463, 12497, + 12506, 12500, 12509, 12503, 12521, 12524, 12522, 12525, 12523, 12479, + 12486, 12481, 12488, 12484, 12535, 12537, 12536, 12538, 12532, 12470, + 12476, 12472, 12478, 12474, 12527, 12529, 12528, 12530, 12516, 12520, + 12518, 12456, 12452, 12458, 12454, 12542, 12543, 12541, 12539, 12448, + 12540, 12444, 12443, 73476, 73477, 73487, 73523, 73498, 73497, 73503, + 73502, 73508, 73507, 73501, 73500, 73506, 73505, 73482, 73483, 73484, + 73485, 73480, 73481, 73478, 73479, 73494, 73504, 73499, 73509, 73519, + 73520, 73521, 73513, 73512, 73496, 73495, 73493, 73492, 73491, 73490, + 73511, 73510, 73522, 73517, 73514, 73516, 73518, 73515, 73486, 73488, + 73551, 73548, 73546, 73545, 73549, 73543, 73541, 73544, 73550, 73542, + 73547, 73474, 73537, 73472, 73475, 73473, 73525, 73524, 73535, 73530, + 73534, 73536, 73528, 73529, 73526, 73527, 73540, 73539, 73557, 73556, + 73559, 73558, 73555, 73554, 73552, 73561, 73553, 73560, 73538, 43283, + 43295, 43299, 43301, 43277, 43281, 43284, 43275, 43274, 43286, 43285, + 43279, 43278, 43294, 43282, 43289, 43297, 43288, 43276, 43292, 43287, + 43290, 43296, 43293, 43291, 43280, 43298, 43300, 43310, 43311, 43308, + 43309, 43307, 43303, 43305, 43304, 43302, 43306, 43269, 43268, 43271, + 43270, 43267, 43266, 43264, 43273, 43265, 43272, 119496, 119506, 119499, + 119503, 119493, 119492, 119502, 119497, 119507, 119495, 119505, 119494, + 119504, 119501, 119491, 119500, 119490, 119498, 119488, 119489, 128331, + 8490, 128273, 9000, 128422, 983552, 983553, 983559, 983558, 983561, + 983560, 983557, 983556, 983554, 983563, 983555, 983562, 128287, 68163, + 68162, 68161, 68160, 68113, 68146, 68112, 68147, 68148, 68123, 68122, + 68128, 68127, 68126, 68121, 68131, 68125, 68124, 68130, 68129, 68141, + 68142, 68143, 68135, 68134, 68118, 68117, 68115, 68114, 68133, 68132, + 68149, 68140, 68145, 68119, 68139, 68136, 68138, 68137, 68144, 68096, + 68165, 68164, 68166, 68167, 68179, 68178, 68183, 68176, 68182, 68181, + 68184, 68180, 68177, 68152, 68153, 68109, 68154, 68111, 68110, 68099, + 68101, 68097, 68102, 68098, 68108, 68159, 68168, 129711, 101120, 101121, + 101122, 101123, 101124, 101125, 101126, 101127, 101128, 101129, 101130, + 101131, 101132, 101133, 101134, 101135, 101136, 101137, 101138, 101139, + 101140, 101141, 101142, 101143, 101144, 101145, 101146, 101147, 101148, + 101149, 101150, 101151, 101152, 101153, 101154, 101155, 101156, 101157, + 101158, 101159, 101160, 101161, 101162, 101163, 101164, 101165, 101166, + 101167, 101168, 101169, 101170, 101171, 101172, 101173, 101174, 101175, + 101176, 101177, 101178, 101179, 101180, 101181, 101182, 101183, 101184, + 101185, 101186, 101187, 101188, 101189, 101190, 101191, 101192, 101193, + 101194, 101195, 101196, 101197, 101198, 101199, 101200, 101201, 101202, + 101203, 101204, 101205, 101206, 101207, 101208, 101209, 101210, 101211, + 101212, 101213, 101214, 101215, 101216, 101217, 101218, 101219, 101220, + 101221, 101222, 101223, 101224, 101225, 101226, 101227, 101228, 101229, + 101230, 101231, 101232, 101233, 101234, 101235, 101236, 101237, 101238, + 101239, 101240, 101241, 101242, 101243, 101244, 101245, 101246, 101247, + 101248, 101249, 101250, 101251, 101252, 101253, 101254, 101255, 101256, + 101257, 101258, 101259, 101260, 101261, 101262, 101263, 101264, 101265, + 101266, 101267, 101268, 101269, 101270, 101271, 101272, 101273, 101274, + 101275, 101276, 101277, 101278, 101279, 101280, 101281, 101282, 101283, + 101284, 101285, 101286, 101287, 101288, 101289, 101290, 101291, 101292, + 101293, 101294, 101295, 101296, 101297, 101298, 101299, 101300, 101301, + 101302, 101303, 101304, 101305, 101306, 101307, 101308, 101309, 101310, + 101311, 101312, 101313, 101314, 101315, 101316, 101317, 101318, 101319, + 101320, 101321, 101322, 101323, 101324, 101325, 101326, 101327, 101328, + 101329, 101330, 101331, 101332, 101333, 101334, 101335, 101336, 101337, + 101338, 101339, 101340, 101341, 101342, 101343, 101344, 101345, 101346, + 101347, 101348, 101349, 101350, 101351, 101352, 101353, 101354, 101355, + 101356, 101357, 101358, 101359, 101360, 101361, 101362, 101363, 101364, + 101365, 101366, 101367, 101368, 101369, 101370, 101371, 101372, 101373, + 101374, 101375, 101584, 101585, 101586, 101587, 101588, 101589, 101376, + 101377, 101378, 101379, 101380, 101381, 101382, 101383, 101384, 101385, + 101386, 101387, 101388, 101389, 101390, 101391, 101392, 101393, 101394, + 101395, 101396, 101397, 101398, 101399, 101400, 101401, 101402, 101403, + 101404, 101405, 101406, 101407, 101408, 101409, 101410, 101411, 101412, + 101413, 101414, 101415, 101416, 101417, 101418, 101419, 101420, 101421, + 101422, 101423, 101424, 101425, 101426, 101427, 101428, 101429, 101430, + 101431, 101432, 101433, 101434, 101435, 101436, 101437, 101438, 101439, + 101440, 101441, 101442, 101443, 101444, 101445, 101446, 101447, 101448, + 101449, 101450, 101451, 101452, 101453, 101454, 101455, 101456, 101457, + 101458, 101459, 101460, 101461, 101462, 101463, 101464, 101465, 101466, + 101467, 101468, 101469, 101470, 101471, 101472, 101473, 101474, 101475, + 101476, 101477, 101478, 101479, 101480, 101481, 101482, 101483, 101484, + 101485, 101486, 101487, 101488, 101489, 101490, 101491, 101492, 101493, + 101494, 101495, 101496, 101497, 101498, 101499, 101500, 101501, 101502, + 101503, 101504, 101505, 101506, 101507, 101508, 101509, 101510, 101511, + 101512, 101513, 101514, 101515, 101516, 101517, 101518, 101519, 101520, + 101521, 101522, 101523, 101524, 101525, 101526, 101527, 101528, 101529, + 101530, 101531, 101532, 101533, 101534, 101535, 101536, 101537, 101538, + 101539, 101540, 101541, 101542, 101543, 101544, 101545, 101546, 101547, + 101548, 101549, 101550, 101551, 101552, 101553, 101554, 101555, 101556, + 101557, 101558, 101559, 101560, 101561, 101562, 101563, 101564, 101565, + 101566, 101567, 101568, 101569, 101570, 101571, 101572, 101573, 101574, + 101575, 101576, 101577, 101578, 101579, 101580, 101581, 101582, 101583, + 94180, 983960, 983965, 983970, 983975, 983962, 983964, 983961, 983963, + 983957, 983959, 983956, 983958, 983977, 983979, 983978, 983972, 983974, + 983967, 983969, 983971, 983973, 983966, 983968, 983989, 983983, 983985, + 983986, 983987, 983980, 983982, 983984, 983981, 983976, 983988, 6107, + 6052, 6064, 6051, 6067, 6066, 6065, 6055, 6057, 6058, 6056, 6053, 6054, + 6063, 983994, 983991, 983992, 983993, 6061, 6062, 6059, 6060, 6022, 6024, + 6021, 6023, 6017, 6019, 6016, 6018, 6020, 6030, 6025, 6035, 6037, 6039, + 6038, 6046, 6045, 6047, 6032, 6034, 6027, 6029, 6031, 6033, 6026, 6028, + 6049, 6043, 6040, 6042, 6044, 6041, 6036, 6048, 6050, 6108, 6109, 6095, + 6096, 6099, 6091, 6101, 6104, 6102, 6098, 6094, 6100, 6106, 6092, 6087, + 6093, 6090, 6103, 6105, 6088, 6086, 6089, 6097, 6652, 6636, 6655, 6639, + 6653, 6637, 6654, 6638, 6651, 6635, 6650, 6634, 6133, 6137, 6136, 6134, + 6135, 6130, 6132, 6131, 6129, 6128, 6624, 6648, 6632, 6649, 6633, 6647, + 6631, 6646, 6630, 6645, 6629, 6642, 6626, 6640, 6643, 6627, 6644, 6628, + 6641, 6625, 6069, 6068, 6070, 983996, 6082, 6083, 6085, 6071, 6080, 6072, + 6078, 983995, 6084, 6073, 6079, 6074, 983990, 6075, 6077, 6076, 6081, + 6117, 6116, 6119, 6118, 6115, 6114, 6112, 6121, 6113, 6120, 70204, 70201, + 70200, 70208, 70185, 70178, 70179, 70177, 70155, 70156, 70154, 70172, + 70167, 70166, 70173, 70171, 70161, 70160, 70144, 70145, 70149, 70151, + 70165, 70164, 70170, 70169, 70187, 70183, 70157, 70168, 70163, 70174, + 70159, 70158, 70153, 70152, 70176, 70175, 70186, 70180, 70207, 70182, + 70184, 70181, 70148, 70146, 70150, 70147, 70199, 70206, 70197, 70198, + 70196, 70203, 70209, 70188, 70193, 70195, 70189, 70190, 70192, 70194, + 70191, 70202, 70205, 70357, 70358, 70356, 70333, 70334, 70332, 70340, + 70339, 70338, 70345, 70347, 70344, 70352, 70351, 70346, 70361, 70320, + 70321, 70327, 70329, 70343, 70342, 70350, 70349, 70324, 70325, 70322, + 70323, 70335, 70348, 70341, 70353, 70337, 70336, 70331, 70330, 70355, + 70354, 70364, 70365, 70366, 70362, 70359, 70363, 70360, 70326, 70328, + 70378, 70377, 70367, 70368, 70374, 70376, 70371, 70372, 70369, 70370, + 70373, 70375, 70389, 70388, 70391, 70390, 70387, 70386, 70384, 70393, + 70385, 70392, 128143, 128535, 128537, 128538, 128573, 128139, 129373, + 8365, 128088, 129665, 129486, 129698, 12927, 128040, 11235, 129404, + 127991, 129357, 128030, 129692, 3805, 3804, 983206, 983207, 3743, 3741, + 3807, 3806, 3714, 3716, 3713, 983209, 3747, 3749, 3730, 3729, 3736, 3728, + 3727, 3731, 3726, 3744, 3721, 3718, 3724, 3756, 3740, 3742, 3739, 3752, + 3753, 3754, 3722, 3734, 3735, 3733, 3755, 3758, 3719, 3725, 3737, 3738, + 3720, 3732, 3745, 983208, 3751, 3746, 3757, 3773, 3772, 3770, 3785, 3786, + 3787, 3784, 3760, 3762, 3780, 3763, 3779, 3761, 3771, 3766, 3767, 3768, + 3769, 3776, 3777, 3764, 3765, 3778, 3782, 3790, 3759, 3797, 3796, 3799, + 3798, 3795, 3794, 3792, 3801, 3793, 3800, 3788, 3789, 128996, 129003, + 128309, 128311, 128998, 128994, 129001, 68413, 68415, 128992, 128310, + 128999, 68412, 68414, 11004, 10201, 10200, 10782, 128995, 129002, 128308, + 128997, 128993, 129000, 9711, 10923, 10925, 8382, 9790, 127772, 127767, + 65, 258, 7858, 7856, 7854, 7862, 7860, 550, 480, 7840, 512, 196, 478, + 197, 506, 7680, 256, 983564, 194, 7848, 7846, 7844, 7852, 7850, 461, + 7842, 260, 983590, 983592, 192, 193, 514, 195, 570, 198, 508, 482, 42946, + 11373, 393, 42808, 42810, 42802, 42804, 42806, 42812, 66, 386, 42902, + 7686, 7684, 7682, 385, 579, 42822, 42932, 67, 199, 7688, 264, 268, 262, + 42948, 391, 42898, 266, 571, 42960, 42796, 42798, 42862, 42931, 68, 498, + 453, 42951, 272, 7696, 7698, 270, 395, 7694, 7692, 7690, 394, 497, 452, + 69, 552, 7708, 202, 983586, 7874, 7872, 7870, 983584, 7878, 7876, 7704, + 282, 278, 983598, 983600, 7864, 516, 203, 7868, 7706, 274, 7700, 7702, + 983570, 983572, 983574, 7866, 280, 983594, 983596, 200, 201, 518, 276, + 582, 439, 494, 440, 42786, 42788, 42858, 208, 425, 330, 70, 401, 7710, + 42904, 71, 290, 284, 486, 500, 286, 7712, 42912, 403, 288, 484, 577, + 42938, 42940, 42942, 404, 983199, 72, 7722, 7720, 292, 542, 7718, 11367, + 7716, 7714, 42922, 294, 11381, 502, 42790, 73, 520, 7882, 304, 207, 7726, + 206, 463, 298, 983566, 296, 7724, 7880, 302, 983604, 983606, 204, 205, + 522, 300, 407, 42873, 42875, 42877, 42882, 42884, 42886, 406, 42860, 74, + 308, 42930, 983608, 584, 75, 310, 488, 42818, 11369, 7730, 42816, 42820, + 7728, 7732, 42914, 408, 76, 42925, 573, 11360, 7734, 7736, 11362, 319, + 456, 321, 315, 7740, 317, 42824, 313, 7738, 983610, 455, 77, 7742, 7746, + 7744, 983612, 11374, 7930, 7932, 42966, 78, 325, 7754, 327, 459, 544, + 7752, 413, 504, 323, 42896, 7750, 7748, 42916, 209, 458, 79, 42826, + 42828, 332, 7760, 7762, 415, 212, 7892, 7890, 7888, 7896, 7894, 465, 214, + 554, 558, 560, 7884, 524, 336, 490, 492, 216, 510, 213, 7758, 7756, 556, + 983576, 983578, 983580, 416, 7902, 7900, 7898, 7906, 7904, 7886, 210, + 211, 526, 334, 42944, 400, 390, 42934, 418, 42830, 546, 80, 42834, 11363, + 42832, 42836, 7764, 420, 7766, 81, 42840, 42838, 82, 342, 344, 7770, + 7772, 7768, 528, 11364, 983614, 340, 7774, 530, 42918, 588, 42842, 42997, + 42923, 42814, 398, 42844, 83, 352, 7782, 350, 536, 348, 346, 7780, 7778, + 7784, 7776, 42953, 11390, 983582, 42920, 42949, 586, 42926, 42891, 7838, + 42968, 42924, 399, 84, 354, 7792, 538, 356, 574, 7788, 7786, 7790, 430, + 428, 358, 42878, 11375, 11376, 42893, 42928, 42880, 412, 42929, 581, 222, + 42852, 42854, 388, 423, 444, 42794, 42792, 85, 219, 7798, 467, 220, 473, + 475, 471, 469, 7794, 532, 368, 7908, 431, 7916, 7914, 7912, 7920, 7918, + 7910, 362, 7802, 983568, 983620, 983622, 370, 983616, 983618, 360, 7800, + 7796, 217, 218, 534, 364, 366, 42936, 580, 433, 86, 42846, 7806, 7804, + 434, 42850, 42906, 42908, 42910, 42856, 42848, 87, 372, 7812, 7816, 7814, + 7808, 7810, 11378, 503, 88, 7820, 7818, 89, 374, 376, 7924, 7822, 7922, + 435, 7926, 7934, 221, 562, 7928, 590, 540, 90, 7824, 381, 377, 11371, + 7826, 379, 7828, 11391, 437, 42950, 548, 306, 338, 10013, 43007, 43005, + 43006, 43003, 43004, 42999, 450, 7461, 684, 664, 685, 662, 122638, 446, + 426, 674, 451, 122634, 7431, 7430, 7459, 618, 641, 671, 122628, 7436, + 7439, 7440, 630, 7445, 640, 7438, 7449, 43846, 42870, 7451, 11387, + 122626, 122640, 43002, 7450, 665, 7427, 610, 667, 7424, 7425, 7428, 7429, + 42800, 668, 7434, 7435, 7437, 628, 7448, 42927, 42801, 7452, 7456, 7457, + 655, 7458, 663, 122639, 42895, 447, 443, 448, 449, 660, 673, 661, 7460, + 422, 7547, 7550, 97, 259, 7859, 7857, 7855, 7863, 7861, 551, 481, 7841, + 513, 228, 479, 229, 507, 7681, 7834, 7567, 257, 983565, 226, 7849, 7847, + 7845, 7853, 7851, 462, 7843, 261, 983591, 983593, 224, 225, 515, 227, + 11365, 43825, 230, 983624, 509, 483, 42947, 593, 7568, 42809, 42811, + 42803, 42805, 42807, 42813, 98, 387, 42903, 7687, 7532, 7552, 7685, 7683, + 595, 384, 43824, 43827, 629, 43853, 43837, 43838, 43826, 42823, 7447, + 42933, 99, 231, 7689, 265, 597, 269, 263, 42900, 122653, 392, 42899, 267, + 572, 43859, 43860, 43861, 42961, 666, 631, 606, 42797, 42799, 42863, 100, + 42952, 273, 396, 598, 7697, 7699, 545, 271, 122661, 7533, 7695, 599, + 7569, 7553, 7693, 7691, 676, 122642, 122649, 7839, 567, 607, 644, 305, + 42965, 43848, 43850, 42963, 499, 454, 675, 677, 43878, 568, 42865, 101, + 553, 7709, 234, 983587, 7875, 7873, 7871, 983585, 7879, 7877, 7705, 283, + 279, 983599, 983601, 7865, 517, 235, 11384, 7869, 7707, 275, 7701, 7703, + 983571, 983573, 983575, 43828, 7867, 281, 983595, 983597, 232, 233, 519, + 277, 7570, 583, 42787, 42789, 331, 43836, 122644, 643, 122635, 122636, + 7563, 646, 7576, 658, 441, 659, 495, 122648, 7578, 442, 42859, 240, 102, + 7534, 7554, 402, 7711, 42905, 681, 122624, 103, 291, 285, 487, 501, 287, + 7713, 7555, 42913, 608, 289, 485, 578, 42939, 42941, 42943, 611, 983200, + 104, 7723, 7721, 293, 543, 7719, 11368, 7717, 7715, 7830, 42901, 614, + 295, 11382, 983631, 983632, 42791, 615, 405, 105, 238, 464, 239, 7727, + 983602, 983588, 983603, 7883, 521, 299, 983567, 303, 983605, 983607, 297, + 7725, 7881, 236, 237, 523, 301, 616, 122650, 7574, 42874, 42876, 7545, + 42883, 42885, 42887, 43876, 43840, 617, 7548, 43873, 42861, 106, 309, + 669, 496, 983609, 585, 107, 311, 489, 42819, 11370, 7731, 42817, 42821, + 7729, 7733, 7556, 42915, 409, 312, 108, 620, 122643, 410, 316, 7741, 564, + 318, 7735, 7737, 43832, 11361, 619, 43833, 320, 122662, 42825, 314, 7739, + 43831, 621, 42894, 122641, 7557, 983611, 322, 411, 622, 122629, 43829, + 383, 7836, 7835, 7837, 682, 683, 42866, 457, 109, 7743, 43834, 7535, + 7558, 7747, 7745, 983613, 625, 7931, 7933, 42967, 42867, 110, 326, 7755, + 43835, 565, 328, 414, 7753, 626, 122663, 7536, 505, 324, 42897, 7751, + 7749, 7559, 627, 42917, 241, 329, 983589, 42868, 460, 111, 244, 7893, + 7891, 7889, 7897, 7895, 466, 246, 555, 559, 561, 7885, 525, 337, 42827, + 11386, 42829, 333, 7761, 7763, 491, 493, 248, 511, 245, 7759, 7757, 557, + 983577, 983579, 983581, 417, 7903, 7901, 7899, 7907, 7905, 7887, 242, + 243, 527, 335, 122651, 42945, 596, 983625, 983626, 7575, 43839, 43874, + 603, 7571, 42935, 419, 42831, 547, 112, 42835, 7549, 42833, 42837, 7765, + 7537, 7560, 421, 7767, 632, 113, 42841, 672, 587, 42839, 569, 114, 343, + 43849, 345, 7771, 7773, 7769, 529, 638, 7539, 122646, 7775, 636, 637, + 983615, 122664, 7538, 341, 531, 7561, 42919, 589, 43847, 42843, 42998, + 604, 7572, 605, 639, 122625, 600, 122631, 8580, 42815, 122627, 42869, + 42845, 612, 115, 347, 7781, 353, 7783, 351, 537, 349, 122654, 7779, 7785, + 7777, 42954, 575, 983583, 122665, 7540, 7562, 42921, 642, 42892, 43872, + 601, 983629, 983630, 7573, 602, 43851, 43852, 609, 43830, 223, 7441, + 7442, 7443, 7455, 7454, 7453, 42969, 645, 43845, 116, 355, 7793, 539, + 566, 357, 11366, 7831, 7789, 7787, 122666, 7541, 7791, 427, 429, 122633, + 648, 359, 679, 122647, 122652, 7546, 254, 42853, 42855, 389, 424, 445, + 7446, 42795, 397, 613, 686, 687, 7433, 42879, 7444, 43842, 43841, 43843, + 43844, 7432, 633, 43880, 122645, 634, 122632, 11385, 635, 647, 122637, + 652, 983627, 983628, 592, 594, 7426, 623, 624, 654, 122630, 43857, 477, + 7543, 670, 42881, 653, 42871, 680, 678, 43879, 11383, 42793, 117, 649, + 43855, 251, 7799, 468, 252, 474, 476, 472, 470, 7795, 533, 369, 7909, + 432, 7917, 7915, 7913, 7921, 7919, 7911, 363, 7803, 983569, 983621, + 983623, 371, 983617, 983619, 7577, 367, 361, 7801, 7797, 249, 43854, + 42937, 250, 535, 365, 43858, 650, 7551, 7531, 43856, 42872, 43875, 118, + 42847, 7807, 7564, 11380, 11377, 7805, 651, 42851, 42907, 42909, 42911, + 42857, 42849, 119, 373, 7813, 7817, 7815, 7809, 7811, 7832, 11379, 120, + 7821, 7819, 43863, 43864, 43865, 43862, 7565, 121, 375, 255, 7925, 7823, + 7923, 436, 7927, 7935, 43866, 591, 253, 563, 7929, 7833, 541, 122, 378, + 7825, 657, 382, 11372, 7827, 380, 7829, 576, 438, 7542, 7566, 656, 549, + 64256, 64259, 64260, 64257, 64258, 307, 64261, 64262, 339, 8347, 8340, + 8336, 8337, 8341, 7522, 11388, 8342, 8343, 8344, 8345, 8338, 8346, 7523, + 8348, 7524, 7525, 8339, 917505, 127811, 129388, 129897, 129916, 129899, + 129917, 129947, 10203, 10202, 128494, 12296, 10641, 10643, 11058, 11056, + 10576, 10571, 10570, 10574, 12304, 10647, 123, 9128, 9129, 9127, 12300, + 8968, 9948, 10714, 12298, 8220, 11816, 11780, 129287, 129284, 129285, + 129283, 129286, 9686, 11240, 9612, 129977, 129970, 129940, 129932, + 128379, 128709, 11804, 10204, 10197, 9614, 9615, 8596, 8700, 8697, 8622, + 10568, 8660, 10500, 8654, 8621, 11012, 8703, 11020, 129112, 11108, 11788, + 10181, 8907, 9609, 8216, 11814, 128488, 91, 9123, 9121, 10639, 10637, + 8261, 10635, 11863, 11861, 9122, 11778, 10703, 129900, 11785, 129985, + 128492, 9613, 9610, 12308, 8867, 12302, 10627, 12310, 10629, 12314, + 12312, 10712, 128398, 9611, 10620, 8970, 8905, 40, 9117, 9115, 9116, + 11808, 9144, 10553, 10154, 1422, 4054, 4056, 129307, 9958, 10748, 9001, + 171, 128269, 8294, 8237, 8234, 8206, 8592, 10563, 11074, 11083, 11082, + 10611, 129973, 10618, 10615, 11070, 8676, 8633, 10525, 11064, 8698, + 129032, 8619, 10566, 129040, 129024, 8602, 11024, 11025, 8610, 11066, + 11065, 129028, 129176, 129044, 8617, 8695, 8612, 10527, 8646, 10521, + 129192, 129184, 11144, 11013, 10603, 10599, 10590, 10582, 8637, 10594, + 10602, 10598, 10586, 10578, 8636, 8651, 129778, 129088, 129092, 11104, + 11136, 11130, 983241, 11174, 11172, 129064, 129060, 129056, 129072, + 129068, 11120, 11114, 11140, 129168, 10510, 8666, 129186, 11067, 11069, + 11068, 11244, 11061, 11060, 11062, 11063, 8606, 8678, 129172, 8604, 8656, + 10498, 8653, 10502, 10523, 10508, 8672, 129194, 129076, 129188, 8701, + 8647, 129783, 129190, 128620, 8668, 129080, 129104, 129084, 11077, 9804, + 128006, 7213, 7221, 7216, 7220, 7215, 7214, 7217, 7218, 7219, 7170, 7169, + 7168, 7184, 7183, 7182, 7247, 7193, 7180, 7188, 7187, 7186, 7185, 7172, + 7171, 7198, 7197, 7190, 7189, 7173, 7177, 7181, 7192, 7191, 7246, 7245, + 7179, 7178, 7175, 7174, 7201, 7200, 7176, 7196, 7195, 7199, 7202, 7194, + 7203, 7227, 7231, 7230, 7228, 7229, 7223, 7222, 7205, 7204, 7210, 7211, + 7208, 7209, 7206, 7212, 7207, 7237, 7236, 7239, 7238, 7235, 7234, 7232, + 7241, 7233, 7240, 10897, 10895, 10893, 10899, 10891, 10614, 10889, 10887, + 8922, 8934, 8808, 10918, 10920, 10885, 10877, 10881, 10883, 10879, 8818, + 8804, 8822, 8806, 10873, 10875, 8918, 60, 128210, 127898, 127819, 129461, + 128626, 128955, 128969, 128943, 11212, 128964, 10099, 128648, 10098, + 9617, 128937, 128949, 128978, 128960, 129653, 128910, 10072, 128930, + 128504, 9735, 128498, 128497, 6429, 6404, 6403, 6412, 6430, 6411, 6421, + 6410, 6405, 6415, 6425, 6426, 6427, 6419, 6418, 6407, 6406, 6414, 6413, + 6409, 6408, 6402, 6401, 6417, 6416, 6428, 6423, 6420, 6422, 6424, 6458, + 6457, 6459, 6464, 6449, 6452, 6450, 6448, 6456, 6454, 6453, 6455, 6451, + 6442, 6443, 6441, 6432, 6436, 6438, 6440, 6437, 6439, 6435, 6433, 6434, + 6400, 6468, 6469, 6475, 6474, 6477, 6476, 6473, 6472, 6470, 6479, 6471, + 6478, 13007, 10770, 10771, 10772, 983062, 8232, 983068, 983143, 67143, + 67146, 67151, 67165, 67166, 67167, 67157, 67158, 67159, 67160, 67161, + 67162, 67163, 67164, 67171, 67172, 67173, 67168, 67169, 67170, 67174, + 67175, 67176, 67177, 67178, 67179, 67230, 67231, 67180, 67181, 67182, + 67183, 67184, 67185, 67186, 67187, 67188, 67189, 67190, 67191, 67192, + 67193, 67194, 67195, 67196, 67197, 67198, 67199, 67200, 67201, 67202, + 67203, 67204, 67205, 67206, 67207, 67208, 67209, 67210, 67211, 67212, + 67213, 67214, 67215, 67216, 67217, 67218, 67219, 67220, 67221, 67222, + 67223, 67224, 67225, 67226, 67227, 67228, 67229, 67232, 67233, 67234, + 67235, 67236, 67237, 67238, 67239, 67240, 67241, 67242, 67243, 67244, + 67245, 67246, 67247, 67248, 67249, 67250, 67251, 67252, 67253, 67254, + 67255, 67256, 67257, 67258, 67259, 67260, 67261, 67262, 67263, 67264, + 67274, 67275, 67276, 67277, 67278, 67279, 67280, 67281, 67282, 67283, + 67284, 67285, 67286, 67287, 67288, 67289, 67290, 67291, 67292, 67293, + 67294, 67295, 67296, 67297, 67298, 67299, 67300, 67301, 67302, 67303, + 67304, 67265, 67266, 67267, 67268, 67269, 67270, 67271, 67272, 67273, + 67325, 67326, 67327, 67328, 67329, 67330, 67305, 67306, 67307, 67308, + 67309, 67310, 67311, 67312, 67313, 67314, 67315, 67316, 67317, 67318, + 67319, 67320, 67321, 67322, 67323, 67324, 67331, 67332, 67333, 67334, + 67335, 67336, 67337, 67338, 67349, 67350, 67351, 67352, 67353, 67354, + 67355, 67356, 67357, 67358, 67359, 67360, 67361, 67362, 67363, 67364, + 67365, 67366, 67367, 67368, 67378, 67379, 67380, 67381, 67382, 67369, + 67370, 67371, 67372, 67373, 67374, 67375, 67376, 67377, 67339, 67340, + 67341, 67342, 67343, 67344, 67345, 67346, 67347, 67348, 67401, 67404, + 67403, 67402, 67400, 67398, 67393, 67397, 67395, 67394, 67399, 67392, + 67396, 67406, 67408, 67409, 67410, 67407, 67405, 67411, 67413, 67412, + 67424, 67425, 67426, 67427, 67428, 67429, 67430, 67431, 67081, 67082, + 67083, 67084, 67085, 67087, 67088, 67089, 67090, 67091, 67092, 67093, + 67094, 67086, 67095, 67096, 67097, 67098, 67100, 67101, 67102, 67103, + 67104, 67105, 67106, 67107, 67108, 67109, 67110, 67111, 67112, 67113, + 67114, 67115, 67116, 67117, 67118, 67119, 67120, 67121, 67122, 67123, + 67124, 67125, 67126, 67127, 67128, 67129, 67130, 67131, 67132, 67133, + 67134, 67135, 67136, 67137, 67138, 67139, 67140, 67141, 67142, 67072, + 67073, 67074, 67075, 67076, 67077, 67078, 67079, 67080, 67145, 67147, + 67148, 67149, 67150, 67154, 67155, 67144, 67152, 67153, 67156, 67099, + 65667, 65668, 65669, 65670, 65671, 65672, 65673, 65675, 65674, 65677, + 65676, 65665, 65664, 65666, 65681, 65679, 65680, 65682, 65678, 65686, + 65685, 65687, 65693, 65690, 65691, 65692, 65694, 65703, 65696, 65695, + 65697, 65698, 65699, 65701, 65702, 65707, 65706, 65704, 65705, 65708, + 65709, 65710, 65711, 65712, 65713, 65719, 65717, 65714, 65715, 65716, + 65718, 65720, 65721, 65722, 65723, 65724, 65725, 65726, 65727, 65728, + 65729, 65731, 65730, 65732, 65733, 65737, 65734, 65735, 65736, 65738, + 65739, 65740, 65741, 65743, 65742, 65744, 65745, 65747, 65748, 65752, + 65749, 65750, 65751, 65753, 65754, 65755, 65756, 65757, 65779, 65780, + 65781, 65782, 65783, 65784, 65785, 65759, 65760, 65761, 65762, 65763, + 65764, 65765, 65766, 65767, 65768, 65769, 65770, 65771, 65772, 65773, + 65774, 65775, 65776, 65777, 65778, 65758, 65786, 65683, 65684, 65689, + 65688, 65700, 65746, 65561, 65543, 65587, 65582, 65589, 65536, 65541, + 65579, 65566, 65571, 65596, 65569, 65584, 65544, 65559, 65540, 65557, + 65560, 65580, 65606, 65600, 65599, 65577, 65562, 65538, 65573, 65563, + 65609, 65588, 65549, 65568, 65537, 65581, 65574, 65601, 65542, 65593, + 65583, 65594, 65552, 65547, 65605, 65578, 65545, 65585, 65586, 65546, + 65570, 65591, 65564, 65565, 65607, 65610, 65611, 65553, 65590, 65550, + 65539, 65576, 65608, 65551, 65554, 65592, 65603, 65597, 65567, 65572, + 65558, 65555, 65612, 65602, 65556, 65613, 65604, 65620, 65621, 65623, + 65624, 65626, 65627, 65628, 65629, 65622, 65616, 65617, 65619, 65618, + 65625, 128391, 128279, 128482, 128132, 42237, 42235, 42232, 42234, 42236, + 42233, 42206, 42205, 42197, 42196, 42204, 42195, 42228, 42229, 42230, + 42224, 42225, 42213, 42208, 42203, 42202, 42221, 42198, 42216, 42214, + 42200, 42199, 42194, 42193, 42219, 42210, 73648, 42220, 42211, 42212, + 42222, 42223, 42227, 42231, 42192, 42217, 42201, 42209, 42207, 42218, + 42215, 42226, 42238, 42239, 8356, 8374, 129409, 129422, 9806, 128274, + 983079, 983076, 128271, 8743, 10848, 10846, 10833, 10844, 10842, 10847, + 8744, 10841, 10851, 10850, 10834, 10845, 10843, 10982, 10188, 129688, + 10234, 10231, 10206, 10229, 10235, 10232, 10237, 11059, 10230, 10236, + 10233, 10238, 10239, 10205, 129524, 128884, 129719, 128140, 127977, + 128261, 129707, 12319, 8270, 11847, 11848, 95, 9691, 129935, 9604, 9697, + 128394, 129852, 129853, 129870, 129872, 129868, 129856, 129871, 129869, + 129854, 129873, 129855, 128395, 128396, 128393, 10559, 129951, 9722, + 128397, 9695, 10558, 128318, 10065, 129950, 9727, 129863, 129865, 129867, + 129864, 129861, 129866, 129859, 129862, 129860, 129857, 129858, 10195, + 10063, 9998, 9694, 9987, 9605, 9602, 9601, 9607, 9603, 9606, 129903, + 9674, 10208, 129438, 128557, 127853, 129523, 128886, 129729, 66190, + 66192, 66187, 66196, 66178, 66179, 66199, 66185, 66200, 66176, 66201, + 66177, 66202, 66191, 66193, 66181, 66180, 66203, 66182, 66186, 66189, + 66195, 66188, 66197, 66198, 66194, 66183, 66204, 66184, 67887, 67892, + 67881, 67895, 67891, 67886, 67872, 67893, 67876, 67894, 67883, 67896, + 67873, 67897, 67875, 67889, 67874, 67878, 67880, 67882, 67884, 67890, + 67885, 67888, 67877, 67879, 67903, 129317, 983226, 983234, 983224, + 983229, 8468, 129433, 983065, 129668, 129522, 129497, 69986, 69981, + 69991, 70002, 69997, 69985, 69984, 69990, 69989, 69983, 69982, 69988, + 69987, 69995, 69994, 69978, 69977, 69976, 69975, 69980, 69979, 69974, + 69973, 69993, 69992, 70001, 69998, 69996, 70000, 69999, 69968, 69971, + 69969, 69972, 69970, 70006, 70005, 70003, 70004, 127012, 127019, 127008, + 126990, 126999, 126976, 127005, 126987, 126996, 127004, 126986, 126995, + 126979, 127009, 126991, 127000, 127001, 126983, 126992, 127011, 127010, + 126977, 127007, 126989, 126998, 127006, 126988, 126997, 127015, 127014, + 127003, 126985, 126994, 127002, 126984, 126993, 126978, 126982, 127017, + 126981, 126980, 127016, 127018, 127013, 73464, 73442, 73451, 73448, + 73444, 73449, 73447, 73441, 73450, 73440, 73454, 73445, 73443, 73453, + 73456, 73446, 73455, 73452, 73457, 73463, 73461, 73459, 73462, 73460, + 73458, 128892, 3415, 3449, 3435, 3434, 3437, 3436, 3433, 3432, 3430, + 3439, 3431, 3438, 3419, 3420, 3446, 3417, 3422, 3416, 3447, 3444, 3443, + 3448, 3418, 3421, 3445, 3333, 3423, 3334, 3344, 3348, 3453, 3454, 3414, + 3451, 3450, 3452, 3455, 3412, 3413, 3355, 3354, 3406, 3362, 3361, 3367, + 3366, 3360, 3386, 3359, 3365, 3364, 3332, 3339, 3424, 3340, 3425, 3381, + 3369, 3363, 3353, 3358, 3368, 3380, 3379, 3378, 3377, 3376, 3337, 3338, + 3346, 3347, 3335, 3336, 3382, 3383, 3384, 3373, 3372, 3352, 3351, 3357, + 3356, 3350, 3349, 3371, 3370, 3342, 3343, 3385, 3374, 3375, 3441, 3442, + 3440, 3328, 3388, 3329, 3387, 3405, 3331, 3389, 3330, 3407, 3390, 3400, + 3404, 3395, 3396, 3426, 3427, 3393, 3394, 3402, 3403, 3391, 3392, 3398, + 3399, 9895, 9894, 9893, 9794, 10016, 129443, 128104, 128372, 129333, + 128114, 128115, 128378, 128107, 2122, 2121, 2133, 2120, 2126, 2132, 2129, + 2136, 2113, 2115, 2114, 2116, 2123, 2124, 2125, 2128, 2130, 2131, 2118, + 2134, 2117, 2112, 2127, 2119, 2135, 2139, 2138, 2142, 2137, 68288, 68314, + 68313, 68290, 68289, 68293, 68308, 68292, 68291, 68300, 68299, 68298, + 68297, 68306, 68304, 68320, 68318, 68323, 68312, 68317, 68322, 68309, + 68302, 68324, 68305, 68319, 68307, 68321, 68303, 68294, 68301, 68311, + 68295, 68316, 68315, 68310, 68331, 68335, 68334, 68333, 68332, 68340, + 68339, 68338, 68342, 68337, 68341, 68336, 68296, 68326, 68325, 128094, + 129469, 8380, 128368, 129389, 9967, 127809, 129671, 72835, 72834, 72827, + 72826, 72836, 72828, 72821, 72825, 72829, 72823, 72822, 72819, 72818, + 72831, 72830, 72844, 72845, 72838, 72839, 72840, 72832, 72820, 72846, + 72824, 72843, 72833, 72842, 72837, 72841, 72847, 72886, 72885, 72867, + 72866, 72859, 72858, 72868, 72860, 72853, 72857, 72861, 72855, 72854, + 72851, 72850, 72863, 72862, 72876, 72877, 72870, 72871, 72864, 72852, + 72878, 72856, 72875, 72865, 72874, 72869, 72873, 72879, 72880, 72883, + 72881, 72884, 72882, 72816, 72817, 9901, 129355, 73007, 72980, 72979, + 72983, 72982, 72988, 73008, 72987, 72960, 72961, 72968, 72971, 72985, + 72984, 72990, 72989, 72964, 72965, 72962, 72963, 73005, 72999, 73006, + 72973, 72972, 72976, 72986, 72981, 72991, 73001, 73002, 73003, 72995, + 72994, 72978, 72977, 72975, 72974, 72993, 72992, 73004, 72996, 72998, + 73000, 72997, 72966, 72969, 73031, 73030, 73027, 73028, 73026, 73025, + 73024, 73014, 73009, 73020, 73023, 73012, 73013, 73010, 73011, 73018, + 73021, 73029, 73045, 73044, 73047, 73046, 73043, 73042, 73040, 73049, + 73041, 73048, 186, 127405, 12348, 119811, 120778, 120491, 119827, 120495, + 120505, 120507, 119808, 120488, 119809, 120489, 119833, 120493, 119812, + 120492, 120494, 119814, 120490, 119816, 120496, 119818, 120497, 119819, + 120498, 119822, 120502, 120512, 119823, 120509, 120511, 120503, 119825, + 120504, 119826, 120506, 119828, 120508, 119810, 120510, 119820, 120499, + 119821, 120500, 119831, 120501, 119813, 119815, 119817, 119824, 119829, + 119830, 119832, 119837, 120779, 120517, 119834, 120514, 119835, 120515, + 119859, 120519, 119838, 120518, 120520, 119839, 120531, 119840, 120516, + 119842, 120522, 119844, 120523, 119845, 120524, 119848, 120528, 120538, + 119849, 120535, 120537, 120529, 119851, 120530, 119852, 120532, 119853, + 120521, 120533, 119854, 120534, 119836, 120536, 119846, 120525, 119847, + 120526, 119857, 120527, 119841, 119843, 119850, 119855, 119856, 119858, + 120016, 120017, 120018, 120019, 120020, 120021, 120022, 120023, 120024, + 120025, 120026, 120027, 120028, 120029, 120030, 120031, 120032, 120033, + 120034, 120035, 120036, 120037, 120038, 120039, 120040, 120041, 120042, + 120043, 120044, 120045, 120046, 120047, 120048, 120049, 120050, 120051, + 120052, 120053, 120054, 120055, 120056, 120057, 120058, 120059, 120060, + 120061, 120062, 120063, 120064, 120065, 120066, 120067, 119931, 120611, + 120621, 120623, 119912, 120604, 119913, 120605, 119937, 120609, 119915, + 120607, 119916, 120608, 120610, 119918, 120606, 119920, 120612, 119922, + 120613, 119923, 120614, 119926, 120618, 120628, 119927, 120625, 120627, + 120619, 119929, 120620, 119930, 120622, 119932, 120624, 119914, 120626, + 119924, 120615, 119925, 120616, 119935, 120617, 119917, 119919, 119921, + 119928, 119933, 119934, 119936, 120656, 120658, 120629, 120659, 120655, + 120661, 120660, 119938, 120630, 119939, 120631, 119963, 120635, 119941, + 120633, 119942, 120634, 120636, 119943, 120647, 119944, 120632, 119946, + 120638, 119948, 120639, 119949, 120640, 119952, 120644, 120654, 119953, + 120651, 120653, 120645, 119955, 120646, 119956, 120648, 119957, 120637, + 120649, 119958, 120650, 119940, 120652, 119950, 120641, 119951, 120642, + 119961, 120643, 119945, 119947, 119954, 119959, 119960, 119962, 120657, + 120540, 120542, 120513, 120543, 120539, 120545, 120544, 120541, 120172, + 120173, 120174, 120175, 120176, 120177, 120178, 120179, 120180, 120181, + 120182, 120183, 120184, 120185, 120186, 120187, 120188, 120189, 120190, + 120191, 120192, 120193, 120194, 120195, 120196, 120197, 120198, 120199, + 120200, 120201, 120202, 120203, 120204, 120205, 120206, 120207, 120208, + 120209, 120210, 120211, 120212, 120213, 120214, 120215, 120216, 120217, + 120218, 120219, 120220, 120221, 120222, 120223, 120787, 120786, 120789, + 120788, 120785, 120784, 120782, 120791, 120783, 120790, 120120, 120121, + 120123, 120124, 120125, 120126, 120128, 120129, 120130, 120131, 120132, + 120134, 120138, 120139, 120140, 120141, 120142, 120143, 120144, 120146, + 120147, 120148, 120149, 120150, 120151, 120152, 120153, 120154, 120155, + 120156, 120157, 120158, 120159, 120160, 120161, 120162, 120163, 120164, + 120165, 120166, 120167, 120168, 120169, 120170, 120171, 120797, 120796, + 120799, 120798, 120795, 120794, 120792, 120801, 120793, 120800, 120068, + 120069, 120071, 120072, 120073, 120074, 120077, 120078, 120079, 120080, + 120081, 120082, 120083, 120084, 120086, 120087, 120088, 120089, 120090, + 120091, 120092, 120094, 120095, 120096, 120097, 120098, 120099, 120100, + 120101, 120102, 120103, 120104, 120105, 120106, 120107, 120108, 120109, + 120110, 120111, 120112, 120113, 120114, 120115, 120116, 120117, 120118, + 120119, 10189, 119889, 120484, 120485, 120575, 119886, 120572, 119887, + 120573, 119911, 120577, 119890, 120576, 120578, 119891, 120589, 119892, + 120574, 119894, 120580, 119896, 120581, 119897, 120582, 119900, 120586, + 120596, 119901, 120593, 120595, 120587, 119903, 120588, 119904, 120590, + 119905, 120579, 120591, 119906, 120592, 119888, 120594, 119898, 120583, + 119899, 120584, 119909, 120585, 119895, 119902, 119907, 119908, 119910, + 119879, 120553, 120563, 120565, 119860, 120546, 119861, 120547, 119885, + 120551, 119863, 120549, 119864, 120550, 120552, 119866, 120548, 119868, + 120554, 119870, 120555, 119871, 120556, 119874, 120560, 120570, 119875, + 120567, 120569, 120561, 119877, 120562, 119878, 120564, 119880, 120566, + 119862, 120568, 119872, 120557, 119873, 120558, 119883, 120559, 119865, + 119867, 119869, 119876, 119881, 119882, 119884, 120598, 120600, 120571, + 120601, 120597, 120603, 120602, 120599, 120432, 120433, 120434, 120435, + 120436, 120437, 120438, 120439, 120440, 120441, 120442, 120443, 120444, + 120445, 120446, 120447, 120448, 120449, 120450, 120451, 120452, 120453, + 120454, 120455, 120456, 120457, 120458, 120459, 120460, 120461, 120462, + 120463, 120464, 120465, 120466, 120467, 120468, 120469, 120470, 120471, + 120472, 120473, 120474, 120475, 120476, 120477, 120478, 120479, 120480, + 120481, 120482, 120483, 120827, 120826, 120829, 120828, 120825, 120824, + 120822, 120831, 120823, 120830, 10215, 10221, 10219, 10217, 10223, 10187, + 10214, 10220, 10218, 10216, 10222, 120399, 120727, 120737, 120739, + 120380, 120720, 120381, 120721, 120405, 120725, 120383, 120723, 120384, + 120724, 120726, 120386, 120722, 120388, 120728, 120390, 120729, 120391, + 120730, 120394, 120734, 120744, 120395, 120741, 120743, 120735, 120397, + 120736, 120398, 120738, 120400, 120740, 120382, 120742, 120392, 120731, + 120393, 120732, 120403, 120733, 120385, 120387, 120389, 120396, 120401, + 120402, 120404, 120772, 120774, 120745, 120775, 120771, 120777, 120776, + 120406, 120746, 120407, 120747, 120431, 120751, 120409, 120749, 120410, + 120750, 120752, 120411, 120763, 120412, 120748, 120414, 120754, 120416, + 120755, 120417, 120756, 120420, 120760, 120770, 120421, 120767, 120769, + 120761, 120423, 120762, 120424, 120764, 120425, 120753, 120765, 120426, + 120766, 120408, 120768, 120418, 120757, 120419, 120758, 120429, 120759, + 120413, 120415, 120422, 120427, 120428, 120430, 120773, 120295, 120669, + 120679, 120681, 120276, 120662, 120277, 120663, 120301, 120667, 120279, + 120665, 120280, 120666, 120668, 120282, 120664, 120284, 120670, 120286, + 120671, 120287, 120672, 120290, 120676, 120686, 120291, 120683, 120685, + 120677, 120293, 120678, 120294, 120680, 120296, 120682, 120278, 120684, + 120288, 120673, 120289, 120674, 120299, 120675, 120281, 120283, 120285, + 120292, 120297, 120298, 120300, 120714, 120716, 120687, 120717, 120713, + 120719, 120718, 120302, 120688, 120303, 120689, 120327, 120693, 120305, + 120691, 120306, 120692, 120694, 120307, 120705, 120308, 120690, 120310, + 120696, 120312, 120697, 120313, 120698, 120316, 120702, 120712, 120317, + 120709, 120711, 120703, 120319, 120704, 120320, 120706, 120321, 120695, + 120707, 120322, 120708, 120304, 120710, 120314, 120699, 120315, 120700, + 120325, 120701, 120309, 120311, 120318, 120323, 120324, 120326, 120715, + 120817, 120816, 120819, 120818, 120815, 120814, 120812, 120821, 120813, + 120820, 120328, 120329, 120330, 120331, 120332, 120333, 120334, 120335, + 120336, 120337, 120338, 120339, 120340, 120341, 120342, 120343, 120344, + 120345, 120346, 120347, 120348, 120349, 120350, 120351, 120352, 120353, + 120354, 120355, 120356, 120357, 120358, 120359, 120360, 120361, 120362, + 120363, 120364, 120365, 120366, 120367, 120368, 120369, 120370, 120371, + 120372, 120373, 120374, 120375, 120376, 120377, 120378, 120379, 120224, + 120225, 120226, 120227, 120228, 120229, 120230, 120231, 120232, 120233, + 120234, 120235, 120236, 120237, 120238, 120239, 120240, 120241, 120242, + 120243, 120244, 120245, 120246, 120247, 120248, 120249, 120250, 120251, + 120252, 120253, 120254, 120255, 120256, 120257, 120258, 120259, 120260, + 120261, 120262, 120263, 120264, 120265, 120266, 120267, 120268, 120269, + 120270, 120271, 120272, 120273, 120274, 120275, 120807, 120806, 120809, + 120808, 120805, 120804, 120802, 120811, 120803, 120810, 119964, 119966, + 119967, 119970, 119973, 119974, 119977, 119978, 119979, 119980, 119982, + 119983, 119984, 119985, 119986, 119987, 119988, 119989, 119990, 119991, + 119992, 119993, 119995, 119997, 119998, 119999, 120000, 120001, 120002, + 120003, 120005, 120006, 120007, 120008, 120009, 120010, 120011, 120012, + 120013, 120014, 120015, 129481, 119528, 119538, 119531, 119535, 119525, + 119524, 119534, 119529, 119539, 119527, 119537, 119526, 119536, 119533, + 119523, 119532, 119522, 119530, 119520, 119521, 128470, 175, 8737, 10667, + 10666, 10671, 10669, 10670, 10668, 10665, 10664, 10651, 10653, 8798, + 127830, 129470, 129471, 93773, 93764, 93790, 93787, 983268, 93783, + 983267, 93782, 93772, 93766, 93791, 93779, 93789, 93786, 93776, 93777, + 93785, 93775, 93770, 93769, 93771, 93774, 93780, 93760, 93767, 93781, + 93788, 93761, 93768, 93778, 93762, 93763, 93784, 93765, 93847, 93827, + 93846, 93826, 93845, 93825, 93844, 93829, 93828, 93831, 93830, 93824, + 93833, 93832, 93837, 93836, 93834, 93842, 93835, 93838, 93839, 93843, + 93840, 93841, 93805, 93796, 93822, 93819, 983270, 93815, 983269, 93814, + 93804, 93798, 93823, 93811, 93821, 93818, 93808, 93809, 93817, 93807, + 93802, 93801, 93803, 93806, 93812, 93792, 93799, 93813, 93820, 93793, + 93800, 93810, 93794, 93795, 93816, 93797, 93849, 93850, 93848, 11859, + 11852, 11860, 128901, 9899, 10090, 10091, 128967, 128965, 128944, 10100, + 10088, 10092, 10101, 10089, 10093, 8287, 9900, 9618, 128971, 128950, + 128938, 128963, 128961, 10073, 128974, 128956, 9898, 128911, 128931, + 43761, 44013, 43762, 43760, 44011, 43994, 43989, 43974, 43746, 43993, + 43991, 43751, 43750, 43992, 43986, 43987, 43990, 43968, 43995, 43976, + 43973, 43999, 43977, 44001, 43752, 43747, 43972, 43998, 43984, 43969, + 43753, 43754, 43975, 44000, 43978, 43749, 43748, 43983, 44002, 43970, + 43996, 43971, 43997, 43981, 43988, 43979, 43985, 43980, 43982, 43744, + 43745, 44012, 43763, 43764, 44005, 43757, 43759, 43758, 44009, 44003, + 44007, 44006, 44004, 43755, 44008, 43756, 44010, 43765, 43766, 44021, + 44020, 44023, 44022, 44019, 44018, 44016, 44025, 44017, 44024, 129760, + 127816, 125140, 125137, 125136, 125139, 125141, 125138, 125142, 124928, + 124929, 124930, 124936, 124937, 124949, 124950, 124948, 124938, 124956, + 124990, 124992, 124974, 124955, 124964, 124963, 124991, 124957, 124962, + 124976, 124996, 124997, 124998, 124982, 124983, 124984, 125004, 124975, + 125003, 125005, 125011, 125018, 125028, 125029, 125012, 125019, 125020, + 125027, 125013, 125035, 125048, 124942, 124934, 125090, 125046, 125078, + 125033, 124946, 125037, 125070, 125000, 125095, 125121, 124951, 125044, + 125041, 125072, 124987, 125066, 125076, 125074, 125009, 125107, 124945, + 125108, 125068, 125124, 125002, 124931, 125089, 125022, 125119, 124980, + 124986, 125080, 125099, 125100, 124933, 125021, 125015, 125071, 124985, + 125117, 125056, 124993, 125039, 125049, 125043, 125024, 124932, 125047, + 125097, 124959, 125069, 125088, 124999, 125123, 124952, 125036, 125026, + 125001, 125057, 125085, 124960, 125073, 124966, 125098, 125014, 125091, + 124989, 125007, 124978, 124940, 125106, 125050, 125030, 125092, 124941, + 125060, 125077, 125102, 125094, 125053, 125103, 125040, 125055, 125104, + 124939, 125017, 125112, 124961, 125087, 124970, 124971, 124969, 125023, + 124979, 125042, 124947, 125075, 125051, 125111, 125086, 124968, 124944, + 125038, 125096, 125016, 125118, 125109, 124953, 125059, 125052, 125006, + 124958, 125093, 125115, 125054, 124988, 125008, 125084, 125061, 125064, + 125120, 125063, 124967, 124977, 124965, 125031, 125081, 125082, 125010, + 125067, 124973, 125032, 124935, 125116, 125122, 125101, 124994, 124995, + 125113, 125058, 125079, 125114, 125065, 125034, 125083, 124954, 125062, + 125105, 125110, 125045, 124943, 124972, 124981, 125025, 125131, 125130, + 125133, 125132, 125129, 125128, 125135, 125127, 125134, 128334, 128697, + 68028, 68093, 68090, 68089, 68086, 68029, 68092, 68091, 68095, 68088, + 68087, 68094, 68000, 68016, 68020, 68021, 68022, 68009, 68010, 68015, + 68017, 68014, 68013, 68018, 68006, 68023, 68012, 68008, 68007, 68019, + 68011, 68005, 68004, 68001, 68002, 68003, 68031, 68030, 68039, 68075, + 68057, 68084, 68066, 68036, 68054, 68081, 68063, 68045, 68072, 68035, + 68053, 68080, 68062, 68044, 68071, 68040, 68076, 68058, 68085, 68067, + 68038, 68056, 68083, 68065, 68047, 68074, 68037, 68055, 68082, 68064, + 68046, 68073, 68034, 68052, 68079, 68061, 68043, 68070, 68033, 68051, + 68078, 68060, 68042, 68069, 68041, 68068, 68032, 68050, 68077, 68059, + 67974, 67975, 67982, 67983, 67978, 67979, 67980, 67981, 67987, 67988, + 67989, 67992, 67993, 67994, 67995, 67996, 67986, 67985, 67990, 67997, + 67984, 67977, 67976, 67991, 67973, 67972, 67968, 67969, 67970, 67971, + 67998, 67999, 129500, 9791, 983173, 9170, 9172, 9177, 9176, 9175, 9173, + 9174, 9171, 9169, 128647, 128221, 94015, 93989, 93971, 93958, 94019, + 94021, 93953, 94023, 93999, 93995, 94008, 93981, 93979, 93967, 93963, + 93993, 93992, 93983, 93977, 93976, 93975, 93974, 93968, 94032, 93988, + 93987, 93973, 93972, 93997, 93996, 93969, 94106, 94107, 94108, 94109, + 94110, 94111, 94002, 94026, 94022, 94003, 94004, 94010, 93980, 93978, + 94099, 94100, 94101, 94102, 94103, 94104, 94105, 93998, 93994, 94007, + 94025, 93966, 93962, 94024, 93961, 93960, 94000, 94009, 93964, 93965, + 94001, 93970, 93984, 93954, 94017, 94014, 94016, 94013, 94006, 94012, + 94005, 94011, 93986, 93985, 93955, 93952, 94020, 93990, 93957, 93956, + 93959, 93982, 94018, 93991, 94035, 94034, 94033, 94031, 94098, 94096, + 94097, 94095, 94036, 94039, 94040, 94067, 94068, 94038, 94037, 94073, + 94075, 94045, 94071, 94069, 94046, 94047, 94085, 94074, 94049, 94050, + 94051, 94052, 94053, 94086, 94057, 94054, 94084, 94055, 94056, 94041, + 94082, 94048, 94081, 94042, 94076, 94058, 94059, 94060, 94061, 94063, + 94064, 94079, 94087, 94062, 94065, 94080, 94066, 94072, 94070, 94044, + 94043, 94077, 94078, 94083, 983239, 983240, 128300, 127908, 181, 129440, + 129986, 183, 8943, 129686, 127894, 127756, 8357, 128189, 128469, 128656, + 8722, 10793, 10794, 10796, 10795, 10810, 8770, 8723, 10751, 129694, + 129705, 128241, 128242, 128244, 129339, 8871, 71232, 71229, 71236, 71231, + 71230, 71216, 71226, 71228, 71221, 71222, 71223, 71224, 71219, 71220, + 71217, 71218, 71225, 71227, 71234, 71233, 71253, 71252, 71255, 71254, + 71251, 71250, 71248, 71257, 71249, 71256, 71168, 71169, 71179, 71181, + 71195, 71194, 71200, 71199, 71193, 71192, 71198, 71197, 71174, 71175, + 71176, 71177, 71210, 71172, 71173, 71170, 71171, 71215, 71209, 71186, + 71196, 71191, 71201, 71211, 71212, 71213, 71205, 71204, 71188, 71187, + 71185, 71184, 71190, 71189, 71183, 71182, 71203, 71202, 71214, 71206, + 71208, 71207, 71178, 71180, 71235, 43867, 67512, 714, 700, 67509, 761, + 763, 7470, 7471, 7487, 7474, 7483, 7476, 43000, 7484, 7485, 7468, 7469, + 42994, 7472, 7473, 42995, 7475, 7477, 7478, 7479, 7480, 7481, 7482, 7486, + 42996, 7488, 7489, 11389, 7490, 723, 722, 42755, 42753, 42757, 42759, + 42754, 42752, 42756, 42758, 42652, 122956, 122958, 122929, 122954, + 122932, 122952, 122943, 122987, 122946, 122938, 122939, 122942, 122960, + 122941, 122959, 122989, 122955, 122950, 122948, 122944, 122951, 122988, + 122953, 122934, 122935, 122936, 122933, 122949, 122931, 122957, 122930, + 122947, 122937, 122928, 122940, 122945, 42653, 7544, 710, 735, 42889, + 67510, 42776, 42777, 42775, 750, 698, 725, 709, 984011, 42765, 42760, + 42770, 741, 984012, 42769, 42764, 42774, 745, 762, 764, 715, 704, 67507, + 4348, 42766, 42761, 42771, 742, 721, 67511, 42888, 42768, 42763, 751, + 767, 753, 42773, 717, 754, 755, 744, 759, 719, 718, 42783, 752, 716, + 42778, 703, 43882, 706, 713, 42767, 42762, 42772, 743, 758, 757, 756, + 727, 766, 726, 697, 42780, 42782, 42781, 42779, 760, 705, 67508, 701, + 67513, 702, 43883, 707, 734, 42890, 765, 7491, 7493, 7516, 67459, 7495, + 7601, 7509, 67461, 7517, 7580, 7590, 694, 7591, 67474, 67476, 7595, + 67484, 67491, 67456, 67460, 67478, 7600, 67498, 7608, 67506, 67471, + 67492, 7581, 7521, 7496, 67468, 67469, 67467, 67466, 7519, 7585, 67480, + 67463, 67465, 67464, 7611, 7613, 7612, 7497, 7604, 7582, 7614, 7505, + 7584, 67472, 7501, 7518, 7520, 67475, 736, 688, 689, 67477, 43868, 67479, + 7504, 7596, 7588, 7589, 690, 7592, 737, 43869, 43870, 7593, 67485, 7594, + 67483, 67481, 67482, 67486, 67487, 43001, 7599, 7598, 7506, 67490, 7499, + 7507, 7510, 7602, 691, 67497, 67496, 67473, 740, 7583, 67470, 738, 67514, + 7603, 7586, 7498, 7513, 7511, 7605, 67503, 67499, 67502, 7508, 67500, + 67501, 7492, 7579, 7494, 7514, 7597, 7500, 692, 67494, 67495, 693, 67488, + 67489, 7587, 7502, 7610, 43881, 7615, 7512, 43871, 7606, 7607, 7515, + 67504, 7609, 7503, 67493, 695, 739, 696, 42784, 42785, 67458, 67457, 720, + 699, 724, 708, 749, 42864, 748, 712, 747, 746, 10762, 128184, 128176, + 129297, 71266, 6165, 6164, 6167, 6166, 6163, 6162, 6160, 6169, 6161, + 6168, 6159, 6157, 6156, 6155, 6147, 6149, 71271, 71272, 6176, 6279, 6272, + 6295, 6273, 6289, 6274, 6313, 6286, 6311, 6310, 6280, 6276, 6275, 6282, + 6287, 6278, 6285, 6284, 6288, 6277, 6291, 6290, 6293, 6294, 6292, 6283, + 6281, 6185, 6196, 6264, 6210, 6190, 6303, 6305, 6307, 6300, 6302, 6304, + 6312, 6298, 6301, 6314, 6308, 6309, 6299, 6306, 6263, 6262, 6260, 6261, + 6259, 6254, 6248, 6244, 6252, 6245, 6253, 6238, 6239, 6257, 6247, 6256, + 6242, 6258, 6255, 6241, 6240, 6249, 6251, 6250, 6243, 6246, 6237, 6193, + 6192, 6297, 6296, 6218, 6236, 6225, 6234, 6227, 6235, 6211, 6228, 6224, + 6222, 6232, 6226, 6233, 6214, 6216, 6215, 6217, 6219, 6231, 6223, 6220, + 6221, 6230, 6229, 6212, 6213, 6204, 6194, 6209, 6207, 6205, 6206, 6203, + 6202, 6208, 6191, 6177, 6183, 6179, 6181, 6180, 6182, 6186, 6195, 6201, + 6189, 6197, 6184, 6187, 6188, 6199, 6200, 6198, 6178, 71273, 71275, + 71274, 6151, 71265, 71270, 71269, 6144, 71268, 71264, 71267, 71276, 6150, + 6158, 6148, 6146, 6152, 6153, 6154, 6145, 9866, 9867, 119552, 9101, + 128669, 128018, 128053, 127889, 129390, 128496, 129742, 129439, 128332, + 129334, 128741, 128757, 129468, 128739, 9968, 128670, 128672, 128693, + 128507, 128001, 129700, 128045, 128068, 128511, 127909, 92748, 92744, + 92761, 92750, 92739, 92751, 92737, 92754, 92749, 92753, 92743, 92752, + 92757, 92766, 92736, 92741, 92746, 92764, 92745, 92765, 92755, 92760, + 92758, 92756, 92763, 92762, 92747, 92738, 92740, 92759, 92742, 92783, + 92782, 92773, 92772, 92775, 92774, 92771, 92770, 92768, 92777, 92769, + 92776, 70291, 70292, 70290, 70297, 70296, 70293, 70287, 70298, 70312, + 70311, 70306, 70285, 70284, 70289, 70288, 70295, 70294, 70303, 70301, + 70283, 70282, 70280, 70278, 70277, 70276, 70300, 70299, 70310, 70307, + 70304, 70309, 70308, 70305, 70272, 70275, 70273, 70274, 70313, 127926, + 215, 10804, 10805, 10807, 10811, 10801, 10800, 10005, 8844, 8845, 8846, + 8888, 9838, 9837, 9839, 127929, 127896, 119161, 119159, 119155, 119157, + 119061, 119060, 119224, 119235, 119132, 119058, 119059, 119255, 119253, + 119130, 119131, 119163, 119169, 119149, 119167, 119168, 119210, 119178, + 119173, 119211, 119150, 119151, 119152, 119153, 119154, 119175, 119212, + 119213, 119166, 119164, 119141, 119142, 119176, 119179, 119143, 119144, + 119145, 119165, 119177, 119170, 119174, 119092, 119052, 119247, 119186, + 119073, 119109, 119093, 119050, 119220, 119221, 119044, 119049, 119187, + 119209, 119082, 119041, 119083, 119077, 119078, 119162, 119160, 119208, + 119156, 119158, 119136, 119102, 119056, 119057, 119146, 119147, 119148, + 119042, 119066, 119065, 119069, 119185, 119074, 119075, 119076, 119231, + 119232, 119085, 119084, 119070, 119071, 119072, 119218, 119217, 119189, + 119188, 119248, 119249, 119172, 119171, 119216, 119134, 119100, 119206, + 119262, 119270, 119271, 119263, 119268, 119269, 119272, 119264, 119267, + 119266, 119265, 119274, 119223, 119234, 119233, 119046, 119222, 119184, + 119227, 119237, 119228, 119122, 119123, 119081, 119098, 119207, 119129, + 119087, 119086, 119128, 119140, 119106, 119062, 119195, 119204, 119205, + 119196, 119197, 119198, 119199, 119200, 119201, 119202, 119203, 119094, + 119095, 119126, 119108, 119215, 119214, 119261, 119252, 119257, 119258, + 119183, 119090, 119091, 119135, 119101, 119096, 119097, 119053, 119054, + 119055, 119048, 119043, 119047, 119180, 119254, 119259, 119225, 119236, + 119226, 119229, 119238, 119230, 119051, 119045, 119089, 119088, 119040, + 119067, 119068, 119137, 119103, 119139, 119105, 119110, 119111, 119250, + 119181, 119273, 119243, 119244, 119245, 119246, 119242, 119240, 119239, + 119241, 119064, 119138, 119104, 119063, 119256, 119260, 119190, 119118, + 119119, 119120, 119121, 119112, 119113, 119116, 119117, 119114, 119115, + 119124, 119125, 119191, 119193, 119194, 119127, 119251, 119107, 119133, + 119099, 119219, 119192, 119182, 127932, 127925, 127812, 8811, 8810, 4158, + 4156, 4157, 4155, 4192, 4191, 4190, 4226, 4129, 43642, 4138, 4135, 4208, + 4207, 4206, 4159, 4099, 4098, 4097, 43625, 43624, 43626, 43623, 43622, + 43621, 43627, 43618, 43617, 43630, 43629, 43620, 43619, 983244, 43631, + 43616, 43635, 43628, 43633, 43634, 4096, 4188, 4189, 4187, 4186, 4136, + 4121, 4106, 4111, 4100, 4105, 4116, 4238, 4123, 4176, 43491, 4218, 4220, + 43490, 4221, 4224, 43492, 4223, 43489, 4216, 43488, 4215, 4214, 4213, + 4219, 4222, 4225, 4217, 4130, 43646, 43647, 4193, 4177, 4126, 4112, + 43503, 43495, 43502, 43501, 43516, 43515, 43518, 43517, 43498, 43497, + 43500, 43499, 43514, 43496, 4108, 4107, 4113, 4198, 4197, 4125, 4110, + 4109, 4115, 4114, 4178, 4179, 4180, 4181, 4133, 4134, 4131, 4132, 4128, + 4124, 4120, 4119, 4102, 4101, 4104, 4103, 4118, 4117, 4127, 4122, 4137, + 43636, 43637, 43638, 43632, 43494, 4154, 4150, 4250, 4251, 4237, 4235, + 4236, 4231, 4232, 4233, 4234, 43493, 4171, 43644, 43645, 4201, 4202, + 4203, 4204, 4205, 4151, 4239, 43643, 4170, 4153, 4152, 43639, 43641, + 43640, 4174, 4172, 4255, 4254, 4175, 4173, 4245, 4244, 4247, 4246, 4243, + 4242, 4240, 4249, 4241, 4248, 4195, 4196, 43509, 43508, 43511, 43510, + 43507, 43506, 43504, 43513, 43505, 43512, 4146, 4252, 4253, 4140, 4209, + 4212, 4210, 4211, 4147, 4148, 4194, 4228, 4229, 4230, 4227, 4145, 4149, + 4199, 4200, 4139, 4182, 4183, 4184, 4185, 4143, 4144, 4141, 4142, 4165, + 4164, 4167, 4166, 4163, 4162, 4160, 4169, 4161, 4168, 983218, 983232, + 983174, 10753, 10754, 10752, 8720, 10761, 10757, 10758, 8721, 8899, + 10756, 10755, 11007, 8896, 8897, 8898, 8719, 67712, 67728, 67740, 67724, + 67726, 67714, 67732, 67718, 67730, 67723, 67742, 67717, 67729, 67738, + 67739, 67713, 67735, 67716, 67721, 67734, 67737, 67741, 67725, 67719, + 67722, 67727, 67715, 67733, 67720, 67736, 67731, 67758, 67752, 67753, + 67757, 67751, 67759, 67756, 67754, 67755, 8711, 124117, 124120, 124119, + 124121, 124118, 124132, 124136, 124133, 124138, 124137, 124134, 124135, + 124122, 124124, 124126, 124123, 124125, 124112, 124116, 124114, 124113, + 124115, 124127, 124128, 124129, 124130, 124131, 124140, 124143, 124142, + 124139, 124141, 124149, 124148, 124151, 124150, 124147, 124146, 124144, + 124153, 124145, 124152, 128133, 8358, 8892, 72102, 72103, 72138, 72144, + 72136, 72096, 72097, 72107, 72109, 72123, 72122, 72128, 72127, 72121, + 72120, 72126, 72125, 72100, 72101, 72098, 72099, 72143, 72137, 72114, + 72124, 72119, 72129, 72139, 72140, 72141, 72133, 72132, 72116, 72115, + 72113, 72112, 72118, 72117, 72111, 72110, 72131, 72130, 72142, 72134, + 72135, 72106, 72108, 72162, 72161, 72158, 72160, 72159, 72164, 72150, + 72151, 72145, 72155, 72157, 72148, 72149, 72146, 72147, 72154, 72156, + 72163, 8302, 127966, 129314, 128219, 129535, 8239, 983092, 983197, + 983128, 9471, 9453, 9460, 9452, 9458, 9451, 9454, 9455, 9459, 9456, 9457, + 127312, 127313, 127314, 127315, 127316, 127317, 127318, 127319, 127320, + 127321, 127322, 127323, 127324, 127325, 127326, 127327, 127328, 127329, + 127330, 127331, 127332, 127333, 127334, 127335, 127336, 127337, 128982, + 128984, 129982, 129981, 129983, 127344, 127345, 127346, 127347, 127348, + 127349, 127350, 127351, 127352, 127353, 127354, 127355, 127356, 127357, + 127358, 127359, 127360, 127361, 127362, 127363, 127364, 127365, 127366, + 127367, 127368, 127369, 10062, 129988, 127374, 127371, 127375, 127372, + 127373, 983091, 8879, 8840, 8841, 8775, 8821, 8817, 8825, 8820, 8816, + 8824, 129670, 129722, 11228, 129540, 129544, 129565, 129586, 129603, + 129607, 129561, 129536, 129557, 129599, 129539, 129560, 129602, 129610, + 129613, 129541, 129562, 129604, 129537, 129558, 129600, 129538, 129559, + 129601, 129581, 129578, 129582, 129583, 129579, 129580, 128528, 9906, + 127770, 127761, 8362, 6595, 6594, 6599, 6598, 6597, 6596, 6593, 6566, + 6530, 6567, 6531, 6570, 6537, 6532, 6544, 6543, 6536, 6542, 6549, 6548, + 6562, 6561, 6554, 6560, 6556, 6550, 6528, 6555, 6538, 6568, 6533, 6569, + 6534, 6571, 6540, 6535, 6547, 6546, 6539, 6545, 6552, 6551, 6565, 6564, + 6557, 6563, 6559, 6553, 6529, 6558, 6541, 6622, 6623, 6600, 6601, 6618, + 6577, 6587, 6582, 6586, 6578, 6592, 6583, 6584, 6590, 6589, 6579, 6585, + 6591, 6580, 6588, 6576, 6581, 6613, 6612, 6615, 6614, 6611, 6610, 6608, + 6617, 6609, 6616, 983063, 70732, 70746, 70731, 70741, 70740, 70743, + 70742, 70739, 70738, 70736, 70745, 70737, 70744, 70734, 70675, 70674, + 70681, 70680, 70692, 70686, 70691, 70751, 70662, 70663, 70664, 70665, + 70656, 70657, 70667, 70669, 70685, 70684, 70690, 70689, 70683, 70682, + 70688, 70687, 70660, 70661, 70658, 70659, 70705, 70706, 70707, 70696, + 70695, 70677, 70676, 70673, 70672, 70679, 70678, 70671, 70670, 70703, + 70702, 70698, 70697, 70694, 70693, 70701, 70700, 70708, 70704, 70699, + 70666, 70668, 70727, 70724, 70723, 70726, 70752, 70728, 70753, 70722, + 70725, 70730, 70750, 70747, 70709, 70719, 70721, 70714, 70715, 70716, + 70717, 70712, 70713, 70710, 70711, 70718, 70720, 70735, 70749, 70733, + 70729, 11154, 11155, 128240, 9112, 983131, 9798, 11209, 128084, 129299, + 983132, 128985, 129399, 127747, 2031, 2032, 2033, 2030, 2034, 2027, 2028, + 2029, 2035, 2040, 2045, 2046, 1989, 1988, 1991, 1990, 1987, 1986, 1984, + 1993, 1985, 1992, 2042, 2008, 2001, 2025, 2024, 2026, 2006, 2002, 2019, + 2016, 2018, 2023, 2010, 2009, 2000, 1999, 2007, 1997, 1995, 2012, 2003, + 2013, 2020, 2014, 2015, 2017, 2004, 2011, 2005, 2021, 2022, 1994, 1996, + 1998, 2037, 2036, 2039, 2038, 2041, 2047, 983127, 128691, 9940, 128683, + 128695, 128370, 128286, 128245, 128685, 8303, 65934, 8209, 128689, 10973, + 8893, 8599, 10542, 10545, 10536, 10532, 10530, 128602, 128594, 128610, + 11111, 11127, 11016, 8663, 129109, 11008, 43063, 43062, 43065, 43064, + 43059, 43060, 43057, 43056, 43061, 43058, 10529, 8598, 8689, 8632, 10546, + 10535, 10531, 128600, 128592, 128608, 11110, 11126, 11017, 8662, 129108, + 11009, 128746, 8882, 8884, 8379, 8836, 8837, 8713, 8772, 8777, 8938, + 8940, 8742, 8930, 8931, 172, 8877, 8769, 8813, 8800, 8802, 8815, 8814, + 9083, 128323, 10159, 128324, 10161, 128456, 128457, 128458, 128211, + 128212, 160, 128067, 9369, 9362, 9365, 9366, 9367, 35, 9368, 9364, 9361, + 9363, 9371, 9370, 8470, 110960, 110961, 110962, 110963, 110964, 110965, + 110966, 110967, 110968, 110969, 110970, 110971, 110972, 110973, 110974, + 110975, 110976, 110977, 110978, 110979, 110980, 110981, 110982, 110983, + 110984, 110985, 110986, 110987, 110988, 110989, 110990, 110991, 110992, + 110993, 110994, 110995, 110996, 110997, 110998, 110999, 111000, 111001, + 111002, 111003, 111004, 111005, 111006, 111007, 111008, 111009, 111010, + 111011, 111012, 111013, 111014, 111015, 111016, 111017, 111018, 111019, + 111020, 111021, 111022, 111023, 111024, 111025, 111026, 111027, 111028, + 111029, 111030, 111031, 111032, 111033, 111034, 111035, 111036, 111037, + 111038, 111039, 111040, 111041, 111042, 111043, 111044, 111045, 111046, + 111047, 111048, 111049, 111050, 111051, 111052, 111053, 111054, 111055, + 111056, 111057, 111058, 111059, 111060, 111061, 111062, 111063, 111064, + 111065, 111066, 111067, 111068, 111069, 111070, 111071, 111072, 111073, + 111074, 111075, 111076, 111077, 111078, 111079, 111080, 111081, 111082, + 111083, 111084, 111085, 111086, 111087, 111088, 111089, 111090, 111091, + 111092, 111093, 111094, 111095, 111096, 111097, 111098, 111099, 111100, + 111101, 111102, 111103, 111104, 111105, 111106, 111107, 111108, 111109, + 111110, 111111, 111112, 111113, 111114, 111115, 111116, 111117, 111118, + 111119, 111120, 111121, 111122, 111123, 111124, 111125, 111126, 111127, + 111128, 111129, 111130, 111131, 111132, 111133, 111134, 111135, 111136, + 111137, 111138, 111139, 111140, 111141, 111142, 111143, 111144, 111145, + 111146, 111147, 111148, 111149, 111150, 111151, 111152, 111153, 111154, + 111155, 111156, 111157, 111158, 111159, 111160, 111161, 111162, 111163, + 111164, 111165, 111166, 111167, 111168, 111169, 111170, 111171, 111172, + 111173, 111174, 111175, 111176, 111177, 111178, 111179, 111180, 111181, + 111182, 111183, 111184, 111185, 111186, 111187, 111188, 111189, 111190, + 111191, 111192, 111193, 111194, 111195, 111196, 111197, 111198, 111199, + 111200, 111201, 111202, 111203, 111204, 111205, 111206, 111207, 111208, + 111209, 111210, 111211, 111212, 111213, 111214, 111215, 111216, 111217, + 111218, 111219, 111220, 111221, 111222, 111223, 111224, 111225, 111226, + 111227, 111228, 111229, 111230, 111231, 111232, 111233, 111234, 111235, + 111236, 111237, 111238, 111239, 111240, 111241, 111242, 111243, 111244, + 111245, 111246, 111247, 111248, 111249, 111250, 111251, 111252, 111253, + 111254, 111255, 111256, 111257, 111258, 111259, 111260, 111261, 111262, + 111263, 111264, 111265, 111266, 111267, 111268, 111269, 111270, 111271, + 111272, 111273, 111274, 111275, 111276, 111277, 111278, 111279, 111280, + 111281, 111282, 111283, 111284, 111285, 111286, 111287, 111288, 111289, + 111290, 111291, 111292, 111293, 111294, 111295, 111296, 111297, 111298, + 111299, 111300, 111301, 111302, 111303, 111304, 111305, 111306, 111307, + 111308, 111309, 111310, 111311, 111312, 111313, 111314, 111315, 111316, + 111317, 111318, 111319, 111320, 111321, 111322, 111323, 111324, 111325, + 111326, 111327, 111328, 111329, 111330, 111331, 111332, 111333, 111334, + 111335, 111336, 111337, 111338, 111339, 111340, 111341, 111342, 111343, + 111344, 111345, 111346, 111347, 111348, 111349, 111350, 111351, 111352, + 111353, 111354, 111355, 94177, 128297, 983041, 983040, 123215, 123149, + 123155, 123138, 123166, 123164, 123148, 123143, 123161, 123153, 123152, + 123141, 123137, 123156, 123139, 123163, 123142, 123172, 123173, 123171, + 123158, 123140, 123167, 123176, 123177, 123165, 123151, 123168, 123136, + 123169, 123162, 123178, 123179, 123144, 123157, 123170, 123150, 123145, + 123159, 123146, 123154, 123160, 123147, 123174, 123175, 123180, 123214, + 123193, 123192, 123195, 123191, 123194, 123196, 123197, 123184, 123190, + 123189, 123186, 123185, 123188, 123187, 123205, 123204, 123207, 123206, + 123203, 123202, 123200, 123209, 123201, 123208, 983231, 983066, 10663, + 10662, 11869, 9215, 65532, 9287, 9286, 9284, 9285, 9289, 9281, 9290, + 9288, 9282, 9283, 9280, 128721, 128025, 128885, 127970, 5787, 5788, 5776, + 5761, 5786, 5770, 5769, 5781, 5779, 5785, 5763, 5772, 5780, 5784, 5762, + 5775, 5773, 5765, 5777, 5782, 5764, 5774, 5783, 5766, 5778, 5771, 5767, + 5768, 5760, 731, 128738, 7265, 7264, 7266, 7267, 7261, 7260, 7262, 7259, + 7280, 7282, 7281, 7279, 7271, 7270, 7272, 7269, 7258, 7263, 7278, 7268, + 7283, 7273, 7284, 7285, 7287, 7286, 7276, 7274, 7275, 7277, 7290, 7288, + 7289, 7295, 7294, 7292, 7291, 7253, 7252, 7255, 7254, 7251, 7250, 7248, + 7257, 7249, 7256, 7293, 94179, 94178, 68736, 68739, 68744, 68737, 68756, + 68745, 68760, 68769, 68761, 68775, 68785, 68741, 68762, 68772, 68773, + 68740, 68777, 68742, 68749, 68750, 68758, 68759, 68774, 68776, 68783, + 68784, 68738, 68743, 68747, 68748, 68751, 68754, 68755, 68768, 68770, + 68782, 68765, 68780, 68766, 68781, 68763, 68767, 68764, 68778, 68757, + 68786, 68779, 68746, 68752, 68753, 68771, 68800, 68803, 68808, 68801, + 68820, 68809, 68824, 68833, 68825, 68839, 68849, 68805, 68826, 68836, + 68837, 68804, 68841, 68806, 68813, 68814, 68822, 68823, 68838, 68840, + 68847, 68848, 68802, 68807, 68811, 68812, 68815, 68818, 68819, 68832, + 68834, 68846, 68829, 68844, 68830, 68845, 68827, 68831, 68828, 68842, + 68821, 68850, 68843, 68810, 68816, 68817, 68835, 68861, 68859, 68858, + 68862, 68863, 68860, 66308, 66324, 66318, 66335, 66323, 66331, 66327, + 66330, 66315, 66316, 66317, 66329, 66314, 66306, 66322, 66351, 66321, + 66350, 66326, 66334, 66313, 66333, 66328, 66320, 66312, 66325, 66332, + 66305, 66307, 66311, 66309, 66349, 66310, 66304, 66319, 66339, 66337, + 66338, 66336, 68241, 68242, 68246, 68244, 68226, 68224, 68237, 68235, + 68249, 68251, 68247, 68233, 68248, 68252, 68227, 68234, 68230, 68239, + 68232, 68240, 68231, 68250, 68236, 68225, 68243, 68245, 68228, 68229, + 68238, 68255, 68254, 68253, 66404, 66390, 66392, 66387, 66388, 66411, + 66393, 66421, 66418, 66396, 66397, 66399, 66406, 66405, 66401, 66413, + 66402, 66398, 66414, 66415, 66416, 66408, 66420, 66417, 66407, 66419, + 66389, 66391, 66395, 66400, 66386, 66409, 66410, 66385, 66384, 66394, + 66412, 66403, 66516, 66514, 66515, 66517, 66513, 66464, 66504, 66505, + 66506, 66482, 66510, 66511, 66477, 66508, 66509, 66478, 66479, 66473, + 66474, 66490, 66491, 66480, 66475, 66476, 66507, 66471, 66469, 66470, + 66467, 66468, 66484, 66485, 66492, 66493, 66486, 66487, 66488, 66497, + 66498, 66495, 66472, 66483, 66499, 66494, 66481, 66489, 66496, 66465, + 66466, 66512, 128435, 69414, 69395, 69376, 69394, 69391, 69392, 69398, + 69399, 69403, 69404, 69377, 69379, 69382, 69400, 69388, 69380, 69384, + 69393, 69397, 69401, 69386, 69381, 69385, 69387, 69378, 69390, 69402, + 69383, 69396, 69389, 69415, 69407, 69412, 69411, 69406, 69410, 69405, + 69413, 69409, 69408, 68209, 68210, 68217, 68211, 68213, 68214, 68212, + 68203, 68205, 68207, 68206, 68202, 68198, 68220, 68219, 68215, 68201, + 68216, 68193, 68196, 68199, 68218, 68192, 68194, 68200, 68204, 68197, + 68208, 68195, 68222, 68221, 68223, 68608, 68619, 68627, 68623, 68634, + 68640, 68644, 68668, 68670, 68677, 68632, 68669, 68671, 68617, 68625, + 68621, 68638, 68643, 68660, 68666, 68675, 68630, 68648, 68653, 68646, + 68650, 68641, 68673, 68658, 68642, 68655, 68628, 68611, 68657, 68662, + 68614, 68615, 68636, 68656, 68664, 68679, 68680, 68609, 68610, 68645, + 68654, 68620, 68624, 68635, 68678, 68633, 68672, 68652, 68618, 68626, + 68622, 68639, 68661, 68667, 68676, 68631, 68613, 68649, 68647, 68651, + 68674, 68659, 68629, 68612, 68663, 68616, 68637, 68665, 69509, 69508, + 69507, 69506, 69488, 69502, 69496, 69505, 69492, 69499, 69501, 69503, + 69494, 69493, 69490, 69495, 69489, 69498, 69504, 69491, 69500, 69497, + 69511, 69512, 69513, 69510, 128477, 128117, 129491, 128116, 129746, + 128283, 128664, 128753, 128660, 128662, 128653, 11819, 8228, 128431, + 129649, 129477, 128214, 9251, 10044, 10027, 10034, 10011, 128194, 128449, + 128080, 128237, 128236, 10180, 10179, 128275, 9103, 9104, 10174, 983191, + 8997, 128191, 128440, 9934, 9741, 128217, 129505, 129447, 8886, 2902, + 2903, 2933, 2934, 2931, 2930, 2935, 2932, 2928, 2909, 2908, 2864, 2911, + 2863, 2821, 2822, 2832, 2836, 2850, 2849, 2855, 2854, 2848, 2847, 2853, + 2852, 2827, 2912, 2828, 2913, 2869, 2825, 2826, 2823, 2824, 2867, 2866, + 2841, 2851, 2846, 2856, 2870, 2871, 2872, 2861, 2860, 2843, 2842, 2840, + 2839, 2845, 2844, 2838, 2837, 2859, 2858, 2873, 2862, 2929, 2831, 2835, + 983660, 983659, 2877, 2818, 2817, 2876, 2901, 2893, 2819, 2878, 2888, + 2892, 2883, 2884, 2914, 2915, 2881, 2882, 2879, 2880, 2887, 2891, 2923, + 2922, 2925, 2924, 2921, 2920, 2918, 2927, 2919, 2926, 64830, 64831, 9766, + 10183, 128895, 66736, 66737, 66738, 66739, 66743, 66763, 66761, 66742, + 66749, 66757, 66744, 66768, 66750, 66748, 66754, 66755, 66764, 66762, + 66760, 66746, 66745, 66741, 66765, 66769, 66759, 66758, 66771, 66770, + 66740, 66751, 66752, 66753, 66756, 66767, 66747, 66766, 66776, 66777, + 66778, 66779, 66783, 66803, 66801, 66782, 66789, 66797, 66784, 66808, + 66790, 66788, 66794, 66795, 66804, 66802, 66800, 66786, 66785, 66781, + 66805, 66809, 66799, 66798, 66811, 66810, 66780, 66791, 66792, 66793, + 66796, 66807, 66787, 66806, 66710, 66688, 66715, 66699, 66694, 66698, + 66703, 66693, 66697, 66696, 66705, 66702, 66713, 66717, 66704, 66706, + 66707, 66711, 66716, 66689, 66701, 66700, 66708, 66691, 66695, 66690, + 66692, 66709, 66712, 66714, 66725, 66724, 66727, 66726, 66723, 66722, + 66720, 66729, 66721, 66728, 983192, 126257, 126264, 126258, 126259, + 126265, 126260, 126263, 126267, 126255, 126266, 126256, 126262, 126261, + 126269, 126268, 126254, 126216, 126225, 126252, 126234, 126243, 126222, + 126249, 126213, 126231, 126240, 126221, 126248, 126212, 126230, 126239, + 126217, 126226, 126253, 126235, 126244, 126215, 126224, 126251, 126233, + 126242, 126214, 126223, 126250, 126232, 126241, 126220, 126247, 126211, + 126229, 126238, 126219, 126246, 126210, 126228, 126237, 126218, 126245, + 126209, 126227, 126236, 129446, 128228, 10015, 9885, 10029, 10009, 8485, + 129397, 128471, 11195, 11194, 11196, 8254, 129450, 8486, 128076, 127842, + 128329, 129417, 128002, 983122, 983121, 128463, 128195, 128479, 128196, + 128223, 128464, 128724, 93059, 93065, 93064, 93058, 93070, 93056, 93055, + 93053, 93062, 93069, 93061, 93066, 93071, 93068, 93054, 93057, 93063, + 93067, 93060, 92967, 92975, 92965, 92969, 92959, 92968, 92971, 92957, + 92962, 92960, 92972, 92970, 92963, 92958, 92966, 92961, 92956, 92974, + 92964, 92973, 92979, 92978, 92980, 92977, 92976, 92982, 92981, 93023, + 93020, 93024, 93021, 93019, 93025, 93022, 93043, 92985, 93047, 93044, + 93045, 92997, 93046, 93042, 93032, 93029, 92995, 93038, 92993, 93041, + 93035, 93033, 93037, 93030, 93039, 92987, 92992, 92986, 92983, 92984, + 93027, 92994, 93034, 92988, 92990, 92989, 92991, 93028, 92996, 93031, + 93040, 93036, 92954, 92955, 92938, 92939, 92932, 92933, 92942, 92943, + 92950, 92951, 92928, 92929, 92936, 92937, 92948, 92949, 92930, 92931, + 92944, 92945, 92934, 92935, 92940, 92941, 92946, 92947, 92952, 92953, + 93013, 93012, 93015, 93014, 93011, 93010, 93008, 93017, 93009, 93016, + 9908, 11801, 127796, 129779, 129780, 67703, 67693, 67688, 67702, 67683, + 67691, 67699, 67700, 67680, 67696, 67682, 67686, 67695, 67698, 67701, + 67689, 67684, 67687, 67690, 67681, 67694, 67685, 67697, 67692, 67704, + 67711, 67706, 67707, 67710, 67709, 67708, 67705, 129330, 129374, 128060, + 11853, 8233, 11791, 10995, 10994, 8741, 129666, 12809, 12823, 12808, + 12822, 12828, 12813, 12827, 12810, 12824, 12800, 12814, 12804, 12818, + 12801, 12815, 12812, 12826, 12805, 12819, 12803, 12817, 12806, 12820, + 12811, 12825, 12802, 12816, 12807, 12821, 12863, 12855, 12858, 12861, + 12847, 12839, 12854, 12843, 12836, 12864, 12835, 12856, 12846, 12842, + 12840, 12852, 12862, 12865, 12857, 12867, 12838, 12866, 12851, 12853, + 12859, 12849, 12860, 12848, 12837, 12834, 12841, 12833, 12845, 12844, + 12850, 12832, 12830, 12829, 9349, 9342, 9345, 9346, 9350, 9347, 9348, + 9344, 9351, 9343, 9341, 9336, 9335, 9338, 9337, 9334, 9333, 9340, 9332, + 9339, 127248, 127249, 127250, 127251, 127252, 127253, 127254, 127255, + 127256, 127257, 127258, 127259, 127260, 127261, 127262, 127263, 127264, + 127265, 127266, 127267, 127268, 127269, 127270, 127271, 127272, 127273, + 9372, 9373, 9374, 9375, 9376, 9377, 9378, 9379, 9380, 9381, 9382, 9383, + 9384, 9385, 9386, 9387, 9388, 9389, 9390, 9391, 9392, 9393, 9394, 9395, + 9396, 9397, 8706, 983147, 983146, 983149, 983150, 9853, 127881, 12880, + 12349, 129436, 11261, 128755, 9105, 9106, 128706, 72437, 72440, 72432, + 72416, 72419, 72413, 72417, 72415, 72412, 72414, 72418, 72420, 72403, + 72407, 72411, 72409, 72410, 72391, 72400, 72404, 72397, 72394, 72385, + 72401, 72384, 72399, 72398, 72396, 72388, 72393, 72392, 72386, 72387, + 72402, 72395, 72390, 72389, 72405, 72406, 72408, 72436, 72435, 72438, + 72439, 72422, 72421, 72424, 72425, 72431, 72433, 72434, 72428, 72427, + 72429, 72430, 72423, 72426, 128062, 128230, 128206, 983228, 983237, + 129434, 9774, 127825, 129372, 129755, 127824, 128039, 128532, 9956, + 128390, 9999, 8240, 8241, 8524, 10178, 10977, 129336, 129494, 129496, + 128113, 9977, 128590, 129733, 128591, 129493, 128589, 128588, 129495, + 128583, 128187, 8966, 128547, 37, 9854, 127917, 8359, 8369, 129515, + 128694, 129730, 43101, 43117, 43120, 43076, 43123, 43077, 43115, 43090, + 43082, 43094, 43098, 43099, 43119, 43118, 43109, 43074, 43075, 43116, + 43079, 43083, 43089, 43088, 43114, 43113, 43081, 43080, 43073, 43072, + 43085, 43084, 43092, 43093, 43104, 43110, 43086, 43108, 43100, 43078, + 43097, 43087, 43106, 43096, 43091, 43107, 43095, 43102, 43105, 43103, + 43127, 43126, 43124, 43121, 43111, 43112, 43122, 43125, 66033, 66023, + 66017, 66010, 66027, 66003, 66018, 66028, 66004, 66012, 66022, 66020, + 66045, 66019, 66031, 66041, 66007, 66006, 66025, 66026, 66038, 66016, + 66013, 66014, 66000, 66001, 66034, 66036, 66037, 66029, 66011, 66024, + 66015, 66021, 66042, 66043, 66002, 66008, 66032, 66005, 66044, 66040, + 66039, 66030, 66009, 66035, 5941, 5942, 67840, 67855, 67843, 67844, + 67847, 67858, 67857, 67860, 67854, 67861, 67848, 67845, 67846, 67849, + 67859, 67842, 67850, 67853, 67851, 67841, 67856, 67852, 67864, 67866, + 67867, 67863, 67862, 67865, 67871, 11227, 9935, 128763, 128022, 128061, + 128055, 128169, 182, 128138, 129292, 129295, 127885, 127821, 10031, + 129655, 129669, 9811, 128299, 8916, 10970, 129383, 8984, 128720, 129703, + 8462, 8463, 127183, 127136, 127167, 127199, 127188, 127140, 127156, + 127172, 127200, 127189, 127141, 127157, 127173, 127196, 127148, 127164, + 127180, 127198, 127150, 127166, 127182, 127192, 127144, 127160, 127176, + 127191, 127143, 127159, 127175, 127190, 127142, 127158, 127174, 127197, + 127149, 127165, 127181, 127194, 127146, 127162, 127178, 127187, 127139, + 127155, 127171, 127186, 127138, 127154, 127170, 127202, 127220, 127221, + 127201, 127210, 127211, 127212, 127213, 127214, 127215, 127216, 127217, + 127218, 127219, 127203, 127204, 127205, 127206, 127207, 127208, 127209, + 127185, 127137, 127153, 127169, 127193, 127145, 127161, 127177, 127195, + 127147, 127163, 127179, 128733, 983151, 43, 10797, 10798, 10809, 10789, + 10786, 10791, 10790, 10788, 10792, 10787, 10866, 177, 9799, 11222, 11221, + 11220, 11219, 129696, 983148, 128659, 128680, 128110, 8297, 8236, 127871, + 128254, 11239, 128239, 12306, 12320, 128238, 8982, 128688, 129364, + 127858, 129716, 127831, 129751, 128574, 128545, 163, 128093, 9212, 9213, + 9214, 9211, 128041, 128425, 129328, 129732, 129731, 65043, 65040, 65045, + 65073, 65074, 65049, 65041, 65042, 65091, 65047, 65083, 65085, 65089, + 65079, 65087, 65077, 65095, 65081, 65075, 65084, 65086, 65092, 983261, + 65048, 65090, 65080, 65088, 65078, 65096, 65082, 65076, 65044, 65072, + 65046, 8478, 8826, 10937, 10933, 10927, 10929, 10935, 10931, 8936, 8830, + 8828, 8880, 9111, 129384, 9113, 128424, 128438, 129332, 128120, 983193, + 983166, 983163, 983164, 983167, 8242, 8965, 8759, 8733, 8522, 128711, + 129455, 11224, 128255, 68507, 68508, 68480, 68483, 68490, 68491, 68485, + 68482, 68486, 68493, 68495, 68496, 68488, 68484, 68487, 68489, 68481, + 68492, 68497, 68494, 68526, 68522, 68523, 68525, 68521, 68527, 68524, + 68505, 68506, 11854, 8200, 128156, 128091, 128686, 128204, 128226, + 983165, 983168, 983194, 9624, 9625, 9626, 9627, 9628, 9629, 9630, 9631, + 9622, 9623, 10764, 8279, 10774, 9833, 128894, 8264, 63, 8799, 34, 9915, + 127949, 127950, 129437, 128251, 9762, 128280, 9143, 128740, 128643, 9926, + 127752, 11827, 11783, 11782, 9995, 128400, 128406, 127338, 127339, + 127340, 9994, 11828, 11787, 129306, 128000, 8758, 128007, 128048, 129682, + 128015, 129534, 9852, 9843, 9844, 9845, 9846, 9847, 9848, 9849, 9850, + 983113, 128665, 127822, 129511, 174, 127462, 127463, 127464, 127465, + 127466, 127467, 127468, 127469, 127470, 127471, 127472, 127473, 127474, + 127475, 127476, 127477, 127478, 127479, 127480, 127481, 127482, 127483, + 127484, 127485, 127486, 127487, 43344, 43343, 43346, 43345, 43330, 43320, + 43333, 43323, 43331, 43314, 43332, 43317, 43319, 43321, 43316, 43313, + 43329, 43322, 43312, 43326, 43318, 43325, 43324, 43315, 43328, 43327, + 43334, 43359, 43337, 43342, 43341, 43338, 43340, 43335, 43339, 43336, + 43347, 128524, 127895, 65533, 9952, 9953, 128699, 8479, 9166, 11152, + 11153, 128639, 128968, 983152, 92, 10184, 10741, 10743, 11073, 11079, + 983153, 10659, 10661, 8246, 12317, 10989, 8976, 11793, 8267, 8245, + 128401, 9753, 11262, 8515, 8271, 8765, 8909, 8247, 128402, 128403, + 128405, 11841, 11822, 128404, 10672, 128158, 8251, 129423, 983154, + 127872, 11190, 11188, 11191, 11189, 11186, 11187, 11184, 11185, 127832, + 127833, 129919, 129918, 128495, 8735, 12297, 10642, 11777, 11776, 9084, + 8894, 10652, 10644, 10228, 8692, 12305, 10648, 125, 9132, 9133, 9131, + 12301, 8969, 11781, 12299, 10608, 10715, 8221, 11817, 129929, 10621, + 8971, 9687, 11241, 9616, 129978, 129971, 129933, 128381, 11805, 8906, + 10198, 129927, 9621, 129980, 41, 9120, 9118, 9119, 11789, 10182, 8908, + 129931, 8217, 11815, 128360, 128361, 128362, 128489, 93, 9126, 9124, + 10638, 10640, 8262, 10636, 11864, 11862, 9125, 11779, 129987, 128493, + 129928, 129930, 11786, 8895, 10702, 129902, 12309, 8866, 11809, 9145, + 12303, 10628, 12311, 10630, 12315, 12313, 10713, 1421, 4053, 4055, + 129308, 9957, 10749, 9002, 187, 128270, 10153, 10552, 8295, 8238, 8235, + 8207, 10813, 8594, 11080, 11084, 10562, 10613, 10612, 129974, 8614, + 10528, 11076, 11075, 10567, 10526, 8677, 8628, 10513, 8699, 129034, 8620, + 10565, 129042, 129026, 8603, 11022, 11023, 8611, 10517, 10516, 129030, + 129178, 129046, 8618, 8696, 8644, 10522, 129193, 129185, 11146, 11157, + 8658, 10499, 8655, 10503, 10524, 10509, 8674, 129195, 129078, 8652, + 10601, 10605, 10591, 10583, 8641, 10600, 10604, 10596, 10587, 10579, + 8640, 129777, 129090, 129094, 129191, 8702, 8649, 129784, 129189, 128622, + 8669, 129082, 129106, 129187, 11106, 11138, 11132, 983242, 11175, 11173, + 129066, 129062, 129058, 129074, 129070, 11122, 11116, 11142, 129170, + 10511, 8667, 10518, 10520, 10519, 11246, 10497, 10496, 10501, 10512, + 8608, 8605, 8680, 8688, 129174, 129086, 11078, 128141, 128735, 11824, + 8790, 8791, 8728, 730, 129680, 128365, 10539, 10544, 65020, 129350, + 983227, 983235, 983225, 983230, 129704, 128640, 128478, 127906, 128764, + 129531, 129315, 128019, 65947, 65942, 65945, 65940, 65943, 8556, 8583, + 8582, 8548, 8558, 8577, 8547, 8544, 8557, 8584, 8559, 8576, 8549, 8581, + 8550, 8553, 8578, 8555, 8545, 8546, 8579, 8554, 8551, 8552, 65938, 65944, + 65936, 65939, 65941, 65937, 65946, 127801, 127989, 10087, 10085, 11213, + 11215, 8506, 128205, 128907, 127588, 127586, 127589, 127584, 127585, + 127587, 128675, 127840, 129302, 8381, 127945, 10740, 69245, 69243, 69244, + 69246, 69241, 69232, 69238, 69229, 69237, 69228, 69242, 69233, 69234, + 69240, 69231, 69239, 69230, 69236, 69227, 69235, 69226, 69225, 69220, + 69219, 69222, 69221, 69218, 69217, 69224, 69216, 69223, 5872, 5869, 5803, + 5802, 5800, 5833, 5837, 5860, 5811, 5859, 5858, 5841, 5851, 5824, 5844, + 5854, 5826, 5846, 5856, 5799, 5814, 5880, 5879, 5877, 5876, 5878, 5792, + 5813, 5815, 5828, 5816, 5819, 5818, 5853, 5852, 5825, 5831, 5864, 5857, + 5827, 5873, 5812, 5810, 5850, 5829, 5820, 5848, 5804, 5862, 5806, 5801, + 5855, 5845, 5807, 5808, 5875, 5809, 5874, 5843, 5821, 5849, 5823, 5805, + 5836, 5840, 5830, 5863, 5835, 5834, 5861, 5842, 5822, 5798, 5839, 5797, + 5817, 5794, 5847, 5832, 5796, 5795, 5865, 5793, 5866, 5838, 5867, 5868, + 5870, 5871, 127933, 127939, 11254, 11252, 11253, 11251, 11255, 11256, + 8360, 983114, 10700, 129466, 129527, 9808, 129474, 9747, 129761, 2049, + 2053, 2051, 2063, 2055, 2052, 2058, 2059, 2062, 2068, 2069, 2056, 2065, + 2048, 2050, 2067, 2054, 2060, 2066, 2061, 2057, 2064, 2073, 2070, 2071, + 2075, 2093, 2072, 2074, 2084, 2088, 2097, 2110, 2098, 2100, 2108, 2099, + 2096, 2101, 2109, 2106, 2104, 2107, 2103, 2105, 2082, 2079, 2076, 2089, + 2086, 2091, 2081, 2078, 2085, 2092, 2083, 2080, 2077, 2090, 2087, 2102, + 128630, 128631, 128632, 128634, 129386, 128752, 128225, 9796, 43138, + 43139, 43150, 43153, 43167, 43166, 43172, 43171, 43165, 43164, 43170, + 43169, 43144, 43145, 43146, 43147, 43182, 43142, 43143, 43151, 43152, + 43140, 43141, 43187, 43181, 43158, 43168, 43163, 43173, 43183, 43184, + 43185, 43177, 43176, 43160, 43159, 43157, 43156, 43162, 43161, 43155, + 43154, 43175, 43174, 43148, 43149, 43186, 43178, 43180, 43179, 43205, + 43136, 43204, 43137, 43215, 43214, 43221, 43220, 43223, 43222, 43219, + 43218, 43216, 43225, 43217, 43224, 43188, 43189, 43200, 43203, 43194, + 43195, 43196, 43197, 43192, 43193, 43201, 43202, 43190, 43191, 43198, + 43199, 129429, 9973, 127927, 127862, 129403, 9878, 129507, 127979, + 127890, 129410, 9807, 128756, 129691, 128437, 8492, 8496, 8497, 8459, + 8464, 8466, 8499, 8472, 8475, 128624, 8495, 8458, 8467, 8500, 8456, + 128220, 983186, 129453, 128186, 167, 8980, 129352, 127793, 128584, 8979, + 130037, 130036, 130039, 130038, 130035, 130034, 130032, 130041, 130033, + 130040, 10802, 9914, 59, 8480, 129324, 9916, 65093, 983169, 8726, 129697, + 11259, 9913, 11250, 129331, 10014, 10061, 10032, 129368, 70086, 70085, + 70101, 70100, 70103, 70102, 70099, 70098, 70096, 70105, 70097, 70104, + 70092, 70106, 70108, 70019, 70020, 70030, 70032, 70046, 70045, 70051, + 70050, 70044, 70043, 70049, 70048, 70025, 70026, 70027, 70028, 70062, + 70023, 70024, 70021, 70022, 70061, 70060, 70037, 70047, 70042, 70052, + 70063, 70064, 70065, 70056, 70055, 70039, 70038, 70036, 70035, 70041, + 70040, 70034, 70033, 70054, 70053, 70066, 70057, 70059, 70058, 70029, + 70031, 70089, 70110, 70111, 70088, 70095, 70107, 70081, 70017, 70016, + 70090, 70082, 70083, 70080, 70018, 70093, 70091, 70094, 70067, 70077, + 70079, 70072, 70073, 70074, 70075, 70070, 70071, 70068, 70069, 70076, + 70078, 70087, 70109, 70084, 129416, 127847, 66684, 66680, 66682, 66665, + 66673, 66679, 66664, 66669, 66647, 66685, 66672, 66683, 66663, 66659, + 66649, 66686, 66674, 66662, 66660, 66656, 66661, 66677, 66678, 66668, + 66676, 66666, 66681, 66640, 66670, 66646, 66645, 66644, 66654, 66641, + 66667, 66658, 66648, 66687, 66657, 66651, 66655, 66643, 66652, 66650, + 66642, 66653, 66671, 66675, 9752, 129768, 128737, 983075, 983078, 9961, + 128674, 127776, 128722, 128717, 11087, 11103, 11086, 10564, 10976, 10985, + 10984, 10974, 10975, 10983, 113825, 113824, 113826, 113827, 127856, + 129651, 9085, 129327, 128703, 128017, 129424, 129335, 10722, 983198, + 983080, 71107, 71106, 71113, 71040, 71131, 71041, 71051, 71053, 71128, + 71070, 71129, 71130, 71065, 71064, 71069, 71067, 71066, 71072, 71071, + 71046, 71047, 71048, 71049, 71082, 71044, 71045, 71042, 71043, 71058, + 71068, 71063, 71073, 71083, 71084, 71085, 71077, 71076, 71060, 71059, + 71057, 71056, 71062, 71061, 71055, 71054, 71075, 71074, 71086, 71081, + 71078, 71080, 71079, 71050, 71052, 71110, 71111, 71112, 71119, 71120, + 71127, 71126, 71125, 71123, 71124, 71117, 71118, 71116, 71121, 71115, + 71114, 71122, 71109, 71108, 71105, 71100, 71104, 71101, 71103, 71102, + 71132, 71133, 71087, 71097, 71099, 71092, 71093, 71090, 71091, 71088, + 71089, 71096, 71098, 128411, 128410, 128417, 128416, 128409, 128408, + 128415, 128414, 121399, 121397, 121400, 121398, 121402, 121401, 121104, + 121103, 121102, 121388, 121387, 121386, 121482, 121479, 121358, 121359, + 121357, 121360, 121341, 121335, 121339, 121340, 121336, 121334, 121333, + 121338, 121337, 121342, 121368, 121367, 121373, 121356, 121355, 121354, + 121380, 121382, 121381, 121384, 121383, 121385, 121377, 121379, 121378, + 121375, 121376, 121374, 121371, 121369, 121366, 121370, 121372, 121364, + 121365, 121452, 121392, 121352, 121353, 121351, 121499, 121500, 121501, + 121502, 121503, 121470, 121117, 121115, 121119, 121118, 121116, 121456, + 121363, 121362, 121361, 121480, 121455, 120965, 120837, 121000, 120969, + 121027, 121026, 121076, 121074, 121075, 120995, 120991, 120990, 120982, + 121005, 121011, 121044, 121042, 121043, 120950, 120833, 120847, 121002, + 120859, 120863, 120997, 120967, 120845, 121019, 120839, 120993, 120980, + 121038, 121045, 121031, 121009, 120934, 121046, 121047, 120905, 120936, + 120937, 120935, 121065, 120941, 120834, 121068, 121069, 121024, 120915, + 120916, 121040, 120940, 120944, 120946, 120942, 120945, 120947, 120943, + 120949, 121020, 121039, 120948, 121091, 120832, 120838, 120861, 120843, + 120852, 120870, 120844, 120846, 120848, 120865, 120853, 120856, 120885, + 120877, 120878, 120879, 120884, 120857, 120882, 120854, 120855, 120858, + 120883, 121001, 120871, 120850, 120867, 120966, 120972, 120971, 120849, + 120862, 120895, 120894, 120872, 120873, 120893, 120875, 120874, 120866, + 120864, 120996, 120842, 120891, 120890, 121067, 120892, 120887, 121064, + 121066, 121063, 121060, 121061, 121062, 120899, 120881, 121052, 121059, + 121057, 121054, 121055, 121056, 121058, 120851, 120869, 120868, 120841, + 121018, 120974, 120977, 120976, 120975, 120985, 120986, 120983, 120992, + 120988, 120984, 120978, 121032, 121037, 120897, 120896, 120898, 120889, + 120888, 120886, 120880, 121035, 121030, 121033, 121028, 121036, 120860, + 121003, 121012, 121014, 121013, 121007, 121016, 121008, 121015, 121006, + 121077, 121083, 120876, 121084, 121085, 121078, 121090, 121087, 121079, + 121080, 121081, 120840, 121086, 121088, 121089, 120979, 121082, 121092, + 120906, 120922, 120908, 120919, 120920, 120921, 120914, 120910, 120912, + 120900, 120903, 120904, 120902, 120901, 120924, 120909, 120911, 120913, + 120926, 120930, 120931, 120932, 120929, 120933, 120928, 120925, 120927, + 120923, 120957, 120917, 120907, 120836, 121051, 120968, 120973, 120998, + 121072, 121053, 121073, 121070, 121071, 121025, 120970, 120994, 120989, + 120987, 121029, 121041, 120955, 120961, 120956, 120959, 120999, 121004, + 120964, 120960, 120963, 120962, 120958, 120939, 120938, 121023, 121021, + 121022, 121050, 121048, 121049, 121034, 121017, 120951, 120981, 120953, + 121010, 120954, 120952, 120918, 120835, 121451, 121343, 121349, 121347, + 121348, 121346, 121345, 121350, 121344, 121462, 121463, 121464, 121465, + 121466, 121467, 121468, 121469, 121428, 121429, 121427, 121476, 121473, + 121477, 121475, 121474, 121478, 121472, 121471, 121404, 121405, 121403, + 121430, 121409, 121411, 121410, 121406, 121408, 121407, 121421, 121423, + 121422, 121415, 121416, 121417, 121418, 121419, 121420, 121414, 121413, + 121412, 121424, 121425, 121426, 121432, 121431, 121183, 121184, 121182, + 121181, 121187, 121188, 121186, 121185, 121175, 121176, 121174, 121173, + 121179, 121180, 121178, 121177, 121324, 121321, 121323, 121320, 121322, + 121319, 121210, 121209, 121208, 121203, 121207, 121305, 121272, 121271, + 121287, 121286, 121303, 121304, 121302, 121301, 121206, 121205, 121204, + 121198, 121332, 121331, 121129, 121276, 121274, 121275, 121273, 121288, + 121289, 121291, 121290, 121306, 121280, 121278, 121279, 121277, 121295, + 121293, 121294, 121292, 121307, 121314, 121191, 121192, 121190, 121189, + 121193, 121202, 121201, 121200, 121199, 121282, 121281, 121297, 121296, + 121308, 121309, 121310, 121328, 121327, 121194, 121196, 121197, 121195, + 121216, 121215, 121214, 121213, 121212, 121211, 121449, 121125, 121126, + 121121, 121122, 121123, 121124, 121127, 121318, 121316, 121317, 121315, + 121156, 121155, 121154, 121146, 121145, 121144, 121150, 121149, 121148, + 121147, 121230, 121231, 121229, 121228, 121261, 121254, 121247, 121233, + 121232, 121226, 121227, 121225, 121224, 121249, 121248, 121153, 121152, + 121151, 121139, 121135, 121137, 121138, 121136, 121330, 121329, 121128, + 121236, 121262, 121255, 121235, 121234, 121237, 121240, 121239, 121263, + 121256, 121238, 121162, 121161, 121160, 121132, 121133, 121131, 121130, + 121134, 121253, 121142, 121143, 121141, 121140, 121243, 121242, 121241, + 121246, 121245, 121244, 121270, 121269, 121268, 121264, 121257, 121326, + 121325, 121159, 121158, 121157, 121448, 121394, 121393, 121396, 121395, + 121450, 121513, 121514, 121515, 121516, 121517, 121518, 121519, 121505, + 121506, 121507, 121508, 121509, 121510, 121511, 121512, 121312, 121284, + 121299, 121311, 121283, 121298, 121313, 121285, 121300, 121267, 121260, + 121252, 121251, 121266, 121259, 121250, 121265, 121258, 121107, 121106, + 121105, 121454, 121453, 121457, 121120, 121112, 121110, 121114, 121113, + 121111, 121108, 121109, 121101, 121100, 121099, 121481, 121441, 121445, + 121446, 121443, 121444, 121442, 121447, 121390, 121389, 121391, 121440, + 121439, 121437, 121435, 121436, 121434, 121433, 121438, 121459, 121458, + 121460, 121095, 121094, 121093, 121219, 121218, 121217, 121222, 121221, + 121220, 121223, 121172, 121171, 121170, 121168, 121167, 121166, 121165, + 121164, 121163, 121169, 121098, 121097, 121096, 121461, 121483, 129304, + 10912, 10911, 10910, 10909, 10860, 983185, 983183, 8219, 8249, 8218, + 8250, 983158, 983155, 983156, 983159, 70117, 70116, 70119, 70118, 70115, + 70114, 70121, 70113, 70120, 70131, 70132, 70129, 70126, 70125, 70130, + 70128, 70127, 70124, 70123, 70122, 983953, 983954, 983952, 3464, 3463, + 3495, 3501, 3497, 3503, 3510, 3488, 3484, 3490, 3482, 3508, 3513, 3462, + 3475, 3478, 3461, 3474, 3473, 3472, 3471, 3470, 3469, 3466, 3465, 3468, + 3467, 3496, 3502, 3498, 3504, 3511, 3489, 3485, 3491, 3483, 3509, 3512, + 3525, 3499, 3522, 3517, 3505, 3523, 3477, 3476, 3500, 3507, 3487, 3494, + 3526, 3524, 3515, 3520, 3514, 3492, 3493, 3521, 3486, 3563, 3562, 3565, + 3564, 3561, 3560, 3558, 3567, 3559, 3566, 3530, 3458, 3457, 3459, 3570, + 3571, 3546, 3537, 3539, 3542, 3544, 3551, 3536, 3538, 3540, 3545, 3548, + 3549, 3550, 3547, 3535, 3572, 8767, 10046, 128973, 10038, 128303, 8198, + 10042, 128510, 127935, 9975, 128128, 9760, 129448, 128761, 10902, 10904, + 10901, 10903, 11098, 11100, 42611, 128716, 128164, 128564, 128554, + 128373, 128759, 127829, 128577, 128578, 10840, 10839, 9011, 127920, + 129445, 65120, 128745, 65121, 128313, 128312, 8717, 8956, 8958, 65131, + 65104, 65109, 65129, 8714, 8948, 8951, 65126, 65111, 65112, 65105, 65115, + 65113, 65117, 65124, 65116, 65114, 65118, 8570, 8567, 8564, 8574, 8572, + 8563, 8560, 8573, 8575, 8571, 8561, 8562, 8569, 8566, 8565, 8568, 65128, + 65108, 68411, 732, 10849, 65125, 65123, 65130, 65122, 65119, 65106, + 65110, 10922, 10924, 10803, 128570, 128571, 128525, 128520, 128519, + 128515, 128517, 128516, 128518, 128522, 129325, 129392, 128526, 129394, + 8995, 128527, 128684, 128012, 128013, 129319, 127956, 9731, 9924, 127938, + 10052, 983077, 9917, 129510, 173, 127846, 128428, 9108, 129358, 69453, + 69452, 69454, 69456, 69447, 69449, 69446, 69448, 69455, 69451, 69450, + 69445, 69424, 69437, 69426, 69433, 69444, 69440, 69429, 69436, 69439, + 69441, 69431, 69427, 69430, 69432, 69425, 69443, 69435, 69442, 69428, + 69438, 69434, 69457, 69460, 69459, 69458, 69463, 69465, 69461, 69462, + 69464, 128618, 128619, 47, 10742, 128284, 69859, 69863, 69864, 69846, + 69847, 69857, 69849, 69842, 69843, 69844, 69845, 69854, 69856, 69855, + 69848, 69851, 69853, 69840, 69841, 69850, 69852, 69858, 69860, 69862, + 69861, 69877, 69876, 69879, 69878, 69875, 69874, 69872, 69881, 69873, + 69880, 8600, 10537, 10541, 8690, 10533, 128603, 128595, 128611, 11112, + 11128, 11018, 8664, 129110, 11010, 8601, 10538, 10534, 128601, 128593, + 128609, 11113, 11129, 11019, 8665, 129111, 11011, 8471, 72328, 72329, + 72327, 72326, 72340, 72339, 72334, 72332, 72341, 72335, 72333, 72330, + 72331, 72338, 72336, 72337, 72344, 72352, 72351, 72350, 72297, 72296, + 72302, 72311, 72301, 72323, 72285, 72284, 72288, 72298, 72293, 72303, + 72319, 72320, 72321, 72310, 72309, 72295, 72294, 72300, 72299, 72307, + 72306, 72290, 72289, 72287, 72286, 72292, 72291, 72305, 72304, 72312, + 72313, 72314, 72322, 72317, 72308, 72316, 72318, 72315, 72272, 72349, + 72348, 72347, 72346, 72324, 72343, 72325, 72342, 72345, 72353, 72354, + 72282, 72281, 72279, 72280, 72277, 72278, 72275, 72274, 72276, 72273, + 72283, 8384, 983043, 983182, 983118, 983177, 127837, 128150, 10055, + 10024, 32, 128586, 128264, 128263, 128265, 128266, 128483, 128676, + 128172, 8375, 8738, 10656, 10657, 128375, 128376, 128467, 128466, 128026, + 128166, 129525, 129348, 128051, 127941, 129533, 13279, 13058, 13057, + 13059, 13056, 13250, 13171, 13278, 13101, 13172, 13108, 13105, 13118, + 13116, 13251, 13192, 8851, 13255, 13183, 13213, 13220, 13216, 13254, + 8852, 13252, 13253, 13170, 13092, 13175, 13177, 13176, 13093, 13094, + 13256, 127376, 13207, 13064, 13179, 13181, 13182, 13055, 13180, 13005, + 13063, 13006, 9974, 9165, 13209, 13070, 13071, 13311, 13075, 13073, + 13072, 13080, 13081, 13203, 13228, 13191, 13257, 13258, 13098, 13110, + 13113, 13121, 13122, 13119, 13107, 13106, 13109, 13259, 13169, 127488, + 13004, 13200, 13260, 13060, 13061, 8847, 8932, 8849, 13178, 13188, 13067, + 13069, 13068, 13074, 13076, 13078, 13079, 13077, 13214, 13262, 13222, + 13218, 13086, 13085, 13082, 13083, 13084, 13201, 13193, 13248, 13226, + 13189, 13199, 13261, 13208, 13263, 13240, 13246, 8977, 13266, 10957, + 13264, 13265, 13267, 13223, 13224, 13249, 13221, 13217, 13187, 13123, + 13124, 13127, 13126, 13125, 13190, 13268, 13131, 13132, 13133, 13128, + 13129, 13130, 13269, 13212, 13219, 13215, 13186, 13196, 13197, 13205, + 13211, 13234, 13238, 13244, 13239, 13241, 13245, 13247, 13202, 13270, + 13227, 13198, 13206, 13235, 13185, 13096, 13097, 13195, 13210, 13233, + 13237, 13243, 13065, 8848, 8933, 8850, 13066, 13173, 13225, 13099, 13100, + 13184, 13115, 13112, 13114, 13111, 13103, 13104, 13102, 13117, 13120, + 11216, 13273, 13174, 13194, 13271, 13272, 13274, 13232, 13236, 13242, + 13229, 13230, 13231, 13142, 13141, 10958, 13137, 13138, 13140, 13139, + 8730, 13087, 13088, 13090, 13091, 13089, 13275, 13276, 128918, 13204, + 13095, 13143, 11027, 9641, 9638, 9636, 11029, 9706, 9703, 11026, 9705, + 9639, 11028, 9640, 9637, 9704, 10720, 13277, 13135, 13134, 13136, 13062, + 127529, 127530, 127512, 127508, 127533, 127545, 127520, 127516, 127534, + 127506, 127540, 127525, 127546, 127532, 127511, 127509, 127524, 127505, + 127517, 127518, 127527, 127537, 127504, 127528, 127535, 127519, 127515, + 127513, 127543, 127542, 127526, 127541, 127544, 127522, 127538, 127514, + 127521, 127539, 127510, 127536, 127523, 127547, 127531, 127378, 127377, + 8865, 10693, 11820, 127390, 127392, 127379, 10692, 127400, 127399, + 127398, 127306, 127489, 127507, 127490, 9919, 127397, 127280, 127281, + 127282, 127283, 127284, 127285, 127286, 127287, 127288, 127289, 127290, + 127291, 127292, 127293, 127294, 127295, 127296, 127297, 127298, 127299, + 127300, 127301, 127302, 127303, 127304, 127305, 10190, 10191, 127401, + 8863, 127307, 127381, 127382, 127396, 127383, 127310, 8862, 127388, + 127393, 127402, 127395, 9949, 10695, 10696, 127384, 127308, 127309, + 127387, 127394, 127389, 8864, 127391, 127385, 127403, 127404, 127386, + 10694, 127311, 127380, 10151, 129425, 983157, 983160, 983134, 983190, + 9877, 9882, 128387, 129485, 8795, 10017, 8902, 9770, 11242, 11243, + 983175, 983133, 983181, 983176, 983042, 983044, 128509, 128649, 127967, + 128642, 127836, 11836, 129658, 129989, 129990, 129993, 129991, 129992, + 128480, 9201, 128207, 9188, 127827, 10025, 983189, 8803, 127897, 129369, + 128723, 983170, 983045, 983103, 8332, 8328, 8330, 8331, 8333, 8334, 8325, + 8324, 8327, 8326, 8323, 8322, 8320, 8329, 8321, 10963, 10965, 10617, + 8834, 10953, 10949, 10951, 10955, 8842, 8838, 10947, 10943, 10945, 10941, + 983102, 8827, 10938, 10934, 10928, 10930, 10936, 10932, 8937, 8831, 8829, + 8881, 9139, 10763, 9138, 9737, 127774, 9925, 7098, 7073, 7074, 7075, + 7084, 7085, 7043, 983220, 7046, 7102, 7103, 7062, 7100, 7068, 7099, 7067, + 7087, 7070, 7048, 7049, 7053, 7057, 7060, 7101, 7064, 7086, 7050, 7054, + 7059, 7052, 7072, 7055, 7065, 7061, 7051, 7058, 7063, 7069, 7071, 7066, + 7056, 7044, 7047, 7045, 7367, 7366, 7365, 7364, 7363, 7361, 7362, 7360, + 7082, 7041, 7042, 7040, 7083, 7080, 7081, 7079, 7077, 7076, 7078, 7093, + 7092, 7095, 7094, 7091, 7090, 7088, 7097, 7089, 7096, 127749, 127748, + 127751, 127803, 8316, 8312, 8305, 8319, 8317, 8314, 8315, 8318, 8309, + 8308, 8311, 8310, 179, 178, 8304, 8313, 185, 10966, 10964, 10619, 10968, + 10967, 8835, 10954, 10950, 10952, 10956, 8843, 8839, 10948, 10944, 10946, + 10942, 10185, 129464, 129465, 8751, 127940, 128671, 127843, 128629, + 129442, 127946, 8275, 43027, 43026, 43031, 43030, 43040, 43038, 43025, + 43024, 43029, 43028, 43036, 43035, 43021, 43020, 43018, 43017, 43023, + 43022, 43016, 43015, 43034, 43033, 43042, 43039, 43037, 43032, 43041, + 43008, 43012, 43009, 43013, 43011, 43048, 43049, 43050, 43051, 43052, + 43019, 43014, 43010, 43047, 43043, 43046, 43044, 43045, 9223, 9224, 9229, + 9240, 9232, 9236, 9235, 9234, 9233, 9249, 9253, 9241, 9220, 9239, 9219, + 9221, 9243, 9244, 9228, 9225, 9227, 9226, 128325, 9237, 9252, 9216, 9222, + 9246, 9245, 9247, 8527, 9230, 9231, 9217, 9218, 9242, 9254, 9238, 9248, + 11159, 9007, 983094, 983093, 128333, 1807, 1866, 1802, 1798, 1799, 1849, + 1848, 1792, 1854, 1853, 1805, 1804, 1803, 1852, 1851, 1850, 1797, 1814, + 1813, 1815, 1818, 1824, 2153, 2152, 2149, 2148, 2144, 2146, 2150, 2147, + 2154, 2145, 2151, 1825, 1830, 1837, 1839, 1838, 1831, 1834, 1827, 1869, + 1870, 1871, 1809, 1835, 1832, 1828, 1808, 1823, 1833, 1819, 1820, 1836, + 1811, 1812, 1821, 1822, 1810, 1817, 1826, 1816, 1829, 1864, 1863, 1842, + 1841, 1840, 1845, 1844, 1843, 1847, 1846, 1855, 1858, 1796, 983204, 1801, + 1794, 1795, 1800, 1793, 1862, 1861, 1860, 1859, 1865, 1856, 1857, 128137, + 983184, 128085, 129430, 983061, 127955, 917543, 917542, 917546, 917598, + 917568, 917548, 917562, 917540, 917557, 917556, 917559, 917558, 917555, + 917554, 917552, 917561, 917553, 917560, 917565, 917537, 917600, 917566, + 917549, 917569, 917570, 917571, 917572, 917573, 917574, 917575, 917576, + 917577, 917578, 917579, 917580, 917581, 917582, 917583, 917584, 917585, + 917586, 917587, 917588, 917589, 917590, 917591, 917592, 917593, 917594, + 917601, 917602, 917603, 917604, 917605, 917606, 917607, 917608, 917609, + 917610, 917611, 917612, 917613, 917614, 917615, 917616, 917617, 917618, + 917619, 917620, 917621, 917622, 917623, 917624, 917625, 917626, 917564, + 917627, 917544, 917595, 917599, 917541, 917547, 917538, 917567, 917629, + 917545, 917597, 917596, 917563, 917551, 917536, 917539, 917630, 917550, + 917628, 5888, 5919, 5893, 5896, 5898, 5895, 5892, 5905, 5891, 5902, 5899, + 5897, 5901, 5904, 5894, 5903, 5900, 5889, 5890, 5909, 5908, 5906, 5907, + 5989, 5992, 5994, 5991, 5988, 5987, 5998, 5995, 5993, 6000, 5990, 5999, + 5996, 5984, 5985, 5986, 6002, 6003, 6499, 6508, 6509, 6507, 6501, 6502, + 6512, 6513, 6514, 6515, 6516, 6497, 6483, 6487, 6486, 6482, 6498, 6505, + 6504, 6496, 6480, 6490, 6489, 6503, 6506, 6492, 6494, 6488, 6491, 6495, + 6484, 6493, 6481, 6485, 6500, 6745, 6746, 6743, 6747, 6742, 6741, 6748, + 6749, 6750, 6783, 6789, 6788, 6791, 6790, 6787, 6786, 6784, 6793, 6785, + 6792, 6805, 6804, 6807, 6806, 6803, 6802, 6800, 6809, 6801, 6808, 6740, + 6689, 6690, 6688, 6702, 6726, 6727, 6728, 6696, 6695, 6713, 6712, 6707, + 6706, 6714, 6729, 6720, 6693, 6692, 6691, 6704, 6699, 6697, 6717, 6715, + 6709, 6708, 6716, 6732, 6698, 6719, 6723, 6739, 6724, 6730, 6721, 6705, + 6701, 6722, 6735, 6736, 6733, 6734, 6694, 6700, 6710, 6738, 6737, 6711, + 6703, 6718, 6725, 6731, 6828, 6820, 6775, 6776, 6777, 6780, 6824, 6825, + 6819, 6772, 6744, 6823, 6779, 6778, 6822, 6826, 6827, 6818, 6752, 6816, + 6817, 6773, 6774, 6821, 6829, 6753, 6755, 6767, 6769, 6754, 6763, 6764, + 6771, 6768, 6765, 6756, 6770, 6761, 6762, 6760, 6759, 6757, 6758, 6766, + 43653, 43651, 43649, 43661, 43659, 43679, 43677, 43671, 43669, 43657, + 43665, 43673, 43675, 43667, 43681, 43655, 43693, 43689, 43683, 43687, + 43663, 43691, 43685, 43695, 43652, 43650, 43648, 43660, 43658, 43678, + 43676, 43670, 43668, 43656, 43664, 43672, 43674, 43666, 43680, 43654, + 43692, 43688, 43682, 43686, 43662, 43690, 43684, 43694, 43696, 43703, + 43743, 43739, 43740, 43742, 43741, 43712, 43713, 43714, 43711, 43707, + 43697, 43710, 43709, 43708, 43700, 43699, 43705, 43706, 43698, 43704, + 43701, 43702, 71353, 71296, 71352, 71297, 71303, 71305, 71338, 71332, + 71319, 71318, 71324, 71323, 71317, 71316, 71322, 71321, 71300, 71301, + 71298, 71299, 71310, 71320, 71315, 71325, 71329, 71328, 71312, 71311, + 71309, 71308, 71314, 71313, 71307, 71306, 71327, 71326, 71335, 71336, + 71337, 71333, 71330, 71334, 71331, 71302, 71304, 71351, 71339, 71350, + 71340, 71341, 71347, 71349, 71344, 71345, 71342, 71343, 71346, 71348, + 71365, 71364, 71367, 71366, 71363, 71362, 71360, 71369, 71361, 71368, + 129377, 119672, 119671, 3064, 3031, 73707, 983662, 983685, 983674, + 983677, 983676, 983669, 983667, 983679, 983663, 983665, 983668, 983666, + 983683, 983681, 983682, 983673, 983678, 983664, 983684, 983680, 983671, + 983670, 983675, 983672, 73706, 3063, 73701, 3062, 3059, 3051, 3050, 3053, + 3052, 3049, 3048, 3046, 3055, 3047, 3054, 73700, 73666, 73676, 73668, + 73679, 73681, 73682, 73665, 73673, 73674, 73667, 73664, 73669, 73672, + 73675, 73680, 73670, 73678, 73671, 73677, 73683, 73684, 73710, 2985, + 2979, 2969, 2974, 2984, 2975, 2980, 2996, 2995, 2994, 2993, 2992, 2949, + 2950, 2960, 2964, 2953, 2954, 2962, 2963, 2951, 2952, 2998, 2999, 3000, + 2958, 2959, 2970, 3001, 2972, 2965, 2990, 2986, 2997, 2991, 73702, 3057, + 3058, 3056, 3066, 73727, 3065, 73703, 73687, 2946, 73686, 73698, 73690, + 73693, 73692, 73712, 73689, 73688, 73691, 73697, 73694, 73695, 73696, + 73713, 73699, 3021, 2947, 73685, 73708, 73711, 983939, 983940, 983947, + 983950, 983943, 983944, 983948, 983949, 983941, 983942, 983945, 983946, + 983686, 983693, 983696, 983689, 983690, 983694, 983695, 983687, 983688, + 983691, 983692, 983840, 983847, 983850, 983843, 983844, 983848, 983849, + 983841, 983842, 983845, 983846, 983851, 983858, 983861, 983854, 983855, + 983859, 983860, 983852, 983853, 983856, 983857, 983818, 983825, 983828, + 983821, 983822, 983826, 983827, 983819, 983820, 983823, 983824, 983873, + 983880, 983883, 983876, 983877, 983881, 983882, 983874, 983875, 983878, + 983879, 983741, 983748, 983751, 983744, 983745, 983749, 983750, 983742, + 983743, 983746, 983747, 983697, 983704, 983707, 983700, 983701, 983705, + 983706, 983698, 983699, 983702, 983703, 983719, 983726, 983729, 983722, + 983723, 983727, 983728, 983720, 983721, 983724, 983725, 983763, 983770, + 983773, 983766, 983767, 983771, 983772, 983764, 983765, 983768, 983769, + 983862, 983869, 983872, 983865, 983866, 983870, 983871, 983863, 983864, + 983867, 983868, 983807, 983814, 983817, 983810, 983811, 983815, 983816, + 983808, 983809, 983812, 983813, 983895, 983902, 983905, 983898, 983899, + 983903, 983904, 983951, 983896, 983897, 983900, 983901, 983906, 983913, + 983916, 983909, 983910, 983914, 983915, 983907, 983908, 983911, 983912, + 983917, 983924, 983927, 983920, 983921, 983925, 983926, 983918, 983919, + 983922, 983923, 983730, 983737, 983740, 983733, 983734, 983738, 983739, + 983731, 983732, 983735, 983736, 983752, 983759, 983762, 983755, 983756, + 983760, 983761, 983753, 983754, 983757, 983758, 983708, 983715, 983718, + 983711, 983712, 983716, 983717, 983709, 983710, 983713, 983714, 983928, + 983935, 983938, 983931, 983932, 983936, 983937, 983929, 983930, 983933, + 983934, 983884, 983891, 983894, 983887, 983888, 983892, 983893, 983885, + 983886, 983889, 983890, 983785, 983792, 983795, 983788, 983789, 983793, + 983794, 983786, 983787, 983790, 983791, 983774, 983781, 983784, 983777, + 983778, 983782, 983783, 983775, 983776, 983779, 983780, 983829, 983836, + 983839, 983832, 983833, 983837, 983838, 983830, 983831, 983834, 983835, + 983796, 983803, 983806, 983799, 983800, 983804, 983805, 983797, 983798, + 983801, 983802, 3006, 3016, 3020, 3009, 3010, 3018, 3019, 3007, 3008, + 3014, 3015, 73709, 73704, 73705, 3061, 3060, 3024, 129748, 127883, + 127818, 92809, 92810, 92811, 92808, 92789, 92790, 92791, 92788, 92816, + 92859, 92856, 92847, 92845, 92817, 92846, 92843, 92829, 92830, 92831, + 92828, 92835, 92851, 92840, 92844, 92818, 92819, 92852, 92836, 92825, + 92826, 92827, 92824, 92813, 92814, 92815, 92812, 92820, 92822, 92823, + 92821, 92805, 92806, 92807, 92804, 92797, 92798, 92799, 92796, 92801, + 92802, 92803, 92800, 92785, 92786, 92787, 92784, 92793, 92794, 92795, + 92792, 92857, 92854, 92848, 92861, 92853, 92860, 92849, 92855, 92834, + 92833, 92832, 92841, 92839, 92842, 92850, 92838, 92858, 92837, 92862, + 92869, 92868, 92871, 92870, 92867, 92866, 92864, 92873, 92865, 92872, + 100352, 100353, 100354, 100355, 100356, 100357, 100358, 100359, 100360, + 100361, 100362, 100363, 100364, 100365, 100366, 100367, 100368, 100369, + 100370, 100371, 100372, 100373, 100374, 100375, 100376, 100377, 100378, + 100379, 100380, 100381, 100382, 100383, 100384, 100385, 100386, 100387, + 100388, 100389, 100390, 100391, 100392, 100393, 100394, 100395, 100396, + 100397, 100398, 100399, 100400, 100401, 100402, 100403, 100404, 100405, + 100406, 100407, 100408, 100409, 100410, 100411, 100412, 100413, 100414, + 100415, 100416, 100417, 100418, 100419, 100420, 100421, 100422, 100423, + 100424, 100425, 100426, 100427, 100428, 100429, 100430, 100431, 100432, + 100433, 100434, 100435, 100436, 100437, 100438, 100439, 100440, 100441, + 100442, 100443, 100444, 100445, 100446, 100447, 100448, 100449, 100450, + 100451, 100452, 100453, 100454, 100455, 100456, 100457, 100458, 100459, + 100460, 100461, 100462, 100463, 100464, 100465, 100466, 100467, 100468, + 100469, 100470, 100471, 100472, 100473, 100474, 100475, 100476, 100477, + 100478, 100479, 100480, 100481, 100482, 100483, 100484, 100485, 100486, + 100487, 100488, 100489, 100490, 100491, 100492, 100493, 100494, 100495, + 100496, 100497, 100498, 100499, 100500, 100501, 100502, 100503, 100504, + 100505, 100506, 100507, 100508, 100509, 100510, 100511, 100512, 100513, + 100514, 100515, 100516, 100517, 100518, 100519, 100520, 100521, 100522, + 100523, 100524, 100525, 100526, 100527, 100528, 100529, 100530, 100531, + 100532, 100533, 100534, 100535, 100536, 100537, 100538, 100539, 100540, + 100541, 100542, 100543, 100544, 100545, 100546, 100547, 100548, 100549, + 100550, 100551, 100552, 100553, 100554, 100555, 100556, 100557, 100558, + 100559, 100560, 100561, 100562, 100563, 100564, 100565, 100566, 100567, + 100568, 100569, 100570, 100571, 100572, 100573, 100574, 100575, 100576, + 100577, 100578, 100579, 100580, 100581, 100582, 100583, 100584, 100585, + 100586, 100587, 100588, 100589, 100590, 100591, 100592, 100593, 100594, + 100595, 100596, 100597, 100598, 100599, 100600, 100601, 100602, 100603, + 100604, 100605, 100606, 100607, 100608, 100609, 100610, 100611, 100612, + 100613, 100614, 100615, 100616, 100617, 100618, 100619, 100620, 100621, + 100622, 100623, 100624, 100625, 100626, 100627, 100628, 100629, 100630, + 100631, 100632, 100633, 100634, 100635, 100636, 100637, 100638, 100639, + 100640, 100641, 100642, 100643, 100644, 100645, 100646, 100647, 100648, + 100649, 100650, 100651, 100652, 100653, 100654, 100655, 100656, 100657, + 100658, 100659, 100660, 100661, 100662, 100663, 100664, 100665, 100666, + 100667, 100668, 100669, 100670, 100671, 100672, 100673, 100674, 100675, + 100676, 100677, 100678, 100679, 100680, 100681, 100682, 100683, 100684, + 100685, 100686, 100687, 100688, 100689, 100690, 100691, 100692, 100693, + 100694, 100695, 100696, 100697, 100698, 100699, 100700, 100701, 100702, + 100703, 100704, 100705, 100706, 100707, 100708, 100709, 100710, 100711, + 100712, 100713, 100714, 100715, 100716, 100717, 100718, 100719, 100720, + 100721, 100722, 100723, 100724, 100725, 100726, 100727, 100728, 100729, + 100730, 100731, 100732, 100733, 100734, 100735, 100736, 100737, 100738, + 100739, 100740, 100741, 100742, 100743, 100744, 100745, 100746, 100747, + 100748, 100749, 100750, 100751, 100752, 100753, 100754, 100755, 100756, + 100757, 100758, 100759, 100760, 100761, 100762, 100763, 100764, 100765, + 100766, 100767, 100768, 100769, 100770, 100771, 100772, 100773, 100774, + 100775, 100776, 100777, 100778, 100779, 100780, 100781, 100782, 100783, + 100784, 100785, 100786, 100787, 100788, 100789, 100790, 100791, 100792, + 100793, 100794, 100795, 100796, 100797, 100798, 100799, 100800, 100801, + 100802, 100803, 100804, 100805, 100806, 100807, 100808, 100809, 100810, + 100811, 100812, 100813, 100814, 100815, 100816, 100817, 100818, 100819, + 100820, 100821, 100822, 100823, 100824, 100825, 100826, 100827, 100828, + 100829, 100830, 100831, 100832, 100833, 100834, 100835, 100836, 100837, + 100838, 100839, 100840, 100841, 100842, 100843, 100844, 100845, 100846, + 100847, 100848, 100849, 100850, 100851, 100852, 100853, 100854, 100855, + 100856, 100857, 100858, 100859, 100860, 100861, 100862, 100863, 100864, + 100865, 100866, 100867, 100868, 100869, 100870, 100871, 100872, 100873, + 100874, 100875, 100876, 100877, 100878, 100879, 100880, 100881, 100882, + 100883, 100884, 100885, 100886, 100887, 100888, 100889, 100890, 100891, + 100892, 100893, 100894, 100895, 100896, 100897, 100898, 100899, 100900, + 100901, 100902, 100903, 100904, 100905, 100906, 100907, 100908, 100909, + 100910, 100911, 100912, 100913, 100914, 100915, 100916, 100917, 100918, + 100919, 100920, 100921, 100922, 100923, 100924, 100925, 100926, 100927, + 100928, 100929, 100930, 100931, 100932, 100933, 100934, 100935, 100936, + 100937, 100938, 100939, 100940, 100941, 100942, 100943, 100944, 100945, + 100946, 100947, 100948, 100949, 100950, 100951, 100952, 100953, 100954, + 100955, 100956, 100957, 100958, 100959, 100960, 100961, 100962, 100963, + 100964, 100965, 100966, 100967, 100968, 100969, 100970, 100971, 100972, + 100973, 100974, 100975, 100976, 100977, 100978, 100979, 100980, 100981, + 100982, 100983, 100984, 100985, 100986, 100987, 100988, 100989, 100990, + 100991, 100992, 100993, 100994, 100995, 100996, 100997, 100998, 100999, + 101000, 101001, 101002, 101003, 101004, 101005, 101006, 101007, 101008, + 101009, 101010, 101011, 101012, 101013, 101014, 101015, 101016, 101017, + 101018, 101019, 101020, 101021, 101022, 101023, 101024, 101025, 101026, + 101027, 101028, 101029, 101030, 101031, 101032, 101033, 101034, 101035, + 101036, 101037, 101038, 101039, 101040, 101041, 101042, 101043, 101044, + 101045, 101046, 101047, 101048, 101049, 101050, 101051, 101052, 101053, + 101054, 101055, 101056, 101057, 101058, 101059, 101060, 101061, 101062, + 101063, 101064, 101065, 101066, 101067, 101068, 101069, 101070, 101071, + 101072, 101073, 101074, 101075, 101076, 101077, 101078, 101079, 101080, + 101081, 101082, 101083, 101084, 101085, 101086, 101087, 101088, 101089, + 101090, 101091, 101092, 101093, 101094, 101095, 101096, 101097, 101098, + 101099, 101100, 101101, 101102, 101103, 101104, 101105, 101106, 101107, + 101108, 101109, 101110, 101111, 101112, 101113, 101114, 101115, 101116, + 101117, 101118, 101119, 94176, 128429, 9991, 9801, 127790, 128661, + 127861, 128198, 10043, 10170, 129750, 129528, 128222, 128380, 8981, 9990, + 8481, 128384, 128301, 128250, 3158, 3195, 3198, 3194, 3197, 3193, 3196, + 3192, 3106, 3105, 3111, 3161, 3110, 3124, 3123, 3122, 3112, 3165, 3097, + 3107, 3102, 3162, 3121, 3120, 3104, 3103, 3109, 3160, 3108, 3077, 3078, + 3088, 3092, 3083, 3168, 3084, 3169, 3125, 3081, 3082, 3090, 3091, 3079, + 3080, 3126, 3127, 3128, 3117, 3116, 3099, 3098, 3096, 3095, 3101, 3100, + 3094, 3093, 3115, 3114, 3086, 3087, 3129, 3118, 3119, 3157, 3076, 3072, + 3073, 3191, 3199, 3133, 3074, 3132, 3149, 3075, 3134, 3144, 3148, 3139, + 3140, 3170, 3171, 3137, 3138, 3146, 3147, 3135, 3136, 3142, 3143, 3179, + 3178, 3181, 3180, 3177, 3176, 3174, 3183, 3175, 3182, 127934, 8376, 9978, + 129514, 119617, 119564, 119577, 119633, 119587, 119566, 119561, 119585, + 119613, 119590, 119631, 119634, 119630, 119608, 119582, 119563, 119573, + 119558, 119624, 119567, 119623, 119586, 119636, 119612, 119625, 119568, + 119584, 119619, 119618, 119583, 119603, 119600, 119626, 119610, 119580, + 119576, 119638, 119559, 119595, 119632, 119606, 119592, 119615, 119599, + 119602, 119614, 119629, 119574, 119569, 119570, 119622, 119562, 119591, + 119637, 119597, 119589, 119616, 119609, 119560, 119635, 119565, 119604, + 119588, 119571, 119594, 119578, 119596, 119579, 119598, 119572, 119605, + 119627, 119621, 119628, 119601, 119593, 119607, 119575, 119620, 119611, + 119581, 1959, 1958, 1964, 1961, 1965, 1927, 1954, 1951, 1937, 1931, 1930, + 1956, 1934, 1935, 1955, 1945, 1920, 1926, 1946, 1933, 1925, 1929, 1943, + 1942, 1941, 1922, 1969, 1950, 1949, 1921, 1936, 1939, 1932, 1947, 1944, + 1952, 1928, 1957, 1938, 1948, 1953, 1924, 1923, 1940, 1967, 1966, 1963, + 1960, 1962, 1968, 3610, 3592, 3594, 3593, 3596, 3598, 3604, 3613, 3615, + 3663, 3630, 3627, 3588, 3587, 3589, 3586, 3590, 3675, 3585, 3628, 3621, + 3653, 3622, 3659, 3633, 3657, 3658, 3656, 3655, 3654, 3617, 3674, 3591, + 3661, 3603, 3609, 3631, 3642, 3612, 3614, 3616, 3611, 3619, 3620, 3632, + 3652, 3651, 3634, 3649, 3635, 3640, 3638, 3639, 3641, 3636, 3637, 3648, + 3650, 3625, 3624, 3626, 3595, 3660, 3601, 3602, 3607, 3600, 3608, 3606, + 3605, 3599, 3623, 3662, 3597, 3618, 3629, 3647, 3669, 3668, 3671, 3670, + 3667, 3666, 3664, 3673, 3665, 3672, 8708, 8707, 8756, 127777, 10727, + 128936, 8201, 128929, 129300, 129353, 128173, 129652, 10176, 8278, 9887, + 9886, 11057, 128485, 128484, 128486, 128487, 8694, 128433, 10870, 128491, + 128962, 128423, 11160, 11162, 10146, 11163, 11161, 10147, 8196, 11835, + 128077, 128078, 9928, 9736, 3865, 3863, 3864, 4032, 4033, 4035, 4034, + 3886, 3885, 3888, 3887, 3884, 3883, 3891, 3890, 3882, 3889, 3877, 3876, + 3879, 3878, 3875, 3874, 3872, 3881, 3873, 3880, 4030, 4031, 3945, 3905, + 3947, 3904, 3948, 3938, 3946, 3917, 3916, 3932, 3931, 3922, 3921, 3908, + 3918, 3913, 3923, 3940, 3941, 3942, 3930, 3929, 3915, 3914, 3920, 3919, + 3927, 3926, 3910, 3909, 3907, 3906, 3925, 3924, 3934, 3935, 3936, 3943, + 3911, 3939, 3928, 3933, 3937, 3944, 3862, 3861, 983210, 3850, 4048, 3849, + 3892, 4049, 3894, 3859, 3846, 3896, 4052, 3845, 3847, 3842, 3843, 3841, + 3860, 3898, 3899, 3900, 3901, 3972, 4051, 3844, 3851, 3895, 3893, 4050, + 3856, 3854, 3973, 3858, 3857, 3848, 3853, 4058, 3897, 3855, 4057, 3852, + 3978, 3979, 3974, 3976, 3903, 3977, 3970, 3866, 3867, 3868, 3871, 3869, + 3870, 4047, 4046, 3966, 3967, 3975, 3902, 3980, 3971, 4028, 4026, 4027, + 3997, 3996, 4012, 4011, 4002, 4001, 4025, 3985, 3984, 3988, 3998, 3993, + 4003, 4020, 4021, 4022, 4010, 4009, 3995, 3994, 4000, 3999, 4007, 4006, + 3990, 3989, 3987, 3986, 4005, 4004, 4014, 4015, 4016, 4023, 3991, 4019, + 4008, 4018, 4013, 4017, 4024, 3983, 3982, 3981, 3840, 4036, 4041, 4044, + 4043, 4042, 4038, 4040, 4037, 4039, 3968, 3969, 3958, 3959, 3960, 3961, + 3956, 3957, 3964, 3965, 3954, 3955, 3962, 3963, 3953, 10717, 11647, + 11608, 11595, 11585, 11573, 11620, 11607, 11600, 11582, 11590, 11596, + 11601, 11586, 11592, 11568, 11575, 11577, 11578, 11576, 11571, 11606, + 11572, 11581, 11589, 11583, 11569, 11570, 11584, 11587, 11609, 11611, + 11610, 11612, 11613, 11615, 11619, 11594, 11621, 11604, 11605, 11614, + 11588, 11580, 11574, 11597, 11598, 11599, 11602, 11591, 11616, 11617, + 11618, 11622, 11579, 11593, 11623, 11603, 11631, 11632, 128005, 128047, + 10053, 126, 8764, 11081, 10610, 10859, 10858, 11807, 11806, 11803, 9202, + 10708, 10709, 10750, 68410, 70854, 70784, 70785, 70786, 70796, 70798, + 70812, 70811, 70817, 70816, 70810, 70809, 70815, 70814, 70791, 70792, + 70793, 70794, 70827, 70789, 70790, 70787, 70788, 70803, 70813, 70808, + 70818, 70828, 70829, 70830, 70822, 70821, 70805, 70804, 70802, 70801, + 70807, 70806, 70800, 70799, 70820, 70819, 70831, 70826, 70823, 70825, + 70824, 70795, 70797, 70852, 70848, 70847, 70851, 70850, 70849, 70832, + 70843, 70846, 70842, 70845, 70837, 70838, 70839, 70840, 70835, 70836, + 70833, 70834, 70841, 70844, 70869, 70868, 70871, 70870, 70867, 70866, + 70864, 70873, 70865, 70872, 70853, 70855, 11858, 8266, 128555, 127915, + 127813, 128069, 129463, 129701, 129520, 10554, 10557, 10556, 9182, 11210, + 11865, 11866, 11833, 8992, 127913, 9180, 8988, 8975, 11810, 8989, 8974, + 11811, 9140, 9184, 128285, 127553, 127554, 127559, 127555, 127557, + 127560, 127552, 127556, 127558, 127274, 9008, 123554, 123556, 123559, + 123561, 123564, 123537, 123553, 123555, 123544, 123543, 123558, 123560, + 123546, 123565, 123563, 123539, 123541, 123550, 123549, 123540, 123552, + 123542, 123536, 123551, 123545, 123538, 123548, 123547, 123562, 123557, + 123566, 128701, 128508, 128434, 128668, 8482, 128650, 128651, 11223, + 10971, 128646, 10701, 10699, 128710, 10698, 10141, 128681, 128208, 8227, + 128305, 9783, 9776, 9777, 9782, 9779, 9781, 9780, 9778, 10998, 10856, + 10857, 10747, 8244, 8779, 10996, 10624, 8874, 10997, 11003, 11851, 11000, + 10999, 8749, 8285, 129484, 128654, 127865, 128032, 127942, 8872, 11231, + 127930, 8366, 8378, 129411, 8523, 10658, 11202, 9930, 9929, 8498, 11826, + 11832, 8587, 8586, 128598, 128596, 8985, 128399, 8513, 8514, 8516, 11829, + 8526, 128599, 128597, 8489, 128034, 129347, 127799, 10041, 128256, 8273, + 128432, 10869, 8229, 8282, 11818, 128149, 10837, 10838, 10697, 10760, + 10759, 128108, 128109, 128490, 11834, 66432, 66451, 66454, 66433, 66436, + 66447, 66457, 66434, 66437, 66440, 66443, 66435, 66445, 66455, 66453, + 66450, 66444, 66461, 66456, 66441, 66458, 66442, 66439, 66449, 66448, + 66452, 66438, 66446, 66459, 66460, 66463, 9730, 9969, 9748, 128530, + 11217, 8255, 9100, 8746, 10824, 10822, 10826, 10817, 10818, 10821, + 983116, 11258, 9842, 129412, 9903, 10685, 8963, 8996, 11193, 10577, + 10573, 10572, 10575, 8597, 8616, 11021, 8661, 129113, 8691, 11109, 10622, + 8944, 8869, 10207, 128742, 128744, 128316, 128743, 128314, 9709, 9710, + 129898, 129946, 129920, 129896, 9985, 129924, 9600, 129937, 129938, 9690, + 129934, 9696, 129885, 129887, 129889, 129886, 129883, 129888, 129881, + 129884, 129882, 129879, 129880, 10196, 129944, 129948, 9720, 9136, 9692, + 129922, 9620, 129874, 129875, 129892, 129894, 129890, 129878, 129893, + 129891, 129876, 129895, 129877, 10064, 9137, 10000, 9693, 128319, 10066, + 129945, 129949, 9721, 129926, 129923, 129925, 129901, 128579, 11797, + 8593, 129976, 8645, 8670, 129033, 129029, 129177, 129041, 129025, 129045, + 8624, 8625, 10505, 8613, 10514, 11145, 11014, 8657, 8673, 129077, 10606, + 10595, 10592, 10584, 8639, 10588, 10580, 8638, 129089, 129093, 129085, + 10224, 128621, 129105, 129081, 11105, 11137, 11121, 129065, 11170, 11171, + 129061, 129057, 129073, 129069, 11131, 11115, 11141, 129169, 10506, 8607, + 11245, 10569, 8648, 8679, 8682, 11192, 8683, 8684, 8685, 129173, 8686, + 8687, 9797, 983117, 42509, 42510, 42511, 42446, 42370, 42486, 42257, + 42333, 42294, 42407, 42445, 42369, 42485, 42256, 42332, 42293, 42406, + 42449, 42373, 42489, 42260, 42336, 42297, 42410, 42434, 42359, 42473, + 42246, 42321, 42283, 42396, 42435, 42360, 42474, 42247, 42322, 42284, + 42397, 42452, 42376, 42492, 42263, 42339, 42300, 42413, 42451, 42375, + 42491, 42262, 42338, 42299, 42412, 42444, 42368, 42484, 42255, 42331, + 42292, 42405, 42443, 42367, 42483, 42254, 42330, 42291, 42404, 42454, + 42378, 42494, 42265, 42341, 42302, 42415, 42453, 42377, 42493, 42264, + 42340, 42301, 42414, 42439, 42440, 42364, 42479, 42251, 42480, 42327, + 42288, 42401, 42502, 42272, 42503, 42461, 42385, 42349, 42309, 42422, + 42429, 42430, 42355, 42468, 42242, 42469, 42316, 42317, 42278, 42279, + 42391, 42392, 42476, 42249, 42477, 42437, 42362, 42324, 42325, 42286, + 42399, 42459, 42383, 42346, 42347, 42499, 42270, 42307, 42420, 42487, + 42508, 42258, 42447, 42371, 42334, 42295, 42408, 42436, 42361, 42475, + 42248, 42323, 42285, 42398, 42438, 42363, 42478, 42250, 42326, 42287, + 42400, 42462, 42386, 42504, 42273, 42350, 42310, 42423, 42450, 42514, + 42539, 42512, 42513, 42538, 42374, 42490, 42261, 42337, 42298, 42411, + 42507, 42500, 42271, 42501, 42460, 42384, 42348, 42308, 42421, 42315, + 42467, 42428, 42457, 42381, 42497, 42268, 42344, 42305, 42418, 42464, + 42388, 42506, 42275, 42352, 42312, 42425, 42463, 42387, 42505, 42274, + 42351, 42311, 42424, 42455, 42379, 42495, 42266, 42342, 42303, 42416, + 42441, 42365, 42481, 42252, 42328, 42289, 42402, 42456, 42380, 42496, + 42267, 42343, 42304, 42417, 42433, 42358, 42472, 42245, 42320, 42282, + 42395, 42448, 42372, 42488, 42259, 42335, 42296, 42409, 42442, 42366, + 42482, 42253, 42329, 42290, 42403, 42458, 42382, 42498, 42269, 42345, + 42306, 42419, 42470, 42243, 42244, 42471, 42431, 42356, 42357, 42432, + 42318, 42319, 42280, 42281, 42393, 42394, 42465, 42240, 42241, 42466, + 42426, 42353, 42354, 42427, 42313, 42314, 42276, 42277, 42389, 42390, + 42523, 42526, 42522, 42515, 42520, 42527, 42516, 42524, 42518, 42517, + 42525, 42521, 42519, 42533, 42532, 42535, 42534, 42531, 42530, 42528, + 42537, 42529, 42536, 65024, 65033, 917843, 917844, 917845, 917846, + 917847, 917848, 917849, 917850, 917851, 917852, 65034, 917853, 917854, + 917855, 917856, 917857, 917858, 917859, 917860, 917861, 917862, 65035, + 917863, 917864, 917865, 917866, 917867, 917868, 917869, 917870, 917871, + 917872, 65036, 917873, 917874, 917875, 917876, 917877, 917878, 917879, + 917880, 917881, 917882, 65037, 917883, 917884, 917885, 917886, 917887, + 917888, 917889, 917890, 917891, 917892, 65038, 917893, 917894, 917895, + 917896, 917897, 917898, 917899, 917900, 917901, 917902, 65039, 917903, + 917904, 917905, 917906, 917907, 917908, 917909, 917910, 917911, 917912, + 917760, 917913, 917914, 917915, 917916, 917917, 917918, 917919, 917920, + 917921, 917922, 917761, 917923, 917924, 917925, 917926, 917927, 917928, + 917929, 917930, 917931, 917932, 917762, 917933, 917934, 917935, 917936, + 917937, 917938, 917939, 917940, 917941, 917942, 65025, 917763, 917943, + 917944, 917945, 917946, 917947, 917948, 917949, 917950, 917951, 917952, + 917764, 917953, 917954, 917955, 917956, 917957, 917958, 917959, 917960, + 917961, 917962, 917765, 917963, 917964, 917965, 917966, 917967, 917968, + 917969, 917970, 917971, 917972, 917766, 917973, 917974, 917975, 917976, + 917977, 917978, 917979, 917980, 917981, 917982, 917767, 917983, 917984, + 917985, 917986, 917987, 917988, 917989, 917990, 917991, 917992, 917768, + 917993, 917994, 917995, 917996, 917997, 917998, 917999, 917769, 917770, + 917771, 917772, 65026, 917773, 917774, 917775, 917776, 917777, 917778, + 917779, 917780, 917781, 917782, 65027, 917783, 917784, 917785, 917786, + 917787, 917788, 917789, 917790, 917791, 917792, 65028, 917793, 917794, + 917795, 917796, 917797, 917798, 917799, 917800, 917801, 917802, 65029, + 917803, 917804, 917805, 917806, 917807, 917808, 917809, 917810, 917811, + 917812, 65030, 917813, 917814, 917815, 917816, 917817, 917818, 917819, + 917820, 917821, 917822, 65031, 917823, 917824, 917825, 917826, 917827, + 917828, 917829, 917830, 917831, 917832, 65032, 917833, 917834, 917835, + 917836, 917837, 917838, 917839, 917840, 917841, 917842, 129499, 983245, + 983254, 983356, 983357, 983358, 983359, 983360, 983361, 983362, 983363, + 983364, 983365, 983255, 983366, 983367, 983368, 983369, 983370, 983371, + 983372, 983373, 983374, 983375, 983256, 983376, 983377, 983378, 983379, + 983380, 983381, 983382, 983383, 983384, 983385, 983257, 983386, 983387, + 983388, 983389, 983390, 983391, 983392, 983393, 983394, 983395, 983258, + 983396, 983397, 983398, 983399, 983400, 983401, 983402, 983403, 983404, + 983405, 983259, 983406, 983407, 983408, 983409, 983410, 983411, 983412, + 983413, 983414, 983415, 983260, 983416, 983417, 983418, 983419, 983420, + 983421, 983422, 983423, 983424, 983425, 983273, 983426, 983427, 983428, + 983429, 983430, 983431, 983432, 983433, 983434, 983435, 983274, 983436, + 983437, 983438, 983439, 983440, 983441, 983442, 983443, 983444, 983445, + 983275, 983446, 983447, 983448, 983449, 983450, 983451, 983452, 983453, + 983454, 983455, 983246, 983276, 983456, 983457, 983458, 983459, 983460, + 983461, 983462, 983463, 983464, 983465, 983277, 983466, 983467, 983468, + 983469, 983470, 983471, 983472, 983473, 983474, 983475, 983278, 983476, + 983477, 983478, 983479, 983480, 983481, 983482, 983483, 983484, 983485, + 983279, 983486, 983487, 983488, 983489, 983490, 983491, 983492, 983493, + 983494, 983495, 983280, 983496, 983497, 983498, 983499, 983500, 983501, + 983502, 983503, 983504, 983505, 983281, 983506, 983507, 983508, 983509, + 983510, 983511, 983512, 983282, 983283, 983284, 983285, 983247, 983286, + 983287, 983288, 983289, 983290, 983291, 983292, 983293, 983294, 983295, + 983248, 983296, 983297, 983298, 983299, 983300, 983301, 983302, 983303, + 983304, 983305, 983249, 983306, 983307, 983308, 983309, 983310, 983311, + 983312, 983313, 983314, 983315, 983250, 983316, 983317, 983318, 983319, + 983320, 983321, 983322, 983323, 983324, 983325, 983251, 983326, 983327, + 983328, 983329, 983330, 983331, 983332, 983333, 983334, 983335, 983252, + 983336, 983337, 983338, 983339, 983340, 983341, 983342, 983343, 983344, + 983345, 983253, 983346, 983347, 983348, 983349, 983350, 983351, 983352, + 983353, 983354, 983355, 7401, 7402, 7409, 7403, 7404, 7415, 7410, 7418, + 7413, 7379, 7398, 7396, 7411, 7408, 7406, 7407, 7405, 7414, 7397, 7400, + 7395, 7399, 7394, 7380, 7384, 7412, 7417, 7386, 7389, 7376, 7388, 7378, + 7416, 7392, 7391, 7387, 7390, 7381, 7382, 7383, 7385, 7393, 7377, 8483, + 10704, 10980, 10978, 10186, 8942, 8286, 12347, 12337, 12339, 12341, + 12338, 12340, 124, 9168, 10992, 10991, 9087, 9896, 129904, 129905, + 129906, 129907, 129908, 129909, 11135, 983069, 983144, 11823, 128678, + 11837, 10650, 128976, 128959, 128947, 128637, 128941, 128953, 128636, + 128904, 128914, 128934, 8921, 8920, 128933, 10799, 9910, 128243, 9996, + 128249, 127918, 128252, 94193, 94192, 8983, 127931, 9805, 66929, 66930, + 66936, 66935, 66942, 66943, 66947, 66946, 66950, 66949, 66932, 66931, + 66934, 66933, 66957, 66956, 66959, 66958, 66941, 66940, 66937, 66944, + 66948, 66952, 66954, 66961, 66962, 66965, 66938, 66945, 66953, 66928, + 66951, 66960, 66964, 66968, 66969, 66975, 66974, 66981, 66982, 66986, + 66985, 66989, 66988, 66971, 66970, 66973, 66972, 66996, 66995, 66998, + 66997, 66980, 66979, 66976, 66983, 66987, 66991, 66993, 67000, 67001, + 67004, 66977, 66984, 66992, 66967, 66990, 66999, 67003, 129979, 127755, + 127952, 8752, 983070, 983145, 11238, 8541, 8538, 8536, 8539, 8533, 189, + 8529, 188, 8528, 8537, 8530, 8531, 8540, 190, 8535, 8534, 8532, 8542, + 8585, 123585, 123584, 123624, 123619, 123620, 123606, 123605, 123622, + 123618, 123611, 123623, 123612, 123621, 123615, 123592, 123613, 123625, + 123593, 123596, 123617, 123616, 123595, 123614, 123626, 123627, 123590, + 123609, 123604, 123591, 123594, 123599, 123598, 123586, 123587, 123588, + 123597, 123589, 123610, 123600, 123608, 123607, 123603, 123602, 123601, + 123647, 123630, 123631, 123628, 123629, 123637, 123636, 123639, 123638, + 123635, 123634, 123632, 123641, 123633, 123640, 127768, 127766, 127762, + 127764, 71841, 71850, 71862, 71861, 71848, 71856, 71853, 71867, 71866, + 71865, 71868, 71840, 71859, 71849, 71857, 71869, 71870, 71855, 71847, + 71843, 71854, 71844, 71845, 71858, 71871, 71863, 71864, 71852, 71846, + 71842, 71860, 71851, 71873, 71882, 71894, 71893, 71880, 71888, 71885, + 71899, 71898, 71897, 71900, 71872, 71891, 71881, 71889, 71901, 71902, + 71887, 71879, 71875, 71886, 71876, 71877, 71890, 71903, 71895, 71896, + 71884, 71878, 71874, 71892, 71883, 71909, 71908, 71911, 71910, 71907, + 71906, 71904, 71913, 71905, 71912, 71921, 71918, 71917, 71922, 71920, + 71919, 71916, 71915, 71914, 71935, 9888, 128702, 127754, 128003, 129341, + 127817, 8986, 12316, 11071, 10547, 127988, 127987, 128075, 12336, 65103, + 8967, 65099, 129479, 128465, 128576, 128553, 10172, 128146, 983238, + 127947, 9840, 128734, 9784, 9855, 129197, 129196, 9702, 9815, 129548, + 129590, 129608, 129611, 9812, 129545, 129587, 9816, 129542, 129563, + 129584, 129591, 129605, 129549, 129616, 129614, 129615, 9817, 129550, + 129592, 9813, 129546, 129588, 9814, 129547, 129589, 129569, 129566, + 129570, 129571, 129567, 129568, 9675, 128906, 9862, 10732, 9863, 9717, + 9718, 9716, 9719, 9831, 10209, 10210, 10211, 9671, 9672, 128922, 128923, + 10192, 9826, 9931, 128071, 128407, 9759, 9663, 9661, 9920, 9921, 10069, + 9872, 9983, 10048, 128174, 11214, 10023, 9785, 128427, 129293, 9825, + 9989, 129984, 11041, 11053, 10710, 11036, 128326, 9945, 128072, 9756, + 9669, 9667, 9665, 128928, 11046, 11088, 9725, 9723, 11048, 11229, 10001, + 9649, 11040, 127985, 10068, 11092, 9659, 9657, 9655, 128073, 9758, 9645, + 9988, 65094, 9750, 11051, 11090, 9643, 9786, 9828, 9633, 128307, 128916, + 9635, 128917, 10212, 9713, 9714, 10213, 9634, 9712, 9715, 9707, 9093, + 127779, 127781, 127782, 9788, 127780, 9734, 128382, 9743, 9186, 10177, + 9943, 128070, 9757, 129994, 9653, 9651, 9708, 11006, 11055, 9647, 11038, + 10163, 128011, 129144, 129152, 129120, 129136, 129128, 129146, 129154, + 129122, 129138, 129130, 129147, 129155, 129123, 129139, 129131, 129145, + 129153, 129121, 129137, 129129, 129149, 129157, 129125, 129141, 129133, + 129148, 129156, 129124, 129140, 129132, 129150, 129158, 129126, 129142, + 129134, 129151, 129159, 129127, 129143, 129135, 11838, 129344, 127888, + 127788, 129695, 127863, 128521, 129725, 128430, 128732, 128105, 128111, + 128098, 128090, 128082, 128097, 128698, 11825, 8288, 128506, 128543, + 129713, 8361, 129717, 128058, 127873, 8768, 129340, 128295, 9997, 983233, + 8999, 129659, 129644, 129643, 129641, 129639, 129642, 129645, 129640, + 129637, 129636, 129634, 129632, 129635, 129638, 129633, 8891, 129393, + 128155, 165, 69292, 69291, 69293, 69256, 69255, 69254, 69281, 69268, + 69259, 69248, 69271, 69289, 69286, 69287, 69257, 69278, 69277, 69279, + 69276, 69280, 69296, 69282, 69251, 69250, 69266, 69265, 69267, 69253, + 69252, 69269, 69274, 69275, 69284, 69285, 69272, 69258, 69288, 69297, + 69263, 69260, 69270, 69262, 69261, 69249, 69283, 69273, 69264, 42139, + 42149, 42173, 42172, 42132, 42147, 42179, 42174, 42148, 42169, 42150, + 42134, 42166, 42135, 42145, 42143, 42137, 42175, 42157, 42154, 42167, + 42165, 42163, 42130, 42182, 42129, 42171, 42138, 42140, 42136, 42131, + 42151, 42164, 42181, 42142, 42156, 42170, 42176, 42178, 42160, 42133, + 42144, 42152, 42159, 42161, 42158, 42141, 42146, 42177, 42180, 42155, + 42162, 42128, 42168, 42153, 41070, 41059, 41060, 41058, 41073, 41072, + 41071, 41068, 41069, 41066, 41067, 41065, 41048, 41052, 41053, 41050, + 41051, 41049, 41046, 41047, 41056, 41057, 41054, 41055, 41063, 41064, + 41061, 41062, 41076, 41077, 41074, 41075, 41006, 40995, 40996, 40994, + 41009, 41008, 41007, 41004, 41005, 41002, 41003, 41001, 40984, 40988, + 40989, 40986, 40987, 40985, 40982, 40983, 40992, 40993, 40990, 40991, + 40999, 41000, 40997, 40998, 41012, 41015, 41014, 41013, 41010, 41011, + 41842, 41831, 41832, 41829, 41830, 41845, 41844, 41843, 41841, 41827, + 41828, 41825, 41826, 41839, 41840, 41837, 41838, 41835, 41836, 41833, + 41834, 41848, 41851, 41850, 41849, 41846, 41847, 41670, 41659, 41660, + 41658, 41673, 41672, 41671, 41668, 41669, 41666, 41667, 41665, 41648, + 41652, 41653, 41650, 41651, 41649, 41646, 41647, 41656, 41657, 41654, + 41655, 41663, 41664, 41661, 41662, 41676, 41679, 41678, 41677, 41674, + 41675, 41293, 41282, 41283, 41281, 41296, 41295, 41294, 41291, 41292, + 41272, 41275, 41276, 41274, 41273, 41270, 41271, 41289, 41290, 41288, + 41279, 41280, 41277, 41278, 41286, 41287, 41284, 41285, 41238, 41228, + 41227, 41241, 41240, 41239, 41236, 41237, 41218, 41221, 41222, 41220, + 41219, 41216, 41217, 41234, 41235, 41233, 41225, 41226, 41223, 41224, + 41231, 41232, 41229, 41230, 41174, 41175, 41173, 41171, 41172, 41169, + 41170, 41167, 41168, 41165, 41166, 41184, 41185, 41182, 41183, 41178, + 41181, 41180, 41179, 41176, 41177, 41494, 41496, 41497, 41495, 41492, + 41493, 41516, 41504, 41505, 41502, 41503, 41519, 41518, 41517, 41514, + 41515, 41500, 41501, 41498, 41499, 41512, 41513, 41510, 41511, 41508, + 41509, 41506, 41507, 41460, 41448, 41449, 41446, 41447, 41463, 41462, + 41461, 41458, 41459, 41436, 41440, 41441, 41438, 41439, 41437, 41434, + 41435, 41444, 41445, 41442, 41443, 41456, 41457, 41454, 41455, 41452, + 41453, 41450, 41451, 41584, 41583, 41582, 41389, 41379, 41380, 41378, + 41392, 41391, 41390, 41387, 41388, 41369, 41372, 41373, 41371, 41370, + 41367, 41368, 41385, 41386, 41384, 41382, 41383, 41381, 41376, 41377, + 41374, 41375, 41395, 41398, 41397, 41396, 41393, 41394, 41125, 41117, + 41118, 41116, 41128, 41127, 41126, 41123, 41124, 41107, 41110, 41111, + 41109, 41108, 41105, 41106, 41114, 41115, 41112, 41113, 41121, 41122, + 41119, 41120, 41130, 41133, 41132, 41131, 41129, 41336, 41334, 41335, + 41333, 41332, 41340, 41338, 41339, 41337, 41322, 41326, 41327, 41324, + 41325, 41323, 41320, 41321, 41330, 41331, 41328, 41329, 41556, 41557, + 41554, 41555, 41563, 41564, 41562, 41544, 41548, 41549, 41546, 41547, + 41545, 41542, 41543, 41552, 41553, 41550, 41551, 41560, 41561, 41558, + 41559, 41591, 41592, 41589, 41590, 41598, 41599, 41597, 41587, 41588, + 41585, 41586, 41595, 41596, 41593, 41594, 40962, 40960, 983243, 40966, + 40967, 40964, 40965, 40963, 40961, 42025, 42017, 42018, 42016, 42028, + 42027, 42026, 42023, 42024, 42010, 42014, 42015, 42012, 42013, 42011, + 42008, 42009, 42021, 42022, 42019, 42020, 42031, 42032, 42029, 42030, + 41970, 41962, 41963, 41960, 41961, 41973, 41972, 41971, 41968, 41969, + 41954, 41958, 41959, 41956, 41957, 41955, 41952, 41953, 41966, 41967, + 41964, 41965, 41976, 41979, 41978, 41977, 41974, 41975, 41488, 41476, + 41477, 41475, 41491, 41490, 41489, 41486, 41487, 41466, 41469, 41470, + 41468, 41467, 41464, 41465, 41473, 41474, 41471, 41472, 41484, 41485, + 41482, 41483, 41480, 41481, 41478, 41479, 41424, 41413, 41414, 41411, + 41412, 41427, 41426, 41425, 41422, 41423, 41420, 41421, 41419, 41401, + 41405, 41406, 41403, 41404, 41402, 41399, 41400, 41409, 41410, 41407, + 41408, 41417, 41418, 41415, 41416, 41430, 41433, 41432, 41431, 41428, + 41429, 41538, 41527, 41528, 41526, 41541, 41540, 41539, 41536, 41537, + 41534, 41535, 41533, 41524, 41525, 41522, 41523, 41531, 41532, 41529, + 41530, 41521, 41520, 41157, 41147, 41148, 41145, 41146, 41160, 41159, + 41158, 41155, 41156, 41136, 41139, 41140, 41138, 41137, 41134, 41135, + 41143, 41144, 41141, 41142, 41151, 41152, 41149, 41150, 41163, 41164, + 41161, 41162, 41154, 41153, 41080, 41083, 41084, 41082, 41081, 41078, + 41079, 41087, 41088, 41085, 41086, 41091, 41092, 41089, 41090, 41095, + 41098, 41097, 41096, 41093, 41094, 41101, 41104, 41103, 41102, 41099, + 41100, 41299, 41302, 41301, 41300, 41297, 41298, 41312, 41313, 41311, + 41305, 41306, 41303, 41304, 41309, 41310, 41307, 41308, 41316, 41319, + 41318, 41317, 41314, 41315, 41574, 41572, 41573, 41580, 41581, 41579, + 41566, 41567, 41565, 41570, 41571, 41568, 41569, 41577, 41578, 41575, + 41576, 42048, 42042, 42041, 42051, 42050, 42049, 42047, 42035, 42039, + 42040, 42037, 42038, 42036, 42033, 42034, 42045, 42046, 42043, 42044, + 42054, 42057, 42056, 42055, 42052, 42053, 41881, 41882, 41880, 41878, + 41879, 41876, 41877, 41885, 41886, 41883, 41884, 41889, 41892, 41891, + 41890, 41887, 41888, 41895, 41898, 41897, 41896, 41893, 41894, 42075, + 42067, 42068, 42066, 42076, 42073, 42074, 42060, 42064, 42065, 42062, + 42063, 42061, 42058, 42059, 42071, 42072, 42069, 42070, 41727, 41721, + 41720, 41730, 41729, 41728, 41726, 41723, 41722, 41711, 41714, 41715, + 41713, 41712, 41709, 41710, 41718, 41719, 41716, 41717, 41733, 41736, + 41735, 41734, 41731, 41732, 41725, 41724, 41363, 41352, 41353, 41351, + 41366, 41365, 41364, 41361, 41362, 41343, 41346, 41347, 41345, 41344, + 41341, 41342, 41349, 41350, 41348, 41359, 41360, 41358, 41356, 41357, + 41354, 41355, 41036, 41028, 41029, 41027, 41039, 41038, 41037, 41034, + 41035, 41018, 41021, 41022, 41020, 41019, 41016, 41017, 41025, 41026, + 41023, 41024, 41032, 41033, 41030, 41031, 41042, 41045, 41044, 41043, + 41040, 41041, 41998, 41990, 41991, 41988, 41989, 42001, 42000, 41999, + 41996, 41997, 41982, 41986, 41987, 41984, 41985, 41983, 41980, 41981, + 41994, 41995, 41992, 41993, 42004, 42007, 42006, 42005, 42002, 42003, + 42115, 42107, 42108, 42105, 42106, 42118, 42117, 42116, 42113, 42114, + 42099, 42103, 42104, 42101, 42102, 42100, 42097, 42098, 42111, 42112, + 42109, 42110, 42121, 42124, 42123, 42122, 42119, 42120, 41866, 41855, + 41854, 41869, 41868, 41867, 41864, 41865, 41862, 41863, 41860, 41861, + 41858, 41859, 41856, 41857, 41872, 41875, 41874, 41873, 41870, 41871, + 41853, 41852, 41942, 41931, 41932, 41930, 41945, 41944, 41943, 41940, + 41941, 41938, 41939, 41937, 41928, 41929, 41926, 41927, 41935, 41936, + 41933, 41934, 41948, 41951, 41950, 41949, 41946, 41947, 41772, 41775, + 41776, 41774, 41773, 41770, 41771, 41786, 41787, 41785, 41779, 41780, + 41777, 41778, 41783, 41784, 41781, 41782, 41790, 41791, 41788, 41789, + 41794, 41797, 41796, 41795, 41792, 41793, 41916, 41904, 41905, 41903, + 41919, 41918, 41917, 41914, 41915, 41901, 41902, 41899, 41900, 41912, + 41913, 41910, 41911, 41908, 41909, 41906, 41907, 41922, 41925, 41924, + 41923, 41920, 41921, 41760, 41749, 41750, 41748, 41763, 41762, 41761, + 41758, 41759, 41739, 41742, 41743, 41741, 41740, 41737, 41738, 41756, + 41757, 41755, 41746, 41747, 41744, 41745, 41753, 41754, 41751, 41752, + 41766, 41769, 41768, 41767, 41764, 41765, 41266, 41255, 41256, 41253, + 41254, 41269, 41268, 41267, 41264, 41265, 41244, 41247, 41248, 41246, + 41245, 41242, 41243, 41262, 41263, 41261, 41251, 41252, 41249, 41250, + 41259, 41260, 41257, 41258, 41203, 41202, 41188, 41192, 41193, 41190, + 41191, 41189, 41186, 41187, 41196, 41197, 41194, 41195, 41200, 41201, + 41198, 41199, 41206, 41209, 41208, 41207, 41204, 41205, 41212, 41215, + 41214, 41213, 41210, 41211, 40981, 41605, 41606, 41604, 41611, 41612, + 41610, 41608, 41609, 41607, 41602, 41603, 41600, 41601, 42079, 42083, + 42084, 42081, 42082, 42080, 42077, 42078, 42089, 42090, 42087, 42088, + 42093, 42096, 42095, 42094, 42091, 42092, 42086, 42085, 41815, 41803, + 41804, 41802, 41818, 41817, 41816, 41813, 41814, 41800, 41801, 41798, + 41799, 41811, 41812, 41809, 41810, 41807, 41808, 41805, 41806, 41821, + 41824, 41823, 41822, 41819, 41820, 41636, 41625, 41626, 41624, 41639, + 41638, 41637, 41634, 41635, 41615, 41618, 41619, 41617, 41616, 41613, + 41614, 41696, 41697, 41695, 41693, 41694, 41692, 41682, 41686, 41687, + 41684, 41685, 41683, 41680, 41681, 41690, 41691, 41688, 41689, 41699, + 41702, 41701, 41700, 41698, 41705, 41708, 41707, 41706, 41703, 41704, + 41632, 41633, 41631, 41622, 41623, 41620, 41621, 41629, 41630, 41627, + 41628, 41642, 41645, 41644, 41643, 41640, 41641, 40973, 40974, 40972, + 40970, 40971, 40968, 40969, 40977, 40978, 40975, 40976, 40980, 40979, + 9775, 129664, 8959, 10853, 10632, 10634, 10814, 10852, 10631, 10633, + 10783, 10784, 10785, 10625, 10626, 72262, 72256, 72253, 72252, 72254, + 72251, 72250, 72261, 72255, 72243, 72215, 72214, 72230, 72229, 72220, + 72219, 72242, 72204, 72203, 72207, 72216, 72211, 72221, 72238, 72239, + 72240, 72228, 72227, 72213, 72212, 72218, 72217, 72225, 72224, 72209, + 72208, 72206, 72205, 72223, 72222, 72231, 72232, 72233, 72241, 72210, + 72236, 72226, 72235, 72237, 72234, 72192, 72259, 72258, 72260, 72257, + 72248, 72245, 72246, 72247, 72244, 72249, 72263, 72202, 72199, 72200, + 72198, 72197, 72195, 72194, 72201, 72196, 72193, 129427, 65279, 8204, + 8203, 8205, 11234, 129296, 118593, 118584, 118585, 118591, 118580, + 118589, 118528, 118540, 118531, 118543, 118559, 118529, 118541, 118532, + 118544, 118592, 118573, 118569, 118568, 118581, 118586, 118561, 118582, + 118583, 118566, 118538, 118550, 118555, 118556, 118535, 118547, 118537, + 118549, 118553, 118558, 118534, 118546, 118572, 118562, 118571, 118554, + 118533, 118545, 118587, 118588, 118530, 118542, 118552, 118563, 118539, + 118551, 118557, 118536, 118548, 118579, 118570, 118560, 118567, 118565, + 118564, 118590, 118576, 118577, 118578, 118619, 118639, 118637, 118645, + 118721, 118611, 118635, 118659, 118626, 118623, 118625, 118624, 118622, + 118638, 118612, 118660, 118608, 118609, 118657, 118719, 118695, 118699, + 118698, 118697, 118696, 118722, 118720, 118703, 118708, 118707, 118706, + 118705, 118704, 118610, 118620, 118723, 118616, 118617, 118640, 118672, + 118636, 118658, 118652, 118651, 118649, 118650, 118648, 118646, 118647, + 118644, 118643, 118641, 118642, 118653, 118656, 118654, 118655, 118662, + 118670, 118664, 118666, 118669, 118663, 118665, 118671, 118667, 118668, + 118673, 118614, 118615, 118618, 118685, 118687, 118684, 118683, 118686, + 118681, 118680, 118709, 118713, 118711, 118716, 118717, 118714, 118715, + 118712, 118718, 118710, 118676, 118679, 118690, 118688, 118693, 118694, + 118691, 118692, 118689, 118675, 118677, 118678, 118674, 118701, 118702, + 118700, 118682, 118632, 118631, 118634, 118633, 118628, 118627, 118630, + 118629, 118613, 118621, 118661, 118596, 118597, 118594, 118595, 118598, + 129503, 983264, 983222, 983221, 983223, }; -static const unsigned short phrasebook_offset1[] = { +#define DAWG_CODEPOINT_TO_POS_SHIFT 8 +#define DAWG_CODEPOINT_TO_POS_NOTFOUND 35762 +static const unsigned char dawg_codepoint_to_pos_index1[] = { 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, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 105, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 130, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 104, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 104, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 104, 182, 183, 104, 184, 185, - 186, 187, 104, 188, 189, 190, 191, 192, 193, 194, 104, 195, 196, 197, - 198, 104, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 223, 224, 225, 226, 227, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 228, 229, 230, 231, 232, - 233, 234, 235, 104, 104, 104, 104, 236, 237, 238, 239, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 250, 251, - 252, 253, 254, 255, 256, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 257, 258, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 104, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 104, 104, 104, 104, 104, 104, 104, 104, 282, 104, 283, 284, 285, - 104, 104, 286, 104, 104, 104, 287, 104, 104, 104, 104, 104, 288, 289, - 290, 291, 104, 104, 104, 104, 104, 292, 293, 294, 104, 295, 296, 104, - 104, 297, 298, 299, 300, 301, 104, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 320, 321, 322, - 323, 324, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 325, 104, 326, 327, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 328, 329, 330, - 331, 332, 333, 334, 335, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 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, 53, 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, 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, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 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, 66, 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, 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, 52, 52, 52, 52, 52, 52, 52, 52, 52, 112, 113, + 114, 115, 116, 117, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 118, 119, 120, 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, 121, 122, 123, 124, 52, 52, 125, 126, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 127, 128, 129, 130, 131, 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, 132, 133, 134, 135, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 136, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 52, 52, + 52, 52, 149, 150, 151, 152, 52, 153, 52, 52, 154, 155, 156, 52, 52, 157, + 158, 159, 52, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 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, 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, 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, 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, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 172, 173, 174, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 175, + 176, 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, 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, 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, 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, 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, 177, 178, 179, 180, 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, 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, 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, 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, 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, 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, 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, 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, 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, }; -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, 1, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 31, - 33, 35, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72, - 75, 78, 82, 86, 91, 96, 101, 105, 110, 115, 120, 124, 129, 134, 138, 143, - 148, 152, 157, 162, 166, 171, 176, 180, 185, 190, 195, 200, 205, 209, - 213, 217, 221, 224, 228, 232, 237, 242, 247, 251, 256, 261, 266, 270, - 275, 280, 284, 289, 294, 298, 303, 308, 312, 317, 322, 326, 331, 336, - 341, 346, 351, 356, 359, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 366, 370, 375, - 378, 381, 384, 387, 390, 393, 395, 398, 404, 412, 415, 419, 422, 424, - 427, 430, 433, 436, 440, 443, 446, 449, 451, 454, 460, 468, 475, 482, - 489, 494, 501, 508, 515, 522, 529, 537, 542, 550, 558, 566, 574, 582, - 590, 598, 606, 614, 619, 627, 634, 641, 648, 655, 662, 665, 671, 678, - 685, 692, 699, 707, 712, 719, 726, 733, 740, 747, 754, 762, 767, 775, - 783, 791, 799, 807, 815, 823, 831, 839, 844, 852, 859, 866, 873, 880, - 887, 890, 896, 903, 910, 917, 924, 932, 937, 945, 952, 959, 966, 973, - 980, 987, 995, 1003, 1011, 1019, 1027, 1035, 1043, 1051, 1059, 1067, - 1074, 1081, 1089, 1097, 1105, 1113, 1121, 1129, 1137, 1145, 1153, 1161, - 1169, 1177, 1185, 1193, 1201, 1209, 1217, 1225, 1233, 1241, 1248, 1255, - 1263, 1271, 1279, 1287, 1295, 1303, 1311, 1319, 1327, 1333, 1338, 1343, - 1351, 1359, 1367, 1375, 1380, 1388, 1396, 1404, 1412, 1420, 1428, 1437, - 1446, 1453, 1460, 1468, 1476, 1484, 1492, 1500, 1508, 1519, 1524, 1529, - 1536, 1543, 1550, 1557, 1565, 1573, 1578, 1583, 1591, 1599, 1607, 1615, - 1623, 1631, 1639, 1647, 1655, 1663, 1671, 1679, 1687, 1695, 1703, 1711, - 1719, 1727, 1734, 1741, 1748, 1755, 1762, 1769, 1776, 1783, 1791, 1799, - 1807, 1815, 1822, 1829, 1837, 1845, 1853, 1861, 1869, 1877, 1885, 1893, - 1901, 1909, 1917, 1923, 1929, 1935, 1942, 1949, 1954, 1959, 1965, 1972, - 1979, 1986, 1993, 2001, 2009, 2015, 2021, 2026, 2032, 2039, 2046, 2053, - 2058, 2063, 2068, 2075, 2082, 2089, 2096, 2103, 2109, 2117, 2127, 2135, - 2142, 2149, 2154, 2159, 2166, 2173, 2177, 2182, 2187, 2192, 2200, 2209, - 2216, 2223, 2232, 2239, 2246, 2251, 2258, 2265, 2272, 2279, 2286, 2291, - 2298, 2305, 2313, 2318, 2323, 2328, 2338, 2342, 2348, 2354, 2360, 2366, - 2374, 2387, 2395, 2400, 2410, 2415, 2420, 2430, 2435, 2442, 2449, 2457, - 2465, 2472, 2479, 2486, 2493, 2503, 2513, 2523, 2533, 2543, 2553, 2563, - 2573, 2578, 2588, 2598, 2608, 2618, 2626, 2634, 2641, 2648, 2656, 2664, - 2672, 2680, 2687, 2694, 2704, 2714, 2722, 2730, 2738, 2743, 2753, 2758, - 2766, 2774, 2779, 2784, 2792, 2800, 2811, 2822, 2830, 2838, 2848, 2858, - 2866, 2874, 2883, 2892, 2901, 2910, 2920, 2930, 2939, 2948, 2958, 2968, - 2976, 2984, 2993, 3002, 3011, 3020, 3030, 3040, 3048, 3056, 3065, 3074, - 3083, 3092, 3101, 3110, 3115, 3120, 3128, 3136, 3146, 3154, 3159, 3164, - 3171, 3178, 3185, 3192, 3200, 3208, 3218, 3228, 3238, 3248, 3255, 3262, - 3272, 3282, 3290, 3298, 3306, 3314, 3322, 3329, 3336, 3343, 3349, 3356, - 3363, 3370, 3379, 3389, 3399, 3406, 3413, 3419, 3424, 3430, 3437, 3444, - 3451, 3458, 3469, 3479, 3486, 3493, 3500, 3507, 3512, 3517, 3523, 3529, - 3535, 3543, 3551, 3558, 3564, 3569, 3576, 3582, 3590, 3601, 3611, 3620, - 3627, 3633, 3639, 3644, 3651, 3657, 3664, 3671, 3678, 3683, 3688, 3697, - 3705, 3714, 3719, 3725, 3735, 3742, 3750, 3759, 3765, 3771, 3777, 3784, - 3789, 3794, 3804, 3812, 3821, 3829, 3837, 3847, 3852, 3859, 3866, 3871, - 3883, 3892, 3900, 3906, 3915, 3920, 3925, 3932, 3938, 3944, 3950, 3956, - 3965, 3973, 3978, 3986, 3992, 4000, 4008, 4014, 4020, 4026, 4034, 4042, - 4048, 4056, 4062, 4067, 4074, 4082, 4092, 4099, 4106, 4116, 4123, 4130, - 4140, 4147, 4154, 4161, 4167, 4173, 4182, 4194, 4199, 4206, 4211, 4215, - 4220, 4228, 4235, 4240, 4245, 4249, 4254, 4259, 4263, 4269, 4275, 4281, - 4287, 4295, 4300, 4305, 4310, 4315, 4321, 4323, 4328, 4332, 4338, 4344, - 4350, 4355, 4362, 4369, 4375, 4382, 4390, 4398, 4403, 4408, 4412, 4417, - 4419, 4421, 4424, 4426, 4429, 4434, 4439, 4445, 4450, 4454, 4459, 4464, - 4473, 4479, 4484, 4490, 4495, 4501, 4509, 4517, 4521, 4525, 4530, 4536, - 4542, 4548, 4554, 4559, 4566, 4574, 4582, 4587, 4593, 4600, 4607, 4614, - 4621, 4625, 4631, 4636, 4641, 4646, 4651, 4654, 4657, 4660, 4663, 4666, - 4669, 4673, 4677, 4683, 4686, 4691, 4697, 4703, 4706, 4711, 4716, 4720, - 4726, 4731, 4737, 4743, 4748, 4753, 4758, 4761, 4767, 4772, 4777, 4781, - 4786, 4792, 4798, 4801, 4805, 4809, 4813, 4816, 4819, 4824, 4828, 4835, - 4839, 4845, 4849, 4855, 4859, 4863, 4867, 4872, 4877, 4884, 4890, 4897, - 4903, 4909, 4915, 4918, 4922, 4926, 4930, 4934, 4939, 4944, 4948, 4952, - 4958, 4962, 4966, 4971, 4977, 4982, 4988, 4992, 4999, 5004, 5009, 5014, - 5019, 5025, 5028, 5032, 5037, 5042, 5051, 5057, 5061, 5065, 5070, 5074, - 5079, 5083, 5087, 5092, 5096, 5102, 5107, 5112, 5117, 5122, 5127, 5132, - 5138, 5144, 5150, 5156, 5161, 5167, 5173, 5179, 5184, 5189, 5196, 5203, - 5207, 5212, 5219, 0, 0, 5226, 5229, 5238, 5247, 5258, 5262, 0, 0, 0, 0, - 5267, 5270, 5275, 5283, 5288, 5296, 5304, 0, 5312, 0, 5320, 5328, 5336, - 5347, 5352, 5357, 5362, 5367, 5372, 5377, 5382, 5387, 5392, 5397, 5402, - 5407, 5412, 5417, 5422, 5427, 0, 5432, 5437, 5442, 5447, 5452, 5457, - 5462, 5467, 5475, 5483, 5491, 5499, 5507, 5515, 5526, 5531, 5536, 5541, - 5546, 5551, 5556, 5561, 5566, 5571, 5576, 5581, 5586, 5591, 5596, 5601, - 5606, 5611, 5617, 5622, 5627, 5632, 5637, 5642, 5647, 5652, 5660, 5668, - 5676, 5684, 5692, 5697, 5701, 5705, 5712, 5722, 5732, 5736, 5740, 5744, - 5750, 5757, 5761, 5766, 5770, 5775, 5779, 5784, 5788, 5793, 5798, 5803, - 5808, 5813, 5818, 5823, 5828, 5833, 5838, 5843, 5848, 5853, 5858, 5863, - 5867, 5871, 5877, 5881, 5886, 5892, 5900, 5905, 5910, 5917, 5922, 5927, - 5934, 5943, 5952, 5963, 5971, 5976, 5981, 5986, 5993, 5998, 6004, 6009, - 6014, 6019, 6024, 6029, 6034, 6042, 6048, 6053, 6057, 6062, 6067, 6072, - 6077, 6082, 6087, 6092, 6096, 6102, 6106, 6111, 6116, 6121, 6125, 6130, - 6135, 6140, 6145, 6149, 6154, 6158, 6163, 6168, 6173, 6178, 6184, 6189, - 6195, 6199, 6204, 6208, 6212, 6217, 6222, 6227, 6232, 6237, 6242, 6247, - 6251, 6257, 6261, 6266, 6271, 6276, 6280, 6285, 6290, 6295, 6300, 6304, - 6309, 6313, 6318, 6323, 6328, 6333, 6339, 6344, 6350, 6354, 6359, 6363, - 6371, 6376, 6381, 6386, 6393, 6398, 6404, 6409, 6414, 6419, 6424, 6429, - 6434, 6442, 6448, 6453, 6458, 6463, 6468, 6473, 6479, 6485, 6492, 6499, - 6508, 6517, 6524, 6531, 6540, 6549, 6554, 6559, 6564, 6569, 6574, 6579, - 6584, 6589, 6600, 6611, 6616, 6621, 6628, 6635, 6643, 6651, 6656, 6661, - 6666, 6671, 6675, 6679, 6683, 6689, 6695, 6699, 6706, 6711, 6721, 6731, - 6737, 6743, 6751, 6759, 6767, 6775, 6782, 6789, 6797, 6805, 6813, 6821, - 6829, 6837, 6845, 6853, 6861, 6869, 6876, 6883, 6889, 6895, 6903, 6911, - 6918, 6925, 6933, 6941, 6947, 6953, 6961, 6969, 6977, 6985, 6991, 6997, - 7005, 7013, 7021, 7029, 7036, 7043, 7051, 7059, 7067, 7075, 7080, 7085, - 7092, 7099, 7109, 7119, 7123, 7131, 7139, 7146, 7153, 7161, 7169, 7176, - 7183, 7191, 7199, 7206, 7213, 7221, 7229, 7234, 7241, 7248, 7255, 7262, - 7268, 7274, 7282, 7290, 7295, 7300, 7308, 7316, 7324, 7332, 7340, 7348, - 7355, 7362, 7370, 7378, 7386, 7394, 7401, 7408, 7414, 7420, 7429, 7438, - 7446, 7454, 7461, 7468, 7475, 7482, 7490, 7498, 7506, 7514, 7522, 7530, - 7538, 7546, 7556, 7566, 7573, 7580, 7587, 7594, 7601, 7608, 7615, 7622, - 7629, 7636, 7643, 7650, 7657, 7664, 7671, 7678, 7685, 7692, 7699, 7706, - 7713, 7720, 7727, 7734, 7739, 7744, 7749, 7754, 7759, 7764, 7769, 7774, - 7779, 7784, 7790, 7796, 7804, 7812, 7820, 7828, 7836, 7844, 7852, 7860, - 7868, 7876, 7881, 7886, 7891, 7896, 7904, 0, 7912, 7918, 7924, 7930, - 7936, 7942, 7948, 7954, 7960, 7965, 7971, 7977, 7983, 7989, 7995, 8001, - 8007, 8013, 8019, 8025, 8031, 8037, 8043, 8049, 8055, 8061, 8067, 8073, - 8078, 8084, 8090, 8096, 8102, 8108, 8114, 8120, 8126, 8132, 0, 0, 8138, - 8146, 8150, 8155, 8160, 8164, 8169, 8174, 8181, 8187, 8193, 8199, 8205, - 8211, 8217, 8223, 8229, 8234, 8240, 8246, 8252, 8258, 8264, 8270, 8276, - 8282, 8288, 8294, 8300, 8306, 8312, 8318, 8324, 8330, 8336, 8342, 8347, - 8353, 8359, 8365, 8371, 8377, 8383, 8389, 8395, 8401, 8407, 8415, 8422, - 8428, 0, 0, 8432, 8439, 8446, 0, 8451, 8456, 8461, 8466, 8473, 8480, - 8485, 8490, 8495, 8500, 8505, 8510, 8515, 8522, 8527, 8534, 8541, 8546, - 8553, 8558, 8563, 8568, 8575, 8580, 8585, 8592, 8601, 8606, 8611, 8616, - 8621, 8627, 8632, 8639, 8646, 8653, 8658, 8663, 8668, 8673, 8678, 8683, - 8693, 8698, 8707, 8712, 8717, 8722, 8727, 8734, 8741, 8748, 8753, 8758, - 8765, 0, 0, 0, 0, 0, 0, 0, 0, 8772, 8776, 8780, 8784, 8788, 8792, 8796, - 8800, 8804, 8808, 8812, 8817, 8821, 8825, 8830, 8834, 8839, 8843, 8847, - 8851, 8856, 8860, 8865, 8869, 8873, 8877, 8881, 0, 0, 0, 0, 8885, 8890, - 8897, 8905, 8912, 8917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8922, 8925, - 8929, 8934, 8938, 8942, 8946, 8952, 8958, 8961, 8968, 8977, 8980, 8983, - 8988, 8994, 8998, 9006, 9012, 9018, 9026, 9030, 9035, 9046, 9051, 9055, - 9059, 9063, 9066, 9069, 9076, 9083, 9087, 9093, 9097, 9104, 9111, 9119, - 9126, 9133, 9137, 9141, 9147, 9151, 9155, 9159, 9163, 9167, 9171, 9175, - 9179, 9183, 9187, 9191, 9195, 9199, 9203, 9207, 9211, 9215, 9223, 9231, - 9241, 9250, 9259, 9262, 9266, 9270, 9274, 9278, 9282, 9286, 9290, 9294, - 9299, 9303, 9306, 9309, 9312, 9315, 9318, 9321, 9324, 9327, 9331, 9335, - 9339, 9344, 9349, 9355, 9358, 9365, 9374, 9379, 9384, 9391, 9397, 9402, - 9406, 9410, 9414, 9418, 9422, 9426, 9430, 9434, 9438, 9442, 9447, 9452, - 9459, 9465, 9471, 9477, 9482, 9491, 9500, 9505, 9512, 9519, 9526, 9533, - 9537, 9541, 9545, 9552, 9562, 9566, 9570, 9574, 9581, 9589, 9593, 9597, - 9604, 9608, 9612, 9616, 9623, 9630, 9642, 9646, 9650, 9654, 9664, 9673, - 9677, 9685, 9692, 9699, 9708, 9719, 9727, 9731, 9740, 9751, 9759, 9772, - 9780, 9788, 9796, 9804, 9810, 9819, 9826, 9830, 9838, 9842, 9849, 9857, - 9861, 9867, 9874, 9881, 9885, 9893, 9897, 9904, 9908, 9916, 9920, 9928, - 9936, 9943, 9951, 9959, 9966, 9972, 9976, 9983, 9991, 9997, 10004, 10011, - 10017, 10027, 10035, 10042, 10048, 10052, 10055, 10059, 10065, 10073, - 10077, 10083, 10089, 10096, 10103, 10106, 10113, 10118, 10127, 10132, - 10136, 10149, 10162, 10168, 10175, 10180, 10186, 10191, 10197, 10207, - 10214, 10223, 10233, 10239, 10244, 10249, 10253, 10257, 10262, 10267, - 10273, 10281, 10289, 10300, 10305, 10314, 10323, 10330, 10336, 10342, - 10348, 10354, 10360, 10366, 10372, 10378, 10384, 10391, 10398, 10405, - 10411, 10419, 10428, 10435, 10443, 10451, 10457, 10463, 10469, 10477, - 10484, 10494, 10503, 10507, 10513, 10519, 0, 10525, 10530, 10535, 10542, - 10547, 10552, 10559, 10564, 10573, 10578, 10583, 10588, 10593, 10598, - 10605, 10610, 10617, 10622, 10627, 10632, 10637, 10642, 10648, 10652, - 10657, 10664, 10669, 10674, 10679, 10684, 10689, 10696, 10703, 10710, - 10715, 10720, 10726, 10731, 10736, 10742, 10747, 10752, 10760, 10768, - 10773, 10778, 10784, 10789, 10794, 10798, 10804, 10808, 10812, 10818, - 10824, 10829, 10834, 10841, 10848, 10852, 0, 0, 10856, 10863, 10870, - 10877, 10887, 10899, 10911, 10928, 10940, 10951, 10959, 10966, 10977, - 10992, 11003, 11009, 11018, 11026, 11038, 11048, 11056, 11068, 11075, - 11083, 11095, 11101, 11107, 11115, 11123, 11131, 11137, 11147, 11155, - 11165, 11175, 11188, 11202, 11216, 11226, 11237, 11248, 11261, 11274, - 11288, 11300, 11312, 11325, 11338, 11350, 11363, 11372, 11380, 11385, - 11390, 11395, 11400, 11405, 11410, 11415, 11420, 11425, 11430, 11435, - 11440, 11445, 11450, 11455, 11460, 11465, 11470, 11475, 11480, 11485, - 11490, 11495, 11500, 11505, 11510, 11515, 11520, 11525, 11530, 11535, - 11540, 11544, 11549, 11554, 11559, 11564, 11569, 11573, 11577, 11581, - 11585, 11589, 11593, 11597, 11601, 11605, 11609, 11613, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 11618, 11623, 11627, 11631, 11635, 11639, 11643, - 11647, 11651, 11655, 11659, 11663, 11668, 11672, 11676, 11680, 11685, - 11689, 11694, 11699, 11704, 11708, 11713, 11718, 11723, 11728, 11732, - 11737, 11741, 11746, 11751, 11755, 11759, 11766, 11770, 11775, 11779, - 11783, 11788, 11792, 11799, 11806, 11813, 11819, 11827, 11835, 11844, - 11852, 11859, 11866, 11874, 11880, 11886, 11892, 11898, 11905, 11910, - 11914, 11919, 0, 0, 11923, 11927, 11932, 11937, 11942, 11947, 11952, - 11957, 11962, 11967, 11972, 11977, 11982, 11987, 11992, 11997, 12002, - 12007, 12012, 12017, 12022, 12027, 12032, 12037, 12042, 12047, 12052, - 12057, 12062, 12067, 12075, 12082, 12088, 12093, 12101, 12108, 12114, - 12121, 12127, 12132, 12139, 12146, 12152, 12157, 12162, 12168, 12173, - 12178, 12184, 0, 0, 12189, 12195, 12201, 12207, 12213, 12219, 12225, - 12230, 12238, 12244, 12250, 12256, 12262, 12268, 12276, 0, 12282, 12287, - 12292, 12297, 12302, 12307, 12312, 12317, 12322, 12327, 12332, 12337, - 12342, 12347, 12352, 12357, 12362, 12367, 12372, 12377, 12382, 12387, - 12392, 12397, 12402, 12407, 12412, 12417, 0, 0, 12422, 0, 12426, 12432, - 12438, 12444, 12450, 12456, 12462, 12468, 12473, 12479, 12485, 0, 0, 0, - 0, 0, 12491, 12499, 12510, 12517, 12524, 12532, 12543, 12553, 12564, - 12575, 12585, 12591, 12605, 12616, 12630, 12645, 12657, 12672, 12681, - 12690, 12698, 12706, 12713, 12719, 12726, 12733, 12743, 12753, 12760, - 12768, 12778, 0, 12782, 12787, 0, 0, 0, 0, 0, 0, 12792, 12799, 12806, - 12813, 12820, 12825, 12831, 12836, 12843, 12852, 12860, 12868, 12876, - 12888, 12895, 12902, 12909, 12921, 12932, 12939, 12947, 12953, 12958, - 12966, 12974, 12982, 12988, 12998, 13006, 13013, 13026, 13034, 13042, - 13051, 13060, 13073, 13079, 13085, 13091, 13099, 13107, 13115, 13123, - 13131, 13139, 13149, 13157, 13165, 13176, 13180, 13186, 13193, 13203, - 13210, 13215, 13222, 13229, 13233, 13239, 13250, 13255, 13262, 13267, - 13272, 13277, 13285, 13293, 13300, 13307, 13314, 13321, 13328, 13335, - 13342, 13348, 13356, 13361, 13366, 13371, 13376, 13381, 13386, 13391, - 13396, 13401, 13406, 13411, 13416, 13421, 13426, 13431, 13436, 13441, - 13447, 13453, 13459, 13464, 13469, 13474, 13479, 13485, 13494, 13502, - 13508, 13516, 13522, 13526, 13530, 13534, 13539, 13542, 13546, 13549, - 13553, 13556, 13560, 13564, 13568, 13573, 13578, 13581, 13585, 13590, - 13595, 13598, 13602, 13605, 13609, 13613, 13617, 13621, 13625, 13629, - 13633, 13637, 13641, 13645, 13649, 13653, 13657, 13661, 13665, 13669, - 13673, 13677, 13680, 13684, 13687, 13691, 13695, 13699, 13702, 13705, - 13708, 13712, 13715, 13719, 13723, 13727, 13731, 13735, 13738, 13741, - 13746, 13751, 13755, 13759, 13764, 13768, 13773, 13777, 13782, 13787, - 13793, 13799, 13805, 13809, 13814, 13820, 13826, 13830, 13835, 13839, - 13845, 13850, 13853, 13859, 13865, 13870, 13875, 13882, 13887, 13892, - 13896, 13900, 13904, 13908, 13912, 13916, 13920, 13924, 13929, 13934, - 13939, 13945, 13948, 13952, 13956, 13959, 13962, 13965, 13968, 13971, - 13974, 13977, 13980, 13983, 13987, 13994, 13999, 14003, 14007, 14011, - 14015, 14019, 14025, 14029, 14033, 14037, 14041, 14047, 14051, 14055, - 14059, 14064, 14069, 0, 14074, 14078, 14083, 14087, 14092, 14096, 14101, - 14106, 0, 0, 14111, 14115, 0, 0, 14120, 14124, 14129, 14133, 14138, - 14143, 14148, 14153, 14158, 14163, 14168, 14173, 14178, 14183, 14188, - 14193, 14198, 14203, 14208, 14213, 14218, 14223, 0, 14227, 14231, 14236, - 14241, 14246, 14250, 14254, 0, 14258, 0, 0, 0, 14262, 14267, 14272, - 14276, 0, 0, 14280, 14285, 14290, 14296, 14301, 14307, 14312, 14318, - 14324, 0, 0, 14331, 14336, 0, 0, 14342, 14347, 14353, 14358, 0, 0, 0, 0, - 0, 0, 0, 0, 14365, 0, 0, 0, 0, 14372, 14377, 0, 14382, 14387, 14393, - 14399, 14405, 0, 0, 14412, 14417, 14421, 14425, 14429, 14433, 14437, - 14441, 14445, 14449, 14453, 14462, 14471, 14476, 14481, 14488, 14495, - 14502, 14509, 14524, 14532, 14536, 14541, 14548, 14553, 0, 0, 14558, - 14565, 14570, 0, 14575, 14579, 14584, 14588, 14593, 14597, 0, 0, 0, 0, - 14602, 14607, 0, 0, 14612, 14617, 14622, 14626, 14631, 14636, 14641, - 14646, 14651, 14656, 14661, 14666, 14671, 14676, 14681, 14686, 14691, - 14696, 14701, 14706, 14711, 14716, 0, 14720, 14724, 14729, 14734, 14739, - 14743, 14747, 0, 14751, 14755, 0, 14760, 14765, 0, 14770, 14774, 0, 0, - 14778, 0, 14783, 14789, 14794, 14800, 14805, 0, 0, 0, 0, 14811, 14817, 0, - 0, 14823, 14829, 14835, 0, 0, 0, 14840, 0, 0, 0, 0, 0, 0, 0, 14845, - 14850, 14855, 14860, 0, 14865, 0, 0, 0, 0, 0, 0, 0, 14870, 14875, 14879, - 14883, 14887, 14891, 14895, 14899, 14903, 14907, 14911, 14915, 14919, - 14923, 14927, 14933, 14938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14943, 14948, - 14953, 0, 14958, 14962, 14967, 14971, 14976, 14980, 14985, 14990, 14995, - 0, 15001, 15005, 15010, 0, 15016, 15020, 15025, 15029, 15034, 15039, - 15044, 15049, 15054, 15059, 15064, 15069, 15074, 15079, 15084, 15089, - 15094, 15099, 15104, 15109, 15114, 15119, 0, 15123, 15127, 15132, 15137, - 15142, 15146, 15150, 0, 15154, 15158, 0, 15163, 15168, 15173, 15178, - 15182, 0, 0, 15186, 15191, 15196, 15202, 15207, 15213, 15218, 15224, - 15230, 15237, 0, 15244, 15249, 15255, 0, 15262, 15267, 15273, 0, 0, - 15278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15282, 15288, 15294, - 15300, 0, 0, 15307, 15312, 15316, 15320, 15324, 15328, 15332, 15336, - 15340, 15344, 15348, 15353, 0, 0, 0, 0, 0, 0, 0, 15358, 15363, 15368, - 15373, 15378, 15386, 15394, 0, 15402, 15407, 15412, 0, 15417, 15421, - 15426, 15430, 15435, 15439, 15444, 15449, 0, 0, 15454, 15458, 0, 0, - 15463, 15467, 15472, 15476, 15481, 15486, 15491, 15496, 15501, 15506, - 15511, 15516, 15521, 15526, 15531, 15536, 15541, 15546, 15551, 15556, - 15561, 15566, 0, 15570, 15574, 15579, 15584, 15589, 15593, 15597, 0, - 15601, 15605, 0, 15610, 15615, 15620, 15625, 15629, 0, 0, 15633, 15638, - 15643, 15649, 15654, 15660, 15665, 15671, 15677, 0, 0, 15684, 15689, 0, - 0, 15695, 15700, 15706, 0, 0, 0, 0, 0, 0, 0, 15711, 15716, 15723, 0, 0, - 0, 0, 15730, 15735, 0, 15740, 15745, 15751, 15757, 15763, 0, 0, 15770, - 15775, 15779, 15783, 15787, 15791, 15795, 15799, 15803, 15807, 15811, - 15815, 15820, 15827, 15834, 15841, 15848, 15855, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15862, 15866, 0, 15870, 15873, 15877, 15880, 15884, 15887, 0, 0, 0, - 15891, 15894, 15898, 0, 15902, 15905, 15909, 15913, 0, 0, 0, 15916, - 15920, 0, 15924, 0, 15928, 15932, 0, 0, 0, 15936, 15940, 0, 0, 0, 15944, - 15947, 15951, 0, 0, 0, 15954, 15957, 15960, 15963, 15967, 15970, 15974, - 15978, 15982, 15986, 15990, 15993, 0, 0, 0, 0, 15996, 16001, 16005, - 16010, 16014, 0, 0, 0, 16019, 16023, 16028, 0, 16033, 16037, 16042, - 16047, 0, 0, 16051, 0, 0, 0, 0, 0, 0, 16054, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 16060, 16064, 16067, 16070, 16073, 16076, 16079, 16082, - 16085, 16088, 16091, 16095, 16100, 16104, 16108, 16112, 16116, 16120, - 16124, 16129, 16133, 0, 0, 0, 0, 0, 16136, 16143, 16148, 16153, 16158, - 16165, 16169, 16174, 16178, 16183, 16187, 16192, 16197, 0, 16202, 16206, - 16211, 0, 16216, 16220, 16225, 16230, 16234, 16239, 16244, 16249, 16254, - 16259, 16264, 16269, 16274, 16279, 16284, 16289, 16294, 16299, 16304, - 16309, 16314, 16319, 16324, 0, 16328, 16332, 16337, 16342, 16347, 16351, - 16355, 16359, 16364, 16368, 16373, 16378, 16383, 16388, 16393, 16397, 0, - 0, 16401, 16406, 16411, 16417, 16422, 16428, 16433, 16439, 16445, 0, - 16452, 16457, 16463, 0, 16469, 16474, 16480, 16486, 0, 0, 0, 0, 0, 0, 0, - 16491, 16496, 0, 16503, 16508, 16513, 0, 0, 16518, 0, 0, 16525, 16531, - 16537, 16543, 0, 0, 16550, 16555, 16559, 16563, 16567, 16571, 16575, - 16579, 16583, 16587, 0, 0, 0, 0, 0, 0, 0, 16591, 16596, 16610, 16623, - 16636, 16649, 16662, 16675, 16688, 16693, 16700, 16705, 16710, 16715, - 16720, 16724, 16729, 16733, 16738, 16742, 16747, 16752, 0, 16757, 16761, - 16766, 0, 16771, 16775, 16780, 16785, 16789, 16794, 16799, 16804, 16809, - 16814, 16819, 16824, 16829, 16834, 16839, 16844, 16849, 16854, 16859, - 16864, 16869, 16874, 16879, 0, 16883, 16887, 16892, 16897, 16902, 16906, - 16910, 16914, 16919, 16923, 0, 16928, 16933, 16938, 16943, 16947, 0, 0, - 16951, 16956, 16961, 16967, 16972, 16978, 16983, 16989, 16995, 0, 17002, - 17007, 17013, 0, 17019, 17024, 17030, 17036, 0, 0, 0, 0, 0, 0, 0, 17041, - 17046, 0, 0, 0, 0, 0, 0, 17053, 17060, 0, 17065, 17071, 17077, 17083, 0, - 0, 17090, 17095, 17099, 17103, 17107, 17111, 17115, 17119, 17123, 17127, - 0, 17131, 17136, 17141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17149, 17155, - 17159, 17163, 17167, 17173, 17176, 17180, 17183, 17187, 17190, 17194, - 17198, 0, 17202, 17205, 17209, 0, 17213, 17216, 17220, 17224, 17227, - 17231, 17235, 17239, 17243, 17247, 17251, 17255, 17259, 17263, 17267, - 17271, 17275, 17279, 17283, 17287, 17291, 17295, 17299, 17302, 17306, - 17309, 17313, 17317, 17321, 17324, 17327, 17330, 17334, 17337, 17341, - 17345, 17349, 17353, 17357, 17360, 17363, 17367, 17374, 17380, 17384, - 17389, 17393, 17398, 17402, 17407, 17412, 0, 17418, 17422, 17427, 0, - 17432, 17436, 17441, 17446, 17450, 17455, 0, 0, 0, 0, 17459, 17465, - 17471, 17477, 17483, 17489, 17495, 17501, 17507, 17513, 17519, 17525, - 17531, 17536, 17541, 17546, 0, 0, 17552, 17556, 17559, 17562, 17565, - 17568, 17571, 17574, 17577, 17580, 17583, 17587, 17592, 17596, 17602, - 17608, 17614, 17620, 17626, 17632, 17636, 17642, 17648, 17654, 17659, - 17665, 0, 17671, 17675, 17679, 0, 17683, 17687, 17691, 17695, 17699, - 17703, 17707, 17711, 17715, 17719, 17723, 17727, 17731, 17735, 17739, - 17743, 17747, 17751, 0, 0, 0, 17755, 17761, 17767, 17773, 17779, 17785, - 17791, 17797, 17803, 17809, 17815, 17821, 17829, 17835, 17841, 17847, - 17853, 17859, 17865, 17871, 17877, 17883, 17889, 17895, 0, 17901, 17907, - 17913, 17919, 17925, 17931, 17935, 17941, 17945, 0, 17949, 0, 0, 17955, - 17959, 17965, 17971, 17977, 17981, 17987, 0, 0, 0, 17991, 0, 0, 0, 0, - 17995, 18000, 18007, 18014, 18021, 18028, 0, 18035, 0, 18042, 18047, - 18052, 18059, 18066, 18075, 18086, 18095, 0, 0, 0, 0, 0, 0, 18100, 18106, - 18111, 18116, 18121, 18126, 18131, 18136, 18141, 18146, 0, 0, 18151, - 18158, 18165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18170, 18178, 18186, - 18194, 18202, 18210, 18218, 18226, 18234, 18242, 18250, 18258, 18266, - 18274, 18282, 18289, 18297, 18305, 18313, 18321, 18329, 18336, 18344, - 18352, 18360, 18368, 18376, 18384, 18392, 18400, 18408, 18416, 18424, - 18431, 18439, 18447, 18453, 18461, 18467, 18475, 18483, 18491, 18499, - 18507, 18515, 18522, 18530, 18536, 18543, 18551, 18559, 18567, 18574, - 18582, 18590, 18598, 18605, 18613, 0, 0, 0, 0, 18619, 18626, 18633, - 18641, 18648, 18658, 18668, 18674, 18680, 18686, 18694, 18702, 18710, - 18718, 18724, 18730, 18736, 18742, 18747, 18751, 18755, 18759, 18763, - 18767, 18771, 18775, 18779, 18783, 18789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18795, 18800, 0, 18807, 0, 18814, 18821, 18826, 18831, 18838, 0, - 18845, 18852, 18857, 18864, 18871, 18878, 18885, 18892, 18899, 18904, - 18908, 18915, 18922, 18929, 18934, 18939, 18944, 18951, 18958, 18965, - 18972, 18979, 18984, 18989, 0, 18996, 0, 19003, 19008, 19015, 19022, - 19029, 19036, 19043, 19047, 19054, 19058, 19063, 19071, 19077, 19083, - 19088, 19094, 19100, 19106, 19111, 19117, 19124, 19132, 19139, 0, 0, - 19146, 19151, 19157, 19162, 19168, 0, 19174, 0, 19179, 19186, 19193, - 19200, 19207, 19212, 19216, 0, 19220, 19225, 19229, 19233, 19237, 19241, - 19245, 19249, 19253, 19257, 0, 0, 19261, 19267, 19273, 19280, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19287, 19291, 19302, 19317, 19332, 19342, 19353, 19366, - 19377, 19383, 19391, 19401, 19407, 19415, 19419, 19425, 19431, 19439, - 19449, 19457, 19470, 19476, 19484, 19492, 19504, 19511, 19519, 19527, - 19535, 19543, 19551, 19559, 19569, 19573, 19576, 19579, 19582, 19585, - 19588, 19591, 19594, 19597, 19600, 19604, 19608, 19612, 19616, 19620, - 19624, 19628, 19632, 19636, 19641, 19647, 19657, 19671, 19681, 19687, - 19693, 19701, 19709, 19717, 19725, 19731, 19737, 19740, 19744, 19748, - 19752, 19756, 19760, 19764, 0, 19768, 19772, 19776, 19780, 19784, 19788, - 19792, 19796, 19800, 19804, 19808, 19811, 19814, 19818, 19822, 19826, - 19829, 19833, 19837, 19841, 19845, 19849, 19853, 19857, 19861, 19864, - 19867, 19870, 19874, 19878, 19881, 19884, 19887, 19891, 19896, 19900, 0, - 0, 0, 0, 19904, 19909, 19913, 19918, 19922, 19927, 19932, 19938, 19943, - 19949, 19953, 19958, 19962, 19967, 19977, 19983, 19989, 19996, 20006, - 20012, 20016, 20020, 20026, 20032, 20040, 20046, 20054, 20062, 20070, - 20080, 20088, 20098, 20103, 20109, 20115, 20121, 20127, 20133, 20139, 0, - 20145, 20151, 20157, 20163, 20169, 20175, 20181, 20187, 20193, 20199, - 20205, 20210, 20215, 20221, 20227, 20233, 20238, 20244, 20250, 20256, - 20262, 20268, 20274, 20280, 20286, 20291, 20296, 20301, 20307, 20313, - 20318, 20323, 20328, 20334, 20342, 20349, 0, 20356, 20363, 20376, 20383, - 20390, 20398, 20406, 20412, 20418, 20424, 20434, 20439, 20445, 20455, - 20465, 0, 20475, 20485, 20493, 20505, 20517, 20523, 20537, 20552, 20557, - 20562, 20570, 20578, 20586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20594, - 20597, 20601, 20605, 20609, 20613, 20617, 20621, 20625, 20629, 20633, - 20637, 20641, 20645, 20649, 20653, 20657, 20661, 20665, 20669, 20673, - 20676, 20679, 20683, 20687, 20691, 20694, 20697, 20700, 20703, 20707, - 20710, 20713, 20717, 20720, 20725, 20728, 20732, 20735, 20739, 20742, - 20747, 20750, 20754, 20761, 20766, 20770, 20775, 20779, 20784, 20788, - 20793, 20800, 20806, 20812, 20816, 20820, 20824, 20828, 20832, 20838, - 20844, 20851, 20857, 20862, 20866, 20869, 20872, 20875, 20878, 20881, - 20884, 20887, 20890, 20893, 20899, 20903, 20907, 20911, 20915, 20919, - 20923, 20927, 20931, 20936, 20940, 20945, 20950, 20956, 20961, 20967, - 20973, 20979, 20985, 20991, 20999, 21007, 21015, 21023, 21032, 21041, - 21052, 21062, 21072, 21083, 21094, 21104, 21114, 21124, 21134, 21144, - 21154, 21164, 21174, 21182, 21189, 21195, 21202, 21207, 21213, 21219, - 21225, 21231, 21237, 21243, 21248, 21254, 21260, 21266, 21272, 21277, - 21286, 21293, 21299, 21307, 21315, 21321, 21327, 21333, 21339, 21347, - 21355, 21365, 21373, 21381, 21387, 21392, 21397, 21402, 21407, 21412, - 21417, 21422, 21427, 21432, 21438, 21444, 21450, 21457, 21462, 21468, - 21473, 21478, 21483, 21488, 21493, 21498, 21503, 21508, 21513, 21518, - 21523, 21528, 21533, 21538, 21543, 21548, 21553, 21558, 21563, 21568, - 21573, 21578, 21583, 21588, 21593, 21598, 21603, 21608, 21613, 21618, - 21623, 21628, 21633, 21638, 21643, 21648, 21653, 0, 21658, 0, 0, 0, 0, 0, - 21663, 0, 0, 21668, 21672, 21676, 21680, 21684, 21688, 21692, 21696, - 21700, 21704, 21708, 21712, 21716, 21720, 21724, 21728, 21732, 21736, - 21740, 21744, 21748, 21752, 21756, 21760, 21764, 21768, 21772, 21776, - 21780, 21784, 21788, 21792, 21796, 21800, 21804, 21808, 21812, 21816, - 21820, 21824, 21828, 21832, 21837, 21841, 21846, 21851, 21855, 21860, - 21865, 21869, 21873, 21877, 21881, 21885, 21889, 21893, 21897, 21901, - 21905, 21909, 21913, 21917, 21921, 21925, 21929, 21933, 21937, 21941, - 21945, 21949, 21953, 21957, 21961, 21965, 21969, 21973, 21977, 21981, - 21985, 21989, 21993, 21997, 22001, 22005, 22009, 22013, 22017, 22021, - 22025, 22029, 22033, 22037, 22041, 22045, 22049, 22053, 22057, 22061, - 22065, 22069, 22073, 22077, 22081, 22085, 22089, 22093, 22097, 22101, - 22105, 22109, 22113, 22117, 22121, 22125, 22129, 22133, 22137, 22141, - 22145, 22149, 22153, 22157, 22161, 22165, 22169, 22173, 22177, 22181, - 22185, 22189, 22193, 22197, 22201, 22205, 22209, 22213, 22217, 22221, - 22225, 22229, 22233, 22237, 22241, 22245, 22249, 22254, 22258, 22263, - 22267, 22272, 22277, 22281, 22286, 22291, 22295, 22300, 22305, 22310, - 22315, 22319, 22324, 22329, 22334, 22339, 22344, 22349, 22353, 22358, - 22363, 22368, 22373, 22378, 22383, 22388, 22393, 22398, 22403, 22408, - 22413, 22418, 22423, 22428, 22433, 22438, 22443, 22448, 22453, 22458, - 22463, 22468, 22473, 22478, 22483, 22488, 22493, 22498, 22503, 22508, - 22513, 22518, 22523, 22528, 22533, 22538, 22543, 22548, 22553, 22558, - 22563, 22568, 22573, 22578, 22583, 22588, 22593, 22598, 22603, 22607, - 22611, 22615, 22619, 22623, 22627, 22631, 22635, 22639, 22643, 22647, - 22651, 22655, 22659, 22663, 22667, 22671, 22675, 22679, 22683, 22687, - 22691, 22695, 22699, 22703, 22707, 22711, 22715, 22719, 22723, 22727, - 22731, 22735, 22739, 22743, 22747, 22751, 22755, 22759, 22763, 22767, - 22771, 22775, 22779, 22783, 22787, 22791, 22795, 22799, 22803, 22807, - 22811, 22815, 22819, 22823, 22827, 22831, 22835, 22839, 22843, 22847, - 22851, 22855, 22859, 22863, 22867, 22871, 22875, 22879, 22883, 22887, - 22891, 22895, 22899, 22903, 22907, 22911, 22915, 22919, 22923, 22927, - 22931, 22935, 22939, 22943, 22947, 22951, 22955, 22958, 22962, 22966, - 22970, 22974, 22978, 22982, 22986, 22989, 22993, 22997, 23001, 23005, - 23009, 23013, 23017, 23021, 23025, 23029, 23033, 23037, 23041, 23045, - 23049, 23052, 23056, 23060, 23064, 23068, 23072, 23076, 23080, 23084, - 23088, 23092, 23096, 23100, 23104, 23108, 23112, 23115, 23119, 23123, - 23127, 23131, 23135, 23139, 23143, 23146, 23150, 23154, 23158, 23162, - 23166, 23170, 23174, 23178, 23182, 23186, 23190, 23194, 23198, 23202, - 23206, 23210, 23214, 23218, 23222, 23226, 23230, 23234, 23238, 0, 23242, - 23246, 23250, 23254, 0, 0, 23258, 23262, 23266, 23270, 23274, 23278, - 23282, 0, 23286, 0, 23290, 23294, 23298, 23302, 0, 0, 23306, 23310, - 23314, 23318, 23322, 23326, 23330, 23334, 23338, 23342, 23346, 23350, - 23354, 23358, 23362, 23366, 23370, 23374, 23378, 23382, 23386, 23390, - 23394, 23397, 23401, 23405, 23409, 23413, 23417, 23421, 23425, 23429, - 23433, 23437, 23441, 23445, 23449, 23453, 23457, 23461, 23465, 0, 23469, - 23473, 23477, 23481, 0, 0, 23485, 23488, 23492, 23496, 23500, 23504, - 23508, 23512, 23516, 23520, 23524, 23528, 23532, 23536, 23540, 23544, - 23548, 23553, 23558, 23563, 23569, 23575, 23580, 23585, 23591, 23594, - 23598, 23602, 23606, 23610, 23614, 23618, 23622, 0, 23626, 23630, 23634, - 23638, 0, 0, 23642, 23646, 23650, 23654, 23658, 23662, 23666, 0, 23670, - 0, 23674, 23678, 23682, 23686, 0, 0, 23690, 23694, 23698, 23702, 23706, - 23710, 23714, 23718, 23722, 23727, 23732, 23737, 23743, 23749, 23754, 0, - 23759, 23763, 23767, 23771, 23775, 23779, 23783, 23787, 23791, 23795, - 23799, 23803, 23807, 23811, 23815, 23819, 23823, 23826, 23830, 23834, - 23838, 23842, 23846, 23850, 23854, 23858, 23862, 23866, 23870, 23874, - 23878, 23882, 23886, 23890, 23894, 23898, 23902, 23906, 23910, 23914, - 23918, 23922, 23926, 23930, 23934, 23938, 23942, 23946, 23950, 23954, - 23958, 23962, 23966, 23970, 23974, 23978, 23982, 0, 23986, 23990, 23994, - 23998, 0, 0, 24002, 24006, 24010, 24014, 24018, 24022, 24026, 24030, - 24034, 24038, 24042, 24046, 24050, 24054, 24058, 24062, 24066, 24070, - 24074, 24078, 24082, 24086, 24090, 24094, 24098, 24102, 24106, 24110, - 24114, 24118, 24122, 24126, 24130, 24134, 24138, 24142, 24146, 24150, - 24154, 24158, 24162, 24166, 24170, 24174, 24178, 24182, 24186, 24190, - 24194, 24198, 24202, 24206, 24210, 24214, 24218, 24222, 24226, 24229, - 24233, 24237, 24241, 24245, 24249, 24253, 24257, 24261, 24265, 0, 0, - 24269, 24278, 24284, 24289, 24293, 24296, 24301, 24304, 24307, 24310, - 24315, 24319, 24324, 24327, 24330, 24333, 24336, 24339, 24342, 24345, - 24348, 24351, 24355, 24359, 24363, 24367, 24371, 24375, 24379, 24383, - 24387, 24391, 0, 0, 0, 24396, 24402, 24406, 24410, 24414, 24420, 24424, - 24428, 24432, 24438, 24442, 24446, 24450, 24456, 24460, 24464, 24468, - 24474, 24480, 24486, 24494, 24500, 24506, 24512, 24518, 24524, 0, 0, 0, - 0, 0, 0, 24530, 24533, 24536, 24539, 24542, 24545, 24549, 24553, 24556, - 24560, 24564, 24568, 24572, 24576, 24579, 24583, 24587, 24591, 24595, - 24599, 24602, 24606, 24610, 24614, 24618, 24622, 24625, 24629, 24633, - 24637, 24641, 24644, 24648, 24652, 24656, 24660, 24664, 24668, 24672, - 24676, 24680, 24684, 24688, 24692, 24696, 24699, 24703, 24707, 24711, - 24715, 24719, 24723, 24727, 24731, 24735, 24739, 24743, 24747, 24751, - 24755, 24759, 24763, 24767, 24771, 24775, 24779, 24783, 24787, 24791, - 24795, 24799, 24803, 24807, 24811, 24815, 24819, 24823, 24827, 24831, - 24835, 24838, 24842, 24846, 24850, 24854, 24858, 0, 0, 24862, 24867, - 24872, 24877, 24882, 24887, 0, 0, 24892, 24896, 24899, 24903, 24906, - 24910, 24913, 24917, 24923, 24928, 24932, 24935, 24939, 24943, 24949, - 24953, 24959, 24963, 24969, 24973, 24979, 24983, 24989, 24995, 24999, - 25005, 25009, 25015, 25021, 25025, 25031, 25037, 25042, 25047, 25055, - 25063, 25070, 25075, 25081, 25090, 25096, 25104, 25109, 25115, 25119, - 25123, 25127, 25131, 25135, 25139, 25143, 25147, 25151, 25155, 25161, - 25166, 25171, 25174, 25178, 25182, 25188, 25192, 25198, 25202, 25208, - 25212, 25218, 25222, 25228, 25232, 25238, 25242, 25248, 25254, 25258, - 25264, 25269, 25273, 25277, 25281, 25285, 25288, 25292, 25298, 25303, - 25308, 25312, 25316, 25320, 25326, 25330, 25336, 25340, 25346, 25349, - 25354, 25358, 25364, 25368, 25374, 25378, 25384, 25390, 25394, 25398, - 25402, 25406, 25410, 25414, 25418, 25422, 25426, 25430, 25434, 25440, - 25443, 25447, 25451, 25457, 25461, 25467, 25471, 25477, 25481, 25487, - 25491, 25497, 25501, 25507, 25511, 25517, 25523, 25527, 25531, 25537, - 25543, 25549, 25555, 25559, 25563, 25567, 25571, 25575, 25579, 25585, - 25589, 25593, 25597, 25603, 25607, 25613, 25617, 25623, 25627, 25633, - 25637, 25643, 25647, 25653, 25657, 25663, 25669, 25673, 25679, 25683, - 25687, 25691, 25695, 25699, 25703, 25709, 25712, 25716, 25720, 25726, - 25730, 25736, 25740, 25746, 25750, 25756, 25760, 25766, 25770, 25776, - 25780, 25786, 25792, 25796, 25802, 25806, 25812, 25818, 25822, 25826, - 25830, 25834, 25838, 25842, 25848, 25851, 25855, 25859, 25865, 25869, - 25875, 25879, 25885, 25891, 25895, 25900, 25904, 25908, 25912, 25916, - 25920, 25924, 25928, 25934, 25937, 25941, 25945, 25951, 25955, 25961, - 25965, 25971, 25975, 25981, 25985, 25991, 25995, 26001, 26005, 26011, - 26014, 26019, 26024, 26028, 26032, 26036, 26040, 26044, 26048, 26054, - 26057, 26061, 26065, 26071, 26075, 26081, 26085, 26091, 26095, 26101, - 26105, 26111, 26115, 26121, 26125, 26131, 26137, 26141, 26147, 26151, - 26157, 26163, 26169, 26175, 26181, 26187, 26193, 26199, 26203, 26207, - 26211, 26215, 26219, 26223, 26227, 26231, 26237, 26241, 26247, 26251, - 26257, 26261, 26267, 26271, 26277, 26281, 26287, 26291, 26297, 26301, - 26305, 26309, 26313, 26317, 26321, 26325, 26331, 26334, 26338, 26342, - 26348, 26352, 26358, 26362, 26368, 26372, 26378, 26382, 26388, 26392, - 26398, 26402, 26408, 26414, 26418, 26424, 26430, 26436, 26440, 26446, - 26452, 26456, 26460, 26464, 26468, 26472, 26478, 26481, 26485, 26490, - 26494, 26500, 26503, 26508, 26513, 26517, 26521, 26525, 26529, 26533, - 26537, 26541, 26545, 26549, 26555, 26559, 26563, 26569, 26573, 26579, - 26583, 26589, 26593, 26597, 26601, 26605, 26609, 26615, 26619, 26623, - 26627, 26631, 26635, 26639, 26643, 26647, 26651, 26655, 26661, 26667, - 26673, 26679, 26685, 26690, 26696, 26702, 26708, 26712, 26716, 26720, - 26724, 26728, 26732, 26736, 26740, 26744, 26748, 26752, 26756, 26760, - 26766, 26772, 26778, 26783, 26787, 26791, 26795, 26799, 26803, 26807, - 26811, 26815, 26819, 26825, 26831, 26837, 26843, 26849, 26855, 26861, - 26867, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901, 26907, - 26913, 26919, 26925, 26931, 26937, 26943, 26949, 26955, 26960, 26965, - 26970, 26975, 26981, 26987, 26993, 26999, 27005, 27011, 27017, 27022, - 27028, 27034, 27040, 27045, 27051, 27057, 27063, 27068, 27073, 27078, - 27083, 27088, 27093, 27098, 27103, 27108, 27113, 27118, 27123, 27127, - 27132, 27137, 27142, 27147, 27152, 27157, 27162, 27167, 27172, 27177, - 27182, 27187, 27192, 27197, 27202, 27207, 27212, 27217, 27222, 27227, - 27232, 27237, 27242, 27247, 27252, 27257, 27262, 27267, 27272, 27276, - 27281, 27286, 27291, 27296, 27301, 27306, 27311, 27316, 27321, 27326, - 27331, 27336, 27341, 27346, 27351, 27356, 27361, 27366, 27371, 27376, - 27381, 27386, 27391, 27396, 27401, 27405, 27410, 27415, 27420, 27425, - 27430, 27434, 27439, 27444, 27449, 27454, 27459, 27463, 27468, 27474, - 27479, 27484, 27489, 27494, 27500, 27505, 27510, 27515, 27520, 27525, - 27530, 27535, 27540, 27545, 27550, 27555, 27560, 27564, 27569, 27574, - 27579, 27584, 27589, 27594, 27599, 27604, 27609, 27614, 27619, 27624, - 27629, 27634, 27639, 27644, 27649, 27654, 27659, 27664, 27669, 27674, - 27679, 27684, 27689, 27694, 27699, 27704, 27709, 27714, 27719, 27725, - 27730, 27735, 27740, 27745, 27750, 27755, 27760, 27765, 27770, 27775, - 27780, 27784, 27789, 27794, 27799, 27804, 27809, 27814, 27819, 27824, - 27829, 27834, 27839, 27844, 27849, 27854, 27859, 27864, 27869, 27874, - 27879, 27884, 27889, 27894, 27899, 27904, 27909, 27914, 27920, 27924, - 27928, 27932, 27936, 27940, 27944, 27948, 27952, 27958, 27964, 27970, - 27976, 27982, 27988, 27994, 28001, 28007, 28012, 28017, 28022, 28027, - 28032, 28037, 28042, 28047, 28052, 28057, 28062, 28067, 28072, 28077, - 28082, 28087, 28092, 28097, 28102, 28107, 28112, 28117, 28122, 28127, - 28132, 28137, 28142, 28147, 0, 0, 0, 28154, 28165, 28170, 28178, 28183, - 28188, 28193, 28202, 28207, 28213, 28219, 28225, 28230, 28236, 28242, - 28246, 28251, 28256, 28266, 28271, 28276, 28283, 28288, 28293, 28302, - 28307, 28316, 28323, 28330, 28337, 28344, 28355, 28362, 28367, 28377, - 28381, 28388, 28393, 28400, 28406, 28413, 28422, 28429, 28436, 28445, - 28452, 28457, 28462, 28473, 28480, 28485, 28496, 28503, 28508, 28513, - 28521, 28530, 28537, 28544, 28554, 28559, 28564, 28569, 28578, 28586, - 28591, 28596, 28601, 28606, 28611, 28616, 28621, 28626, 28631, 28636, - 28641, 28647, 28653, 28659, 28664, 28669, 28674, 28679, 28684, 28689, - 28698, 28707, 28716, 28725, 0, 0, 0, 0, 0, 0, 0, 28734, 28738, 28742, - 28746, 28750, 28755, 28760, 28765, 28770, 28774, 28778, 28783, 28787, - 28791, 28795, 28799, 28804, 28808, 28812, 28817, 28822, 28827, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28832, 28838, 28842, 28846, 28850, 28854, 28859, 28864, - 28869, 28874, 28878, 28882, 28887, 28891, 28895, 28899, 28903, 28908, - 28912, 28916, 28921, 28926, 28931, 28937, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 28942, 28946, 28950, 28954, 28958, 28963, 28968, 28973, 28978, 28982, - 28986, 28991, 28995, 28999, 29003, 29007, 29012, 29016, 29020, 29025, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29030, 29034, 29038, 29042, 29046, - 29051, 29056, 29061, 29066, 29070, 29074, 29079, 29083, 0, 29087, 29091, - 29096, 0, 29100, 29105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29110, 29113, - 29117, 29121, 29125, 29129, 29133, 29137, 29141, 29145, 29149, 29153, - 29157, 29161, 29165, 29169, 29173, 29177, 29180, 29184, 29188, 29192, - 29196, 29200, 29204, 29208, 29212, 29216, 29220, 29224, 29228, 29232, - 29235, 29238, 29241, 29245, 29251, 29257, 29263, 29269, 29275, 29281, - 29287, 29293, 29299, 29305, 29311, 29317, 29323, 29329, 29338, 29347, - 29353, 29359, 29365, 29370, 29374, 29379, 29384, 29389, 29393, 29398, - 29403, 29408, 29412, 29417, 29421, 29426, 29431, 29436, 29441, 29445, - 29449, 29453, 29457, 29461, 29465, 29469, 29473, 29477, 29481, 29487, - 29491, 29495, 29499, 29503, 29507, 29515, 29521, 29525, 29531, 29535, - 29541, 29545, 0, 0, 29549, 29553, 29556, 29559, 29562, 29565, 29568, - 29571, 29574, 29577, 0, 0, 0, 0, 0, 0, 29580, 29588, 29596, 29604, 29612, - 29620, 29628, 29636, 29644, 29652, 0, 0, 0, 0, 0, 0, 29660, 29663, 29666, - 29669, 29674, 29677, 29682, 29689, 29697, 29702, 29709, 29712, 29719, - 29726, 29733, 29737, 29744, 29748, 29751, 29754, 29757, 29760, 29763, - 29766, 29769, 29772, 0, 0, 0, 0, 0, 0, 29775, 29778, 29781, 29784, 29787, - 29790, 29794, 29798, 29802, 29805, 29809, 29813, 29816, 29820, 29824, - 29827, 29830, 29833, 29837, 29841, 29845, 29849, 29853, 29856, 29859, - 29863, 29867, 29870, 29874, 29878, 29882, 29886, 29890, 29894, 29898, - 29902, 29909, 29914, 29919, 29924, 29929, 29935, 29941, 29947, 29953, - 29958, 29964, 29970, 29975, 29981, 29987, 29993, 29999, 30005, 30010, - 30016, 30021, 30027, 30033, 30039, 30045, 30051, 30056, 30061, 30067, - 30073, 30078, 30084, 30089, 30095, 30100, 30105, 30111, 30117, 30123, - 30129, 30135, 30141, 30147, 30153, 30159, 30165, 30171, 30177, 30182, - 30187, 30192, 30198, 30204, 0, 0, 0, 0, 0, 0, 0, 30212, 30221, 30230, - 30238, 30246, 30256, 30264, 30273, 30280, 30287, 30294, 30302, 30310, - 30318, 30326, 30334, 30342, 30350, 30358, 30365, 30373, 30381, 30389, - 30397, 30405, 30415, 30425, 30435, 30445, 30455, 30465, 30475, 30485, - 30495, 30505, 30515, 30525, 30535, 30545, 30553, 30561, 30571, 30579, 0, - 0, 0, 0, 0, 30589, 30593, 30597, 30601, 30605, 30609, 30613, 30617, - 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653, 30657, - 30661, 30665, 30669, 30673, 30677, 30681, 30687, 30691, 30697, 30701, - 30707, 30711, 30717, 30721, 30725, 30729, 30733, 30737, 30741, 30747, - 30753, 30759, 30765, 30771, 30777, 30783, 30789, 30795, 30801, 30807, - 30814, 30820, 30826, 30832, 30836, 30840, 30844, 30848, 30852, 30856, - 30860, 30866, 30872, 30878, 30883, 30890, 30895, 30900, 30906, 30911, - 30918, 30925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30932, 30938, 30942, 30947, - 30952, 30957, 30962, 30967, 30972, 30977, 30982, 30987, 30992, 30997, - 31002, 31007, 31011, 31015, 31020, 31025, 31030, 31034, 31038, 31042, - 31046, 31051, 31056, 31061, 31065, 31069, 31074, 0, 31079, 31084, 31089, - 31094, 31100, 31106, 31112, 31118, 31123, 31128, 31134, 31140, 0, 0, 0, - 0, 31147, 31152, 31158, 31164, 31170, 31175, 31180, 31185, 31190, 31195, - 31200, 31205, 0, 0, 0, 0, 31210, 0, 0, 0, 31215, 31220, 31225, 31230, - 31234, 31238, 31242, 31246, 31250, 31254, 31258, 31262, 31266, 31271, - 31277, 31283, 31289, 31294, 31299, 31305, 31311, 31316, 31321, 31327, - 31332, 31338, 31344, 31349, 31355, 31361, 31367, 31372, 31377, 31382, - 31388, 31394, 31399, 31405, 31410, 31416, 31421, 31427, 0, 0, 31433, - 31439, 31445, 31451, 31457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31463, - 31472, 31481, 31489, 31498, 31507, 31515, 31524, 31533, 31542, 31550, - 31558, 31567, 31575, 31583, 31592, 31601, 31609, 31618, 31627, 31635, - 31643, 31652, 31660, 31668, 31677, 31685, 31694, 31703, 31711, 31720, - 31729, 31737, 31745, 31754, 31763, 31771, 31780, 31789, 31798, 31807, - 31816, 31825, 31834, 0, 0, 0, 0, 31843, 31853, 31862, 31871, 31879, - 31888, 31896, 31905, 31913, 31922, 31931, 31940, 31949, 31958, 31967, - 31976, 31985, 31994, 32003, 32012, 32021, 32030, 32039, 32048, 32057, - 32065, 0, 0, 0, 0, 0, 0, 32073, 32081, 32088, 32095, 32102, 32109, 32116, - 32123, 32130, 32137, 32144, 0, 0, 0, 32152, 32160, 32168, 32172, 32178, - 32184, 32190, 32196, 32202, 32208, 32214, 32220, 32226, 32232, 32238, - 32244, 32250, 32256, 32262, 32266, 32272, 32278, 32284, 32290, 32296, - 32302, 32308, 32314, 32320, 32326, 32332, 32338, 32344, 32350, 32356, - 32360, 32365, 32370, 32375, 32379, 32384, 32388, 32393, 32398, 32403, - 32407, 32412, 32417, 32422, 32427, 32432, 32436, 32440, 32444, 32449, - 32453, 32457, 32461, 32466, 32471, 32476, 32481, 0, 0, 32487, 32491, - 32498, 32503, 32509, 32515, 32520, 32526, 32532, 32537, 32543, 32549, - 32555, 32560, 32566, 32571, 32576, 32582, 32587, 32593, 32598, 32604, - 32610, 32616, 32622, 32626, 32631, 32636, 32642, 32648, 32653, 32659, - 32665, 32669, 32674, 32679, 32683, 32688, 32692, 32697, 32702, 32708, - 32714, 32719, 32724, 32729, 32733, 32738, 32742, 32747, 32751, 32756, - 32761, 32766, 32771, 32777, 32784, 32791, 32801, 32810, 32817, 32823, - 32834, 32839, 32845, 0, 32850, 32855, 32860, 32868, 32874, 32882, 32887, - 32893, 32899, 32905, 32910, 32916, 32921, 32928, 32934, 32939, 32945, - 32951, 32957, 32964, 32971, 32978, 32983, 32988, 32995, 33002, 33009, - 33016, 33023, 0, 0, 33030, 33037, 33044, 33050, 33056, 33062, 33068, - 33074, 33080, 33086, 33092, 0, 0, 0, 0, 0, 0, 33098, 33104, 33109, 33114, - 33119, 33124, 33129, 33134, 33139, 33144, 0, 0, 0, 0, 0, 0, 33149, 33154, - 33159, 33164, 33169, 33174, 33179, 33188, 33195, 33200, 33205, 33210, - 33215, 33220, 0, 0, 33225, 33232, 33235, 33238, 33242, 33247, 33251, - 33257, 33262, 33268, 33275, 33283, 33287, 33292, 33296, 33301, 33308, - 33316, 33323, 33329, 33337, 33344, 33349, 33353, 33360, 33364, 33369, - 33374, 33381, 33389, 33396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33404, 33410, 33416, 33420, 33424, 33428, - 33432, 33438, 33442, 33448, 33452, 33458, 33464, 33472, 33478, 33486, - 33490, 33494, 33498, 33504, 33507, 33513, 33517, 33523, 33527, 33531, - 33537, 33541, 33547, 33551, 33557, 33565, 33573, 33581, 33587, 33591, - 33597, 33601, 33607, 33610, 33613, 33619, 33623, 33629, 33632, 33635, - 33638, 33641, 33645, 33651, 33657, 33660, 33663, 33667, 33672, 33677, - 33684, 33689, 33696, 33703, 33712, 33719, 33728, 33733, 33740, 33747, - 33756, 33761, 33768, 33773, 33779, 33785, 33791, 33797, 33803, 33809, - 33815, 0, 0, 0, 33821, 33825, 33828, 33831, 33834, 33837, 33840, 33843, - 33846, 33849, 33852, 33855, 33858, 33861, 33866, 33871, 33876, 33879, - 33884, 33889, 33894, 33899, 33906, 33911, 33916, 33921, 33926, 33933, - 33939, 33945, 33951, 33957, 33963, 33972, 33981, 33987, 33993, 34002, - 34011, 34020, 34029, 34038, 34047, 34056, 34065, 34074, 34079, 0, 34084, - 34089, 34094, 34099, 34103, 34107, 34111, 34116, 34120, 34124, 34129, - 34133, 34138, 34143, 34148, 34153, 34158, 34163, 34168, 34173, 34178, - 34182, 34186, 34191, 34196, 34201, 34205, 34209, 34213, 34217, 34222, - 34226, 34231, 34235, 34241, 34247, 34253, 34259, 34265, 34271, 34277, - 34283, 34289, 34294, 34299, 34306, 34314, 34319, 34324, 34329, 34333, - 34337, 34341, 34345, 34349, 34353, 34357, 34361, 34365, 34369, 34374, - 34379, 34384, 34390, 34396, 34400, 34406, 34410, 34416, 34422, 34427, - 34434, 34438, 34444, 34448, 34454, 34459, 34466, 34473, 34478, 34485, - 34490, 34495, 34499, 34505, 34509, 34515, 34522, 34529, 34533, 34539, - 34545, 34549, 34555, 34560, 34564, 34570, 34575, 34580, 34585, 34590, - 34594, 34598, 34603, 34608, 34615, 34621, 34626, 34633, 34638, 34645, - 34650, 34659, 34665, 34671, 34675, 0, 0, 0, 0, 0, 0, 0, 0, 34679, 34688, - 34695, 34702, 34709, 34713, 34718, 34723, 34728, 34733, 34738, 34743, - 34748, 34753, 34758, 34763, 34768, 34773, 34777, 34781, 34786, 34791, - 34796, 34801, 34806, 34811, 34815, 34820, 34825, 34830, 34835, 34839, - 34843, 34847, 34851, 34856, 34861, 34865, 34870, 34875, 34879, 34885, - 34891, 34897, 34902, 34907, 34913, 34918, 34924, 34929, 34935, 34941, - 34946, 34952, 34958, 34963, 34969, 34975, 34981, 34986, 0, 0, 0, 34991, - 34997, 35007, 35013, 35021, 35027, 35032, 35036, 35040, 35044, 35048, - 35052, 35056, 35060, 35064, 0, 0, 0, 35068, 35073, 35078, 35083, 35090, - 35096, 35102, 35108, 35114, 35120, 35126, 35132, 35138, 35144, 35150, - 35157, 35164, 35171, 35178, 35185, 35192, 35199, 35206, 35213, 35220, - 35227, 35234, 35241, 35248, 35255, 35262, 35269, 35276, 35283, 35290, - 35297, 35304, 35311, 35318, 35325, 35332, 35339, 35346, 35353, 35361, - 35369, 35377, 35383, 35389, 35395, 35403, 35412, 35419, 35426, 35432, - 35439, 35446, 35453, 35461, 35468, 0, 0, 0, 0, 0, 0, 0, 35475, 35482, - 35489, 35496, 35503, 35510, 35517, 35524, 35531, 35538, 35545, 35552, - 35559, 35566, 35573, 35580, 35587, 35594, 35601, 35608, 35615, 35622, - 35629, 35636, 35643, 35650, 35657, 35664, 35671, 35678, 35685, 35692, - 35699, 35706, 35713, 35720, 35727, 35734, 35741, 35748, 35755, 35762, - 35770, 0, 0, 35777, 35784, 35792, 35800, 35808, 35816, 35824, 35832, - 35842, 35852, 35862, 0, 0, 0, 0, 0, 0, 0, 0, 35872, 35877, 35882, 35887, - 35892, 35901, 35912, 35921, 35932, 35938, 35951, 35957, 35964, 35971, - 35976, 35982, 35988, 35999, 36008, 36015, 36022, 36031, 36038, 36047, - 36057, 36067, 36074, 36081, 36088, 36098, 36103, 36111, 36117, 36125, - 36134, 36139, 36146, 36152, 36157, 36162, 36167, 36173, 36180, 0, 0, 0, - 0, 0, 36188, 36193, 36199, 36205, 36213, 36219, 36225, 36231, 36236, - 36243, 36248, 36254, 36260, 36268, 36274, 36282, 36287, 36294, 36300, - 36308, 36316, 36322, 36328, 36335, 36342, 36348, 36355, 36361, 36367, - 36372, 36378, 36386, 36394, 36400, 36406, 36412, 36418, 36426, 36430, - 36436, 36442, 36448, 36454, 36460, 36466, 36470, 36475, 36480, 36487, - 36492, 36496, 36502, 36507, 36512, 36516, 36521, 36526, 36530, 36535, - 36540, 36547, 36551, 36556, 36561, 36565, 36570, 36574, 36579, 36583, - 36588, 36593, 36599, 36604, 36609, 36613, 36618, 36624, 36631, 36636, - 36641, 36646, 36651, 36656, 36660, 36666, 36673, 36680, 36685, 36690, - 36694, 36700, 36706, 36711, 36716, 36721, 36727, 36732, 36738, 36743, - 36749, 36755, 36761, 36768, 36775, 36782, 36789, 36796, 36803, 36808, - 36816, 36825, 36834, 36843, 36852, 36861, 36870, 36882, 36891, 36900, - 36909, 36915, 36920, 36927, 36935, 36943, 36950, 36957, 36964, 36971, - 36979, 36988, 36997, 37006, 37015, 37024, 37033, 37042, 37051, 37060, - 37069, 37078, 37087, 37096, 37105, 37113, 37122, 37133, 37142, 37153, - 37166, 37175, 37184, 37194, 37203, 37211, 37220, 37226, 37231, 37239, - 37244, 37252, 37257, 37266, 37272, 37278, 37285, 37290, 37295, 37303, - 37311, 37320, 37329, 37334, 37341, 37351, 37359, 37368, 37374, 37380, - 37385, 37392, 37397, 37406, 37411, 37416, 37421, 37428, 37434, 37439, - 37448, 37456, 37461, 37466, 37473, 37480, 37484, 37488, 37491, 37494, - 37497, 37500, 37503, 37506, 37513, 37516, 37519, 37524, 37528, 37532, - 37536, 37540, 37544, 37554, 37560, 37566, 37572, 37580, 37588, 37594, - 37600, 37607, 37613, 37618, 37624, 37631, 37637, 37644, 37650, 37658, - 37664, 37671, 37677, 37683, 37689, 37695, 37701, 37707, 37718, 37728, - 37734, 37740, 37750, 37756, 37764, 37772, 37780, 37785, 37790, 37796, - 37801, 37809, 37815, 37819, 37826, 37833, 37838, 37847, 37855, 37863, - 37870, 37877, 37884, 37891, 37899, 37907, 37918, 37929, 37937, 37945, - 37953, 37961, 37970, 37979, 37987, 37995, 38004, 38013, 38024, 38035, - 38046, 38057, 38066, 38075, 38084, 38093, 38104, 38115, 38123, 38131, - 38139, 38147, 38155, 38163, 38171, 38179, 38187, 38195, 38203, 38211, - 38220, 38229, 38238, 38247, 38258, 38269, 38277, 38285, 38293, 38301, - 38310, 38319, 38327, 38335, 38347, 38359, 38368, 38377, 38386, 38395, - 38403, 38411, 38419, 38427, 38435, 38443, 38451, 38459, 38467, 38475, - 38484, 38493, 38502, 38511, 38521, 38531, 38541, 38551, 38561, 38571, - 38581, 38591, 38599, 38607, 38615, 38623, 38631, 38639, 38647, 38655, - 38667, 38679, 38688, 38697, 38705, 38713, 38721, 38729, 38740, 38751, - 38762, 38773, 38785, 38797, 38805, 38813, 38821, 38829, 38838, 38847, - 38856, 38865, 38873, 38881, 38889, 38897, 38905, 38913, 38923, 38933, - 38943, 38953, 38961, 38969, 38977, 38985, 38993, 39001, 39009, 39017, - 39025, 39033, 39041, 39049, 39057, 39065, 39073, 39081, 39089, 39097, - 39105, 39113, 39121, 39129, 39137, 39145, 39154, 39163, 39172, 39180, - 39189, 39198, 39207, 39216, 39226, 39235, 39242, 39247, 39254, 39261, - 39269, 39277, 39287, 39297, 39307, 39317, 39328, 39339, 39349, 39359, - 39369, 39379, 39389, 39399, 39409, 39419, 39430, 39441, 39451, 39461, - 39471, 39481, 39489, 39497, 39506, 39515, 39523, 39531, 39542, 39553, - 39564, 39575, 39587, 39599, 39610, 39621, 39632, 39643, 39652, 39661, - 39669, 39677, 39684, 39691, 39699, 39707, 39717, 39727, 39737, 39747, - 39758, 39769, 39779, 39789, 39799, 39809, 39819, 39829, 39839, 39849, - 39860, 39871, 39881, 39891, 39901, 39911, 39918, 39925, 39933, 39941, - 39951, 39961, 39971, 39981, 39992, 40003, 40013, 40023, 40033, 40043, - 40051, 40059, 40067, 40075, 40084, 40093, 40101, 40109, 40116, 40123, - 40130, 40137, 40145, 40153, 40161, 40169, 40180, 40191, 40202, 40213, - 40224, 40235, 40243, 40251, 40262, 40273, 40284, 40295, 40306, 40317, - 40325, 40333, 40344, 40355, 40366, 0, 0, 40377, 40385, 40393, 40404, - 40415, 40426, 0, 0, 40437, 40445, 40453, 40464, 40475, 40486, 40497, - 40508, 40519, 40527, 40535, 40546, 40557, 40568, 40579, 40590, 40601, - 40609, 40617, 40628, 40639, 40650, 40661, 40672, 40683, 40691, 40699, - 40710, 40721, 40732, 40743, 40754, 40765, 40773, 40781, 40792, 40803, - 40814, 0, 0, 40825, 40833, 40841, 40852, 40863, 40874, 0, 0, 40885, - 40893, 40901, 40912, 40923, 40934, 40945, 40956, 0, 40967, 0, 40975, 0, - 40986, 0, 40997, 41008, 41016, 41024, 41035, 41046, 41057, 41068, 41079, - 41090, 41098, 41106, 41117, 41128, 41139, 41150, 41161, 41172, 41180, - 41188, 41196, 41204, 41212, 41220, 41228, 41236, 41244, 41252, 41260, - 41268, 41276, 0, 0, 41284, 41295, 41306, 41320, 41334, 41348, 41362, - 41376, 41390, 41401, 41412, 41426, 41440, 41454, 41468, 41482, 41496, - 41507, 41518, 41532, 41546, 41560, 41574, 41588, 41602, 41613, 41624, - 41638, 41652, 41666, 41680, 41694, 41708, 41719, 41730, 41744, 41758, - 41772, 41786, 41800, 41814, 41825, 41836, 41850, 41864, 41878, 41892, - 41906, 41920, 41928, 41936, 41947, 41955, 0, 41966, 41974, 41985, 41993, - 42001, 42009, 42017, 42025, 42028, 42031, 42034, 42037, 42043, 42054, - 42062, 0, 42073, 42081, 42092, 42100, 42108, 42116, 42124, 42132, 42138, - 42144, 42150, 42158, 42166, 42177, 0, 0, 42188, 42196, 42207, 42215, - 42223, 42231, 0, 42239, 42245, 42251, 42257, 42265, 42273, 42284, 42295, - 42303, 42311, 42319, 42330, 42338, 42346, 42354, 42362, 42370, 42376, - 42382, 0, 0, 42385, 42396, 42404, 0, 42415, 42423, 42434, 42442, 42450, - 42458, 42466, 42474, 42477, 0, 42480, 42484, 42488, 42492, 42496, 42500, - 42504, 42508, 42512, 42516, 42520, 42524, 42530, 42536, 42542, 42545, - 42548, 42550, 42554, 42558, 42562, 42566, 42569, 42573, 42577, 42583, - 42589, 42596, 42603, 42608, 42613, 42619, 42625, 42627, 42630, 42632, - 42636, 42640, 42644, 42648, 42652, 42656, 42660, 42664, 42668, 42674, - 42678, 42682, 42688, 42693, 42700, 42702, 42705, 42709, 42713, 42718, - 42724, 42726, 42735, 42744, 42747, 42751, 42753, 42755, 42757, 42761, - 42767, 42769, 42773, 42777, 42784, 42791, 42795, 42800, 42805, 42810, - 42815, 42819, 42823, 42826, 42830, 42834, 42841, 42846, 42850, 42854, - 42859, 42863, 42867, 42872, 42877, 42881, 42885, 42889, 42891, 42896, - 42901, 42905, 42909, 42913, 42917, 0, 42921, 42925, 42929, 42935, 42941, - 42947, 42953, 42960, 42967, 42972, 42977, 42981, 0, 0, 42987, 42990, - 42993, 42996, 42999, 43002, 43005, 43009, 43013, 43018, 43023, 43028, - 43035, 43039, 43042, 43045, 43048, 43051, 43054, 43057, 43060, 43063, - 43066, 43070, 43074, 43079, 43084, 0, 43089, 43095, 43101, 43107, 43114, - 43121, 43128, 43135, 43141, 43148, 43155, 43162, 43169, 0, 0, 0, 43176, - 43179, 43182, 43185, 43190, 43193, 43196, 43199, 43202, 43205, 43208, - 43213, 43216, 43219, 43222, 43225, 43228, 43233, 43236, 43239, 43242, - 43245, 43248, 43253, 43256, 43259, 43264, 43269, 43273, 43276, 43279, - 43282, 43285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43288, 43293, - 43298, 43305, 43313, 43318, 43323, 43327, 43331, 43336, 43343, 43350, - 43354, 43359, 43364, 43369, 43374, 43381, 43386, 43391, 43396, 43405, - 43412, 43419, 43423, 43428, 43434, 43439, 43446, 43454, 43462, 43466, - 43470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43474, 43478, 43485, - 43490, 43494, 43499, 43503, 43507, 43511, 43513, 43517, 43521, 43525, - 43530, 43535, 43539, 43547, 43550, 43554, 43557, 43560, 43566, 43571, - 43574, 43580, 43584, 43589, 43594, 43597, 43601, 43605, 43609, 43611, - 43614, 43617, 43621, 43623, 43628, 43631, 43634, 43639, 43644, 43650, - 43653, 43656, 43660, 43665, 43668, 43671, 43674, 43678, 43682, 43686, - 43689, 43691, 43694, 43697, 43700, 43704, 43709, 43712, 43717, 43722, - 43727, 43732, 43738, 43743, 43747, 43752, 43757, 43763, 43769, 43774, - 43779, 43785, 43789, 43792, 43795, 43797, 43801, 43807, 43814, 43821, - 43828, 43835, 43842, 43849, 43856, 43863, 43871, 43878, 43886, 43893, - 43900, 43908, 43916, 43921, 43926, 43931, 43936, 43941, 43946, 43951, - 43956, 43961, 43966, 43972, 43978, 43984, 43990, 43997, 44005, 44011, - 44017, 44023, 44029, 44035, 44041, 44047, 44053, 44059, 44065, 44072, - 44079, 44086, 44093, 44101, 44110, 44117, 44128, 44135, 44142, 44151, - 44158, 44167, 44176, 44183, 44191, 44199, 44202, 0, 0, 0, 0, 44205, - 44207, 44210, 44212, 44215, 44218, 44221, 44225, 44229, 44234, 44239, - 44243, 44247, 44251, 44255, 44260, 44266, 44271, 44277, 44282, 44287, - 44292, 44298, 44303, 44309, 44315, 44319, 44323, 44328, 44333, 44338, - 44343, 44348, 44356, 44364, 44372, 44380, 44387, 44395, 44402, 44409, - 44416, 44426, 44433, 44440, 44447, 44454, 44462, 44470, 44477, 44484, - 44492, 44500, 44505, 44513, 44518, 44523, 44529, 44534, 44540, 44547, - 44554, 44559, 44565, 44570, 44573, 44577, 44580, 44584, 44588, 44592, - 44597, 44602, 44608, 44614, 44618, 44622, 44626, 44630, 44636, 44642, - 44646, 44651, 44655, 44660, 44664, 44668, 44671, 44675, 44678, 44682, - 44689, 44697, 44709, 44720, 44725, 44734, 44741, 44748, 44756, 44760, - 44766, 44774, 44778, 44783, 44788, 44794, 44800, 44806, 44813, 44817, - 44821, 44826, 44829, 44831, 44835, 44839, 44847, 44851, 44853, 44855, - 44859, 44867, 44872, 44878, 44888, 44895, 44900, 44904, 44908, 44912, - 44915, 44918, 44921, 44925, 44929, 44933, 44937, 44941, 44944, 44948, - 44952, 44955, 44957, 44960, 44962, 44966, 44970, 44972, 44978, 44981, - 44986, 44990, 44994, 44996, 44998, 45000, 45003, 45007, 45011, 45015, - 45019, 45023, 45029, 45035, 45037, 45039, 45041, 45043, 45046, 45048, - 45052, 45054, 45058, 45062, 45068, 45072, 45076, 45080, 45084, 45089, - 45096, 45101, 45112, 45123, 45128, 45135, 45144, 45148, 45153, 45156, - 45161, 45165, 45171, 45176, 45189, 45199, 45203, 45207, 45214, 45219, - 45222, 45224, 45227, 45231, 45236, 45243, 45247, 45252, 45257, 45260, - 45265, 45270, 45277, 45284, 45290, 45296, 45305, 45314, 45318, 45322, - 45324, 45329, 45333, 45337, 45346, 45355, 45362, 45369, 45378, 45387, - 45393, 45399, 45407, 45415, 45417, 45419, 45426, 45433, 45440, 45447, - 45453, 45459, 45463, 45467, 45474, 45481, 45489, 45497, 45508, 45519, - 45528, 45537, 45539, 45543, 45547, 45552, 45557, 45566, 45575, 45578, - 45581, 45584, 45587, 45590, 45595, 45599, 45604, 45609, 45612, 45615, - 45618, 45621, 45624, 45628, 45631, 45634, 45637, 45640, 45642, 45644, - 45646, 45648, 45656, 45664, 45670, 45674, 45680, 45690, 45696, 45702, - 45708, 45716, 45726, 45739, 45743, 45747, 45749, 45755, 45757, 45759, - 45761, 45763, 45769, 45772, 45778, 45784, 45788, 45792, 45796, 45799, - 45803, 45807, 45809, 45818, 45827, 45832, 45837, 45843, 45849, 45855, - 45858, 45861, 45864, 45867, 45869, 45875, 45880, 45885, 45891, 45897, - 45906, 45915, 45922, 45929, 45936, 45943, 45953, 45963, 45974, 45985, - 45996, 46007, 46016, 46025, 46034, 46043, 46051, 46063, 46075, 46091, - 46094, 46100, 46106, 46112, 46120, 46135, 46151, 46157, 46163, 46170, - 46176, 46185, 46192, 46206, 46221, 46226, 46232, 46240, 46243, 46246, - 46248, 46251, 46254, 46256, 46258, 46262, 46265, 46268, 46271, 46274, - 46279, 46284, 46289, 46294, 46299, 46302, 46304, 46306, 46308, 46312, - 46316, 46320, 46326, 46330, 46332, 46334, 46339, 46344, 46349, 46354, - 46359, 46364, 46366, 46368, 46378, 46382, 46388, 46397, 46399, 46405, - 46411, 46418, 46422, 46424, 46428, 46430, 46434, 46438, 46442, 46444, - 46446, 46448, 46455, 46464, 46473, 46482, 46491, 46500, 46509, 46518, - 46527, 46535, 46543, 46552, 46561, 46570, 46579, 46587, 46595, 46604, - 46613, 46622, 46632, 46641, 46651, 46660, 46670, 46679, 46689, 46699, - 46708, 46718, 46727, 46737, 46746, 46756, 46765, 46774, 46783, 46792, - 46801, 46811, 46820, 46829, 46838, 46848, 46857, 46866, 46875, 46884, - 46894, 46904, 46913, 46922, 46930, 46939, 46946, 46955, 46964, 46975, - 46984, 46994, 47004, 47011, 47018, 47025, 47034, 47043, 47052, 47061, - 47068, 47073, 47082, 47088, 47091, 47098, 47101, 47106, 47111, 47114, - 47117, 47125, 47128, 47133, 47136, 47144, 47149, 47157, 47160, 47163, - 47166, 47171, 47176, 47179, 47182, 47190, 47193, 47200, 47207, 47211, - 47215, 47220, 47225, 47230, 47235, 47240, 47245, 47250, 47255, 47262, - 47268, 47275, 47282, 47288, 47295, 47302, 47310, 47317, 47323, 47330, - 47338, 47345, 47349, 47355, 47367, 47379, 47383, 47387, 47392, 47397, - 47408, 47412, 47417, 47422, 47428, 47434, 47440, 47446, 47455, 47464, - 47472, 47483, 47494, 47502, 47513, 47524, 47532, 47543, 47554, 47562, - 47570, 47580, 47590, 47593, 47596, 47599, 47604, 47608, 47614, 47621, - 47628, 47636, 47643, 47647, 47651, 47655, 47659, 47661, 47665, 47669, - 47675, 47681, 47689, 47697, 47700, 47707, 47709, 47711, 47715, 47719, - 47724, 47730, 47736, 47742, 47748, 47757, 47766, 47775, 47779, 47781, - 47785, 47792, 47799, 47806, 47813, 47820, 47823, 47828, 47834, 47837, - 47842, 47847, 47852, 47857, 47861, 47868, 47875, 47882, 47889, 47893, - 47897, 47901, 47905, 47911, 47917, 47922, 47928, 47934, 47940, 47946, - 47954, 47961, 47968, 47975, 47982, 47988, 47994, 48003, 48007, 48014, - 48018, 48022, 48028, 48034, 48040, 48046, 48050, 48054, 48057, 48061, - 48065, 48072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48079, 48082, 48086, 48090, 48096, 48102, 48108, 48116, - 48123, 48127, 48135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48140, 48143, 48146, 48149, 48152, 48155, 48158, 48161, - 48164, 48167, 48171, 48175, 48179, 48183, 48187, 48191, 48195, 48199, - 48203, 48207, 48211, 48214, 48217, 48220, 48223, 48226, 48229, 48232, - 48235, 48238, 48242, 48246, 48250, 48254, 48258, 48262, 48266, 48270, - 48274, 48278, 48282, 48288, 48294, 48300, 48307, 48314, 48321, 48328, - 48335, 48342, 48349, 48356, 48363, 48370, 48377, 48384, 48391, 48398, - 48405, 48412, 48419, 48424, 48430, 48436, 48442, 48447, 48453, 48459, - 48465, 48470, 48476, 48482, 48487, 48493, 48499, 48504, 48510, 48516, - 48521, 48527, 48533, 48538, 48544, 48550, 48556, 48562, 48568, 48573, - 48579, 48585, 48591, 48596, 48602, 48608, 48614, 48619, 48625, 48631, - 48636, 48642, 48648, 48653, 48659, 48665, 48670, 48676, 48682, 48687, - 48693, 48699, 48705, 48711, 48717, 48722, 48728, 48734, 48740, 48745, - 48751, 48757, 48763, 48768, 48774, 48780, 48785, 48791, 48797, 48802, - 48808, 48814, 48819, 48825, 48831, 48836, 48842, 48848, 48854, 48860, - 48866, 48870, 48876, 48882, 48888, 48894, 48900, 48906, 48912, 48918, - 48924, 48930, 48934, 48938, 48942, 48946, 48950, 48954, 48958, 48962, - 48966, 48971, 48977, 48982, 48987, 48992, 48997, 49006, 49015, 49024, - 49033, 49042, 49051, 49060, 49069, 49075, 49083, 49091, 49097, 49104, - 49112, 49120, 49127, 49133, 49141, 49149, 49155, 49162, 49170, 49178, - 49185, 49191, 49199, 49208, 49217, 49225, 49234, 49243, 49249, 49256, - 49264, 49273, 49282, 49290, 49299, 49308, 49315, 49322, 49331, 49340, - 49349, 49358, 49367, 49376, 49383, 49390, 49399, 49408, 49417, 49426, - 49435, 49444, 49451, 49458, 49467, 49476, 49485, 49495, 49505, 49514, - 49524, 49534, 49544, 49554, 49564, 49574, 49583, 49592, 49599, 49607, - 49615, 49623, 49631, 49636, 49641, 49650, 49658, 49664, 49673, 49681, - 49688, 49697, 49705, 49711, 49720, 49728, 49735, 49744, 49752, 49758, - 49767, 49775, 49782, 49792, 49801, 49808, 49818, 49827, 49834, 49844, - 49853, 49860, 49868, 49877, 49886, 49894, 49905, 49915, 49922, 49927, - 49932, 49936, 49941, 49946, 49951, 49955, 49960, 49967, 49975, 49982, - 49990, 49994, 50000, 50006, 50012, 50016, 50023, 50029, 50036, 50040, - 50047, 50053, 50060, 50064, 50070, 50076, 50082, 50086, 50089, 50093, - 50097, 50103, 50109, 50114, 50118, 50123, 50133, 50140, 50151, 50161, - 50165, 50173, 50183, 50186, 50189, 50196, 50204, 50210, 50215, 50223, - 50232, 50241, 50249, 50253, 50257, 50260, 50263, 50267, 50271, 50274, - 50277, 50282, 50287, 50293, 50299, 50304, 50309, 50315, 50321, 50326, - 50331, 50336, 50341, 50347, 50353, 50358, 50363, 50369, 50375, 50380, - 50385, 50388, 50391, 50400, 50402, 50404, 50407, 50411, 50417, 50419, - 50422, 50429, 50436, 50443, 50450, 50459, 50472, 50477, 50482, 50486, - 50491, 50498, 50505, 50513, 50521, 50529, 50537, 50541, 50545, 50550, - 50555, 50560, 50565, 50568, 50574, 50580, 50589, 50598, 50606, 50614, - 50623, 50632, 50636, 50643, 50650, 50657, 50664, 50672, 50680, 50688, - 50696, 50700, 50704, 50708, 50713, 50718, 50724, 50730, 50734, 50740, - 50742, 50744, 50746, 50748, 50751, 50754, 50756, 50758, 50760, 50764, - 50768, 50770, 50772, 50775, 50778, 50782, 50788, 50794, 50796, 50803, - 50807, 50812, 50817, 50819, 50829, 50835, 50841, 50847, 50853, 50859, - 50865, 50870, 50873, 50876, 50879, 50881, 50883, 50887, 50891, 50896, - 50901, 50906, 50909, 50913, 50918, 50921, 50925, 50930, 50935, 50940, - 50945, 50950, 50955, 50960, 50965, 50970, 50975, 50980, 50985, 50991, - 50997, 51003, 51005, 51008, 51010, 51013, 51015, 51017, 51019, 51021, - 51023, 51025, 51027, 51029, 51031, 51033, 51035, 51037, 51039, 51041, - 51043, 51045, 51047, 51052, 51057, 51062, 51067, 51072, 51077, 51082, - 51087, 51092, 51097, 51102, 51107, 51112, 51117, 51122, 51127, 51132, - 51137, 51142, 51147, 51151, 51155, 51159, 51165, 51171, 51176, 51181, - 51186, 51192, 51198, 51203, 51211, 51219, 51227, 51235, 51243, 51251, - 51259, 51267, 51273, 51278, 51283, 51288, 51291, 51295, 51299, 51303, - 51307, 51311, 51315, 51321, 51328, 51335, 51343, 51348, 51353, 51360, - 51367, 51374, 51381, 51384, 51387, 51392, 51394, 51398, 51403, 51405, - 51407, 51409, 51411, 51416, 51419, 51421, 51426, 51432, 51439, 51442, - 51446, 51451, 51456, 51464, 51470, 51476, 51488, 51495, 51503, 51508, - 51513, 51519, 51522, 51525, 51530, 51532, 51536, 51538, 51540, 51542, - 51544, 51546, 51548, 51553, 51555, 51557, 51559, 51561, 51565, 51567, - 51570, 51575, 51580, 51585, 51590, 51596, 51602, 51604, 51607, 51614, - 51620, 51626, 51633, 51637, 51641, 51643, 51645, 51649, 51655, 51660, - 51662, 51666, 51675, 51683, 51691, 51697, 51703, 51708, 51714, 51719, - 51722, 51736, 51739, 51744, 51749, 51755, 51765, 51767, 51773, 51779, - 51783, 51790, 51794, 51796, 51798, 51802, 51808, 51813, 51819, 51821, - 51827, 51829, 51835, 51837, 51839, 51844, 51846, 51850, 51855, 51857, - 51862, 51867, 51871, 51878, 51888, 51893, 51898, 51901, 51906, 51909, - 51914, 51919, 51923, 51925, 51927, 51931, 51935, 51939, 51943, 51947, - 51949, 51953, 51956, 51959, 51962, 51966, 51970, 51975, 51979, 51984, - 51989, 51993, 51999, 52006, 52009, 52015, 52020, 52024, 52029, 52035, - 52041, 52048, 52054, 52061, 52068, 52070, 52077, 52081, 52088, 52094, - 52099, 52105, 52109, 52114, 52117, 52123, 52129, 52136, 52144, 52151, - 52160, 52170, 52177, 52183, 52187, 52195, 52200, 52209, 52212, 52215, - 52224, 52235, 52242, 52244, 52250, 52255, 52257, 52260, 52264, 52272, - 52281, 52284, 52289, 52295, 52302, 52309, 52316, 52323, 52329, 52335, - 52341, 52349, 52354, 52357, 52361, 52364, 52375, 52385, 52395, 52404, - 52415, 52425, 52434, 52440, 52448, 52452, 52460, 52464, 52472, 52479, - 52486, 52495, 52504, 52514, 52524, 52534, 52544, 52553, 52562, 52572, - 52582, 52591, 52600, 52607, 52614, 52621, 52628, 52635, 52642, 52649, - 52656, 52663, 52671, 52677, 52683, 52689, 52695, 52701, 52707, 52713, - 52719, 52725, 52732, 52740, 52748, 52756, 52764, 52772, 52780, 52788, - 52796, 52804, 52813, 52818, 52821, 52825, 52829, 52835, 52838, 52843, - 52849, 52854, 52858, 52863, 52869, 52876, 52879, 52886, 52893, 52897, - 52906, 52915, 52920, 52926, 52931, 52936, 52943, 52950, 52957, 52964, - 52972, 52976, 52984, 52989, 52993, 53000, 53004, 53010, 53018, 53023, - 53030, 53034, 53039, 53043, 53048, 53052, 53057, 53062, 53071, 53073, - 53077, 53081, 53088, 53095, 53101, 53109, 53115, 53122, 53127, 53130, - 53135, 53140, 53145, 53153, 53157, 53164, 53171, 53178, 53183, 53188, - 53194, 53199, 53204, 53210, 53215, 53218, 53222, 53226, 53233, 53243, - 53248, 53257, 53266, 53272, 53278, 53284, 53290, 53296, 53302, 53309, - 53316, 53325, 53334, 53340, 53346, 53351, 53356, 53363, 53370, 53376, - 53379, 53382, 53386, 53390, 53394, 53399, 53405, 53411, 53418, 53425, - 53430, 53434, 53438, 53442, 53446, 53450, 53454, 53458, 53462, 53466, - 53470, 53474, 53478, 53482, 53486, 53490, 53494, 53498, 53502, 53506, - 53510, 53514, 53518, 53522, 53526, 53530, 53534, 53538, 53542, 53546, - 53550, 53554, 53558, 53562, 53566, 53570, 53574, 53578, 53582, 53586, - 53590, 53594, 53598, 53602, 53606, 53610, 53614, 53618, 53622, 53626, - 53630, 53634, 53638, 53642, 53646, 53650, 53654, 53658, 53662, 53666, - 53670, 53674, 53678, 53682, 53686, 53690, 53694, 53698, 53702, 53706, - 53710, 53714, 53718, 53722, 53726, 53730, 53734, 53738, 53742, 53746, - 53750, 53754, 53758, 53762, 53766, 53770, 53774, 53778, 53782, 53786, - 53790, 53794, 53798, 53802, 53806, 53810, 53814, 53818, 53822, 53826, - 53830, 53834, 53838, 53842, 53846, 53850, 53854, 53858, 53862, 53866, - 53870, 53874, 53878, 53882, 53886, 53890, 53894, 53898, 53902, 53906, - 53910, 53914, 53918, 53922, 53926, 53930, 53934, 53938, 53942, 53946, - 53950, 53954, 53958, 53962, 53966, 53970, 53974, 53978, 53982, 53986, - 53990, 53994, 53998, 54002, 54006, 54010, 54014, 54018, 54022, 54026, - 54030, 54034, 54038, 54042, 54046, 54050, 54054, 54058, 54062, 54066, - 54070, 54074, 54078, 54082, 54086, 54090, 54094, 54098, 54102, 54106, - 54110, 54114, 54118, 54122, 54126, 54130, 54134, 54138, 54142, 54146, - 54150, 54154, 54158, 54162, 54166, 54170, 54174, 54178, 54182, 54186, - 54190, 54194, 54198, 54202, 54206, 54210, 54214, 54218, 54222, 54226, - 54230, 54234, 54238, 54242, 54246, 54250, 54254, 54258, 54262, 54266, - 54270, 54274, 54278, 54282, 54286, 54290, 54294, 54298, 54302, 54306, - 54310, 54314, 54318, 54322, 54326, 54330, 54334, 54338, 54342, 54346, - 54350, 54354, 54358, 54362, 54366, 54370, 54374, 54378, 54382, 54386, - 54390, 54394, 54398, 54402, 54406, 54410, 54414, 54418, 54422, 54426, - 54430, 54434, 54438, 54442, 54446, 54450, 54454, 54461, 54469, 54475, - 54481, 54488, 54495, 54501, 54507, 54514, 54521, 54526, 54531, 54536, - 54541, 54547, 54553, 54561, 54568, 54573, 54578, 54586, 54595, 54602, - 54612, 54623, 54626, 54629, 54633, 54637, 54643, 54649, 54659, 54669, - 54678, 54687, 54693, 54699, 54706, 54713, 54722, 54732, 54743, 54753, - 54763, 54773, 54784, 54795, 54805, 54816, 54826, 54836, 54844, 54854, - 54864, 54875, 54886, 54893, 54900, 54907, 54914, 54924, 54934, 54941, - 54948, 54955, 54962, 54969, 54976, 54983, 54988, 54993, 54999, 55007, - 55017, 55025, 55033, 55041, 55049, 55057, 55065, 55073, 55081, 55089, - 55097, 55106, 55115, 55123, 55131, 55140, 55149, 55158, 55167, 55177, - 55187, 55196, 55205, 55215, 55225, 55239, 55255, 55269, 55285, 55299, - 55313, 55327, 55341, 55351, 55362, 55372, 55383, 55399, 55415, 55423, - 55429, 55436, 55443, 55450, 55458, 55463, 55469, 55474, 55479, 55485, - 55490, 55495, 55500, 55505, 55510, 55517, 55523, 55531, 55537, 55543, - 55547, 55551, 55560, 55569, 55578, 55587, 55594, 55601, 55614, 55627, - 55640, 55653, 55661, 55669, 55676, 55683, 55691, 55699, 55707, 55715, - 55719, 55724, 55732, 55740, 55748, 55755, 55759, 55767, 55775, 55778, - 55782, 55787, 55794, 55802, 55810, 55829, 55849, 55868, 55888, 55908, - 55928, 55948, 55968, 55974, 55981, 55990, 55998, 56006, 56012, 56015, - 56018, 56023, 56026, 56046, 56053, 56059, 56065, 56069, 56072, 56075, - 56078, 56088, 56100, 56107, 56114, 56117, 56121, 56124, 56129, 56134, - 56139, 56145, 56154, 56161, 56168, 56176, 56183, 56190, 56193, 56199, - 56205, 56208, 56211, 56216, 56221, 56227, 56233, 56237, 56242, 56249, - 56253, 56259, 56263, 56267, 56275, 56287, 56295, 56299, 56301, 56310, - 56319, 56325, 56328, 56334, 56340, 56345, 56350, 56355, 56360, 56365, - 56370, 56372, 56378, 56383, 56391, 56395, 56401, 56404, 56408, 56416, - 56424, 56426, 56428, 56434, 56440, 56446, 56455, 56464, 56471, 56478, - 56484, 56491, 56496, 56501, 56506, 56512, 56518, 56523, 56530, 56534, - 56538, 56551, 56564, 56576, 56585, 56591, 56598, 56603, 56608, 56613, - 56618, 56623, 56625, 56632, 56640, 56648, 56656, 56663, 56671, 56677, - 56682, 56688, 56694, 56700, 56707, 56713, 56721, 56729, 56737, 56745, - 56753, 56759, 56765, 56774, 56778, 56787, 56796, 56805, 56813, 56817, - 56823, 56830, 56837, 56841, 56847, 56855, 56861, 56866, 56872, 56877, - 56882, 56889, 56896, 56901, 56906, 56914, 56922, 56932, 56942, 56949, - 56956, 56960, 56964, 56976, 56982, 56989, 56994, 56999, 57006, 57013, - 57019, 57025, 57035, 57042, 57050, 57058, 57067, 57074, 57080, 57087, - 57093, 57101, 57109, 57117, 57125, 57131, 57136, 57146, 57157, 57164, - 57173, 57179, 57184, 57189, 57199, 57208, 57214, 57220, 57228, 57233, - 57240, 57247, 57258, 57265, 57272, 57279, 57286, 57293, 57302, 57311, - 57324, 57337, 57349, 57361, 57374, 57388, 57394, 57400, 57410, 57420, - 57427, 57434, 57444, 57454, 57463, 57472, 57480, 57488, 57498, 57508, - 57523, 57538, 57547, 57556, 57569, 57582, 57591, 57600, 57611, 57622, - 57628, 57634, 57643, 57652, 57657, 57662, 57670, 57676, 57682, 57690, - 57698, 57711, 57724, 57728, 57732, 57741, 57750, 57757, 57765, 57773, - 57783, 57793, 57799, 57805, 57813, 57821, 57829, 57837, 57847, 57857, - 57860, 57863, 57868, 57873, 57879, 57885, 57892, 57899, 57910, 57921, - 57928, 57935, 57943, 57951, 57960, 57969, 57978, 57987, 57994, 58001, - 58005, 58009, 58018, 58027, 58032, 58037, 58042, 58047, 58053, 58067, - 58074, 58081, 58085, 58087, 58089, 58094, 58099, 58104, 58109, 58117, - 58124, 58131, 58139, 58151, 58159, 58167, 58178, 58182, 58186, 58192, - 58200, 58213, 58220, 58227, 58234, 58240, 58247, 58256, 58265, 58271, - 58277, 58283, 58294, 58305, 58313, 58322, 58327, 58330, 58335, 58340, - 58345, 58351, 58357, 58361, 58364, 58368, 58372, 58377, 58382, 58388, - 58394, 58398, 58402, 58409, 58416, 58423, 58430, 58437, 58444, 58453, - 58462, 58469, 58476, 58484, 58492, 58496, 58501, 58506, 58512, 58518, - 58521, 58524, 58527, 58530, 58535, 58540, 58545, 58550, 58555, 58560, - 58564, 58568, 58572, 58577, 58582, 58586, 58590, 58596, 58600, 58606, - 58611, 58618, 58626, 58633, 58641, 58648, 58656, 58665, 58672, 58682, - 58693, 58699, 58708, 58714, 58723, 58733, 58739, 58745, 58749, 58753, - 58762, 58772, 58779, 58787, 58796, 58805, 58812, 58818, 58825, 58830, - 58834, 58838, 58843, 58848, 58853, 58861, 58869, 58872, 58876, 58885, - 58895, 58904, 58914, 58926, 58940, 58944, 58949, 58953, 58958, 58963, - 58968, 58974, 58980, 58987, 58994, 59000, 59007, 59013, 59020, 59029, - 59038, 59044, 59051, 59057, 0, 0, 59064, 59072, 59080, 59089, 59098, - 59107, 59117, 59126, 59136, 59142, 59147, 59156, 59168, 59177, 59189, - 59196, 59204, 59211, 59219, 59224, 59230, 59235, 59241, 59249, 59258, - 59266, 59275, 59279, 59282, 59286, 59289, 59299, 0, 59302, 59309, 59318, - 59328, 59337, 59347, 59353, 59360, 59366, 59373, 59384, 59395, 59406, - 59417, 59427, 59437, 59447, 59457, 59465, 59473, 59481, 59489, 59497, - 59505, 59513, 59521, 59527, 59532, 59538, 59543, 59549, 59555, 59561, - 59567, 59579, 59589, 59594, 59601, 59606, 59613, 59616, 59620, 59624, - 59629, 59633, 59638, 59641, 59650, 59659, 59668, 59677, 59682, 59688, - 59694, 59702, 59712, 59719, 59728, 59733, 59736, 59739, 59744, 59749, - 59754, 59759, 59761, 59763, 59765, 59767, 59769, 59771, 59776, 59783, - 59790, 59792, 59794, 59796, 59798, 59800, 59802, 59804, 59806, 59811, - 59816, 59823, 59830, 59839, 59849, 59858, 59868, 59873, 59878, 59880, - 59887, 59894, 59901, 59908, 59915, 59922, 59929, 59932, 59935, 59938, - 59941, 59946, 59951, 59956, 59961, 59966, 59971, 59976, 59981, 59986, - 59991, 59996, 60001, 60007, 60011, 60016, 60021, 60026, 60031, 60036, - 60041, 60046, 60051, 60056, 60061, 60066, 60071, 60076, 60081, 60086, - 60091, 60096, 60101, 60106, 60111, 60116, 60121, 60127, 60132, 60138, - 60147, 60152, 60160, 60167, 60176, 60181, 60186, 60191, 60197, 60204, - 60211, 60216, 60221, 60226, 60231, 60236, 60241, 60246, 60251, 60256, - 60261, 60267, 60271, 60276, 60281, 60286, 60291, 60296, 60301, 60306, - 60311, 60316, 60321, 60326, 60331, 60336, 60341, 60346, 60351, 60356, - 60361, 60366, 60371, 60376, 60381, 60387, 60392, 60398, 60407, 60412, - 60420, 60427, 60436, 60441, 60446, 60451, 60457, 60464, 60471, 60479, - 60487, 60496, 60503, 60511, 60517, 60526, 60534, 60542, 60550, 60558, - 60566, 60574, 60579, 60586, 60591, 60597, 60605, 60612, 60619, 60627, - 60633, 60639, 60646, 60654, 60663, 60673, 60679, 60686, 60691, 60701, - 60711, 60716, 60721, 60726, 60731, 60736, 60741, 60746, 60751, 60756, - 60761, 60766, 60771, 60776, 60781, 60786, 60791, 60796, 60801, 60806, - 60811, 60816, 60821, 60826, 60831, 60836, 60841, 60846, 60851, 60856, - 60861, 60865, 60869, 60874, 60879, 60884, 60889, 60894, 60899, 60904, - 60909, 60914, 60919, 60924, 60929, 60934, 60939, 60944, 60949, 60954, - 60959, 60966, 60973, 60980, 60987, 60994, 61001, 61008, 61015, 61022, - 61029, 61036, 61043, 61050, 61057, 61062, 61067, 61074, 61081, 61088, - 61095, 61102, 61109, 61116, 61123, 61130, 61137, 61144, 61151, 61157, - 61163, 61169, 61175, 61182, 61189, 61196, 61203, 61210, 61217, 61224, - 61231, 61238, 61245, 61253, 61261, 61269, 61277, 61285, 61293, 61301, - 61309, 61313, 61319, 61325, 61329, 61335, 61341, 61347, 61354, 61361, - 61368, 61375, 61380, 61386, 61392, 61399, 0, 0, 0, 0, 0, 61406, 61414, - 61423, 61432, 61440, 61446, 61451, 61456, 61461, 61466, 61471, 61476, - 61481, 61486, 61491, 61496, 61501, 61506, 61511, 61516, 61521, 61526, - 61531, 61536, 61541, 61546, 61551, 61556, 61561, 61566, 61571, 61576, - 61581, 61586, 61591, 61596, 61601, 61606, 61611, 61616, 61621, 61626, - 61631, 61636, 61641, 0, 61646, 0, 0, 0, 0, 0, 61651, 0, 0, 61656, 61660, - 61665, 61670, 61675, 61680, 61689, 61694, 61699, 61704, 61709, 61714, - 61719, 61724, 61729, 61736, 61741, 61746, 61755, 61762, 61767, 61772, - 61777, 61784, 61789, 61796, 61801, 61806, 61813, 61820, 61825, 61830, - 61835, 61842, 61849, 61854, 61859, 61864, 61869, 61874, 61881, 61888, - 61893, 61898, 61903, 61908, 61913, 61918, 61923, 61928, 61933, 61938, - 61943, 61950, 61955, 61960, 0, 0, 0, 0, 0, 0, 0, 61965, 61972, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61977, 61982, 61986, 61990, 61994, - 61998, 62002, 62006, 62010, 62014, 62018, 62022, 62028, 62032, 62036, - 62040, 62044, 62048, 62052, 62056, 62060, 62064, 62068, 62072, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 62076, 62080, 62084, 62088, 62092, 62096, 62100, 0, - 62104, 62108, 62112, 62116, 62120, 62124, 62128, 0, 62132, 62136, 62140, - 62144, 62148, 62152, 62156, 0, 62160, 62164, 62168, 62172, 62176, 62180, - 62184, 0, 62188, 62192, 62196, 62200, 62204, 62208, 62212, 0, 62216, - 62220, 62224, 62228, 62232, 62236, 62240, 0, 62244, 62248, 62252, 62256, - 62260, 62264, 62268, 0, 62272, 62276, 62280, 62284, 62288, 62292, 62296, - 0, 62300, 62305, 62310, 62315, 62320, 62325, 62330, 62334, 62339, 62344, - 62349, 62353, 62358, 62363, 62368, 62373, 62377, 62382, 62387, 62392, - 62397, 62402, 62407, 62411, 62416, 62421, 62428, 62433, 62438, 62444, - 62451, 62458, 62467, 62474, 62483, 62488, 62493, 62500, 62507, 62513, - 62521, 62527, 62532, 62537, 62541, 62548, 62555, 62559, 62561, 62565, - 62571, 62573, 62577, 62581, 62585, 62591, 62596, 62600, 62604, 62609, - 62615, 62621, 62627, 62632, 62637, 62644, 62651, 62657, 62663, 62669, - 62675, 62681, 62687, 62691, 62695, 62702, 62709, 62715, 62719, 62724, - 62727, 62731, 62738, 62741, 62745, 62749, 62752, 62758, 62764, 62767, - 62773, 62777, 62781, 62787, 62792, 62797, 62799, 62802, 62806, 62812, - 62818, 62822, 62827, 62836, 62839, 62845, 62850, 62854, 62858, 62862, - 62865, 62870, 62876, 62884, 62892, 62898, 62903, 62908, 62914, 62920, - 62927, 62934, 62940, 62946, 62952, 62958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 62962, 62966, 62970, 62975, 62980, 62985, 62989, 62993, 62997, 63002, - 63007, 63011, 63015, 63019, 63023, 63028, 63033, 63038, 63043, 63047, - 63051, 63056, 63061, 63066, 63071, 63075, 0, 63079, 63083, 63087, 63091, - 63095, 63099, 63103, 63108, 63113, 63117, 63122, 63127, 63136, 63140, - 63144, 63148, 63155, 63159, 63164, 63169, 63173, 63177, 63183, 63188, - 63193, 63198, 63203, 63207, 63211, 63215, 63219, 63223, 63228, 63233, - 63237, 63241, 63246, 63251, 63256, 63260, 63264, 63269, 63274, 63280, - 63286, 63290, 63296, 63302, 63306, 63312, 63318, 63323, 63328, 63332, - 63338, 63342, 63346, 63352, 63358, 63363, 63368, 63372, 63376, 63384, - 63390, 63396, 63402, 63407, 63412, 63417, 63423, 63427, 63433, 63437, - 63441, 63447, 63453, 63459, 63465, 63471, 63477, 63483, 63489, 63495, - 63501, 63507, 63513, 63517, 63523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 63529, 63532, 63536, 63540, 63544, 63548, 63551, 63554, 63558, 63562, - 63566, 63570, 63573, 63578, 63582, 63586, 63590, 63596, 63600, 63604, - 63608, 63612, 63619, 63625, 63629, 63633, 63637, 63641, 63645, 63649, - 63653, 63657, 63661, 63665, 63669, 63675, 63679, 63683, 63687, 63691, - 63695, 63699, 63703, 63707, 63711, 63715, 63719, 63723, 63727, 63731, - 63735, 63739, 63745, 63751, 63756, 63761, 63765, 63769, 63773, 63777, - 63781, 63785, 63789, 63793, 63797, 63801, 63805, 63809, 63813, 63817, - 63821, 63825, 63829, 63833, 63837, 63841, 63845, 63849, 63853, 63857, - 63863, 63867, 63871, 63875, 63879, 63883, 63887, 63891, 63895, 63900, - 63907, 63911, 63915, 63919, 63923, 63927, 63931, 63935, 63939, 63943, - 63947, 63951, 63955, 63962, 63966, 63972, 63976, 63980, 63984, 63988, - 63992, 63995, 63999, 64003, 64007, 64011, 64015, 64019, 64023, 64027, - 64031, 64035, 64039, 64043, 64047, 64051, 64055, 64059, 64063, 64067, - 64071, 64075, 64079, 64083, 64087, 64091, 64095, 64099, 64103, 64107, - 64111, 64115, 64119, 64123, 64129, 64133, 64137, 64141, 64145, 64149, - 64153, 64157, 64161, 64165, 64169, 64173, 64177, 64181, 64185, 64189, - 64193, 64197, 64201, 64205, 64209, 64213, 64217, 64221, 64225, 64229, - 64233, 64237, 64245, 64249, 64253, 64257, 64261, 64265, 64271, 64275, - 64279, 64283, 64287, 64291, 64295, 64299, 64303, 64307, 64311, 64315, - 64319, 64323, 64329, 64333, 64337, 64341, 64345, 64349, 64353, 64357, - 64361, 64365, 64369, 64373, 64377, 64381, 64385, 64389, 64393, 64397, - 64401, 64405, 64409, 64413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64417, 64425, 64433, 64443, 64453, - 64462, 64472, 64482, 64493, 64505, 64516, 64528, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 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, 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, 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, - 84225, 84229, 84233, 84237, 84241, 84245, 84249, 84253, 84257, 84261, - 84265, 84269, 84273, 84277, 84281, 84285, 84289, 84293, 84297, 84301, - 84305, 84309, 84313, 84317, 84321, 84325, 84329, 84333, 84337, 84341, - 84345, 84349, 84353, 84357, 84361, 84365, 84369, 84373, 84377, 84381, - 84385, 84389, 84393, 84397, 84401, 84405, 84409, 84413, 84417, 84421, - 84425, 84429, 84433, 84437, 84441, 84445, 84449, 84453, 84457, 84461, - 84465, 84469, 84473, 84477, 84481, 84485, 84489, 84493, 84497, 84501, - 84505, 84509, 84513, 84517, 84521, 84525, 84529, 84533, 84537, 84541, - 84545, 84549, 84553, 84557, 84561, 84565, 84569, 84573, 84577, 84581, - 84585, 84589, 84593, 84597, 84601, 84605, 84609, 84613, 84617, 84621, - 84625, 84629, 84633, 84637, 84641, 84645, 84649, 84653, 84657, 84661, - 84665, 84669, 84673, 84677, 84681, 84685, 84689, 84693, 84697, 84701, - 84705, 84709, 84713, 84717, 84721, 84725, 84729, 84733, 84737, 84741, - 84745, 84749, 84753, 84757, 84761, 84765, 84769, 84773, 84777, 84781, - 84785, 84789, 84793, 84797, 84801, 84805, 84809, 84813, 84817, 84821, - 84825, 84829, 84833, 84837, 84841, 84845, 84849, 84853, 84857, 84861, - 84865, 84869, 84873, 84877, 84881, 84885, 84889, 84893, 84897, 84901, - 84905, 84909, 84913, 84917, 84921, 84925, 84929, 84933, 84937, 84941, - 84945, 84949, 84953, 84957, 84961, 84965, 84969, 84973, 84977, 84981, - 84985, 84989, 84993, 84997, 85001, 85005, 85009, 85013, 85017, 85021, - 85025, 85029, 85033, 85037, 85041, 85045, 85049, 85053, 85057, 85061, - 85065, 85069, 85073, 85077, 85081, 85085, 85089, 85093, 85097, 85101, - 85105, 85109, 85113, 85117, 85121, 85125, 85129, 85133, 85137, 85141, - 85145, 85149, 85153, 85157, 85161, 85165, 85169, 85173, 85177, 85181, - 85185, 85189, 85193, 85197, 85201, 85205, 85209, 85213, 85217, 85221, - 85225, 85229, 85233, 85237, 85241, 85245, 85249, 85253, 85257, 85261, - 85265, 85269, 85273, 85277, 85281, 85285, 85289, 85293, 85297, 85301, - 85305, 85309, 85313, 85317, 85321, 85325, 85329, 85333, 85337, 85341, - 85345, 85349, 85353, 85357, 85361, 85365, 85369, 85373, 85377, 85381, - 85385, 85389, 85393, 85397, 85401, 85405, 85409, 85413, 85417, 85421, - 85425, 85429, 85433, 85437, 85441, 85445, 85449, 85453, 85457, 85461, - 85465, 85469, 85473, 85477, 85481, 85485, 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, - 85661, 85665, 85669, 85673, 85677, 85681, 85685, 85689, 85693, 85697, - 85701, 85705, 85709, 85713, 85717, 85721, 85725, 85729, 85733, 85737, - 85741, 85745, 85749, 85753, 85757, 85761, 85765, 85769, 85773, 85777, - 85781, 85785, 85789, 85793, 85797, 85801, 85805, 85809, 85813, 85817, - 85821, 85825, 85829, 85833, 85837, 85841, 85845, 85849, 85853, 85857, - 85861, 85865, 85869, 85873, 85877, 85881, 85885, 85889, 85893, 85897, - 85901, 85905, 85909, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, - 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, 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, - 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, 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, -}; - -/* name->code dictionary */ -static const unsigned int code_hash[] = { - 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, - 12064, 110752, 129548, 194597, 69850, 65842, 0, 0, 0, 78159, 68476, - 72392, 1373, 0, 0, 5816, 0, 0, 4231, 0, 0, 4233, 4234, 4232, 68885, - 70351, 0, 7404, 72393, 0, 0, 0, 0, 0, 41601, 8874, 0, 0, 0, 128498, 0, 0, - 41603, 9784, 0, 9188, 41600, 0, 0, 0, 0, 3535, 0, 0, 0, 66797, 0, 74491, - 0, 3404, 100419, 0, 72411, 1759, 100417, 0, 100418, 69972, 11240, 121038, - 100416, 127764, 0, 0, 0, 0, 0, 69970, 0, 0, 9834, 43249, 2234, 983891, 0, - 0, 0, 0, 92417, 0, 74398, 12035, 0, 983074, 43548, 0, 0, 0, 0, 0, 64318, - 917549, 0, 3390, 74483, 43265, 0, 983884, 0, 0, 0, 3400, 0, 0, 11647, 0, - 0, 0, 0, 2121, 128741, 4043, 8712, 0, 983814, 0, 121172, 0, 129456, 0, 0, - 93042, 0, 0, 983875, 0, 0, 0, 11851, 0, 3181, 66002, 0, 69601, 0, 66021, - 0, 194588, 5457, 5440, 0, 93981, 65282, 2843, 5355, 0, 129333, 69971, - 5194, 11657, 128353, 0, 0, 0, 0, 0, 120766, 100525, 0, 0, 74350, 0, - 10682, 110820, 10602, 800, 70044, 118883, 0, 0, 64930, 118940, 67853, - 72001, 0, 762, 120485, 0, 0, 0, 10906, 1353, 6960, 0, 0, 5828, 8724, 0, - 0, 118548, 0, 0, 7080, 0, 128806, 122979, 0, 72388, 0, 11859, 0, 0, - 68878, 0, 0, 0, 7240, 0, 556, 0, 118544, 0, 0, 0, 72397, 0, 0, 0, 0, 0, - 0, 0, 0, 72986, 0, 0, 43931, 0, 11093, 0, 0, 122960, 7341, 66801, 68527, - 0, 1874, 0, 0, 129314, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 9036, 0, 0, 66389, - 0, 121347, 0, 0, 10100, 0, 2725, 0, 0, 43981, 42128, 0, 0, 68146, 0, 0, - 0, 0, 71349, 7859, 1945, 0, 0, 0, 65918, 7188, 9992, 0, 7389, 127008, - 71341, 0, 0, 0, 528, 129681, 44017, 11429, 71347, 0, 0, 120864, 0, 0, 0, - 11530, 73102, 6188, 0, 0, 68208, 1823, 0, 0, 92928, 0, 64843, 7233, - 92929, 0, 0, 6639, 0, 0, 123149, 0, 1176, 0, 0, 8276, 128667, 0, 0, - 68892, 42931, 0, 0, 0, 0, 0, 0, 0, 5388, 0, 0, 0, 11310, 0, 123607, 0, - 68888, 4199, 119264, 0, 119020, 0, 0, 9560, 0, 0, 43869, 0, 0, 0, 83172, - 0, 0, 0, 83173, 101559, 128875, 0, 0, 74327, 0, 0, 0, 0, 0, 123623, - 68886, 0, 0, 0, 8408, 64704, 0, 0, 0, 0, 118711, 67999, 0, 0, 0, 0, - 43049, 0, 43050, 73028, 0, 0, 0, 0, 0, 127396, 0, 69847, 9322, 0, 0, - 129321, 68192, 120507, 983634, 0, 0, 0, 6199, 67249, 0, 0, 0, 0, 11329, - 66285, 0, 983086, 0, 0, 0, 0, 41335, 118866, 43401, 0, 41334, 0, 0, 0, - 983484, 71997, 983483, 128114, 0, 42627, 0, 32, 6187, 0, 123619, 983480, - 3665, 121083, 42871, 983119, 41336, 0, 0, 983476, 0, 0, 0, 4412, 0, 0, 0, - 0, 119533, 0, 4181, 0, 0, 127589, 0, 0, 71453, 6181, 74755, 917895, 0, 0, - 0, 73557, 121107, 0, 0, 10073, 0, 100738, 127186, 0, 42844, 7498, 1098, - 92565, 119530, 0, 0, 10207, 0, 983233, 0, 983555, 0, 9234, 0, 6182, 0, - 92552, 0, 0, 0, 0, 5471, 9461, 6697, 0, 5473, 0, 0, 0, 0, 0, 0, 70073, 0, - 0, 7767, 8304, 41339, 0, 983494, 69450, 0, 0, 983492, 43855, 41337, 0, 0, - 0, 129706, 0, 0, 0, 72396, 0, 0, 0, 42633, 0, 0, 0, 0, 0, 0, 0, 70005, - 129506, 0, 0, 0, 129580, 69817, 128299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1437, - 41617, 0, 0, 0, 128853, 0, 0, 0, 0, 0, 128529, 12113, 0, 42772, 0, 0, - 7693, 10749, 67485, 65210, 5773, 978, 128134, 0, 41619, 10239, 0, 0, 0, - 74328, 0, 9748, 0, 0, 0, 0, 0, 0, 0, 70681, 0, 72811, 0, 67464, 0, 92776, - 0, 0, 2379, 11325, 0, 0, 67854, 0, 78547, 42209, 0, 120392, 2369, 0, - 984003, 984004, 0, 0, 73936, 7008, 69415, 122919, 0, 43841, 2367, 127827, - 983888, 0, 2375, 8060, 6194, 0, 0, 119084, 0, 0, 0, 0, 6961, 0, 0, 0, - 68426, 0, 42862, 0, 0, 6192, 127900, 42771, 0, 0, 11435, 128445, 118797, - 120800, 0, 12892, 0, 128621, 67149, 0, 0, 0, 0, 120707, 0, 0, 19954, 0, - 121164, 8983, 0, 0, 0, 0, 0, 6198, 121344, 0, 196, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 983512, 41323, 0, 0, 92289, 0, 0, 0, 983508, 41321, - 12907, 3048, 7752, 41320, 0, 0, 12819, 111247, 72127, 0, 0, 0, 0, 0, - 72971, 0, 0, 0, 0, 78650, 78649, 0, 41326, 0, 11806, 43167, 0, 1245, 0, - 66463, 0, 0, 0, 0, 0, 194619, 0, 194618, 0, 0, 194620, 0, 70403, 325, - 12874, 128454, 74178, 0, 0, 119110, 0, 0, 0, 0, 0, 0, 983563, 92175, 0, - 125016, 0, 121049, 0, 0, 0, 0, 0, 0, 110844, 11776, 0, 19908, 0, 0, 0, - 8753, 69278, 0, 0, 9511, 43493, 0, 93032, 6205, 0, 0, 0, 0, 0, 78928, 0, - 0, 120269, 0, 41607, 0, 0, 120617, 0, 0, 0, 7005, 41609, 9580, 0, 401, 0, - 43779, 0, 127962, 0, 65486, 0, 12857, 0, 11983, 0, 0, 0, 121371, 0, - 194971, 74258, 983647, 0, 0, 0, 0, 0, 8295, 6200, 0, 127864, 0, 0, 71435, - 0, 92523, 0, 128631, 0, 0, 125197, 0, 100426, 0, 127556, 0, 0, 0, 64775, - 0, 68862, 120590, 0, 0, 129959, 8074, 8199, 126641, 1907, 127269, 4432, - 127271, 10808, 120668, 127272, 127259, 3888, 127261, 72724, 127263, - 127262, 127265, 123169, 121195, 127250, 66879, 127252, 100422, 66023, - 67363, 7663, 0, 0, 0, 0, 66321, 0, 12814, 127248, 127169, 0, 0, 194603, - 7641, 92694, 0, 0, 0, 0, 74320, 120818, 120268, 0, 128475, 0, 110627, 0, - 9622, 128972, 120264, 0, 0, 0, 0, 68319, 0, 0, 71484, 118613, 0, 0, - 69906, 0, 0, 947, 0, 194586, 129059, 10969, 119935, 7613, 119937, 119936, - 4795, 119930, 119933, 7376, 0, 0, 0, 72343, 69373, 0, 0, 0, 119919, 7216, - 119921, 7217, 119915, 7218, 119917, 7219, 119927, 119926, 119929, 119928, - 7213, 119922, 7214, 7215, 128622, 0, 8880, 7685, 128849, 0, 0, 119618, - 119853, 8187, 119913, 12815, 7236, 7915, 71906, 0, 121284, 0, 0, 0, 0, 0, - 0, 0, 122969, 0, 0, 0, 0, 0, 10468, 0, 0, 0, 0, 0, 0, 0, 0, 917909, 0, - 110633, 1616, 3795, 67732, 11529, 0, 126225, 0, 0, 1138, 194577, 12677, - 0, 0, 3239, 0, 0, 194809, 194583, 0, 42164, 0, 11778, 67473, 43259, - 118543, 119073, 122975, 0, 0, 67094, 129638, 0, 78421, 128123, 78418, 0, - 0, 0, 0, 43959, 43960, 0, 72257, 0, 9359, 78416, 0, 0, 0, 6662, 0, 0, - 3863, 0, 41329, 55266, 0, 127822, 41328, 75026, 194569, 129516, 0, 0, - 2178, 119595, 569, 0, 0, 0, 119085, 110669, 0, 0, 11610, 11368, 0, - 194570, 41331, 1006, 127747, 120883, 1550, 8201, 0, 194811, 5499, 43956, - 77908, 77910, 77906, 43957, 77904, 77905, 128410, 0, 0, 129581, 100447, - 43955, 77913, 122989, 0, 5511, 0, 983721, 0, 69241, 8255, 5512, 128560, - 119560, 127858, 64313, 127928, 5906, 1119, 128180, 67088, 983367, 0, - 113798, 0, 66423, 0, 0, 0, 67089, 0, 0, 0, 0, 128177, 983728, 0, 0, 0, - 5821, 6186, 129960, 128034, 19961, 0, 983719, 0, 65138, 302, 41113, - 41115, 0, 6637, 5907, 128789, 0, 43642, 0, 128625, 0, 70345, 5513, 6666, - 100567, 78442, 5510, 0, 0, 0, 983725, 78437, 0, 0, 0, 110838, 0, 0, 0, - 92710, 0, 0, 0, 0, 0, 74497, 92395, 120511, 6929, 69412, 0, 110835, - 64442, 0, 0, 74496, 0, 6674, 43397, 0, 1476, 0, 0, 72276, 3233, 0, 0, - 10164, 118555, 0, 3530, 67243, 0, 111219, 6656, 0, 0, 74647, 8512, 72275, - 74261, 8967, 0, 0, 0, 72277, 7986, 73782, 120556, 9006, 983562, 72273, 0, - 7853, 0, 983360, 0, 0, 0, 0, 983971, 0, 0, 0, 0, 0, 0, 0, 0, 127971, - 67983, 13296, 517, 0, 0, 0, 41528, 19923, 65454, 73518, 0, 0, 10531, - 7784, 41526, 71727, 0, 8057, 1126, 73895, 0, 0, 130040, 119186, 4251, - 8235, 43142, 0, 489, 71733, 4250, 71731, 110721, 43151, 94177, 71725, 0, - 121238, 0, 0, 0, 110726, 0, 8711, 6183, 110722, 110723, 0, 0, 7623, 0, 0, - 9235, 12760, 74176, 0, 0, 0, 0, 3743, 11514, 11078, 74582, 0, 0, 126597, - 0, 0, 0, 0, 983907, 267, 3393, 127504, 2364, 0, 69233, 6958, 0, 6201, 0, - 42360, 0, 10652, 41612, 917802, 3402, 917801, 3398, 0, 0, 0, 3391, 70683, - 0, 92541, 128017, 126087, 126590, 0, 12767, 0, 983380, 64261, 0, 127537, - 70852, 70347, 0, 6673, 0, 0, 129346, 12438, 0, 0, 0, 71128, 0, 9053, - 43954, 74523, 0, 0, 0, 6195, 0, 6660, 0, 917760, 917793, 0, 12629, 0, 0, - 0, 0, 0, 127940, 0, 0, 0, 65448, 0, 0, 121084, 129688, 43949, 0, 78099, - 0, 983385, 0, 0, 0, 5741, 1131, 0, 0, 74862, 0, 43952, 42533, 119598, - 78107, 0, 0, 43950, 121297, 118990, 7691, 43951, 578, 0, 0, 0, 42514, - 74547, 74196, 120608, 74561, 0, 983976, 0, 0, 0, 0, 0, 0, 0, 0, 7241, 0, - 93846, 119167, 0, 12811, 78082, 3946, 0, 10998, 66807, 673, 0, 0, 0, 0, - 119301, 0, 68890, 0, 0, 78085, 10267, 0, 74560, 78083, 0, 8729, 0, 0, 0, - 0, 0, 0, 0, 119296, 0, 0, 0, 2181, 983463, 731, 0, 71904, 128316, 0, - 73539, 0, 1175, 0, 68167, 0, 0, 10793, 0, 67644, 7723, 983458, 0, 0, 0, - 0, 5273, 0, 5269, 0, 69607, 2404, 5267, 124967, 124913, 0, 5277, 0, 0, - 6189, 65469, 1314, 0, 0, 118873, 8785, 0, 0, 127527, 68414, 43535, 9204, - 0, 3879, 0, 71696, 6197, 9497, 0, 7567, 64484, 78128, 41390, 41379, - 41882, 67647, 67279, 70085, 0, 121413, 41388, 64446, 41392, 64288, 41387, - 0, 8706, 10675, 0, 700, 0, 5775, 0, 7088, 74756, 7499, 0, 78120, 78111, - 67251, 126557, 0, 0, 128945, 10311, 78115, 6665, 11115, 0, 7618, 10821, - 11455, 0, 64632, 64447, 0, 0, 78093, 78091, 0, 0, 65033, 0, 6668, 0, 0, - 0, 656, 69686, 65037, 0, 0, 127024, 0, 0, 0, 0, 73014, 0, 0, 917774, - 9702, 0, 92273, 66580, 118895, 66683, 43640, 3417, 0, 6832, 0, 917768, 0, - 917767, 118583, 4935, 11906, 0, 0, 67296, 92896, 3651, 0, 67294, 70848, - 0, 67292, 0, 12983, 0, 55272, 0, 0, 1439, 0, 74897, 0, 0, 0, 78373, 0, - 42087, 3063, 0, 0, 7838, 0, 129282, 0, 0, 67968, 0, 128582, 9078, 92446, - 0, 0, 0, 0, 0, 0, 119586, 0, 7750, 128422, 68237, 6190, 0, 0, 0, 72340, - 9857, 7014, 9856, 0, 92620, 120547, 0, 8481, 0, 6202, 0, 10920, 67970, 0, - 0, 983297, 0, 7843, 65818, 66824, 0, 73481, 0, 0, 0, 0, 0, 6657, 207, 0, - 69728, 74819, 0, 0, 0, 0, 0, 0, 0, 0, 41368, 43974, 488, 0, 0, 71339, - 10157, 118700, 43034, 11982, 0, 0, 0, 0, 0, 41372, 6669, 8504, 72103, 0, - 41367, 129328, 119272, 0, 11726, 8261, 129793, 304, 129799, 129795, - 129822, 129807, 113683, 983239, 238, 74522, 0, 0, 19905, 120577, 122968, - 129200, 41044, 67640, 67302, 64814, 9912, 65939, 983470, 0, 0, 0, 917925, - 0, 0, 309, 6622, 0, 10858, 0, 67636, 0, 72749, 0, 0, 0, 67637, 123138, - 9712, 68680, 43970, 0, 65165, 93047, 983831, 0, 0, 0, 0, 0, 6191, 12944, - 0, 0, 67634, 43763, 0, 0, 67635, 9370, 41381, 0, 0, 123148, 118817, 0, - 3222, 121439, 0, 0, 66663, 0, 0, 0, 0, 0, 65732, 121144, 0, 983219, 0, 0, - 67309, 72192, 41383, 64568, 0, 0, 0, 0, 984009, 66725, 0, 0, 0, 0, 73766, - 67306, 3632, 128246, 0, 8376, 3648, 0, 74844, 67639, 3636, 0, 3650, 8837, - 0, 0, 0, 43250, 41562, 0, 0, 68839, 3640, 127190, 0, 11781, 0, 0, 0, 0, - 129659, 0, 126649, 0, 42080, 2529, 0, 78004, 0, 42083, 0, 0, 120531, - 67619, 0, 0, 9634, 0, 0, 0, 0, 0, 0, 0, 68841, 0, 92545, 68874, 127399, - 0, 0, 41987, 119667, 67623, 983779, 0, 925, 127156, 0, 41985, 64441, - 9586, 120988, 41984, 9217, 128372, 0, 0, 9186, 67620, 4016, 983834, 0, - 381, 983700, 0, 42077, 0, 128777, 67622, 42078, 0, 10810, 0, 4585, 19943, - 5860, 67633, 0, 0, 812, 0, 0, 0, 92518, 0, 0, 0, 0, 67629, 0, 10692, 0, - 67630, 0, 924, 0, 67631, 42616, 0, 0, 0, 67317, 67632, 0, 12771, 12736, - 12753, 0, 983753, 67626, 67722, 0, 0, 0, 0, 12751, 74906, 8542, 0, 0, - 3626, 66706, 0, 0, 3883, 64388, 0, 0, 0, 0, 0, 0, 126268, 67624, 0, - 10932, 0, 65585, 64338, 806, 0, 41884, 110845, 1318, 128828, 0, 0, 0, - 983808, 3465, 2405, 983395, 0, 12756, 65259, 69381, 983812, 12752, 5833, - 1432, 110843, 41883, 110841, 9799, 0, 41886, 0, 0, 2062, 0, 0, 0, 0, - 129376, 0, 124969, 983392, 0, 120971, 0, 118832, 0, 983286, 0, 68005, - 10622, 0, 0, 0, 6566, 71195, 0, 73780, 0, 68865, 0, 0, 0, 8284, 0, 0, 0, - 0, 0, 43023, 0, 983290, 6642, 3977, 72743, 64729, 836, 983386, 92947, 0, - 0, 0, 0, 0, 0, 125239, 917923, 0, 0, 0, 0, 0, 0, 1374, 65149, 119014, - 67720, 0, 2273, 0, 0, 0, 11234, 0, 0, 9630, 12597, 0, 0, 0, 6661, 0, - 113751, 120551, 125015, 0, 0, 72151, 0, 73674, 7718, 113755, 0, 69570, 0, - 0, 983777, 0, 0, 0, 127841, 6365, 1887, 983414, 0, 8080, 113681, 0, 0, 0, - 129855, 1544, 0, 0, 64677, 0, 0, 0, 0, 73561, 0, 0, 12812, 7342, 0, - 73784, 66947, 7904, 0, 0, 120910, 0, 0, 0, 0, 9724, 0, 983804, 9524, 0, - 0, 0, 0, 0, 129344, 0, 471, 0, 0, 128302, 72450, 0, 0, 983769, 0, 0, - 6918, 118685, 0, 5156, 0, 128683, 10232, 10615, 10213, 0, 0, 42528, 0, 0, - 0, 0, 65311, 74935, 0, 13306, 10533, 7870, 0, 7625, 0, 120544, 0, 0, - 128816, 126098, 118870, 0, 92819, 0, 0, 92341, 0, 12978, 128533, 0, 0, - 43836, 42675, 0, 12845, 0, 19942, 0, 0, 0, 0, 0, 120000, 120008, 120001, - 0, 194894, 983746, 0, 0, 0, 7186, 73107, 0, 70093, 445, 119028, 0, 0, 0, - 73047, 0, 0, 128442, 0, 0, 0, 3902, 68913, 129916, 0, 0, 1560, 43958, 0, - 4584, 0, 67862, 0, 10866, 92905, 1118, 92209, 74888, 0, 1081, 7436, - 11147, 7252, 0, 121188, 0, 0, 0, 41386, 5162, 129823, 1330, 0, 121270, 0, - 12047, 7675, 0, 0, 1848, 74528, 983148, 64708, 0, 0, 194880, 0, 0, 0, - 983772, 12715, 128349, 0, 101402, 0, 66672, 73710, 66685, 0, 0, 92464, 0, - 68884, 0, 72835, 123546, 70800, 70101, 120725, 0, 194893, 9214, 43494, 0, - 0, 120841, 0, 0, 6313, 65513, 119355, 0, 0, 0, 2345, 72975, 0, 0, 129937, - 0, 3117, 0, 71882, 0, 73100, 0, 0, 0, 0, 78415, 983236, 100907, 0, 13248, - 0, 120241, 129416, 128415, 0, 94193, 12382, 71120, 0, 0, 0, 0, 1471, 0, - 113747, 0, 12378, 0, 69664, 0, 12374, 121357, 0, 0, 0, 0, 0, 0, 12376, 0, - 0, 0, 12380, 10557, 0, 12520, 11122, 2024, 127180, 0, 0, 74588, 0, 0, - 70120, 3853, 0, 0, 0, 983763, 0, 0, 12090, 0, 12474, 92579, 9503, 0, 0, - 73505, 68318, 0, 110834, 0, 0, 0, 12470, 0, 74189, 2742, 12476, 66370, - 10946, 0, 12472, 0, 0, 0, 0, 8213, 43824, 7771, 6161, 983280, 68010, 0, - 0, 0, 68235, 0, 0, 0, 120985, 0, 0, 0, 129814, 73791, 129830, 68871, 0, - 0, 0, 0, 0, 73704, 12015, 128561, 8275, 0, 43459, 120927, 127555, 0, 0, - 0, 68881, 71215, 983642, 118841, 0, 12516, 4444, 0, 119017, 120506, - 10892, 118828, 0, 6473, 0, 0, 71735, 3591, 0, 0, 0, 0, 72345, 0, 0, 0, - 127547, 0, 0, 0, 0, 128253, 0, 0, 0, 0, 94060, 687, 0, 0, 983404, 0, 0, - 43882, 0, 128526, 285, 0, 0, 0, 4459, 0, 0, 74917, 0, 0, 126255, 0, - 119248, 0, 9743, 0, 0, 126535, 0, 0, 73104, 0, 69659, 0, 0, 3081, 74577, - 42921, 0, 0, 0, 0, 0, 0, 0, 9125, 119023, 0, 120820, 0, 65221, 0, 0, - 64852, 0, 0, 0, 0, 66578, 5001, 41879, 0, 0, 5003, 884, 0, 0, 4943, 5150, - 73889, 74182, 0, 41876, 0, 78915, 42448, 42299, 72804, 0, 0, 0, 0, 8491, - 0, 0, 983635, 4530, 42409, 7126, 119526, 66200, 0, 118559, 19929, 0, 0, - 0, 4242, 0, 0, 0, 0, 66034, 65941, 124929, 64522, 10740, 8958, 128257, - 9754, 119102, 983251, 74222, 983249, 983248, 119064, 983246, 983245, 0, - 0, 0, 74518, 66026, 4306, 41468, 68432, 0, 0, 66667, 0, 0, 983499, 42200, - 0, 0, 0, 120236, 6948, 0, 8524, 0, 0, 12385, 0, 74926, 0, 1386, 73996, 0, - 0, 0, 121184, 12392, 0, 8064, 0, 0, 78216, 119004, 2080, 710, 128491, - 12390, 1666, 42091, 0, 12383, 92968, 42092, 68418, 0, 128106, 0, 0, - 42096, 0, 3362, 12377, 127878, 0, 0, 0, 0, 1244, 4401, 73786, 12683, - 10662, 0, 8112, 129837, 119021, 121017, 12379, 73108, 120534, 0, 42208, - 0, 12381, 0, 0, 0, 4327, 0, 0, 128350, 0, 78232, 0, 584, 12933, 0, 12373, - 73105, 13000, 0, 2935, 129113, 12665, 0, 43081, 73098, 120505, 12427, 0, - 983625, 78227, 0, 0, 0, 0, 128760, 74551, 0, 0, 12426, 0, 73497, 0, - 12428, 0, 0, 0, 0, 0, 12429, 6727, 0, 0, 0, 3387, 0, 0, 0, 0, 0, 0, - 73517, 0, 3536, 120589, 9752, 92397, 6162, 0, 0, 10113, 0, 0, 0, 12422, - 0, 439, 3072, 0, 42207, 74549, 120830, 0, 0, 0, 0, 8308, 0, 70807, 0, 0, - 0, 13218, 0, 0, 8082, 12424, 0, 6819, 3539, 93838, 0, 0, 74539, 0, 68181, - 0, 72964, 0, 72969, 12420, 11371, 0, 4600, 0, 127810, 0, 0, 0, 72962, - 128552, 6704, 4591, 72966, 0, 0, 0, 72960, 120623, 561, 12159, 78223, 0, - 78224, 0, 71068, 11932, 7172, 42687, 8368, 0, 0, 93068, 0, 0, 75010, 0, - 0, 0, 0, 42463, 0, 2924, 67183, 0, 129947, 0, 128958, 0, 0, 42330, 73079, - 3969, 0, 129973, 7169, 1992, 9652, 0, 0, 42086, 0, 100865, 0, 0, 0, 0, 0, - 327, 0, 0, 0, 0, 73509, 12433, 0, 0, 118570, 12431, 0, 12434, 983439, 0, - 73544, 0, 7712, 12432, 0, 69377, 129147, 100867, 0, 8212, 0, 128014, 0, - 119066, 7333, 0, 0, 0, 67407, 70006, 128461, 0, 12436, 0, 43160, 0, - 74896, 92757, 71360, 42350, 0, 0, 0, 100566, 0, 11348, 0, 0, 9194, - 983185, 0, 55250, 0, 100569, 0, 0, 0, 0, 0, 64746, 66012, 100565, 3444, - 75029, 64651, 0, 41503, 0, 0, 0, 0, 0, 0, 0, 120876, 0, 0, 129408, 65309, - 12416, 0, 0, 0, 0, 93024, 12418, 74111, 121046, 0, 0, 0, 119361, 0, 4596, - 66339, 12417, 66001, 0, 126491, 12414, 8287, 0, 69499, 0, 1143, 0, 0, - 12415, 0, 0, 983247, 0, 9021, 120783, 0, 11724, 0, 0, 0, 194794, 0, 0, - 8027, 194796, 74257, 127375, 11400, 74197, 194799, 66833, 194798, 0, 0, - 983252, 0, 0, 1324, 0, 0, 0, 194878, 7715, 0, 0, 194777, 194780, 0, 0, 0, - 194787, 0, 0, 0, 0, 0, 66289, 127109, 3889, 129561, 194800, 0, 0, 0, 0, - 121226, 12999, 0, 120902, 0, 0, 0, 0, 0, 64802, 42210, 4597, 983134, 0, - 0, 12371, 67164, 0, 67163, 10805, 0, 0, 0, 0, 118662, 12367, 0, 0, 92557, - 12363, 0, 0, 128611, 983645, 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, - 0, 70095, 0, 0, 0, 42923, 0, 0, 0, 0, 0, 0, 66659, 0, 0, 0, 0, 5268, - 4954, 0, 0, 5266, 126980, 5272, 92294, 0, 42230, 983980, 0, 9128, 0, 0, - 0, 0, 6928, 9803, 42282, 9110, 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8722, 120805, 0, 0, 66695, 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, - 0, 0, 3419, 42229, 0, 0, 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, - 41576, 42215, 122888, 0, 0, 8578, 68178, 7573, 41575, 74789, 92310, 0, - 73863, 0, 2670, 0, 0, 11723, 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, - 67168, 12413, 129746, 67177, 0, 0, 0, 0, 12302, 0, 5250, 12407, 12245, - 4404, 9189, 12401, 42007, 0, 42005, 65806, 43997, 122922, 42002, 12404, - 0, 74928, 4940, 12410, 0, 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11956, 0, 0, 122882, 0, 6631, 128923, 120704, 74583, 42218, 0, 0, 70094, - 0, 0, 0, 71058, 0, 0, 0, 127341, 0, 0, 0, 0, 0, 43370, 0, 5016, 121052, - 0, 0, 9491, 0, 0, 0, 0, 64922, 0, 0, 0, 0, 92198, 0, 118622, 0, 74619, 0, - 0, 70422, 983688, 10565, 0, 12177, 0, 0, 0, 0, 0, 12395, 127874, 12878, - 92630, 12396, 0, 0, 92537, 0, 43113, 0, 0, 0, 9781, 0, 4927, 0, 0, 0, 0, - 12397, 129089, 128910, 0, 12394, 0, 0, 0, 0, 0, 72789, 10781, 1546, 0, - 5010, 0, 10507, 127891, 128291, 0, 0, 0, 0, 7267, 0, 0, 0, 0, 2819, 0, 0, - 71063, 0, 7266, 128553, 7264, 7265, 0, 1363, 0, 119581, 65080, 0, 0, 0, - 0, 43336, 67004, 0, 126263, 73776, 0, 43339, 0, 9836, 0, 0, 0, 43335, - 41276, 0, 73795, 43337, 817, 11211, 2241, 128841, 41274, 11340, 42408, - 42447, 74932, 0, 0, 12386, 0, 0, 0, 12389, 128398, 0, 41996, 41686, 0, - 8269, 1147, 43849, 120896, 1987, 128540, 43195, 42001, 41990, 41999, - 12391, 0, 0, 4939, 12384, 0, 0, 43243, 0, 0, 70746, 0, 0, 0, 0, 0, 8247, - 0, 0, 7545, 0, 43643, 121445, 0, 10036, 0, 119813, 10178, 119816, 0, - 119815, 11762, 119818, 0, 92282, 120597, 0, 0, 119819, 0, 0, 7719, 0, - 2486, 0, 119808, 1507, 0, 129185, 70301, 9687, 119825, 0, 119811, 66196, - 0, 5262, 0, 74642, 12681, 0, 0, 12406, 12219, 0, 127528, 42810, 110991, - 0, 983692, 128144, 121027, 126096, 120753, 12403, 2500, 118672, 0, 12409, - 0, 0, 0, 74113, 2343, 12412, 19946, 74112, 125042, 13112, 0, 120603, - 67866, 110634, 0, 66369, 5861, 110632, 11999, 12400, 0, 0, 12645, 0, - 11320, 68410, 6748, 65040, 0, 64184, 12974, 66927, 67613, 120645, 0, 0, - 0, 0, 0, 1928, 0, 67649, 0, 0, 67609, 11235, 0, 0, 67610, 8241, 0, 0, - 4206, 0, 0, 0, 128298, 110980, 0, 67238, 0, 0, 0, 1422, 8357, 0, 7187, 0, - 120641, 0, 0, 0, 0, 125022, 111064, 92539, 10120, 12405, 0, 72997, 0, - 13278, 0, 6366, 0, 7945, 0, 4402, 0, 12402, 129372, 0, 74754, 12408, 0, - 44007, 0, 0, 0, 12411, 0, 120824, 128306, 121092, 0, 1575, 0, 0, 0, - 73003, 119622, 0, 0, 12399, 0, 6833, 0, 0, 0, 71878, 9692, 0, 0, 100615, - 6750, 66855, 0, 0, 0, 0, 43527, 0, 727, 0, 0, 0, 0, 6726, 127387, 0, - 12370, 44023, 0, 126592, 2280, 0, 12372, 120642, 0, 0, 0, 0, 12366, - 10963, 6066, 1329, 0, 3052, 72987, 0, 66029, 0, 10803, 0, 983648, 0, - 92473, 0, 0, 0, 0, 1499, 0, 0, 42740, 0, 0, 0, 0, 12056, 126484, 0, 3660, - 69404, 42192, 74253, 0, 42223, 67617, 125254, 0, 0, 0, 0, 9941, 0, 0, - 1933, 0, 0, 0, 0, 73866, 0, 0, 2487, 67614, 7361, 1804, 0, 67615, 0, 0, - 12220, 67616, 0, 0, 0, 68200, 6675, 0, 0, 67592, 126582, 0, 64771, 0, - 9132, 0, 111004, 510, 0, 0, 0, 4561, 7711, 92769, 92944, 111007, 0, - 41569, 121282, 0, 8167, 66885, 123197, 0, 0, 69992, 66403, 6967, 0, 0, 0, - 0, 333, 0, 0, 10566, 66409, 0, 121373, 0, 72965, 110999, 66388, 6678, 0, - 0, 12621, 0, 128775, 10227, 4764, 0, 9981, 0, 70278, 11589, 0, 0, 42202, - 12754, 0, 0, 69576, 0, 67594, 2048, 0, 4050, 67595, 0, 0, 43221, 11184, - 72709, 0, 0, 64175, 0, 72746, 0, 0, 129966, 65461, 9798, 0, 71210, 0, - 69841, 0, 952, 128235, 125107, 0, 70296, 6449, 72102, 0, 0, 43098, 64171, - 8142, 64160, 0, 0, 0, 0, 0, 0, 0, 0, 67597, 6676, 3930, 42615, 73124, - 69991, 67598, 0, 0, 0, 65591, 41581, 128056, 1453, 0, 0, 0, 8500, 42222, - 0, 119270, 72992, 69996, 0, 0, 64676, 0, 0, 67606, 66385, 0, 42217, - 13102, 0, 67607, 6672, 0, 0, 0, 0, 67608, 0, 9001, 0, 11274, 67601, 0, - 64210, 6664, 0, 42056, 67602, 0, 0, 0, 0, 1469, 67603, 65381, 69921, - 4988, 42372, 0, 9598, 904, 352, 42225, 0, 8061, 10673, 0, 0, 128276, - 67600, 67477, 0, 127293, 8575, 127295, 127296, 127289, 127290, 127291, - 127292, 127285, 127286, 127287, 118877, 127281, 127282, 9460, 823, 11587, - 0, 0, 0, 127305, 12387, 0, 0, 127301, 126979, 42783, 69998, 64208, - 127298, 127299, 66031, 0, 11606, 64784, 0, 69973, 0, 124149, 0, 5152, - 11048, 0, 120121, 67605, 0, 69604, 0, 70276, 194847, 0, 127052, 42587, - 42214, 41394, 0, 4763, 0, 118935, 0, 5260, 0, 94038, 326, 120131, 74119, - 0, 10771, 42198, 194920, 194835, 194925, 41398, 127079, 41393, 127077, - 127076, 453, 41396, 0, 13159, 11227, 9572, 0, 0, 194576, 128835, 127081, - 0, 126617, 43144, 0, 72972, 194887, 0, 0, 0, 0, 0, 64061, 0, 0, 64056, - 70310, 0, 0, 0, 66971, 0, 111084, 64301, 72998, 10464, 0, 128393, 72847, - 0, 11528, 64024, 128072, 679, 0, 0, 5850, 758, 7536, 0, 0, 43712, 0, - 64006, 983589, 64005, 70298, 0, 126487, 0, 0, 0, 0, 0, 72999, 0, 64027, - 64029, 0, 0, 64000, 0, 194874, 0, 42201, 12421, 194875, 0, 1852, 0, 0, - 73744, 0, 64041, 129127, 0, 0, 0, 92322, 12423, 12854, 0, 3496, 0, - 110966, 0, 194823, 0, 0, 6158, 8327, 74553, 0, 12419, 0, 11570, 2169, 0, - 123618, 0, 7844, 983820, 194909, 0, 1682, 93039, 194911, 42756, 6765, - 128178, 0, 0, 0, 11412, 6768, 0, 194830, 71316, 0, 0, 0, 11577, 0, - 194829, 1833, 11576, 74334, 0, 0, 42854, 69438, 0, 70307, 0, 194856, - 8085, 0, 194850, 0, 72996, 128778, 1949, 11614, 7847, 120489, 120997, - 64483, 0, 0, 0, 122639, 0, 0, 0, 126651, 42864, 0, 64667, 74624, 0, 0, - 43261, 11484, 127535, 67840, 0, 0, 128965, 0, 72974, 0, 72456, 8995, - 3455, 0, 0, 9879, 0, 0, 4158, 128050, 0, 0, 110929, 0, 0, 0, 332, 118808, - 0, 0, 2407, 0, 42199, 92386, 110865, 0, 77921, 55217, 123161, 125199, - 70043, 0, 0, 0, 121093, 1834, 0, 0, 71315, 0, 65249, 0, 8662, 0, 0, - 123153, 0, 11539, 10784, 0, 67674, 0, 92233, 0, 0, 118858, 0, 0, 0, 0, 0, - 0, 12499, 6280, 0, 0, 0, 0, 0, 0, 43851, 6279, 12508, 0, 12502, 9161, 0, - 1620, 0, 3601, 0, 0, 67246, 609, 11555, 0, 12496, 0, 74181, 120492, - 12505, 0, 194902, 0, 43567, 239, 0, 127085, 0, 0, 42671, 0, 0, 83095, - 43565, 127082, 983955, 12696, 127753, 0, 94062, 12929, 0, 712, 0, 4197, - 0, 42818, 0, 70306, 0, 0, 983824, 0, 43562, 0, 119506, 68076, 0, 111074, - 64628, 0, 0, 0, 0, 7494, 0, 4924, 0, 0, 0, 0, 72368, 0, 127087, 69987, - 64796, 0, 0, 12033, 119492, 0, 72370, 0, 0, 0, 0, 70299, 0, 0, 68324, - 72420, 0, 0, 0, 0, 70309, 127000, 0, 0, 0, 72418, 72963, 0, 5699, 0, - 983898, 9488, 74410, 119112, 70477, 11170, 0, 0, 72312, 0, 5265, 0, 0, 0, - 0, 12464, 0, 43264, 72977, 0, 43345, 120853, 0, 120592, 6807, 0, 9829, - 69997, 0, 0, 43346, 11393, 795, 0, 72412, 12462, 72416, 72415, 0, 0, - 64362, 0, 0, 120811, 0, 12468, 8607, 1008, 0, 120670, 0, 0, 67855, - 125018, 72372, 6758, 0, 0, 1820, 41112, 0, 11202, 129451, 0, 13223, 0, - 64595, 0, 0, 0, 983649, 12616, 0, 127088, 0, 74467, 0, 0, 0, 0, 0, 0, - 67233, 119060, 0, 83448, 19920, 69897, 0, 129057, 0, 1130, 0, 0, 0, - 11823, 0, 0, 118896, 0, 0, 13280, 0, 10747, 118925, 0, 43509, 0, 0, 8959, - 0, 6747, 0, 0, 8568, 0, 120870, 0, 120803, 83060, 42670, 0, 11621, 12460, - 0, 0, 0, 0, 111188, 0, 66570, 72989, 121305, 126476, 120582, 0, 0, 0, - 111191, 70308, 11594, 0, 68333, 69427, 10491, 0, 0, 0, 0, 0, 127506, 0, - 194910, 4923, 65086, 8981, 0, 42133, 0, 72244, 0, 70294, 0, 0, 12485, 0, - 8642, 0, 42766, 0, 2210, 11109, 0, 0, 0, 0, 0, 7398, 0, 0, 0, 8041, 1461, - 0, 119133, 0, 6749, 0, 0, 0, 71705, 0, 0, 68071, 0, 67668, 0, 0, 9193, 0, - 0, 0, 0, 73810, 0, 0, 64305, 0, 0, 623, 781, 670, 10660, 5769, 613, 7543, - 0, 477, 92633, 92521, 0, 592, 0, 12459, 0, 0, 0, 12465, 119578, 654, - 11345, 653, 652, 111250, 647, 0, 633, 120744, 0, 111262, 12480, 74354, 0, - 39, 12487, 0, 0, 74803, 12482, 0, 12489, 0, 128962, 5550, 129175, 0, 0, - 0, 0, 1813, 0, 41311, 111205, 0, 11229, 0, 70496, 1675, 69840, 129435, 0, - 119078, 10070, 10595, 111207, 119077, 111206, 121162, 0, 0, 0, 11222, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 71716, 917841, 0, 0, 270, 0, 0, 0, 0, 0, - 120561, 0, 69741, 0, 0, 68251, 0, 71721, 364, 9595, 0, 0, 0, 707, 110603, - 0, 9282, 0, 224, 0, 68670, 9332, 65581, 68677, 0, 68644, 0, 11764, 68634, - 0, 10732, 68640, 850, 0, 0, 71123, 0, 68619, 44008, 68627, 0, 0, 0, 0, - 66969, 0, 0, 0, 12507, 0, 0, 128311, 0, 120529, 4375, 0, 0, 0, 12198, 0, - 67339, 0, 0, 72994, 74293, 128434, 0, 0, 64546, 0, 71208, 0, 0, 78916, - 42334, 42502, 0, 120887, 72961, 0, 917838, 5767, 0, 0, 71710, 8353, 0, 0, - 0, 121233, 0, 0, 0, 0, 119920, 0, 0, 121186, 0, 0, 0, 72719, 64604, 0, - 6096, 122632, 10063, 0, 0, 119630, 3485, 12987, 0, 127522, 0, 0, 0, 0, 0, - 0, 0, 0, 127173, 0, 0, 68249, 0, 0, 118923, 0, 64574, 128794, 0, 1640, - 12495, 66691, 0, 3138, 12504, 11171, 1922, 0, 12498, 128733, 0, 69939, 0, - 65543, 0, 0, 0, 66643, 0, 120734, 0, 4228, 0, 10303, 128884, 0, 0, 10335, - 3520, 0, 12490, 0, 0, 0, 12493, 121452, 64636, 1002, 12491, 0, 0, 92615, - 2096, 0, 0, 0, 0, 11611, 66228, 0, 11241, 66224, 66221, 66226, 66229, - 66219, 66231, 66216, 0, 66236, 66211, 66218, 0, 66240, 78041, 66233, - 66217, 0, 7909, 66234, 11605, 0, 0, 66208, 0, 0, 128282, 73875, 0, 12898, - 12494, 120939, 12492, 0, 128774, 0, 74153, 0, 127391, 127489, 4882, - 13040, 0, 120762, 4885, 194732, 0, 13042, 4880, 128834, 2429, 118674, - 8647, 0, 0, 0, 0, 0, 0, 68896, 0, 119101, 66693, 0, 1870, 78040, 470, - 68893, 78035, 78036, 983577, 78034, 110607, 110608, 0, 12511, 74453, - 12514, 0, 128609, 7239, 7001, 11974, 121214, 0, 0, 7378, 12512, 11615, - 13041, 0, 0, 128057, 13038, 0, 0, 71717, 70195, 120836, 12510, 127070, - 13039, 75019, 12513, 71969, 12471, 110761, 0, 121385, 70193, 0, 0, 0, - 71714, 0, 12477, 0, 12473, 7666, 67362, 237, 6281, 0, 0, 0, 0, 1312, 0, - 0, 12469, 0, 0, 64335, 12475, 0, 69382, 0, 11524, 10367, 10431, 74368, - 13017, 3388, 129547, 69573, 0, 0, 128725, 4932, 0, 0, 13015, 0, 0, 65451, - 8185, 0, 0, 2189, 129362, 74375, 10129, 0, 7948, 9236, 0, 0, 69512, - 92726, 43473, 6289, 10484, 0, 0, 0, 12082, 12521, 3147, 110643, 110644, - 12524, 110642, 2310, 0, 0, 0, 0, 13013, 0, 8596, 983871, 10804, 70497, 0, - 0, 13014, 12444, 0, 43088, 13016, 0, 0, 0, 0, 12331, 0, 0, 8744, 726, - 121090, 983868, 4155, 0, 0, 0, 71690, 12522, 73128, 0, 0, 127805, 0, - 110647, 0, 0, 983872, 12525, 0, 12523, 2152, 11969, 120596, 403, 0, - 11021, 0, 0, 11030, 8610, 92567, 0, 0, 63998, 0, 0, 0, 0, 0, 0, 0, 12506, - 0, 11146, 71477, 12500, 0, 12509, 0, 0, 0, 0, 6608, 0, 0, 0, 0, 69288, - 77995, 0, 3608, 0, 0, 1107, 0, 129658, 0, 0, 0, 0, 983956, 43217, 66571, - 13222, 118963, 0, 126514, 10463, 11553, 0, 63995, 9043, 128634, 71722, 0, - 0, 127751, 92974, 12529, 8042, 0, 2344, 12528, 0, 0, 0, 69719, 120956, 0, - 0, 66512, 0, 12530, 0, 0, 68917, 12658, 0, 71683, 0, 983241, 0, 127526, - 469, 0, 4363, 3313, 0, 0, 2023, 0, 72251, 78225, 65706, 10051, 78219, - 78220, 0, 9920, 12215, 0, 4931, 1951, 12497, 119363, 0, 0, 119336, 0, 0, - 0, 0, 0, 1491, 128578, 129169, 0, 0, 0, 0, 78898, 94086, 41993, 0, 67379, - 0, 0, 0, 0, 9738, 41995, 1075, 0, 12535, 41992, 0, 2187, 0, 0, 128117, 0, - 9940, 0, 7692, 0, 9727, 41131, 330, 8566, 0, 41133, 41117, 128482, 12532, - 78550, 78546, 43177, 0, 43235, 0, 917542, 78229, 78231, 13031, 12910, - 67710, 78555, 13028, 78553, 12537, 0, 0, 71692, 12536, 2350, 13029, - 78233, 0, 0, 13030, 0, 4527, 71250, 12538, 0, 0, 0, 0, 0, 0, 0, 12484, - 4032, 71459, 194728, 0, 64344, 0, 66700, 66000, 8412, 0, 43466, 1296, - 2325, 0, 121020, 10149, 74118, 0, 0, 12481, 121280, 12488, 0, 0, 0, - 67972, 0, 2354, 42619, 0, 73027, 6295, 901, 0, 0, 0, 0, 0, 128653, 11927, - 66584, 78559, 78560, 78557, 78558, 0, 74649, 0, 126241, 67220, 194726, - 78568, 67226, 78565, 70190, 78563, 78564, 2352, 67219, 78569, 71945, - 11289, 1407, 67973, 0, 13026, 6762, 10399, 70192, 13023, 78578, 9777, - 67208, 1871, 0, 0, 0, 13024, 71936, 0, 9325, 6818, 6283, 11738, 0, 0, - 71938, 11741, 0, 0, 9216, 8263, 11279, 0, 983856, 0, 13021, 71922, 3136, - 0, 983859, 0, 13022, 129143, 9956, 0, 0, 0, 42580, 0, 0, 0, 13020, 10024, - 0, 94013, 0, 0, 0, 43001, 8029, 0, 0, 0, 3335, 127924, 9209, 13048, - 73126, 0, 0, 0, 3333, 119100, 0, 0, 3342, 78582, 78583, 73056, 78581, - 4156, 0, 0, 0, 78591, 1611, 73058, 13018, 78586, 78588, 78584, 3337, - 4537, 78593, 11736, 0, 0, 0, 4214, 73790, 0, 0, 13046, 194844, 425, - 74763, 42066, 78595, 0, 2392, 13047, 0, 0, 12425, 13049, 0, 92243, 0, - 72715, 73944, 13050, 0, 0, 0, 0, 983506, 0, 0, 8929, 6849, 0, 0, 0, - 983990, 0, 13045, 0, 0, 7751, 0, 9726, 0, 3997, 0, 8768, 13044, 0, 0, - 4024, 0, 0, 2419, 9757, 69736, 0, 0, 0, 129500, 0, 0, 0, 72735, 0, 0, 0, - 0, 0, 11911, 124990, 0, 2346, 194691, 69931, 0, 9646, 3773, 43557, 68154, - 42536, 0, 70108, 13043, 92686, 92494, 0, 208, 0, 43766, 0, 0, 0, 10699, - 0, 0, 7825, 7110, 111275, 0, 111274, 41109, 2398, 111271, 0, 0, 0, 0, 0, - 0, 72723, 8294, 42912, 129343, 0, 0, 4876, 111316, 0, 111326, 111282, 0, - 0, 0, 73950, 13053, 9944, 0, 2811, 13051, 111313, 3143, 111246, 66374, - 110759, 0, 0, 13052, 0, 0, 63972, 119071, 7025, 0, 0, 100464, 74161, - 4154, 9863, 129686, 0, 0, 63970, 1564, 0, 0, 0, 0, 0, 9942, 0, 0, 111227, - 0, 128471, 0, 63957, 0, 1626, 0, 63983, 2161, 111232, 0, 0, 121275, - 111292, 6254, 4910, 69453, 0, 64753, 100458, 111303, 111204, 127404, - 111297, 3229, 111306, 42774, 0, 0, 111218, 111286, 2331, 0, 7085, 6137, - 0, 70411, 0, 126070, 0, 128438, 0, 0, 65043, 0, 127588, 70412, 128921, - 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, 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, - 78065, 8913, 120390, 4875, 73678, 120396, 120389, 71854, 0, 120394, - 120386, 120395, 13104, 78076, 78077, 120393, 78075, 0, 3134, 83096, - 65696, 72432, 0, 0, 0, 8334, 0, 83207, 3449, 0, 0, 83215, 0, 0, 0, 83204, - 0, 0, 0, 69707, 0, 0, 10734, 0, 83198, 83108, 7804, 121401, 83166, 8457, - 83212, 0, 11367, 0, 78054, 0, 72762, 0, 64285, 0, 5464, 0, 83100, 2361, - 7971, 78072, 78073, 78070, 78071, 0, 8086, 0, 6707, 0, 2312, 40977, 0, - 40962, 0, 0, 74962, 40980, 0, 0, 0, 40970, 92895, 110823, 0, 42438, - 72752, 6288, 0, 127946, 5653, 42400, 10891, 73946, 5658, 70401, 0, 0, 0, - 0, 71060, 0, 0, 42326, 100482, 92191, 92685, 42478, 2327, 0, 12959, - 42287, 92883, 0, 83081, 917550, 0, 0, 2867, 128562, 66312, 698, 0, 0, 0, - 70017, 0, 8000, 12641, 83140, 0, 0, 129064, 0, 72979, 83133, 0, 83134, 0, - 0, 111011, 92960, 74356, 0, 74562, 0, 72745, 0, 0, 120568, 0, 0, 0, 0, 0, - 8703, 5462, 83195, 0, 10101, 0, 70049, 0, 0, 128793, 0, 0, 66254, 120821, - 0, 1565, 123621, 0, 119194, 0, 42651, 0, 0, 917847, 83227, 83218, 0, - 75011, 0, 129724, 0, 64399, 0, 12899, 74564, 0, 42206, 0, 72718, 71715, - 83149, 983794, 83146, 12192, 917826, 0, 0, 0, 0, 68056, 0, 67426, 128687, - 0, 0, 0, 0, 0, 0, 67431, 71718, 74357, 0, 121176, 43596, 6090, 0, 7812, - 10534, 0, 0, 0, 0, 129763, 0, 0, 0, 0, 0, 0, 43306, 0, 0, 0, 7930, 0, - 2292, 0, 0, 72737, 0, 6130, 0, 0, 0, 0, 0, 70463, 968, 0, 0, 0, 43304, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 11838, 0, 0, 0, 42682, 0, 0, 0, 41227, 0, - 71475, 0, 64848, 0, 78574, 0, 113792, 0, 0, 129133, 0, 66015, 74614, 959, - 8885, 0, 0, 0, 9469, 9632, 128211, 74761, 64323, 100478, 0, 2266, 78575, - 310, 0, 0, 68403, 100480, 72738, 125279, 0, 0, 6497, 127320, 0, 0, 19958, - 0, 128691, 74953, 0, 118998, 67332, 374, 0, 41933, 120975, 0, 0, 41934, - 7465, 0, 128168, 70666, 11151, 6101, 0, 41936, 100476, 4879, 0, 65446, 0, - 0, 983695, 0, 5374, 0, 128059, 127390, 0, 126618, 983575, 129146, 0, 0, - 1929, 0, 12142, 0, 0, 0, 121472, 0, 12982, 0, 5378, 0, 128679, 0, 0, - 127869, 0, 127343, 0, 0, 0, 78832, 74481, 0, 43262, 100511, 2421, 0, - 2324, 828, 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, 7999, 0, 11217, - 983266, 10634, 10942, 0, 2348, 0, 0, 0, 0, 118587, 9982, 64324, 41240, 0, - 100470, 78462, 1810, 0, 92566, 71299, 0, 0, 917848, 0, 0, 100515, 0, 0, - 0, 43912, 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, 74576, 44019, - 128171, 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, 8699, 723, 83084, - 966, 0, 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, 0, 8075, 55276, - 123589, 8047, 983787, 78827, 12634, 0, 78781, 71322, 0, 12174, 42610, 0, - 0, 0, 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 2257, 64418, - 0, 0, 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, 11414, 0, - 2531, 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 129979, 13037, 0, - 129956, 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, - 0, 129439, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, 66273, 0, - 6755, 73827, 9046, 67355, 0, 0, 0, 0, 0, 0, 0, 0, 92221, 83235, 2563, - 13033, 247, 83229, 0, 12338, 0, 83231, 11270, 0, 0, 0, 0, 70107, 0, 0, 0, - 0, 3752, 83243, 68895, 66973, 68897, 0, 0, 0, 0, 5009, 0, 0, 0, 0, - 119521, 78823, 78824, 70353, 68399, 3877, 0, 78825, 10145, 43566, 0, 0, - 10236, 0, 43782, 0, 127329, 0, 69652, 2247, 120612, 128058, 0, 43200, - 43777, 71253, 983644, 69558, 0, 71866, 43203, 0, 68894, 0, 127326, 0, - 43778, 119538, 0, 0, 43781, 11303, 65547, 0, 7031, 0, 0, 67343, 83237, - 83267, 0, 67341, 120522, 8535, 0, 0, 0, 66032, 0, 0, 120786, 42233, 0, - 9946, 7667, 0, 11822, 0, 43189, 120673, 100507, 2979, 1579, 0, 0, 0, 0, - 0, 12635, 71337, 0, 94055, 0, 1285, 64882, 0, 0, 83113, 12640, 83112, - 7401, 92869, 12625, 0, 71296, 72744, 0, 74286, 55260, 3396, 12642, 0, - 110719, 0, 12630, 0, 0, 10153, 0, 6166, 120516, 0, 110680, 0, 0, 119499, - 9285, 913, 42259, 83017, 0, 2142, 127889, 0, 94012, 7878, 0, 72733, 0, 0, - 0, 0, 92868, 0, 0, 0, 0, 128918, 5263, 74782, 0, 41939, 43702, 0, 917856, - 0, 10139, 980, 43698, 0, 2208, 0, 43701, 0, 125132, 0, 100528, 0, 10085, - 0, 0, 119989, 100529, 0, 71699, 0, 8072, 0, 43700, 0, 7304, 7783, 66894, - 12398, 0, 0, 0, 0, 0, 0, 120565, 0, 2217, 0, 94015, 6367, 0, 66688, 0, 0, - 0, 0, 0, 92199, 7808, 1829, 0, 41937, 0, 43272, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 92467, 6627, 0, 6258, 10683, 0, 0, 0, 5649, 0, 0, 0, 1643, 127898, - 0, 127846, 67244, 0, 42452, 0, 0, 0, 0, 64291, 0, 0, 0, 6576, 74773, 0, - 0, 66309, 0, 9886, 55225, 11292, 0, 72867, 55227, 0, 12632, 0, 194817, 0, - 7680, 0, 92745, 120714, 12639, 3380, 8123, 0, 12638, 42262, 4501, 0, 0, - 0, 0, 125131, 1494, 983147, 0, 0, 0, 0, 10494, 0, 65872, 0, 0, 0, 0, 0, - 0, 983587, 0, 0, 0, 0, 0, 0, 0, 71077, 0, 127335, 121128, 0, 5570, 1881, - 7210, 0, 1012, 66630, 0, 128982, 7208, 66442, 5569, 113723, 42339, 92655, - 0, 0, 0, 0, 92378, 65602, 0, 92375, 64727, 9160, 0, 0, 0, 124928, 10503, - 0, 3423, 3870, 8483, 10162, 0, 4319, 0, 0, 0, 0, 0, 983117, 0, 69562, 0, - 0, 0, 0, 0, 0, 5571, 7630, 9740, 9121, 5568, 0, 0, 42085, 0, 0, 65056, 0, - 589, 0, 0, 0, 10233, 66252, 66251, 78734, 66253, 0, 0, 42645, 0, 128424, - 8583, 0, 0, 0, 129932, 0, 0, 0, 0, 0, 12204, 92436, 120453, 0, 0, 0, - 983262, 0, 0, 70311, 0, 0, 128012, 41063, 0, 10664, 0, 983660, 0, 4551, - 129090, 74759, 0, 983270, 0, 0, 72806, 0, 0, 12517, 7806, 0, 12034, 0, - 6355, 12519, 41004, 0, 0, 93849, 0, 71707, 0, 121231, 7332, 129075, - 12111, 3927, 0, 12515, 1474, 68768, 0, 6923, 69509, 0, 127802, 0, 43990, - 74639, 126229, 121007, 0, 92706, 0, 0, 0, 0, 0, 9645, 0, 121026, 5853, 0, - 10363, 120729, 12956, 0, 0, 0, 0, 127888, 0, 0, 0, 0, 0, 10514, 65517, 0, - 0, 71101, 0, 0, 0, 43570, 2969, 43420, 129944, 0, 0, 92366, 70809, 0, 0, - 0, 0, 0, 118714, 12125, 41124, 0, 1164, 128817, 0, 120466, 0, 0, 65014, - 66009, 74451, 125075, 983129, 7469, 0, 0, 0, 69988, 120671, 83171, 41123, - 11176, 0, 0, 41126, 9991, 41128, 0, 0, 110949, 0, 0, 42877, 7994, 0, - 6104, 983612, 0, 129869, 0, 0, 0, 0, 74438, 128272, 121409, 41981, 0, - 69296, 42904, 0, 0, 74435, 126640, 0, 0, 0, 127968, 92442, 12703, 9661, - 67360, 67359, 7455, 70732, 11473, 119217, 128512, 0, 92323, 0, 0, 129632, - 67358, 0, 0, 0, 0, 174, 121131, 883, 4161, 128033, 42603, 0, 0, 72256, 0, - 0, 128356, 0, 0, 0, 0, 3846, 8070, 6150, 128109, 4370, 118617, 0, 0, - 74587, 0, 0, 0, 0, 4986, 12189, 917553, 67648, 120499, 0, 4257, 71695, - 123620, 6220, 0, 65561, 0, 0, 0, 0, 122652, 0, 0, 0, 69684, 0, 0, 128452, - 120873, 0, 0, 74922, 0, 71897, 0, 0, 67368, 67367, 8871, 67366, 0, 0, 0, - 0, 0, 67361, 0, 0, 67365, 67364, 3427, 4240, 67376, 67375, 67374, 67373, - 0, 0, 0, 67377, 0, 71689, 0, 0, 67372, 67371, 67370, 67369, 0, 0, 0, - 124962, 0, 0, 0, 0, 65898, 0, 65312, 0, 0, 0, 0, 4010, 121208, 41106, 0, - 0, 0, 41105, 0, 64803, 83456, 0, 0, 0, 0, 0, 0, 0, 11008, 0, 0, 71351, - 41110, 71681, 64892, 9113, 1954, 41108, 0, 42878, 0, 67405, 0, 0, 0, 0, - 0, 119539, 69435, 73463, 0, 4586, 129342, 0, 0, 0, 0, 0, 125233, 92307, - 0, 0, 0, 67382, 0, 9500, 0, 4957, 0, 2422, 2212, 0, 67381, 67380, 11045, - 67378, 0, 0, 3890, 12168, 121328, 0, 0, 0, 41947, 0, 120828, 74946, - 917901, 0, 1571, 66461, 41949, 42805, 8270, 943, 41946, 0, 2073, 0, - 41980, 0, 0, 0, 0, 4429, 6272, 0, 1460, 6954, 128572, 41120, 0, 65733, 0, - 41119, 0, 127006, 0, 0, 0, 129168, 12895, 0, 0, 0, 69440, 0, 1985, 6296, - 0, 0, 0, 0, 0, 41122, 0, 2457, 0, 0, 0, 0, 0, 0, 8840, 8035, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 8681, 0, 121505, 128747, 0, 0, 70102, 0, 124976, 9605, - 0, 13220, 0, 67354, 11312, 0, 9246, 67349, 0, 0, 0, 0, 10012, 12123, 0, - 0, 0, 0, 983846, 0, 0, 0, 67817, 0, 1272, 0, 0, 0, 983578, 0, 1467, - 119501, 917806, 0, 0, 0, 70312, 73537, 124955, 0, 70400, 0, 0, 72817, 0, - 19935, 0, 92162, 0, 0, 0, 128406, 5275, 0, 0, 44006, 129082, 0, 3789, - 128205, 0, 0, 0, 11474, 0, 0, 0, 129050, 0, 92194, 129503, 9537, 4496, 0, - 120443, 2605, 4500, 0, 55224, 8600, 0, 0, 41646, 11667, 69569, 0, 0, - 917905, 4499, 41649, 0, 0, 0, 69254, 0, 0, 0, 65804, 0, 70034, 41866, 0, - 0, 0, 11174, 0, 0, 0, 9559, 128773, 41940, 8299, 41945, 0, 41941, 5455, - 7190, 0, 0, 917810, 65266, 0, 41943, 10762, 0, 41931, 0, 0, 8106, 4128, - 0, 0, 4494, 0, 0, 72405, 0, 119567, 42068, 917808, 0, 11004, 12794, - 65072, 5271, 7317, 0, 0, 0, 0, 0, 0, 92281, 0, 0, 0, 0, 71880, 3868, - 71881, 983573, 128431, 7703, 0, 64390, 0, 7406, 120358, 93850, 0, 3985, - 66425, 0, 66615, 10177, 0, 41853, 71873, 12809, 0, 12193, 0, 10879, - 122945, 0, 9055, 0, 3851, 8132, 0, 0, 119263, 917908, 0, 0, 0, 0, 122940, - 42657, 122952, 7643, 0, 0, 122936, 43568, 0, 11949, 7650, 43569, 64951, - 7647, 7649, 0, 7646, 0, 0, 9651, 125005, 3891, 0, 0, 2337, 77831, 77832, - 67860, 129288, 0, 0, 43561, 67706, 119669, 0, 1860, 0, 68835, 5812, - 12784, 0, 0, 0, 0, 69260, 7727, 0, 69292, 69818, 66444, 128665, 42719, 0, - 1569, 0, 12534, 12124, 7690, 194871, 12533, 0, 68383, 67997, 0, 6969, 0, - 0, 0, 67974, 63895, 128650, 0, 0, 0, 42144, 0, 0, 0, 0, 92211, 119043, 0, - 0, 917545, 0, 0, 12791, 0, 0, 0, 4447, 71065, 12793, 0, 0, 43385, 0, 0, - 12790, 120256, 0, 983840, 12792, 120254, 0, 0, 12789, 128489, 12317, - 74934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127840, 41652, 2974, 78689, 11476, - 0, 0, 0, 0, 43871, 0, 10894, 119176, 74557, 65686, 0, 0, 3724, 67335, - 67334, 67333, 67338, 67337, 0, 67336, 0, 65306, 0, 128421, 0, 8646, - 129593, 77829, 0, 0, 74852, 0, 0, 0, 0, 0, 220, 120252, 43551, 0, 10044, - 0, 0, 983847, 68659, 110825, 5707, 71362, 0, 0, 0, 0, 0, 0, 10297, 0, - 41308, 67331, 0, 0, 0, 0, 2467, 0, 6003, 0, 0, 8040, 0, 0, 4182, 0, - 11135, 120501, 0, 0, 2510, 0, 10208, 0, 78302, 70829, 0, 0, 6837, 0, 0, - 67348, 0, 0, 0, 0, 1559, 67342, 11104, 67340, 67347, 67346, 67345, 67344, - 0, 0, 67357, 67356, 0, 0, 0, 0, 67352, 67351, 5516, 2845, 7717, 8036, - 65161, 67353, 5514, 12045, 6278, 0, 5515, 0, 0, 0, 0, 0, 65194, 100387, - 5517, 70116, 92774, 0, 67884, 0, 67890, 42094, 67880, 67881, 67882, - 67883, 0, 0, 67879, 120411, 1902, 67887, 67888, 12976, 126546, 12483, - 12368, 41769, 42726, 41765, 69557, 12787, 67874, 7556, 67878, 74351, - 67897, 989, 42677, 67889, 0, 6060, 0, 4326, 11000, 64601, 68478, 0, 0, - 6917, 0, 120837, 0, 0, 0, 6148, 8605, 74205, 0, 0, 0, 42715, 0, 101047, - 0, 68663, 0, 41796, 1269, 42703, 64754, 101049, 101042, 5144, 12221, - 42716, 71048, 5133, 4331, 0, 128675, 0, 5279, 121362, 71046, 0, 0, 42701, - 0, 0, 0, 121470, 0, 0, 0, 983311, 0, 72455, 121259, 42666, 12207, 1067, - 255, 12131, 0, 0, 0, 0, 0, 0, 0, 70728, 43460, 0, 42723, 125216, 0, - 70427, 0, 12797, 0, 0, 983722, 0, 67977, 12799, 0, 92504, 9746, 5135, 0, - 12796, 0, 0, 0, 5139, 346, 74303, 121134, 12795, 125109, 5168, 0, 43845, - 983727, 0, 8253, 8817, 1136, 983735, 43563, 127774, 129542, 0, 0, 0, 0, - 0, 0, 983619, 0, 0, 4041, 0, 2357, 43240, 12786, 0, 0, 0, 44004, 7142, 0, - 67984, 0, 0, 0, 0, 12785, 0, 0, 7770, 10712, 64853, 42679, 118916, 42375, - 0, 983124, 94074, 12119, 0, 11059, 10791, 111092, 450, 0, 0, 0, 0, 5450, - 64691, 0, 0, 44009, 0, 0, 111097, 94085, 1839, 94004, 0, 10927, 1701, 0, - 129610, 41749, 41761, 5453, 8361, 66045, 41758, 5444, 41763, 0, 0, 0, - 66349, 983138, 121274, 0, 0, 8801, 0, 4340, 0, 0, 0, 0, 70001, 41824, 0, - 0, 0, 0, 42700, 0, 127980, 0, 0, 0, 0, 0, 0, 4493, 4336, 129171, 2314, - 983061, 41808, 0, 0, 0, 64638, 0, 65937, 4489, 71331, 0, 0, 5358, 42717, - 0, 71236, 0, 0, 0, 127042, 41813, 2712, 0, 127044, 1410, 0, 0, 0, 0, 0, - 0, 0, 0, 128587, 0, 0, 0, 4892, 0, 0, 0, 0, 122966, 5777, 0, 759, 0, - 2079, 65248, 12788, 0, 64552, 0, 41803, 68043, 0, 0, 0, 0, 128785, 0, - 68492, 67991, 75071, 2340, 0, 120638, 0, 983902, 0, 0, 917865, 64749, 0, - 2321, 3587, 0, 67236, 9953, 9952, 0, 0, 42714, 9951, 0, 0, 127902, 74150, - 0, 0, 74757, 127554, 0, 983826, 2395, 0, 9976, 0, 125128, 0, 0, 0, 42809, - 42807, 0, 66290, 70854, 4150, 64424, 8318, 41790, 67976, 65559, 2360, - 41794, 0, 0, 120987, 0, 0, 2418, 0, 2411, 0, 41783, 0, 41786, 65108, 0, - 0, 41772, 42813, 2317, 0, 118980, 0, 0, 0, 0, 0, 0, 78682, 7753, 2351, - 6655, 64489, 0, 0, 0, 4443, 41697, 230, 65793, 0, 65943, 42803, 0, 0, - 5441, 0, 0, 127053, 0, 855, 0, 6109, 101021, 0, 119116, 69989, 0, 0, - 72146, 0, 101023, 0, 72148, 124918, 19915, 41892, 0, 0, 128901, 41887, 0, - 67980, 9735, 0, 0, 120591, 13082, 101026, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, - 64504, 0, 69489, 120514, 0, 92962, 0, 42724, 69977, 0, 0, 0, 0, 67994, 0, - 0, 983823, 3565, 0, 0, 127553, 43035, 69898, 0, 0, 0, 0, 4891, 0, 0, - 4602, 0, 121065, 0, 0, 121157, 0, 43978, 8988, 0, 0, 0, 0, 0, 119184, - 121436, 73902, 69740, 0, 0, 72976, 0, 0, 8771, 0, 0, 0, 119209, 74974, - 71737, 0, 0, 67987, 0, 0, 0, 67989, 0, 10065, 8207, 0, 983588, 0, 0, 662, - 0, 41927, 0, 0, 0, 0, 0, 0, 0, 41929, 0, 0, 0, 41926, 69994, 0, 0, 0, - 126230, 68013, 1433, 64648, 6475, 0, 120983, 0, 73876, 0, 0, 0, 67992, - 78052, 0, 3978, 0, 0, 0, 0, 120761, 12281, 0, 0, 13241, 0, 0, 0, 0, - 11765, 42577, 0, 0, 2641, 7192, 0, 0, 118809, 101015, 0, 101016, 128948, - 101013, 6479, 64294, 118683, 0, 0, 0, 64334, 0, 0, 0, 92266, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9478, 127339, 124964, 0, 202, 0, 0, 1242, 0, 121170, 0, - 63940, 0, 0, 0, 63939, 11990, 92430, 67982, 0, 65440, 70068, 0, 0, 64829, - 0, 0, 0, 0, 0, 2858, 0, 63989, 0, 69239, 0, 121152, 0, 77841, 0, 70078, - 92574, 129519, 0, 0, 0, 128974, 0, 12922, 92498, 0, 66424, 71124, 0, 0, - 0, 2856, 0, 47, 0, 126986, 65858, 0, 0, 0, 0, 119161, 8417, 65903, 0, 0, - 0, 4033, 128164, 0, 0, 0, 129961, 64600, 1903, 12320, 0, 120894, 0, 0, - 8915, 0, 945, 0, 0, 0, 0, 111068, 0, 74828, 0, 69560, 9531, 0, 8505, 0, - 119238, 0, 0, 65538, 0, 0, 0, 0, 0, 0, 63935, 0, 0, 0, 0, 0, 64787, - 111060, 0, 0, 110828, 0, 2230, 0, 0, 71886, 9843, 0, 92419, 111062, - 67488, 92715, 0, 1320, 0, 1673, 0, 92383, 129902, 9338, 128355, 0, 0, 0, - 0, 11997, 0, 0, 0, 0, 0, 0, 43308, 0, 0, 0, 0, 0, 0, 0, 63920, 0, 0, 0, - 0, 0, 0, 3514, 78723, 0, 7492, 0, 0, 0, 7514, 0, 63924, 0, 7502, 7587, 0, - 0, 0, 118689, 43881, 7610, 0, 0, 118710, 692, 43588, 0, 0, 75056, 9688, - 0, 9535, 0, 0, 0, 64530, 0, 125251, 194861, 0, 72209, 7453, 0, 8013, - 66396, 0, 0, 8895, 5356, 0, 5458, 0, 2866, 0, 127860, 71732, 71724, 6700, - 0, 111081, 120583, 0, 110614, 0, 9641, 63830, 65294, 0, 0, 67969, 0, - 7441, 0, 63826, 0, 0, 0, 0, 2844, 983972, 0, 63824, 12139, 67971, 0, 0, - 3358, 65295, 0, 3104, 0, 0, 0, 0, 65772, 0, 0, 0, 0, 2862, 11326, 0, 0, - 94001, 3268, 66591, 0, 6552, 42367, 7035, 120558, 0, 0, 1814, 195092, - 10240, 195093, 0, 0, 0, 0, 0, 66960, 0, 0, 2837, 4341, 0, 0, 129982, - 125064, 195094, 0, 0, 66964, 0, 72721, 863, 66936, 0, 0, 43323, 66928, 0, - 0, 68054, 0, 3654, 66951, 0, 66942, 0, 0, 7653, 0, 0, 66587, 0, 0, 92401, - 0, 0, 12927, 0, 0, 129697, 13056, 0, 0, 3056, 0, 0, 195101, 0, 0, 74506, - 73770, 0, 0, 0, 0, 0, 0, 0, 0, 72233, 0, 5811, 0, 0, 0, 66817, 983855, 0, - 0, 128636, 129311, 0, 128041, 0, 67739, 120965, 0, 0, 67507, 0, 68375, 0, - 0, 70300, 0, 0, 0, 983698, 111078, 0, 11991, 128079, 0, 92943, 1502, - 74117, 127988, 0, 129478, 121253, 0, 67661, 0, 0, 125084, 68667, 0, - 74057, 68639, 0, 42898, 120742, 0, 74388, 74838, 120822, 0, 0, 0, 0, - 69452, 43214, 5893, 0, 0, 92496, 0, 0, 119907, 119900, 0, 0, 0, 0, 41950, - 0, 0, 68610, 0, 68626, 894, 0, 0, 12306, 73846, 0, 0, 0, 8636, 0, 121028, - 42503, 0, 92942, 0, 121468, 119241, 0, 126569, 5096, 5095, 2863, 127505, - 0, 10454, 42530, 5094, 0, 0, 13156, 0, 111035, 5093, 111024, 983419, 0, - 5092, 10708, 11327, 0, 5091, 0, 0, 9153, 4104, 78599, 78601, 2929, 42712, - 75067, 12272, 9832, 0, 0, 111105, 0, 0, 0, 0, 0, 0, 13106, 0, 0, 129111, - 0, 0, 0, 0, 9074, 111111, 0, 111110, 0, 8113, 11168, 92563, 1786, 111109, - 0, 111108, 0, 74423, 0, 586, 74414, 64359, 1267, 0, 127531, 0, 65731, 0, - 0, 0, 92932, 0, 0, 0, 0, 0, 0, 1228, 0, 42846, 0, 0, 70343, 1714, 74406, - 0, 0, 0, 127389, 66225, 0, 0, 42660, 0, 0, 3804, 0, 0, 129859, 0, 2826, - 0, 0, 0, 128396, 0, 0, 0, 0, 0, 0, 12206, 5839, 0, 68524, 74065, 73521, - 0, 0, 126240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67241, 917821, 7030, 0, - 10479, 64959, 2852, 0, 121225, 0, 0, 128586, 0, 6963, 0, 0, 0, 74786, 0, - 0, 0, 0, 121281, 0, 0, 0, 0, 113815, 121360, 0, 9994, 118680, 2864, - 64719, 1148, 0, 41677, 0, 0, 2765, 0, 128181, 0, 0, 0, 92516, 74777, 0, - 0, 65206, 0, 0, 0, 0, 69391, 0, 0, 983770, 0, 41839, 129616, 983773, 0, - 0, 6931, 0, 0, 7177, 125137, 0, 0, 0, 93020, 0, 10722, 0, 0, 128186, - 121050, 0, 0, 127207, 0, 750, 0, 129453, 63912, 0, 0, 7032, 0, 0, 4314, - 128600, 0, 128409, 730, 0, 127866, 0, 0, 41380, 0, 0, 0, 69697, 8240, - 92939, 0, 41378, 0, 6938, 70026, 0, 0, 66246, 0, 0, 0, 0, 0, 0, 983094, - 0, 92754, 41470, 64805, 0, 0, 0, 0, 0, 0, 0, 0, 92938, 68370, 0, 0, - 73831, 0, 0, 0, 2872, 0, 0, 0, 0, 604, 41097, 0, 0, 0, 0, 0, 127488, 0, - 2836, 0, 0, 9707, 0, 43202, 0, 0, 69374, 0, 0, 120916, 2832, 92702, 9670, - 12937, 0, 0, 0, 0, 2822, 0, 0, 92519, 0, 73752, 0, 0, 0, 1331, 92603, 0, - 11856, 73510, 129432, 5090, 5089, 0, 3200, 0, 0, 0, 5088, 0, 0, 9477, 0, - 0, 5087, 92325, 0, 96, 5086, 0, 0, 0, 5085, 64286, 0, 0, 43820, 0, - 129710, 0, 0, 119042, 0, 129660, 0, 0, 0, 0, 0, 127241, 120891, 7601, 0, - 591, 0, 118953, 0, 0, 0, 0, 0, 10939, 7246, 6933, 67142, 67141, 0, 74600, - 120695, 0, 67138, 65574, 0, 78058, 67140, 73851, 74598, 67139, 128094, 0, - 6372, 0, 73514, 7963, 6371, 0, 0, 125040, 0, 0, 0, 0, 0, 0, 0, 8258, - 123591, 0, 0, 65148, 118919, 42, 0, 0, 0, 0, 0, 0, 0, 0, 67135, 67134, - 67133, 0, 0, 0, 0, 67136, 67130, 74597, 11550, 0, 67132, 65868, 0, 12826, - 127872, 124116, 126235, 9737, 92448, 0, 0, 0, 8878, 0, 0, 0, 0, 0, 72220, - 9086, 0, 100952, 0, 7437, 7454, 0, 0, 0, 0, 9042, 0, 0, 0, 0, 3805, 0, - 67128, 44001, 67126, 0, 44022, 19949, 12200, 43522, 983045, 43525, 0, 0, - 0, 64422, 67125, 67124, 7602, 0, 0, 43521, 0, 0, 43711, 43523, 41447, - 8424, 68483, 8704, 2397, 0, 0, 0, 0, 0, 10916, 0, 129290, 93998, 0, 0, 0, - 127800, 67686, 9961, 123203, 0, 68842, 10792, 8889, 121402, 6951, 0, - 68827, 917835, 74342, 0, 0, 0, 68816, 129152, 0, 42909, 66597, 70092, 0, - 0, 10481, 4559, 0, 1956, 43138, 0, 0, 43490, 43148, 0, 0, 0, 43140, 0, 0, - 0, 0, 69268, 8533, 0, 0, 0, 0, 0, 4357, 0, 70289, 983157, 0, 42911, 0, 0, - 0, 10941, 0, 6962, 0, 0, 113808, 0, 11014, 0, 8942, 12000, 0, 0, 73515, - 0, 0, 0, 42650, 0, 75016, 63975, 0, 66210, 0, 0, 129150, 0, 11193, 0, 0, - 0, 0, 0, 0, 0, 43476, 0, 11024, 74811, 72787, 10563, 92954, 0, 0, 2462, - 92955, 0, 0, 66213, 6957, 0, 120559, 0, 0, 0, 74594, 983424, 92347, 0, - 110702, 110708, 110707, 127119, 3109, 127117, 119909, 0, 121434, 0, 0, - 4042, 0, 0, 0, 127123, 127122, 127121, 0, 127999, 0, 3503, 74444, 68300, - 6694, 127997, 0, 0, 74306, 0, 983757, 7736, 0, 0, 0, 10521, 0, 42173, - 9705, 0, 129719, 6955, 71467, 0, 6149, 3887, 19956, 1411, 2824, 0, 0, 0, - 1403, 0, 1347, 66282, 127996, 0, 0, 0, 0, 8640, 0, 1178, 1654, 0, 0, - 129529, 43314, 0, 0, 0, 0, 2873, 67461, 0, 0, 67085, 10861, 0, 0, 70377, - 0, 67082, 11159, 41391, 67084, 0, 376, 6987, 983182, 119904, 0, 8823, 0, - 12943, 65185, 100988, 42099, 0, 0, 100990, 0, 8301, 0, 0, 1684, 0, 0, 0, - 120620, 0, 0, 0, 42121, 0, 66781, 78067, 42115, 0, 127998, 0, 67080, - 1493, 42111, 67077, 4097, 0, 983767, 0, 65808, 41642, 0, 118568, 67076, - 41636, 67074, 65095, 110660, 72254, 121240, 41629, 12154, 75073, 0, - 128179, 74084, 64380, 0, 0, 0, 0, 0, 71193, 65371, 7078, 121218, 0, 0, - 74592, 0, 0, 43275, 0, 41434, 6062, 0, 0, 19916, 0, 6950, 9606, 9842, 0, - 65744, 0, 0, 128659, 0, 41615, 10105, 0, 0, 41632, 7493, 0, 0, 41622, 0, - 0, 0, 0, 7632, 983217, 983216, 9805, 5990, 900, 0, 122955, 0, 120869, - 3612, 0, 64376, 0, 5389, 129469, 73495, 0, 2839, 9621, 582, 0, 0, 3749, - 0, 7569, 0, 0, 92865, 6956, 4403, 0, 0, 3299, 0, 0, 119127, 65676, 0, - 74372, 0, 983497, 7598, 69819, 42469, 42242, 1918, 9542, 480, 7716, 0, 0, - 0, 0, 0, 69918, 0, 8328, 0, 118894, 0, 0, 0, 0, 11132, 983502, 66743, - 74185, 100531, 2854, 66747, 0, 65755, 0, 67120, 67119, 65835, 67117, - 66736, 67123, 67122, 67121, 9881, 100481, 65757, 100538, 100459, 67116, - 8648, 128377, 6741, 43047, 0, 13180, 0, 100487, 66754, 73507, 73487, 0, - 0, 41752, 0, 8641, 100490, 125185, 73477, 100462, 100541, 6942, 69501, - 1024, 42849, 41751, 0, 8941, 101034, 11121, 0, 9023, 40973, 121476, 9928, - 67109, 66865, 0, 67114, 67113, 67112, 67111, 0, 41206, 120724, 9049, - 67108, 43166, 0, 41200, 128201, 125142, 126537, 0, 0, 41188, 119553, 0, - 101007, 917548, 74585, 78626, 0, 0, 11466, 0, 120797, 0, 125067, 2261, 0, - 2860, 0, 0, 70828, 127925, 92357, 67106, 12065, 42872, 0, 43875, 67103, - 43856, 0, 67102, 67105, 7531, 40981, 2413, 100522, 67404, 100521, 0, - 67101, 41196, 100523, 0, 129723, 73512, 43117, 100495, 0, 0, 0, 0, 69876, - 0, 7173, 496, 0, 4313, 64607, 0, 0, 983202, 2065, 42793, 2842, 0, 83152, - 13132, 798, 0, 12801, 67098, 10686, 118528, 128143, 0, 8054, 9174, 67087, - 67086, 67097, 67096, 41611, 67095, 74504, 78854, 42512, 0, 78857, 42089, - 74613, 78856, 0, 101029, 100468, 42079, 100467, 0, 66961, 100474, 0, 0, - 0, 68338, 69958, 0, 0, 0, 0, 0, 78859, 42093, 128951, 100504, 0, 0, 0, - 4580, 0, 0, 0, 92167, 0, 3021, 42004, 0, 0, 42317, 41998, 0, 6946, 77920, - 0, 123610, 0, 0, 0, 121442, 42690, 9880, 0, 0, 64589, 0, 0, 127880, - 68035, 0, 11360, 0, 0, 72242, 0, 0, 0, 0, 0, 64941, 0, 0, 0, 6856, 65671, - 11244, 73706, 6959, 41994, 42907, 0, 0, 122902, 8617, 41982, 8860, 0, 0, - 121256, 0, 0, 9597, 0, 43172, 0, 10117, 0, 92297, 65865, 73549, 0, - 128077, 0, 126065, 0, 187, 0, 65669, 0, 4963, 0, 0, 0, 8964, 0, 7775, 0, - 41948, 0, 0, 101010, 41942, 65449, 3160, 65922, 13226, 42665, 0, 42663, - 128210, 41766, 983503, 78848, 78849, 41760, 1189, 905, 110620, 42658, - 78851, 67859, 9629, 6742, 0, 43625, 12952, 7888, 0, 3980, 0, 42656, 0, - 42055, 0, 0, 0, 64540, 0, 7867, 69218, 6236, 0, 73490, 10505, 0, 12851, - 118948, 0, 5474, 128843, 3103, 0, 41753, 41733, 78051, 983477, 78844, - 78845, 41739, 78843, 70744, 10931, 41756, 43347, 68098, 122909, 41746, - 119147, 92591, 41259, 66954, 69930, 2691, 121338, 11231, 41244, 0, 69800, - 66364, 41262, 67503, 0, 0, 41251, 0, 0, 11805, 0, 0, 68331, 94045, 0, 0, - 0, 74633, 41266, 126642, 0, 0, 0, 65741, 41737, 2275, 2666, 121232, - 41738, 4967, 419, 13126, 0, 0, 42822, 0, 6434, 74913, 0, 0, 6432, 0, - 69932, 128862, 769, 41742, 69927, 74805, 6433, 0, 547, 1943, 6439, 0, - 4994, 487, 0, 0, 3754, 0, 0, 0, 0, 74780, 0, 0, 1595, 92777, 74431, 0, 0, - 74860, 43267, 0, 0, 129083, 12185, 69406, 0, 73479, 100984, 0, 42856, 0, - 0, 983765, 128319, 75057, 0, 0, 0, 65612, 0, 669, 0, 0, 0, 0, 0, 70445, - 100404, 69929, 0, 0, 460, 121513, 0, 0, 0, 120747, 0, 121519, 121518, 0, - 0, 121515, 71491, 65187, 9044, 78497, 11760, 78494, 7577, 78491, 41912, - 100412, 0, 100411, 0, 0, 100394, 78501, 0, 2933, 78500, 0, 66441, 100392, - 100397, 100391, 1549, 0, 100415, 0, 41755, 6206, 8670, 120587, 0, 69935, - 0, 0, 69768, 73492, 0, 66958, 0, 0, 10552, 64342, 41922, 0, 917858, 0, - 917857, 2717, 0, 0, 0, 73664, 41908, 100722, 41916, 0, 0, 0, 92506, - 100723, 66664, 69803, 0, 100725, 0, 0, 43373, 0, 0, 8468, 100729, 121173, - 128297, 119210, 118952, 0, 0, 0, 100686, 0, 0, 0, 128703, 100670, 457, - 78502, 78503, 123180, 43006, 0, 8802, 113777, 0, 0, 0, 0, 126632, 0, - 41757, 0, 100657, 44000, 0, 0, 43534, 0, 0, 11961, 121316, 0, 0, 0, - 128736, 0, 0, 9499, 73522, 128330, 0, 0, 92260, 68184, 0, 0, 7256, 66993, - 983180, 0, 42161, 0, 119126, 128022, 65880, 0, 10802, 64861, 0, 0, 0, 0, - 0, 0, 73109, 0, 955, 0, 0, 5350, 64339, 0, 100705, 10875, 0, 5477, 73121, - 0, 0, 0, 67693, 69790, 0, 0, 3874, 0, 983741, 0, 0, 83272, 100674, - 127397, 0, 100989, 0, 41038, 67502, 9207, 42239, 0, 0, 0, 0, 74432, 0, 0, - 1455, 129680, 0, 11753, 119233, 0, 118594, 127854, 100716, 69801, 0, 0, - 43520, 0, 119556, 0, 0, 0, 0, 100733, 10788, 6088, 0, 129587, 190, - 983346, 12593, 100737, 129308, 64408, 0, 4417, 128615, 74359, 41744, 0, - 0, 100435, 6965, 0, 0, 13201, 100430, 69896, 78868, 74382, 11841, 7918, - 92721, 0, 0, 0, 1728, 0, 0, 0, 983350, 92679, 0, 0, 92711, 0, 0, 119536, - 73491, 66679, 8382, 0, 0, 100381, 0, 917889, 42254, 68371, 100383, 0, 0, - 0, 9923, 0, 0, 11763, 100386, 120688, 0, 78187, 0, 0, 0, 0, 8333, 0, 0, - 0, 917805, 74464, 0, 92320, 74080, 0, 69911, 11910, 0, 74141, 8963, 0, 0, - 0, 121396, 0, 41747, 0, 0, 8968, 0, 0, 129110, 110590, 0, 8836, 12315, 0, - 8300, 0, 0, 0, 8856, 0, 0, 69891, 0, 66965, 120405, 120402, 120403, - 120400, 120401, 12853, 43269, 7263, 120244, 6536, 120238, 120239, 65516, - 12321, 120391, 120388, 55287, 2237, 120246, 9588, 120248, 120382, 120383, - 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, 110583, 0, 0, 0, 128689, - 5006, 64328, 68219, 917894, 0, 8825, 122972, 0, 0, 0, 128616, 0, 119177, - 0, 0, 128641, 120225, 71366, 120227, 120228, 438, 4510, 41707, 8721, - 120233, 120234, 120235, 12840, 120229, 10845, 120231, 8096, 0, 120935, 0, - 0, 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, 11262, 73747, 128522, 917902, - 64591, 42405, 0, 0, 1632, 127982, 128326, 0, 0, 121327, 121477, 42444, 0, - 0, 215, 41258, 128494, 64494, 1953, 10185, 0, 1256, 3910, 41260, 917903, - 0, 0, 41257, 0, 8675, 10700, 0, 124951, 0, 9333, 0, 121471, 0, 0, 0, 0, - 0, 499, 0, 70729, 42915, 0, 101000, 0, 100999, 0, 0, 73111, 128893, - 122897, 0, 125006, 0, 11118, 0, 128009, 0, 0, 118633, 9180, 0, 0, 0, - 100986, 43438, 118588, 0, 0, 0, 0, 120669, 64782, 0, 0, 73969, 565, - 42484, 118913, 201, 0, 42292, 69610, 0, 0, 119625, 43518, 0, 0, 1022, - 113788, 3880, 74247, 0, 0, 0, 0, 0, 0, 0, 0, 72272, 100997, 0, 0, 66937, - 74255, 0, 0, 92598, 0, 9903, 118993, 0, 68226, 0, 0, 0, 127788, 100955, - 83280, 7892, 0, 10777, 0, 0, 65562, 0, 101002, 0, 8039, 3363, 101009, 0, - 0, 66940, 12596, 70812, 0, 0, 0, 0, 42944, 92425, 74992, 64541, 0, 0, - 10520, 12802, 0, 12998, 0, 83270, 42861, 83273, 11415, 0, 7541, 125068, - 65878, 822, 0, 0, 5774, 194746, 43252, 0, 92619, 7672, 129281, 0, 0, - 7463, 0, 0, 0, 0, 0, 0, 121411, 0, 0, 0, 66938, 0, 475, 0, 120586, 7329, - 0, 0, 195088, 66291, 10645, 0, 6543, 100966, 0, 0, 119065, 0, 0, 0, - 983237, 195095, 0, 8923, 1645, 0, 0, 0, 3196, 72404, 0, 0, 43595, 0, 0, - 0, 0, 0, 195076, 0, 0, 5258, 4328, 0, 0, 0, 405, 11454, 0, 0, 0, 0, - 75052, 41245, 0, 195078, 4523, 11369, 0, 0, 0, 195079, 0, 0, 983510, 0, - 100961, 10480, 74610, 0, 0, 0, 12610, 0, 41247, 0, 7609, 118837, 0, 0, - 92253, 0, 984, 0, 92621, 0, 0, 129885, 73982, 0, 0, 0, 43369, 0, 0, 0, - 983507, 6634, 0, 71952, 0, 66930, 74214, 0, 67709, 0, 0, 0, 71114, 9552, - 0, 0, 0, 12997, 0, 0, 0, 0, 129109, 12883, 10994, 10529, 55283, 0, 74618, - 0, 67736, 10661, 19951, 9614, 2428, 0, 121023, 92837, 126224, 66933, - 71127, 0, 124996, 119162, 1952, 92181, 8455, 100958, 118654, 93033, - 119566, 100960, 0, 12183, 100951, 0, 64929, 0, 0, 0, 128290, 42509, - 73087, 3922, 9187, 983626, 0, 0, 119057, 0, 3353, 9358, 0, 0, 66680, 0, - 73975, 12879, 0, 9795, 68380, 0, 0, 119488, 0, 0, 41027, 0, 66931, 0, - 983631, 0, 70378, 0, 11751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129356, 0, 0, - 0, 0, 41029, 0, 126513, 0, 0, 0, 11294, 0, 66665, 0, 0, 127750, 0, 0, - 70105, 0, 983643, 0, 67843, 0, 0, 121167, 983895, 0, 8088, 129412, 0, 0, - 0, 983992, 6926, 72423, 0, 129569, 42369, 4350, 0, 65145, 9041, 43559, 0, - 0, 0, 41263, 0, 0, 0, 65825, 9577, 68199, 0, 0, 983122, 0, 6793, 0, - 70409, 0, 0, 0, 0, 64669, 0, 0, 0, 11200, 72725, 2995, 0, 0, 0, 7868, - 72720, 72020, 11386, 1009, 70405, 66871, 2333, 0, 0, 0, 0, 0, 70407, - 128121, 0, 0, 0, 0, 983657, 66949, 0, 74968, 0, 0, 110601, 0, 0, 41261, - 0, 0, 0, 0, 118989, 6736, 917883, 124132, 43010, 66952, 0, 69635, 73011, - 983716, 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, - 42655, 0, 0, 1577, 11772, 78327, 0, 66673, 0, 65911, 118705, 0, 0, - 101303, 92180, 0, 0, 120566, 125140, 127177, 0, 0, 119593, 1539, 0, - 74969, 42731, 0, 74970, 71066, 0, 3051, 0, 73783, 0, 0, 0, 0, 78777, 0, - 983161, 0, 0, 101310, 0, 0, 0, 0, 0, 0, 3505, 8707, 0, 6725, 128013, 0, - 92314, 0, 66391, 5479, 0, 6686, 0, 0, 983318, 42754, 0, 0, 0, 0, 0, 0, - 128523, 0, 0, 4433, 41156, 0, 74971, 1443, 9339, 0, 92871, 10926, 0, - 43511, 0, 0, 983324, 0, 126086, 72236, 10021, 0, 101329, 0, 65914, 0, - 66749, 0, 6721, 217, 12466, 0, 0, 10443, 0, 68654, 0, 0, 0, 78334, 0, - 41250, 0, 129532, 128375, 0, 0, 69232, 0, 41252, 66682, 0, 119637, 41249, - 1366, 0, 0, 101326, 0, 0, 4397, 101324, 0, 66946, 9545, 101323, 0, 0, 0, - 3511, 0, 92190, 0, 0, 126244, 760, 0, 12088, 0, 0, 42256, 0, 0, 417, 0, - 111347, 41565, 74965, 0, 111355, 0, 0, 0, 2284, 0, 0, 11311, 0, 0, 0, 0, - 0, 0, 42273, 0, 69430, 121041, 0, 126643, 0, 65910, 0, 10246, 0, 68224, - 12169, 128858, 4552, 0, 0, 0, 1375, 66705, 128412, 0, 3329, 0, 42811, - 74251, 74192, 120794, 7840, 0, 0, 65374, 0, 0, 71072, 0, 4396, 0, 126608, - 0, 10331, 125224, 0, 11543, 0, 8944, 0, 0, 0, 0, 0, 19965, 43025, 10299, - 128436, 68845, 0, 69724, 67412, 92952, 0, 43811, 0, 128924, 0, 11062, - 128748, 0, 0, 0, 69276, 2901, 7865, 66945, 78354, 0, 78347, 0, 126123, 0, - 66363, 0, 0, 0, 74967, 7414, 0, 0, 92691, 0, 128507, 885, 64772, 65180, - 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, 67809, 9609, 12156, 0, - 122930, 43586, 11035, 10411, 0, 13268, 6710, 0, 0, 0, 43853, 77949, 4315, - 0, 111104, 0, 43639, 43343, 0, 0, 0, 73074, 0, 65812, 43431, 0, 0, 0, 0, - 0, 129890, 0, 0, 0, 0, 994, 125222, 127104, 127103, 73966, 66890, 0, - 65291, 70753, 0, 0, 0, 0, 66873, 4186, 92531, 127106, 127105, 6718, 7330, - 4406, 122946, 8480, 7319, 64373, 128699, 4413, 0, 0, 3198, 0, 0, 92469, - 111126, 0, 128591, 128681, 0, 0, 0, 101321, 73023, 742, 0, 2893, 78738, - 0, 0, 0, 2553, 42294, 6756, 0, 73020, 8363, 0, 2993, 128381, 3916, 4301, - 0, 1141, 42407, 0, 0, 7572, 973, 0, 125077, 0, 2415, 0, 0, 9640, 42333, - 0, 0, 129546, 42486, 43381, 65390, 0, 69434, 1202, 0, 0, 0, 0, 68484, 0, - 0, 64542, 3260, 0, 65388, 43502, 69904, 0, 6738, 0, 0, 74193, 0, 0, 0, - 74641, 6312, 0, 74556, 12446, 0, 0, 128076, 8229, 1235, 0, 11472, 83064, - 0, 0, 101366, 0, 0, 1740, 12872, 0, 985, 0, 0, 0, 12068, 983658, 0, - 101363, 0, 0, 0, 13133, 65071, 110780, 12655, 12134, 0, 92934, 0, 66915, - 120349, 119572, 0, 93030, 41572, 0, 0, 0, 41573, 0, 3931, 0, 74143, 2251, - 127034, 0, 0, 0, 0, 83067, 0, 129303, 0, 0, 0, 0, 0, 0, 83068, 0, 72740, - 128637, 72717, 92935, 120291, 0, 1780, 6936, 0, 0, 819, 0, 9694, 125228, - 0, 0, 0, 0, 8343, 8342, 8345, 8344, 8346, 8338, 7523, 6922, 8348, 8347, - 7525, 3346, 8339, 125004, 72705, 69462, 268, 0, 0, 5754, 94019, 0, - 110684, 8336, 0, 0, 0, 8337, 8341, 0, 11388, 7522, 0, 0, 0, 11090, 6953, - 125240, 0, 74973, 120708, 0, 0, 0, 0, 0, 110782, 0, 9038, 7887, 0, 0, - 42534, 64347, 0, 0, 67660, 120341, 0, 122933, 0, 120878, 0, 0, 73999, 0, - 64580, 0, 0, 64643, 0, 0, 74975, 0, 92227, 129052, 0, 83071, 83072, - 83073, 119154, 0, 119153, 0, 0, 5349, 72440, 2160, 917554, 7411, 0, - 983224, 0, 0, 0, 42736, 70747, 5756, 983229, 92946, 0, 42764, 0, 0, - 119529, 5752, 120600, 0, 0, 0, 0, 0, 78893, 0, 0, 0, 125242, 0, 0, - 120331, 122957, 0, 0, 67501, 0, 10080, 83056, 12647, 0, 0, 69252, 66882, - 0, 0, 0, 0, 0, 72005, 72845, 0, 0, 0, 0, 0, 74213, 0, 0, 0, 0, 0, 6302, - 0, 0, 0, 0, 1417, 983226, 0, 9452, 0, 74393, 0, 0, 110850, 0, 65391, - 63789, 69251, 78659, 78660, 41264, 78658, 6426, 42398, 9179, 78654, - 64906, 41255, 42036, 0, 41269, 0, 41267, 42436, 67759, 42323, 42034, 0, - 0, 42475, 42033, 0, 0, 68916, 43948, 0, 78673, 78674, 1659, 919, 42784, - 1671, 0, 6069, 9219, 0, 1661, 71489, 0, 92690, 10140, 9713, 78400, - 119143, 125236, 0, 2306, 0, 0, 6068, 10612, 0, 0, 121314, 92561, 41462, - 0, 0, 0, 0, 0, 0, 0, 128204, 10635, 0, 983225, 0, 0, 0, 983235, 92251, 0, - 121029, 983227, 0, 8100, 0, 78669, 78670, 13301, 78667, 9667, 78665, 0, - 0, 11003, 9904, 0, 0, 0, 0, 0, 0, 78680, 78681, 78677, 78678, 0, 10313, - 0, 0, 64320, 10265, 78686, 129404, 78684, 78685, 8945, 78683, 70750, 41, - 0, 0, 0, 0, 8655, 0, 0, 71333, 0, 0, 0, 0, 2585, 0, 65254, 3126, 0, - 74136, 10957, 0, 11160, 0, 0, 0, 0, 0, 11408, 0, 7443, 0, 0, 6997, 68004, - 0, 0, 8739, 11075, 0, 65216, 0, 69795, 2593, 0, 0, 0, 0, 125062, 0, 0, 0, - 4411, 0, 72837, 0, 43442, 78799, 0, 0, 0, 66351, 0, 0, 13061, 0, 78687, - 78688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119925, 0, 983637, 0, 0, 0, - 71494, 83399, 127541, 83398, 8022, 78808, 0, 73794, 0, 0, 83414, 119916, - 0, 0, 0, 0, 0, 0, 63799, 78427, 12063, 78425, 78424, 0, 0, 0, 75025, 0, - 297, 0, 0, 68326, 0, 78429, 78428, 7077, 2497, 128651, 0, 983112, 0, 0, - 0, 4292, 0, 74815, 10512, 0, 74814, 119931, 0, 72841, 2503, 65070, 1762, - 69794, 2495, 0, 71230, 94069, 77984, 0, 12654, 0, 1899, 0, 2507, 0, 8726, - 0, 65594, 0, 71272, 8892, 0, 0, 0, 0, 0, 420, 0, 0, 125130, 10797, 74637, - 0, 0, 0, 0, 63796, 0, 66581, 0, 119205, 0, 0, 194840, 0, 120788, 92817, - 0, 92956, 0, 0, 0, 0, 119230, 0, 0, 83496, 7399, 0, 66434, 42779, 0, - 92220, 42197, 92543, 5380, 0, 0, 1155, 11365, 43126, 0, 77971, 65684, 0, - 5601, 0, 42765, 78258, 0, 7987, 72843, 0, 69799, 6857, 0, 78735, 119165, - 0, 0, 4473, 0, 72426, 0, 65347, 65346, 65345, 0, 127384, 0, 69802, 0, - 73868, 0, 64826, 0, 0, 0, 0, 6218, 78422, 69676, 4555, 0, 83459, 70071, - 128670, 65190, 0, 0, 65244, 0, 0, 42519, 74472, 0, 0, 83466, 0, 0, 0, - 83468, 92581, 0, 0, 65370, 65369, 65368, 65367, 65366, 65365, 41086, - 65363, 65362, 65361, 65360, 43410, 11323, 65357, 65356, 65355, 5345, - 65353, 65352, 65351, 761, 65349, 19959, 69718, 0, 0, 0, 0, 64647, 0, 0, - 4699, 126077, 0, 129940, 0, 0, 0, 68074, 0, 0, 0, 128347, 0, 72829, 0, - 69773, 121438, 0, 0, 0, 73980, 78255, 78254, 83453, 43157, 0, 0, 0, 7946, - 12541, 0, 74615, 69780, 0, 0, 0, 0, 9005, 1225, 0, 0, 0, 0, 68011, 8847, - 0, 0, 0, 8329, 74590, 43878, 0, 0, 0, 3127, 2595, 71040, 69766, 129188, - 0, 41089, 0, 0, 70292, 983613, 12112, 0, 74200, 0, 8764, 0, 0, 0, 67273, - 67272, 67271, 71044, 0, 0, 0, 71042, 67266, 67265, 0, 67270, 67269, - 67268, 67267, 67282, 67281, 67280, 3572, 10023, 4959, 0, 0, 67275, 9729, - 125110, 0, 67278, 67277, 0, 67276, 0, 7996, 9907, 0, 13304, 83392, 0, - 72830, 0, 11095, 11100, 0, 83358, 83387, 10142, 0, 0, 0, 0, 68022, 0, - 83363, 128292, 19955, 0, 83366, 69807, 125246, 70124, 0, 72230, 83373, - 83385, 0, 0, 0, 0, 68020, 0, 2239, 261, 8406, 7791, 0, 7362, 0, 10696, 0, - 0, 9838, 118920, 0, 83477, 0, 0, 0, 6437, 68830, 83476, 0, 0, 74177, 0, - 0, 67288, 67287, 0, 67286, 0, 83470, 0, 67289, 67283, 83471, 70002, 0, 0, - 0, 67285, 11499, 67297, 7816, 67295, 55247, 68015, 10929, 67298, 122640, - 68017, 9642, 10912, 0, 67293, 11387, 67291, 67290, 70792, 0, 67715, 0, 0, - 68099, 13287, 74430, 10836, 0, 75053, 69775, 0, 128746, 7450, 0, 0, - 119648, 9697, 3606, 0, 0, 0, 0, 125029, 0, 0, 121262, 0, 128873, 1389, - 128871, 0, 0, 0, 12941, 0, 83438, 121062, 0, 12301, 83440, 0, 41102, - 66604, 72025, 0, 0, 0, 66600, 523, 92642, 71100, 74436, 0, 0, 0, 8608, - 83435, 72828, 128704, 0, 127402, 11307, 66707, 67301, 67300, 67299, 0, - 67304, 67303, 0, 0, 0, 0, 122654, 5908, 0, 0, 6744, 67310, 1699, 67308, - 67307, 67314, 67313, 6306, 67311, 983209, 72150, 69862, 3766, 2389, - 67305, 74569, 6611, 65700, 0, 0, 0, 42386, 0, 0, 2599, 917972, 119131, - 119049, 65717, 0, 0, 119654, 0, 0, 73538, 74203, 3760, 1718, 68160, 0, - 3776, 7335, 0, 0, 67324, 69861, 0, 69792, 0, 0, 3778, 0, 9462, 7824, 0, - 78896, 3768, 68142, 765, 72822, 3764, 0, 0, 113822, 129667, 12947, 0, 0, - 0, 118806, 73753, 0, 0, 0, 6829, 5225, 66901, 0, 0, 0, 0, 67319, 67318, - 3162, 67316, 67323, 67322, 67321, 67320, 0, 5353, 128190, 74179, 67315, - 0, 1010, 6851, 0, 67326, 67325, 127870, 6952, 67329, 67328, 67327, 2590, - 120036, 65552, 120034, 120039, 7183, 120037, 120038, 120027, 120028, - 118536, 120026, 120031, 970, 120029, 74611, 120019, 120020, 120017, - 67330, 120023, 120024, 120021, 10961, 113693, 11148, 67486, 0, 0, 128448, - 0, 113703, 64378, 0, 0, 0, 68821, 119649, 11358, 71172, 69797, 0, 11065, - 126464, 0, 68864, 0, 5694, 120839, 66784, 0, 4325, 3047, 0, 43652, - 120962, 93029, 69764, 0, 0, 0, 0, 5431, 6652, 0, 67753, 71460, 0, 0, 0, - 1129, 65016, 0, 65900, 1986, 7846, 0, 8661, 75058, 0, 0, 3845, 0, 0, 0, - 74400, 1456, 7530, 121382, 118631, 0, 0, 0, 120016, 0, 0, 0, 917863, - 127772, 119966, 0, 11002, 7026, 8145, 68216, 0, 12138, 71464, 0, 0, 0, - 12323, 130033, 917869, 0, 0, 0, 92316, 68494, 0, 0, 129384, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 42205, 0, 236, 0, 78867, 0, 0, 113784, 0, 0, 984001, 0, - 0, 119985, 8097, 0, 0, 68012, 72820, 11194, 0, 72824, 0, 127974, 0, 0, - 110602, 129948, 10416, 68070, 3872, 127508, 0, 0, 0, 0, 2838, 917867, 0, - 917866, 119589, 0, 0, 0, 0, 11096, 83019, 10553, 83421, 0, 0, 0, 0, 0, 0, - 73742, 6436, 10096, 0, 0, 0, 113687, 0, 4463, 68018, 0, 78074, 0, 983591, - 7184, 0, 0, 0, 0, 0, 0, 93825, 12818, 12032, 0, 0, 0, 0, 10357, 121418, - 8170, 0, 8556, 0, 9659, 0, 0, 0, 9556, 0, 4503, 92700, 9647, 64004, - 78185, 0, 0, 64002, 78889, 0, 0, 118910, 0, 6438, 0, 9109, 78884, 72382, - 64599, 0, 68009, 0, 0, 2447, 129863, 72381, 0, 126545, 0, 119002, 0, 0, - 0, 19937, 0, 1322, 0, 119204, 254, 72373, 0, 69392, 42425, 0, 0, 65204, - 42312, 0, 118578, 0, 42826, 129731, 42464, 120567, 0, 67155, 74796, - 64400, 64693, 126212, 77861, 0, 0, 67154, 0, 0, 0, 68008, 11785, 0, - 119142, 41978, 0, 0, 43244, 10536, 0, 9901, 7103, 0, 7102, 71428, 120748, - 3140, 0, 0, 68007, 0, 67258, 10909, 0, 1428, 0, 67254, 67253, 7699, - 12393, 67257, 0, 67256, 67255, 0, 0, 69389, 0, 0, 0, 0, 0, 67153, 0, 0, - 127383, 69376, 64554, 0, 3878, 0, 42352, 1752, 0, 129702, 42506, 0, - 10199, 0, 983468, 125231, 0, 0, 0, 720, 0, 0, 0, 68831, 0, 1464, 128339, - 0, 7974, 0, 125017, 68082, 0, 0, 0, 0, 74787, 0, 78864, 92258, 0, 0, - 78863, 0, 1302, 66288, 0, 0, 0, 67152, 0, 983611, 983618, 0, 0, 3995, 0, - 65608, 3714, 0, 0, 67262, 67261, 67260, 67259, 43251, 67264, 67263, 0, - 120557, 92346, 8672, 68006, 11964, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92610, 0, 468, 0, 0, 0, 983475, 0, 0, 128544, 129397, 65907, 983164, 0, - 0, 0, 0, 0, 983473, 41743, 0, 0, 0, 74880, 0, 121001, 820, 41741, 0, - 120667, 0, 64684, 126992, 128604, 126082, 69934, 65177, 6226, 353, 43645, - 0, 119612, 120738, 67700, 0, 0, 0, 0, 42457, 120276, 0, 120277, 1884, - 129637, 42418, 113678, 41157, 0, 42305, 120279, 0, 0, 41151, 0, 71430, 0, - 42344, 0, 194864, 0, 42497, 0, 194870, 72754, 69933, 73703, 0, 42521, - 8539, 128606, 0, 123609, 69957, 4788, 0, 68023, 0, 0, 983053, 0, 0, 0, 0, - 41590, 118717, 113754, 0, 0, 118901, 68637, 41136, 64351, 0, 128453, - 41154, 113731, 127038, 4038, 41143, 68232, 64859, 0, 129910, 0, 5435, - 129911, 6734, 41343, 127035, 0, 0, 41359, 66761, 0, 119835, 41349, 0, - 129915, 10374, 10310, 0, 0, 10254, 119836, 10278, 10262, 69858, 41363, 0, - 0, 0, 119840, 0, 41356, 10314, 10282, 0, 10378, 0, 40976, 10266, 0, - 119848, 40975, 123547, 129554, 0, 40978, 119851, 92945, 0, 0, 0, 119098, - 119083, 0, 71437, 119854, 69936, 0, 0, 3525, 6824, 0, 0, 119858, 128451, - 0, 72239, 113738, 0, 71424, 0, 0, 0, 0, 0, 10727, 7212, 129071, 71957, 0, - 0, 0, 67156, 808, 7207, 42387, 0, 0, 0, 0, 0, 0, 0, 0, 9225, 121149, 0, - 9145, 128060, 41018, 67841, 983159, 42300, 0, 3084, 983156, 125014, - 41025, 6037, 0, 194885, 0, 10290, 0, 3083, 10322, 111017, 129030, 0, - 41036, 0, 0, 43321, 65606, 0, 41032, 42388, 0, 64700, 0, 1445, 40961, 0, - 0, 0, 40960, 0, 67727, 0, 2223, 64952, 10402, 0, 0, 0, 10603, 0, 118577, - 71438, 0, 0, 0, 128469, 0, 0, 0, 0, 0, 0, 42585, 65032, 10704, 65030, - 4787, 0, 917556, 0, 127015, 0, 128118, 0, 0, 9525, 0, 0, 68773, 0, 0, 0, - 0, 40966, 0, 0, 3998, 0, 0, 65919, 71433, 11792, 2690, 0, 42836, 127150, - 41954, 194921, 194923, 6737, 0, 64933, 126260, 3487, 194873, 71427, - 72758, 65426, 72756, 66757, 0, 0, 41976, 9720, 74964, 11179, 41970, 0, - 12116, 65024, 0, 127912, 9048, 65028, 65027, 65026, 65025, 64757, 0, - 41488, 0, 8527, 0, 126480, 0, 41480, 41053, 3266, 0, 194876, 12093, - 41466, 122881, 78642, 1519, 983925, 3638, 65887, 65429, 0, 0, 0, 0, 8633, - 0, 0, 0, 125118, 0, 70375, 0, 0, 6368, 128124, 0, 70369, 8078, 0, 0, - 70373, 72876, 0, 7002, 121003, 41430, 0, 41051, 41484, 0, 0, 41050, 8872, - 0, 13099, 71445, 70371, 0, 6435, 72154, 11362, 0, 0, 0, 0, 41420, 0, - 3625, 74915, 41409, 71441, 0, 0, 0, 9672, 0, 0, 43317, 0, 0, 0, 41424, - 917598, 0, 0, 0, 0, 41417, 1261, 0, 0, 12102, 119662, 41401, 0, 127538, - 129518, 0, 124943, 72765, 3275, 92472, 0, 0, 0, 118686, 0, 128946, 0, 0, - 125129, 983141, 10598, 0, 128633, 6711, 0, 2920, 0, 0, 0, 0, 19928, 0, 0, - 3917, 0, 113756, 0, 0, 66588, 128078, 0, 0, 113721, 113758, 983081, 0, 0, - 41184, 0, 232, 0, 0, 74170, 0, 0, 0, 0, 9094, 0, 0, 92585, 0, 1064, 0, 0, - 10115, 0, 0, 0, 7862, 0, 13224, 0, 0, 66650, 0, 0, 72877, 1878, 0, 71434, - 2911, 0, 41178, 5427, 0, 0, 0, 12617, 41174, 0, 67148, 67147, 0, 42413, - 41167, 2406, 0, 0, 0, 0, 0, 9618, 128668, 0, 0, 0, 0, 41436, 9337, - 126067, 0, 41456, 0, 119086, 11333, 0, 6703, 0, 125071, 1613, 0, 0, 0, - 983192, 0, 0, 74500, 41460, 78197, 0, 0, 194899, 67144, 65841, 0, 121109, - 74064, 111146, 111144, 120375, 0, 111122, 0, 111121, 64687, 111120, - 42592, 3871, 0, 128305, 9111, 111163, 0, 111156, 120366, 121462, 11150, - 111154, 71488, 111179, 0, 111168, 0, 120362, 41587, 70391, 0, 74322, - 110589, 194908, 111166, 111133, 0, 71443, 194842, 0, 111151, 0, 0, 7928, - 111127, 111140, 41595, 0, 0, 65801, 110587, 110586, 110585, 110584, - 73712, 0, 41598, 3993, 121269, 1545, 40971, 121286, 72874, 0, 0, 0, - 120767, 65286, 0, 0, 0, 0, 2201, 0, 0, 5402, 0, 0, 74462, 73457, 0, 0, - 78194, 64326, 40969, 0, 128110, 983703, 40968, 0, 121139, 0, 128891, 0, - 0, 128513, 8020, 0, 41012, 0, 0, 65805, 41006, 0, 0, 74605, 0, 118942, - 43432, 0, 0, 92900, 0, 0, 68671, 120687, 0, 92958, 0, 0, 68332, 0, 40992, - 0, 0, 0, 0, 0, 42235, 0, 1741, 42370, 0, 0, 0, 11413, 126583, 0, 0, - 128769, 6470, 0, 74517, 0, 0, 120651, 40984, 0, 42742, 0, 12916, 6284, 0, - 41663, 0, 0, 68313, 72840, 70164, 41648, 0, 0, 2299, 41666, 0, 0, 2056, - 41656, 0, 0, 71917, 42219, 0, 0, 78112, 41676, 0, 0, 0, 41670, 0, 92590, - 2796, 0, 0, 9902, 0, 67988, 64785, 82995, 128822, 42631, 983040, 71890, - 0, 74164, 41238, 10049, 11405, 0, 64368, 0, 120925, 0, 397, 12299, 42139, - 0, 9590, 0, 0, 43661, 43819, 0, 6651, 3544, 0, 0, 9620, 0, 0, 0, 92229, - 1333, 7104, 0, 6425, 0, 0, 123561, 0, 0, 129725, 11976, 8554, 13055, 0, - 110733, 0, 110731, 41218, 0, 0, 128673, 1883, 0, 0, 70443, 41225, 70788, - 42419, 983707, 129450, 0, 127896, 0, 65809, 11837, 0, 129104, 7141, 0, 0, - 0, 0, 0, 42363, 0, 0, 0, 0, 69949, 119157, 64732, 0, 0, 126983, 0, 0, - 983697, 7140, 42051, 0, 4164, 118799, 0, 120569, 42049, 42042, 0, 0, 0, - 120637, 69938, 0, 42047, 0, 0, 8470, 11807, 128935, 0, 0, 194825, 74300, - 126267, 0, 120517, 68128, 0, 0, 0, 8736, 0, 42643, 72753, 129925, 0, 0, - 71432, 0, 93023, 110730, 72869, 110728, 0, 0, 0, 0, 68445, 0, 0, 2106, 0, - 11273, 120986, 43004, 0, 82988, 0, 961, 64307, 0, 0, 129752, 67711, - 110615, 0, 1696, 0, 9762, 12105, 0, 110622, 110623, 3264, 110621, 110618, - 43003, 110616, 110617, 0, 120359, 0, 128660, 0, 2322, 0, 70831, 11449, - 128187, 42868, 0, 0, 0, 0, 113746, 983238, 0, 129583, 66398, 0, 0, 0, 0, - 0, 69494, 119224, 0, 0, 64421, 0, 113739, 0, 65823, 0, 11182, 0, 0, 0, - 7766, 55268, 0, 4598, 0, 65839, 0, 0, 3315, 10851, 0, 6179, 92602, 6180, - 129524, 11952, 0, 78648, 78651, 78646, 78647, 78644, 78645, 3801, 78643, - 6176, 120580, 0, 0, 6177, 0, 78652, 78653, 6178, 0, 0, 0, 0, 2214, 8754, - 0, 0, 2137, 0, 0, 0, 0, 66889, 0, 0, 0, 8974, 2308, 0, 74579, 0, 2318, - 122920, 0, 8198, 0, 0, 0, 74307, 0, 119524, 0, 0, 6970, 0, 0, 0, 41159, - 0, 120363, 6385, 0, 128403, 0, 0, 126258, 0, 72785, 42053, 2075, 42057, - 0, 42052, 0, 0, 67651, 0, 9665, 0, 0, 13181, 0, 0, 69379, 0, 0, 0, 0, - 73010, 0, 0, 0, 41145, 0, 0, 0, 41148, 0, 7594, 113686, 75033, 119090, - 10869, 43458, 41146, 0, 0, 121456, 917630, 0, 0, 0, 0, 0, 65184, 11780, - 0, 42796, 0, 69742, 0, 65146, 66803, 0, 0, 0, 7358, 78241, 0, 7988, - 101371, 101370, 3271, 101372, 0, 69281, 0, 0, 0, 101369, 13070, 113736, - 42044, 101365, 1095, 101367, 3599, 101361, 101364, 101157, 129087, 66390, - 101360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42043, 43232, 67656, 121014, 42046, - 64355, 4036, 123601, 0, 0, 983062, 0, 11954, 0, 41191, 12986, 0, 194854, - 65441, 0, 72202, 0, 129338, 0, 101353, 101352, 12834, 0, 101349, 101348, - 101351, 72858, 101345, 101344, 41190, 101346, 129693, 4575, 41193, 0, - 429, 119174, 124931, 194859, 0, 65792, 128754, 78509, 0, 128866, 0, 0, 0, - 66786, 0, 194862, 10590, 0, 0, 0, 0, 0, 0, 6247, 10214, 65126, 68253, 0, - 0, 0, 983699, 1617, 8050, 0, 0, 0, 101358, 101357, 0, 101359, 101354, 0, - 101356, 6352, 0, 0, 0, 0, 0, 0, 0, 0, 92335, 0, 0, 42926, 0, 0, 0, 8689, - 78750, 70067, 42896, 74147, 3559, 101327, 0, 74526, 65850, 12327, 72763, - 101325, 0, 0, 72761, 0, 78903, 0, 0, 0, 0, 70079, 72751, 0, 12153, - 101340, 101343, 101342, 71940, 0, 101339, 101338, 0, 0, 681, 129406, 703, - 101335, 3272, 101337, 101332, 70077, 101334, 101333, 70514, 78902, 92532, - 71436, 42238, 124930, 3276, 0, 101311, 65928, 0, 0, 101307, 101306, - 101309, 101308, 78813, 78814, 3262, 78811, 42711, 101305, 0, 0, 101302, - 92746, 9995, 1655, 70131, 78818, 78815, 12479, 0, 0, 101296, 70513, - 42797, 0, 0, 128371, 43112, 101318, 43488, 101320, 101315, 101314, 42684, - 101316, 0, 0, 101313, 101312, 128308, 0, 0, 0, 0, 0, 0, 11031, 0, 0, 0, - 70386, 10348, 10412, 0, 0, 74329, 0, 0, 122647, 101285, 101284, 101287, - 101286, 8810, 101280, 686, 101282, 0, 0, 0, 0, 110709, 0, 0, 12040, 0, 0, - 65118, 110704, 0, 118891, 110599, 0, 110598, 0, 120543, 983679, 0, 65455, - 74413, 94097, 0, 119129, 0, 0, 0, 78776, 0, 64467, 10300, 10161, 10396, - 0, 0, 0, 0, 78773, 101294, 101293, 0, 1458, 101290, 0, 72429, 65120, - 11479, 0, 0, 6350, 101289, 101288, 71473, 1061, 69787, 9115, 43111, 0, 0, - 0, 0, 983979, 0, 120907, 1045, 0, 73913, 983564, 0, 0, 0, 0, 0, 0, 8486, - 0, 0, 0, 4362, 0, 0, 93054, 1025, 0, 0, 0, 0, 0, 92328, 128206, 0, 1774, - 0, 122913, 0, 0, 0, 11207, 0, 0, 3988, 0, 0, 983048, 0, 0, 8564, 983977, - 0, 0, 0, 0, 0, 0, 66513, 6256, 0, 579, 55218, 0, 0, 0, 127337, 0, 11814, - 0, 4488, 128716, 127336, 0, 10444, 118846, 78238, 0, 0, 127331, 4487, - 127849, 42832, 1032, 0, 43450, 0, 70155, 0, 614, 0, 127325, 0, 0, 128466, - 0, 127321, 0, 127322, 0, 0, 0, 1050, 7549, 127319, 0, 9314, 0, 0, 0, 0, - 0, 70434, 127314, 12527, 66504, 0, 0, 0, 0, 64333, 127312, 128547, 92594, - 0, 0, 0, 129316, 0, 124960, 10360, 6746, 0, 0, 0, 0, 13085, 9233, 0, 0, - 0, 0, 983474, 0, 92766, 0, 121114, 983944, 74212, 42819, 10910, 118627, - 68044, 9896, 0, 0, 120915, 0, 0, 7970, 0, 0, 0, 0, 113699, 9849, 0, - 122910, 0, 0, 10487, 69714, 0, 10103, 0, 4769, 0, 129967, 0, 2283, 0, 0, - 74785, 0, 0, 0, 110595, 110596, 0, 110594, 64565, 4773, 0, 0, 0, 4770, 0, - 0, 0, 65457, 69441, 0, 0, 127338, 983593, 4774, 0, 68497, 2259, 0, 0, - 10215, 0, 0, 0, 0, 0, 74776, 92160, 4768, 0, 0, 4099, 0, 110699, 110700, - 110697, 2225, 0, 0, 0, 41183, 125217, 11255, 42814, 880, 0, 0, 0, 0, 0, - 67756, 65246, 0, 0, 129463, 7095, 0, 0, 0, 0, 0, 0, 2427, 0, 7093, 0, - 11585, 0, 9962, 0, 12223, 0, 78211, 1434, 42939, 0, 11573, 0, 0, 0, - 121257, 0, 0, 0, 0, 74437, 0, 113711, 917596, 0, 8740, 0, 3782, 64331, 0, - 65167, 1014, 0, 0, 0, 10835, 129987, 0, 0, 0, 0, 0, 118824, 7302, 0, - 67707, 0, 1150, 10547, 0, 0, 68427, 0, 0, 0, 0, 118788, 0, 0, 0, 42257, - 8010, 0, 0, 0, 9643, 0, 0, 12864, 0, 0, 0, 0, 0, 0, 0, 0, 1426, 68217, 0, - 68447, 129971, 0, 0, 0, 73701, 0, 0, 0, 65383, 0, 0, 0, 0, 0, 0, 43196, - 43194, 92549, 10744, 0, 990, 93772, 0, 0, 0, 0, 0, 66470, 0, 0, 0, 3945, - 0, 0, 0, 130039, 0, 127546, 127746, 1020, 73763, 92257, 118669, 0, 64748, - 0, 0, 10205, 0, 0, 10016, 0, 74051, 0, 43242, 125096, 2667, 0, 125037, 0, - 9911, 0, 0, 10097, 0, 0, 0, 118836, 0, 0, 0, 0, 68889, 10159, 113759, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 983343, 92291, 0, 127973, 72882, 0, 1041, 127182, - 6354, 0, 65364, 0, 0, 0, 72884, 0, 128477, 0, 65906, 127819, 72883, 0, - 128470, 5375, 72881, 0, 8215, 0, 10074, 0, 0, 0, 69899, 0, 0, 121426, - 41382, 0, 0, 5173, 65348, 527, 0, 0, 0, 128250, 0, 0, 0, 0, 0, 0, 42695, - 0, 42250, 0, 11187, 113695, 0, 1568, 66806, 0, 0, 113705, 0, 0, 129487, - 0, 0, 128839, 9069, 6144, 0, 0, 0, 0, 66783, 0, 74027, 118934, 66787, - 74580, 0, 110790, 6364, 0, 66794, 43508, 0, 92612, 0, 0, 0, 0, 128405, - 66449, 0, 0, 0, 0, 70714, 0, 70716, 0, 1044, 42411, 0, 0, 0, 0, 43239, 0, - 0, 0, 118572, 42450, 0, 0, 68479, 119237, 0, 0, 0, 0, 0, 69956, 11537, 0, - 121206, 0, 0, 0, 0, 1057, 566, 0, 0, 10907, 42274, 43464, 0, 118698, 0, - 78472, 71207, 42636, 0, 123603, 0, 0, 121171, 64659, 0, 127749, 0, 6357, - 6362, 0, 0, 2216, 9090, 0, 0, 0, 0, 68227, 0, 0, 0, 0, 1053, 12830, 0, 0, - 0, 1052, 1051, 459, 1060, 0, 66479, 0, 0, 0, 128061, 42490, 689, 6508, - 4163, 42298, 8639, 983338, 4246, 0, 43514, 42362, 0, 42337, 64596, 0, 0, - 0, 0, 0, 6359, 0, 43471, 0, 0, 0, 127274, 0, 6358, 6361, 1926, 6356, 0, - 7898, 0, 10935, 0, 127972, 121285, 0, 43685, 0, 0, 42910, 0, 8693, 0, 0, - 44010, 0, 120991, 121454, 0, 0, 0, 0, 129514, 0, 0, 0, 0, 73947, 0, - 129361, 92412, 0, 66477, 0, 0, 0, 43854, 71913, 0, 0, 0, 0, 72227, 65899, - 92275, 0, 0, 0, 68887, 0, 71057, 0, 0, 0, 0, 119183, 2923, 10853, 0, 0, - 0, 0, 72864, 0, 72773, 72772, 0, 120801, 65251, 122624, 68228, 0, 128548, - 0, 0, 5370, 70465, 2931, 73848, 0, 10188, 0, 118848, 0, 983942, 0, 0, - 120584, 72212, 0, 10844, 121016, 128195, 92424, 0, 0, 0, 286, 0, 1062, 0, - 0, 124127, 7395, 0, 1070, 128993, 0, 6095, 0, 0, 0, 127796, 126465, - 64497, 0, 0, 0, 0, 70054, 8189, 78272, 0, 0, 0, 0, 0, 113783, 42102, - 78276, 0, 0, 42101, 0, 78402, 67427, 33, 67425, 67424, 10824, 67430, - 67429, 67428, 427, 64723, 0, 0, 0, 0, 1031, 0, 0, 42104, 0, 0, 2328, 0, - 1071, 42899, 128486, 0, 7673, 0, 0, 1047, 194837, 0, 42908, 0, 0, 10651, - 0, 0, 0, 72433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13216, 0, 69716, 0, - 0, 0, 0, 0, 92411, 69654, 0, 0, 129904, 2761, 129909, 0, 0, 0, 0, 8643, - 0, 0, 94021, 2757, 11067, 0, 74498, 8910, 10689, 0, 0, 0, 71173, 0, 9196, - 71214, 0, 0, 0, 0, 118911, 0, 0, 0, 0, 0, 0, 0, 0, 68130, 119616, 0, 0, - 42477, 67482, 0, 4495, 0, 0, 0, 0, 70080, 10992, 0, 0, 0, 0, 9318, 0, - 6002, 0, 73808, 0, 92601, 42249, 7639, 43995, 0, 0, 5454, 0, 0, 0, 0, 0, - 0, 0, 121189, 0, 119173, 0, 9704, 120686, 0, 78436, 78435, 11204, 0, 0, - 1731, 0, 92937, 0, 67990, 0, 0, 0, 126576, 127018, 71951, 55265, 0, 0, 0, - 0, 127257, 73826, 0, 3840, 0, 41432, 0, 0, 68430, 0, 43253, 128284, 0, - 3371, 92936, 0, 0, 1479, 69282, 0, 1109, 77997, 0, 129154, 0, 92782, 0, - 0, 8868, 399, 67978, 74842, 0, 0, 194839, 73498, 551, 0, 10156, 0, 92572, - 0, 2544, 65074, 0, 0, 0, 0, 0, 0, 0, 128713, 0, 0, 74268, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 68045, 0, 0, 0, 3447, 0, 0, 121414, 2549, 110818, 0, 0, - 43564, 8946, 0, 74411, 66864, 0, 70480, 7980, 0, 113698, 0, 119653, - 66489, 0, 64695, 128063, 0, 0, 0, 0, 0, 0, 43452, 0, 92993, 0, 10919, 0, - 67810, 0, 0, 0, 0, 6450, 10055, 0, 0, 0, 0, 42720, 0, 9626, 0, 128055, - 74447, 0, 125127, 92573, 0, 0, 0, 119075, 0, 0, 66486, 0, 0, 0, 0, 0, 0, - 75028, 983883, 74839, 0, 0, 0, 0, 0, 55286, 0, 1055, 917628, 0, 0, 0, - 70516, 12146, 118623, 73956, 66488, 0, 0, 0, 0, 0, 0, 42518, 0, 0, 0, - 7407, 74978, 0, 0, 0, 0, 0, 0, 0, 10231, 0, 66626, 0, 0, 92951, 0, 65927, - 0, 0, 69696, 0, 92389, 0, 0, 0, 68095, 92950, 0, 10555, 0, 0, 9091, - 10798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43222, 0, 74982, 0, 0, 120952, 0, 0, - 2992, 7826, 74321, 110879, 125103, 74981, 92628, 0, 129903, 128289, - 128203, 4361, 129597, 1306, 78770, 1497, 983628, 0, 0, 0, 8248, 0, - 127253, 7973, 128706, 0, 0, 73122, 983949, 0, 0, 2963, 120653, 0, 128554, - 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, 125008, 42625, 0, 72022, 0, 0, - 64905, 0, 9512, 0, 119076, 6443, 983267, 0, 9135, 0, 0, 123202, 0, 0, - 983882, 93788, 0, 0, 0, 93767, 64256, 0, 11669, 0, 0, 4524, 0, 129182, - 128390, 0, 74266, 0, 0, 0, 70119, 78410, 69809, 121031, 55219, 69815, - 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2986, 0, 93763, 3437, 0, 6203, - 4247, 0, 11920, 8274, 68240, 129694, 1657, 0, 121276, 122951, 0, 2954, - 43506, 42837, 0, 0, 71179, 0, 0, 0, 66476, 68450, 0, 0, 0, 43362, 983135, - 129596, 11705, 0, 0, 0, 127354, 0, 11710, 0, 0, 0, 119507, 74429, 0, 0, - 1058, 129555, 0, 0, 5484, 1144, 0, 0, 0, 0, 0, 118972, 0, 65322, 0, 6441, - 0, 0, 2547, 66484, 43634, 0, 5871, 0, 0, 0, 0, 0, 0, 71204, 0, 0, 1865, - 0, 0, 69950, 0, 93021, 73713, 0, 71199, 65826, 2069, 0, 119092, 43999, - 2997, 0, 126588, 0, 65319, 0, 12316, 0, 0, 123630, 8776, 0, 0, 66294, - 13130, 0, 71191, 126625, 0, 10030, 11709, 12364, 983853, 0, 11704, 0, - 118641, 68672, 0, 0, 0, 0, 11706, 9710, 0, 82985, 0, 413, 65623, 0, 0, - 93980, 74446, 0, 1042, 0, 128378, 12171, 119240, 0, 69384, 4984, 0, 708, - 11391, 0, 0, 0, 983930, 1308, 0, 3673, 810, 0, 120933, 118567, 0, 0, - 1917, 3000, 0, 0, 0, 65628, 66387, 74470, 0, 0, 0, 10027, 0, 0, 0, 0, - 128831, 983168, 2980, 755, 0, 0, 65622, 0, 121012, 7277, 121022, 0, 0, 0, - 0, 8730, 0, 0, 0, 7274, 119250, 0, 7275, 0, 935, 0, 0, 377, 42325, - 121103, 0, 101133, 101132, 101135, 101134, 0, 74911, 2417, 101130, 0, - 19912, 0, 0, 101128, 101127, 0, 101129, 101124, 7248, 101126, 101125, - 1781, 5496, 3627, 62, 1649, 0, 964, 0, 0, 0, 0, 92897, 0, 0, 127364, 0, - 43689, 127911, 66287, 78812, 64389, 66575, 0, 73041, 0, 129687, 0, 7677, - 2991, 3293, 0, 0, 0, 72201, 0, 11341, 127049, 0, 65625, 9714, 11692, 0, - 0, 120850, 6478, 10195, 43673, 65237, 6241, 0, 0, 0, 6238, 0, 129889, 0, - 4409, 0, 0, 67170, 0, 0, 0, 94047, 6237, 5461, 66851, 9176, 92882, - 121341, 65231, 0, 0, 121182, 110581, 0, 44018, 0, 64765, 0, 0, 0, 5685, - 0, 2461, 0, 7091, 0, 0, 0, 68163, 0, 73030, 0, 0, 73928, 0, 0, 0, 0, 0, - 0, 110582, 0, 0, 68506, 0, 0, 0, 0, 0, 2542, 0, 0, 0, 128176, 5776, 0, 0, - 0, 0, 0, 11987, 0, 0, 75036, 68744, 0, 0, 10039, 42828, 0, 0, 0, 0, 0, - 10721, 67664, 43433, 0, 0, 41875, 0, 41870, 266, 129066, 0, 41873, 71271, - 0, 0, 0, 0, 0, 0, 41871, 66186, 3734, 7734, 43683, 8750, 110600, 66011, - 92899, 0, 127937, 0, 0, 10572, 0, 42906, 0, 64349, 7287, 0, 0, 0, 0, - 11167, 69220, 0, 43429, 0, 1697, 0, 0, 68633, 7286, 0, 128738, 10031, - 78754, 0, 68645, 8620, 0, 42162, 0, 0, 7285, 0, 119577, 0, 66842, 43677, - 41583, 0, 65799, 129332, 0, 0, 0, 0, 110806, 0, 3609, 0, 129448, 119074, - 125116, 126254, 128108, 73948, 0, 0, 0, 0, 129189, 42732, 92699, 74984, - 68620, 11691, 74985, 0, 0, 0, 0, 0, 6348, 243, 74075, 0, 0, 92309, - 123585, 0, 0, 10648, 8538, 43687, 0, 118723, 0, 70515, 0, 118954, 92886, - 13307, 129573, 92891, 0, 120770, 983850, 0, 0, 0, 0, 214, 0, 0, 0, 65893, - 0, 120488, 128386, 0, 92893, 0, 2603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 43, 0, 0, 1016, 0, 0, 0, 3885, 92, 65456, 64608, 0, 0, 0, 70656, 113742, - 0, 0, 0, 128128, 983857, 0, 0, 6791, 983861, 127960, 0, 0, 0, 118976, 0, - 7328, 92358, 0, 7995, 8759, 43421, 0, 68029, 92860, 0, 125272, 0, 3197, - 0, 0, 0, 983151, 0, 11595, 0, 0, 43435, 0, 0, 0, 0, 0, 70660, 0, 741, - 83291, 5494, 0, 70668, 1990, 11107, 4498, 0, 0, 70658, 0, 0, 2960, 73779, - 0, 8969, 101256, 43424, 0, 101257, 2950, 101251, 101254, 101253, 370, 0, - 101250, 101249, 0, 0, 0, 122967, 0, 0, 0, 122900, 0, 0, 983256, 0, 2964, - 43663, 0, 6344, 0, 0, 10144, 0, 8252, 729, 66016, 78446, 0, 0, 0, 78740, - 43669, 9032, 0, 0, 0, 0, 0, 0, 0, 0, 74612, 3761, 101261, 101260, 101263, - 101262, 0, 0, 3850, 101258, 0, 128389, 0, 0, 0, 0, 8611, 0, 0, 0, 43691, - 125032, 0, 41802, 120540, 0, 0, 0, 0, 0, 3848, 101230, 113800, 127536, - 101227, 101226, 101229, 101228, 663, 0, 0, 0, 0, 0, 0, 0, 0, 13221, 0, 0, - 101244, 101243, 101246, 101245, 0, 65579, 12980, 68046, 12143, 101069, - 128067, 0, 43441, 41804, 101241, 101240, 101235, 101234, 101237, 101236, - 66329, 0, 72324, 101232, 0, 125038, 0, 129383, 101214, 101213, 0, 101215, - 101210, 0, 101212, 101211, 0, 1097, 129033, 0, 101209, 101208, 93828, 0, - 101205, 101204, 101207, 101206, 101201, 101200, 101203, 101202, 0, 13110, - 0, 983886, 68229, 1000, 0, 0, 101222, 1209, 101224, 101223, 92354, 1073, - 6321, 77878, 92818, 0, 68213, 0, 12167, 0, 0, 0, 0, 73673, 121500, 0, - 121501, 0, 6587, 0, 0, 0, 9231, 0, 2959, 101191, 0, 101193, 101188, - 101187, 101190, 101189, 101184, 0, 101186, 42941, 0, 0, 68434, 0, 70742, - 0, 0, 12290, 0, 0, 110801, 0, 77873, 8205, 110803, 5131, 118542, 0, 0, 0, - 0, 0, 1944, 78453, 0, 0, 119990, 119991, 12701, 78492, 11308, 119995, 0, - 113702, 66836, 119999, 74263, 92382, 120002, 120003, 7075, 101196, - 101199, 101198, 41817, 73934, 42275, 101194, 120012, 120013, 120014, - 42943, 6041, 0, 41899, 0, 8002, 0, 41902, 0, 0, 64332, 0, 7813, 119117, - 0, 41900, 120633, 101167, 7281, 78455, 7279, 12041, 93027, 101165, 12673, - 0, 129123, 9660, 0, 72984, 101161, 0, 0, 0, 92901, 2970, 0, 101180, - 101179, 77870, 101181, 0, 0, 101178, 0, 0, 0, 0, 0, 3486, 101174, 69498, - 101176, 101171, 101170, 101173, 101172, 0, 69920, 101169, 66834, 0, - 984006, 0, 68312, 101150, 65673, 1019, 78495, 4148, 0, 12289, 101147, - 4316, 0, 13119, 983932, 101145, 101144, 0, 0, 101141, 101140, 43434, - 41865, 101137, 9163, 8659, 9072, 5867, 13302, 7622, 7120, 0, 0, 0, 0, - 7400, 5416, 101160, 101159, 10817, 101153, 101156, 101155, 0, 68162, - 41855, 41867, 0, 983228, 0, 11536, 71988, 0, 7115, 0, 0, 5498, 7337, - 41536, 0, 0, 92587, 7221, 8997, 0, 0, 0, 71949, 0, 0, 127814, 0, 0, 0, 0, - 0, 295, 0, 0, 0, 0, 121292, 0, 43454, 63903, 63902, 63901, 122644, 3971, - 0, 0, 2952, 0, 11038, 10901, 63900, 63899, 63898, 5198, 667, 43273, - 63887, 63886, 128458, 78521, 66830, 0, 92714, 4159, 0, 0, 63885, 63884, - 63883, 63882, 63880, 8555, 63878, 63877, 93057, 0, 0, 63881, 10746, 0, - 118983, 0, 63876, 63875, 63874, 63873, 7432, 1913, 41913, 43686, 0, - 128971, 0, 983894, 0, 446, 41911, 0, 63851, 63850, 41910, 0, 63846, 2972, - 63844, 7262, 0, 63849, 63848, 63847, 72990, 6570, 0, 7259, 63842, 4178, - 63840, 121321, 41521, 63894, 63893, 63892, 0, 0, 1105, 4180, 0, 7418, 0, - 129714, 63891, 63890, 63889, 63888, 0, 0, 0, 0, 1678, 0, 66909, 0, 0, 0, - 0, 11192, 128360, 128404, 9159, 70089, 63861, 63860, 63859, 63858, 63865, - 1615, 63863, 63862, 0, 0, 0, 0, 63857, 63856, 71902, 0, 1077, 0, 65099, - 0, 0, 0, 0, 0, 0, 42773, 121331, 0, 0, 119220, 120912, 129564, 0, 1112, - 119122, 8686, 120654, 0, 65081, 0, 0, 0, 11077, 0, 7260, 0, 5327, 0, - 63870, 63869, 3847, 63867, 0, 2903, 0, 3001, 66762, 0, 43746, 0, 63866, - 0, 0, 0, 0, 0, 127785, 68420, 2990, 0, 128254, 66957, 0, 0, 0, 1117, - 118987, 12212, 129003, 129151, 63836, 63835, 63834, 0, 0, 63839, 63838, - 63837, 0, 125095, 63833, 6042, 66360, 0, 74808, 0, 63821, 63820, 63819, - 63818, 0, 0, 9047, 63822, 128328, 6091, 0, 10691, 0, 74344, 8226, 0, - 63812, 63811, 63810, 63809, 2289, 63815, 63814, 63813, 6047, 0, 0, 780, - 63808, 77925, 77922, 65147, 63931, 63930, 2076, 1093, 9882, 63934, 2082, - 63932, 75050, 63929, 63928, 63927, 77934, 9806, 65566, 77933, 63922, - 63921, 2086, 0, 63926, 2984, 5968, 63923, 0, 0, 129458, 11137, 13169, - 5290, 2089, 0, 63827, 1088, 63825, 7268, 1084, 1085, 63829, 1083, 10131, - 7283, 0, 0, 0, 1092, 0, 7273, 983277, 44016, 43627, 0, 0, 0, 11809, 0, 0, - 0, 2965, 7258, 8808, 0, 1089, 7278, 63937, 63936, 43405, 11106, 940, - 5787, 10099, 63938, 101269, 63897, 101271, 2994, 101265, 101264, 101267, - 101266, 77939, 77940, 77937, 77938, 74343, 93043, 72704, 660, 10127, 666, - 0, 5532, 43667, 5533, 77941, 0, 0, 0, 979, 0, 0, 72706, 92652, 9108, 0, - 72716, 129403, 63951, 71685, 0, 0, 128782, 63946, 1707, 983843, 128612, - 63950, 63949, 63948, 63947, 63945, 6038, 63943, 63942, 101274, 0, 101276, - 101275, 0, 0, 0, 0, 0, 0, 73884, 0, 1690, 63919, 63918, 63917, 70865, - 43659, 0, 983848, 0, 2054, 0, 78515, 63916, 9184, 63914, 69737, 63911, - 63910, 63909, 63908, 0, 0, 63913, 6044, 0, 64838, 9061, 5534, 10672, - 11653, 124932, 5531, 101501, 101500, 101503, 101502, 0, 0, 11957, 101498, - 68668, 124922, 0, 0, 10474, 43426, 0, 42354, 101492, 101491, 101494, - 101493, 101488, 8413, 66841, 101489, 7269, 7272, 0, 0, 101471, 101470, - 78460, 0, 101467, 101466, 101469, 101468, 0, 0, 0, 66840, 0, 101465, - 128441, 0, 101462, 101461, 92187, 7270, 101458, 101457, 6628, 1076, - 128700, 0, 101456, 0, 0, 0, 0, 12807, 43413, 63906, 4548, 63904, 71187, - 70393, 41729, 44005, 1307, 0, 101473, 101472, 0, 0, 128268, 0, 8180, 0, - 127778, 0, 0, 5413, 43681, 123205, 3493, 0, 0, 0, 92544, 73937, 10517, 0, - 4518, 10990, 101447, 5167, 4481, 3771, 101443, 2710, 0, 66277, 0, 0, - 43073, 118579, 0, 0, 0, 121071, 0, 119659, 1628, 0, 0, 0, 65262, 66809, - 10783, 11172, 0, 0, 70840, 113679, 0, 119029, 0, 0, 41530, 66843, 4457, - 0, 0, 0, 0, 0, 41529, 0, 121210, 6031, 65807, 70814, 0, 101455, 71984, - 69705, 101452, 101451, 11926, 6033, 9656, 0, 0, 0, 68869, 0, 128930, 0, - 128100, 0, 42612, 43655, 0, 0, 0, 66468, 0, 0, 68623, 101423, 0, 0, - 101420, 101419, 101422, 101421, 0, 1151, 101418, 73709, 127544, 0, 71106, - 118722, 0, 0, 0, 0, 101437, 101436, 11527, 101438, 0, 0, 11538, 101434, - 0, 11020, 0, 66467, 101432, 8087, 71700, 101433, 9894, 101427, 73485, - 70824, 101424, 0, 78513, 8053, 0, 0, 0, 0, 101407, 101406, 0, 63845, - 101403, 78912, 78602, 101404, 13084, 42966, 8741, 0, 0, 101401, 0, 64605, - 83051, 101397, 473, 43415, 101394, 101393, 101396, 1087, 124966, 71275, - 101392, 0, 66439, 43218, 0, 0, 7237, 101414, 101417, 101416, 71996, - 101410, 92261, 101412, 121036, 4384, 74220, 101408, 2058, 917561, 0, - 129462, 0, 0, 0, 3857, 0, 0, 0, 64630, 0, 0, 74168, 127113, 125088, 4421, - 0, 0, 101381, 66400, 101383, 68431, 101377, 101376, 101379, 83053, 0, 0, - 69640, 127861, 0, 437, 73483, 0, 0, 0, 65236, 13290, 119180, 4997, 64306, - 0, 0, 4999, 0, 0, 0, 4711, 120769, 0, 2739, 0, 92915, 74834, 0, 127175, - 0, 0, 0, 0, 0, 1779, 6600, 6601, 0, 5325, 101390, 101389, 13058, 101391, - 101386, 0, 92186, 101387, 71845, 10575, 43399, 0, 101385, 101384, 1104, - 0, 0, 10655, 0, 0, 69497, 0, 1082, 110878, 0, 67401, 0, 0, 0, 0, 6783, 0, - 0, 42867, 69655, 44021, 6458, 0, 0, 0, 0, 0, 0, 1273, 43407, 0, 0, 0, 0, - 1313, 6322, 41720, 128627, 66433, 0, 0, 0, 11216, 0, 0, 0, 43437, 93833, - 0, 0, 0, 5122, 0, 72728, 129520, 70161, 0, 0, 0, 0, 0, 8303, 0, 128926, - 0, 10003, 0, 0, 0, 1686, 0, 0, 42834, 3664, 0, 126088, 121346, 0, 0, - 4324, 126, 0, 0, 0, 0, 0, 65166, 0, 0, 0, 0, 43817, 0, 43822, 0, 0, - 65600, 13002, 0, 0, 0, 1103, 0, 119575, 129452, 0, 13078, 0, 8116, 0, - 2050, 0, 0, 1102, 0, 6555, 0, 0, 74003, 74794, 0, 0, 42591, 127278, 0, - 1111, 0, 75047, 4707, 0, 0, 0, 0, 43468, 4522, 8645, 0, 74857, 0, 11352, - 0, 92787, 0, 2293, 0, 0, 0, 128265, 71709, 0, 121194, 0, 93827, 0, 0, 0, - 128488, 0, 160, 2677, 0, 0, 120141, 0, 983646, 70790, 0, 42770, 0, 71986, - 0, 43821, 113769, 0, 0, 43816, 0, 0, 1079, 3867, 64817, 0, 118549, 0, 0, - 64768, 0, 0, 4005, 983213, 0, 10991, 0, 92957, 917578, 92850, 917580, - 917575, 128314, 917577, 917576, 917571, 78534, 917573, 917572, 0, 0, - 128359, 73458, 0, 3339, 11448, 1106, 917591, 917590, 129192, 3340, - 917587, 917586, 917589, 917588, 917583, 10605, 1309, 74996, 120743, - 92650, 0, 0, 9485, 0, 129781, 0, 0, 0, 125002, 92533, 128487, 0, 129285, - 4338, 11238, 0, 66825, 0, 0, 0, 0, 122939, 0, 74128, 0, 0, 73680, 0, - 129438, 9553, 1590, 63777, 63776, 128677, 63782, 63781, 63780, 63779, - 1583, 101525, 101528, 101527, 101522, 101521, 101524, 101523, 41522, 0, - 92168, 983803, 66759, 0, 983580, 0, 0, 0, 0, 11394, 0, 983071, 0, 66823, - 1334, 0, 4479, 0, 0, 120663, 0, 122883, 10497, 0, 0, 983796, 66828, 0, 0, - 0, 6809, 63786, 0, 0, 63791, 63790, 1145, 63788, 101535, 63785, 63784, - 63783, 10192, 65267, 101533, 101532, 8928, 0, 0, 0, 0, 0, 74216, 66805, - 0, 0, 63759, 63758, 3523, 1074, 0, 121340, 74077, 92832, 0, 0, 63757, - 43145, 63755, 63754, 63752, 1349, 63750, 63749, 0, 0, 0, 63753, 63802, - 41084, 72784, 0, 41930, 63805, 63804, 11140, 63801, 41082, 43843, 42787, - 101514, 0, 101516, 101515, 63793, 63792, 0, 128241, 10201, 12238, 63795, - 42358, 92394, 43862, 101511, 101510, 41932, 66826, 101507, 101506, 92809, - 121136, 0, 7950, 63772, 63771, 63770, 0, 63767, 63766, 2793, 63764, 0, - 128501, 63769, 9530, 0, 92398, 0, 128642, 63763, 63762, 4595, 63760, 792, - 92808, 0, 0, 8742, 0, 0, 0, 63744, 0, 0, 120815, 63748, 63747, 63746, - 63745, 5055, 0, 0, 1090, 0, 125268, 11665, 92830, 4558, 78919, 72211, 0, - 0, 0, 11513, 983978, 6157, 63775, 63774, 63773, 0, 12170, 9067, 92843, 0, - 10872, 129643, 43891, 43893, 43892, 129747, 43933, 0, 128231, 0, 0, 0, 0, - 0, 11063, 0, 43888, 0, 0, 128368, 43889, 0, 73807, 983105, 7386, 0, 0, - 70295, 0, 0, 0, 71201, 128460, 0, 0, 0, 0, 69915, 2918, 66820, 65300, 0, - 124898, 64726, 2790, 0, 3793, 42065, 127829, 0, 124901, 0, 0, 0, 0, 0, - 92712, 0, 12923, 5270, 2166, 0, 0, 65813, 0, 128499, 0, 75012, 0, 10888, - 0, 93997, 94180, 3330, 129417, 0, 0, 0, 0, 0, 8220, 0, 0, 101581, 72457, - 1627, 101582, 0, 0, 5371, 101578, 0, 1826, 118794, 0, 0, 70023, 0, 0, 0, - 71108, 0, 0, 124907, 0, 92207, 68125, 74898, 71353, 0, 72006, 71098, - 70029, 0, 43116, 10190, 70019, 64346, 0, 101585, 66818, 101587, 70031, 0, - 12666, 120413, 120420, 120414, 101567, 120428, 0, 101564, 101563, 65509, - 101565, 7449, 0, 101562, 0, 7438, 0, 0, 9054, 971, 101558, 92803, 101560, - 65195, 64767, 101557, 101556, 0, 0, 101553, 101552, 0, 0, 0, 64303, - 101576, 2303, 0, 101577, 101572, 101571, 65833, 101573, 7271, 0, 101570, - 92802, 0, 12229, 0, 0, 43411, 73751, 126577, 64813, 0, 0, 10476, 0, 0, - 3932, 64958, 0, 0, 73989, 0, 0, 101542, 101541, 101544, 101543, 101538, - 101537, 101540, 101539, 92645, 65474, 4796, 118892, 129357, 65479, 0, - 42895, 11858, 65500, 983600, 9899, 92608, 2162, 404, 65484, 120639, 0, - 5788, 127852, 0, 65491, 1831, 66020, 0, 984012, 92588, 0, 1343, 120784, - 0, 0, 12018, 0, 0, 0, 0, 0, 4422, 4708, 3799, 101550, 119357, 0, 101547, - 101546, 101549, 101548, 983095, 0, 1364, 0, 8038, 101545, 0, 12868, - 129560, 70425, 55223, 0, 64414, 110689, 122978, 0, 0, 0, 0, 0, 118802, - 118644, 42855, 118856, 42866, 73525, 0, 0, 0, 66438, 0, 983996, 119356, - 92853, 119354, 0, 123556, 0, 73013, 67685, 128062, 119350, 0, 11864, - 10404, 10340, 119352, 1556, 5274, 0, 127821, 10017, 9733, 0, 69488, 0, - 41373, 0, 0, 0, 0, 0, 349, 4863, 41371, 0, 0, 0, 0, 72295, 4398, 8543, - 65618, 128018, 129784, 0, 0, 0, 12441, 0, 119348, 119347, 4318, 10452, 0, - 8032, 0, 119349, 119344, 0, 127844, 121156, 0, 110729, 119345, 8597, 0, - 110727, 9864, 0, 92796, 0, 92799, 0, 0, 0, 7722, 0, 0, 92797, 0, 0, - 66590, 0, 0, 129850, 0, 0, 0, 4965, 0, 917536, 0, 123196, 0, 0, 0, 10436, - 119342, 43147, 119340, 10356, 10420, 982, 2756, 0, 983997, 0, 0, 11162, - 119338, 0, 92914, 0, 65110, 0, 0, 983800, 78543, 0, 118793, 0, 128112, - 119179, 64476, 1694, 8216, 0, 0, 78539, 0, 65620, 0, 78537, 0, 0, 42158, - 65621, 69955, 120324, 120327, 120326, 120321, 120320, 120323, 120322, - 12314, 65616, 55221, 43825, 983553, 119337, 68060, 119335, 0, 71874, - 123628, 128537, 119332, 73089, 0, 41347, 0, 0, 8842, 0, 0, 4379, 127393, - 12692, 0, 0, 66353, 71875, 0, 0, 92907, 0, 0, 71877, 120303, 65619, 9872, - 0, 0, 1846, 120309, 120308, 119256, 71192, 120305, 120304, 120307, 6442, - 120317, 120316, 5379, 120318, 110717, 120312, 120315, 71876, 0, 65934, - 66497, 0, 66986, 0, 0, 0, 0, 0, 0, 0, 0, 72002, 0, 6151, 12110, 0, - 129761, 0, 66959, 0, 0, 0, 0, 68335, 129655, 0, 0, 0, 0, 0, 66041, 9676, - 10202, 0, 0, 0, 64575, 78929, 11965, 0, 124936, 0, 0, 0, 0, 0, 9698, - 66293, 0, 119651, 0, 0, 41921, 0, 0, 0, 119258, 0, 0, 0, 0, 0, 8012, - 12355, 12353, 0, 0, 74107, 0, 0, 41925, 0, 41920, 65444, 0, 0, 41923, - 12694, 0, 10112, 1294, 0, 120091, 0, 120092, 0, 0, 128474, 121400, 0, 0, - 0, 8718, 0, 10284, 10268, 10380, 10316, 92593, 0, 71850, 0, 0, 92889, 0, - 0, 0, 0, 9342, 12829, 0, 0, 101239, 127978, 0, 0, 69428, 0, 73767, 72347, - 0, 7956, 598, 0, 72329, 93837, 0, 0, 128860, 0, 120041, 0, 0, 101242, 0, - 0, 847, 0, 9529, 0, 0, 0, 101247, 120035, 0, 0, 0, 67411, 0, 0, 119497, - 120040, 0, 128580, 0, 9624, 0, 0, 0, 65463, 1554, 0, 0, 0, 0, 71879, 0, - 0, 0, 121161, 19963, 123566, 0, 72326, 92933, 71887, 10324, 10292, 65546, - 0, 68141, 8372, 0, 0, 83018, 120022, 10175, 10388, 42799, 0, 983181, - 10568, 0, 127400, 0, 0, 0, 983762, 0, 4366, 0, 983805, 0, 0, 42608, 0, - 9884, 0, 0, 0, 0, 129180, 0, 128964, 0, 0, 1609, 0, 92773, 73448, 0, - 11661, 0, 5818, 0, 0, 0, 9540, 0, 2554, 5158, 0, 2213, 0, 0, 78522, - 43079, 0, 0, 8264, 11175, 64553, 120863, 42155, 0, 0, 0, 0, 0, 69552, - 8676, 0, 129927, 0, 451, 0, 0, 0, 0, 0, 0, 123167, 43609, 0, 0, 1440, 0, - 0, 0, 127061, 11005, 0, 66656, 127063, 0, 129936, 0, 127065, 43393, 0, - 120643, 0, 0, 0, 0, 120798, 0, 0, 0, 0, 0, 0, 70435, 64356, 0, 0, 0, 383, - 7154, 127815, 43495, 128809, 121448, 0, 0, 0, 11286, 0, 0, 0, 0, 0, 0, 0, - 42644, 73555, 129797, 129801, 8292, 0, 4980, 113726, 92674, 70130, 0, 0, - 0, 0, 74912, 0, 10631, 83330, 100488, 68042, 0, 0, 7900, 101252, 0, - 78779, 4198, 128555, 0, 0, 0, 123159, 0, 0, 12931, 0, 0, 0, 2088, 0, - 72164, 129284, 0, 0, 69265, 0, 0, 0, 69694, 92838, 129794, 8593, 0, 0, 0, - 0, 0, 0, 11798, 0, 100483, 0, 0, 0, 64211, 128865, 120494, 0, 0, 0, - 121228, 68901, 128788, 0, 0, 65162, 0, 0, 0, 0, 0, 128130, 0, 92264, - 127153, 0, 128818, 0, 0, 61, 0, 74373, 92182, 119554, 92862, 0, 12089, 0, - 65834, 83281, 119671, 128701, 0, 0, 42566, 42743, 0, 69824, 0, 92653, 0, - 0, 42621, 0, 64833, 0, 0, 0, 43266, 0, 0, 0, 74843, 0, 0, 119103, 64417, - 0, 0, 64737, 0, 0, 8930, 0, 0, 66900, 10056, 1800, 0, 0, 0, 129337, - 121175, 7743, 0, 0, 119528, 92640, 92453, 9034, 6039, 129139, 10075, 0, - 0, 0, 10748, 0, 0, 0, 0, 0, 92984, 0, 0, 128183, 129421, 0, 43064, - 127558, 0, 7539, 0, 0, 0, 0, 0, 0, 0, 92898, 42567, 0, 0, 73886, 0, - 129988, 12326, 0, 92848, 0, 0, 11355, 0, 0, 0, 0, 69437, 128222, 129803, - 129811, 119537, 72327, 43005, 65342, 118902, 0, 0, 8644, 0, 0, 11186, - 74296, 41909, 0, 128682, 2791, 127472, 1891, 0, 0, 41907, 66647, 0, 0, - 41906, 0, 129672, 10773, 70206, 0, 0, 0, 6412, 2061, 8520, 13146, 0, - 92836, 83275, 65902, 2882, 0, 126232, 65852, 0, 92795, 0, 123627, 0, 0, - 92794, 0, 0, 128098, 0, 0, 0, 70871, 0, 92792, 0, 120087, 0, 0, 92793, - 93971, 0, 3844, 6842, 0, 0, 6612, 0, 0, 0, 0, 0, 783, 0, 0, 0, 983064, - 68032, 119225, 0, 0, 68378, 4556, 67839, 68480, 78663, 120069, 120074, - 67657, 10510, 4382, 74218, 42194, 0, 92806, 9177, 8902, 93958, 9839, - 92804, 120700, 92807, 0, 63999, 41904, 41917, 9788, 120973, 92805, 1862, - 0, 0, 0, 41915, 0, 41919, 63994, 41914, 7981, 0, 0, 0, 0, 0, 0, 0, - 120834, 0, 0, 0, 6784, 78788, 0, 0, 0, 0, 127534, 127484, 127476, 983874, - 0, 983960, 64289, 65289, 0, 129539, 129575, 64509, 0, 0, 126505, 11051, - 0, 66635, 55259, 65885, 0, 128310, 0, 0, 0, 0, 7500, 4506, 0, 0, 0, 0, 0, - 126609, 4040, 128680, 6167, 0, 42945, 0, 0, 0, 0, 7830, 43036, 0, 0, - 63990, 19947, 63988, 63987, 0, 63993, 10440, 9611, 2244, 71883, 0, 65260, - 63986, 11446, 63984, 92641, 3435, 119652, 0, 119108, 0, 128632, 0, 0, - 12748, 0, 0, 92705, 0, 78790, 0, 0, 63956, 42458, 63954, 63953, 63960, - 63959, 63958, 11596, 0, 11469, 69267, 42306, 2723, 0, 0, 70027, 0, 0, 0, - 128093, 2880, 0, 0, 0, 0, 128506, 3498, 4378, 0, 129825, 0, 65551, - 118928, 0, 43387, 0, 64415, 128898, 0, 0, 0, 0, 8161, 393, 12013, 0, - 92216, 126479, 63965, 63964, 63963, 42345, 0, 2174, 63967, 42498, 0, - 2927, 0, 63961, 0, 0, 983946, 0, 69699, 0, 42340, 0, 0, 0, 10730, 0, - 69688, 0, 64187, 118535, 0, 12437, 9813, 0, 42453, 1604, 9565, 0, 69701, - 69235, 42414, 110724, 129196, 0, 42301, 11372, 0, 917973, 0, 0, 63980, - 63979, 63978, 0, 128207, 12017, 63982, 63981, 73687, 0, 63977, 63976, - 72794, 0, 0, 0, 63971, 4347, 4416, 63968, 11009, 63974, 63973, 402, - 69390, 13147, 0, 0, 64646, 13228, 0, 0, 3515, 74252, 65261, 0, 0, 6259, - 0, 0, 0, 0, 0, 0, 74813, 74425, 0, 126998, 126114, 0, 0, 0, 129933, - 983717, 0, 0, 74301, 0, 122633, 0, 0, 74060, 69508, 0, 66235, 5145, 0, 0, - 128394, 0, 73120, 0, 7402, 0, 0, 0, 7952, 7832, 43382, 66616, 0, 983950, - 120852, 0, 127875, 64866, 0, 0, 0, 78784, 74248, 0, 0, 983197, 0, 0, 0, - 78656, 42390, 0, 0, 983940, 0, 0, 0, 92839, 9508, 0, 9544, 11520, 0, - 110898, 3377, 0, 129562, 0, 0, 0, 0, 66989, 66280, 0, 127198, 0, 0, 0, - 1955, 119565, 0, 0, 3076, 0, 42168, 73049, 66304, 0, 0, 8917, 42403, 301, - 0, 111175, 0, 0, 0, 0, 0, 0, 67819, 92987, 0, 0, 0, 983206, 0, 69403, - 3182, 0, 0, 0, 0, 0, 42169, 123162, 74244, 0, 42329, 0, 66326, 6841, 0, - 128913, 0, 1219, 3934, 71276, 11483, 74510, 101122, 121110, 42442, 65470, - 69565, 0, 64622, 7759, 42482, 485, 0, 0, 42290, 0, 0, 42280, 0, 0, 11655, - 64379, 127913, 42431, 10126, 42318, 0, 119631, 74397, 42470, 0, 68315, 0, - 110829, 74041, 0, 0, 0, 5411, 0, 0, 0, 64205, 0, 64206, 42393, 64478, - 1310, 125007, 0, 12052, 10643, 55271, 72727, 0, 121045, 0, 0, 118852, 0, - 0, 0, 0, 113826, 0, 0, 64385, 0, 0, 0, 0, 0, 0, 93848, 92560, 2713, 0, - 9650, 0, 0, 120602, 1406, 983650, 78174, 92659, 0, 68223, 0, 0, 0, 0, - 43475, 0, 65287, 1508, 127938, 8779, 10569, 75034, 0, 0, 0, 0, 0, 0, 0, - 70786, 0, 0, 128344, 9185, 0, 42932, 43403, 0, 0, 0, 0, 0, 0, 0, 0, - 12955, 0, 2888, 0, 0, 0, 0, 0, 0, 0, 2878, 0, 0, 0, 0, 0, 0, 129028, - 13203, 129722, 10429, 10365, 0, 0, 127165, 7503, 0, 113676, 68381, - 119658, 0, 8986, 0, 10632, 11934, 11452, 1332, 0, 0, 0, 0, 73741, 1791, - 8850, 9288, 0, 2892, 0, 43394, 555, 0, 0, 0, 0, 64172, 118899, 0, 0, 0, - 0, 8854, 0, 5858, 73101, 10582, 0, 0, 1361, 0, 0, 7905, 0, 65256, 0, - 41210, 0, 0, 71884, 0, 0, 0, 6828, 0, 92302, 0, 1342, 68440, 0, 64161, - 10903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64381, 0, 0, 0, 42245, 126467, - 41972, 0, 0, 0, 9127, 0, 66619, 126489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11620, - 0, 1149, 68316, 0, 0, 0, 0, 0, 92492, 0, 118784, 0, 0, 0, 12838, 0, - 118819, 0, 0, 0, 0, 41087, 0, 0, 0, 0, 12036, 0, 124143, 0, 0, 0, 64428, - 12227, 0, 0, 0, 0, 125248, 120964, 0, 0, 0, 0, 0, 69566, 0, 0, 0, 0, 0, - 1743, 0, 0, 0, 65186, 122626, 0, 0, 0, 0, 64439, 0, 68062, 0, 111259, - 111258, 43866, 0, 111263, 3395, 9362, 111260, 0, 111257, 111256, 111255, - 0, 0, 41091, 3426, 1344, 111249, 111248, 126215, 4735, 11111, 6119, - 111251, 42699, 0, 0, 74818, 1423, 0, 0, 0, 0, 12039, 10559, 0, 0, 0, - 9472, 67734, 11929, 0, 0, 0, 0, 128826, 0, 11579, 0, 0, 128364, 0, 92185, - 0, 0, 1004, 92584, 0, 0, 0, 129755, 0, 2556, 0, 0, 72790, 0, 0, 9686, 0, - 0, 0, 70109, 111102, 0, 10718, 13154, 111100, 9139, 0, 0, 0, 0, 0, 0, 0, - 0, 92831, 92810, 41708, 12860, 41703, 0, 42090, 5403, 10352, 73917, - 129144, 111096, 111088, 5140, 3753, 118785, 41704, 0, 43078, 127789, - 2207, 129360, 0, 983207, 92362, 0, 0, 2410, 92525, 0, 0, 0, 0, 0, 0, 0, - 0, 119253, 0, 126601, 0, 2066, 74199, 0, 43463, 10659, 119623, 68863, 0, - 1336, 0, 0, 69463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126639, 0, 272, 0, 0, 0, 0, - 983965, 128133, 0, 0, 124940, 0, 1190, 42146, 1335, 42177, 43867, 0, 0, - 10448, 0, 125041, 0, 0, 2099, 5120, 2409, 7799, 0, 74424, 0, 126581, - 4731, 0, 111199, 111198, 111197, 111196, 11689, 0, 74977, 9913, 129430, - 0, 0, 0, 111195, 111194, 11694, 0, 11690, 111189, 92842, 111187, 11693, - 111193, 111192, 43097, 11688, 0, 78797, 194, 111186, 111185, 111184, 0, - 0, 0, 11226, 4519, 70337, 10898, 43072, 70205, 0, 0, 0, 73094, 10695, 0, - 7540, 0, 110984, 41859, 6067, 92790, 110982, 0, 110981, 13311, 92788, - 41857, 92791, 8359, 121224, 12689, 0, 983132, 64577, 92789, 111203, - 68183, 111209, 111208, 6064, 110988, 0, 110979, 74142, 0, 111201, 111200, - 6051, 123613, 0, 0, 983374, 0, 983651, 0, 0, 0, 110864, 10537, 110862, - 1276, 0, 6549, 6052, 0, 0, 0, 0, 118687, 0, 0, 0, 0, 1960, 0, 71232, - 66297, 0, 129313, 0, 0, 1345, 111213, 111212, 111211, 8956, 43083, 0, - 111215, 64682, 0, 6430, 69563, 111210, 119814, 0, 0, 0, 119817, 0, 492, - 43087, 0, 0, 0, 0, 0, 2582, 0, 0, 7444, 72863, 0, 2297, 111243, 73837, 0, - 0, 65096, 197, 74183, 0, 69571, 111241, 111240, 129760, 66515, 43550, - 119829, 111229, 111228, 93764, 111226, 0, 0, 111231, 111230, 71686, 1799, - 0, 42148, 74336, 0, 0, 65340, 111220, 110974, 2262, 111217, 111224, - 74931, 111222, 10896, 0, 0, 0, 0, 6338, 111003, 110997, 110994, 111006, - 111002, 111005, 0, 111279, 111278, 111277, 72133, 0, 111273, 111272, - 110961, 3171, 6623, 4961, 0, 886, 55216, 8654, 110965, 111270, 74390, - 64603, 111267, 129283, 68122, 0, 43084, 0, 0, 0, 0, 69693, 8994, 10944, - 65938, 111239, 111238, 111237, 111236, 66279, 92890, 42510, 0, 0, 6804, - 0, 1947, 0, 0, 0, 42759, 0, 1705, 122631, 0, 0, 0, 0, 72722, 74036, 0, 0, - 66720, 111281, 111280, 0, 4909, 111285, 111284, 111283, 4904, 0, 43503, - 1365, 9253, 42757, 0, 7462, 0, 11860, 0, 0, 119587, 0, 917579, 92526, 0, - 125035, 0, 111311, 111310, 0, 0, 0, 0, 93977, 0, 0, 0, 0, 3629, 0, 13005, - 0, 3628, 0, 111295, 0, 0, 0, 0, 111290, 64809, 2928, 4905, 111083, 851, - 55233, 111291, 111059, 43086, 9114, 43870, 42583, 9315, 4822, 4906, - 121097, 2847, 111028, 10330, 0, 1251, 7777, 41852, 125059, 111327, - 111032, 111325, 12646, 0, 10259, 0, 65821, 75046, 6018, 0, 111324, - 111323, 111322, 68372, 111319, 111318, 71893, 2558, 0, 64584, 111321, - 111320, 0, 0, 0, 0, 78911, 111308, 111307, 69500, 73987, 74599, 71895, - 93012, 0, 128715, 0, 12867, 111296, 0, 0, 11044, 111300, 111299, 8904, - 11824, 65857, 0, 128674, 129027, 4387, 0, 0, 124920, 0, 0, 0, 0, 11842, - 0, 0, 0, 5136, 1968, 983041, 126627, 1337, 0, 0, 0, 0, 66506, 0, 0, 0, 0, - 42314, 121384, 0, 0, 6120, 0, 65670, 67457, 0, 43082, 6016, 0, 42284, - 71894, 4276, 111314, 3619, 41638, 69691, 0, 42322, 8853, 111043, 0, 490, - 0, 13231, 68384, 72310, 65350, 0, 0, 0, 68245, 42435, 6154, 0, 65354, 0, - 0, 42397, 334, 72732, 42416, 65359, 65273, 74634, 128227, 4442, 10364, 0, - 778, 41626, 42455, 7989, 0, 3227, 69907, 111053, 0, 2915, 11502, 983214, - 41702, 10309, 0, 0, 0, 0, 0, 0, 0, 127268, 127258, 127267, 65215, 64410, - 127260, 71175, 0, 0, 0, 0, 0, 0, 41700, 110651, 69266, 126488, 0, 0, - 42495, 0, 0, 0, 10460, 43364, 0, 1356, 3728, 42713, 0, 0, 42342, 10914, - 0, 42489, 64310, 66896, 41861, 42297, 0, 0, 41860, 64862, 0, 0, 5289, - 42336, 128658, 0, 92529, 42410, 71129, 120624, 0, 2649, 74493, 0, 126635, - 0, 3382, 42449, 9081, 1658, 11936, 93019, 113814, 11269, 0, 0, 43100, - 69888, 65508, 0, 0, 121451, 0, 0, 0, 129780, 69272, 4732, 128283, 0, 0, - 0, 121113, 2236, 126551, 0, 6048, 0, 0, 73965, 0, 0, 0, 0, 10151, 9681, - 4475, 0, 41142, 2100, 0, 0, 6035, 0, 123599, 10296, 0, 0, 0, 0, 0, 0, 0, - 983312, 68488, 10392, 10328, 0, 43462, 0, 0, 0, 8979, 0, 0, 983309, 0, 0, - 0, 10977, 0, 10344, 0, 65299, 10408, 0, 0, 121187, 66505, 0, 0, 0, 0, 0, - 122648, 43074, 73799, 0, 0, 122944, 0, 3446, 0, 129891, 128692, 0, 0, - 119582, 4474, 0, 43093, 6282, 0, 0, 127372, 0, 0, 0, 129881, 0, 0, 0, 0, - 66910, 67811, 92277, 0, 64948, 0, 74347, 0, 0, 0, 983981, 8194, 0, - 121165, 11010, 0, 8893, 0, 983988, 0, 0, 0, 983322, 7925, 0, 0, 113825, - 0, 1352, 11069, 7707, 0, 126486, 0, 0, 0, 0, 65605, 6040, 0, 10071, 0, - 128156, 43750, 0, 8899, 69873, 0, 0, 983316, 128208, 7820, 69615, 0, 0, - 7746, 1492, 0, 0, 0, 66866, 0, 11788, 65913, 0, 0, 43095, 0, 0, 92265, - 2999, 0, 120720, 0, 371, 120759, 6023, 0, 0, 11708, 0, 0, 6323, 0, 0, 0, - 8938, 6043, 65866, 0, 78910, 0, 72419, 0, 129480, 2589, 74332, 1689, - 7802, 0, 0, 0, 0, 66704, 0, 129992, 0, 0, 128127, 6049, 0, 4027, 0, 0, - 111334, 111333, 1503, 111331, 0, 111337, 11951, 111335, 2387, 0, 0, 8289, - 111330, 7326, 66514, 65514, 0, 64865, 0, 9668, 0, 0, 0, 0, 93060, 6036, - 92768, 4026, 74089, 127091, 0, 0, 75044, 110821, 0, 110819, 0, 0, 0, 0, - 6021, 0, 128288, 0, 43155, 0, 110822, 124152, 111343, 42691, 111341, - 111340, 2246, 166, 0, 0, 0, 10623, 408, 0, 111339, 13298, 0, 7426, 43694, - 0, 0, 8811, 0, 0, 129753, 0, 0, 74134, 983054, 0, 127811, 0, 0, 0, 6645, - 646, 128813, 0, 42129, 0, 120880, 0, 8697, 0, 120936, 122953, 0, 0, 0, - 5809, 1950, 0, 92432, 68339, 0, 42136, 0, 0, 0, 0, 0, 0, 111354, 983984, - 0, 0, 111349, 111348, 43330, 111346, 111353, 111352, 41567, 111350, 0, 0, - 0, 0, 111345, 111344, 8285, 0, 4509, 0, 128361, 0, 77774, 129851, 0, 0, - 41727, 0, 0, 0, 0, 0, 71188, 0, 74512, 7027, 3886, 0, 74023, 92888, 0, 0, - 126092, 94058, 119855, 0, 121455, 11707, 119852, 0, 7939, 10342, 92460, - 72747, 121408, 917569, 0, 71198, 94077, 119847, 0, 0, 7201, 0, 123554, - 120866, 983987, 1540, 0, 0, 124923, 0, 119856, 41718, 71177, 0, 0, - 128001, 118699, 0, 119040, 0, 9619, 120840, 0, 0, 0, 0, 3560, 0, 6070, - 129000, 0, 2922, 6082, 70147, 65009, 983973, 0, 0, 0, 0, 0, 0, 3607, - 65863, 0, 92487, 42153, 121042, 0, 983862, 2032, 0, 0, 0, 0, 129985, 0, - 43085, 6057, 0, 0, 0, 0, 0, 0, 0, 0, 638, 6083, 126976, 0, 0, 2305, 0, 0, - 118658, 6056, 10878, 0, 0, 6085, 119351, 0, 3915, 0, 0, 0, 0, 0, 0, 4028, - 1787, 0, 43096, 0, 0, 1768, 0, 0, 0, 128125, 0, 0, 583, 129137, 0, 0, - 66004, 0, 0, 0, 92859, 0, 55267, 120810, 128995, 43075, 65049, 0, 74531, - 0, 93009, 70694, 0, 0, 129375, 9869, 128815, 1771, 0, 0, 0, 0, 0, 0, - 119115, 113708, 0, 0, 74101, 0, 0, 0, 0, 83367, 0, 0, 0, 12539, 123631, - 0, 0, 129846, 73862, 69842, 9897, 0, 100561, 0, 124142, 0, 0, 0, 8931, 0, - 1415, 8866, 74552, 0, 128312, 0, 983566, 43106, 127275, 71089, 1580, - 92278, 68424, 0, 0, 7658, 3440, 78215, 1562, 0, 0, 129031, 0, 0, 0, 0, 0, - 0, 6028, 68900, 42892, 0, 111016, 0, 0, 0, 0, 0, 128269, 0, 66776, 42946, - 127276, 92849, 0, 72448, 120510, 11599, 0, 11602, 11591, 11574, 11581, - 11597, 11598, 6253, 11571, 11584, 70273, 11569, 122937, 8906, 0, 5755, - 2636, 0, 10815, 11619, 129094, 0, 7815, 11616, 11617, 70064, 11618, - 11604, 7869, 11612, 0, 42152, 0, 122941, 0, 92586, 126247, 0, 92173, 0, - 0, 6616, 0, 0, 120875, 391, 0, 0, 0, 42296, 11588, 0, 0, 0, 68397, 0, 0, - 42335, 983189, 0, 0, 7538, 94040, 0, 42491, 0, 0, 128088, 4576, 0, 0, - 43809, 4277, 0, 3563, 0, 42338, 368, 0, 0, 42412, 0, 78209, 119144, 0, - 43814, 983616, 1849, 0, 9921, 42451, 4253, 0, 0, 118688, 42404, 64657, - 73919, 3618, 78338, 0, 0, 0, 0, 0, 929, 6827, 42035, 0, 0, 0, 67847, 0, - 0, 0, 0, 0, 0, 0, 0, 4578, 64513, 0, 0, 0, 71049, 68090, 127086, 43305, - 0, 73462, 118530, 0, 42048, 10166, 0, 127095, 113810, 983128, 0, 983991, - 0, 0, 42483, 0, 0, 0, 42291, 0, 71047, 0, 6641, 525, 66404, 0, 8763, - 125091, 0, 0, 0, 0, 0, 42504, 42581, 74280, 6915, 42310, 0, 8559, 0, - 983994, 125100, 0, 0, 11666, 8679, 0, 1576, 42423, 0, 0, 73840, 983092, - 11374, 0, 10889, 129076, 0, 42462, 0, 77982, 0, 2718, 42424, 0, 0, - 127166, 0, 1179, 0, 0, 0, 363, 11015, 72229, 0, 43857, 0, 66692, 0, 0, 0, - 11041, 72018, 0, 0, 0, 0, 125184, 0, 92520, 0, 9492, 66709, 9212, 12833, - 0, 0, 1297, 122932, 0, 0, 0, 0, 0, 12924, 0, 0, 10090, 125249, 0, 42505, - 0, 42507, 0, 42311, 92940, 120919, 68401, 10759, 0, 0, 120924, 42351, - 42919, 9398, 66292, 0, 9422, 122942, 122943, 0, 0, 0, 129440, 92575, - 1603, 0, 0, 0, 0, 0, 69703, 11250, 0, 0, 10546, 0, 0, 11600, 0, 2797, - 73821, 42427, 306, 714, 3058, 120154, 0, 0, 0, 42395, 0, 11607, 0, 11198, - 127512, 0, 72232, 129067, 0, 42433, 0, 7603, 74063, 0, 42141, 0, 0, 0, - 129085, 8244, 362, 125069, 0, 8037, 0, 0, 0, 69510, 41606, 66696, 77912, - 0, 2093, 0, 120676, 122929, 41604, 0, 0, 0, 0, 10523, 1446, 42320, 0, - 120247, 64773, 42472, 0, 0, 1722, 5581, 0, 64496, 0, 0, 64914, 0, 42620, - 128603, 124988, 0, 0, 10549, 130035, 71190, 0, 0, 0, 0, 0, 71712, 0, 0, - 0, 0, 0, 0, 0, 7684, 66338, 0, 1174, 0, 0, 983621, 0, 0, 0, 42277, 0, - 42456, 65667, 0, 0, 0, 0, 42417, 0, 0, 120812, 42304, 0, 0, 0, 74443, - 127894, 0, 8313, 0, 0, 1316, 66690, 0, 0, 0, 0, 0, 0, 66844, 983715, 0, - 0, 0, 65200, 3383, 0, 0, 70063, 122947, 0, 0, 42420, 119185, 0, 0, - 983917, 0, 121079, 72369, 0, 42343, 124980, 42706, 1751, 42496, 65742, - 13166, 0, 0, 0, 0, 0, 42683, 12697, 0, 0, 0, 125047, 0, 42346, 0, 0, - 3757, 0, 0, 121075, 65869, 0, 9247, 74976, 3193, 0, 0, 42459, 7596, 7921, - 0, 74095, 0, 42499, 11590, 66006, 0, 42307, 0, 43953, 118591, 0, 1023, - 474, 0, 0, 0, 0, 42487, 0, 0, 0, 42295, 0, 121474, 72237, 0, 9835, 0, - 127782, 0, 12275, 0, 0, 8595, 0, 0, 0, 0, 0, 10118, 0, 129156, 0, 0, 0, - 0, 0, 0, 699, 0, 120923, 11601, 0, 92941, 0, 7581, 0, 92530, 0, 0, 0, - 7765, 65583, 0, 0, 64597, 43444, 0, 92197, 0, 64279, 7036, 5823, 1937, 0, - 917854, 65415, 13308, 65417, 0, 65217, 0, 0, 11017, 0, 0, 7294, 0, 0, 0, - 0, 42466, 65416, 68858, 0, 71350, 65413, 92381, 126498, 12964, 42240, - 1941, 0, 0, 1713, 118679, 0, 0, 11407, 42441, 128262, 6297, 0, 0, 0, - 42481, 0, 0, 7179, 42289, 0, 120921, 969, 0, 0, 0, 6165, 0, 0, 0, 0, - 42402, 0, 0, 0, 129511, 0, 72234, 0, 0, 64876, 92635, 6046, 0, 6208, - 128870, 129309, 73749, 0, 0, 42422, 0, 0, 128155, 73775, 338, 0, 121369, - 0, 42328, 10767, 0, 8115, 0, 0, 0, 0, 92687, 0, 0, 0, 0, 73029, 0, 0, 0, - 71687, 4486, 128082, 2171, 0, 10925, 0, 0, 0, 0, 42309, 10257, 0, 10273, - 7668, 10305, 42461, 74882, 42349, 8832, 0, 0, 10644, 0, 129531, 42278, 0, - 0, 69874, 0, 129949, 42429, 0, 42316, 11223, 0, 0, 42468, 0, 0, 0, 65402, - 0, 0, 72235, 0, 0, 41963, 120990, 0, 0, 125013, 6823, 42391, 1588, 65400, - 0, 0, 0, 65398, 787, 0, 0, 0, 0, 2078, 127239, 65399, 0, 0, 0, 65401, 0, - 121196, 0, 113816, 644, 0, 71335, 0, 3659, 0, 0, 0, 13107, 92669, 0, - 10502, 74457, 0, 11221, 41554, 0, 0, 0, 41557, 11209, 0, 11070, 119221, - 0, 0, 73858, 41555, 9514, 0, 66771, 64641, 92447, 0, 7520, 73888, 77955, - 0, 0, 0, 0, 0, 64527, 0, 118707, 12723, 0, 68776, 0, 0, 0, 78835, 4055, - 78826, 77960, 65212, 0, 127353, 12319, 0, 0, 983218, 7964, 65427, 0, - 65424, 72217, 120966, 0, 65425, 74890, 128251, 0, 0, 0, 3448, 10827, 0, - 9866, 74527, 0, 0, 8625, 69783, 92304, 10477, 0, 0, 0, 65423, 0, 0, 0, 0, - 6152, 0, 0, 6629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11046, 11490, 0, 4485, - 71126, 0, 0, 0, 0, 0, 5869, 118533, 119633, 0, 7040, 3588, 0, 12825, 0, - 0, 128569, 0, 0, 0, 0, 0, 126637, 0, 0, 128449, 64499, 65245, 127367, - 1171, 127368, 69717, 127365, 1805, 8772, 0, 127363, 9930, 65247, 0, 0, - 2338, 127362, 92695, 0, 0, 0, 69219, 0, 120104, 0, 120103, 72221, 120102, - 129924, 118814, 8734, 4212, 0, 0, 66701, 0, 65862, 0, 120095, 42903, 0, - 0, 0, 126117, 426, 0, 120098, 8251, 0, 65436, 0, 2120, 43302, 1224, 0, - 65576, 0, 66876, 1764, 6074, 0, 12858, 0, 0, 65439, 6378, 74566, 128885, - 41960, 0, 41644, 0, 2129, 0, 9222, 0, 0, 4259, 9092, 0, 41961, 0, 0, - 66357, 42331, 64935, 0, 0, 1293, 0, 2132, 0, 983569, 0, 2454, 0, 3613, - 128837, 71117, 0, 0, 69681, 10978, 10840, 0, 10668, 72826, 127197, 9118, - 120164, 0, 0, 0, 1157, 64903, 8638, 0, 101295, 0, 0, 0, 0, 67466, 128981, - 10086, 0, 11128, 0, 0, 65430, 74013, 6079, 0, 10764, 127910, 64435, - 128051, 1339, 118643, 65428, 1317, 8822, 0, 0, 0, 127143, 0, 0, 0, 43110, - 0, 10428, 129848, 0, 0, 5742, 43076, 4692, 0, 0, 4007, 5004, 128781, 0, - 751, 6595, 6596, 0, 66373, 0, 0, 64908, 0, 6593, 72349, 12004, 119192, - 74097, 43108, 0, 0, 119333, 92188, 6598, 0, 6599, 0, 93031, 74194, 0, - 121483, 66674, 6597, 0, 73921, 0, 64745, 2281, 0, 0, 128996, 43790, 0, - 2430, 41678, 71492, 0, 43785, 113716, 0, 121263, 0, 0, 1921, 0, 19927, - 70390, 65406, 0, 43786, 4284, 128346, 72210, 43789, 12841, 9229, 0, - 42285, 0, 0, 0, 0, 3521, 0, 118690, 8325, 0, 65403, 0, 1854, 0, 0, 0, 0, - 0, 0, 0, 0, 4344, 0, 65433, 6076, 0, 0, 74764, 12074, 0, 0, 129148, 0, - 12934, 119555, 65432, 128877, 0, 6071, 65434, 0, 65435, 4053, 128623, 0, - 0, 0, 917934, 69823, 127463, 0, 121403, 127473, 8421, 73836, 0, 43705, - 502, 0, 65431, 0, 0, 0, 1303, 316, 7364, 0, 2136, 0, 120796, 64365, - 43480, 92639, 4860, 0, 127877, 0, 129728, 9583, 0, 5546, 0, 118565, 0, 0, - 0, 5544, 127475, 0, 70352, 5543, 128917, 72821, 12137, 5548, 0, 0, 10007, - 0, 127523, 6077, 0, 65452, 0, 119341, 11214, 65952, 0, 72226, 0, 0, 1319, - 74210, 65410, 67399, 92606, 0, 0, 118660, 0, 66716, 83513, 4691, 128619, - 9345, 621, 92872, 0, 122889, 65411, 0, 74575, 121246, 65408, 73899, 0, - 9474, 2812, 119118, 65412, 3786, 65409, 8894, 83246, 119611, 7923, 3716, - 92798, 0, 0, 0, 7012, 124122, 128439, 9566, 0, 94176, 0, 65012, 126242, - 545, 9575, 0, 10050, 12718, 0, 8859, 6820, 124915, 129941, 120740, 0, 0, - 9119, 2787, 0, 984000, 8507, 2012, 7985, 0, 0, 0, 0, 194634, 0, 410, 0, - 0, 120789, 120609, 0, 120378, 120379, 0, 0, 120374, 72742, 120376, - 120377, 120370, 120371, 120372, 120373, 3860, 120367, 72205, 74031, - 111131, 73685, 11748, 120365, 7941, 111134, 8749, 111132, 12698, 111129, - 361, 110793, 845, 67509, 0, 0, 4562, 72241, 2926, 0, 4569, 0, 110797, - 43487, 0, 0, 0, 74287, 122885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6291, 0, 0, 0, - 9734, 0, 0, 0, 0, 127754, 7359, 83523, 43863, 0, 111150, 8769, 111148, - 111147, 111145, 4859, 111143, 111142, 0, 0, 0, 0, 12172, 111136, 0, - 127899, 111141, 64764, 4210, 111138, 0, 804, 0, 83520, 0, 70344, 0, 0, - 67202, 10091, 67200, 119257, 67206, 67205, 67204, 67203, 72302, 0, 0, 0, - 128959, 0, 1425, 92259, 119229, 11049, 0, 71480, 42649, 8482, 0, 0, - 66715, 67209, 11940, 67207, 664, 0, 0, 0, 70200, 127525, 0, 70194, 93061, - 111155, 68474, 111153, 6032, 67218, 67217, 7430, 194670, 70191, 0, 0, 0, - 0, 0, 41161, 0, 9765, 10993, 41162, 0, 70189, 1169, 111181, 0, 1905, - 6034, 41164, 64744, 43236, 0, 128800, 73110, 0, 0, 788, 0, 0, 111167, - 111128, 1663, 128976, 42901, 127237, 67211, 67210, 0, 0, 67215, 67214, - 67213, 67212, 111160, 111159, 111158, 111157, 0, 69492, 0, 111161, 43612, - 0, 0, 0, 10855, 67223, 9355, 67221, 65198, 120355, 0, 221, 0, 0, 0, - 121141, 7191, 118930, 72208, 125212, 0, 0, 0, 0, 67228, 67227, 43333, - 67225, 0, 0, 0, 67229, 0, 7245, 0, 74405, 69922, 72219, 111178, 3873, - 8367, 111174, 111173, 111172, 43649, 0, 111177, 111176, 0, 11164, 0, - 74403, 111171, 111170, 111169, 7682, 74404, 1462, 10235, 0, 0, 0, 0, 0, - 111130, 0, 0, 74402, 0, 92299, 0, 0, 74052, 0, 126127, 120549, 0, 64295, - 0, 0, 0, 0, 0, 120662, 0, 0, 67231, 67230, 10755, 55257, 11155, 128568, - 983137, 9470, 0, 127540, 0, 69680, 64384, 0, 128607, 0, 0, 0, 122987, - 73764, 8204, 0, 0, 0, 0, 0, 8728, 0, 10904, 73446, 19936, 7833, 0, 0, 0, - 0, 92546, 0, 0, 0, 8537, 0, 0, 0, 121244, 0, 0, 2254, 128193, 0, 0, 0, 0, - 3062, 0, 0, 0, 0, 0, 41160, 41147, 41158, 0, 120777, 0, 41155, 111116, - 111115, 111114, 0, 121332, 111119, 111118, 111117, 129878, 0, 129091, 0, - 0, 0, 64594, 2456, 66867, 0, 0, 0, 0, 3721, 0, 0, 1230, 2678, 0, 3597, - 917795, 0, 0, 92215, 0, 67737, 8352, 0, 0, 0, 64515, 121378, 0, 129128, - 67846, 0, 129767, 92466, 0, 0, 71338, 0, 8660, 0, 0, 0, 0, 0, 4483, 0, 0, - 0, 6080, 0, 0, 1746, 1315, 0, 70201, 0, 13140, 74508, 0, 0, 4480, 0, - 111113, 111112, 0, 67979, 0, 6360, 10897, 111106, 605, 68302, 110737, - 69875, 110735, 110736, 66681, 0, 0, 0, 0, 0, 0, 0, 10877, 118868, 64885, - 0, 0, 0, 0, 0, 0, 345, 0, 0, 64606, 9917, 0, 0, 92196, 0, 1776, 8422, - 43992, 0, 0, 0, 126543, 43328, 0, 0, 1295, 0, 42869, 0, 0, 0, 0, 128772, - 65123, 125210, 11293, 11288, 0, 0, 65666, 0, 92369, 65420, 0, 0, 4252, 0, - 0, 0, 706, 72800, 0, 0, 129931, 65419, 92177, 0, 8419, 65421, 0, 66702, - 0, 12670, 118608, 0, 0, 0, 72825, 65422, 83008, 0, 0, 0, 0, 0, 124153, - 9736, 4184, 65418, 0, 0, 74035, 0, 129955, 0, 0, 0, 0, 129447, 0, 7962, - 12211, 9837, 83505, 0, 0, 5719, 0, 129720, 119068, 73777, 1857, 0, 9927, - 0, 983959, 0, 10037, 0, 73695, 78322, 78319, 7818, 0, 0, 127769, 0, 0, 0, - 65077, 0, 78325, 78326, 78323, 43327, 43989, 0, 65828, 0, 0, 83499, 0, - 68390, 0, 110687, 78336, 78339, 9543, 78335, 78332, 78333, 0, 127964, 0, - 129552, 983914, 0, 69448, 0, 71429, 0, 0, 0, 11914, 69431, 0, 0, 0, 9949, - 0, 0, 119215, 0, 12073, 73519, 0, 0, 0, 101218, 2260, 0, 0, 0, 0, 0, 0, - 1939, 0, 0, 0, 69903, 0, 0, 0, 0, 6643, 92477, 128485, 0, 78330, 78331, - 78328, 78329, 0, 92551, 0, 0, 0, 0, 124124, 72417, 0, 0, 0, 0, 78341, - 78342, 120944, 78340, 129513, 127529, 92350, 3784, 78350, 0, 78348, - 78349, 78345, 43324, 78343, 78344, 2231, 0, 0, 0, 42467, 0, 0, 42894, - 78363, 13281, 78360, 78361, 78356, 78358, 78353, 64899, 0, 41149, 0, - 43162, 68096, 41150, 0, 10571, 67162, 67161, 67160, 67159, 6947, 41152, - 887, 9249, 6565, 64806, 74366, 0, 67158, 67157, 0, 10831, 67175, 67174, - 120232, 65827, 43325, 67178, 10168, 67176, 0, 0, 9190, 128497, 9666, - 41997, 0, 0, 0, 0, 0, 0, 129411, 0, 78508, 0, 78351, 78352, 0, 75063, - 72839, 983749, 0, 126604, 0, 0, 0, 983422, 0, 2270, 0, 129957, 0, 78365, - 0, 67189, 72818, 0, 0, 0, 0, 0, 0, 0, 72833, 101119, 78366, 78367, 0, 0, - 0, 0, 10137, 6121, 10995, 0, 71050, 8119, 0, 71052, 0, 0, 0, 0, 0, 0, 0, - 1394, 0, 0, 128960, 0, 67184, 2998, 67182, 67181, 67188, 67187, 67186, - 67185, 0, 101185, 0, 0, 67180, 42003, 0, 0, 67193, 67192, 67191, 67190, - 67197, 67196, 67195, 67194, 0, 72770, 43315, 71051, 0, 1593, 0, 125120, - 619, 4635, 0, 72875, 0, 128859, 118657, 0, 0, 0, 67199, 67198, 0, 42790, - 42006, 0, 0, 0, 128998, 10757, 9347, 127767, 0, 0, 74227, 78904, 0, - 74116, 128423, 121073, 120860, 0, 92427, 0, 0, 0, 0, 64590, 0, 4371, 0, - 0, 92478, 0, 0, 73977, 0, 0, 127847, 0, 120862, 0, 64550, 73745, 70451, - 0, 121013, 0, 0, 0, 129286, 0, 0, 0, 0, 9131, 118648, 125214, 983223, 0, - 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 983614, 0, 129648, 66455, 127533, - 3219, 0, 0, 0, 1037, 0, 64491, 0, 78579, 78572, 78580, 4568, 549, 0, 0, - 0, 0, 0, 128095, 70851, 2205, 0, 0, 0, 0, 129716, 0, 10825, 8079, 118962, - 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, - 65048, 1909, 42172, 0, 0, 10736, 11580, 72228, 7615, 0, 0, 4237, 66576, - 0, 65815, 68083, 0, 0, 0, 3489, 0, 0, 0, 0, 0, 0, 127146, 3796, 6800, 0, - 65582, 0, 129521, 0, 0, 68036, 0, 0, 64857, 121213, 126493, 0, 66308, 0, - 0, 64634, 127817, 0, 0, 0, 0, 3246, 0, 43972, 128643, 0, 0, 0, 0, 120751, - 0, 0, 0, 0, 1496, 42827, 0, 942, 2378, 119213, 0, 0, 0, 0, 9510, 1232, - 8139, 0, 0, 0, 11409, 0, 6382, 0, 66319, 121237, 0, 0, 0, 127887, 2374, - 0, 8475, 120844, 66313, 0, 0, 64879, 119298, 0, 0, 70869, 0, 0, 129025, - 0, 7705, 11942, 0, 0, 3309, 0, 119302, 0, 83345, 983866, 0, 0, 1280, - 6998, 128104, 0, 0, 0, 129945, 0, 0, 0, 0, 0, 0, 0, 74239, 983073, 0, 0, - 0, 6078, 121354, 0, 1475, 0, 9938, 6084, 0, 983995, 0, 118571, 0, 3256, - 0, 43973, 0, 0, 0, 8727, 0, 0, 0, 110831, 110832, 10562, 110830, 0, 0, 0, - 3248, 0, 0, 9015, 0, 0, 3635, 64337, 0, 0, 43852, 7195, 0, 2007, 64431, - 0, 0, 0, 0, 0, 0, 0, 65613, 77909, 0, 0, 0, 0, 119218, 7984, 11670, - 74434, 127770, 4176, 69248, 2034, 69442, 11154, 65891, 0, 0, 318, 2038, - 0, 0, 0, 3649, 13149, 42145, 42798, 3634, 0, 0, 128483, 122928, 124113, - 0, 11402, 120954, 94032, 74238, 0, 43313, 0, 0, 7938, 0, 1761, 0, 65379, - 68386, 128185, 1159, 71183, 0, 0, 0, 66687, 120851, 0, 41680, 0, 0, 0, - 1514, 11668, 67891, 9313, 0, 128490, 67877, 0, 41681, 0, 0, 12848, 69982, - 67873, 0, 74278, 0, 0, 12649, 0, 0, 1194, 3242, 9761, 9555, 8598, 0, - 120524, 0, 1551, 65447, 129414, 126211, 0, 0, 0, 67875, 0, 3495, 66648, - 125079, 0, 73024, 983232, 0, 126130, 10641, 0, 0, 0, 77845, 0, 0, 0, 0, - 0, 11131, 0, 0, 0, 0, 0, 42685, 72017, 193, 0, 0, 0, 42667, 0, 0, 92318, - 71958, 0, 1362, 9558, 0, 0, 0, 7351, 73789, 0, 0, 4426, 0, 0, 0, 0, 7276, - 42163, 5220, 0, 0, 67822, 0, 0, 0, 0, 41692, 0, 72283, 0, 0, 3223, 65492, - 0, 0, 4549, 983706, 0, 0, 101162, 10807, 0, 0, 0, 42182, 8688, 12866, 0, - 3294, 0, 0, 128101, 0, 64514, 0, 43329, 129989, 0, 0, 0, 119061, 0, - 43422, 0, 0, 128618, 0, 42729, 0, 3215, 120982, 68880, 917564, 0, 0, 0, - 65682, 0, 0, 65924, 0, 73506, 0, 1501, 0, 118807, 0, 0, 9607, 0, 65794, - 72243, 983046, 10989, 0, 74399, 0, 0, 7152, 0, 0, 129530, 7483, 125083, - 0, 8104, 70128, 7474, 0, 5189, 0, 0, 0, 8141, 0, 42537, 69612, 0, 0, 0, - 0, 0, 127307, 42934, 0, 0, 0, 0, 0, 0, 64517, 0, 0, 1650, 0, 0, 128502, - 7901, 3238, 0, 65556, 0, 0, 65158, 43416, 74959, 0, 7527, 0, 43319, 0, 0, - 45, 0, 0, 0, 0, 0, 7347, 0, 0, 0, 13129, 0, 9084, 0, 8737, 0, 0, 0, - 66808, 9639, 7912, 2620, 129653, 3564, 0, 0, 0, 0, 75049, 0, 2853, 0, 0, - 0, 0, 0, 2850, 8084, 0, 0, 71446, 92284, 43122, 0, 0, 0, 126503, 72214, - 0, 74767, 0, 7331, 110646, 0, 8245, 0, 3158, 92396, 3983, 0, 923, 0, - 69397, 292, 0, 126548, 0, 3221, 1763, 0, 0, 0, 0, 7253, 194636, 68391, - 75002, 0, 3637, 12996, 0, 70461, 0, 0, 3228, 0, 0, 0, 0, 0, 0, 120833, - 118939, 0, 7696, 78589, 0, 0, 0, 43316, 4177, 0, 9089, 0, 128805, 72116, - 64500, 68133, 0, 0, 1856, 100572, 0, 6379, 0, 118999, 0, 3208, 0, 0, 0, - 0, 0, 0, 129402, 0, 0, 0, 2033, 0, 0, 0, 55254, 7740, 0, 0, 0, 128197, 0, - 93988, 0, 67612, 0, 0, 41689, 129380, 0, 0, 6646, 0, 0, 0, 983964, 0, 0, - 4573, 0, 0, 0, 0, 0, 92961, 0, 118620, 41688, 0, 0, 0, 8314, 0, 0, 0, 0, - 0, 66721, 0, 0, 121033, 0, 128226, 0, 0, 0, 13164, 0, 66237, 983982, 0, - 0, 0, 3257, 0, 0, 1845, 0, 0, 0, 0, 128783, 0, 0, 0, 0, 3499, 8609, 0, - 7145, 0, 0, 0, 0, 74829, 984007, 983296, 0, 0, 0, 7591, 0, 0, 0, 73778, - 70132, 128167, 0, 0, 0, 0, 119261, 0, 0, 118561, 13083, 0, 0, 0, 0, - 66177, 983274, 5429, 0, 0, 68168, 66181, 0, 0, 983258, 0, 0, 5433, 67659, - 0, 42776, 1547, 66176, 92428, 0, 5425, 4977, 9999, 0, 5423, 64560, - 125094, 0, 0, 0, 74122, 0, 0, 0, 128003, 4418, 66199, 0, 92300, 0, 0, 0, - 11863, 124995, 0, 11908, 0, 9360, 125101, 983204, 0, 66187, 12837, - 983293, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983291, - 0, 129595, 0, 983801, 0, 9958, 0, 125108, 0, 0, 0, 2433, 128602, 0, 3352, - 0, 0, 0, 0, 0, 0, 305, 567, 67662, 0, 69979, 65242, 0, 41695, 0, 0, 0, - 7837, 92873, 129002, 5337, 917622, 7325, 43312, 917619, 68742, 917617, - 74086, 68777, 917614, 917613, 10973, 917611, 1372, 128768, 917608, - 917607, 1254, 917605, 917604, 93967, 917602, 65228, 113753, 129367, - 67723, 8068, 0, 0, 983970, 0, 3245, 64393, 119069, 118681, 0, 0, 0, 0, 0, - 0, 983284, 0, 119563, 129935, 78865, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, - 92698, 3226, 67695, 0, 0, 983958, 10200, 0, 128779, 101143, 0, 65610, 0, - 0, 0, 3585, 250, 101142, 43320, 0, 0, 0, 0, 1152, 129849, 1688, 0, 0, 0, - 0, 0, 121040, 128340, 0, 0, 0, 2107, 0, 129048, 0, 0, 0, 43868, 129832, - 129817, 0, 128239, 0, 0, 127777, 0, 6927, 42267, 42261, 11464, 3365, 0, - 0, 0, 0, 0, 41869, 0, 0, 0, 43326, 0, 11519, 0, 5530, 5210, 0, 983989, 0, - 5208, 0, 128842, 0, 2424, 7976, 0, 0, 3244, 5529, 0, 73894, 128852, 5432, - 0, 5527, 0, 78484, 0, 5528, 0, 0, 120281, 0, 0, 43545, 120282, 0, 0, - 73686, 42565, 0, 0, 3206, 120278, 73985, 0, 101149, 0, 0, 211, 3216, - 83407, 0, 120998, 3220, 68750, 0, 118586, 8951, 5214, 0, 8118, 0, 10768, - 8735, 0, 5852, 124952, 0, 0, 67513, 0, 0, 2623, 127859, 0, 0, 127388, - 4698, 66509, 0, 0, 4701, 0, 120289, 74225, 120284, 8267, 0, 1421, 66426, - 0, 0, 2625, 92724, 0, 74309, 0, 0, 0, 7850, 120296, 69639, 127032, 0, 0, - 43384, 12660, 110663, 0, 0, 110706, 110661, 0, 92380, 0, 0, 69649, 0, - 713, 41073, 0, 3990, 0, 0, 0, 5017, 128313, 120352, 0, 0, 1030, 0, - 983121, 9513, 0, 0, 0, 4668, 0, 120350, 0, 6339, 0, 0, 0, 64650, 0, 0, - 74766, 983869, 8908, 0, 0, 0, 0, 10752, 13003, 68769, 0, 41307, 8732, - 120336, 0, 41310, 0, 4696, 0, 983953, 0, 120334, 3641, 5419, 124119, 0, - 0, 0, 120344, 128129, 0, 7320, 65230, 11808, 0, 93970, 936, 13289, 0, - 69892, 65774, 0, 65243, 0, 19953, 0, 126469, 121375, 127256, 12913, - 70722, 68759, 0, 0, 70203, 0, 4113, 0, 2372, 1819, 0, 128053, 12152, 0, - 682, 7655, 120330, 129921, 0, 10593, 1703, 0, 0, 8033, 69953, 0, 9810, 0, - 0, 127949, 0, 119159, 10109, 0, 73898, 0, 71730, 126704, 0, 0, 917620, - 1965, 917621, 0, 0, 73887, 0, 0, 0, 6314, 0, 8501, 0, 0, 0, 41317, 0, - 5417, 983582, 0, 0, 9353, 68148, 41315, 0, 11161, 0, 41314, 194892, 0, - 126562, 119236, 634, 0, 0, 0, 69779, 4355, 12016, 0, 9654, 12856, 6924, - 7660, 0, 0, 0, 0, 0, 42692, 0, 74604, 0, 0, 0, 680, 6274, 0, 1181, 0, - 3174, 67248, 0, 0, 0, 0, 113776, 10650, 917603, 92295, 70672, 118965, 0, - 64644, 126981, 0, 0, 0, 0, 983961, 0, 65302, 40989, 68239, 68230, 68234, - 0, 0, 124989, 0, 40987, 4667, 0, 983963, 8828, 0, 0, 0, 4746, 0, 129840, - 2269, 4749, 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, - 68919, 0, 2245, 0, 0, 66790, 10850, 0, 0, 0, 983391, 0, 129853, 64680, 0, - 0, 120562, 0, 127324, 0, 100551, 128721, 0, 7316, 0, 983610, 100552, - 74157, 1646, 0, 0, 73995, 120857, 73500, 0, 7350, 0, 0, 0, 9099, 4107, - 3441, 0, 2975, 194701, 0, 983966, 55220, 10084, 73943, 120845, 118649, 0, - 0, 3399, 0, 0, 11909, 0, 0, 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, - 92589, 9151, 1137, 0, 749, 7505, 125076, 5385, 0, 69387, 0, 0, 41298, 0, - 69461, 0, 0, 0, 0, 0, 0, 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, - 0, 41297, 0, 0, 0, 41300, 74468, 65160, 0, 129839, 127511, 0, 0, 6558, 0, - 0, 128686, 92775, 0, 71450, 41302, 127927, 0, 0, 128646, 68762, 11729, - 8719, 9060, 0, 128796, 0, 0, 118573, 129682, 0, 11734, 93011, 11730, - 73450, 9593, 5757, 2403, 0, 55275, 0, 11728, 65894, 0, 0, 0, 68741, 0, 0, - 0, 43489, 4282, 983864, 0, 83497, 70328, 128103, 70324, 0, 69490, 127509, - 0, 8456, 0, 0, 74783, 0, 78250, 0, 70320, 120722, 9792, 0, 70326, 0, 0, - 83500, 70322, 10019, 71701, 123617, 6568, 4365, 129399, 0, 3647, 0, - 41134, 128341, 0, 125043, 41135, 0, 0, 0, 129938, 0, 123616, 0, 41137, - 41139, 0, 6545, 0, 125139, 7597, 10528, 75054, 0, 3732, 73910, 0, 0, 0, - 7312, 983639, 9062, 93840, 11853, 0, 0, 128324, 41538, 0, 0, 118702, 0, - 194706, 41531, 1263, 3720, 0, 68028, 0, 41524, 64692, 119635, 0, 41534, - 0, 92193, 0, 41168, 0, 67398, 127347, 3524, 0, 8831, 127349, 127357, 0, - 127360, 127352, 129816, 0, 0, 0, 0, 0, 5845, 0, 0, 0, 71909, 8200, 0, - 68460, 0, 43283, 5551, 0, 0, 0, 6340, 983552, 100602, 0, 0, 0, 0, 0, - 5422, 0, 0, 0, 2471, 0, 0, 2749, 0, 73774, 10913, 72122, 0, 8666, 675, - 74093, 0, 194986, 0, 69262, 0, 0, 0, 10928, 0, 41153, 0, 0, 0, 3738, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42347, 12092, 9615, 7234, 74047, - 129782, 0, 0, 123639, 0, 0, 2934, 0, 0, 0, 0, 74507, 0, 74461, 0, 0, - 74290, 0, 64562, 129975, 64473, 0, 0, 73728, 0, 11212, 0, 12128, 6534, 0, - 0, 1901, 0, 0, 0, 0, 0, 127520, 0, 0, 0, 0, 69940, 65459, 68293, 92290, - 128808, 3770, 0, 0, 0, 64579, 128511, 0, 0, 983337, 983345, 0, 0, 0, - 5941, 0, 0, 65079, 0, 0, 0, 73961, 983339, 0, 0, 0, 0, 0, 0, 10638, 0, 0, - 0, 71486, 0, 0, 983354, 0, 43840, 129495, 0, 5233, 983351, 64792, 71233, - 0, 983329, 0, 73553, 9847, 0, 1685, 595, 0, 73971, 1292, 8940, 0, 11088, - 0, 10004, 0, 0, 6541, 0, 0, 0, 5603, 9014, 5606, 0, 538, 128705, 5602, - 8467, 74391, 6547, 0, 0, 0, 0, 8458, 129534, 8495, 0, 0, 917552, 10981, - 78314, 125057, 2465, 0, 0, 0, 9730, 9280, 0, 0, 74155, 72766, 113690, 0, - 504, 0, 120715, 0, 983606, 0, 0, 0, 123141, 125024, 0, 0, 732, 3737, 0, - 1548, 0, 0, 1832, 5604, 0, 41141, 0, 5607, 72854, 2176, 3745, 0, 0, - 128137, 0, 0, 3869, 11937, 5725, 0, 66566, 7416, 5728, 0, 0, 0, 11918, - 66567, 5724, 118829, 5727, 0, 0, 0, 5723, 118585, 128116, 71999, 0, 0, 0, - 42532, 0, 12303, 0, 11423, 0, 983116, 68303, 74074, 0, 128267, 6559, - 64557, 71348, 0, 66763, 43019, 0, 10238, 0, 0, 43377, 0, 71346, 124937, - 9783, 42704, 0, 71719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41144, 129465, 0, - 0, 0, 72793, 92176, 0, 70682, 0, 8820, 0, 0, 0, 11515, 526, 0, 0, 0, 0, - 0, 0, 8635, 0, 0, 8288, 11815, 0, 0, 0, 1543, 3713, 0, 0, 0, 68041, - 127816, 0, 0, 64357, 0, 42082, 0, 0, 8987, 42081, 0, 0, 0, 0, 0, 0, 6553, - 0, 0, 11253, 0, 0, 5475, 0, 0, 0, 119334, 12990, 1160, 42084, 0, 123152, - 0, 0, 360, 0, 0, 128274, 5863, 3137, 0, 983320, 0, 0, 10959, 3146, 0, - 127374, 0, 68341, 13076, 3135, 983303, 0, 0, 3142, 0, 94068, 10819, - 128479, 0, 74635, 12877, 119867, 73967, 0, 70808, 0, 0, 0, 0, 6163, - 129745, 113728, 0, 0, 0, 8603, 0, 0, 3306, 0, 43392, 0, 917565, 5751, 0, - 0, 0, 0, 0, 7403, 0, 118933, 0, 122628, 64783, 92658, 0, 0, 129592, 0, 0, - 65569, 7021, 0, 0, 119864, 0, 0, 6540, 6974, 0, 0, 0, 0, 0, 0, 0, 983655, - 0, 43585, 0, 6551, 983993, 0, 0, 0, 0, 0, 72216, 8977, 602, 120814, 0, 0, - 0, 72119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983624, 74812, 0, 0, 0, 9475, 0, - 65105, 0, 118556, 0, 43592, 7831, 66751, 0, 0, 73915, 0, 43593, 0, 43591, - 43061, 0, 0, 43589, 43584, 0, 13113, 0, 0, 43590, 8766, 9087, 0, 0, - 41574, 78337, 0, 42900, 6376, 0, 0, 0, 0, 9854, 0, 0, 0, 0, 0, 0, 0, - 2909, 110928, 0, 0, 6529, 110930, 75004, 3751, 0, 0, 0, 1798, 0, 0, 1354, - 0, 13152, 6557, 12430, 0, 94098, 0, 0, 0, 68123, 128097, 0, 0, 0, 71264, - 123559, 11082, 0, 65677, 8682, 42054, 92595, 42045, 9804, 0, 0, 3595, 0, - 0, 119498, 0, 42399, 0, 0, 0, 65541, 0, 7324, 0, 0, 0, 8797, 77895, 0, - 64888, 7167, 2356, 95, 110810, 0, 0, 42286, 0, 0, 69999, 0, 120877, 0, 0, - 42324, 129359, 0, 0, 43492, 0, 43406, 0, 0, 0, 0, 0, 43400, 0, 0, 71720, - 0, 66435, 0, 0, 3201, 514, 74502, 0, 43396, 0, 64493, 0, 43404, 11218, 0, - 0, 43398, 0, 0, 41341, 129485, 6564, 1463, 41342, 0, 5293, 0, 0, 3733, 0, - 0, 41344, 0, 0, 0, 0, 41346, 0, 69747, 0, 0, 0, 0, 0, 0, 0, 983764, 0, 0, - 0, 65272, 0, 0, 1270, 1132, 0, 0, 0, 66655, 0, 0, 74314, 64761, 0, - 110853, 8510, 0, 129600, 0, 0, 0, 0, 0, 0, 69692, 0, 0, 42383, 69690, 0, - 69700, 13141, 0, 92465, 0, 0, 0, 41566, 0, 0, 129334, 127171, 0, 0, 0, 0, - 0, 0, 0, 6308, 0, 0, 2611, 0, 66881, 0, 65063, 0, 0, 0, 0, 4484, 8747, - 110597, 128369, 0, 0, 0, 0, 0, 0, 12902, 0, 0, 7299, 0, 0, 12107, 7100, - 10905, 65010, 0, 125135, 66018, 9284, 0, 0, 0, 0, 0, 0, 0, 12010, 0, - 126093, 120949, 121032, 0, 0, 0, 0, 0, 0, 0, 0, 6618, 3562, 66365, 0, - 42234, 12648, 128039, 0, 0, 0, 41309, 9764, 41316, 0, 0, 13230, 41299, 0, - 0, 68365, 0, 0, 0, 0, 0, 0, 4153, 0, 0, 128047, 0, 0, 42889, 0, 129322, - 41578, 0, 41577, 0, 68092, 0, 6533, 0, 41570, 0, 72414, 0, 41580, 74628, - 0, 12901, 0, 0, 0, 0, 71461, 41360, 0, 0, 4743, 0, 0, 0, 0, 68398, - 110781, 5890, 110779, 111103, 3739, 8695, 92514, 0, 3964, 8984, 111095, - 68288, 0, 0, 70000, 111090, 111089, 67504, 3956, 82952, 111093, 6563, - 111091, 41305, 0, 0, 12067, 41312, 0, 0, 0, 129708, 0, 8175, 0, 3600, 0, - 934, 0, 0, 173, 129844, 0, 110784, 110785, 1750, 110783, 41358, 68368, - 1807, 0, 92298, 0, 5889, 0, 0, 0, 67127, 129472, 0, 121395, 6982, 1721, - 0, 7891, 0, 42160, 67129, 4512, 983790, 69460, 0, 0, 0, 122636, 0, - 120716, 0, 0, 0, 0, 0, 119140, 3975, 72253, 74087, 0, 12672, 0, 129821, - 0, 0, 129836, 0, 121100, 0, 0, 41095, 3962, 68242, 2932, 41101, 3954, - 6457, 4513, 0, 0, 0, 0, 1468, 0, 0, 55237, 128230, 0, 127244, 55238, - 41080, 0, 0, 4320, 74104, 0, 0, 83315, 0, 77918, 118563, 128384, 8256, 0, - 72413, 0, 8879, 0, 0, 8770, 0, 0, 92214, 0, 0, 128786, 4283, 129689, 0, - 68361, 0, 74826, 0, 0, 0, 0, 127954, 65106, 42761, 121516, 4581, 8411, 0, - 0, 72259, 0, 93037, 0, 0, 0, 92452, 4392, 0, 10786, 69661, 0, 8184, 0, 0, - 7396, 0, 0, 69788, 0, 43512, 7965, 111039, 111038, 111037, 111036, 41350, - 0, 0, 0, 2294, 64501, 68034, 0, 68405, 111034, 0, 0, 111030, 111029, - 71105, 111027, 0, 111033, 92200, 111031, 0, 6764, 0, 0, 111026, 111025, - 72454, 65203, 128010, 0, 0, 0, 3210, 0, 129978, 0, 0, 82958, 127970, - 82957, 0, 68875, 10043, 71979, 1186, 41571, 0, 5209, 9464, 82960, 66657, - 5207, 65062, 5213, 0, 0, 41348, 41568, 128803, 3253, 111045, 111044, - 74067, 111042, 111049, 5596, 111047, 111046, 0, 64887, 0, 5217, 111041, - 72252, 0, 0, 0, 0, 2635, 92760, 0, 0, 0, 92742, 0, 113672, 0, 0, 0, 2258, - 67081, 0, 67083, 0, 0, 0, 5784, 0, 0, 0, 0, 4011, 0, 0, 0, 0, 4254, 0, - 111054, 5600, 111052, 111051, 10447, 5598, 1207, 111055, 0, 3501, 42582, - 0, 111050, 0, 1124, 5597, 983501, 78908, 9321, 129464, 75040, 983498, 0, - 1719, 68356, 68354, 9671, 1125, 2721, 0, 129876, 983504, 7631, 5488, - 111082, 0, 0, 5491, 111086, 8937, 0, 3236, 74187, 5490, 0, 5489, 8522, - 68358, 111069, 6300, 111067, 111066, 0, 0, 111071, 111070, 0, 9875, 7593, - 111065, 0, 0, 43182, 0, 68379, 3311, 111058, 111057, 3746, 11016, 65752, - 111061, 0, 43423, 68775, 0, 111056, 72225, 0, 0, 127120, 0, 2232, 0, 0, - 0, 0, 0, 126555, 0, 0, 8656, 0, 128358, 0, 0, 983490, 983491, 917563, - 983489, 983486, 983487, 0, 0, 0, 129669, 0, 111183, 128043, 983495, 1036, - 983493, 111075, 1723, 111073, 111072, 111079, 41579, 111077, 111076, - 10705, 0, 983485, 74486, 71693, 740, 983481, 983482, 129645, 0, 0, 74846, - 92255, 0, 0, 0, 0, 0, 10438, 74487, 73798, 13285, 0, 0, 0, 5690, 0, - 93992, 0, 0, 13095, 0, 127857, 121419, 7321, 121203, 13254, 70176, 75070, - 0, 0, 0, 0, 127845, 3247, 317, 0, 0, 0, 0, 917543, 0, 10173, 0, 0, 0, 0, - 0, 5223, 0, 0, 119564, 5226, 0, 94044, 5880, 94065, 7758, 0, 0, 5224, - 5487, 94041, 5692, 41725, 983467, 0, 5695, 41711, 0, 43171, 0, 94049, - 5691, 983472, 866, 1488, 983471, 983457, 65665, 94036, 983456, 74797, 0, - 0, 11039, 983465, 11145, 71211, 983464, 983461, 983462, 983459, 983460, - 42492, 43402, 125208, 3302, 0, 72842, 43153, 0, 0, 120885, 121300, 0, - 7856, 8690, 0, 73076, 110880, 0, 0, 73091, 0, 69925, 120635, 65153, 0, 0, - 0, 0, 0, 0, 4540, 0, 0, 0, 0, 11844, 121209, 8863, 0, 75061, 71978, 6389, - 0, 42371, 83205, 8790, 120911, 0, 111125, 71168, 8869, 0, 0, 42060, 0, - 9648, 111123, 71170, 10270, 10286, 10318, 10382, 43529, 0, 0, 0, 0, 0, - 70110, 43835, 119520, 70111, 119360, 118815, 127084, 127083, 8767, 0, - 128437, 41281, 0, 5201, 0, 6215, 67072, 6214, 13101, 0, 0, 65268, 67073, - 0, 0, 127976, 72995, 127073, 10511, 42075, 0, 73475, 129509, 0, 67115, - 127069, 111293, 127068, 0, 127067, 0, 74845, 0, 42071, 43156, 0, 0, 0, 0, - 7954, 0, 0, 0, 8485, 4671, 0, 69513, 4740, 0, 0, 42618, 78294, 3064, - 6212, 0, 0, 0, 9554, 0, 83044, 0, 126598, 0, 78291, 6159, 6213, 12885, 0, - 129086, 64720, 0, 983926, 0, 0, 0, 11430, 0, 7518, 9317, 0, 3729, 10406, - 0, 119259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73825, 0, 0, 129599, 8786, 10390, - 0, 0, 917601, 93034, 0, 7924, 0, 43307, 0, 0, 0, 0, 0, 0, 118843, 9623, - 435, 0, 0, 12893, 8093, 9079, 0, 0, 0, 0, 0, 64430, 0, 10294, 10326, 0, - 0, 0, 0, 0, 0, 3623, 125188, 83378, 0, 43197, 0, 111149, 0, 78296, 0, 0, - 0, 7914, 0, 69749, 0, 2624, 0, 0, 0, 120859, 67110, 11058, 0, 67107, 0, - 0, 0, 0, 120793, 0, 0, 6717, 10619, 0, 0, 0, 11832, 128664, 0, 0, 0, - 70202, 0, 0, 0, 3232, 73824, 74581, 0, 0, 0, 41889, 0, 0, 1161, 41895, - 74103, 9701, 0, 0, 129385, 73819, 120588, 5012, 0, 41362, 0, 68507, 0, 0, - 0, 0, 0, 41364, 0, 0, 41352, 41361, 0, 41366, 0, 70129, 129065, 917, 0, - 119934, 119923, 92421, 119912, 0, 119924, 64841, 118582, 71482, 0, 0, 0, - 125136, 128583, 0, 7022, 0, 4739, 0, 5802, 9816, 8615, 0, 0, 491, 65837, - 0, 0, 128644, 0, 8426, 11092, 9891, 0, 0, 0, 41881, 118823, 3736, 7394, - 42648, 0, 68448, 9095, 7741, 12684, 41885, 0, 0, 0, 0, 5815, 0, 0, 0, - 127392, 0, 0, 41878, 0, 0, 0, 0, 0, 0, 0, 0, 119503, 0, 120804, 0, 0, - 2267, 0, 78289, 78359, 78288, 0, 0, 78318, 65920, 0, 194819, 7057, 9408, - 9409, 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, - 9421, 5897, 9423, 917933, 127107, 0, 127108, 917937, 127963, 8955, 9399, - 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 0, 128626, 42669, 73832, - 78261, 67683, 2631, 119308, 78259, 0, 78260, 3996, 0, 119307, 0, 0, 0, 0, - 0, 0, 64825, 917916, 917913, 917914, 917919, 5899, 917917, 129990, 12085, - 0, 574, 69734, 77825, 73828, 9473, 77824, 118918, 73900, 41735, 42211, 0, - 4190, 77834, 77835, 77830, 77833, 3616, 77828, 77837, 77838, 7708, 77836, - 2228, 113765, 0, 0, 4191, 42968, 77844, 73800, 77842, 77843, 77839, - 77840, 0, 78311, 83375, 0, 0, 10415, 74102, 0, 5896, 0, 10351, 67151, 0, - 73829, 0, 127159, 0, 73998, 41355, 42883, 70736, 71212, 8021, 0, 119150, - 983732, 41357, 8011, 42885, 42887, 41354, 0, 0, 10026, 5472, 120554, - 1191, 101217, 5470, 128784, 5476, 101216, 0, 0, 0, 42874, 78281, 42876, - 6304, 78283, 0, 2675, 120690, 0, 0, 128954, 0, 0, 5478, 5904, 0, 0, 0, - 7291, 77848, 43761, 13067, 0, 0, 119271, 120360, 69731, 77856, 77857, - 77854, 77855, 77852, 77853, 77850, 10750, 43714, 77858, 0, 0, 0, 12887, - 120364, 127745, 77866, 77867, 77864, 77865, 9929, 5199, 77859, 1120, 0, - 0, 0, 9486, 7554, 0, 77868, 72832, 0, 0, 5894, 70069, 0, 0, 92511, 70358, - 1323, 13162, 120937, 0, 0, 0, 77881, 66022, 0, 72857, 0, 0, 0, 0, 0, - 1142, 0, 8271, 0, 0, 126645, 12903, 43622, 4002, 0, 10442, 10676, 120368, - 0, 120369, 0, 0, 0, 0, 66642, 1277, 0, 7871, 0, 0, 78853, 0, 119015, 0, - 0, 11784, 0, 78012, 4700, 0, 78858, 0, 78855, 0, 0, 92400, 77879, 19932, - 77876, 77877, 74804, 77874, 77869, 77871, 0, 71487, 43118, 0, 0, 6774, - 6773, 0, 194684, 10346, 10410, 78860, 118974, 0, 101197, 6108, 0, 110612, - 0, 0, 5901, 121309, 74166, 124973, 0, 0, 0, 69407, 0, 70357, 0, 0, 74217, - 0, 64698, 4192, 9289, 0, 0, 128847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11603, 0, - 0, 101166, 82976, 0, 0, 67812, 0, 101163, 0, 42572, 0, 128300, 119146, - 1963, 11622, 0, 43237, 82981, 7550, 67100, 5903, 82984, 78009, 129750, - 9662, 0, 128391, 0, 0, 0, 0, 11013, 0, 0, 0, 128433, 67090, 0, 0, 0, 0, - 0, 11568, 983704, 43367, 0, 0, 7852, 119496, 0, 0, 0, 0, 194676, 0, - 194675, 0, 0, 416, 129668, 0, 73834, 0, 68921, 10984, 0, 0, 101175, - 129838, 101182, 0, 127013, 92423, 0, 983261, 121199, 0, 0, 12540, 0, - 983220, 0, 0, 11445, 101168, 2112, 0, 0, 0, 1021, 0, 9507, 10210, 78005, - 8023, 93963, 78006, 78001, 43181, 78003, 9532, 119094, 0, 0, 0, 0, 0, - 1885, 43268, 129802, 129798, 120542, 121153, 392, 7894, 4391, 129810, - 8221, 119597, 77999, 77998, 0, 0, 0, 92967, 0, 3558, 0, 3913, 70429, - 121376, 0, 0, 1265, 0, 6309, 0, 12969, 0, 101151, 0, 101146, 0, 101139, - 0, 41864, 0, 0, 74294, 0, 167, 0, 917584, 0, 93983, 72354, 68477, 0, 0, - 917594, 0, 2493, 129827, 0, 129804, 0, 917570, 917593, 0, 0, 406, 917592, - 0, 0, 0, 0, 0, 0, 0, 127161, 0, 128597, 0, 0, 0, 3421, 10561, 0, 8365, - 917581, 0, 127569, 120787, 128669, 0, 0, 0, 0, 7834, 0, 0, 101154, 10298, - 6624, 4908, 0, 1639, 120842, 0, 0, 6327, 6724, 0, 0, 0, 69910, 4817, 0, - 0, 0, 68059, 0, 11022, 0, 0, 0, 118888, 0, 0, 7548, 64794, 0, 12291, - 983166, 0, 0, 0, 0, 0, 0, 1134, 1838, 0, 2057, 0, 0, 0, 0, 0, 0, 5206, 0, - 0, 42523, 0, 0, 0, 0, 65550, 8570, 4816, 0, 127926, 0, 4821, 0, 0, 0, - 4818, 125257, 119974, 119977, 0, 0, 119970, 119973, 0, 119983, 119982, - 67470, 119984, 119979, 119978, 0, 119980, 119670, 129297, 0, 11284, - 119987, 70097, 65155, 119988, 0, 9363, 0, 0, 0, 5900, 93990, 7889, 2722, - 128770, 0, 0, 0, 0, 2282, 0, 0, 0, 68093, 0, 0, 0, 0, 0, 70150, 118628, - 0, 0, 0, 129651, 70146, 983079, 119967, 71330, 70148, 0, 0, 94006, 70144, - 119964, 110677, 110678, 110675, 110676, 0, 110674, 4226, 0, 123165, 5732, - 71327, 0, 0, 65119, 0, 0, 92971, 64770, 0, 0, 6093, 0, 0, 1395, 0, 0, 0, - 121179, 786, 0, 43174, 64340, 0, 125269, 0, 983662, 125138, 10132, 0, 0, - 0, 0, 0, 93956, 0, 68444, 0, 92437, 123143, 0, 0, 92656, 0, 0, 0, 1399, - 121463, 0, 121465, 121464, 120808, 241, 121469, 4907, 0, 0, 0, 0, 0, 0, - 0, 0, 127904, 0, 0, 42780, 0, 0, 0, 4217, 0, 0, 0, 0, 72158, 0, 0, 43099, - 3965, 0, 0, 0, 13300, 0, 0, 43057, 0, 0, 0, 0, 0, 65372, 0, 6410, 126073, - 125252, 70468, 0, 0, 0, 119558, 0, 0, 0, 0, 0, 0, 43188, 2626, 7762, 0, - 0, 0, 127183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67726, 0, 126993, 1542, 0, 0, - 92550, 0, 0, 74311, 0, 0, 10181, 2150, 0, 0, 0, 0, 124921, 68053, 6029, - 72852, 0, 0, 0, 0, 8993, 0, 0, 0, 93968, 606, 118664, 0, 0, 0, 4311, 0, - 6027, 126615, 4322, 0, 65207, 0, 2184, 983920, 0, 0, 2735, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 70806, 0, 73547, 0, 92783, 92844, 0, 65817, 55288, - 127934, 66564, 8530, 0, 7709, 0, 121202, 66560, 128528, 917595, 12876, - 66561, 0, 121430, 983957, 7789, 5855, 809, 0, 0, 72853, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 64386, 0, 74909, 64845, 120607, 66416, 83360, 6532, 0, 0, - 0, 0, 128224, 0, 0, 0, 0, 43091, 92287, 0, 0, 129312, 0, 0, 0, 11361, 0, - 0, 8153, 128105, 0, 10741, 0, 0, 0, 0, 0, 64706, 917922, 0, 69505, 78870, - 9466, 78866, 9824, 0, 0, 0, 120977, 915, 0, 0, 43865, 0, 0, 0, 67131, - 70096, 67137, 0, 129614, 73648, 6730, 78862, 68161, 0, 78861, 126542, 0, - 0, 94010, 118655, 0, 0, 66043, 0, 0, 43107, 0, 0, 92343, 0, 73879, 0, 0, - 0, 6103, 0, 0, 92470, 0, 12889, 0, 127137, 0, 0, 0, 0, 0, 0, 119262, - 83028, 0, 0, 0, 69279, 0, 0, 0, 13118, 7700, 917537, 9690, 0, 0, 68080, - 512, 0, 72792, 0, 0, 77892, 632, 77890, 77891, 42529, 0, 0, 0, 0, 0, 0, - 0, 128273, 0, 0, 7379, 64581, 5386, 0, 0, 10633, 72316, 64488, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 124956, 71307, 0, 0, 0, 0, 0, 92370, 0, 0, 0, 0, 0, - 71314, 1801, 0, 0, 120867, 0, 0, 77888, 2085, 702, 77887, 77884, 77885, - 13074, 77883, 66299, 0, 0, 12106, 78905, 0, 1755, 0, 77897, 77898, 1163, - 3102, 77893, 77894, 0, 0, 0, 0, 69227, 0, 77901, 77902, 77899, 77900, - 65171, 0, 0, 0, 70157, 0, 0, 0, 64846, 2908, 0, 11177, 64902, 64950, 0, - 128740, 66906, 124959, 70499, 0, 0, 0, 64352, 0, 125031, 1007, 0, 9199, - 0, 127371, 118992, 41890, 0, 2730, 119072, 0, 5428, 0, 73771, 129993, 0, - 0, 0, 71458, 0, 0, 0, 68089, 0, 44012, 0, 71456, 0, 9158, 66878, 69905, - 92440, 0, 101272, 0, 484, 0, 0, 0, 194742, 0, 0, 0, 0, 572, 7041, 2736, - 0, 0, 93962, 0, 68628, 0, 128727, 5438, 5222, 5381, 43114, 0, 5193, 5125, - 5456, 5509, 0, 120664, 113700, 0, 0, 0, 3430, 0, 42905, 0, 74929, 6050, - 0, 0, 129197, 0, 0, 10908, 0, 0, 127809, 64617, 0, 0, 3957, 0, 0, 0, 674, - 0, 0, 2946, 5354, 5251, 5328, 5307, 3759, 72318, 8364, 5123, 0, 5281, - 5469, 5121, 0, 0, 0, 5130, 0, 129608, 0, 0, 0, 1221, 2733, 0, 0, 0, - 72321, 127245, 0, 0, 0, 101277, 0, 5939, 0, 0, 0, 71867, 68400, 128216, - 10321, 10289, 0, 10385, 123164, 0, 0, 0, 0, 118943, 0, 11411, 0, 5938, 0, - 120865, 0, 0, 10401, 10337, 0, 0, 0, 0, 0, 0, 0, 71942, 0, 0, 12165, 0, - 0, 9885, 0, 8077, 0, 127908, 0, 0, 0, 0, 129138, 4220, 10725, 10433, 0, - 68395, 4987, 64519, 0, 0, 0, 123626, 120356, 0, 11733, 0, 120792, 0, - 127233, 0, 0, 0, 92345, 68254, 983661, 77991, 0, 2724, 0, 0, 12313, - 110619, 515, 119947, 119944, 119945, 119942, 119943, 119940, 119941, - 119938, 8606, 4046, 4589, 4521, 0, 9141, 0, 0, 2741, 0, 0, 1370, 0, 0, 0, - 0, 0, 0, 66880, 0, 66003, 0, 64440, 0, 129943, 69458, 0, 11593, 68669, - 68666, 68660, 0, 0, 2744, 72285, 68638, 0, 814, 0, 119962, 119963, - 119960, 119961, 101106, 43029, 119956, 11623, 119954, 11955, 119952, - 119953, 41986, 119951, 0, 120497, 4847, 110975, 0, 0, 0, 0, 1581, 64920, - 93830, 12954, 963, 110973, 110972, 110971, 110969, 5278, 110967, 68621, - 92222, 983454, 68625, 983452, 68617, 110960, 0, 101459, 101487, 110964, - 110963, 110962, 0, 0, 101464, 101483, 101463, 983443, 983440, 92648, - 127379, 0, 65137, 6483, 65392, 0, 4213, 129649, 41303, 0, 0, 0, 41306, - 129751, 2698, 0, 0, 0, 68396, 0, 41304, 824, 0, 78011, 72315, 78894, - 74827, 78892, 64804, 9820, 119820, 110985, 110976, 0, 6739, 0, 5481, - 3490, 110978, 110977, 71706, 69947, 67702, 9124, 12688, 119833, 101496, - 0, 101495, 119821, 119824, 67480, 42575, 101474, 101478, 119827, 101481, - 101476, 71087, 68658, 119946, 8025, 68630, 101490, 68675, 92445, 71097, - 69613, 0, 0, 0, 0, 983435, 2745, 11797, 110990, 983431, 9202, 983429, - 983430, 0, 0, 0, 10525, 5436, 74584, 110987, 110986, 121506, 43080, - 121508, 121507, 983420, 6246, 119958, 10921, 9723, 6777, 6776, 6775, 0, - 0, 70287, 92384, 0, 8669, 0, 0, 65093, 0, 78881, 2716, 0, 0, 11252, - 101475, 68369, 0, 11060, 12985, 2711, 78872, 78027, 78026, 7992, 0, 0, - 42938, 78033, 78032, 78877, 70724, 78029, 78028, 78031, 78030, 64535, - 110998, 10130, 110996, 0, 0, 111001, 111000, 127914, 983417, 78014, 5713, - 110995, 7570, 110993, 110992, 0, 11190, 129700, 9026, 0, 74864, 7547, - 78891, 0, 10008, 10222, 0, 129543, 9744, 0, 68809, 983413, 119656, - 983411, 94070, 983409, 983410, 983407, 9045, 78888, 4225, 78886, 78887, - 68757, 78885, 78882, 78883, 983402, 983403, 8405, 983401, 10423, 10359, - 983396, 983397, 0, 129149, 4215, 9789, 0, 4321, 12309, 983405, 41313, 0, - 5368, 66886, 0, 0, 5366, 0, 5372, 101482, 67512, 0, 7720, 7390, 2696, 0, - 0, 8268, 0, 1790, 0, 0, 118977, 0, 0, 0, 5376, 1835, 72313, 78704, - 128089, 0, 0, 68655, 1180, 0, 0, 0, 0, 119274, 0, 0, 9122, 118584, 11928, - 0, 65283, 0, 101449, 5971, 101448, 43500, 1268, 65097, 983222, 0, 101445, - 0, 1427, 128440, 0, 5970, 3431, 72299, 101439, 101435, 983389, 983390, - 983387, 2738, 125066, 10455, 0, 74026, 0, 4222, 6240, 0, 119013, 983394, - 68377, 6248, 983378, 67815, 983376, 917907, 92582, 0, 101453, 125215, 0, - 2728, 65549, 64563, 101428, 101425, 101429, 128145, 0, 10713, 7166, - 119559, 2622, 101450, 0, 0, 0, 8954, 0, 94008, 2632, 42617, 10108, 1011, - 42852, 12080, 2709, 0, 5716, 0, 0, 0, 0, 127100, 69378, 0, 9515, 127098, - 66465, 6451, 0, 127097, 8918, 983556, 0, 0, 19950, 0, 0, 0, 44003, 0, - 64735, 0, 0, 0, 0, 983500, 74022, 0, 128795, 68643, 67410, 0, 5721, 0, 0, - 0, 121074, 11267, 983369, 66464, 5720, 983368, 0, 4219, 5718, 8696, 5717, - 122651, 983375, 983897, 983373, 541, 983371, 983372, 119948, 119089, - 68389, 983357, 119949, 56, 4216, 10577, 0, 0, 77849, 69620, 983362, - 983363, 66899, 983361, 0, 0, 67628, 0, 0, 7086, 0, 67998, 67621, 0, 2734, - 69616, 0, 67627, 118937, 0, 67625, 0, 0, 0, 42593, 0, 128217, 0, 0, - 119939, 0, 68180, 0, 0, 71104, 7442, 43665, 359, 41253, 68392, 6239, - 120599, 41256, 0, 67740, 111023, 111022, 111021, 9346, 69660, 41254, 0, - 43291, 78002, 0, 67491, 124993, 93841, 0, 0, 0, 4368, 983505, 0, 68137, - 0, 0, 41024, 0, 0, 121359, 121420, 0, 0, 0, 4223, 0, 8574, 83502, 0, 0, - 0, 118576, 0, 92718, 983636, 70432, 128323, 68382, 0, 0, 0, 0, 0, 4144, - 0, 83193, 6245, 0, 2732, 92644, 0, 0, 64558, 83501, 0, 0, 0, 128005, 0, - 0, 129652, 983149, 3097, 0, 0, 77996, 0, 0, 10863, 111020, 111019, - 111018, 0, 111015, 111014, 111013, 111012, 118964, 0, 10216, 64293, 0, 0, - 69393, 128331, 12325, 111010, 8717, 111008, 101413, 0, 101380, 0, 8700, - 0, 101382, 68363, 10426, 0, 71091, 10362, 0, 1715, 101378, 0, 64918, - 101409, 43278, 42635, 0, 0, 65275, 0, 0, 101319, 0, 69746, 1607, 466, - 118949, 0, 0, 127918, 6243, 983901, 1350, 74195, 64420, 1993, 5362, - 10666, 2708, 92471, 0, 13143, 234, 3199, 0, 41268, 6334, 2173, 0, 0, - 73750, 0, 73762, 10458, 0, 8576, 127136, 0, 2704, 64953, 0, 64832, 8322, - 0, 3132, 0, 2694, 0, 0, 2439, 65104, 69804, 0, 303, 74625, 92622, 0, - 2437, 0, 9817, 4844, 0, 0, 0, 0, 0, 121120, 43292, 0, 2441, 0, 0, 0, 0, - 0, 2451, 2714, 0, 0, 43379, 127984, 74541, 753, 5849, 0, 43089, 0, 0, - 119534, 72380, 0, 0, 0, 2726, 3107, 0, 0, 64937, 0, 78841, 1408, 0, 4607, - 101299, 181, 0, 67728, 9539, 0, 0, 65201, 121121, 92973, 64185, 4142, - 64183, 0, 0, 0, 9706, 64178, 64177, 64176, 0, 64182, 64181, 64180, 64179, - 11401, 125124, 0, 1822, 0, 128581, 68055, 3865, 122918, 0, 10500, 129602, - 119024, 0, 110732, 9830, 0, 0, 0, 65131, 0, 0, 0, 0, 74608, 7038, 0, - 9599, 8748, 0, 0, 9557, 0, 0, 0, 11494, 0, 0, 10865, 0, 43279, 64186, - 68521, 0, 64191, 64190, 8898, 64188, 129153, 41030, 78836, 0, 0, 78820, - 126100, 0, 78805, 78806, 78801, 78802, 6745, 78800, 0, 0, 0, 110866, 0, - 0, 73679, 67838, 41039, 78809, 128162, 0, 129893, 0, 110869, 127045, - 110867, 110868, 127039, 4400, 0, 64207, 10275, 8925, 10371, 10307, 64202, - 4248, 0, 72802, 4541, 6299, 64204, 64203, 64201, 64200, 64199, 64198, - 126471, 0, 0, 0, 64193, 64192, 0, 9943, 64197, 64196, 64195, 64194, - 13282, 42652, 64174, 64173, 83495, 846, 72337, 9965, 74495, 72330, 83493, - 83494, 2543, 12163, 64170, 83490, 64167, 64166, 64165, 64164, 72333, 0, - 64169, 64168, 64949, 0, 10251, 10247, 64163, 64162, 2295, 43299, 43301, - 129363, 0, 70791, 0, 0, 550, 9910, 0, 0, 66579, 0, 0, 0, 9504, 0, 0, - 10373, 0, 0, 10261, 10253, 7821, 10277, 0, 74823, 1552, 0, 0, 129389, 0, - 121435, 19910, 0, 0, 118849, 121150, 0, 43985, 68051, 0, 69890, 121329, - 78355, 983776, 0, 66405, 2431, 3744, 66852, 1809, 0, 0, 0, 73759, 1264, - 0, 78676, 11697, 121278, 9785, 64716, 0, 0, 0, 0, 121307, 0, 0, 42609, - 128388, 0, 66912, 127016, 0, 983904, 74229, 118590, 6487, 93798, 70743, - 0, 0, 0, 83484, 83485, 83486, 83487, 83480, 8355, 7854, 83483, 954, - 64927, 0, 41045, 0, 41438, 0, 0, 10711, 0, 0, 0, 0, 64774, 13309, 10947, - 66727, 101426, 0, 0, 66795, 0, 0, 0, 0, 0, 0, 0, 120634, 69228, 0, 0, 0, - 0, 101430, 0, 3060, 83478, 9986, 0, 83473, 83474, 11698, 77880, 83469, - 9916, 11701, 83472, 42586, 0, 8320, 0, 119095, 0, 0, 1477, 43289, 0, - 74358, 10884, 69446, 9908, 0, 0, 0, 3414, 74304, 0, 0, 0, 0, 2110, 0, - 68306, 0, 74532, 0, 129865, 0, 0, 7164, 0, 0, 0, 11950, 5392, 42248, - 65129, 68656, 5397, 129579, 0, 68136, 0, 0, 5395, 72870, 5393, 354, - 68615, 0, 0, 0, 0, 0, 126236, 0, 0, 626, 0, 5895, 0, 0, 5780, 0, 66407, - 10220, 0, 71121, 43297, 0, 0, 11468, 64436, 0, 0, 0, 73818, 3918, 0, - 3797, 72786, 122961, 0, 4140, 0, 71254, 0, 9030, 813, 0, 68131, 4146, - 119957, 5360, 0, 129498, 0, 0, 6249, 0, 0, 0, 0, 0, 73092, 0, 4911, 988, - 0, 73125, 0, 42948, 0, 0, 0, 0, 74972, 0, 0, 0, 9825, 0, 0, 12803, - 126977, 11032, 67654, 6244, 0, 0, 68662, 0, 129351, 0, 72131, 4169, 0, 0, - 0, 129986, 121410, 120657, 0, 0, 68657, 128943, 78496, 0, 0, 5898, 74540, - 0, 41856, 93056, 194926, 118538, 127373, 83424, 83425, 83426, 73736, - 83420, 68870, 6448, 6835, 0, 4831, 83418, 83419, 67731, 0, 0, 0, 0, 0, 0, - 0, 78499, 0, 0, 0, 43288, 122931, 0, 0, 0, 0, 43418, 0, 0, 0, 7876, - 68132, 917872, 0, 917870, 43378, 0, 0, 120890, 5892, 43605, 0, 0, 0, - 129058, 0, 0, 6251, 83409, 83410, 83411, 83412, 126512, 0, 71092, 83408, - 10114, 0, 0, 5387, 0, 0, 0, 0, 65553, 78346, 1747, 917849, 65109, 69240, - 917852, 126509, 0, 0, 0, 0, 125065, 0, 9850, 0, 367, 1472, 917859, 6687, - 0, 0, 5905, 12339, 8919, 73953, 65680, 0, 2204, 78664, 0, 9134, 118589, - 78666, 43011, 0, 126626, 0, 0, 0, 43013, 10614, 0, 0, 83413, 66646, - 83415, 83416, 0, 73881, 43012, 121127, 83293, 54, 43009, 73885, 0, 6211, - 0, 0, 83295, 68119, 43008, 10758, 0, 0, 0, 0, 0, 70018, 0, 0, 0, 0, - 12765, 0, 0, 0, 0, 126580, 0, 0, 43657, 0, 0, 0, 983737, 0, 83405, - 917843, 0, 0, 83401, 83402, 83403, 83404, 83397, 11363, 12057, 83400, - 1567, 0, 0, 83396, 0, 8957, 4139, 0, 0, 129336, 0, 0, 12740, 0, 92195, - 12761, 127793, 12759, 0, 72304, 67169, 83467, 44002, 0, 83462, 83463, - 83464, 12755, 12762, 41022, 67690, 64217, 476, 0, 983734, 0, 64212, - 41020, 1382, 64209, 64216, 64215, 64214, 64213, 0, 0, 0, 67584, 8720, - 3908, 0, 0, 0, 0, 101529, 129576, 0, 0, 3849, 92324, 94026, 9778, 917906, - 5891, 917912, 55, 917910, 917911, 0, 0, 7935, 67586, 0, 1114, 92599, - 67585, 78675, 0, 83447, 83449, 0, 0, 0, 64717, 0, 0, 0, 66884, 6292, - 65303, 0, 6452, 917886, 917887, 66249, 917885, 917890, 917891, 917888, - 719, 101446, 0, 917892, 0, 0, 0, 94083, 10868, 121333, 2349, 5902, - 917896, 6335, 101350, 917899, 917900, 0, 64369, 0, 0, 0, 69245, 0, - 126564, 0, 0, 128565, 0, 0, 0, 0, 0, 6454, 1229, 83457, 83458, 83450, - 83451, 83452, 65100, 120508, 8224, 917873, 917874, 917879, 917880, - 917877, 917878, 128929, 0, 917881, 917882, 5365, 67836, 8901, 0, 0, - 129951, 0, 69257, 5925, 83436, 64330, 128400, 83431, 83432, 83433, 83434, - 83427, 83428, 83429, 83430, 64928, 10543, 0, 0, 83446, 414, 0, 0, 83442, - 6456, 71490, 83445, 11905, 83439, 66284, 83441, 0, 68337, 0, 83437, - 43832, 983140, 9751, 0, 128085, 11770, 0, 0, 69600, 65061, 0, 0, 0, 0, 0, - 0, 121087, 0, 0, 69924, 0, 0, 0, 69913, 0, 121387, 101513, 101504, - 101512, 42038, 387, 0, 12737, 0, 0, 43368, 0, 0, 0, 0, 129713, 129449, - 121295, 0, 69400, 127309, 0, 375, 0, 0, 0, 983905, 0, 0, 119202, 119203, - 124117, 43120, 0, 0, 119196, 119197, 0, 4529, 119200, 119201, 119198, - 119199, 0, 0, 69698, 13150, 64492, 0, 0, 0, 0, 0, 42891, 66327, 74298, 0, - 0, 0, 2587, 42193, 0, 6455, 0, 4241, 0, 0, 0, 0, 0, 0, 0, 118821, 0, 0, - 0, 125030, 0, 128684, 129390, 6988, 5373, 0, 0, 119232, 10015, 0, 0, 0, - 68642, 0, 120855, 42040, 128827, 5779, 129841, 42037, 83282, 0, 0, 93040, - 83283, 101116, 0, 101117, 6983, 0, 0, 101115, 0, 0, 0, 127323, 101111, 0, - 119588, 0, 92495, 74558, 0, 68138, 70163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11144, 73484, 2551, 73482, 6453, 0, 6235, 0, 0, 129081, 72886, 44020, - 11826, 0, 7780, 5369, 118958, 0, 0, 5367, 66870, 0, 0, 5377, 0, 68143, - 128624, 78245, 5218, 0, 127333, 0, 0, 129717, 0, 0, 1300, 0, 127334, - 64505, 0, 0, 119624, 1465, 0, 127316, 0, 0, 0, 101109, 0, 113694, 10729, - 0, 0, 8839, 119243, 0, 7785, 126530, 0, 0, 0, 0, 118638, 0, 0, 0, 3897, - 0, 92331, 74417, 113704, 0, 68127, 71425, 70688, 0, 0, 0, 0, 69287, 3542, - 0, 120685, 7951, 68152, 118857, 0, 92972, 0, 0, 127311, 73683, 0, 65150, - 68031, 0, 0, 0, 0, 9985, 0, 127328, 0, 0, 0, 0, 10830, 0, 615, 64490, - 7574, 0, 0, 0, 12909, 73698, 64559, 127332, 73951, 0, 67996, 2020, 0, 0, - 0, 120701, 0, 983640, 0, 0, 0, 92991, 0, 0, 9070, 0, 68411, 11281, 42829, - 0, 1033, 0, 78918, 0, 118610, 0, 65226, 0, 0, 0, 0, 0, 3450, 0, 7397, 0, - 0, 42778, 10000, 41088, 449, 0, 0, 68458, 113725, 0, 0, 10738, 69634, 0, - 0, 41085, 0, 0, 0, 12764, 0, 93058, 3596, 7322, 0, 0, 0, 0, 0, 0, 0, 0, - 2092, 0, 0, 0, 121350, 10820, 0, 0, 126567, 1853, 0, 0, 93014, 0, 12770, - 0, 0, 124997, 0, 0, 0, 0, 0, 129053, 4828, 1258, 0, 2006, 0, 0, 74285, - 127987, 0, 120683, 122880, 983900, 983903, 8846, 128255, 0, 128091, 2650, - 9182, 1961, 121399, 11525, 0, 1959, 0, 55228, 11774, 41016, 0, 0, 128054, - 41017, 13109, 0, 10519, 66331, 3454, 19930, 0, 41019, 92894, 0, 0, 78362, - 41021, 101566, 0, 0, 0, 0, 65531, 0, 0, 0, 0, 0, 0, 8865, 6402, 113827, - 77923, 0, 101536, 0, 7733, 0, 4998, 68493, 0, 78930, 0, 4268, 101368, 0, - 0, 101555, 101579, 10881, 0, 0, 0, 0, 2014, 0, 71901, 0, 0, 195057, 0, 0, - 78357, 65281, 0, 0, 0, 0, 0, 2015, 0, 0, 71840, 66318, 74824, 101575, 0, - 101574, 101569, 0, 70061, 8094, 10135, 101551, 0, 794, 0, 0, 66335, 0, - 121303, 4343, 0, 4833, 0, 0, 0, 0, 189, 12611, 0, 72215, 0, 4838, 126214, - 4834, 65078, 2183, 126104, 4837, 118853, 0, 121230, 4832, 128271, 0, - 101584, 127838, 0, 0, 0, 0, 0, 118697, 0, 3976, 118995, 128937, 0, 0, 0, - 0, 0, 119010, 0, 121015, 0, 0, 0, 0, 2871, 0, 0, 999, 0, 68177, 0, 0, - 2017, 0, 67824, 0, 0, 0, 0, 0, 0, 4775, 12555, 12571, 12550, 12583, - 12560, 2019, 12556, 12584, 12586, 0, 12562, 12561, 12566, 12569, 12554, - 0, 83344, 0, 68882, 0, 12567, 1402, 0, 0, 83348, 125072, 83347, 0, 83346, - 0, 0, 0, 0, 64391, 0, 83341, 69602, 0, 1999, 0, 128141, 0, 0, 0, 0, 0, 0, - 0, 68873, 0, 0, 66913, 2377, 101090, 0, 12572, 11318, 12557, 12559, 9192, - 12549, 12568, 2373, 9446, 9447, 9448, 9449, 0, 9480, 481, 0, 9438, 9439, - 9440, 9441, 9442, 9443, 9444, 9445, 9430, 9431, 9432, 9433, 9434, 9435, - 9436, 9437, 983097, 0, 9424, 9425, 9426, 9427, 9428, 7481, 0, 2362, 9655, - 0, 2004, 0, 9782, 0, 0, 0, 0, 0, 0, 0, 1108, 0, 92461, 0, 128764, 0, - 64781, 0, 0, 0, 121126, 0, 1392, 0, 0, 917557, 0, 8065, 42994, 128739, 0, - 0, 0, 121068, 92418, 0, 0, 0, 43280, 0, 70718, 1812, 0, 73046, 0, 0, 0, - 0, 0, 6054, 10697, 3169, 0, 0, 70720, 11487, 70712, 0, 0, 0, 194716, 0, - 0, 41863, 0, 0, 2304, 0, 92326, 0, 42951, 0, 0, 64760, 11766, 0, 0, 0, 0, - 69236, 119171, 0, 8773, 10733, 36, 0, 0, 0, 0, 0, 11074, 0, 64910, - 983131, 2009, 0, 0, 128036, 68114, 128906, 0, 0, 0, 983998, 12852, 3031, - 0, 0, 129088, 0, 66414, 0, 0, 119950, 42613, 65933, 366, 0, 9892, 0, - 11754, 101107, 83329, 65301, 44013, 83058, 67245, 10102, 0, 7739, 41026, - 0, 0, 0, 0, 0, 0, 0, 0, 78386, 129475, 71868, 113811, 13081, 10923, - 129330, 0, 68145, 0, 65861, 74083, 0, 0, 128392, 83063, 83065, 0, 70706, - 0, 0, 0, 70168, 66586, 4183, 64967, 66250, 0, 92547, 0, 0, 113685, 0, - 3792, 2011, 0, 0, 77748, 83332, 77749, 120595, 0, 68489, 41023, 77747, 0, - 11659, 7922, 12614, 2005, 8523, 129880, 0, 7513, 1863, 129436, 83337, - 128969, 0, 120274, 120033, 0, 8144, 0, 73031, 77767, 127524, 120270, - 42241, 8783, 77764, 77765, 77766, 77760, 77761, 77762, 77763, 0, 10680, - 0, 43293, 68771, 0, 119164, 83320, 72003, 10187, 77742, 77743, 0, 77737, - 77738, 77739, 0, 10968, 43296, 119044, 0, 0, 101400, 0, 1005, 43826, - 120030, 0, 2870, 0, 101399, 0, 0, 983798, 0, 235, 1384, 77758, 74887, - 70494, 77754, 77755, 9796, 69895, 77750, 77751, 77752, 13186, 120407, - 120250, 0, 0, 0, 42527, 12911, 43427, 1383, 983581, 0, 0, 0, 6156, 68117, - 0, 7993, 4288, 0, 0, 13238, 13244, 0, 0, 120426, 13234, 120427, 0, - 118904, 0, 11364, 0, 1380, 65617, 120253, 120261, 13196, 13197, 120311, - 120419, 9495, 0, 0, 120418, 0, 73976, 128160, 0, 6941, 0, 13205, 13211, - 5801, 0, 74271, 120319, 0, 120302, 7670, 0, 68075, 983583, 0, 19957, - 72314, 2021, 93811, 43877, 0, 0, 0, 0, 3875, 120431, 64341, 0, 9814, - 43457, 13066, 3314, 7787, 0, 0, 0, 0, 0, 0, 64531, 129860, 0, 0, 0, 0, 0, - 127138, 0, 0, 9742, 0, 0, 10800, 77718, 8404, 0, 92592, 77714, 7089, - 77716, 78545, 0, 77712, 77713, 0, 0, 4772, 5771, 101405, 0, 9841, 8843, - 0, 0, 0, 129862, 120816, 0, 123137, 0, 77735, 0, 0, 0, 77731, 8849, - 77733, 77734, 65112, 1796, 77729, 77730, 69665, 8164, 41301, 3502, 0, - 122884, 128387, 0, 983835, 5825, 0, 0, 0, 0, 121322, 10983, 10354, 10418, - 0, 2022, 0, 1409, 100789, 0, 0, 0, 0, 1390, 0, 0, 10471, 65904, 5846, - 126472, 0, 0, 0, 0, 0, 0, 66035, 77725, 0, 77726, 77720, 77721, 67458, - 3168, 67733, 0, 0, 2370, 0, 126243, 0, 195049, 0, 0, 1836, 0, 121207, - 119137, 118959, 125232, 0, 0, 0, 2390, 3944, 0, 0, 0, 0, 69908, 125011, - 0, 0, 123200, 0, 0, 8975, 64739, 0, 0, 0, 0, 64409, 0, 0, 0, 0, 128564, - 0, 0, 0, 0, 6204, 0, 0, 0, 10911, 64954, 119003, 74809, 118903, 4267, 0, - 0, 0, 0, 0, 0, 72023, 0, 0, 119504, 92887, 0, 0, 0, 0, 121125, 0, 128337, - 5842, 0, 41439, 0, 0, 0, 9328, 0, 120980, 120917, 0, 0, 2285, 0, 0, 0, 0, - 118634, 64555, 0, 0, 72162, 9541, 0, 0, 0, 41441, 0, 0, 0, 41040, 2459, - 0, 0, 41041, 0, 0, 0, 0, 0, 10450, 0, 41043, 0, 0, 43125, 0, 0, 0, 0, 0, - 121008, 68436, 128040, 0, 120649, 0, 0, 4312, 43927, 0, 0, 11923, 42227, - 0, 5763, 0, 4827, 74559, 42228, 64406, 0, 0, 129703, 433, 119620, 0, - 2499, 67167, 67166, 0, 11973, 0, 4293, 42271, 42224, 0, 0, 66322, 42226, - 0, 0, 0, 74180, 0, 55277, 0, 0, 0, 119317, 0, 74632, 0, 0, 71103, 0, 0, - 0, 585, 2383, 0, 43263, 0, 4290, 64842, 0, 68920, 0, 8511, 0, 0, 0, - 119048, 2380, 126119, 0, 71704, 2376, 0, 0, 0, 5197, 127046, 127047, - 127048, 2366, 127050, 127051, 73442, 0, 0, 0, 93835, 0, 93818, 0, 0, - 74188, 113813, 0, 0, 0, 983838, 0, 0, 0, 0, 1847, 0, 72771, 0, 42384, 0, - 4227, 74158, 0, 92501, 0, 0, 42365, 0, 128902, 0, 92821, 0, 0, 0, 0, 0, - 0, 0, 0, 122934, 128563, 0, 983509, 127560, 2754, 0, 0, 128900, 0, - 127867, 119638, 0, 1711, 12984, 92365, 77776, 6255, 77770, 77771, 77772, - 77773, 0, 42063, 74184, 0, 0, 0, 0, 0, 77785, 77786, 41035, 43274, 77781, - 11256, 77783, 77784, 520, 77778, 41037, 77780, 0, 0, 41034, 0, 983829, - 64815, 0, 0, 321, 41028, 0, 0, 0, 0, 0, 0, 0, 74191, 0, 0, 72767, 1861, - 118938, 129666, 0, 0, 100770, 0, 0, 128530, 3859, 0, 41660, 0, 70793, 0, - 983756, 75014, 0, 127514, 41658, 0, 0, 0, 0, 0, 4414, 77769, 0, 42632, 0, - 0, 0, 0, 0, 1405, 0, 43220, 43341, 0, 0, 0, 0, 0, 983733, 11199, 0, 3513, - 0, 70341, 43342, 0, 65529, 0, 0, 0, 6485, 1397, 0, 0, 92678, 118566, - 124137, 0, 82961, 0, 82962, 0, 74270, 43287, 983731, 0, 0, 983738, 0, - 71914, 4317, 10490, 0, 0, 194867, 74463, 128952, 464, 41624, 0, 0, 0, - 1346, 128240, 69271, 64724, 128566, 423, 0, 0, 113748, 0, 128161, 0, 0, - 120563, 64960, 0, 0, 0, 0, 9584, 77795, 77796, 78927, 0, 9718, 77792, - 42642, 77794, 64750, 77789, 77790, 0, 0, 128333, 0, 3204, 64666, 0, - 43530, 2752, 0, 0, 119594, 0, 0, 0, 0, 92371, 0, 41983, 0, 7010, 0, 0, - 41495, 92379, 5877, 42252, 93070, 8009, 3305, 0, 0, 0, 0, 92293, 0, 0, 0, - 100836, 0, 65915, 1400, 75018, 10685, 75017, 2103, 122908, 0, 43276, 0, - 11169, 0, 6481, 0, 0, 0, 100837, 72249, 100838, 74198, 0, 9116, 0, 0, 0, - 0, 0, 0, 8129, 92994, 0, 124992, 0, 11658, 0, 0, 3452, 41031, 0, 1385, 0, - 100754, 0, 43340, 11123, 41033, 6493, 12758, 0, 0, 11426, 0, 1681, - 100755, 1204, 11960, 69902, 0, 69457, 0, 119322, 129483, 7415, 43338, 0, - 0, 67717, 64915, 0, 100759, 72021, 41497, 65044, 0, 19960, 65358, 983601, - 0, 0, 0, 73670, 0, 1789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64728, 0, 0, 0, - 6506, 64312, 0, 2368, 0, 0, 0, 0, 3439, 1825, 1192, 0, 73739, 10639, 0, - 7790, 5430, 0, 0, 2848, 92981, 0, 0, 7607, 0, 0, 0, 120658, 0, 0, 8883, - 0, 728, 0, 0, 0, 0, 92931, 0, 121372, 128348, 0, 68078, 8091, 11447, 0, - 0, 126261, 983729, 0, 70003, 0, 0, 74419, 12335, 0, 0, 3443, 0, 0, 0, - 127145, 0, 0, 0, 0, 11843, 0, 9205, 8624, 128543, 92930, 43295, 0, 65445, - 0, 6277, 41672, 0, 10010, 70186, 983052, 0, 835, 71340, 0, 0, 0, 0, 0, - 5426, 4258, 0, 64891, 5424, 0, 8283, 0, 5434, 0, 0, 0, 0, 0, 11947, 0, - 1404, 0, 11432, 0, 3464, 6486, 4819, 0, 0, 570, 8095, 0, 0, 1498, 0, 0, - 0, 431, 67820, 0, 120574, 128096, 0, 0, 13096, 0, 0, 43408, 0, 128538, - 8835, 77875, 0, 0, 122973, 0, 0, 0, 0, 0, 3477, 227, 10488, 0, 382, - 11418, 0, 5878, 0, 0, 0, 0, 6484, 92355, 66039, 0, 0, 0, 78717, 0, 92662, - 119665, 0, 0, 43290, 0, 0, 0, 0, 8782, 0, 0, 4323, 128649, 0, 120903, - 12094, 67499, 0, 0, 0, 92953, 3856, 120970, 124138, 5872, 6495, 72306, 0, - 0, 0, 67173, 67172, 67171, 3953, 0, 0, 93063, 11994, 4339, 0, 92654, 0, - 0, 0, 0, 128804, 0, 5228, 0, 9766, 0, 92741, 0, 0, 0, 0, 68860, 0, 1162, - 0, 2671, 0, 73666, 92632, 92631, 72117, 0, 73811, 0, 194895, 0, 68085, 0, - 74331, 11424, 0, 10466, 121239, 0, 194890, 0, 4820, 0, 0, 0, 194891, 0, - 119212, 4896, 0, 4897, 42821, 64611, 0, 4438, 0, 0, 1753, 11331, 6147, 0, - 43282, 8833, 0, 0, 6504, 0, 0, 0, 118670, 0, 1413, 0, 0, 64353, 12141, - 121138, 0, 0, 43163, 0, 72880, 64789, 127094, 838, 127092, 120697, - 127090, 5014, 0, 256, 0, 0, 42443, 42739, 0, 7542, 0, 70389, 0, 6489, - 10048, 74326, 0, 66573, 0, 125271, 78712, 11761, 126078, 129603, 41094, - 0, 0, 0, 0, 92689, 8453, 0, 0, 120942, 128184, 0, 11816, 0, 0, 2930, - 93845, 0, 41098, 92771, 41093, 0, 0, 6498, 41096, 0, 0, 1238, 200, 0, - 1660, 74476, 0, 0, 74362, 0, 0, 72301, 9224, 0, 0, 0, 0, 0, 0, 0, 0, - 72729, 43284, 0, 72110, 67459, 13183, 0, 0, 0, 1669, 10776, 0, 0, 0, 0, - 0, 1732, 4030, 0, 3963, 0, 0, 0, 6491, 0, 0, 914, 121394, 0, 0, 0, 78713, - 0, 92441, 74367, 42960, 0, 0, 0, 0, 0, 0, 0, 65537, 0, 0, 43430, 5301, 0, - 92618, 0, 43285, 0, 0, 125186, 0, 0, 5876, 0, 69555, 0, 0, 110713, 0, 0, - 0, 0, 0, 0, 11114, 74536, 0, 0, 0, 0, 983130, 0, 0, 0, 0, 10915, 983069, - 12007, 0, 0, 0, 0, 67655, 92604, 0, 8629, 0, 43168, 41872, 0, 0, 0, - 42488, 0, 0, 0, 0, 0, 64730, 70041, 0, 122895, 0, 0, 0, 92306, 11416, - 4280, 128516, 8765, 73451, 0, 1393, 0, 11157, 74386, 0, 0, 0, 0, 6683, 0, - 93832, 12144, 0, 74513, 13019, 74994, 0, 0, 0, 983272, 0, 6488, 357, 0, - 41100, 0, 41104, 0, 41099, 0, 71320, 0, 0, 0, 4434, 0, 0, 0, 74231, - 83107, 0, 194914, 0, 0, 72286, 68305, 0, 41759, 12757, 0, 0, 72769, 9790, - 7674, 0, 121095, 68209, 0, 41764, 0, 0, 72322, 2268, 0, 129845, 983608, - 12743, 0, 6480, 0, 41779, 0, 66601, 0, 74490, 10986, 66602, 0, 64807, 0, - 0, 41767, 119629, 0, 0, 0, 3955, 64571, 194918, 127089, 0, 70187, 69975, - 9770, 12305, 12230, 0, 73551, 0, 0, 74752, 0, 0, 123168, 128263, 74449, - 0, 65948, 69611, 0, 0, 71131, 129505, 78573, 0, 0, 11116, 0, 5747, 0, - 110667, 9802, 41092, 120731, 0, 0, 0, 0, 0, 120733, 41090, 0, 0, 0, - 11271, 57, 0, 0, 983244, 0, 71268, 121290, 43137, 0, 0, 110672, 126221, - 0, 0, 0, 0, 0, 277, 74385, 0, 0, 0, 72155, 0, 13025, 8757, 0, 0, 1574, 0, - 126124, 100800, 0, 5749, 129923, 0, 42824, 0, 1039, 9801, 0, 5745, 0, - 41858, 0, 0, 120655, 0, 41862, 0, 0, 78822, 436, 4771, 118635, 42501, 0, - 10573, 0, 77931, 118560, 917986, 9644, 0, 0, 0, 0, 69837, 0, 0, 0, 0, - 67409, 0, 0, 0, 125204, 11939, 0, 0, 0, 0, 0, 0, 0, 3504, 0, 0, 92854, - 126209, 0, 10226, 65558, 0, 3594, 0, 0, 40, 0, 0, 0, 0, 0, 74312, 72138, - 74337, 0, 69577, 0, 0, 0, 70476, 0, 121143, 72317, 0, 0, 4304, 0, 0, - 78707, 0, 0, 0, 78597, 1348, 78596, 0, 0, 0, 70406, 92392, 0, 7599, 0, 0, - 13269, 0, 129729, 0, 100804, 0, 74494, 6097, 7568, 43980, 4982, 78592, 0, - 0, 0, 0, 13270, 0, 128090, 13138, 0, 9484, 0, 0, 71364, 0, 0, 0, 9487, 0, - 92913, 0, 71911, 78668, 73963, 6193, 0, 0, 0, 194848, 7228, 10011, - 194849, 194852, 194851, 11654, 194853, 126218, 194855, 0, 194857, 3604, - 0, 0, 0, 0, 0, 94110, 43740, 94109, 194860, 194863, 66750, 121021, 0, - 94111, 6995, 74173, 5437, 74174, 0, 8702, 7339, 129981, 0, 199, 194843, - 194846, 194845, 0, 126069, 0, 67818, 0, 7560, 0, 0, 0, 0, 6472, 65814, 0, - 128983, 70845, 0, 0, 9191, 0, 0, 0, 0, 124904, 10196, 0, 72452, 6585, 0, - 120750, 0, 0, 71872, 129129, 0, 0, 78590, 72308, 11382, 129499, 0, - 983670, 0, 194833, 194832, 2165, 129540, 94020, 194836, 42727, 194838, - 128252, 78585, 43874, 119610, 0, 0, 43248, 0, 194816, 0, 194818, 128845, - 194820, 127879, 5297, 194821, 13284, 6112, 93964, 93010, 73927, 42947, 0, - 65746, 0, 0, 194827, 194826, 4342, 42839, 194831, 1677, 0, 72135, 0, 0, - 0, 11011, 66399, 0, 0, 0, 10160, 0, 0, 0, 0, 2052, 4308, 92174, 43000, - 118659, 543, 64916, 122964, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, - 0, 69984, 0, 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, - 0, 0, 506, 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, - 2063, 0, 0, 0, 0, 72136, 0, 74333, 194912, 11827, 74308, 194913, 194916, - 194915, 64564, 194917, 67986, 194919, 0, 11037, 0, 121102, 0, 0, 10560, - 0, 120756, 194922, 113737, 194924, 194927, 120495, 1931, 0, 0, 0, 128228, - 0, 12643, 8751, 123629, 0, 12294, 0, 78834, 9138, 78831, 78833, 12631, - 78829, 11080, 78821, 0, 0, 1239, 0, 121067, 0, 12636, 0, 0, 0, 0, 0, 0, - 8998, 0, 0, 9152, 0, 0, 0, 67589, 0, 64290, 0, 92393, 12615, 0, 129141, - 6914, 93013, 0, 119569, 0, 65188, 0, 67611, 4337, 0, 194897, 194896, - 78516, 194898, 7681, 194900, 194903, 67596, 194905, 194904, 2477, 93974, - 0, 0, 0, 67604, 70705, 0, 194882, 194881, 194884, 194883, 194886, 128914, - 194888, 67599, 0, 194889, 0, 0, 0, 0, 3357, 0, 78852, 4207, 1288, 78842, - 78839, 78840, 78837, 78838, 66354, 194872, 0, 128432, 0, 67618, 92664, 0, - 42788, 0, 64612, 129897, 10774, 194877, 0, 194879, 129125, 0, 0, 997, - 194901, 0, 92577, 0, 11440, 11379, 42000, 13139, 0, 0, 74030, 72293, - 73796, 0, 0, 0, 0, 2818, 0, 0, 73793, 0, 4172, 93028, 126523, 124981, 0, - 129896, 0, 0, 129522, 69706, 0, 6834, 0, 0, 194865, 126982, 121211, - 194866, 194869, 194868, 766, 1257, 0, 0, 0, 3265, 66617, 3274, 0, 0, - 94042, 0, 8373, 41989, 69507, 73460, 3418, 3263, 0, 0, 0, 3270, 64539, - 11489, 0, 118945, 126220, 0, 127795, 0, 94031, 0, 0, 0, 0, 0, 70512, - 983983, 186, 0, 119156, 5770, 13179, 0, 12612, 12949, 64856, 12800, 0, 0, - 983152, 11507, 0, 0, 118929, 0, 0, 72141, 0, 73459, 0, 0, 0, 73461, 9254, - 66877, 194907, 0, 92338, 5624, 126253, 0, 0, 0, 120472, 120464, 0, 0, - 122915, 120462, 0, 1872, 66508, 120467, 41079, 0, 5502, 119330, 41078, - 194906, 0, 0, 4511, 68449, 0, 0, 0, 0, 43245, 41083, 68861, 0, 0, 9003, - 119959, 0, 5305, 9653, 41081, 43146, 9546, 0, 0, 120478, 0, 65205, 71713, - 64063, 120459, 0, 0, 0, 64058, 43101, 43102, 0, 64062, 1028, 64060, - 64059, 0, 10567, 110816, 110817, 92857, 110815, 0, 2902, 64043, 64042, - 43749, 10756, 64047, 64046, 64045, 64044, 0, 10076, 64040, 64039, 0, - 1034, 0, 0, 64034, 64033, 64032, 42735, 64038, 64037, 64036, 64035, 4291, - 67497, 64015, 64014, 83393, 83394, 83395, 983784, 0, 43090, 83391, 3476, - 64013, 64012, 64011, 64010, 64008, 64007, 2003, 7706, 0, 0, 119050, - 64009, 204, 0, 0, 4430, 8239, 64003, 10626, 64001, 64057, 13079, 64055, - 64054, 0, 0, 43246, 9343, 64049, 64048, 0, 1133, 64053, 64052, 64051, - 64050, 0, 0, 0, 66415, 12329, 0, 0, 129698, 1942, 0, 0, 0, 128249, 0, - 68291, 10760, 64023, 64022, 64021, 64020, 43670, 77924, 64025, 41412, - 78243, 78244, 0, 0, 64019, 64018, 64017, 64016, 0, 0, 78251, 78252, - 78248, 78249, 77914, 78247, 0, 917560, 77919, 6788, 13094, 0, 7532, - 41414, 0, 3179, 70745, 64769, 0, 0, 71967, 0, 10751, 0, 0, 0, 0, 0, 0, 0, - 2008, 64031, 64030, 294, 41874, 83383, 83384, 64844, 83376, 129063, - 83379, 83380, 64028, 11396, 64026, 83374, 0, 0, 118795, 71739, 43247, 0, - 70153, 70846, 0, 0, 0, 0, 0, 0, 0, 7801, 83359, 83361, 128931, 0, 3297, - 83356, 83357, 1135, 83350, 83351, 73696, 1995, 7927, 71738, 110742, 2552, - 83372, 60, 0, 8649, 83368, 83369, 83370, 83371, 10541, 83365, 78679, - 43833, 0, 0, 2013, 83362, 0, 110636, 0, 0, 12832, 110638, 8081, 8362, - 120188, 0, 9137, 0, 0, 0, 0, 3466, 0, 0, 1996, 0, 3453, 3412, 0, 2002, - 2000, 120176, 0, 0, 0, 0, 1998, 0, 1842, 7037, 0, 9628, 68446, 0, 9826, - 64502, 1767, 3413, 0, 0, 0, 0, 0, 0, 13108, 44024, 120204, 0, 92693, 0, - 0, 0, 70291, 12650, 983210, 0, 68061, 0, 3592, 0, 0, 0, 0, 983975, 0, - 66417, 128792, 10742, 0, 0, 1994, 9281, 3296, 64475, 1997, 1895, 128936, - 43024, 0, 0, 123184, 72391, 0, 8999, 0, 983633, 0, 66480, 0, 0, 0, - 983083, 0, 596, 0, 0, 120216, 8651, 120217, 0, 0, 12995, 0, 0, 70740, 0, - 42930, 119955, 64810, 917834, 6825, 0, 917839, 120208, 64275, 120889, - 128069, 120210, 6384, 917840, 126477, 0, 67698, 0, 0, 0, 120496, 0, - 43412, 0, 0, 0, 0, 0, 120172, 0, 120763, 0, 0, 0, 128343, 1457, 0, 0, - 6381, 2815, 0, 65240, 129664, 0, 0, 119522, 70487, 0, 0, 0, 0, 0, 120572, - 0, 0, 0, 0, 0, 125253, 0, 0, 0, 11862, 0, 0, 0, 3055, 9852, 0, 65288, 0, - 11398, 0, 0, 93016, 123550, 0, 603, 128557, 0, 0, 0, 129366, 3350, 0, 0, - 917828, 917827, 68428, 917825, 73045, 917831, 917830, 917829, 0, 1919, 0, - 110767, 83296, 83297, 83298, 66446, 64141, 8562, 64139, 64138, 64136, - 64135, 64134, 64133, 11297, 0, 0, 11966, 64128, 66286, 0, 123541, 64132, - 10867, 64130, 64129, 0, 43374, 9779, 2764, 0, 0, 9471, 0, 0, 0, 0, 66010, - 0, 8857, 128771, 121423, 0, 69223, 0, 194660, 983876, 0, 0, 43984, 0, 0, - 0, 0, 0, 0, 10717, 64570, 5630, 0, 64143, 64142, 83300, 67758, 83302, 0, - 77930, 0, 0, 0, 11631, 64146, 64145, 64144, 2384, 72801, 127380, 0, 0, 0, - 0, 118547, 0, 0, 0, 0, 122916, 8933, 1601, 917803, 858, 118637, 64109, - 64108, 8090, 0, 72387, 917811, 587, 0, 82971, 0, 0, 0, 78214, 2750, 0, - 9983, 64158, 64157, 83288, 83289, 83290, 2167, 83284, 83285, 83286, - 83287, 64156, 64155, 64154, 69495, 64151, 64150, 12679, 10053, 10421, 0, - 64153, 64152, 0, 0, 4839, 0, 0, 4435, 119016, 0, 64126, 64125, 64124, - 64123, 129287, 0, 67478, 7007, 0, 65443, 0, 0, 64122, 0, 0, 93834, 64117, - 64116, 6287, 64114, 64121, 64120, 64119, 64118, 110659, 127842, 1177, - 65601, 12322, 64106, 92169, 110654, 64102, 64101, 64100, 64099, 0, 10453, - 64104, 64103, 7997, 0, 92534, 0, 8705, 64097, 64096, 9571, 0, 110652, - 127398, 12132, 0, 0, 0, 110624, 73841, 83339, 83340, 9056, 0, 129970, 0, - 6155, 64068, 64067, 64066, 64065, 64072, 64071, 63, 64069, 127382, 0, - 93822, 7257, 64064, 0, 0, 0, 0, 0, 0, 78748, 0, 0, 0, 120519, 0, 66242, - 66232, 4333, 9855, 64112, 0, 0, 118531, 0, 0, 0, 0, 66222, 0, 0, 0, 0, - 69816, 0, 118796, 0, 8708, 0, 64077, 64076, 8996, 4992, 4471, 83343, - 64079, 64078, 92179, 0, 0, 123540, 64615, 0, 0, 12075, 42041, 0, 0, 0, 0, - 127557, 3123, 0, 983754, 0, 0, 0, 83328, 0, 9223, 0, 83321, 83322, 73797, - 83327, 1116, 0, 83319, 7136, 73550, 0, 0, 0, 75031, 0, 0, 0, 64092, - 43675, 10104, 83338, 83331, 64095, 64094, 8111, 66247, 0, 64089, 64088, - 0, 70106, 42236, 11434, 64083, 64082, 43216, 7737, 64087, 64086, 64085, - 64084, 0, 0, 0, 4118, 1797, 83312, 0, 0, 46, 83308, 83309, 298, 83303, - 72402, 83305, 83306, 0, 0, 0, 128905, 11495, 0, 67490, 0, 127377, 194828, - 127370, 0, 0, 0, 66239, 74945, 64403, 0, 0, 83314, 0, 0, 65758, 43536, 0, - 8544, 0, 0, 0, 0, 194824, 0, 0, 0, 0, 0, 3639, 11242, 194822, 0, 0, 0, 0, - 0, 0, 68409, 0, 0, 0, 101121, 0, 0, 0, 128654, 8789, 126248, 0, 0, - 128325, 0, 0, 0, 0, 65058, 0, 78234, 68064, 0, 66227, 71694, 5573, - 118936, 0, 44, 0, 66244, 118907, 0, 66238, 12844, 0, 1622, 129190, 1900, - 0, 11458, 0, 0, 6581, 5576, 128303, 0, 126122, 0, 113680, 8947, 0, - 113812, 0, 69744, 0, 7908, 0, 917998, 6579, 0, 0, 0, 0, 2138, 6583, 7761, - 0, 0, 0, 66802, 5058, 0, 0, 0, 5057, 125256, 0, 74538, 5054, 0, 0, 0, 0, - 0, 0, 658, 3497, 128509, 0, 5061, 5060, 4235, 0, 0, 0, 127757, 4236, - 4727, 0, 0, 0, 128791, 0, 7488, 128693, 7476, 0, 125259, 120646, 0, 0, 0, - 66209, 0, 0, 0, 78931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128903, 0, 9341, - 119596, 0, 0, 0, 64668, 0, 8125, 0, 6743, 119175, 0, 129441, 83406, 0, - 127966, 119235, 74092, 0, 0, 43660, 71125, 0, 127901, 0, 0, 0, 264, 0, - 74954, 0, 0, 0, 0, 0, 6019, 0, 0, 129121, 0, 0, 0, 8800, 0, 66376, 0, - 120948, 0, 100744, 0, 0, 92333, 725, 68014, 110579, 110578, 72099, 0, 0, - 0, 0, 74899, 0, 0, 0, 110804, 0, 72142, 5074, 5073, 0, 0, 128726, 0, - 70723, 5072, 128576, 13098, 72403, 0, 11040, 0, 0, 0, 4929, 0, 0, 0, 0, - 0, 0, 0, 0, 67754, 4934, 0, 0, 9758, 0, 0, 70181, 42584, 0, 4329, 0, - 4979, 8663, 74521, 0, 983042, 74418, 983653, 0, 5071, 0, 3642, 0, 5070, - 10042, 0, 3987, 5068, 120209, 8909, 0, 0, 69917, 0, 73981, 983142, 70749, - 4531, 120212, 9105, 0, 4921, 121059, 4926, 65544, 113786, 69621, 0, 0, 0, - 83269, 0, 120790, 4922, 0, 992, 119568, 4925, 0, 0, 9526, 4920, 128617, - 948, 0, 0, 4930, 0, 0, 0, 4933, 0, 0, 0, 4928, 0, 0, 0, 0, 128379, 722, - 118696, 127483, 127482, 127485, 82997, 127487, 1509, 0, 5468, 66214, - 127474, 127477, 1672, 127479, 10864, 127481, 72132, 127467, 72159, - 127469, 127468, 127471, 127470, 68336, 82999, 120115, 1679, 120116, 0, - 120113, 127462, 127465, 127464, 127110, 120119, 120112, 0, 120109, 6968, - 5761, 342, 8553, 0, 8143, 127115, 127114, 2253, 624, 127111, 4057, 0, - 5078, 0, 0, 0, 5076, 0, 0, 0, 120097, 685, 9025, 1524, 8003, 0, 5539, - 113727, 113795, 118673, 7138, 120552, 0, 0, 0, 113724, 0, 8058, 9732, 0, - 5080, 0, 5036, 5035, 0, 42604, 72118, 0, 0, 275, 13291, 69995, 0, 0, - 983927, 5033, 0, 0, 4836, 70184, 73792, 0, 0, 0, 120681, 43704, 0, 2274, - 119000, 124983, 0, 8858, 6409, 0, 119585, 0, 0, 0, 0, 0, 68442, 0, 3432, - 10218, 0, 6094, 11232, 0, 0, 0, 0, 1676, 129157, 0, 0, 5030, 0, 118810, - 0, 73869, 0, 0, 69944, 6787, 0, 0, 0, 983595, 10544, 12919, 69425, 92218, - 0, 0, 0, 129172, 118715, 67703, 0, 0, 0, 0, 0, 72290, 0, 0, 0, 0, 7018, - 66241, 0, 0, 0, 0, 0, 74056, 0, 11833, 0, 67975, 65232, 40964, 251, - 12686, 7895, 4395, 43538, 0, 0, 0, 78042, 0, 0, 40967, 5879, 0, 0, 0, 0, - 0, 65540, 128590, 625, 0, 120194, 1113, 120195, 13103, 3630, 67224, 8179, - 74264, 67886, 9316, 10980, 2489, 120958, 8150, 1359, 121353, 70464, - 127330, 127327, 5042, 5041, 42769, 12084, 11196, 42961, 92279, 72398, - 120535, 127317, 127318, 127315, 12283, 127313, 11453, 70207, 8795, 66245, - 0, 5919, 0, 5037, 118864, 0, 0, 67724, 0, 66893, 74006, 129535, 8431, 0, - 0, 0, 0, 12620, 6826, 73773, 70169, 5040, 0, 0, 0, 0, 0, 5039, 0, 0, 0, - 5038, 0, 0, 0, 0, 0, 65908, 0, 0, 0, 0, 0, 65157, 0, 0, 70182, 0, 73909, - 4835, 0, 0, 0, 4309, 7127, 0, 0, 0, 1301, 0, 0, 12222, 0, 73813, 711, - 92439, 7133, 0, 0, 0, 0, 0, 0, 0, 7661, 72263, 129541, 0, 0, 70453, 7627, - 0, 5031, 92340, 42738, 65784, 0, 65782, 3758, 0, 65781, 67865, 0, 2440, - 65780, 70795, 8449, 121393, 121479, 0, 2118, 0, 12121, 0, 0, 129510, - 2128, 2130, 2131, 2126, 2133, 0, 121250, 2114, 2116, 2455, 0, 2122, 2123, - 2124, 2125, 983806, 8714, 0, 2113, 0, 2115, 0, 127907, 43713, 5052, - 66220, 66653, 65777, 65778, 65775, 5051, 65773, 1429, 42647, 5050, 65769, - 388, 70685, 735, 0, 129899, 128035, 0, 12726, 0, 0, 0, 0, 0, 5109, 5053, - 0, 120854, 0, 0, 0, 2470, 0, 0, 1925, 71251, 0, 10971, 113770, 5048, - 5047, 0, 0, 194946, 92313, 129972, 0, 0, 8089, 128468, 639, 0, 68179, 0, - 70180, 0, 4599, 0, 0, 0, 0, 983817, 648, 194948, 65819, 0, 0, 0, 129968, - 94017, 0, 11777, 9750, 983123, 0, 0, 92367, 70175, 5046, 66255, 0, 0, - 65253, 0, 5045, 0, 1916, 74069, 5044, 92348, 0, 0, 5043, 0, 0, 0, 74004, - 9669, 12341, 0, 8402, 0, 0, 70174, 0, 3586, 64508, 92456, 0, 0, 119606, - 0, 42628, 10069, 0, 0, 0, 0, 123, 120703, 0, 121326, 0, 10719, 129409, - 120444, 10829, 120593, 0, 12130, 0, 0, 0, 0, 3925, 0, 0, 75065, 71112, - 92372, 71110, 71111, 0, 120441, 120452, 983179, 0, 0, 0, 0, 0, 0, 0, 0, - 69879, 8509, 120449, 0, 0, 0, 120448, 0, 118889, 194858, 0, 0, 0, 66445, - 0, 71109, 0, 0, 72425, 0, 12136, 0, 983629, 0, 0, 0, 0, 19922, 41768, - 74002, 0, 0, 0, 0, 2458, 0, 0, 0, 41074, 4266, 64834, 0, 41077, 0, 9050, - 0, 0, 73693, 0, 0, 41075, 2476, 0, 0, 0, 69761, 0, 0, 74202, 78745, 0, - 121324, 70152, 66033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83106, 0, 0, 0, 43693, - 78753, 0, 12194, 66215, 71987, 121273, 67216, 121499, 0, 121118, 0, - 78756, 0, 0, 55256, 0, 0, 0, 0, 43876, 0, 0, 0, 12948, 195003, 195002, - 195005, 195004, 195007, 195006, 0, 128320, 4287, 70183, 4902, 74020, 0, - 917961, 0, 1816, 0, 0, 168, 0, 4898, 64298, 0, 78450, 4901, 1821, 0, - 43294, 3653, 120899, 791, 9162, 6977, 121183, 0, 70160, 0, 73731, 8354, - 0, 0, 0, 7557, 0, 0, 8234, 194992, 78456, 194994, 194993, 194996, 101519, - 65925, 194997, 195000, 194999, 0, 66996, 0, 64397, 0, 0, 0, 71310, - 194977, 194976, 2448, 194978, 194981, 194980, 2452, 194982, 194985, - 194984, 78694, 72292, 7845, 0, 78692, 4408, 4122, 6772, 194988, 8723, - 72147, 194989, 73472, 11857, 119304, 119303, 2438, 119297, 119300, - 119299, 41953, 0, 42135, 373, 119172, 2119, 11457, 129618, 41955, 0, 0, - 0, 41952, 0, 0, 2127, 0, 128496, 5202, 0, 78765, 42823, 11291, 0, 0, - 12963, 0, 0, 4125, 41958, 12133, 0, 125099, 1271, 129427, 0, 66024, 0, - 3864, 127825, 0, 0, 0, 0, 4166, 0, 0, 129917, 7459, 0, 119914, 5384, 0, - 0, 70154, 5759, 0, 0, 0, 0, 66744, 0, 120571, 0, 75066, 5552, 0, 0, - 127192, 5553, 0, 0, 0, 12906, 0, 0, 110787, 110792, 110788, 5554, 0, - 12344, 110786, 101508, 0, 0, 0, 0, 8517, 101509, 0, 0, 66017, 5555, - 92317, 0, 983672, 0, 0, 0, 9143, 0, 195067, 67995, 195069, 127162, - 195071, 195070, 4577, 64624, 0, 0, 125105, 983680, 4269, 983674, 983671, - 983669, 0, 950, 0, 983673, 983683, 983668, 0, 983675, 0, 119121, 0, 5098, - 0, 0, 119099, 5097, 0, 9848, 0, 10293, 983664, 72798, 0, 0, 70303, - 983684, 5102, 5101, 128370, 0, 8138, 4517, 1932, 5100, 195060, 65022, - 1247, 10034, 195064, 5099, 0, 1441, 0, 4724, 650, 0, 73954, 983271, - 129348, 195040, 195043, 9031, 195045, 195044, 195047, 8545, 66356, - 195048, 0, 9154, 127243, 0, 0, 2676, 2277, 0, 73812, 195051, 8599, - 195053, 917918, 195055, 65462, 0, 92524, 195033, 71903, 0, 0, 41199, 0, - 11399, 195035, 195034, 195037, 195036, 195039, 195038, 5108, 5107, 0, - 66019, 0, 0, 5541, 0, 0, 12613, 5284, 0, 0, 118537, 4275, 74865, 854, - 68147, 74381, 120918, 0, 5103, 124986, 64348, 0, 0, 5221, 69811, 0, - 71493, 121163, 0, 0, 11438, 0, 0, 70158, 0, 0, 5106, 195024, 110749, - 65154, 69813, 195028, 5105, 195030, 69720, 195032, 5104, 983780, 0, 3176, - 127342, 70149, 932, 0, 6567, 195009, 195008, 195011, 195010, 70145, - 43850, 195015, 195014, 195017, 195016, 0, 0, 0, 69511, 10670, 0, 13273, - 0, 195020, 121370, 8803, 195021, 72431, 8151, 67145, 72436, 0, 12553, 0, - 0, 0, 0, 13065, 12570, 0, 0, 0, 983199, 124985, 0, 0, 66466, 0, 0, - 194595, 0, 194596, 11351, 43256, 0, 0, 0, 0, 41754, 0, 0, 2720, 194975, - 68462, 8232, 120758, 0, 0, 0, 0, 122959, 0, 0, 93067, 10834, 0, 0, - 119266, 0, 0, 125025, 67679, 0, 75064, 7781, 0, 0, 126076, 0, 12077, 0, - 64586, 127164, 42396, 0, 3475, 0, 2479, 0, 0, 0, 120728, 0, 42434, - 129709, 194963, 194962, 110611, 67894, 42473, 194966, 110609, 1843, - 42283, 0, 0, 0, 0, 0, 194970, 0, 42321, 7284, 194974, 194973, 194950, - 194949, 194952, 194951, 0, 194953, 123614, 128645, 0, 0, 0, 0, 74952, - 194954, 194957, 194956, 66367, 194958, 41069, 67689, 9988, 0, 41068, 0, - 4295, 0, 0, 41951, 67835, 0, 785, 8236, 128647, 9027, 0, 194943, 0, - 122986, 0, 0, 0, 0, 41071, 41059, 0, 92458, 129442, 0, 0, 0, 123612, - 2067, 4310, 0, 123611, 5180, 123605, 0, 73872, 0, 69880, 5184, 42385, - 194947, 983774, 128531, 0, 0, 119149, 73503, 121334, 0, 983781, 0, 0, - 5178, 194929, 120548, 194931, 5188, 194933, 194932, 72245, 194934, 1166, - 64429, 42639, 0, 0, 0, 0, 128071, 2442, 10703, 194940, 194939, 194635, - 42439, 0, 0, 0, 73933, 983242, 42401, 0, 0, 0, 42288, 0, 0, 0, 13145, 0, - 2468, 0, 42327, 0, 0, 0, 42479, 128698, 0, 0, 92580, 0, 74939, 120678, 0, - 73733, 0, 0, 2715, 0, 71257, 0, 74114, 0, 0, 0, 0, 0, 66325, 69603, 0, - 9240, 0, 0, 129142, 0, 0, 0, 9815, 0, 11246, 0, 73912, 42733, 0, 0, 2480, - 0, 0, 0, 6494, 5537, 0, 0, 0, 0, 1211, 0, 121379, 0, 0, 12318, 0, 113796, - 0, 0, 0, 0, 0, 64642, 0, 0, 0, 0, 64864, 0, 0, 0, 121212, 0, 0, 3589, - 92719, 4035, 6492, 92236, 4265, 6843, 0, 74186, 41778, 113764, 119216, - 2488, 0, 4582, 0, 71426, 41777, 12926, 72708, 7528, 10550, 113761, 0, 0, - 11439, 0, 0, 64878, 0, 0, 0, 0, 2286, 0, 0, 126646, 127909, 5909, 400, - 126500, 0, 0, 0, 0, 0, 64827, 0, 74948, 390, 0, 71301, 0, 3473, 0, 0, - 66742, 0, 55285, 0, 0, 0, 92206, 194964, 0, 8004, 0, 6763, 0, 0, 7006, 0, - 0, 6757, 73707, 126648, 0, 6766, 0, 0, 0, 6146, 0, 771, 0, 0, 41318, 0, - 42272, 0, 120211, 69559, 0, 953, 12917, 72287, 12300, 64837, 11491, - 68612, 0, 0, 71321, 7490, 11389, 7489, 3379, 0, 7487, 42996, 7486, 7484, - 7482, 6753, 7480, 7479, 7478, 7477, 6501, 7475, 42995, 7473, 7472, 2474, - 7470, 7468, 124977, 0, 0, 0, 0, 71871, 11834, 128376, 0, 6017, 0, 128763, - 0, 0, 0, 119365, 73949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2472, 69945, - 120699, 121133, 2139, 4256, 120776, 74380, 0, 73847, 73844, 0, 0, 101375, - 0, 101374, 0, 0, 101347, 7083, 0, 8066, 7678, 0, 121124, 101341, 101373, - 101336, 0, 101331, 0, 101304, 0, 101301, 0, 0, 0, 8330, 0, 101298, - 101322, 101297, 0, 0, 19934, 0, 1770, 67091, 0, 128671, 129617, 110605, - 101355, 73843, 110604, 0, 101362, 67092, 0, 71334, 0, 0, 0, 0, 0, 8162, - 0, 5996, 129644, 4903, 0, 0, 43063, 0, 5172, 0, 7139, 0, 127385, 0, - 118667, 0, 0, 4334, 6324, 41975, 12186, 10674, 12308, 0, 0, 0, 72807, - 41977, 68002, 0, 126630, 2018, 121388, 41979, 68003, 0, 68000, 0, 0, - 126984, 68001, 9334, 118609, 71440, 0, 7975, 0, 0, 0, 66621, 4884, 70367, - 983759, 0, 121010, 0, 0, 0, 0, 127799, 0, 0, 0, 463, 0, 194584, 69617, - 6509, 5460, 0, 0, 0, 0, 42279, 0, 0, 0, 0, 0, 0, 0, 125027, 0, 121119, 0, - 0, 0, 5663, 0, 0, 0, 0, 2482, 66202, 0, 0, 42247, 65174, 73925, 0, - 100940, 0, 0, 126573, 0, 0, 2460, 0, 11944, 0, 0, 64679, 120835, 127310, - 0, 0, 0, 5870, 0, 0, 0, 100931, 539, 100933, 100932, 100935, 9064, - 100937, 100936, 100939, 100938, 0, 0, 0, 0, 0, 0, 41295, 100941, 2478, - 100943, 4162, 100945, 4260, 12953, 100950, 100949, 129800, 0, 0, 0, 0, 0, - 0, 0, 5000, 0, 0, 0, 69672, 71439, 0, 74017, 0, 0, 6709, 0, 0, 983739, 0, - 0, 100922, 100921, 10301, 10333, 10397, 100925, 100928, 100927, 0, 0, 0, - 127830, 0, 4014, 12842, 0, 67413, 0, 0, 3893, 0, 0, 12210, 0, 42147, 0, - 983622, 74465, 0, 0, 0, 0, 0, 0, 0, 0, 110805, 8231, 0, 69946, 41968, - 100929, 41973, 12935, 41969, 0, 2453, 0, 0, 78807, 122893, 0, 10349, - 10413, 122956, 41962, 3202, 119097, 0, 8316, 129174, 0, 7314, 0, 0, 0, 0, - 1840, 0, 0, 0, 4883, 100908, 4723, 70099, 100909, 0, 0, 0, 0, 11089, 240, - 19906, 0, 0, 0, 43600, 121004, 13134, 93065, 0, 65931, 110649, 110650, - 42634, 110648, 0, 121005, 11463, 0, 0, 129861, 10445, 0, 92969, 0, 2614, - 0, 129954, 1729, 0, 0, 100911, 0, 43334, 100912, 100915, 100914, 66201, - 100916, 69662, 100896, 100899, 100898, 4121, 100900, 70272, 82954, 63879, - 0, 70872, 0, 0, 4039, 643, 7726, 120082, 0, 120068, 58, 0, 0, 0, 63872, - 0, 0, 100891, 0, 10625, 100892, 100895, 100894, 1416, 120073, 917761, - 67393, 0, 0, 0, 6996, 4264, 0, 100902, 66179, 66768, 100903, 13114, - 72311, 67510, 3094, 0, 0, 127074, 4437, 0, 0, 0, 55280, 42174, 0, 42430, - 129796, 72246, 42355, 0, 0, 0, 0, 121251, 127401, 0, 0, 0, 0, 0, 0, - 100882, 100881, 74037, 100883, 0, 127099, 0, 0, 0, 0, 0, 69646, 65035, - 65034, 11480, 6116, 65039, 65038, 41180, 65036, 194565, 0, 12101, 5822, - 0, 0, 0, 0, 11663, 127873, 63854, 119657, 63853, 0, 63852, 65810, 4289, - 100885, 63896, 100887, 100890, 43621, 0, 0, 0, 129613, 194560, 7461, - 73901, 0, 331, 0, 0, 0, 128029, 0, 0, 0, 74629, 0, 0, 0, 41964, 0, 63843, - 2084, 41965, 0, 100864, 100863, 100866, 63841, 78549, 41220, 13032, - 100869, 8383, 0, 78548, 126102, 0, 0, 1351, 983865, 8698, 100874, 100877, - 1930, 100879, 78554, 74360, 100880, 69859, 78551, 0, 0, 129433, 3657, 0, - 65202, 6000, 119206, 41901, 0, 0, 41740, 0, 41283, 73543, 119267, 0, 0, - 100871, 9695, 100873, 7562, 100853, 5170, 100855, 100854, 676, 100856, - 100859, 100858, 9978, 100860, 0, 0, 64934, 0, 0, 0, 113714, 113706, - 41829, 65886, 5159, 0, 41832, 704, 43077, 0, 120532, 0, 68496, 65065, - 41830, 0, 917799, 917798, 917797, 917796, 0, 67864, 113696, 917800, - 12336, 4135, 69805, 341, 2727, 4129, 100862, 100861, 0, 64503, 7913, 0, - 0, 4131, 63868, 0, 63871, 4133, 63864, 210, 0, 0, 0, 4137, 78505, 78506, - 0, 78504, 78830, 0, 0, 43873, 0, 0, 0, 0, 11988, 78510, 195, 68321, - 41501, 0, 42031, 0, 13135, 0, 0, 0, 41499, 0, 0, 9680, 41498, 917794, - 42025, 78567, 78556, 0, 0, 0, 0, 0, 0, 101074, 120502, 92597, 0, 0, - 917784, 7864, 129001, 129704, 917788, 121106, 917786, 917785, 5753, - 67816, 72371, 2219, 0, 0, 0, 0, 0, 0, 121277, 0, 917777, 917776, 917775, - 69644, 917781, 917780, 917779, 917778, 8668, 0, 121383, 917782, 5999, 0, - 0, 129195, 128243, 43653, 1726, 1015, 0, 127247, 0, 0, 64919, 0, 0, 0, - 128478, 0, 69791, 927, 0, 0, 42010, 0, 42021, 0, 0, 1299, 12240, 64537, - 0, 0, 0, 0, 0, 0, 69454, 0, 0, 0, 122903, 19914, 12179, 0, 2296, 0, 0, - 63832, 917773, 0, 63816, 2594, 63823, 63817, 11178, 0, 0, 0, 11265, - 68295, 0, 0, 0, 10554, 3972, 0, 121198, 0, 917766, 10816, 917764, 119608, - 74374, 917769, 11210, 93069, 8586, 3882, 8532, 120183, 1573, 128648, 0, - 69916, 0, 101051, 67719, 0, 0, 0, 0, 0, 0, 0, 128821, 119169, 0, 0, 6626, - 42763, 130034, 118884, 128613, 0, 83128, 0, 0, 0, 0, 0, 983561, 0, 0, 0, - 9171, 0, 0, 71305, 983919, 121146, 0, 101095, 128881, 119604, 126596, 0, - 0, 0, 128214, 42368, 0, 983106, 2271, 41487, 12118, 74124, 68651, 110836, - 110833, 3009, 41476, 41489, 69825, 3007, 1448, 3018, 0, 41491, 8521, - 5083, 5082, 0, 0, 8519, 0, 3014, 5081, 73926, 0, 128549, 0, 69951, 5079, - 129963, 2557, 128086, 65532, 11828, 0, 71297, 11105, 0, 0, 0, 8518, - 10779, 0, 71303, 0, 0, 42170, 110769, 0, 629, 1924, 0, 12037, 0, 5987, - 8462, 127744, 0, 63933, 69735, 110770, 128295, 63941, 67981, 5077, 0, - 10880, 64849, 5075, 0, 128152, 65075, 0, 11007, 983736, 0, 0, 0, 66684, - 72331, 3434, 72338, 1904, 0, 0, 72730, 0, 10499, 4507, 9578, 63925, 0, - 7979, 0, 9831, 66689, 0, 461, 194834, 0, 4504, 0, 0, 6325, 0, 43021, 0, - 0, 55236, 0, 0, 5177, 41324, 12055, 63831, 0, 41327, 12591, 0, 4114, 409, - 0, 0, 8948, 41325, 0, 721, 10182, 0, 71311, 0, 0, 94052, 74963, 83503, - 5998, 0, 0, 74825, 0, 12587, 0, 78571, 74889, 71328, 128955, 0, 74121, - 78570, 73499, 0, 0, 5995, 0, 42568, 0, 0, 63944, 73860, 126586, 0, 4167, - 0, 43175, 0, 74120, 0, 65076, 938, 73857, 73854, 11737, 9721, 0, 0, 0, - 11742, 0, 0, 11493, 12334, 128762, 0, 66623, 0, 9173, 0, 11978, 0, 12734, - 113750, 113741, 0, 6759, 0, 0, 0, 126222, 0, 70388, 129093, 13027, 42777, - 7683, 1167, 0, 4983, 0, 861, 0, 0, 68297, 0, 43757, 92978, 129298, - 122630, 127804, 0, 73546, 70815, 9616, 0, 0, 12816, 43759, 0, 12710, - 68674, 12721, 4101, 66185, 0, 5992, 7616, 0, 0, 12577, 0, 0, 853, 42693, - 0, 121088, 0, 0, 917915, 0, 42835, 0, 0, 0, 0, 0, 12712, 7105, 127807, - 65060, 66875, 9900, 0, 0, 0, 121482, 119265, 0, 64778, 12585, 0, 0, 0, 0, - 0, 0, 77826, 0, 4900, 125245, 0, 0, 0, 4119, 74768, 8971, 0, 0, 0, 78594, - 41132, 9245, 73060, 0, 4138, 194841, 0, 0, 0, 77827, 0, 13054, 0, 0, - 128416, 110760, 0, 0, 3948, 128878, 0, 0, 0, 1680, 0, 11861, 0, 0, - 120032, 0, 0, 0, 0, 74833, 74190, 5993, 42709, 0, 12706, 77846, 1893, 0, - 63915, 0, 0, 110744, 129826, 0, 63997, 120018, 63996, 3077, 0, 0, 1512, - 0, 12589, 41479, 0, 0, 0, 0, 11831, 120727, 122949, 41481, 0, 118912, 0, - 3090, 0, 3086, 1664, 1850, 0, 3079, 0, 0, 94080, 127140, 0, 0, 74401, 0, - 917555, 0, 0, 0, 0, 0, 11526, 63985, 5864, 0, 63992, 0, 63991, 0, 5480, - 7858, 0, 4116, 78149, 0, 0, 0, 63907, 0, 0, 126131, 63905, 119601, 0, - 983191, 0, 119666, 0, 0, 7534, 507, 91, 2042, 120775, 118596, 0, 66028, - 118811, 41844, 70680, 774, 0, 0, 0, 5994, 0, 12733, 0, 0, 0, 72297, 0, 0, - 0, 0, 6026, 0, 0, 0, 162, 0, 125247, 78151, 78152, 983590, 92709, 0, - 68304, 0, 0, 0, 66658, 0, 0, 0, 0, 121511, 2226, 121512, 129349, 10492, - 0, 121510, 0, 43119, 0, 0, 0, 66192, 0, 0, 4899, 12729, 0, 0, 0, 0, 4103, - 0, 129842, 77851, 69429, 129046, 0, 12859, 70087, 0, 101580, 0, 0, 0, 0, - 0, 0, 65264, 5146, 0, 194694, 71684, 0, 0, 983652, 983863, 78924, 71688, - 78463, 5147, 125019, 0, 74524, 71682, 128435, 0, 194692, 5991, 3445, 0, - 4976, 66193, 0, 0, 0, 0, 128309, 128594, 129819, 69579, 0, 63855, 0, - 10138, 0, 0, 8897, 0, 75027, 0, 120931, 77862, 65836, 0, 0, 77860, 0, 0, - 1123, 4124, 41553, 77903, 0, 71680, 121386, 398, 0, 129035, 41551, 0, 0, - 0, 41550, 9970, 0, 93062, 42392, 1305, 78901, 0, 129292, 0, 7346, 41464, - 0, 0, 0, 41465, 983567, 8528, 9149, 0, 63955, 165, 3024, 11852, 119163, - 0, 9093, 0, 9147, 0, 0, 110989, 9148, 0, 4096, 53, 8296, 0, 71352, 0, - 9594, 0, 0, 63952, 0, 10997, 0, 0, 5805, 0, 0, 129777, 42176, 71455, - 74601, 129604, 10591, 0, 92852, 0, 0, 0, 0, 0, 0, 92475, 0, 0, 42379, 0, - 0, 9220, 0, 121425, 0, 0, 4132, 0, 0, 11239, 0, 0, 74837, 0, 66408, 0, - 8055, 0, 0, 0, 63962, 74042, 8924, 43123, 5988, 0, 63969, 0, 42718, 8788, - 1357, 77872, 65743, 0, 8774, 0, 0, 0, 0, 92748, 120598, 128234, 9564, 0, - 0, 119124, 0, 121241, 110983, 92975, 3121, 0, 0, 0, 70081, 0, 0, 0, 0, 0, - 64851, 0, 0, 73085, 119532, 0, 0, 0, 0, 1198, 69293, 66708, 64619, 0, - 64663, 93991, 0, 0, 2101, 1398, 0, 92554, 0, 0, 92684, 11406, 101588, - 12127, 66998, 840, 0, 0, 7101, 120938, 0, 0, 12880, 0, 43104, 0, 0, 0, - 2117, 0, 0, 0, 0, 123023, 0, 0, 7769, 129867, 92413, 0, 0, 100695, 0, - 40986, 83117, 0, 0, 4127, 0, 0, 129034, 0, 0, 0, 70738, 0, 129466, 0, 0, - 0, 0, 119081, 0, 10581, 0, 4533, 0, 128941, 6490, 0, 12038, 0, 0, 68225, - 0, 0, 69704, 0, 1948, 119007, 129607, 101586, 0, 0, 0, 120802, 0, 9494, - 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, 3436, 0, 127279, 12817, 0, - 126607, 118678, 0, 0, 0, 74433, 0, 0, 71962, 0, 121296, 65916, 0, 0, - 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983133, 67676, 0, 0, 74627, - 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, 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, - 121271, 0, 11919, 64962, 0, 43739, 0, 66358, 0, 0, 0, 43679, 72284, - 72289, 0, 129523, 1253, 983870, 65766, 500, 65764, 65765, 65762, 65763, - 65760, 65761, 70334, 983867, 9821, 11702, 110630, 110631, 110628, 110629, - 128481, 0, 7533, 66717, 92500, 92305, 0, 0, 69277, 127758, 71332, 0, 0, - 0, 0, 11188, 0, 4112, 0, 0, 12890, 0, 0, 9915, 0, 68423, 0, 0, 2876, 0, - 0, 0, 0, 7382, 92415, 0, 128132, 0, 0, 0, 0, 69561, 127915, 0, 7003, 0, - 0, 7704, 0, 0, 0, 4123, 0, 0, 9977, 0, 0, 65759, 0, 0, 128266, 9808, 0, - 92611, 4126, 0, 9521, 9589, 64755, 0, 0, 0, 69948, 0, 92368, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 93814, 0, 0, 92234, 0, 10693, 0, 0, 65897, 4058, 0, 0, - 64660, 0, 0, 0, 983730, 1139, 43298, 0, 65929, 8970, 0, 9934, 0, 11023, - 128020, 42522, 0, 0, 0, 78899, 3057, 128113, 7349, 69959, 128722, 68065, - 110813, 0, 92826, 67201, 0, 0, 0, 9528, 0, 0, 0, 9102, 627, 92827, 6273, - 129496, 0, 0, 983212, 92966, 43300, 0, 983740, 11696, 92825, 1018, 65554, - 0, 74338, 0, 7645, 0, 128321, 0, 0, 0, 0, 73814, 11544, 12563, 10728, 0, - 0, 127340, 43311, 64966, 92841, 0, 0, 118946, 0, 0, 74779, 0, 185, 65085, - 74533, 0, 0, 7535, 0, 42525, 0, 9749, 41701, 6131, 0, 4117, 129062, - 126988, 0, 92429, 65693, 0, 73445, 0, 69695, 0, 0, 0, 0, 0, 0, 0, 1184, - 0, 815, 0, 0, 0, 0, 0, 71325, 0, 0, 64683, 983816, 0, 127959, 0, 0, 0, 0, - 0, 0, 0, 68166, 0, 0, 0, 0, 66799, 0, 128912, 0, 5142, 0, 69643, 0, 0, - 68367, 93975, 0, 0, 0, 123209, 124133, 0, 0, 74855, 121330, 0, 0, 0, 0, - 10940, 66030, 0, 70385, 73494, 0, 2652, 120527, 0, 129946, 0, 126508, 0, - 0, 0, 0, 0, 0, 1828, 0, 128357, 0, 8531, 0, 74799, 12324, 72434, 65238, - 68374, 0, 65573, 0, 68308, 68679, 12904, 43445, 0, 0, 0, 11247, 0, 0, - 41426, 0, 0, 0, 0, 0, 67250, 69451, 83354, 11869, 0, 0, 0, 0, 0, 0, 637, - 0, 0, 0, 121178, 0, 0, 74474, 71306, 0, 7298, 128256, 0, 0, 0, 0, 8210, - 0, 0, 0, 2046, 0, 0, 0, 70333, 0, 1506, 69926, 0, 83353, 0, 12651, 0, 0, - 11867, 12058, 120626, 72111, 7803, 0, 0, 65592, 118844, 0, 0, 355, 9719, - 0, 118961, 0, 121077, 127246, 0, 42178, 0, 69760, 42571, 0, 0, 0, 0, 0, - 0, 127176, 3178, 0, 0, 92704, 83381, 9080, 120943, 67697, 0, 121342, - 129875, 0, 71485, 0, 917837, 0, 0, 78157, 0, 0, 0, 0, 0, 71313, 0, 70710, - 128212, 0, 72238, 67858, 0, 0, 0, 0, 0, 0, 0, 10770, 118994, 0, 465, 0, - 983656, 74348, 0, 0, 0, 0, 0, 0, 0, 10930, 0, 0, 0, 119091, 69388, - 122637, 129918, 0, 0, 0, 0, 0, 10092, 0, 0, 0, 0, 119019, 1766, 11282, - 11996, 66644, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120906, 4345, 0, 0, - 128947, 0, 0, 0, 0, 0, 5382, 0, 0, 118552, 0, 0, 5406, 43127, 120007, 0, - 3590, 129874, 0, 0, 0, 42016, 0, 0, 121002, 0, 7742, 0, 66562, 71323, 0, - 0, 5310, 0, 123625, 0, 43594, 0, 128260, 66723, 0, 73816, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1326, 128723, 0, 0, 74519, 0, 0, 0, 0, 71308, 0, 5410, 5783, - 0, 8403, 5400, 120526, 0, 128863, 0, 0, 0, 64412, 0, 0, 5587, 42865, - 71858, 0, 0, 129854, 0, 113785, 0, 120755, 0, 69738, 0, 74867, 10461, - 12103, 0, 0, 70701, 0, 0, 0, 0, 0, 94009, 0, 2760, 0, 8816, 41515, 0, - 11802, 0, 7585, 910, 0, 0, 0, 3658, 83386, 120525, 0, 7617, 0, 12888, 0, - 0, 64631, 0, 41514, 11097, 5703, 0, 41517, 41504, 41519, 0, 70104, 0, - 65864, 0, 120533, 0, 121037, 0, 0, 43553, 120774, 0, 0, 0, 0, 0, 1578, 0, - 43449, 0, 0, 8225, 121191, 94024, 72799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 110655, 0, 110656, 121247, 72213, 0, 110658, 0, 74997, 0, 3195, 10999, - 983570, 7897, 0, 1203, 74396, 0, 64544, 0, 0, 0, 2877, 0, 0, 0, 121112, - 0, 0, 128977, 119607, 0, 0, 0, 0, 983623, 0, 0, 0, 0, 0, 0, 0, 0, 983078, - 0, 0, 0, 9939, 0, 0, 0, 0, 0, 0, 0, 10714, 0, 0, 0, 0, 0, 67738, 0, - 74038, 0, 42897, 0, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 11163, 0, 0, 0, 113701, - 4966, 128802, 70674, 129468, 123207, 3841, 0, 0, 983231, 77886, 0, 4972, - 0, 64699, 0, 0, 0, 0, 0, 12705, 10203, 9608, 0, 0, 11962, 121397, 0, - 1196, 67684, 0, 777, 0, 0, 65271, 0, 0, 0, 0, 64824, 983195, 0, 9454, - 63778, 8658, 0, 0, 2705, 0, 64894, 0, 0, 11986, 92636, 0, 8280, 0, 2701, - 0, 0, 0, 0, 0, 9809, 0, 0, 0, 0, 0, 63761, 1748, 0, 65719, 121078, 0, 0, - 0, 55244, 3061, 0, 63765, 63787, 0, 41520, 0, 7694, 0, 8896, 63768, - 55282, 0, 127781, 0, 0, 63807, 1591, 0, 6386, 118554, 0, 0, 0, 983200, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 68289, 0, 0, 7624, 67487, 10996, 92247, 10609, 0, - 127181, 10987, 0, 70370, 3894, 0, 0, 0, 0, 493, 0, 0, 1717, 12228, 479, - 917941, 129347, 129473, 917935, 917939, 917924, 917932, 92303, 64315, - 92170, 0, 83522, 6233, 42681, 83525, 83518, 83519, 64911, 83521, 0, 0, - 83516, 83517, 129843, 8378, 11632, 0, 0, 7323, 0, 120771, 0, 0, 0, 0, - 120904, 83526, 0, 128710, 92672, 0, 0, 0, 0, 0, 0, 0, 63806, 63800, 0, 0, - 0, 63798, 63803, 244, 11542, 0, 0, 73761, 0, 12669, 120310, 0, 0, 0, 0, - 120680, 71908, 0, 0, 8612, 0, 0, 0, 0, 0, 64662, 125056, 1360, 248, 0, - 63797, 0, 63794, 0, 7292, 983685, 63756, 42786, 74957, 0, 12663, 0, 0, 0, - 0, 0, 0, 0, 4579, 0, 0, 0, 0, 0, 0, 71130, 65545, 9602, 8623, 0, 128052, - 0, 0, 0, 0, 0, 0, 0, 659, 6098, 0, 12234, 83511, 83512, 8311, 83514, - 7669, 83508, 83509, 83510, 0, 0, 0, 0, 983951, 0, 0, 2323, 0, 2319, - 77917, 120900, 77916, 2311, 83077, 4415, 1586, 68050, 0, 128724, 83020, - 2309, 83022, 8173, 83013, 83014, 83015, 83016, 0, 83010, 69275, 83012, - 9397, 0, 9395, 9396, 9393, 9394, 9391, 9392, 9389, 6209, 9387, 9388, - 9385, 9386, 9383, 9384, 0, 0, 0, 0, 0, 11259, 0, 0, 0, 2313, 0, 119661, - 0, 0, 0, 0, 10570, 65776, 110968, 0, 83006, 83007, 11998, 83009, 83002, - 83003, 83004, 66406, 0, 128780, 83000, 11818, 9381, 9382, 9379, 9380, - 9377, 9378, 9375, 9376, 1683, 9374, 0, 9372, 0, 0, 0, 0, 127801, 0, - 42029, 11079, 0, 43451, 42032, 0, 0, 118666, 0, 5005, 0, 0, 42030, 5007, - 78828, 126210, 0, 4951, 110776, 0, 110775, 0, 43309, 121222, 92172, 0, - 92334, 0, 9548, 0, 119138, 71896, 0, 0, 0, 0, 0, 0, 65691, 65580, 64361, - 10496, 0, 0, 0, 917975, 0, 0, 41046, 0, 0, 0, 13177, 0, 64703, 0, 43499, - 3389, 10589, 0, 11208, 120719, 78395, 73964, 78393, 78392, 78391, 11314, - 8281, 113732, 113667, 113745, 9076, 8862, 69743, 41052, 78397, 64766, - 69821, 0, 0, 0, 82992, 82994, 10671, 82998, 82987, 82989, 82990, 6303, - 113664, 498, 64471, 82986, 129901, 0, 9349, 0, 0, 119343, 8031, 2249, 0, - 128999, 3231, 0, 6422, 0, 0, 119339, 2537, 78405, 41429, 78403, 78401, - 78399, 0, 0, 41433, 4719, 41431, 0, 78411, 5211, 41428, 78407, 82983, - 1772, 0, 0, 82979, 66850, 64812, 82982, 82975, 68767, 82977, 82978, 0, 0, - 0, 0, 41064, 70368, 9663, 66838, 129381, 12304, 125113, 0, 41062, 66847, - 0, 0, 41061, 70454, 0, 127187, 83049, 83050, 41509, 83054, 83045, 83046, - 83047, 83048, 0, 43184, 41507, 1958, 0, 66816, 41506, 0, 0, 0, 120717, 0, - 0, 0, 74349, 72113, 8008, 0, 0, 0, 65083, 6839, 0, 126517, 73803, 127055, - 127056, 3508, 127058, 127059, 78038, 0, 120932, 0, 6411, 128115, 0, 0, - 128832, 100930, 0, 0, 0, 0, 0, 129776, 128546, 0, 0, 120914, 0, 0, 0, 0, - 917822, 128810, 983676, 65599, 0, 9966, 12607, 4948, 128070, 0, 128149, - 0, 0, 6207, 0, 6117, 73916, 0, 0, 0, 0, 68244, 41511, 0, 129489, 127304, - 0, 121289, 0, 118618, 83031, 83032, 0, 41556, 0, 0, 0, 128571, 73504, 0, - 0, 118645, 41510, 7953, 0, 0, 41513, 0, 0, 0, 83038, 83039, 83040, 83041, - 83034, 83035, 848, 9868, 983150, 6424, 118625, 83033, 0, 0, 0, 0, 118539, - 0, 893, 64576, 13299, 0, 0, 71998, 71447, 0, 0, 0, 0, 8903, 0, 0, 0, - 8099, 0, 0, 0, 0, 0, 0, 0, 0, 113713, 0, 0, 0, 0, 0, 83027, 41483, 83029, - 83030, 83023, 83024, 69436, 64836, 194756, 41485, 194758, 194757, 194760, - 41482, 42737, 64588, 0, 127787, 0, 10014, 0, 0, 194763, 194762, 68785, - 194764, 194767, 194766, 0, 0, 0, 11377, 122634, 0, 983811, 0, 0, 0, 9776, - 0, 93824, 5215, 194750, 13227, 8758, 194751, 128744, 0, 0, 5363, 12957, - 0, 0, 129051, 129526, 6421, 0, 0, 121304, 0, 0, 0, 0, 92625, 119070, - 67895, 983962, 0, 68608, 6482, 0, 0, 11945, 0, 0, 8838, 0, 4025, 10709, - 0, 2108, 0, 73929, 0, 0, 10617, 194737, 128031, 194739, 194738, 68614, - 194740, 68611, 9924, 129952, 194744, 0, 0, 0, 3277, 0, 4947, 41055, 0, - 194722, 129930, 194724, 194723, 64626, 194725, 42266, 194727, 8371, - 194729, 127028, 12806, 41492, 0, 0, 73930, 194731, 124140, 41054, 1078, - 194735, 194734, 41057, 0, 0, 0, 0, 0, 92210, 73009, 0, 41496, 0, 9165, - 1572, 0, 129712, 0, 128635, 9215, 9330, 129809, 10032, 41745, 43183, - 6401, 5831, 0, 0, 0, 8056, 0, 65681, 92377, 0, 0, 0, 121048, 0, 118887, - 6408, 0, 0, 5661, 82972, 82973, 3603, 0, 82967, 3548, 82969, 82970, 0, - 82964, 82965, 9918, 118787, 11321, 0, 0, 0, 128992, 0, 0, 0, 0, 0, 0, - 41558, 41471, 0, 8158, 41561, 41472, 0, 0, 194672, 43762, 77927, 6701, - 41559, 1896, 66256, 66248, 194680, 5665, 0, 194681, 0, 0, 0, 74352, 0, - 5664, 127895, 194682, 12310, 5662, 194687, 194686, 73924, 1121, 82953, - 82955, 0, 74378, 0, 0, 74966, 0, 71892, 0, 69413, 194667, 8627, 194669, - 10110, 194671, 42024, 6420, 42028, 0, 10509, 2795, 73923, 0, 69231, 0, - 6275, 93957, 917927, 124972, 194655, 127786, 6423, 129733, 0, 0, 68526, - 12823, 0, 0, 42026, 42017, 0, 7524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12691, - 68072, 42722, 69877, 82956, 78655, 78661, 82959, 78662, 41265, 41065, - 1795, 917809, 118791, 10587, 0, 917807, 0, 194640, 0, 12946, 194641, - 71921, 194643, 9169, 70372, 194648, 194647, 68202, 194649, 73990, 65111, - 0, 748, 41067, 6234, 194651, 9990, 72795, 194652, 194629, 194628, 194631, - 194630, 67896, 194632, 917812, 3593, 82948, 82949, 82950, 82951, 82944, - 69729, 82946, 82947, 194638, 194637, 0, 581, 0, 42929, 7944, 0, 0, 0, 0, - 0, 0, 72143, 0, 10119, 6415, 42893, 0, 69702, 0, 0, 11375, 0, 0, 0, 412, - 92765, 42928, 42880, 43587, 0, 0, 0, 0, 0, 0, 122638, 0, 0, 0, 65854, - 92508, 65811, 75024, 194624, 194627, 9344, 8826, 92916, 0, 125090, 74781, - 0, 0, 129582, 0, 0, 0, 127783, 0, 0, 0, 0, 10133, 92755, 0, 0, 0, 0, - 78414, 78413, 118950, 74011, 0, 0, 121080, 0, 1908, 127378, 4918, 0, 0, - 70709, 67825, 6250, 0, 10811, 78412, 11339, 4914, 0, 0, 118971, 4917, - 70686, 0, 0, 4912, 69722, 73845, 0, 0, 129527, 0, 0, 0, 118986, 0, 0, - 74317, 0, 8319, 194714, 194717, 10960, 72196, 8305, 12573, 983620, 72193, - 0, 13202, 0, 12582, 0, 72198, 69856, 0, 0, 78598, 0, 72195, 0, 65802, - 74822, 7698, 12708, 74045, 0, 0, 70460, 4913, 127990, 0, 123539, 0, 0, - 12728, 129980, 128895, 0, 101281, 0, 130038, 0, 101283, 0, 12588, 8821, - 6153, 194705, 78900, 194707, 194710, 194709, 194712, 194711, 118854, - 194713, 651, 0, 0, 0, 0, 0, 78468, 78469, 69433, 78467, 69614, 74905, - 194695, 78461, 194697, 194696, 0, 4716, 43277, 0, 2185, 78475, 128592, - 120928, 194700, 55264, 194702, 12732, 0, 12707, 0, 0, 0, 0, 121417, 8479, - 4151, 0, 0, 0, 0, 0, 0, 0, 0, 113799, 0, 74050, 0, 0, 0, 0, 0, 129467, - 12278, 0, 129507, 0, 2700, 12576, 7842, 0, 67471, 0, 2699, 0, 0, 2985, 0, - 126475, 0, 129873, 119314, 0, 119312, 9827, 101292, 119311, 101291, - 119309, 119306, 11481, 118718, 119305, 0, 35, 78481, 78482, 66694, 78480, - 78477, 78478, 0, 0, 64257, 0, 0, 0, 78485, 78486, 78483, 4272, 0, 0, - 40965, 0, 12704, 78487, 983568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5244, 4189, - 94108, 0, 127948, 4188, 1879, 0, 0, 0, 43743, 71974, 8873, 2279, 0, 0, 0, - 12574, 12735, 92749, 92753, 983921, 0, 0, 75001, 0, 0, 0, 12578, 12720, - 128628, 101088, 0, 12346, 128596, 101089, 0, 0, 7251, 0, 0, 118850, - 73025, 0, 0, 0, 0, 0, 12564, 66457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101131, - 0, 41564, 10976, 0, 121223, 0, 0, 10054, 9197, 120618, 0, 9012, 65737, - 74420, 0, 13215, 12730, 0, 0, 0, 0, 816, 0, 101123, 122664, 83191, 0, 0, - 92752, 101120, 4715, 94107, 94106, 71075, 0, 0, 0, 67729, 0, 307, 0, - 9585, 0, 0, 0, 101255, 0, 125267, 0, 70727, 65567, 101238, 75006, 101231, - 983909, 0, 12236, 41419, 101259, 194621, 101248, 75003, 194622, 73675, - 120957, 41421, 75005, 4462, 118569, 126599, 983911, 821, 0, 2498, 5800, - 100834, 100833, 1760, 67483, 4469, 64377, 100840, 100839, 0, 757, 1185, - 118558, 100841, 0, 10628, 100842, 68849, 100844, 43971, 100846, 100849, - 64763, 0, 7713, 0, 0, 0, 4380, 194608, 128073, 194610, 194609, 194612, - 862, 65626, 194613, 65627, 65629, 5137, 194617, 0, 0, 0, 65069, 7566, - 64688, 67143, 118592, 100823, 100822, 100825, 4748, 92228, 100826, - 100829, 42260, 129494, 64107, 0, 0, 0, 0, 128189, 0, 194604, 13137, 8775, - 127945, 123633, 194607, 0, 8410, 4454, 194585, 0, 92542, 4449, 92330, - 127064, 75022, 92761, 70664, 194589, 339, 194591, 194590, 0, 70662, 0, - 100830, 41543, 0, 0, 0, 41542, 127066, 8916, 6705, 0, 129296, 0, 0, 0, 0, - 0, 41548, 6729, 119329, 0, 7348, 0, 0, 7537, 0, 11819, 0, 0, 123624, - 71269, 0, 7344, 100808, 129073, 9780, 0, 11117, 74993, 0, 194578, 10483, - 194580, 194579, 194582, 194581, 68781, 125114, 100820, 100819, 0, 4211, - 1259, 7517, 0, 0, 194561, 70827, 194563, 194562, 641, 5219, 94034, - 194566, 11064, 194568, 0, 129820, 0, 0, 0, 0, 100812, 100811, 100814, - 100813, 100816, 100815, 100818, 100817, 100798, 100797, 41410, 100799, - 64262, 0, 41407, 75000, 0, 0, 93812, 0, 0, 72803, 74999, 78897, 0, 0, - 67675, 0, 0, 0, 0, 43647, 0, 0, 100792, 100791, 100794, 100793, 100796, - 100795, 983276, 74630, 11933, 0, 0, 41903, 67892, 11001, 100801, 42255, - 100803, 100802, 100805, 41905, 100807, 100806, 10775, 9793, 0, 0, 74452, - 0, 983063, 42535, 0, 64529, 41408, 42853, 0, 0, 42674, 118915, 0, 0, - 983807, 0, 70838, 0, 0, 0, 64506, 0, 66738, 4747, 100783, 69844, 100785, - 5832, 0, 0, 5141, 42600, 124147, 0, 0, 0, 0, 0, 93790, 0, 7657, 0, 71132, - 74137, 0, 128362, 73682, 73681, 859, 0, 0, 0, 6059, 126985, 55235, 0, 0, - 0, 0, 0, 100787, 11488, 72838, 100788, 0, 100790, 10558, 0, 124144, - 118646, 126090, 71069, 0, 0, 1788, 0, 0, 0, 0, 119571, 92822, 9028, 0, - 69234, 73665, 0, 9905, 73556, 41242, 70086, 0, 74109, 100765, 100764, - 100767, 100766, 70830, 83184, 70082, 3940, 0, 43754, 0, 128188, 8665, 0, - 0, 0, 1653, 100775, 42406, 100777, 100780, 70825, 120523, 0, 8815, 0, - 65046, 0, 42445, 0, 11180, 119318, 119315, 68454, 42485, 0, 0, 8211, - 42293, 983602, 0, 0, 0, 0, 65385, 100771, 42332, 100773, 78431, 78432, - 78423, 78430, 78420, 10022, 65387, 78419, 65384, 0, 0, 0, 65386, 0, - 11248, 0, 43198, 64751, 0, 0, 0, 0, 0, 0, 101102, 7363, 0, 0, 119323, - 119324, 100752, 100751, 0, 119320, 0, 983632, 0, 8237, 0, 0, 0, 0, 0, 0, - 9914, 0, 100763, 100762, 120009, 6351, 119993, 92740, 68766, 0, 120010, - 41243, 0, 74108, 11467, 120165, 119998, 4358, 0, 6353, 0, 0, 0, 93045, - 1710, 0, 0, 92237, 0, 49, 73871, 120005, 78671, 0, 78672, 9741, 78443, - 78444, 78441, 43443, 78439, 78440, 69244, 78438, 3470, 0, 0, 92814, 0, 0, - 78445, 0, 1072, 78457, 78452, 78454, 74230, 78451, 78447, 78449, 1080, 0, - 74100, 0, 1101, 68404, 78458, 78459, 71082, 0, 1086, 1869, 0, 0, 0, - 65458, 0, 0, 41988, 0, 1091, 0, 7977, 0, 66992, 0, 0, 0, 92758, 0, 0, 0, - 0, 0, 71255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64582, 0, 0, 70794, 0, 120989, - 128495, 74106, 0, 66883, 0, 0, 0, 0, 0, 0, 0, 92553, 43752, 110592, 0, - 71249, 120886, 0, 0, 0, 0, 6063, 100857, 101221, 917995, 6053, 74096, 0, - 0, 74169, 13100, 0, 917999, 0, 71081, 0, 70387, 6055, 7800, 4279, 8490, - 120114, 120111, 64786, 8602, 120110, 83389, 92204, 0, 0, 74961, 0, - 120117, 120118, 120099, 120100, 65087, 64402, 3674, 120096, 0, 120094, - 120107, 118624, 120105, 10107, 42159, 42870, 120101, 69632, 0, 0, 43281, - 127078, 0, 74098, 0, 0, 126497, 74099, 129056, 0, 0, 0, 121123, 5847, - 125258, 0, 0, 0, 0, 0, 66592, 64469, 71698, 19966, 0, 42561, 0, 129170, - 66854, 8120, 75042, 0, 0, 0, 0, 0, 0, 126068, 8369, 0, 0, 122912, 3369, - 0, 121094, 0, 0, 69238, 10495, 121365, 0, 557, 9457, 0, 0, 121054, 73880, - 127220, 0, 74937, 74094, 0, 0, 119001, 92171, 127219, 128175, 127939, - 120424, 0, 127214, 2109, 67893, 127211, 69656, 127217, 10604, 127215, 0, - 0, 0, 129727, 126561, 0, 0, 0, 0, 1618, 0, 0, 83175, 10430, 0, 0, 13063, - 917585, 0, 92982, 113666, 0, 78390, 83489, 12060, 0, 113669, 0, 6329, 0, - 0, 0, 74395, 2707, 8309, 0, 127054, 78398, 0, 2697, 0, 78396, 127057, - 2695, 0, 0, 68334, 0, 0, 0, 72325, 2693, 74091, 0, 0, 2703, 113729, - 70283, 41918, 983169, 127542, 8687, 127543, 12178, 43361, 92540, 64075, - 110705, 5248, 110703, 120538, 6427, 0, 0, 0, 0, 110710, 0, 74990, 74989, - 70703, 127031, 0, 9873, 0, 0, 0, 64762, 2053, 0, 6591, 9340, 0, 1589, 0, - 296, 67712, 128315, 12766, 118931, 74370, 120417, 2414, 128068, 43829, - 111202, 74836, 0, 12579, 0, 12575, 6416, 5656, 0, 13262, 65590, 5299, - 983702, 0, 5449, 1252, 0, 78404, 69748, 74369, 65373, 5295, 0, 121066, - 1223, 1642, 78408, 0, 12158, 5303, 0, 120546, 41413, 3212, 127025, 3211, - 74810, 41425, 127029, 0, 74450, 9728, 0, 10924, 74778, 6636, 73552, - 129884, 0, 0, 129882, 9519, 0, 0, 129106, 101110, 68780, 0, 0, 0, 119182, - 0, 12104, 77942, 77951, 9004, 0, 74249, 10230, 0, 0, 0, 77947, 0, 69679, - 121475, 9890, 125049, 12971, 0, 92556, 0, 67903, 70051, 983924, 0, 0, - 9635, 12600, 0, 0, 0, 118900, 6469, 0, 101113, 65304, 4679, 101114, - 64300, 64867, 6531, 101118, 101099, 101098, 92813, 101100, 42916, 0, 0, - 0, 0, 0, 0, 4445, 72296, 0, 11533, 0, 3416, 124112, 0, 0, 0, 78566, 0, 0, - 101091, 92815, 101093, 5447, 72140, 70752, 101097, 101096, 0, 0, 0, - 64448, 0, 43920, 70677, 0, 6232, 101101, 101104, 101103, 43608, 101105, - 101108, 6538, 4335, 0, 3941, 74986, 11061, 0, 74988, 74987, 0, 12155, - 128278, 0, 0, 0, 0, 74578, 0, 65832, 0, 129459, 70789, 0, 125050, 0, 0, - 350, 10951, 101081, 509, 101083, 101086, 101085, 0, 0, 0, 917540, 0, - 100905, 110970, 12162, 64741, 0, 9354, 0, 70802, 100901, 2496, 11516, - 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, 1220, 917952, 93844, 0, 0, - 5008, 42630, 70787, 101087, 2229, 68206, 564, 0, 312, 0, 0, 0, 70797, - 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, 0, 10862, 0, 0, 41416, 0, - 4173, 0, 0, 0, 1906, 983854, 41418, 74073, 101068, 101067, 41415, 69622, - 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, 10469, 101076, 101079, - 68088, 0, 101080, 72342, 0, 129692, 0, 6129, 0, 0, 0, 0, 7874, 0, 0, - 11206, 13136, 118529, 129305, 0, 64374, 74925, 0, 73892, 0, 101073, - 101072, 101075, 74960, 9228, 101054, 101057, 101056, 5240, 9811, 0, - 101060, 129718, 0, 0, 74079, 65873, 0, 0, 0, 9501, 0, 68081, 72808, - 65465, 64654, 7467, 0, 0, 83460, 10040, 0, 3096, 0, 101053, 101052, - 68820, 83461, 0, 0, 0, 0, 0, 0, 83377, 0, 68801, 0, 101062, 101061, - 101064, 101063, 0, 8637, 70741, 0, 77983, 77969, 11471, 43554, 0, 77968, - 0, 0, 0, 2426, 12042, 0, 0, 0, 3961, 12115, 129633, 0, 77972, 64561, 0, - 4981, 74644, 129558, 0, 0, 42686, 77976, 128776, 64686, 0, 77958, 7589, - 0, 0, 3237, 0, 68215, 0, 8541, 127157, 71067, 120174, 0, 0, 0, 0, 0, - 43555, 0, 0, 10060, 111261, 100917, 0, 0, 0, 64877, 0, 0, 8614, 65220, - 41493, 0, 0, 0, 43780, 0, 0, 70689, 0, 0, 0, 0, 0, 0, 4012, 10395, 0, 0, - 111253, 126511, 111254, 125051, 695, 739, 696, 7611, 0, 42755, 68421, - 9227, 7506, 7510, 67493, 691, 738, 7511, 7512, 7515, 7501, 688, 41847, - 690, 2548, 737, 974, 43386, 0, 0, 0, 0, 0, 0, 65860, 0, 7051, 69777, - 4682, 0, 983096, 6406, 4685, 0, 0, 10347, 4680, 6341, 0, 0, 92607, 74325, - 0, 123555, 0, 0, 0, 0, 0, 0, 43505, 92468, 11718, 42373, 11714, 0, 0, - 129567, 11717, 0, 10594, 129732, 11712, 122962, 0, 10967, 0, 0, 0, 66632, - 118647, 0, 0, 0, 1735, 0, 11134, 2363, 983136, 0, 0, 70695, 128032, 0, - 7491, 7495, 7580, 7496, 7497, 7584, 121478, 127853, 0, 0, 70025, 0, 8498, - 0, 8949, 3065, 0, 0, 0, 0, 0, 0, 11713, 0, 64939, 0, 6418, 4543, 0, 0, 0, - 74800, 0, 0, 0, 0, 0, 0, 0, 12282, 3165, 0, 0, 64556, 0, 9238, 0, 68063, - 0, 0, 0, 65438, 0, 128525, 0, 119268, 0, 0, 12900, 67489, 10950, 0, 0, 0, - 41400, 126636, 119664, 0, 42232, 0, 1744, 0, 41402, 0, 0, 0, 41399, 0, - 125028, 0, 0, 12690, 0, 0, 43672, 0, 0, 0, 100870, 11315, 0, 278, 121204, - 41405, 129345, 0, 10077, 129650, 70667, 0, 0, 0, 68210, 0, 0, 11189, - 70657, 0, 0, 0, 7934, 0, 93829, 120940, 0, 0, 122971, 0, 0, 0, 6413, - 6550, 0, 1940, 2809, 43637, 70045, 0, 0, 10678, 0, 0, 0, 129701, 78804, - 6403, 6556, 78803, 0, 0, 123557, 0, 0, 0, 123553, 0, 3742, 74408, 3959, - 0, 0, 917969, 123565, 0, 128024, 0, 123558, 127956, 0, 0, 0, 6855, 4676, - 983049, 9210, 0, 78143, 983922, 0, 78168, 983100, 11540, 43546, 6692, 0, - 0, 0, 0, 9083, 0, 0, 78144, 128515, 0, 9677, 0, 70867, 74175, 0, 74070, - 0, 0, 365, 0, 43027, 0, 0, 128236, 0, 119574, 70284, 13151, 0, 0, 127935, - 127950, 544, 13249, 119018, 0, 120846, 0, 0, 73671, 65339, 73000, 2211, - 0, 0, 0, 0, 0, 0, 0, 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 92977, - 69708, 9638, 0, 100878, 0, 0, 0, 74545, 128820, 128819, 75062, 128963, 0, - 0, 0, 11264, 43994, 0, 0, 0, 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, - 0, 949, 0, 0, 0, 78176, 69709, 78177, 63828, 0, 0, 118629, 70282, 0, 0, - 0, 64822, 0, 6530, 983275, 0, 70493, 0, 129325, 0, 0, 4431, 118839, - 127490, 983760, 73667, 127986, 0, 10336, 10400, 0, 0, 92959, 0, 0, 0, - 42270, 128880, 6428, 0, 0, 0, 0, 43455, 0, 43526, 100888, 12835, 129501, - 9493, 0, 0, 11793, 0, 127897, 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, - 74274, 983627, 43556, 3929, 123615, 6614, 2768, 0, 65609, 0, 11811, - 129696, 0, 118615, 127513, 0, 6554, 0, 6305, 66283, 4675, 118826, 78552, - 0, 0, 74361, 0, 0, 68108, 0, 0, 92232, 0, 93022, 7392, 8230, 9365, - 983742, 0, 0, 0, 0, 42925, 0, 0, 122965, 0, 229, 43834, 119884, 0, 43552, - 119881, 119880, 119883, 119882, 119877, 119876, 119879, 119878, 119873, - 119872, 119875, 119874, 0, 0, 0, 0, 0, 66352, 0, 0, 0, 128663, 0, 12239, - 0, 0, 10432, 12097, 0, 194815, 1233, 78179, 0, 127200, 0, 66395, 0, 0, - 129504, 0, 0, 92342, 0, 2388, 92555, 119868, 119871, 119870, 119865, 895, - 92668, 119866, 64889, 7143, 119863, 119862, 0, 0, 69983, 0, 74376, 3053, - 2168, 0, 2047, 0, 0, 0, 121279, 67985, 194801, 92600, 194803, 194802, - 194805, 194804, 194807, 194806, 129134, 194808, 0, 0, 0, 10473, 129331, - 0, 194810, 129806, 194812, 129813, 194814, 194813, 123195, 43528, 69673, - 194791, 0, 194793, 1912, 120779, 10306, 10370, 0, 0, 8867, 10250, 10258, - 10274, 1635, 120152, 0, 0, 0, 129379, 0, 0, 9919, 120148, 559, 128157, - 41825, 127975, 92989, 0, 74016, 194781, 6542, 41957, 7318, 124126, 0, - 41956, 65749, 65750, 65751, 121323, 64487, 0, 0, 10223, 42062, 100640, - 101195, 125044, 3668, 65754, 43560, 12226, 0, 93973, 194784, 41959, - 194786, 194785, 194788, 43618, 65747, 10937, 2962, 0, 2953, 10062, 65745, - 71457, 8921, 66013, 129370, 0, 194769, 194768, 43409, 194770, 2949, - 194772, 194775, 194774, 2958, 194776, 74868, 2300, 2951, 120061, 0, - 120043, 194778, 0, 120051, 194779, 120056, 120065, 70798, 120048, 0, - 120062, 120055, 71989, 100668, 0, 0, 71985, 0, 71992, 70796, 127818, 0, - 0, 64890, 0, 43630, 11336, 799, 0, 10276, 10308, 10372, 917541, 0, 0, - 10252, 10260, 68220, 55284, 125225, 0, 10384, 0, 0, 0, 64523, 129744, 0, - 65736, 0, 0, 0, 0, 0, 0, 0, 124912, 43549, 65738, 42150, 65739, 0, 78195, - 10288, 10320, 0, 10596, 129829, 67673, 65045, 121283, 78198, 2049, 10098, - 0, 122904, 127943, 10264, 10280, 10312, 10376, 7013, 0, 69504, 0, 0, - 66375, 0, 4862, 0, 6537, 0, 128335, 3914, 92178, 93976, 9065, 64816, 0, - 72218, 73026, 0, 0, 72139, 4694, 11420, 4690, 0, 0, 983211, 4693, 0, 0, - 0, 4688, 0, 0, 128892, 0, 8238, 3110, 0, 983939, 0, 6528, 0, 0, 0, 218, - 0, 1520, 129577, 70039, 0, 983594, 0, 120167, 78167, 10088, 6548, 100786, - 0, 0, 0, 8888, 0, 124954, 0, 0, 126593, 68876, 0, 0, 0, 0, 0, 0, 0, 4689, - 43541, 77954, 120157, 0, 120156, 78810, 120163, 0, 0, 0, 0, 78121, 0, 0, - 11450, 0, 71900, 92613, 0, 121317, 74622, 128720, 9244, 0, 0, 127763, 0, - 0, 0, 0, 0, 0, 71084, 0, 0, 0, 0, 10513, 0, 0, 0, 52, 119178, 0, 0, - 93961, 0, 0, 4812, 0, 0, 0, 0, 0, 0, 128425, 0, 6850, 0, 77959, 10170, - 120450, 6544, 0, 0, 69782, 121517, 0, 0, 65258, 10369, 0, 1585, 74014, - 10249, 422, 1500, 2036, 986, 0, 64394, 69502, 5599, 917981, 2494, 0, 0, - 74021, 983896, 78203, 127808, 0, 72871, 65102, 8961, 74305, 10243, 10245, - 128170, 0, 0, 0, 0, 0, 2508, 129591, 120440, 0, 120439, 0, 0, 0, 0, 0, 0, - 64533, 983187, 0, 0, 74008, 0, 0, 43375, 0, 2504, 0, 121313, 0, 983941, - 6943, 0, 5859, 100677, 0, 0, 72873, 983945, 0, 0, 983923, 92390, 2753, - 1936, 2153, 67701, 2751, 12662, 2763, 8953, 0, 10731, 0, 7052, 0, 0, 0, - 0, 119899, 0, 66675, 0, 119897, 0, 71053, 0, 119903, 0, 67829, 7899, - 119901, 71119, 43798, 7072, 119902, 122898, 11260, 0, 71059, 0, 0, 212, - 0, 12350, 0, 0, 0, 0, 0, 128402, 2759, 0, 0, 93064, 0, 0, 0, 1291, 0, - 195065, 121318, 119911, 0, 119910, 0, 12062, 0, 121216, 0, 129124, - 121044, 120611, 8246, 128874, 0, 0, 0, 0, 0, 73962, 0, 0, 43524, 0, - 64426, 0, 0, 0, 0, 65664, 6693, 0, 0, 8674, 0, 128812, 0, 11846, 70690, - 121461, 69395, 4811, 0, 5986, 0, 3046, 74480, 5985, 0, 0, 0, 0, 12187, - 83148, 71041, 5984, 0, 93817, 4393, 126264, 120206, 917599, 0, 0, 0, - 93806, 93805, 0, 3491, 0, 67146, 0, 93819, 0, 72428, 0, 0, 0, 124968, - 41284, 126228, 0, 0, 41287, 0, 100689, 0, 0, 92189, 0, 0, 219, 120874, 0, - 0, 0, 68485, 119672, 43241, 0, 7147, 73554, 0, 0, 0, 0, 0, 64610, 11804, - 0, 7149, 64808, 0, 0, 0, 92301, 73690, 0, 5253, 0, 0, 0, 0, 129045, - 983596, 11098, 68433, 0, 120484, 111009, 0, 0, 0, 0, 0, 70801, 100779, 0, - 128198, 9604, 0, 130036, 0, 0, 118941, 64392, 0, 118684, 0, 0, 41974, - 126262, 0, 0, 0, 129818, 0, 129833, 0, 0, 0, 0, 0, 983243, 5308, 0, 290, - 0, 125278, 128382, 2792, 0, 0, 120521, 0, 126237, 0, 126099, 0, 0, 0, 0, - 128503, 0, 0, 72816, 0, 0, 0, 92671, 0, 195061, 42646, 7606, 2591, 73896, - 0, 43513, 64482, 0, 0, 65270, 0, 0, 983701, 9112, 0, 113763, 9490, 0, 0, - 0, 0, 0, 9071, 0, 0, 0, 0, 74607, 0, 2535, 65504, 43602, 0, 0, 71256, - 2248, 0, 123147, 11845, 11006, 92315, 7807, 8073, 0, 10629, 0, 74088, 0, - 10823, 0, 113762, 8762, 0, 69689, 123536, 43969, 65047, 10737, 3463, - 67467, 129585, 66645, 0, 4815, 0, 0, 12345, 983761, 0, 5195, 129808, 0, - 66639, 0, 0, 66941, 0, 92759, 92385, 1262, 0, 6561, 19939, 0, 0, 100772, - 123160, 69269, 0, 100774, 0, 0, 0, 0, 0, 0, 67511, 0, 0, 0, 0, 0, 0, - 5702, 3655, 0, 8430, 0, 68807, 0, 0, 121137, 0, 0, 5254, 0, 0, 124917, 0, - 119107, 5129, 0, 70816, 0, 92280, 5614, 0, 0, 11720, 0, 11721, 70804, - 4798, 0, 120541, 66038, 4793, 67851, 7352, 0, 0, 0, 0, 917600, 0, 300, 0, - 0, 128575, 92660, 0, 0, 2562, 70156, 120856, 0, 0, 92738, 0, 0, 127820, - 71093, 0, 127969, 128221, 0, 3424, 93843, 0, 0, 7074, 70873, 128519, 0, - 0, 10832, 0, 0, 69852, 72430, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1215, 0, - 5744, 0, 66440, 0, 0, 0, 42881, 0, 8980, 118988, 67861, 8844, 7433, 0, 0, - 4278, 124925, 0, 0, 70821, 9312, 4348, 0, 128401, 65946, 0, 7087, 5255, - 0, 661, 0, 0, 0, 0, 0, 0, 0, 121009, 73694, 0, 123154, 0, 73688, 0, - 127179, 3621, 83325, 66666, 72968, 0, 6562, 12928, 0, 73991, 0, 0, 11383, - 0, 0, 65588, 120739, 0, 0, 0, 0, 0, 0, 0, 0, 11436, 2070, 64, 110824, 0, - 10291, 10323, 10387, 0, 0, 0, 42008, 9708, 42710, 0, 42011, 0, 92164, 0, - 0, 1702, 1240, 128383, 6286, 9689, 111080, 0, 0, 0, 1765, 0, 0, 92373, 0, - 0, 0, 8401, 72991, 42014, 0, 67237, 0, 0, 0, 0, 0, 0, 0, 70819, 0, 0, 0, - 0, 12667, 0, 0, 10147, 0, 127568, 126483, 72812, 0, 0, 0, 0, 123139, - 128968, 0, 64947, 0, 0, 0, 0, 10435, 11462, 0, 7084, 0, 0, 0, 0, 0, - 126084, 0, 66662, 0, 0, 0, 0, 125134, 0, 0, 77990, 263, 983747, 41288, - 127953, 0, 78387, 74340, 70313, 129140, 0, 0, 0, 42022, 71265, 0, 0, 0, - 0, 0, 0, 42020, 123146, 0, 6992, 42019, 0, 41290, 0, 12295, 126233, - 71304, 0, 120984, 71300, 120631, 5954, 64931, 69385, 100699, 198, 68453, - 78129, 0, 121351, 0, 70818, 13165, 7107, 0, 42804, 678, 72850, 118960, 0, - 72985, 42806, 42808, 0, 0, 2097, 0, 120560, 70823, 0, 0, 3892, 68632, 0, - 6712, 917959, 0, 0, 0, 0, 123158, 69954, 0, 497, 12100, 5953, 92667, - 7796, 0, 43254, 0, 0, 11072, 5952, 1281, 43747, 0, 69380, 10677, 0, 0, 0, - 1859, 0, 72856, 3425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65199, 1738, 0, - 122911, 0, 0, 0, 11101, 0, 0, 0, 0, 127002, 69651, 4436, 194683, 73984, - 6860, 70305, 64872, 128296, 0, 0, 0, 121377, 0, 6862, 0, 6861, 983109, 0, - 119109, 0, 70826, 319, 0, 43479, 73001, 0, 0, 12849, 0, 7640, 71083, - 9673, 0, 0, 0, 92670, 0, 92665, 113717, 41422, 0, 100708, 74941, 3772, 0, - 120660, 5011, 0, 0, 126587, 111315, 0, 0, 6677, 111312, 0, 41427, 64419, - 129445, 92262, 0, 70799, 0, 0, 0, 6106, 0, 41271, 6760, 983758, 4534, - 41270, 128876, 0, 0, 119561, 0, 0, 3671, 8976, 123177, 0, 41275, 0, - 128084, 55261, 0, 42013, 0, 568, 0, 41273, 0, 0, 6728, 0, 9715, 0, 0, - 121058, 74820, 0, 92268, 0, 194564, 11191, 43688, 128023, 0, 0, 0, - 126266, 0, 0, 0, 11958, 11165, 0, 125087, 0, 0, 66336, 127944, 0, 0, 0, - 0, 42858, 11789, 72878, 5557, 0, 69444, 7300, 0, 9467, 5558, 64486, - 43844, 0, 0, 6706, 10146, 0, 127185, 64566, 0, 0, 0, 0, 0, 0, 0, 4546, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 64528, 123136, 6307, 128966, 0, 7544, 0, 43469, - 111317, 0, 10152, 0, 65091, 0, 129047, 0, 0, 66652, 0, 0, 0, 0, 64823, - 5559, 0, 70711, 6702, 5556, 0, 0, 0, 0, 0, 11166, 0, 0, 5506, 0, 1911, - 73021, 0, 12598, 8845, 66698, 0, 73012, 123145, 73496, 2098, 0, 0, 0, - 66622, 194678, 0, 0, 0, 9898, 0, 0, 7552, 0, 0, 0, 7223, 65723, 0, 0, 0, - 7024, 65728, 127155, 1210, 0, 65175, 10184, 65726, 43654, 0, 0, 0, 38, - 65729, 66669, 0, 917948, 0, 0, 0, 0, 119837, 0, 74233, 73018, 119843, - 42860, 111301, 92576, 65721, 65722, 0, 0, 0, 0, 68843, 0, 68850, 0, - 92388, 92267, 128536, 65577, 42967, 0, 127518, 11650, 5013, 92663, 68810, - 92568, 118914, 6613, 74371, 0, 0, 122985, 0, 64714, 71479, 0, 983797, - 12120, 0, 0, 43124, 0, 0, 78037, 69263, 0, 126219, 0, 0, 1837, 125086, 0, - 0, 0, 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, - 10403, 127005, 0, 41449, 0, 74028, 72019, 0, 119234, 1127, 455, 0, 0, - 72860, 3483, 0, 1989, 0, 69678, 9104, 0, 65375, 0, 0, 0, 1864, 0, 72810, - 8107, 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 73501, 8604, 0, 0, - 0, 0, 128270, 0, 0, 3115, 0, 10106, 120498, 118842, 101136, 0, 9631, 0, - 0, 0, 0, 0, 0, 0, 258, 129079, 0, 0, 0, 92292, 0, 70699, 0, 11478, 0, - 129640, 11522, 0, 8549, 0, 128430, 0, 0, 0, 0, 0, 0, 123140, 0, 0, 0, - 9221, 12590, 73048, 0, 0, 0, 67741, 111294, 12619, 0, 10154, 111266, - 74439, 2039, 0, 7446, 0, 111276, 10974, 458, 72831, 0, 0, 0, 11916, 0, 0, - 69671, 0, 121057, 12288, 0, 111288, 0, 111289, 983177, 0, 128199, 13080, - 0, 67828, 6610, 6030, 8059, 7508, 123170, 0, 0, 0, 0, 41278, 129393, - 118691, 128192, 41277, 64658, 984002, 101278, 6625, 983160, 19904, 0, 0, - 0, 0, 0, 0, 833, 0, 6369, 0, 0, 42664, 0, 0, 0, 0, 129765, 0, 6913, 933, - 1341, 68828, 6720, 0, 0, 983604, 0, 0, 7405, 128025, 0, 0, 0, 0, 0, 0, 0, - 70704, 0, 0, 0, 0, 9716, 0, 0, 0, 70719, 0, 0, 0, 0, 72862, 70687, 0, - 93987, 0, 0, 0, 70721, 9573, 0, 0, 111245, 83225, 83226, 6949, 126482, - 74061, 83222, 83223, 83224, 0, 19962, 83219, 83220, 0, 111233, 0, 42830, - 0, 111234, 74236, 66276, 0, 546, 72861, 0, 70661, 0, 472, 11083, 10319, - 10383, 917971, 0, 83202, 83203, 3602, 83206, 41182, 83199, 83200, 69796, - 3790, 0, 10271, 10287, 684, 0, 0, 0, 83214, 4592, 83216, 83217, 83210, - 11963, 43620, 83213, 0, 0, 83208, 83209, 0, 92623, 128559, 3415, 0, - 121267, 0, 0, 123151, 43447, 0, 92212, 0, 418, 0, 0, 10295, 10327, 10391, - 0, 83189, 83190, 83192, 83194, 83185, 83186, 83187, 83188, 120879, 0, - 41446, 70700, 118652, 0, 120809, 10599, 66892, 0, 0, 0, 0, 0, 129184, - 11437, 0, 0, 0, 0, 0, 0, 12624, 0, 41185, 72865, 69439, 8159, 0, 11686, - 71478, 65224, 0, 4655, 0, 0, 92183, 0, 10343, 10407, 0, 0, 0, 111221, 0, - 0, 0, 94057, 68201, 129574, 0, 983572, 72156, 42792, 5743, 10424, 0, 0, - 0, 0, 0, 8875, 111225, 0, 917991, 13117, 12847, 4651, 118917, 0, 962, 0, - 0, 2242, 42564, 0, 1582, 0, 5508, 0, 0, 0, 10801, 123602, 118798, 73705, - 0, 66911, 10439, 66891, 0, 0, 7860, 0, 906, 917985, 0, 6405, 64722, 0, - 83266, 64694, 83268, 917990, 1153, 83263, 64788, 83265, 0, 12626, 83260, - 83261, 9964, 0, 0, 4642, 66574, 127886, 0, 0, 0, 0, 0, 9008, 100847, 0, - 0, 0, 83248, 917976, 917993, 123173, 42842, 83244, 83245, 83247, 83239, - 83240, 83241, 83242, 0, 11335, 92661, 83238, 3920, 0, 0, 0, 83255, 83256, - 41967, 83258, 83251, 83252, 83253, 8920, 0, 0, 83249, 83250, 0, 0, 43919, - 0, 0, 0, 0, 128021, 0, 68113, 65196, 0, 0, 128472, 0, 10111, 64875, 0, - 83491, 43998, 83232, 83233, 83234, 70691, 83228, 42149, 83230, 68508, 0, - 0, 0, 0, 0, 0, 0, 4110, 66005, 74034, 0, 0, 0, 66703, 0, 0, 983158, 6025, - 69242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70733, 0, 983043, 0, 73513, 0, 68817, - 0, 0, 0, 0, 0, 0, 43286, 0, 68765, 0, 0, 0, 0, 129871, 65144, 0, 0, - 83236, 65840, 0, 0, 10081, 0, 0, 983912, 0, 0, 0, 127394, 65882, 0, - 128758, 0, 0, 3605, 10985, 0, 0, 128872, 93972, 1745, 0, 73835, 0, 0, 0, - 0, 0, 0, 8806, 7023, 0, 0, 0, 70702, 70304, 0, 0, 0, 0, 0, 0, 0, 0, 348, - 10089, 0, 9017, 0, 0, 0, 0, 0, 0, 0, 67465, 0, 42515, 0, 0, 0, 0, 5391, - 983240, 110576, 0, 0, 5561, 0, 9429, 0, 67150, 7933, 5562, 0, 0, 0, 0, - 78039, 0, 0, 0, 0, 3979, 71248, 0, 0, 0, 68847, 0, 0, 118847, 65847, - 68836, 68838, 0, 10585, 0, 92676, 7334, 0, 0, 0, 831, 0, 0, 10716, 0, - 121325, 0, 12218, 0, 6939, 70697, 65042, 0, 0, 916, 0, 0, 11968, 0, - 122641, 5563, 0, 0, 128830, 5560, 41212, 41774, 0, 4497, 0, 0, 0, 9039, - 70678, 41776, 0, 8716, 3567, 119252, 0, 0, 74260, 0, 93954, 0, 0, 100827, - 0, 128879, 70072, 68355, 68357, 0, 0, 8634, 0, 0, 4209, 120702, 68832, - 65879, 68825, 68819, 68822, 0, 5679, 68813, 68815, 68811, 68812, 64697, - 5678, 11821, 68802, 93969, 0, 0, 0, 0, 70114, 0, 0, 0, 0, 0, 0, 0, 0, - 7782, 0, 0, 0, 0, 129977, 65711, 65712, 1216, 0, 69409, 5792, 0, 0, 0, 0, - 0, 12244, 0, 5683, 0, 120895, 121336, 43448, 70670, 0, 0, 5682, 10242, - 75043, 74520, 5680, 917568, 10001, 0, 0, 1449, 10241, 0, 70708, 0, 0, - 83180, 83182, 83183, 8584, 83176, 5567, 83178, 83179, 0, 5564, 42886, - 42884, 42882, 5565, 119022, 120881, 0, 65708, 65709, 5566, 0, 65704, - 65705, 11904, 42875, 0, 42873, 5942, 0, 0, 10361, 10425, 65697, 65698, - 65699, 0, 66598, 0, 64664, 10647, 78702, 78703, 78690, 78700, 0, 65701, - 1934, 0, 0, 0, 78710, 0, 78706, 78709, 6087, 78705, 78716, 78719, 78711, - 8043, 8950, 65694, 64485, 0, 10457, 0, 78724, 78725, 78722, 72332, 78720, - 78721, 0, 65515, 0, 10035, 13069, 0, 0, 127773, 0, 0, 0, 125207, 0, 0, - 1667, 0, 0, 42428, 110950, 0, 0, 41750, 0, 0, 93999, 0, 8101, 3610, - 113670, 41748, 110948, 0, 78394, 119208, 0, 0, 113691, 64549, 68359, 0, - 0, 65692, 92701, 0, 917960, 12896, 10456, 68298, 0, 0, 0, 0, 917962, 0, - 0, 113665, 70502, 0, 65687, 0, 0, 74009, 0, 113673, 8536, 70671, 0, - 78726, 0, 724, 0, 113675, 78749, 9975, 78746, 78747, 78744, 4175, 78741, - 78743, 78751, 939, 0, 128799, 983120, 0, 0, 0, 78763, 78764, 78760, - 78761, 78758, 78759, 78755, 8425, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 6370, 0, - 7827, 68441, 75008, 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, - 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, - 41928, 0, 78406, 78409, 0, 0, 0, 9931, 0, 0, 0, 0, 0, 983778, 6107, 0, 0, - 0, 0, 128745, 0, 335, 127003, 64689, 0, 0, 5765, 0, 0, 119227, 6092, - 118851, 0, 8876, 83465, 74947, 83455, 129186, 83454, 70713, 0, 0, 126606, - 70121, 41602, 0, 92308, 74831, 0, 11783, 68482, 0, 0, 0, 0, 0, 0, 843, 0, - 71099, 0, 0, 41935, 0, 0, 0, 0, 1371, 0, 43818, 43159, 8069, 9579, 41938, - 41608, 0, 92444, 6242, 0, 0, 128595, 128244, 0, 92499, 8805, 1742, - 113722, 0, 8202, 72399, 0, 983198, 0, 0, 73882, 100809, 0, 43467, 123636, - 55290, 0, 1712, 5932, 0, 41762, 71982, 0, 11967, 1775, 0, 75009, 0, - 11868, 120387, 9458, 0, 126614, 0, 0, 43176, 101032, 101031, 42782, - 101033, 101036, 101035, 101038, 101037, 101040, 101039, 0, 0, 0, 0, - 101041, 5794, 92274, 2662, 101045, 101044, 8254, 101046, 10975, 101048, - 120625, 101050, 917977, 4108, 8478, 917982, 194790, 0, 92263, 917980, - 7507, 0, 43149, 0, 65031, 7961, 1636, 0, 65029, 0, 129665, 70188, 9674, - 0, 99, 98, 97, 101022, 92203, 4049, 101027, 43880, 7090, 101028, 0, - 101030, 66589, 0, 65310, 66593, 66599, 129805, 0, 0, 7447, 66594, 0, 0, - 0, 73920, 66595, 66596, 42570, 5593, 0, 0, 0, 0, 6061, 64854, 119, 118, - 117, 116, 0, 122, 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, - 102, 101, 100, 107, 106, 105, 104, 128504, 73974, 534, 0, 67713, 1536, - 73973, 73970, 0, 129671, 0, 6020, 12716, 0, 12744, 65143, 0, 13266, - 127813, 0, 0, 0, 127116, 0, 1212, 65560, 0, 8134, 42935, 12129, 73870, 0, - 1866, 0, 122948, 0, 0, 65073, 12059, 66585, 121391, 0, 0, 0, 5935, 1250, - 0, 8174, 9787, 6733, 9859, 9858, 9861, 9860, 101012, 1882, 1892, 6731, - 10882, 10795, 101018, 73911, 101020, 101019, 41169, 8939, 0, 120713, - 41170, 1454, 0, 65130, 69732, 0, 0, 129611, 41172, 7855, 0, 71472, 0, 0, - 0, 71691, 65901, 0, 0, 645, 100992, 100991, 100994, 100993, 100996, - 100995, 100998, 65587, 0, 10688, 0, 0, 7729, 0, 101001, 120518, 101003, - 66722, 101005, 101004, 68415, 101006, 4538, 101008, 43141, 0, 0, 73699, - 0, 0, 0, 71918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71454, 0, 2381, 983752, 0, 0, - 69857, 100981, 0, 100983, 100982, 100985, 10856, 100987, 55255, 41478, - 8582, 10064, 0, 0, 0, 0, 64896, 0, 74609, 0, 128048, 10082, 11575, 0, 0, - 0, 917505, 0, 6145, 75020, 0, 92433, 71916, 83279, 43186, 0, 0, 83274, - 83276, 83277, 83278, 10191, 83271, 69633, 72353, 0, 0, 0, 0, 120090, - 120089, 7931, 8558, 917946, 0, 0, 0, 119145, 120081, 120084, 120083, - 120086, 71449, 120088, 7366, 7019, 75021, 0, 917951, 120078, 120077, - 120080, 8657, 100967, 8594, 100969, 100968, 0, 100970, 120072, 120071, 0, - 0, 43154, 0, 0, 11332, 0, 7728, 100978, 100977, 100980, 100979, 7851, 0, - 8375, 128662, 0, 0, 126095, 9085, 0, 0, 9327, 6160, 0, 0, 0, 0, 70698, - 74012, 0, 0, 4439, 121151, 100972, 100971, 100974, 100973, 100976, - 100975, 100956, 42524, 71220, 100957, 10826, 100959, 11296, 0, 0, 0, - 7504, 43161, 127868, 0, 64670, 0, 78056, 0, 11295, 0, 78053, 0, 0, 0, - 10902, 0, 0, 122650, 78068, 10472, 100954, 100953, 120215, 78062, 2371, - 78069, 118893, 259, 0, 0, 2402, 12157, 6440, 0, 100963, 100962, 100965, - 100964, 65380, 9103, 2278, 0, 0, 7301, 0, 10219, 0, 0, 0, 67718, 43178, - 0, 120214, 119362, 917974, 8613, 0, 126121, 917978, 917979, 121449, - 12005, 7353, 0, 1890, 129130, 0, 0, 0, 42815, 7991, 0, 10578, 0, 0, 0, 0, - 0, 0, 0, 111190, 120601, 42668, 9348, 0, 6164, 0, 0, 0, 7676, 0, 0, 0, 0, - 128732, 129422, 83443, 71096, 83444, 9175, 0, 78047, 9088, 73689, 0, - 1396, 0, 0, 11461, 71088, 127835, 92252, 0, 71090, 121185, 69872, 0, 0, - 0, 0, 74043, 119632, 0, 0, 0, 5928, 4525, 10658, 0, 1266, 10180, 64472, - 0, 12622, 0, 0, 0, 0, 127139, 13310, 773, 19933, 0, 0, 0, 0, 92205, 0, 0, - 0, 0, 5862, 7823, 0, 0, 0, 3250, 43991, 69687, 66649, 0, 0, 0, 0, 0, - 64673, 917963, 917964, 0, 0, 917967, 917968, 917965, 917966, 127791, - 75041, 3471, 917970, 64573, 882, 0, 119584, 0, 120772, 0, 0, 0, 92696, 0, - 0, 72988, 0, 3225, 0, 73729, 0, 0, 43173, 11752, 4381, 0, 0, 917945, - 11756, 11757, 917944, 917949, 42654, 127848, 118663, 0, 0, 5160, 1387, 0, - 917953, 0, 128933, 917956, 917957, 917954, 917955, 118595, 121082, - 917958, 10789, 68314, 0, 126521, 11143, 0, 0, 70669, 128904, 42179, 0, - 5931, 11744, 11215, 70676, 119245, 0, 0, 0, 77915, 10217, 64635, 128661, - 83292, 0, 0, 0, 0, 0, 41296, 11747, 41291, 0, 0, 0, 41294, 41282, 5923, - 120610, 0, 0, 0, 0, 66800, 5786, 68252, 42539, 119869, 119860, 0, 41474, - 0, 0, 0, 5934, 74572, 66583, 119231, 0, 94072, 64481, 0, 0, 0, 0, 67240, - 0, 0, 123201, 0, 5819, 0, 0, 0, 0, 0, 129387, 0, 0, 0, 67993, 1237, - 194749, 0, 0, 983557, 0, 0, 0, 0, 0, 0, 0, 69789, 11266, 69845, 0, 10506, - 194747, 0, 0, 0, 0, 43185, 194748, 100533, 100532, 100535, 10769, 100537, - 100536, 100539, 9753, 121035, 100540, 0, 0, 121433, 0, 100542, 6072, - 100544, 100543, 100546, 100545, 100548, 100547, 100550, 100549, 0, - 113744, 0, 0, 7222, 10283, 10315, 10379, 4996, 0, 129294, 66517, 0, - 10087, 127833, 74938, 0, 0, 83492, 7565, 42890, 0, 73520, 43180, 77928, - 74891, 77929, 43982, 100526, 622, 77926, 100527, 100530, 1602, 0, 0, 0, - 129559, 12160, 0, 10212, 77936, 194605, 12071, 43143, 77935, 917983, - 917984, 917989, 77932, 917987, 917988, 10255, 10263, 10279, 4194, 10375, - 93035, 0, 0, 12644, 127516, 917994, 75007, 110791, 67408, 110789, 11501, - 41177, 0, 0, 71912, 0, 0, 8715, 0, 41179, 0, 0, 0, 41176, 0, 41181, 0, - 8452, 121006, 13161, 0, 70503, 5921, 0, 2597, 0, 5922, 72128, 0, 74242, - 128374, 0, 0, 0, 0, 0, 0, 0, 127906, 0, 64944, 0, 0, 0, 0, 5924, 5920, - 129508, 6921, 78081, 74007, 78078, 8418, 11681, 43169, 10176, 0, 0, 0, - 78087, 10772, 65276, 5937, 1914, 78084, 11682, 0, 0, 0, 11685, 0, 100513, - 7772, 11680, 100514, 100517, 100516, 100519, 7417, 718, 100520, 70083, - 100500, 120718, 3235, 0, 43164, 0, 8018, 0, 0, 128708, 6937, 67672, - 128508, 0, 10067, 120849, 0, 0, 0, 118693, 0, 100491, 0, 100493, 100492, - 13116, 100494, 100497, 9945, 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, - 100501, 1431, 100503, 66565, 100505, 100508, 12804, 100510, 100509, - 78090, 3307, 78088, 78089, 0, 4544, 71228, 0, 0, 0, 78097, 11110, 66810, - 12882, 64511, 78094, 78100, 78102, 71226, 10141, 0, 78280, 65298, 4476, - 78109, 94005, 71216, 8907, 78105, 78106, 78103, 78104, 120898, 0, 10665, - 64616, 128944, 0, 127545, 69605, 83159, 83160, 4554, 0, 83155, 83156, - 83157, 83158, 0, 125123, 0, 72258, 129831, 0, 129815, 0, 43179, 0, 0, 0, - 717, 10754, 83168, 83169, 83162, 83163, 83164, 83165, 78282, 0, 0, 83161, - 68848, 10611, 72859, 126978, 71474, 129426, 127871, 0, 0, 0, 12820, - 110882, 0, 7009, 70103, 0, 0, 67848, 41173, 4574, 0, 0, 128338, 575, - 78110, 43456, 8563, 100469, 0, 0, 65565, 123598, 5936, 7290, 78117, - 78118, 74919, 308, 78113, 78114, 83151, 78123, 83153, 83154, 0, 0, 0, 0, - 67496, 5926, 68250, 78130, 78126, 78127, 78124, 78125, 42513, 0, 129026, - 0, 11651, 13093, 78135, 0, 100471, 0, 100473, 100472, 100475, 74048, - 100477, 71995, 100457, 100456, 43703, 13097, 0, 100460, 13283, 0, 0, - 125073, 3488, 5933, 10033, 983947, 0, 65570, 0, 12297, 0, 0, 0, 128517, - 42538, 0, 129293, 0, 100451, 0, 100453, 100452, 100455, 100454, 121221, - 0, 0, 7638, 0, 129193, 0, 43109, 7637, 0, 11213, 100461, 83355, 100463, - 100466, 100465, 0, 0, 7636, 0, 0, 0, 128848, 983087, 291, 0, 0, 2027, - 78141, 78142, 78136, 78137, 83481, 4640, 64713, 10224, 120429, 11183, - 83482, 120430, 0, 0, 0, 127148, 83479, 0, 0, 83488, 0, 0, 0, 0, 68837, - 5778, 0, 0, 0, 12680, 119130, 0, 67242, 93041, 0, 0, 0, 11552, 0, 127855, - 0, 70091, 0, 10172, 65453, 120408, 66014, 120410, 0, 4641, 11556, 64819, - 78269, 120416, 72341, 41469, 41467, 120412, 120415, 4646, 120425, 865, - 78275, 78274, 78273, 4645, 78271, 78270, 0, 983173, 7338, 0, 68840, 0, - 12565, 0, 0, 0, 195089, 119655, 195091, 195090, 2913, 13120, 128956, - 69493, 195097, 195096, 128019, 0, 71462, 0, 7916, 10485, 195098, 0, - 195100, 195099, 0, 67705, 128351, 195077, 195080, 129636, 129549, 195081, - 0, 0, 0, 10229, 10687, 826, 128081, 195082, 195085, 195084, 195087, - 195086, 0, 1808, 7848, 0, 0, 0, 0, 0, 0, 128897, 69255, 42942, 67704, 0, - 0, 0, 0, 42940, 0, 9144, 0, 0, 92992, 9840, 0, 0, 0, 0, 0, 0, 74448, - 83475, 0, 10962, 66904, 113718, 983188, 0, 0, 74537, 195072, 1792, - 195074, 195073, 78266, 195075, 0, 0, 12066, 0, 385, 4152, 0, 0, 0, 67397, - 0, 0, 0, 0, 43258, 0, 0, 13157, 0, 0, 3570, 0, 0, 0, 67252, 0, 71218, - 126631, 7879, 68247, 128579, 78914, 0, 70196, 0, 0, 8463, 7810, 917862, - 7839, 983878, 127768, 917860, 9691, 0, 129323, 0, 120385, 0, 917844, 0, - 10066, 0, 2175, 0, 0, 0, 8016, 0, 983072, 64831, 0, 126103, 0, 73493, - 1634, 68115, 94192, 11056, 0, 0, 0, 41165, 11328, 12450, 0, 41166, 0, - 12456, 0, 171, 67508, 12452, 917544, 12458, 12531, 0, 917853, 0, 74162, - 0, 0, 9969, 0, 12454, 74160, 42132, 110755, 78878, 110753, 3230, 73711, - 0, 0, 8932, 4399, 5810, 64534, 8415, 0, 110756, 110757, 74159, 0, 0, 960, - 74156, 6981, 92374, 12938, 9201, 0, 118713, 74904, 0, 72866, 92270, 0, 0, - 0, 129792, 5851, 73833, 5824, 0, 5844, 110848, 110849, 110846, 110847, - 4663, 0, 0, 0, 0, 0, 74085, 0, 0, 0, 0, 0, 92339, 0, 0, 5782, 67495, 0, - 0, 43796, 129639, 0, 195083, 125223, 128004, 0, 43861, 0, 0, 0, 92976, 0, - 0, 0, 4659, 0, 128894, 0, 0, 129386, 0, 11129, 2238, 329, 0, 92707, - 121416, 0, 0, 0, 69943, 67692, 42167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 69618, 43671, 0, 64701, 0, 0, 0, 93055, 1172, 125089, 6786, 43601, 0, - 74126, 0, 0, 0, 0, 0, 118695, 0, 0, 118804, 0, 66741, 5347, 125026, - 983663, 0, 0, 10588, 0, 0, 0, 0, 5343, 0, 0, 0, 5341, 0, 0, 74916, 5351, - 0, 0, 917884, 0, 92692, 0, 121148, 128916, 0, 0, 66785, 126256, 6638, 0, - 0, 271, 0, 917904, 0, 0, 12653, 67588, 0, 0, 0, 0, 128838, 11912, 128301, - 983665, 0, 11800, 0, 0, 11103, 0, 7340, 0, 110695, 0, 0, 70170, 0, 2423, - 0, 0, 0, 128136, 42705, 0, 0, 0, 11854, 0, 0, 0, 0, 4916, 0, 380, 10958, - 66563, 127790, 78284, 67587, 0, 12918, 0, 917897, 0, 917898, 917893, - 10684, 0, 125063, 92906, 0, 0, 8182, 0, 0, 129434, 0, 0, 0, 6859, 0, - 6630, 100405, 0, 123191, 0, 0, 0, 65876, 5535, 129892, 0, 0, 92609, 0, - 983348, 6477, 43795, 92217, 129571, 72163, 69496, 43848, 0, 0, 74256, - 2665, 11304, 43751, 0, 4970, 74353, 0, 8934, 0, 93996, 4492, 92908, - 65011, 0, 0, 92909, 1188, 7254, 1100, 0, 0, 0, 2912, 11749, 92643, 0, 0, - 65057, 0, 12343, 0, 78879, 0, 78880, 0, 0, 0, 70355, 0, 0, 11803, 0, 0, - 41450, 0, 100897, 0, 41451, 0, 0, 8273, 0, 3451, 0, 972, 41453, 68164, - 78876, 0, 92408, 73945, 43504, 2288, 78873, 9538, 78874, 128685, 0, - 129095, 0, 0, 0, 0, 11019, 0, 0, 121205, 0, 73007, 71365, 92716, 5927, 0, - 0, 0, 0, 128484, 0, 6073, 0, 0, 0, 6075, 93995, 282, 126510, 0, 74078, - 121459, 2206, 0, 0, 66791, 0, 3474, 0, 0, 0, 6081, 0, 127843, 74076, 0, - 0, 0, 128908, 0, 0, 0, 12623, 120273, 9120, 120275, 4665, 12628, 4670, - 120271, 120272, 0, 0, 121480, 958, 0, 0, 0, 4666, 0, 4915, 0, 4669, 0, 0, - 0, 4664, 0, 120550, 0, 0, 0, 0, 94023, 0, 917875, 8664, 11664, 0, 129327, - 11224, 0, 0, 1063, 119088, 120251, 9772, 7255, 8886, 0, 127932, 120257, - 120258, 120259, 120260, 42661, 71345, 120255, 119125, 120265, 120266, - 120267, 42721, 92407, 120262, 120263, 66788, 1017, 0, 118580, 505, 1447, - 0, 0, 70340, 66793, 65115, 42789, 128443, 0, 0, 123634, 0, 119195, 0, 0, - 11745, 7919, 0, 1641, 0, 0, 8966, 0, 0, 8743, 71870, 0, 67813, 0, 0, 0, - 123206, 0, 0, 128505, 10169, 71324, 0, 10068, 0, 120457, 120456, 120455, - 120454, 257, 43170, 13153, 0, 0, 0, 0, 0, 0, 6496, 19917, 5930, 128354, - 11033, 0, 0, 5622, 120436, 8477, 8474, 120433, 120432, 0, 0, 0, 41435, - 4352, 0, 2435, 0, 5621, 0, 4201, 8450, 4203, 4202, 4205, 4204, 120447, - 120446, 120445, 66792, 41440, 120442, 8473, 6373, 8469, 120438, 0, 4564, - 125206, 0, 0, 0, 8374, 73669, 0, 0, 66796, 0, 0, 0, 0, 0, 69297, 129762, - 5626, 43507, 11771, 0, 0, 0, 42614, 0, 5625, 0, 0, 0, 5623, 0, 0, 42623, - 64277, 69942, 0, 0, 120752, 0, 5817, 5629, 0, 7551, 10325, 5632, 69674, - 0, 0, 124946, 125194, 5628, 129766, 5631, 0, 0, 2400, 5627, 0, 0, 118786, - 74792, 0, 0, 0, 203, 129084, 74365, 0, 0, 0, 0, 83382, 83422, 0, 0, 554, - 0, 0, 0, 12182, 0, 64569, 110840, 73891, 0, 0, 0, 7689, 69798, 9323, - 10269, 10285, 10317, 175, 0, 0, 0, 0, 0, 1243, 42154, 0, 92387, 0, 0, - 43651, 0, 125021, 0, 9075, 118597, 0, 64777, 128570, 0, 0, 0, 0, 65255, - 0, 121142, 4490, 0, 6649, 120698, 12181, 0, 11977, 7249, 8366, 0, 7756, - 12342, 0, 51, 41516, 69432, 0, 9568, 71318, 456, 0, 10437, 1168, 9251, - 9082, 0, 0, 42781, 3866, 0, 41512, 0, 0, 68121, 41494, 0, 4660, 0, 10405, - 0, 0, 0, 0, 0, 73918, 119627, 110686, 41454, 12605, 0, 126611, 41455, - 917996, 983605, 0, 8214, 0, 100413, 129320, 41457, 983077, 0, 1969, - 127771, 0, 69554, 7413, 0, 69426, 10341, 43864, 78079, 5854, 0, 0, 0, - 129684, 72819, 0, 0, 73548, 0, 0, 8429, 0, 72328, 0, 6429, 0, 0, 0, 0, - 110688, 83417, 0, 917864, 120813, 83423, 1662, 125000, 0, 0, 917871, - 917868, 0, 0, 66, 65, 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, - 79, 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, 0, 0, 7385, 70508, 1704, - 12993, 0, 0, 0, 0, 0, 0, 0, 0, 11353, 72207, 0, 0, 0, 0, 118831, 0, 0, 0, - 0, 0, 118719, 83364, 0, 0, 1289, 0, 0, 119583, 0, 65507, 0, 0, 0, 128042, - 0, 74409, 0, 0, 0, 0, 64793, 0, 0, 100843, 5675, 119239, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6972, 70735, 0, 121108, 126217, 0, 0, 0, 0, 0, 110640, - 67687, 0, 0, 119634, 0, 43977, 111252, 129105, 0, 7412, 64671, 0, 1412, - 4594, 1391, 0, 8067, 12478, 110639, 78375, 110637, 10281, 110635, 0, 0, - 7960, 43271, 0, 12518, 69846, 0, 3566, 0, 0, 69864, 0, 0, 68021, 0, 0, 0, - 8223, 0, 4261, 121460, 68918, 0, 0, 121294, 113712, 0, 128046, 43419, - 72748, 92866, 10574, 0, 67691, 0, 0, 73785, 0, 78875, 128541, 0, 127366, - 0, 0, 0, 0, 6695, 65113, 324, 0, 128373, 40985, 0, 0, 0, 0, 0, 72307, - 43474, 0, 121190, 0, 0, 3420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110871, 9574, - 120684, 110870, 110814, 5204, 74774, 0, 11835, 0, 0, 983186, 0, 0, 0, 0, - 0, 0, 11750, 68898, 127004, 0, 0, 0, 0, 8130, 0, 0, 0, 121268, 0, 129443, - 0, 68455, 42863, 73839, 0, 0, 0, 92288, 0, 0, 0, 612, 110875, 110876, - 72231, 10538, 0, 1674, 0, 0, 0, 12280, 0, 540, 74550, 0, 66422, 8432, 0, - 11073, 0, 64316, 129894, 0, 7388, 0, 0, 0, 0, 126107, 0, 3359, 0, 0, - 67284, 0, 0, 65482, 129589, 0, 64742, 129304, 0, 124141, 74273, 0, 19941, - 0, 0, 0, 0, 9481, 65555, 0, 66628, 129126, 1195, 64898, 0, 0, 0, 2010, 0, - 0, 0, 0, 0, 0, 4360, 127009, 9739, 0, 72885, 0, 0, 0, 126265, 72200, 0, - 0, 120025, 72199, 0, 0, 65734, 0, 0, 129690, 13075, 0, 94063, 0, 43532, - 10837, 2492, 74516, 983075, 120882, 0, 0, 11813, 9649, 0, 119617, 5128, - 7377, 0, 65604, 0, 0, 6771, 1648, 7819, 0, 0, 0, 125192, 128131, 12709, - 6986, 0, 0, 0, 0, 0, 12581, 0, 5175, 0, 73806, 0, 128420, 0, 0, 77950, 0, - 0, 607, 0, 0, 128846, 119605, 67475, 129528, 65477, 0, 121130, 0, 8265, - 0, 0, 0, 5840, 42838, 0, 0, 68366, 0, 119255, 0, 0, 0, 127929, 0, 2550, - 121011, 6779, 70059, 0, 0, 0, 0, 0, 0, 5619, 65822, 0, 0, 0, 129392, - 5616, 11486, 0, 0, 0, 0, 5615, 0, 121319, 42380, 127958, 0, 66451, 74407, - 0, 11347, 0, 1026, 5620, 0, 0, 11350, 5617, 0, 0, 64639, 0, 0, 0, 1338, - 0, 0, 0, 4603, 0, 70715, 92484, 0, 9002, 0, 3974, 78213, 0, 0, 0, 0, 0, - 0, 75038, 66040, 70455, 0, 0, 0, 72982, 0, 0, 0, 0, 0, 118661, 0, 0, - 119105, 0, 0, 0, 0, 0, 128883, 0, 66897, 0, 0, 0, 42594, 0, 0, 0, 0, - 6714, 10083, 0, 121019, 0, 69976, 0, 0, 9073, 0, 64302, 0, 128286, 9725, - 0, 0, 121288, 73769, 121306, 0, 9570, 0, 11500, 2689, 917626, 0, 983813, - 66740, 0, 0, 0, 917623, 13286, 5500, 42598, 42596, 503, 0, 0, 917618, 0, - 0, 0, 0, 917615, 1652, 772, 6688, 8310, 0, 0, 72124, 0, 10194, 43542, 0, - 125054, 0, 6468, 68110, 0, 917606, 11767, 0, 0, 5836, 12358, 0, 0, 65624, - 12180, 0, 127994, 0, 43699, 0, 0, 72114, 43706, 0, 12362, 12435, 12360, - 0, 9020, 0, 12356, 8616, 0, 42924, 2227, 0, 0, 7315, 12354, 83097, 83098, - 83099, 2358, 83092, 83093, 83094, 0, 0, 83089, 83090, 0, 11759, 71723, 0, - 72834, 83109, 41423, 0, 83103, 83104, 83105, 42237, 110653, 70717, 72260, - 83102, 0, 67856, 0, 128534, 110657, 129354, 129194, 0, 64395, 0, 73008, - 120897, 74816, 0, 0, 0, 83088, 0, 0, 94064, 83083, 83085, 83086, 83087, - 83079, 83080, 2041, 9178, 0, 64870, 0, 83076, 74924, 0, 0, 0, 0, 0, - 78739, 0, 0, 0, 0, 0, 0, 3726, 0, 0, 0, 0, 0, 121432, 129457, 0, 0, 0, 0, - 0, 74901, 0, 0, 0, 0, 0, 124944, 113781, 0, 7410, 2669, 903, 0, 0, 0, - 127232, 74603, 0, 128264, 0, 128411, 0, 0, 11732, 0, 72797, 41448, 41461, - 124934, 0, 917558, 0, 8819, 0, 0, 74606, 92847, 121412, 74835, 0, 9168, - 65786, 0, 73691, 0, 67665, 0, 11758, 68425, 0, 0, 0, 128044, 0, 19924, - 67312, 0, 128755, 64551, 0, 8516, 0, 0, 7561, 983999, 74018, 0, 0, 0, 0, - 83074, 83075, 0, 11233, 83062, 83066, 3787, 83070, 83055, 41458, 83059, - 41463, 65308, 41459, 8683, 775, 0, 65584, 69923, 0, 110798, 110799, - 110796, 43440, 0, 0, 0, 3656, 0, 0, 0, 67694, 1599, 83138, 83139, 8514, - 8513, 83036, 83135, 83136, 110794, 110795, 83131, 83132, 0, 0, 0, 11684, - 10542, 9937, 83150, 0, 75037, 83145, 65730, 83147, 0, 8427, 83142, 55246, - 0, 0, 11497, 0, 0, 0, 119222, 0, 983598, 0, 10621, 0, 0, 129295, 119111, - 120745, 0, 0, 0, 11648, 83126, 83127, 42118, 83129, 83122, 65512, 83124, - 83125, 0, 0, 0, 83121, 74530, 128456, 0, 0, 0, 65724, 0, 0, 0, 65727, 0, - 0, 64963, 73830, 66042, 0, 0, 7875, 0, 0, 0, 129476, 0, 0, 536, 0, 0, 0, - 0, 65173, 129122, 0, 70331, 0, 0, 118598, 0, 129419, 0, 0, 0, 1687, 0, 0, - 0, 0, 0, 0, 10526, 0, 8323, 0, 83301, 11731, 73530, 0, 65460, 12242, 0, - 0, 10843, 11554, 0, 0, 8266, 0, 121101, 0, 0, 0, 0, 67667, 118694, - 119155, 0, 0, 119636, 67857, 0, 0, 0, 11755, 66305, 0, 0, 10917, 93979, - 113688, 0, 2040, 92596, 0, 0, 0, 0, 1227, 83119, 83120, 0, 0, 83115, - 74427, 11149, 4978, 83111, 1984, 11830, 83114, 128934, 74548, 118545, - 9373, 0, 0, 0, 0, 0, 0, 0, 0, 9237, 9390, 0, 0, 0, 0, 0, 1830, 0, 0, 0, - 0, 0, 128577, 983839, 68086, 0, 0, 0, 983059, 0, 983145, 0, 0, 0, 72197, - 55291, 11683, 0, 983659, 0, 11451, 0, 72714, 3731, 2359, 0, 67844, 0, - 121503, 548, 121502, 983250, 121405, 983253, 0, 66272, 0, 64678, 0, 9547, - 0, 0, 1614, 0, 0, 66307, 128092, 1358, 120871, 428, 0, 1466, 0, 10982, 0, - 0, 0, 407, 0, 0, 0, 0, 0, 0, 5804, 73464, 0, 0, 0, 70167, 9057, 42446, 0, - 125097, 0, 0, 8250, 10952, 8048, 0, 129155, 0, 118955, 0, 0, 118593, - 4407, 74648, 0, 0, 0, 8448, 92491, 0, 0, 12675, 12659, 0, 0, 983285, - 68077, 55273, 10766, 12012, 2386, 0, 9170, 0, 9123, 128194, 0, 0, 0, 0, - 129942, 0, 0, 0, 0, 0, 0, 8709, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 128342, 0, - 577, 128610, 0, 0, 124999, 68087, 74840, 126474, 127036, 0, 0, 0, 1414, - 124963, 9683, 43486, 92231, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, - 66317, 0, 66315, 66316, 0, 0, 0, 0, 0, 0, 0, 0, 66323, 66324, 0, 0, 3106, - 65917, 0, 2182, 0, 891, 0, 0, 42624, 0, 0, 8824, 65089, 128734, 10936, 0, - 0, 0, 0, 92688, 0, 0, 0, 0, 12745, 0, 0, 41285, 3547, 0, 0, 129877, 0, - 118701, 6089, 0, 68490, 120578, 4170, 1029, 127761, 0, 0, 42374, 917625, - 744, 917624, 0, 0, 0, 93046, 0, 3551, 0, 0, 4623, 0, 0, 12340, 0, 65136, - 0, 0, 0, 0, 0, 0, 0, 72291, 0, 0, 120778, 0, 11972, 0, 78757, 0, 122886, - 177, 122894, 0, 0, 0, 0, 55243, 0, 0, 0, 70172, 120249, 120242, 128027, - 120243, 0, 0, 0, 120237, 120245, 94079, 0, 0, 9136, 120240, 120614, - 41280, 0, 0, 0, 0, 74149, 128327, 0, 0, 66361, 12601, 72194, 64360, - 65163, 125241, 0, 0, 0, 0, 0, 5404, 43332, 3667, 7936, 12925, 0, 0, 0, 0, - 0, 10874, 65505, 0, 0, 0, 0, 128920, 983681, 0, 0, 0, 0, 0, 0, 0, 0, - 66677, 0, 0, 0, 70088, 74148, 0, 0, 72868, 120230, 120224, 74172, 0, 0, - 94096, 0, 128414, 120636, 0, 127519, 917609, 917616, 0, 128652, 0, 0, - 11441, 0, 3512, 0, 0, 43597, 0, 0, 72734, 68153, 41563, 0, 0, 129352, - 41544, 0, 0, 74927, 0, 129177, 0, 0, 0, 118908, 0, 78108, 67396, 73804, - 64711, 0, 0, 917610, 0, 0, 0, 11557, 127776, 0, 12079, 0, 0, 0, 0, - 128861, 0, 0, 0, 0, 0, 983201, 8103, 72303, 128174, 92486, 110698, 0, - 64587, 0, 0, 124961, 0, 0, 0, 126481, 0, 0, 0, 0, 0, 70348, 1450, 0, - 1340, 0, 0, 128970, 0, 0, 125117, 0, 0, 0, 0, 6539, 92948, 0, 128213, - 125060, 0, 0, 0, 3973, 0, 70504, 121193, 7982, 0, 0, 127194, 0, 0, 0, - 128408, 118968, 6417, 120619, 129748, 0, 0, 0, 129455, 4919, 65121, - 110872, 7755, 0, 0, 64548, 0, 1621, 0, 0, 0, 0, 0, 12188, 0, 0, 0, 0, - 5015, 0, 0, 42590, 70354, 1756, 0, 0, 0, 120694, 0, 0, 7555, 73874, 5408, - 2817, 1214, 69919, 0, 983126, 0, 0, 125055, 127195, 7957, 0, 0, 1056, - 74944, 0, 0, 0, 0, 7073, 74979, 0, 70853, 0, 110874, 0, 0, 2341, 126644, - 8484, 0, 0, 68322, 0, 8461, 67721, 42269, 0, 0, 43709, 43708, 9451, 7571, - 13073, 43847, 126647, 0, 983263, 0, 0, 0, 8781, 12894, 78134, 0, 78132, - 0, 0, 78184, 0, 11338, 120768, 0, 0, 0, 0, 0, 121367, 65021, 64795, - 74574, 0, 10047, 0, 0, 0, 0, 0, 0, 119181, 163, 576, 9895, 0, 0, 74591, - 0, 0, 66888, 0, 0, 0, 0, 0, 0, 7017, 128111, 0, 0, 129922, 0, 41591, - 11036, 65252, 120795, 129488, 0, 0, 0, 0, 0, 0, 8887, 0, 7295, 71203, 0, - 127221, 0, 0, 0, 0, 8755, 0, 0, 8147, 73127, 0, 0, 121348, 0, 129377, 0, - 74499, 0, 0, 0, 4619, 0, 6654, 123192, 0, 0, 0, 65689, 10128, 0, 129612, - 0, 0, 92651, 0, 2401, 0, 8792, 118546, 0, 74980, 0, 92246, 0, 0, 0, - 12886, 0, 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, 3010, - 0, 70349, 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, 78116, - 64780, 2001, 0, 55230, 0, 4052, 92856, 7626, 78080, 0, 0, 0, 41477, 0, 0, - 0, 43707, 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, 129872, - 119602, 0, 0, 70325, 0, 41443, 0, 0, 0, 9711, 1523, 0, 0, 41445, 0, 0, - 8567, 41442, 12821, 0, 0, 118978, 0, 65274, 0, 94082, 0, 127515, 0, 0, - 43446, 0, 0, 0, 0, 127985, 0, 10206, 127167, 6375, 2673, 0, 0, 0, 43219, - 129355, 0, 0, 0, 0, 129400, 11799, 101225, 68466, 0, 0, 0, 0, 0, 120736, - 0, 7203, 0, 0, 70361, 127213, 120615, 127216, 0, 0, 0, 0, 43121, 0, - 128366, 72161, 0, 129868, 0, 121260, 73781, 70365, 0, 68039, 70446, - 10057, 0, 0, 0, 101219, 120963, 101220, 2307, 0, 0, 0, 0, 73873, 0, - 94035, 0, 0, 67469, 0, 129983, 7327, 0, 0, 440, 0, 0, 68613, 75059, 0, 0, - 9957, 0, 0, 8046, 0, 119158, 0, 0, 68609, 0, 129405, 1521, 129460, 92256, - 65344, 0, 11850, 68737, 0, 0, 68914, 7303, 65770, 5243, 0, 5239, 65771, - 121429, 0, 5237, 0, 68756, 0, 5247, 0, 0, 0, 12873, 5764, 0, 0, 3008, - 118981, 128102, 0, 0, 55231, 41103, 0, 92756, 0, 0, 92717, 70074, 7872, - 74886, 917567, 8731, 65378, 118564, 0, 11316, 128163, 126600, 70360, - 3019, 9997, 0, 0, 9456, 129545, 0, 0, 101192, 0, 0, 92682, 4281, 0, 0, 0, - 118982, 0, 69993, 78096, 0, 78095, 0, 78098, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2134, 0, 10116, 9877, 70679, 0, 0, 92723, 8379, 0, 6778, 0, 0, 8243, 0, - 0, 0, 0, 128008, 0, 0, 0, 983630, 119668, 129962, 92722, 983098, 5637, - 125115, 0, 0, 120479, 0, 113730, 0, 0, 194990, 64432, 0, 70363, 121368, - 1156, 68052, 0, 0, 120482, 0, 68030, 0, 0, 0, 7634, 0, 0, 65536, 0, 0, 0, - 7702, 0, 78890, 0, 65779, 65783, 195066, 120961, 5700, 0, 0, 92161, 2339, - 92476, 5697, 0, 0, 0, 74923, 0, 5696, 92677, 0, 3862, 0, 0, 0, 983055, 0, - 0, 0, 0, 5701, 9722, 41490, 41370, 5698, 0, 0, 0, 42204, 55270, 8571, 0, - 0, 43859, 0, 78731, 0, 12184, 0, 0, 0, 0, 0, 5650, 0, 64712, 120474, 0, - 120458, 5647, 120473, 7387, 0, 92675, 11477, 5646, 0, 11018, 0, 0, 0, 0, - 0, 0, 69280, 128459, 126128, 5651, 0, 0, 0, 5648, 0, 120920, 0, 127517, - 3545, 0, 6984, 0, 0, 0, 69414, 126613, 0, 10123, 0, 69274, 0, 0, 65020, - 74885, 119166, 0, 0, 0, 0, 0, 1140, 78426, 0, 0, 0, 122665, 8128, 9889, - 0, 0, 1815, 0, 890, 0, 3267, 0, 0, 0, 983686, 4410, 125081, 10576, 8102, - 0, 580, 74232, 0, 0, 0, 0, 0, 19938, 0, 0, 0, 0, 3298, 6546, 0, 0, 0, 0, - 6134, 41246, 0, 0, 0, 917770, 0, 6264, 0, 0, 0, 0, 0, 0, 69445, 0, 0, 0, - 92697, 11915, 10377, 0, 10072, 0, 0, 2329, 0, 0, 0, 0, 0, 0, 0, 67498, 0, - 101164, 0, 11201, 92708, 74769, 0, 13263, 0, 0, 92404, 126066, 69491, 0, - 0, 64917, 0, 0, 494, 128026, 0, 65098, 0, 956, 125265, 129556, 0, 73740, - 0, 0, 0, 74281, 128638, 0, 0, 69217, 120930, 0, 0, 0, 0, 0, 9922, 0, - 126269, 100948, 0, 65229, 0, 118671, 0, 0, 0, 0, 3907, 118833, 64526, - 11829, 68197, 0, 0, 11475, 70329, 3020, 42264, 0, 0, 0, 7098, 0, 0, - 127967, 957, 42696, 0, 3016, 0, 0, 0, 0, 0, 121248, 92510, 3006, 4620, 0, - 0, 0, 0, 129369, 129425, 0, 0, 0, 126246, 8626, 0, 128824, 0, 65377, 0, - 983103, 42920, 1698, 0, 64477, 0, 0, 43813, 100432, 100431, 100434, - 100433, 100436, 70321, 100438, 100437, 100440, 100439, 0, 121024, 101177, - 70327, 100441, 55252, 100443, 100442, 100445, 100444, 66641, 100446, - 100449, 100448, 0, 100450, 113820, 74866, 64375, 0, 127850, 129477, 0, 0, - 0, 0, 983799, 0, 0, 120827, 0, 0, 123637, 0, 0, 0, 101183, 8110, 100421, - 0, 100423, 5830, 100425, 100424, 100427, 73540, 100429, 100428, 42389, - 78611, 121398, 0, 0, 0, 0, 0, 0, 0, 83342, 983954, 0, 127147, 119187, - 2135, 11836, 0, 0, 78869, 42313, 5579, 0, 70384, 983082, 94002, 0, 5578, - 11840, 73006, 42023, 69849, 5669, 92559, 0, 0, 68833, 917845, 128275, - 5583, 0, 0, 42426, 5580, 42276, 0, 892, 2220, 42465, 74313, 73440, 5795, - 194991, 68774, 65702, 68770, 0, 65695, 0, 65710, 128399, 0, 0, 68783, 0, - 0, 0, 1638, 10966, 0, 917547, 0, 118921, 0, 0, 0, 8172, 120760, 0, 0, 0, - 0, 0, 6374, 0, 0, 120972, 0, 0, 0, 0, 0, 0, 0, 72204, 64900, 7153, 65785, - 68826, 0, 3015, 68743, 68740, 68738, 68805, 6400, 68749, 68748, 68760, - 68758, 11276, 68754, 100420, 372, 101138, 68761, 118874, 0, 41585, - 128202, 0, 74228, 276, 129895, 74234, 0, 74226, 0, 9007, 0, 41588, - 125001, 119189, 10763, 0, 0, 983560, 126097, 68525, 6257, 73112, 100393, - 100396, 100395, 100398, 92409, 100400, 100399, 101148, 74848, 120006, - 983592, 100401, 66498, 100403, 100402, 64790, 73454, 100407, 100406, - 70356, 100408, 0, 100410, 66829, 70817, 5711, 41633, 12098, 65571, 9166, - 0, 5710, 0, 6790, 65213, 0, 0, 0, 69726, 0, 73817, 0, 0, 5715, 0, 70408, - 0, 5712, 100382, 41620, 100384, 3074, 5722, 100389, 100388, 73768, 0, - 118906, 0, 0, 0, 66419, 71972, 0, 0, 0, 0, 64839, 78607, 0, 129074, 0, 0, - 0, 0, 0, 0, 113682, 0, 11261, 0, 0, 0, 8701, 0, 11236, 0, 129490, 100390, - 0, 0, 0, 78293, 0, 0, 0, 64946, 0, 0, 0, 70336, 0, 0, 93986, 68814, - 42902, 0, 0, 0, 0, 92344, 0, 67845, 42641, 71444, 0, 0, 70366, 101152, - 100369, 100368, 5084, 100370, 101158, 118861, 0, 733, 74646, 0, 0, 0, - 125085, 0, 9218, 0, 100380, 100379, 71070, 0, 0, 0, 0, 70323, 0, 0, 5155, - 0, 0, 983775, 0, 0, 72351, 0, 0, 0, 122891, 0, 0, 0, 100372, 100371, - 100374, 100373, 100376, 100375, 100378, 100377, 4974, 100357, 100360, - 100359, 0, 0, 0, 12205, 0, 0, 64507, 0, 0, 0, 0, 0, 0, 12149, 13088, - 78290, 0, 12241, 0, 0, 0, 6932, 100352, 73676, 100354, 100353, 100356, - 351, 68764, 0, 0, 0, 0, 73443, 0, 0, 100361, 42377, 100363, 100362, - 100365, 100364, 100367, 9013, 4054, 0, 0, 71939, 0, 120782, 5585, 65881, - 0, 0, 118541, 0, 5584, 8358, 128975, 121177, 0, 0, 0, 41616, 0, 983815, - 2218, 0, 5589, 0, 2664, 41613, 5586, 118890, 0, 11356, 0, 0, 0, 78609, 0, - 0, 0, 0, 0, 129870, 0, 0, 8135, 129685, 0, 983810, 0, 0, 0, 5657, 0, - 12915, 121453, 0, 10179, 5654, 12939, 0, 120799, 0, 0, 5652, 10945, - 118626, 0, 0, 113710, 0, 73449, 68069, 0, 70332, 0, 5659, 0, 0, 66729, - 5655, 0, 0, 0, 68806, 0, 128225, 66310, 73444, 0, 0, 70362, 0, 11609, 0, - 126990, 92949, 10272, 10304, 10368, 74511, 594, 10244, 10248, 10256, - 983918, 122974, 0, 3467, 41010, 0, 3331, 946, 0, 1495, 13184, 74330, - 128242, 9562, 0, 123175, 0, 70036, 122976, 0, 0, 123176, 0, 0, 0, 5666, - 65227, 123174, 68419, 0, 11796, 123178, 0, 0, 10186, 123172, 7732, - 983755, 0, 0, 0, 5668, 83334, 0, 74645, 5670, 0, 0, 12741, 126619, - 123638, 5667, 19952, 120807, 113766, 12749, 0, 67757, 2263, 0, 0, 119260, - 129131, 9286, 83335, 128457, 83336, 70359, 0, 3571, 13247, 5874, 78279, - 73447, 68435, 78278, 78267, 78268, 0, 78265, 553, 113768, 0, 93053, 5829, - 0, 4587, 78285, 78299, 129699, 12746, 0, 70338, 0, 5633, 0, 94101, 94102, - 94099, 94100, 94105, 74856, 94103, 12742, 0, 983837, 0, 0, 0, 70330, 0, - 983830, 0, 0, 0, 12148, 0, 0, 0, 0, 0, 64938, 67234, 5634, 0, 0, 2146, 0, - 118880, 2425, 65182, 983832, 43636, 0, 83326, 328, 0, 68736, 0, 5636, - 123163, 5329, 0, 5638, 0, 7940, 0, 43223, 43760, 5635, 3373, 72424, - 78292, 74223, 73441, 68763, 78287, 9833, 0, 74208, 41635, 0, 77775, - 43040, 78297, 68778, 78295, 5639, 65603, 5660, 5640, 78303, 0, 78300, 0, - 68301, 0, 0, 78312, 0, 78310, 41625, 78308, 78309, 100731, 41780, 5642, - 100732, 100735, 100734, 4356, 100736, 100739, 12051, 70166, 100740, 5641, - 8259, 0, 0, 0, 119570, 0, 0, 121264, 983558, 0, 0, 0, 73890, 0, 0, 2800, - 11220, 5645, 64964, 8652, 83323, 0, 0, 121356, 5608, 128281, 119932, - 118562, 0, 0, 9000, 0, 83324, 92673, 129176, 0, 5613, 74267, 100721, - 100724, 5610, 100726, 92965, 100728, 5612, 100730, 10787, 0, 3615, - 123647, 5609, 78316, 78317, 78313, 78315, 5875, 5808, 0, 8186, 0, 74269, - 122977, 70004, 65874, 72422, 5807, 0, 66320, 5306, 12936, 0, 92970, - 127961, 0, 92583, 10211, 0, 0, 78871, 121063, 0, 129512, 0, 0, 0, 0, 0, - 74237, 0, 9133, 74262, 0, 92840, 0, 64779, 4672, 73529, 6185, 64776, 0, - 121266, 6499, 0, 0, 0, 92720, 0, 67494, 93791, 2534, 0, 93768, 93778, - 93762, 71849, 71869, 93781, 64583, 93761, 93780, 78922, 93787, 92443, - 128714, 71848, 93774, 66411, 93785, 71841, 93770, 93769, 0, 0, 0, 121168, - 68443, 69774, 931, 0, 125052, 6363, 2748, 0, 0, 0, 983603, 44011, 0, 0, - 100711, 119009, 100713, 100712, 100715, 65896, 100717, 78298, 100719, - 100718, 128836, 100720, 11649, 0, 0, 0, 0, 0, 42341, 65284, 0, 0, 12884, - 0, 7907, 127255, 0, 0, 0, 0, 68779, 0, 68786, 0, 100691, 0, 100693, - 100692, 42851, 100694, 100697, 100696, 92276, 78226, 66393, 100700, 0, - 93773, 93776, 93777, 100702, 78301, 100704, 100703, 42415, 78307, 4542, - 69909, 94022, 100709, 0, 0, 0, 0, 42454, 11565, 7949, 124939, 0, 0, - 42494, 3073, 0, 0, 42302, 0, 126553, 70810, 0, 72401, 0, 0, 0, 129319, - 4877, 100681, 100684, 100683, 10548, 100685, 100688, 100687, 100690, - 64798, 70805, 5346, 0, 126570, 124135, 4874, 124136, 0, 0, 0, 0, 65884, - 0, 0, 0, 11378, 0, 42785, 0, 3251, 11203, 0, 0, 0, 69568, 11052, 0, 5342, - 8317, 0, 0, 5340, 0, 122970, 128599, 0, 129538, 0, 128395, 0, 128510, 0, - 0, 9142, 0, 0, 0, 10938, 0, 0, 1182, 127381, 4829, 0, 0, 72438, 529, 0, - 0, 0, 10586, 10790, 10839, 121427, 41593, 100669, 0, 118532, 41594, 225, - 66418, 0, 0, 983969, 11376, 0, 41596, 0, 64975, 0, 0, 11084, 3194, 0, - 78306, 78305, 0, 0, 0, 11324, 0, 0, 8420, 127756, 128844, 0, 41338, - 129683, 11485, 0, 41322, 66605, 100671, 0, 100673, 100672, 100675, 5161, - 41330, 100676, 100679, 100678, 100659, 100658, 0, 100660, 0, 100485, - 12361, 0, 12359, 983559, 41369, 66412, 12191, 0, 0, 0, 0, 78221, 41376, - 0, 9870, 0, 41385, 65824, 100651, 11938, 100653, 100652, 100655, 100654, - 42678, 100656, 0, 64649, 0, 0, 0, 0, 0, 983967, 100662, 100661, 100664, - 66334, 100666, 70280, 832, 100667, 2240, 78473, 66007, 78471, 65703, 0, - 0, 0, 12357, 0, 41395, 0, 0, 0, 0, 0, 0, 983466, 0, 41114, 65466, 0, - 983844, 6024, 0, 9979, 0, 0, 0, 0, 0, 0, 0, 4285, 0, 0, 4230, 0, 7367, 0, - 92353, 7563, 42376, 0, 128532, 0, 0, 0, 0, 67500, 0, 78466, 0, 12208, - 128138, 0, 66311, 71309, 0, 41130, 78286, 0, 0, 70047, 0, 6022, 0, 0, 0, - 0, 0, 41125, 0, 66453, 0, 41107, 0, 41121, 5300, 129588, 0, 0, 128759, - 74801, 70855, 2074, 73456, 0, 0, 12453, 0, 0, 0, 0, 68159, 12457, 0, 0, - 66278, 0, 0, 0, 0, 0, 66637, 12455, 0, 128473, 0, 12449, 0, 71224, 0, 0, - 66908, 0, 10165, 0, 119249, 113715, 0, 128223, 0, 0, 0, 0, 4993, 0, 6168, - 74033, 4995, 0, 69459, 77756, 4639, 0, 72223, 0, 73478, 0, 0, 0, 73486, - 66991, 0, 0, 0, 0, 0, 0, 83310, 0, 0, 0, 0, 0, 0, 0, 0, 129594, 4953, 0, - 0, 0, 0, 83311, 0, 73453, 65688, 0, 10125, 3517, 0, 0, 0, 65094, 74791, - 78262, 10627, 66333, 78256, 78257, 83304, 78253, 0, 71317, 64923, 0, - 65208, 10608, 78263, 78264, 0, 0, 0, 65883, 0, 0, 74914, 0, 0, 6853, 0, - 0, 12912, 119012, 0, 128191, 0, 0, 129586, 0, 1290, 0, 0, 0, 0, 113719, - 71442, 0, 0, 8978, 0, 119135, 120979, 10527, 71079, 0, 0, 0, 0, 0, 0, - 5336, 0, 0, 6934, 0, 10780, 0, 0, 78767, 0, 0, 0, 347, 0, 0, 78775, - 64675, 41582, 78774, 78771, 68094, 74903, 78769, 69221, 69657, 0, 0, - 11153, 120981, 78526, 0, 0, 0, 0, 41584, 0, 69464, 0, 0, 0, 0, 43510, - 66661, 0, 66306, 78791, 66384, 0, 6609, 0, 0, 11319, 0, 66984, 0, 41730, - 0, 0, 127920, 0, 65172, 41728, 41721, 0, 0, 0, 41203, 0, 0, 41726, 0, 0, - 5758, 0, 0, 41140, 2028, 78092, 0, 0, 0, 92739, 983196, 41138, 0, 0, 0, - 125082, 1115, 127060, 9794, 127062, 67671, 92238, 12237, 78787, 66314, - 78785, 9290, 73668, 78783, 78780, 66985, 127144, 7926, 0, 0, 0, 64398, - 100924, 71274, 12311, 101268, 78796, 78798, 78794, 78795, 78792, 78793, - 0, 101270, 0, 73455, 0, 0, 0, 42142, 9968, 11583, 0, 7092, 129835, 9627, - 78536, 73677, 78535, 0, 0, 1248, 10148, 127755, 0, 0, 101273, 0, 66447, - 0, 0, 0, 0, 65305, 0, 4031, 42794, 119986, 0, 8154, 0, 0, 128028, 126259, - 129926, 125220, 73452, 0, 0, 0, 6696, 0, 119599, 0, 0, 0, 4364, 0, 0, 0, - 120976, 0, 120922, 0, 10124, 7526, 8601, 0, 68246, 0, 129318, 1418, - 10885, 0, 0, 0, 0, 0, 0, 4571, 0, 0, 0, 12078, 41597, 0, 10933, 0, 72129, - 67479, 0, 0, 41599, 0, 0, 0, 12950, 119190, 10498, 0, 66782, 4239, 0, 0, - 66511, 68066, 2637, 110685, 8460, 110683, 8476, 110681, 0, 110679, 0, - 127919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5412, 66243, 9935, 122892, 0, - 73864, 41734, 8206, 74081, 0, 3286, 120730, 0, 0, 41732, 0, 41736, - 983203, 41731, 0, 0, 70842, 0, 0, 0, 0, 129329, 0, 66853, 0, 0, 78742, - 72755, 11277, 65892, 0, 10620, 92272, 68165, 0, 0, 0, 73942, 67001, - 100479, 0, 119093, 3459, 0, 129398, 0, 0, 72130, 92512, 0, 66377, 69781, - 128718, 0, 111304, 3161, 69981, 0, 0, 0, 0, 0, 9016, 78153, 0, 0, 43641, - 0, 121018, 0, 101279, 0, 0, 0, 0, 0, 68342, 120950, 94043, 0, 12332, - 121310, 6086, 41722, 0, 120709, 0, 0, 111305, 118677, 0, 128307, 74288, - 0, 74546, 124123, 129178, 124125, 92224, 42460, 0, 0, 0, 0, 120941, - 42421, 0, 41723, 110606, 64358, 11460, 983511, 0, 64718, 120838, 66869, - 0, 42348, 0, 6752, 452, 42500, 0, 128258, 0, 42308, 0, 0, 0, 12932, 0, - 69968, 42950, 66827, 917582, 0, 0, 8302, 0, 66929, 0, 0, 7250, 13214, - 10041, 8105, 65568, 127780, 69969, 127759, 0, 0, 121467, 0, 121466, - 41384, 0, 69878, 0, 5538, 9987, 111298, 118932, 129307, 0, 552, 0, 7357, - 10785, 66995, 0, 4557, 0, 0, 10171, 68320, 0, 5540, 0, 0, 281, 0, 0, - 42622, 0, 5536, 0, 0, 1388, 0, 0, 10504, 0, 0, 11531, 74324, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3663, 0, 121081, 70335, 74859, 0, 5334, 0, 110738, - 72319, 0, 11305, 66997, 68456, 0, 66611, 0, 19907, 64363, 3478, 7583, - 7679, 74154, 0, 0, 1158, 0, 983890, 73748, 0, 0, 1915, 4846, 0, 120132, - 118984, 120134, 120129, 120128, 805, 120130, 64438, 120124, 8760, 120126, - 72137, 120120, 120123, 94003, 0, 0, 0, 0, 0, 12225, 0, 0, 0, 70173, - 75045, 0, 129515, 8083, 0, 0, 0, 111094, 92626, 0, 0, 0, 0, 0, 0, 110837, - 0, 67699, 560, 5643, 0, 0, 0, 0, 0, 0, 0, 120144, 0, 120661, 78304, 1597, - 120143, 120142, 206, 70126, 120139, 120138, 8168, 0, 73086, 0, 0, 0, - 118650, 125036, 0, 0, 3546, 42573, 66811, 67000, 0, 128397, 8400, 0, 0, - 0, 0, 0, 7903, 9287, 72791, 0, 0, 0, 0, 72134, 66603, 1695, 917861, - 124150, 0, 111101, 0, 0, 0, 0, 0, 0, 0, 111099, 0, 111098, 4754, 0, - 69222, 128229, 0, 0, 7354, 7408, 0, 0, 121181, 0, 0, 0, 12739, 0, 1278, - 4187, 0, 42119, 42120, 0, 121158, 0, 12467, 0, 68902, 0, 12463, 0, 0, - 118827, 0, 9664, 70834, 74475, 0, 0, 0, 0, 0, 3661, 0, 0, 9022, 127955, - 0, 101460, 126257, 0, 6118, 222, 126250, 3884, 0, 74151, 0, 6502, 0, - 11085, 121261, 0, 0, 0, 0, 0, 0, 0, 0, 12461, 0, 0, 0, 94059, 11254, - 10860, 64880, 0, 64685, 0, 0, 94087, 7776, 11219, 0, 0, 121339, 69730, - 801, 43165, 0, 78212, 0, 0, 13277, 0, 12951, 0, 9906, 5486, 2334, 128672, - 67680, 5483, 73732, 120884, 119128, 2256, 0, 127876, 2539, 0, 78507, - 5485, 69826, 42697, 0, 0, 113689, 4502, 68057, 253, 73672, 0, 0, 9203, 0, - 0, 0, 0, 0, 121242, 11127, 0, 0, 0, 13257, 0, 0, 0, 69645, 0, 0, 0, - 70431, 0, 5693, 64470, 0, 66610, 67678, 0, 983678, 0, 0, 0, 0, 0, 0, 0, - 94078, 0, 0, 66608, 3111, 0, 8804, 66607, 0, 0, 0, 66606, 0, 0, 0, 1436, - 0, 55226, 0, 111287, 7393, 41592, 0, 0, 1598, 78101, 0, 0, 65193, 4423, - 0, 113692, 10515, 41589, 0, 0, 0, 101485, 1430, 101486, 0, 120606, 0, - 66223, 7619, 3255, 128280, 74032, 11549, 10735, 93038, 100741, 6801, - 100743, 100746, 2148, 100748, 100747, 100750, 100749, 0, 121229, 101479, - 69243, 41724, 67716, 69669, 41690, 111269, 983666, 8380, 100355, 983849, - 0, 101480, 0, 0, 0, 0, 6333, 111264, 42315, 0, 129502, 111265, 0, 0, - 5339, 74323, 0, 13004, 0, 0, 0, 0, 0, 0, 5684, 0, 0, 0, 5689, 0, 0, - 68464, 12633, 12870, 0, 65183, 5688, 0, 0, 6310, 5686, 0, 0, 0, 120647, - 70046, 50, 94095, 9871, 0, 0, 121446, 0, 0, 0, 66905, 0, 4448, 0, 121406, - 113734, 72125, 1321, 0, 10640, 0, 0, 101497, 0, 0, 73542, 0, 0, 0, 0, 0, - 12501, 0, 0, 0, 0, 8812, 0, 69986, 8673, 0, 129024, 0, 0, 2105, 72101, - 72712, 0, 129929, 0, 0, 0, 4636, 55262, 77745, 4515, 2382, 0, 0, 7313, - 101477, 0, 0, 194626, 0, 0, 0, 0, 0, 0, 0, 10197, 194719, 0, 0, 0, - 194718, 0, 0, 0, 64189, 0, 1873, 0, 0, 0, 0, 0, 983682, 0, 0, 101499, - 72282, 126991, 71113, 0, 0, 129340, 9489, 0, 70843, 0, 0, 0, 0, 128030, - 13295, 43191, 0, 0, 1154, 0, 1205, 0, 0, 0, 12958, 0, 0, 0, 66968, 0, - 10592, 0, 495, 0, 41712, 7983, 0, 0, 0, 6347, 69465, 7654, 41710, 4196, - 0, 0, 41709, 73772, 70832, 0, 9465, 983783, 0, 0, 917612, 0, 72374, - 41714, 0, 0, 0, 6343, 72376, 0, 43996, 0, 8044, 66979, 0, 41789, 0, - 10809, 71953, 0, 0, 0, 8146, 11025, 0, 120513, 642, 0, 0, 0, 12875, 0, 0, - 13229, 71950, 41788, 0, 92835, 0, 41791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8428, 6569, 92851, 0, 0, 0, 10167, 0, 68248, 8049, 0, 0, 0, 0, 128882, - 4761, 0, 4766, 64623, 0, 121180, 194653, 118876, 0, 6912, 9232, 7033, 0, - 0, 41545, 0, 71970, 72160, 72107, 0, 0, 0, 3484, 0, 0, 0, 8503, 41539, - 41527, 0, 0, 983842, 0, 0, 66983, 41537, 0, 41541, 8282, 11817, 129965, - 128219, 0, 0, 126132, 0, 0, 70115, 66609, 111235, 65921, 0, 0, 194664, 0, - 129326, 77970, 42246, 75030, 120605, 0, 65926, 7744, 68859, 94056, 74277, - 126108, 0, 6966, 194633, 8136, 0, 0, 0, 0, 0, 4762, 0, 0, 0, 4765, 69443, - 983585, 66970, 4760, 0, 0, 10871, 43199, 194645, 0, 93955, 0, 0, 11546, - 0, 337, 0, 0, 0, 12279, 7768, 0, 128352, 0, 69812, 10143, 7883, 121444, - 7880, 64618, 13012, 5704, 13010, 0, 0, 119531, 0, 0, 0, 0, 66654, 0, 0, - 0, 13008, 0, 4385, 0, 13011, 0, 92569, 66972, 13009, 74771, 70159, 0, 0, - 41793, 64450, 74221, 120996, 41792, 111242, 94054, 126094, 0, 111244, - 5709, 120689, 71076, 0, 0, 0, 0, 0, 5708, 0, 0, 0, 5706, 66362, 5705, - 8791, 41797, 0, 10237, 66436, 0, 66974, 0, 0, 128083, 13170, 0, 127075, - 0, 0, 41377, 0, 0, 10058, 120735, 101431, 0, 0, 0, 0, 0, 0, 129641, - 119525, 0, 0, 72350, 0, 983584, 2144, 0, 120765, 0, 0, 1754, 92226, - 13246, 864, 0, 118926, 8972, 0, 7849, 0, 0, 13240, 0, 5192, 0, 0, 10948, - 0, 13199, 0, 1236, 13208, 13261, 13189, 13188, 93993, 0, 7440, 66976, 0, - 0, 1844, 125229, 0, 13178, 0, 0, 0, 125230, 0, 0, 13260, 4550, 121249, - 125227, 0, 71071, 0, 0, 68523, 0, 0, 11354, 94071, 0, 42795, 129317, 0, - 0, 0, 125237, 0, 13194, 13274, 0, 0, 129533, 65586, 68311, 0, 119193, - 4601, 194661, 101454, 194658, 0, 194659, 0, 121422, 128790, 194657, - 41717, 67402, 101444, 121129, 41716, 127376, 7910, 0, 0, 754, 41944, 0, - 8183, 120741, 2037, 101440, 0, 101441, 125, 0, 0, 0, 983125, 101442, - 41719, 0, 7990, 12637, 13258, 9536, 71056, 0, 4427, 0, 71200, 0, 12217, - 0, 41532, 129315, 0, 0, 0, 0, 111063, 83349, 0, 0, 120622, 0, 0, 0, 0, - 43632, 0, 0, 8140, 0, 6260, 0, 0, 66765, 129657, 0, 3898, 0, 0, 13200, 0, - 0, 66582, 0, 0, 0, 0, 1068, 71178, 13259, 12945, 0, 42203, 0, 3124, - 69411, 0, 4386, 12224, 6973, 129563, 0, 0, 119535, 0, 121312, 0, 12232, - 0, 0, 5681, 64578, 75023, 72016, 13209, 0, 0, 0, 0, 0, 11053, 0, 74902, - 128107, 128942, 7588, 0, 1693, 74942, 43204, 65831, 124120, 0, 0, 68803, - 111216, 111223, 0, 0, 65685, 9523, 2243, 0, 0, 0, 0, 0, 0, 0, 0, 13191, - 0, 3500, 3139, 100643, 3170, 100645, 100644, 66934, 100646, 13006, 64433, - 0, 100650, 941, 0, 0, 120967, 3727, 0, 0, 0, 72378, 0, 0, 118611, 94039, - 129299, 92455, 0, 0, 64444, 0, 0, 43603, 94075, 65397, 288, 0, 0, 0, - 10025, 73692, 0, 0, 68182, 0, 0, 0, 92438, 65395, 0, 0, 0, 65393, 83078, - 121111, 0, 122666, 0, 0, 0, 65394, 11548, 72305, 0, 65396, 0, 0, 13256, - 1282, 0, 0, 0, 111085, 0, 0, 0, 111087, 72115, 0, 0, 0, 0, 0, 3304, 0, 0, - 0, 126595, 72437, 68353, 0, 0, 42113, 0, 0, 0, 0, 0, 43094, 0, 0, 94037, - 68317, 9035, 0, 0, 0, 0, 0, 70822, 128467, 164, 68309, 94067, 94000, - 100631, 100634, 100633, 100636, 100635, 100638, 100637, 68808, 100639, - 110665, 73893, 11099, 110664, 13175, 13207, 0, 127552, 0, 74643, 5929, 0, - 0, 119502, 983654, 11306, 0, 119059, 3180, 125102, 0, 0, 0, 13062, 0, - 129551, 128707, 0, 0, 74428, 0, 128000, 0, 11251, 70204, 0, 10045, 0, - 13275, 0, 11057, 0, 13276, 125133, 41525, 983084, 128015, 11444, 0, - 129158, 0, 122642, 41523, 127765, 0, 0, 0, 0, 0, 0, 0, 3858, 0, 119573, - 0, 0, 0, 0, 0, 0, 101014, 369, 74908, 41784, 0, 120994, 0, 71180, 0, 0, - 13210, 41782, 0, 73536, 101388, 41781, 10486, 74058, 43002, 0, 0, 0, 0, - 0, 3741, 0, 0, 0, 118540, 41222, 0, 128317, 3982, 0, 4388, 126105, 746, - 0, 0, 0, 13131, 0, 0, 0, 0, 0, 10434, 8794, 122963, 0, 0, 0, 0, 0, 11700, - 4374, 129413, 0, 0, 0, 0, 0, 917597, 0, 69814, 0, 6735, 73979, 13174, - 73968, 13225, 0, 69808, 0, 0, 2365, 7841, 71476, 0, 120934, 66510, - 128099, 0, 0, 0, 41785, 41171, 0, 13173, 4372, 6854, 0, 0, 0, 128939, 0, - 0, 12965, 384, 0, 0, 12685, 41473, 0, 13242, 13236, 0, 0, 0, 41787, 0, - 70684, 0, 68486, 13272, 0, 13232, 13233, 65838, 0, 0, 11656, 0, 126110, - 119885, 12861, 0, 13271, 0, 92737, 1096, 0, 0, 0, 0, 0, 0, 2255, 5203, 0, - 92902, 0, 13243, 13237, 12719, 0, 0, 0, 64884, 78043, 43052, 0, 0, 0, - 12014, 0, 101415, 0, 0, 13195, 41452, 64961, 41535, 42969, 10459, 0, - 124949, 0, 0, 0, 41533, 66337, 0, 92184, 0, 126091, 0, 0, 73849, 0, - 43638, 0, 101398, 6261, 0, 129568, 0, 1957, 0, 0, 0, 13292, 13206, 0, 0, - 2925, 73809, 42576, 101395, 13212, 43238, 0, 13190, 13187, 0, 13198, 0, - 0, 5242, 0, 0, 128146, 0, 73535, 6770, 43331, 127539, 0, 0, 71074, - 126466, 73524, 41444, 0, 0, 64799, 5246, 119106, 13185, 9709, 0, 0, - 92751, 0, 5238, 0, 71085, 0, 5236, 40979, 0, 74201, 8286, 0, 3936, 92833, - 11699, 0, 127249, 13235, 69578, 41248, 127264, 13245, 13239, 0, 7969, - 127266, 74832, 127251, 0, 120509, 0, 983893, 734, 127270, 0, 127254, - 70297, 127273, 64921, 120969, 66631, 41771, 120490, 0, 983172, 41770, - 1670, 42560, 0, 121349, 129634, 0, 41163, 0, 11136, 0, 11506, 0, 42841, - 13267, 126109, 0, 41775, 0, 7130, 41773, 0, 0, 0, 0, 0, 0, 0, 42673, - 65572, 0, 65250, 13265, 13264, 64518, 66798, 6100, 0, 0, 6740, 71080, - 67814, 12967, 70028, 68101, 4583, 0, 0, 68097, 0, 0, 0, 0, 119211, 0, 0, - 42653, 83181, 68102, 0, 7814, 71045, 0, 73702, 0, 0, 0, 9756, 6985, 0, 0, - 74219, 0, 0, 129069, 124987, 5674, 0, 66421, 0, 5677, 5588, 0, 0, 0, 0, - 5673, 73488, 5676, 0, 94048, 0, 5672, 6476, 0, 128798, 110951, 42511, - 1727, 0, 0, 0, 0, 0, 0, 0, 3550, 736, 0, 4505, 5873, 74090, 5826, 55232, - 5813, 0, 120712, 5841, 5837, 55234, 0, 3105, 64370, 5838, 5796, 0, - 119592, 5793, 0, 5866, 5797, 41011, 5865, 0, 0, 71899, 0, 71235, 5806, - 73528, 0, 9037, 5671, 0, 0, 0, 0, 71266, 126616, 7296, 0, 0, 0, 0, 6980, - 0, 72108, 0, 0, 0, 0, 0, 64613, 983910, 0, 129969, 0, 78277, 7114, 0, - 72100, 43190, 93842, 128666, 72096, 42611, 42563, 0, 125080, 0, 6792, - 43201, 72098, 0, 128719, 0, 72106, 73534, 0, 5644, 0, 66627, 69727, 0, 0, - 0, 65116, 0, 0, 73526, 0, 66410, 94104, 41013, 0, 0, 0, 2869, 0, 41015, - 0, 2785, 120616, 0, 73907, 194689, 0, 0, 0, 194688, 4759, 0, 0, 43192, - 129913, 1170, 43365, 69810, 73908, 0, 902, 0, 0, 0, 0, 8122, 66420, - 129642, 0, 3861, 0, 11028, 0, 73820, 5714, 0, 0, 0, 807, 127001, 78474, - 0, 976, 113782, 0, 0, 0, 0, 0, 128657, 118801, 71043, 0, 127017, 0, 0, - 5582, 0, 0, 5798, 0, 0, 0, 128521, 0, 0, 68058, 120553, 983184, 0, 0, - 74933, 74283, 0, 0, 194698, 66044, 0, 0, 0, 0, 0, 10094, 0, 0, 10857, - 69225, 0, 0, 93, 0, 10954, 0, 0, 0, 8171, 0, 0, 82996, 0, 0, 0, 73527, - 92634, 0, 0, 5187, 120711, 71086, 118704, 0, 0, 0, 5232, 0, 41009, 0, - 41005, 0, 43205, 0, 0, 0, 194708, 0, 71054, 10028, 66478, 7076, 13182, - 100385, 0, 0, 0, 78782, 7972, 78786, 0, 0, 0, 78789, 11309, 3806, 71252, - 0, 0, 0, 78819, 0, 125218, 0, 127532, 0, 0, 0, 78817, 0, 64366, 65156, - 8814, 0, 0, 0, 0, 12836, 42725, 120079, 0, 0, 0, 0, 69258, 13255, 0, 0, - 7464, 0, 93831, 0, 0, 0, 0, 13213, 118557, 0, 64516, 0, 0, 0, 41007, - 983929, 0, 40995, 12209, 983933, 119136, 123635, 0, 0, 0, 0, 0, 69283, - 43558, 5522, 0, 71061, 0, 74105, 3633, 983931, 119364, 41234, 41231, 0, - 9771, 983936, 13251, 0, 0, 6262, 2784, 0, 71078, 8126, 66483, 0, 0, 441, - 0, 0, 0, 41002, 40999, 0, 129394, 7108, 0, 10890, 0, 74445, 8324, 0, 0, - 74817, 2813, 119056, 74853, 983690, 0, 0, 0, 1193, 10462, 65197, 13253, - 13252, 7829, 120992, 130032, 0, 0, 0, 77911, 0, 77907, 0, 10386, 0, - 41042, 0, 65944, 65683, 10338, 66469, 0, 0, 0, 0, 0, 41966, 0, 0, 0, - 68915, 0, 0, 911, 983889, 128932, 40963, 0, 65159, 0, 122950, 0, 5520, 0, - 0, 0, 0, 0, 0, 0, 42965, 0, 0, 0, 0, 0, 983892, 0, 0, 66839, 0, 0, 0, - 68647, 0, 5857, 68135, 92727, 119120, 983694, 13171, 0, 0, 0, 120338, 0, - 0, 0, 13250, 69663, 0, 92201, 66397, 0, 0, 0, 8761, 12942, 5748, 92713, - 92414, 0, 83174, 8796, 0, 0, 0, 43633, 0, 72805, 71073, 0, 0, 0, 0, 0, - 12843, 4520, 0, 0, 73004, 983691, 0, 0, 194935, 110754, 64345, 0, 983677, - 3457, 0, 0, 0, 110750, 110758, 110751, 0, 0, 10427, 0, 73859, 0, 9755, - 1110, 65239, 0, 0, 0, 0, 0, 0, 0, 194936, 0, 983821, 0, 70437, 3620, 0, - 0, 72855, 0, 0, 0, 74250, 0, 0, 11980, 0, 66482, 67823, 0, 128345, - 110768, 0, 0, 0, 0, 12891, 983786, 983667, 0, 2016, 0, 65668, 92311, - 67696, 10366, 70117, 9155, 120652, 9786, 65082, 0, 8579, 0, 0, 0, 0, - 4508, 64883, 0, 92522, 129847, 0, 64592, 74276, 67688, 0, 69270, 0, - 69456, 0, 113821, 0, 12147, 9024, 66378, 66472, 0, 0, 0, 0, 0, 71935, 0, - 0, 113697, 0, 0, 69285, 0, 74275, 0, 122896, 127941, 41214, 0, 67476, 0, - 0, 0, 7773, 0, 0, 9963, 68649, 0, 73734, 0, 0, 0, 0, 6594, 983771, 0, 0, - 3624, 70342, 0, 64655, 121481, 0, 0, 0, 0, 0, 65932, 0, 983809, 6803, - 120968, 7738, 0, 0, 120628, 129721, 66614, 122921, 0, 43810, 7029, 0, - 41292, 118898, 0, 43115, 9517, 11518, 0, 0, 0, 0, 64423, 0, 0, 0, 12503, - 9591, 4516, 0, 118845, 0, 0, 129479, 43650, 983193, 69250, 0, 0, 68079, - 0, 11397, 2884, 0, 0, 12678, 0, 0, 41014, 73730, 917539, 4270, 92254, - 127836, 68205, 6633, 118947, 0, 5230, 101055, 0, 0, 983234, 121392, 0, - 92985, 0, 0, 0, 0, 415, 0, 0, 0, 0, 5183, 1877, 0, 0, 0, 0, 0, 4472, 0, - 0, 0, 128285, 110682, 78230, 4756, 0, 7081, 0, 0, 0, 78606, 0, 42922, - 42103, 8628, 74861, 0, 0, 0, 43059, 10539, 0, 0, 0, 0, 0, 0, 0, 0, 64873, - 11992, 129444, 0, 0, 11801, 3622, 0, 0, 983215, 0, 0, 11521, 0, 1966, - 43628, 111048, 0, 0, 0, 0, 0, 0, 42098, 66671, 10694, 128520, 0, 0, 0, 0, - 42100, 0, 111040, 0, 42097, 0, 0, 0, 0, 11302, 118640, 129145, 43395, - 83259, 0, 0, 92351, 0, 0, 11299, 1561, 0, 92359, 92725, 69253, 0, 194733, - 0, 194730, 0, 127893, 11280, 0, 0, 983802, 0, 0, 72760, 0, 12486, 65018, - 66516, 5409, 0, 0, 194720, 5399, 9685, 0, 983713, 5401, 0, 0, 66832, 0, - 0, 5405, 0, 0, 0, 0, 0, 2235, 0, 11330, 983711, 64690, 3254, 0, 129974, - 0, 0, 43678, 0, 0, 983146, 0, 6388, 3355, 0, 9867, 0, 55258, 5611, 0, - 128527, 0, 0, 129181, 0, 78228, 0, 0, 119119, 0, 0, 194959, 0, 0, 1379, - 246, 0, 0, 64736, 0, 0, 0, 121227, 0, 0, 0, 0, 0, 0, 11855, 0, 0, 0, - 71961, 10656, 0, 65214, 119242, 0, 0, 13163, 0, 120831, 0, 0, 101484, 0, - 0, 0, 0, 0, 4755, 0, 122627, 11443, 0, 0, 0, 608, 600, 0, 8580, 128712, - 0, 43635, 0, 129695, 74485, 43808, 0, 0, 0, 13160, 0, 129418, 42268, - 128006, 70505, 9828, 0, 69261, 0, 0, 9351, 7778, 0, 0, 0, 6916, 1208, 0, - 0, 194754, 0, 0, 0, 0, 0, 83318, 83317, 0, 43539, 0, 72024, 0, 0, 0, - 9150, 66831, 0, 128322, 0, 66848, 0, 0, 12166, 128492, 194685, 0, 2546, - 0, 213, 0, 65611, 83316, 0, 0, 74310, 70836, 0, 65285, 5452, 0, 983938, - 92772, 0, 0, 0, 0, 65518, 129029, 12609, 194679, 125255, 123193, 0, 0, 0, - 74638, 194677, 125190, 4143, 110854, 110855, 65748, 4141, 9682, 110851, - 118790, 194674, 0, 0, 8725, 0, 66638, 0, 42263, 4145, 6380, 0, 66613, 0, - 119207, 0, 0, 9550, 100621, 0, 100623, 100622, 78050, 100624, 65753, - 100626, 65756, 72731, 0, 100630, 0, 0, 0, 0, 9657, 9019, 121154, 0, 0, - 5390, 0, 0, 194965, 72144, 69937, 69286, 6328, 0, 0, 0, 0, 0, 983047, 0, - 5235, 803, 69289, 0, 0, 127979, 43838, 0, 119562, 43544, 0, 0, 0, 0, - 194960, 70426, 9107, 5191, 119113, 0, 0, 0, 121099, 0, 0, 0, 0, 0, - 128150, 983067, 0, 7289, 74055, 0, 0, 0, 0, 0, 0, 0, 1784, 124947, 0, 0, - 0, 0, 64868, 0, 13158, 0, 7211, 0, 9371, 129378, 0, 0, 1625, 7664, 0, 0, - 0, 0, 0, 0, 69273, 0, 0, 0, 0, 4482, 118886, 0, 0, 0, 0, 0, 0, 0, 100612, - 66849, 100614, 100613, 100616, 444, 100618, 100617, 100620, 100619, 0, - 129401, 0, 11349, 40991, 0, 0, 129324, 0, 0, 1197, 0, 40993, 0, 0, 0, - 40990, 43765, 0, 3492, 0, 127942, 0, 0, 100592, 100591, 100594, 19948, - 100596, 3099, 92239, 100597, 100600, 100599, 0, 129042, 0, 0, 100601, - 194969, 100603, 8152, 100605, 100604, 100607, 100606, 100609, 12828, 0, - 75015, 0, 0, 129950, 0, 0, 75068, 127507, 0, 92680, 0, 0, 129928, 129920, - 0, 130037, 0, 118820, 0, 0, 0, 0, 0, 100581, 0, 100583, 100582, 100585, - 100584, 100587, 100586, 100589, 7576, 11995, 100590, 43260, 0, 0, 64830, - 0, 125046, 101526, 0, 43979, 8870, 0, 0, 42357, 0, 0, 12822, 0, 0, 0, - 118944, 0, 0, 42637, 0, 0, 70725, 0, 129934, 0, 71344, 0, 0, 72449, - 194745, 7170, 9596, 8277, 194743, 43629, 110610, 0, 0, 983571, 123545, 0, - 66699, 42952, 0, 0, 0, 43234, 66008, 12627, 0, 0, 0, 43619, 43303, 11300, - 0, 0, 8745, 0, 7558, 71342, 100570, 0, 0, 127881, 3461, 121258, 129471, - 69264, 0, 0, 0, 73877, 74335, 124982, 0, 0, 0, 64620, 74762, 12069, - 10838, 92548, 43616, 0, 10061, 0, 64840, 10508, 209, 0, 43193, 120581, 0, - 0, 128049, 0, 10899, 69855, 100571, 100574, 100573, 100576, 993, 100578, - 100577, 100580, 100579, 100560, 100559, 7232, 0, 0, 0, 0, 0, 0, 10489, - 42166, 0, 128588, 0, 0, 4224, 7671, 41518, 121311, 0, 0, 0, 0, 64820, - 92538, 12966, 100554, 100553, 100556, 100555, 100558, 100557, 4263, 8793, - 0, 0, 41502, 0, 983, 0, 100563, 100562, 13086, 4109, 4274, 841, 5888, - 100568, 68522, 0, 43481, 0, 120926, 0, 7209, 0, 41505, 0, 78698, 127012, - 0, 2147, 0, 0, 66629, 0, 0, 1255, 4149, 0, 0, 66633, 0, 129391, 92352, 0, - 65101, 0, 0, 0, 0, 5835, 128797, 66625, 10842, 0, 42123, 0, 0, 66634, - 1094, 66636, 0, 0, 0, 0, 0, 9972, 73865, 129289, 6114, 0, 0, 0, 0, 93960, - 0, 0, 0, 0, 12070, 0, 881, 7857, 0, 65164, 0, 0, 118703, 124151, 0, - 64404, 64321, 0, 125187, 0, 0, 11245, 129395, 69506, 71859, 128886, 0, 0, - 1287, 121509, 0, 0, 0, 125264, 74152, 120504, 64545, 0, 69668, 8985, 0, - 0, 0, 0, 0, 0, 3652, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 1489, 125189, 0, 0, - 3899, 0, 42124, 43828, 42122, 0, 0, 0, 11985, 73755, 78600, 0, 0, 10988, - 0, 0, 42138, 78610, 0, 65768, 78608, 78604, 78605, 6285, 78603, 78612, - 78613, 74339, 65767, 8685, 0, 0, 0, 78622, 78623, 68475, 11470, 64538, - 78618, 78615, 78616, 0, 0, 0, 101534, 2527, 0, 128209, 2799, 0, 0, 0, - 9933, 0, 0, 767, 5524, 7028, 0, 101520, 0, 0, 0, 78633, 67481, 0, 94011, - 0, 6971, 0, 70731, 0, 0, 118979, 126075, 2434, 94018, 0, 120579, 0, 4631, - 0, 0, 6407, 0, 19931, 0, 0, 124905, 0, 3192, 0, 8414, 0, 0, 0, 124902, 0, - 9164, 66612, 93959, 8228, 124897, 0, 0, 0, 78624, 0, 0, 9993, 0, 0, - 129350, 78631, 78632, 78629, 78630, 78627, 78628, 78625, 2399, 0, 92399, - 71202, 41208, 0, 0, 8178, 2149, 3367, 0, 78640, 78641, 78636, 78638, - 78634, 6337, 0, 78909, 0, 0, 11068, 0, 9331, 0, 74798, 9181, 0, 0, 8017, - 0, 0, 0, 0, 0, 0, 0, 12126, 119494, 129306, 0, 0, 69650, 0, 0, 0, 43436, - 983744, 0, 0, 0, 0, 66845, 69249, 0, 0, 5398, 0, 127386, 93953, 0, 0, 0, - 0, 0, 9476, 68899, 0, 12763, 126603, 74788, 0, 42114, 11181, 92502, 0, 0, - 0, 3469, 42107, 42116, 0, 0, 119493, 0, 9853, 69648, 9040, 101518, 64665, - 119557, 0, 0, 0, 69638, 12602, 983068, 3852, 0, 67872, 12231, 11317, 0, - 119812, 0, 11410, 10964, 12274, 122890, 100524, 0, 119810, 9865, 195019, - 0, 0, 0, 0, 12276, 0, 124919, 0, 0, 119613, 0, 111214, 10467, 0, 2443, - 10918, 0, 0, 1001, 9241, 1927, 0, 0, 0, 127885, 195022, 0, 113752, - 119830, 65678, 0, 0, 8260, 0, 7519, 11505, 101505, 0, 518, 0, 119832, 0, - 13204, 0, 857, 121252, 0, 0, 92336, 83177, 0, 0, 0, 0, 0, 0, 92762, 0, 0, - 120613, 67247, 1629, 124926, 796, 0, 0, 74123, 72334, 127587, 72336, - 43388, 0, 43944, 72335, 478, 65151, 0, 128147, 0, 0, 0, 0, 0, 42933, - 1206, 71209, 43837, 0, 3843, 12011, 0, 3361, 0, 8121, 10715, 7578, 0, 0, - 0, 10530, 12348, 8653, 0, 73545, 0, 9551, 0, 0, 784, 0, 0, 0, 0, 0, 0, - 43937, 0, 0, 43938, 43935, 73765, 66230, 0, 0, 0, 43936, 0, 43932, 11102, - 0, 0, 42753, 67165, 0, 78324, 0, 0, 6975, 917928, 5415, 12176, 0, 0, - 3462, 43940, 42629, 78691, 128016, 43942, 0, 9759, 0, 0, 78320, 8114, - 78321, 78697, 78696, 78695, 8710, 118812, 118956, 0, 4051, 92657, 0, - 71206, 0, 0, 0, 128857, 0, 1619, 9703, 77986, 0, 42112, 0, 1875, 0, - 42109, 0, 0, 71189, 121160, 64907, 5396, 13144, 0, 0, 5575, 9675, 0, - 5940, 226, 0, 6336, 0, 0, 0, 5116, 64521, 0, 0, 0, 121390, 125048, 74138, - 0, 74139, 128447, 92249, 0, 0, 0, 0, 8935, 0, 0, 0, 0, 616, 78131, 65178, - 4684, 78701, 983899, 74631, 0, 0, 0, 74460, 42110, 0, 10870, 8557, 11054, - 68664, 0, 0, 0, 122629, 0, 0, 0, 0, 65597, 0, 7651, 6846, 0, 0, 68868, 0, - 0, 118966, 129302, 40997, 127218, 0, 0, 40998, 0, 74488, 71182, 9800, 0, - 0, 0, 41000, 0, 5114, 55263, 3386, 70730, 42574, 0, 5115, 5394, 0, - 128756, 5113, 0, 64855, 0, 4425, 0, 0, 0, 43967, 0, 0, 0, 5112, 12173, - 127037, 0, 0, 74998, 118668, 0, 0, 0, 0, 64874, 43964, 1587, 0, 0, 0, 0, - 1369, 917931, 9959, 0, 43963, 4560, 0, 0, 0, 0, 124896, 0, 43961, 42601, - 4514, 72149, 0, 0, 0, 65041, 10965, 120905, 0, 0, 12542, 0, 65341, 0, - 65829, 0, 0, 10475, 0, 0, 0, 0, 11795, 0, 0, 2164, 127102, 127101, 74956, - 7099, 11275, 67681, 127096, 0, 9336, 0, 42626, 43966, 7798, 64474, 64259, - 0, 5730, 119809, 43018, 983175, 93796, 0, 0, 0, 69401, 0, 0, 5127, 11285, - 0, 5495, 4273, 0, 74765, 10849, 6346, 5493, 6342, 68636, 74319, 5492, 0, - 0, 169, 5497, 125053, 0, 0, 68198, 0, 0, 128417, 0, 0, 12738, 0, 983076, - 5321, 0, 0, 0, 5323, 120732, 9773, 125209, 4683, 74318, 0, 68823, 0, 0, - 0, 0, 129553, 0, 123562, 0, 0, 834, 0, 1803, 0, 5733, 0, 0, 71312, 5731, - 1381, 2891, 128639, 0, 127212, 64525, 0, 2881, 92996, 93847, 9601, 2879, - 0, 0, 73129, 5729, 0, 0, 0, 64881, 127905, 9361, 0, 2887, 0, 3526, 6298, - 0, 121219, 0, 0, 0, 8572, 127863, 77896, 0, 71174, 0, 0, 71197, 0, 12096, - 0, 0, 0, 110745, 71176, 110746, 65279, 0, 121236, 5734, 0, 0, 0, 0, 0, - 41641, 12717, 0, 12552, 983615, 66713, 0, 0, 41643, 110747, 0, 8713, - 41640, 78657, 41645, 66712, 125196, 0, 66726, 66711, 0, 93994, 0, 3472, - 64863, 0, 121424, 0, 0, 0, 125203, 67837, 0, 0, 0, 0, 0, 0, 121440, 0, 0, - 129461, 119008, 92402, 65017, 0, 0, 66668, 0, 0, 0, 0, 0, 119822, 0, 0, - 124148, 0, 0, 0, 0, 0, 0, 0, 0, 121043, 66471, 12216, 0, 40988, 0, 0, 0, - 0, 0, 2396, 129078, 0, 0, 0, 64940, 0, 8321, 119823, 128165, 100409, - 83299, 996, 0, 0, 4249, 0, 83294, 92535, 8222, 0, 118875, 71213, 0, 0, 0, - 0, 8534, 72844, 40983, 0, 125195, 0, 12551, 73960, 125193, 74469, 12558, - 121039, 0, 10052, 40982, 129371, 0, 0, 0, 127403, 0, 917559, 0, 78364, - 1563, 0, 0, 19911, 0, 0, 0, 71363, 0, 7797, 78708, 10006, 0, 3308, - 119134, 74940, 0, 0, 78488, 0, 0, 0, 0, 0, 128462, 9200, 10046, 9612, 0, - 8218, 66496, 0, 43742, 78489, 0, 0, 0, 0, 67826, 0, 70056, 508, 128585, - 0, 126539, 0, 0, 0, 0, 0, 0, 0, 124950, 0, 194601, 0, 0, 0, 0, 6659, 0, - 0, 0, 0, 0, 0, 41634, 0, 41639, 71169, 11941, 0, 0, 0, 42180, 68505, - 43753, 3249, 41637, 93982, 12328, 501, 93985, 10601, 129783, 6503, 0, - 92192, 0, 71181, 0, 6505, 74010, 0, 13064, 126112, 121105, 6500, 5526, 0, - 128949, 0, 0, 92376, 0, 9678, 120832, 0, 41706, 0, 0, 0, 8936, 92964, - 119123, 4208, 0, 0, 0, 67742, 0, 74379, 128605, 0, 0, 92422, 983110, 0, - 66475, 0, 5027, 0, 0, 0, 5069, 0, 5028, 0, 0, 0, 5026, 0, 0, 6331, 0, 0, - 0, 0, 41076, 0, 74790, 0, 0, 0, 0, 5029, 0, 5317, 3598, 0, 41070, 92166, - 11185, 6663, 0, 6507, 0, 126079, 0, 1716, 983710, 0, 917824, 620, 41001, - 0, 917823, 43758, 0, 71116, 5024, 0, 41003, 0, 5025, 7297, 122988, 75039, - 69745, 119328, 65557, 0, 0, 983599, 0, 0, 0, 0, 43947, 43946, 0, 0, - 128363, 6105, 0, 119325, 983230, 0, 68203, 43945, 66491, 43939, 0, 68144, - 78718, 2301, 0, 0, 66490, 6979, 101561, 7721, 0, 0, 1592, 0, 0, 121096, - 41048, 129358, 829, 0, 92406, 0, 73541, 0, 41056, 0, 118665, 10953, - 41066, 0, 917813, 482, 101554, 0, 0, 43606, 71185, 0, 917926, 0, 72262, - 110863, 72421, 12050, 0, 5315, 917817, 0, 0, 42061, 917816, 0, 0, 68417, - 917815, 0, 0, 42059, 0, 0, 120723, 42058, 3960, 11043, 11337, 121358, 0, - 92824, 3958, 101568, 0, 917818, 0, 917819, 0, 0, 42064, 11959, 983714, 0, - 0, 0, 0, 73511, 64336, 10478, 92629, 70350, 118692, 0, 0, 42437, 1555, 0, - 8691, 129656, 2215, 41662, 119046, 0, 0, 0, 93952, 0, 66481, 41664, 0, - 42578, 0, 41661, 78715, 78714, 9356, 0, 129544, 0, 1286, 110701, 0, 0, - 983208, 128925, 42476, 0, 11156, 78895, 0, 0, 101583, 72123, 0, 10020, - 43359, 72827, 0, 120946, 41627, 0, 11979, 0, 41628, 533, 11931, 65225, 0, - 125122, 129994, 0, 68118, 0, 4377, 0, 0, 8587, 72097, 13193, 64350, - 68233, 0, 41924, 0, 7735, 0, 127585, 120843, 0, 65820, 0, 0, 43461, 7757, - 0, 0, 43787, 66493, 77943, 4168, 43904, 73952, 0, 0, 121072, 4440, 43902, - 77948, 66837, 77946, 43903, 77944, 77945, 0, 120909, 120826, 120226, - 66492, 43901, 64625, 0, 0, 0, 0, 10013, 64434, 0, 983113, 0, 11782, - 64382, 0, 0, 0, 0, 41630, 630, 120960, 0, 0, 70165, 1043, 93017, 0, 0, 0, - 124945, 313, 129590, 0, 0, 65593, 7445, 43906, 5750, 42258, 0, 55222, - 68222, 11268, 11225, 0, 8526, 0, 0, 43894, 66495, 69990, 0, 92990, 0, - 10707, 7863, 0, 0, 70692, 631, 77952, 77953, 66443, 71171, 83313, 0, 0, - 0, 13305, 77961, 43925, 43924, 77956, 77957, 66903, 66328, 42381, 77962, - 0, 0, 0, 0, 0, 0, 43899, 66821, 77967, 9157, 77965, 77966, 77963, 77964, - 0, 0, 180, 73904, 0, 0, 66494, 12674, 43896, 0, 0, 43890, 43897, 0, - 11535, 0, 66769, 5185, 7165, 5521, 10334, 5519, 71329, 10302, 12351, - 83333, 1027, 5181, 0, 5117, 2186, 5179, 73955, 6845, 991, 3332, 43676, - 41647, 0, 73883, 92571, 77979, 3405, 69572, 0, 5523, 43915, 66487, 92459, - 74943, 9549, 0, 125093, 43923, 0, 43682, 74884, 120537, 0, 43921, 0, - 71184, 0, 43922, 128709, 0, 10414, 9846, 0, 10350, 0, 43918, 77981, - 75075, 77978, 77980, 66485, 77977, 77973, 77974, 78057, 43909, 73983, - 12330, 0, 0, 0, 43910, 69291, 3407, 6293, 0, 68149, 43908, 129060, 0, - 10209, 0, 4195, 0, 9010, 983705, 75072, 6332, 0, 0, 65871, 0, 1736, 0, - 3901, 0, 0, 65890, 128801, 10446, 0, 693, 9130, 314, 78119, 64149, 0, 0, - 0, 11026, 0, 5332, 6940, 0, 0, 127007, 119831, 0, 273, 8165, 118551, - 83307, 0, 0, 12824, 43911, 4528, 5320, 6301, 43662, 6133, 0, 9463, 73738, - 127141, 10922, 121069, 0, 0, 0, 0, 0, 2569, 0, 2326, 0, 2565, 0, 66401, - 0, 0, 0, 0, 41848, 2567, 78620, 121145, 4044, 92646, 0, 12233, 0, 9509, - 0, 0, 127158, 7336, 0, 0, 0, 129598, 0, 67235, 0, 0, 0, 0, 2222, 66499, - 0, 127170, 0, 10895, 118682, 274, 983782, 1858, 0, 67849, 55251, 2172, - 3133, 0, 71857, 0, 9610, 0, 8197, 0, 0, 0, 41665, 5868, 0, 0, 72120, 0, - 19940, 43668, 41667, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 6464, 92750, - 2996, 125221, 0, 68481, 41835, 4047, 41842, 0, 0, 129601, 0, 0, 0, 0, - 293, 0, 0, 64791, 41827, 0, 0, 10579, 8560, 0, 0, 118835, 4803, 73805, - 1739, 0, 3900, 128967, 73737, 0, 72451, 73957, 0, 66474, 41971, 0, 0, 0, - 0, 0, 11716, 66473, 0, 92647, 0, 78920, 0, 0, 0, 0, 0, 0, 0, 6632, 73861, - 0, 74770, 0, 0, 8914, 0, 0, 3183, 1435, 0, 0, 0, 0, 0, 0, 5746, 67392, 0, - 0, 0, 83506, 0, 7082, 71481, 12618, 5059, 983597, 83524, 43604, 0, 0, 0, - 0, 0, 0, 8227, 0, 1218, 0, 64416, 65848, 92884, 0, 0, 0, 126987, 0, 0, 0, - 0, 0, 0, 83515, 83507, 0, 0, 42672, 71194, 43224, 0, 0, 0, 0, 0, 0, 0, - 65905, 0, 42662, 0, 121159, 0, 129536, 0, 7794, 0, 42953, 6377, 0, - 126080, 3669, 3968, 0, 71319, 69658, 129550, 0, 66296, 118616, 0, 0, 0, - 124998, 6699, 126120, 0, 0, 66678, 0, 0, 0, 8409, 119527, 19967, 0, 0, - 9502, 0, 0, 6115, 0, 41654, 0, 0, 0, 41655, 113779, 43975, 72427, 128080, - 0, 0, 0, 41657, 10778, 0, 9533, 184, 1553, 128868, 69574, 0, 0, 0, - 129420, 0, 101589, 983576, 73697, 0, 92480, 0, 128938, 74292, 0, 5157, - 4020, 0, 128154, 43788, 64818, 0, 0, 0, 92979, 0, 0, 74377, 11029, 66651, - 0, 0, 125202, 0, 0, 7877, 121070, 101411, 0, 119828, 2810, 9955, 0, - 69375, 42817, 0, 65122, 11715, 0, 0, 0, 71270, 0, 0, 0, 0, 0, 70199, 0, - 0, 0, 0, 0, 0, 127862, 0, 0, 0, 78222, 127981, 0, 0, 0, 0, 0, 11290, 0, - 0, 0, 0, 8315, 0, 0, 0, 74595, 0, 0, 0, 42531, 0, 0, 0, 74589, 43993, 0, - 0, 0, 0, 43690, 0, 119139, 42730, 0, 0, 0, 64926, 0, 0, 43830, 65257, 0, - 42728, 0, 128697, 123150, 0, 43540, 0, 0, 12725, 72993, 78635, 127826, - 223, 0, 69675, 0, 0, 0, 0, 0, 0, 42605, 0, 0, 0, 0, 0, 0, 0, 0, 78621, 0, - 78619, 119062, 0, 0, 0, 42676, 129353, 64800, 78617, 83504, 68126, 1213, - 0, 0, 797, 0, 0, 83021, 83005, 64387, 4115, 0, 0, 0, 129857, 10679, - 83001, 121091, 0, 64276, 83498, 13168, 83011, 0, 10136, 0, 0, 65088, 0, - 4262, 129866, 0, 0, 10701, 0, 3101, 0, 123204, 0, 0, 11373, 0, 0, 12731, - 9117, 0, 0, 4539, 0, 0, 12727, 0, 0, 0, 43684, 74567, 68877, 983726, - 12724, 73940, 0, 0, 0, 0, 0, 7947, 12003, 0, 74593, 121140, 69653, 74807, - 42018, 0, 0, 0, 65888, 0, 0, 69683, 0, 120306, 0, 0, 12595, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 69848, 68307, 0, 4405, 0, 128336, 129032, 69216, 0, - 128011, 118656, 0, 6817, 67400, 120314, 0, 0, 998, 0, 13105, 120313, - 64327, 1558, 0, 1991, 7882, 0, 0, 0, 530, 0, 0, 0, 12002, 0, 68422, 0, - 10979, 0, 41823, 70696, 0, 0, 7896, 0, 66676, 0, 120325, 0, 0, 129407, - 94033, 0, 6311, 110725, 41698, 0, 12049, 78133, 0, 125020, 41705, 0, 0, - 121298, 0, 66822, 0, 65389, 0, 66027, 0, 0, 41699, 8340, 0, 69776, 0, - 78921, 0, 1988, 5407, 69978, 0, 65912, 93059, 0, 2336, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 126238, 0, 19913, 0, 113733, 0, 0, 74279, 0, 10956, 0, 41674, - 19964, 41679, 65084, 41675, 195031, 0, 0, 0, 0, 983089, 0, 10794, 128961, - 13217, 0, 0, 0, 5280, 0, 0, 12905, 41610, 11532, 0, 0, 768, 120545, 442, - 0, 0, 0, 64081, 41682, 0, 41693, 0, 77993, 77994, 0, 4804, 6994, 983115, - 0, 0, 41696, 467, 983934, 0, 0, 0, 0, 8678, 0, 69682, 64801, 0, 0, 0, - 2193, 64093, 12043, 0, 69666, 0, 2029, 65191, 119246, 42847, 0, 0, 0, 0, - 0, 0, 0, 70339, 126116, 0, 0, 8019, 73856, 0, 0, 0, 118709, 2355, 12150, - 65725, 77988, 77989, 68033, 77987, 0, 77985, 0, 0, 68388, 0, 74171, 0, 0, - 0, 11301, 78013, 78008, 78010, 9874, 78007, 983331, 71064, 3050, 0, 0, 0, - 78016, 78017, 71852, 78015, 0, 0, 0, 92242, 0, 69642, 0, 0, 43883, 0, 0, - 0, 78025, 0, 78023, 78024, 11847, 10545, 0, 10887, 0, 123179, 0, 0, 0, - 83352, 64942, 92363, 9996, 8508, 0, 0, 8195, 0, 42171, 0, 3722, 0, 63751, - 0, 0, 92637, 69670, 0, 41552, 69854, 0, 78639, 0, 0, 129374, 128978, 0, - 0, 0, 7920, 70285, 4021, 0, 0, 0, 119663, 0, 0, 78021, 78022, 78019, - 78020, 1802, 78018, 0, 74895, 41659, 41671, 1827, 0, 64396, 41668, - 128524, 41673, 0, 11422, 71846, 0, 11370, 0, 68412, 41345, 0, 0, 0, 0, 0, - 0, 65114, 0, 2104, 64858, 0, 0, 7553, 0, 41560, 11970, 0, 917920, 0, - 68495, 74131, 74130, 0, 0, 0, 611, 74129, 64871, 129958, 0, 0, 0, 74854, - 0, 70466, 0, 0, 0, 121147, 0, 68487, 41669, 7094, 917921, 0, 123144, - 74054, 0, 0, 0, 839, 0, 7695, 0, 0, 0, 92202, 0, 121053, 123157, 67885, - 0, 7206, 0, 6647, 43986, 129743, 0, 0, 122646, 0, 0, 127936, 43748, - 66746, 0, 12298, 110802, 984011, 110800, 64924, 0, 73931, 9468, 74245, 0, - 0, 74246, 0, 0, 118830, 0, 71851, 1279, 0, 6224, 0, 92405, 128601, - 129886, 128997, 0, 0, 0, 5032, 0, 0, 0, 0, 0, 5034, 0, 0, 72846, 42702, - 0, 0, 13294, 0, 64869, 0, 67808, 9129, 123632, 0, 0, 120819, 68387, - 120168, 120169, 120170, 120171, 5518, 4174, 120166, 66932, 120160, - 120161, 120162, 434, 41437, 66212, 120158, 120159, 0, 0, 118867, 0, 524, - 0, 74029, 0, 126559, 0, 0, 0, 10355, 10419, 74025, 77847, 0, 69725, 0, - 120656, 0, 67876, 0, 0, 0, 74145, 74039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5445, 0, 93779, 71855, 7391, 8989, 0, 74068, 0, 0, 0, 0, 4962, 120409, - 8855, 0, 70820, 0, 0, 0, 0, 71847, 0, 120406, 0, 10451, 0, 67653, 120153, - 12443, 120155, 9947, 120149, 120150, 120151, 13128, 0, 120146, 120147, 0, - 0, 0, 0, 0, 129715, 74059, 74062, 6217, 74053, 43846, 0, 74049, 0, 0, 0, - 0, 0, 0, 0, 0, 42595, 0, 68112, 118860, 0, 0, 92497, 74949, 128953, - 126245, 0, 0, 0, 42997, 122984, 119251, 0, 0, 0, 0, 0, 6216, 0, 0, 9455, - 127027, 8124, 128851, 0, 6944, 0, 0, 0, 2828, 128550, 531, 42638, 0, 0, - 129888, 43428, 0, 3614, 2827, 9696, 0, 129711, 0, 4354, 0, 78562, 78561, - 0, 118553, 0, 42599, 42597, 0, 68829, 125012, 0, 127277, 0, 120421, 0, - 983165, 0, 0, 10121, 120422, 74950, 123142, 69715, 0, 0, 120423, 120630, - 12608, 125244, 0, 74144, 9700, 12580, 0, 128911, 0, 71864, 0, 74071, 0, - 0, 12713, 0, 70402, 0, 0, 0, 1734, 0, 0, 0, 119491, 118951, 231, 0, - 74167, 542, 0, 0, 0, 0, 128074, 0, 121343, 0, 4446, 10584, 74235, 0, - 4037, 0, 0, 0, 5687, 0, 0, 0, 0, 0, 0, 78434, 92816, 0, 113709, 74284, 0, - 0, 0, 126495, 0, 0, 0, 74482, 93978, 1709, 69721, 9909, 92286, 0, 0, 0, - 55229, 8667, 0, 0, 0, 0, 0, 0, 0, 0, 127586, 1226, 6930, 124146, 71736, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 41500, 0, 311, 74282, 6221, 92988, 0, 67682, - 0, 120528, 122901, 74272, 0, 0, 0, 0, 69667, 0, 124933, 74456, 74302, - 42589, 0, 0, 0, 0, 64847, 0, 66987, 0, 41508, 0, 323, 125211, 0, 42698, - 8131, 0, 4625, 0, 4630, 0, 0, 0, 74316, 78417, 2668, 92483, 0, 42640, 0, - 2519, 0, 92474, 92479, 0, 983085, 5049, 42659, 119011, 64705, 7754, - 10854, 8738, 74623, 0, 0, 0, 649, 0, 0, 73480, 0, 0, 1013, 70707, 68212, - 705, 0, 0, 127803, 1183, 126519, 9320, 0, 0, 8157, 0, 0, 0, 0, 0, 0, 0, - 11913, 0, 42848, 0, 64925, 0, 0, 70693, 0, 0, 2051, 0, 0, 0, 66988, 0, 0, - 0, 8466, 0, 4626, 8464, 8472, 68844, 4629, 8499, 0, 0, 4624, 194623, 0, - 94025, 0, 7805, 0, 94007, 6935, 0, 0, 0, 0, 0, 0, 0, 8492, 0, 8459, 0, - 8497, 8496, 0, 129864, 0, 0, 129834, 69553, 73476, 0, 65849, 0, 0, 0, - 12451, 3328, 8684, 0, 6102, 0, 5298, 110881, 5294, 0, 129615, 0, 0, 0, 0, - 43617, 0, 0, 0, 0, 0, 77863, 128695, 0, 0, 0, 0, 0, 5292, 0, 0, 42688, - 5302, 3970, 73516, 0, 1793, 0, 0, 0, 0, 0, 65263, 0, 0, 0, 0, 0, 0, - 13219, 9569, 69567, 74383, 0, 0, 72157, 0, 42949, 0, 0, 0, 5322, 0, 0, - 43631, 5324, 0, 128694, 41614, 65269, 6230, 0, 0, 0, 3360, 0, 11523, - 72726, 92488, 9926, 7197, 0, 68429, 126575, 41821, 1249, 0, 127951, 0, - 123641, 0, 0, 0, 74459, 41807, 0, 41815, 0, 0, 0, 119918, 0, 128248, 0, - 66835, 0, 0, 72145, 41800, 0, 0, 0, 41811, 74466, 93966, 6670, 77882, 0, - 0, 43092, 0, 0, 0, 0, 0, 128655, 0, 0, 0, 0, 74501, 74005, 0, 74387, - 69860, 315, 12813, 128556, 72409, 0, 72408, 0, 0, 73061, 0, 0, 1378, 0, - 0, 0, 72407, 3066, 0, 0, 72406, 0, 0, 0, 8787, 194615, 0, 41618, 0, 0, 0, - 194614, 64652, 194611, 42088, 125226, 0, 0, 0, 0, 7176, 43756, 0, 122649, - 74492, 0, 74534, 0, 0, 0, 127199, 0, 128630, 74525, 0, 194594, 12930, - 7168, 74514, 0, 74515, 0, 128919, 43962, 9527, 120659, 70123, 12977, - 69723, 0, 93783, 194598, 41236, 92235, 65168, 118838, 41237, 5848, 0, - 194600, 3670, 129905, 129906, 129907, 129908, 7890, 0, 11298, 0, 0, 6229, - 0, 0, 0, 194593, 128907, 0, 0, 194592, 4120, 65337, 65336, 0, 0, 0, 0, - 9366, 0, 0, 0, 65327, 65326, 65325, 65324, 65323, 42216, 65321, 65320, - 65335, 65334, 65333, 65332, 65331, 65330, 65329, 42689, 0, 43943, 118885, - 42073, 6785, 68491, 0, 42076, 7196, 65318, 2035, 65316, 4106, 65314, - 65313, 42074, 0, 41228, 0, 0, 41241, 93786, 41239, 43533, 0, 7189, - 194602, 0, 43941, 0, 42802, 0, 8487, 0, 0, 4615, 12695, 0, 0, 12175, - 100414, 0, 0, 7809, 0, 0, 0, 0, 6590, 69762, 0, 64738, 0, 0, 0, 0, 0, 0, - 2025, 0, 0, 0, 10637, 71860, 0, 1570, 43839, 2835, 83052, 10624, 43623, - 194587, 0, 78433, 0, 42812, 0, 2825, 0, 128287, 0, 2821, 0, 92327, 7365, - 83043, 0, 68296, 0, 2823, 0, 0, 0, 2831, 0, 0, 11465, 0, 0, 0, 0, 0, - 7181, 92855, 41332, 0, 12333, 0, 0, 0, 124914, 0, 9883, 127294, 73906, - 70751, 0, 71863, 0, 0, 0, 0, 0, 0, 43741, 0, 8166, 70739, 0, 0, 74535, 0, - 65297, 68294, 571, 0, 8752, 0, 5288, 118822, 1541, 0, 127284, 8864, 0, - 73559, 0, 0, 0, 113778, 12151, 0, 66874, 0, 1035, 0, 0, 7881, 701, 65936, - 128493, 0, 70462, 0, 11403, 0, 0, 82991, 0, 983143, 70472, 3994, 11421, - 121217, 127297, 127242, 127300, 70659, 127303, 0, 125205, 2855, 127828, - 0, 41621, 68214, 0, 0, 10654, 82945, 119226, 12164, 41623, 7906, 0, - 74297, 7182, 0, 83069, 0, 0, 0, 0, 121115, 0, 0, 747, 0, 92463, 12019, - 43136, 0, 110861, 0, 0, 8001, 0, 0, 69394, 0, 0, 0, 68373, 0, 0, 0, - 128279, 0, 71915, 0, 129742, 7282, 94066, 0, 0, 0, 0, 0, 5286, 83061, 0, - 3718, 0, 83057, 78933, 124906, 71905, 0, 128480, 0, 0, 0, 0, 9206, 82980, - 113824, 6802, 0, 41653, 0, 1241, 0, 0, 0, 0, 68124, 41651, 42937, 0, - 83042, 41650, 0, 83037, 0, 12914, 2814, 0, 119552, 120691, 0, 0, 71968, - 0, 0, 0, 917546, 71862, 0, 0, 0, 3494, 10189, 69784, 0, 0, 71861, 0, 0, - 65875, 0, 0, 127762, 0, 74215, 43065, 0, 0, 7200, 0, 3261, 0, 0, 0, - 65889, 71888, 71975, 0, 0, 0, 0, 0, 77793, 0, 0, 129424, 77791, 635, 0, - 0, 74753, 0, 92420, 73997, 0, 0, 43905, 0, 118834, 126125, 0, 6667, 0, - 983268, 0, 0, 125200, 0, 0, 0, 0, 83137, 0, 0, 0, 0, 0, 121104, 127856, - 125112, 71885, 0, 120125, 7866, 194573, 92770, 194574, 0, 120140, 126074, - 2849, 0, 0, 42157, 12960, 0, 11812, 0, 74509, 0, 69881, 0, 0, 0, 123156, - 7178, 0, 0, 0, 0, 129041, 11534, 1967, 0, 0, 71361, 7015, 120298, 72757, - 0, 12989, 0, 9368, 983638, 1624, 43270, 0, 0, 10818, 0, 83091, 0, 120908, - 0, 0, 0, 0, 0, 0, 6169, 12871, 0, 2798, 65176, 4958, 42752, 119025, 0, 0, - 0, 70346, 66448, 0, 113780, 68364, 0, 0, 0, 68360, 0, 73746, 120945, - 68352, 0, 73787, 83110, 2154, 7199, 64955, 0, 0, 0, 0, 71980, 66507, 0, - 69853, 0, 0, 0, 0, 0, 0, 0, 92517, 118882, 120301, 13297, 0, 129446, - 71963, 0, 0, 0, 6658, 8045, 0, 0, 983873, 92319, 83101, 0, 72126, 0, 0, - 0, 2416, 3310, 0, 0, 379, 0, 43755, 0, 0, 0, 68362, 1284, 0, 73756, 0, 0, - 83141, 70784, 71977, 0, 0, 0, 8515, 83144, 83143, 0, 0, 0, 8529, 93782, - 0, 7564, 0, 0, 0, 0, 73757, 73760, 42359, 0, 2031, 0, 7202, 129984, - 12676, 0, 0, 128418, 0, 7710, 1610, 73801, 0, 0, 118706, 983607, 43917, - 0, 9974, 228, 0, 10398, 0, 0, 0, 92241, 70062, 118927, 42999, 1725, - 65533, 8196, 9352, 0, 0, 66868, 0, 8502, 5762, 0, 0, 43898, 0, 0, 0, 0, - 43914, 0, 126507, 64598, 13001, 9326, 83082, 43916, 1557, 0, 983879, - 6330, 6805, 8631, 2545, 70052, 0, 0, 0, 42998, 70410, 0, 42762, 71941, - 42914, 126516, 262, 1637, 0, 83025, 129491, 83026, 128757, 0, 0, 0, - 128922, 0, 43658, 0, 0, 129183, 6419, 0, 0, 0, 0, 93989, 0, 128173, 7194, - 5291, 67395, 43666, 0, 0, 0, 0, 128293, 0, 12881, 123596, 0, 73842, 0, - 9011, 0, 0, 0, 70436, 179, 43644, 0, 0, 64747, 0, 118813, 0, 0, 121389, - 92649, 126629, 0, 73850, 2801, 119495, 42069, 119839, 119838, 119841, - 42072, 92736, 119842, 0, 0, 0, 8377, 0, 42070, 119313, 119834, 119310, - 4389, 43656, 1633, 119857, 118632, 119859, 11119, 119845, 119844, 9967, - 119846, 119849, 4612, 92867, 119850, 42913, 70456, 0, 71983, 10782, - 66898, 0, 119141, 0, 0, 0, 11541, 69636, 0, 0, 119614, 2731, 0, 0, 0, - 4102, 0, 73878, 0, 0, 0, 0, 0, 11283, 0, 0, 0, 0, 0, 43674, 0, 0, 126705, - 0, 0, 0, 0, 11142, 128304, 0, 12975, 0, 123208, 0, 0, 74072, 0, 55269, 0, - 0, 0, 78577, 78576, 0, 0, 82966, 82974, 70448, 0, 0, 82968, 0, 0, 0, 0, - 0, 113809, 0, 69399, 64909, 0, 11790, 74019, 0, 128066, 0, 8561, 94076, - 129481, 125045, 69259, 65674, 7230, 0, 0, 8778, 0, 0, 67725, 2071, 0, - 6459, 68325, 7628, 65092, 73903, 0, 11342, 129388, 0, 0, 93965, 94081, 0, - 11810, 70057, 10723, 967, 0, 71973, 73905, 0, 6387, 0, 12307, 43913, - 121089, 0, 127584, 0, 1886, 0, 43895, 870, 7648, 0, 7662, 7652, 876, 871, - 877, 7665, 878, 42015, 879, 43692, 4563, 0, 0, 0, 73072, 867, 9520, 872, - 7656, 868, 873, 7642, 7659, 869, 874, 7644, 0, 875, 790, 0, 0, 0, 0, 0, - 124899, 0, 0, 0, 0, 0, 68452, 0, 0, 42067, 0, 0, 0, 12292, 0, 0, 0, - 42012, 0, 0, 83388, 0, 0, 8494, 4611, 0, 72344, 0, 9679, 0, 0, 0, 0, - 93015, 0, 74364, 4628, 4245, 0, 0, 0, 1851, 0, 127189, 0, 0, 0, 118897, - 0, 64674, 124971, 983887, 8829, 983693, 128864, 0, 0, 0, 0, 8809, 983696, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7427, 0, 4588, 43680, 72300, 74484, 0, 0, 0, - 0, 113787, 74363, 129043, 0, 793, 0, 11197, 0, 0, 0, 842, 0, 8208, 70833, - 0, 1647, 0, 70841, 0, 73508, 818, 0, 0, 0, 0, 0, 0, 120594, 0, 0, 70179, - 0, 13167, 66359, 0, 127172, 0, 4969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2840, 0, - 0, 0, 66887, 65877, 9068, 0, 68194, 0, 0, 12991, 0, 2651, 68016, 983915, - 0, 983264, 70835, 0, 70844, 43648, 0, 0, 0, 0, 0, 0, 64372, 121064, 7458, - 655, 752, 7457, 7456, 7452, 3285, 74894, 11152, 73099, 0, 2391, 93766, - 92271, 671, 7435, 7434, 618, 668, 610, 42800, 7431, 7451, 42801, 640, - 42927, 7448, 7439, 628, 3905, 100742, 0, 0, 0, 67850, 0, 0, 0, 4605, 0, - 100745, 43372, 65945, 72710, 0, 119590, 0, 0, 70495, 987, 71229, 11572, - 0, 0, 10002, 9971, 70673, 0, 0, 0, 0, 0, 0, 11334, 0, 129493, 42364, - 11503, 0, 0, 0, 4627, 70090, 127784, 73473, 0, 74046, 68872, 92562, 0, 0, - 129900, 0, 129812, 0, 0, 42569, 64965, 0, 0, 10516, 129828, 12190, 0, - 42140, 0, 0, 0, 0, 9887, 0, 4000, 7429, 7428, 665, 7424, 0, 0, 7884, 0, - 0, 0, 0, 0, 2509, 0, 120573, 0, 0, 92449, 0, 10690, 0, 119114, 126226, 0, - 0, 73080, 4590, 0, 74440, 0, 0, 0, 1708, 0, 0, 983609, 0, 0, 69226, - 69974, 8813, 0, 1066, 0, 0, 71965, 127921, 70447, 0, 0, 0, 2202, 0, 7516, - 0, 0, 0, 8034, 0, 0, 3631, 110696, 0, 0, 8416, 110694, 71937, 0, 0, - 110692, 74621, 0, 70185, 0, 74850, 0, 0, 12099, 70475, 0, 6252, 0, 0, 0, - 0, 0, 0, 66368, 0, 64956, 7071, 129070, 70457, 128159, 118800, 0, 77757, - 0, 9357, 0, 1773, 0, 125092, 0, 68451, 7745, 9844, 0, 0, 94, 1880, - 120929, 0, 0, 0, 0, 0, 0, 0, 0, 11237, 0, 129173, 0, 0, 0, 1757, 6964, - 42480, 72823, 0, 120806, 0, 0, 7731, 0, 0, 127883, 0, 77777, 43988, - 70423, 74758, 0, 7592, 856, 74299, 0, 0, 0, 78138, 1459, 0, 0, 0, 0, 0, - 1504, 0, 0, 0, 0, 7529, 0, 0, 0, 0, 12594, 0, 0, 336, 0, 7509, 0, 0, 0, - 0, 127882, 0, 0, 0, 65859, 0, 983986, 43062, 124948, 0, 0, 0, 0, 12970, - 0, 0, 0, 0, 0, 0, 0, 119247, 0, 65068, 74291, 122938, 7069, 0, 0, 66977, - 11130, 2087, 0, 0, 0, 0, 126249, 0, 92747, 0, 92614, 2091, 0, 2090, 0, 0, - 7117, 2077, 72281, 0, 77889, 2083, 0, 71196, 0, 0, 71981, 0, 0, 0, 0, - 4165, 8746, 0, 0, 0, 0, 129572, 7066, 77779, 70415, 128135, 0, 0, 7786, - 127766, 2233, 0, 124965, 121122, 2302, 0, 0, 7056, 0, 0, 0, 0, 118639, 0, - 126506, 6920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983099, 70438, 2613, 0, 0, - 110734, 0, 74571, 42760, 0, 0, 0, 0, 0, 0, 71843, 0, 0, 70506, 1246, - 74243, 0, 0, 41008, 0, 0, 0, 921, 70048, 0, 12702, 119500, 0, 1566, 8407, - 0, 64653, 0, 74617, 0, 0, 72711, 5313, 951, 0, 0, 0, 0, 77807, 4009, - 70277, 71844, 0, 83123, 0, 72250, 0, 119898, 113760, 0, 0, 0, 0, 70024, - 0, 0, 119892, 0, 0, 0, 119890, 2579, 119906, 3177, 11357, 69224, 0, 0, - 83130, 64734, 0, 9822, 110670, 70471, 110668, 66990, 110666, 66967, 0, 0, - 0, 9851, 983748, 110673, 9059, 110671, 77736, 0, 41687, 129054, 0, 71842, - 70178, 0, 66975, 1777, 67003, 10158, 69767, 122982, 42366, 70444, 0, 0, - 0, 70127, 71955, 5989, 110716, 74636, 126999, 0, 41685, 0, 0, 9769, - 41684, 0, 6225, 111328, 11740, 0, 118840, 0, 2600, 0, 70416, 0, 118720, - 3666, 70420, 127193, 71976, 0, 0, 74542, 69771, 0, 0, 0, 0, 0, 69765, - 77804, 252, 0, 69769, 0, 194616, 0, 69763, 0, 0, 0, 0, 0, 0, 0, 120947, - 0, 129410, 0, 118792, 0, 68323, 125219, 0, 119188, 0, 2177, 121335, 0, 0, - 0, 0, 0, 7764, 983745, 11094, 120825, 119490, 0, 92505, 8298, 0, 0, 0, 0, - 0, 64449, 0, 126650, 0, 0, 0, 70442, 0, 0, 0, 0, 7774, 10607, 0, 0, 0, 0, - 0, 120764, 0, 0, 77746, 0, 3458, 0, 70053, 0, 120995, 0, 2602, 0, 0, 0, - 74907, 0, 0, 0, 0, 172, 0, 4971, 70419, 1889, 7238, 0, 0, 0, 8257, 0, 0, - 78917, 129570, 0, 111342, 71948, 0, 43366, 43363, 9807, 0, 0, 0, 72247, - 64479, 0, 0, 0, 113707, 0, 10900, 121355, 0, 0, 12048, 0, 64292, 0, 0, 0, - 6099, 94084, 129486, 0, 0, 299, 0, 8525, 92356, 0, 0, 111338, 0, 92564, - 3075, 0, 94053, 0, 94050, 0, 0, 70440, 0, 123590, 0, 0, 0, 2581, 11395, - 0, 0, 0, 0, 128584, 0, 0, 129423, 101092, 118855, 0, 0, 0, 7204, 70065, - 2588, 2914, 7011, 55281, 0, 7466, 0, 2883, 42253, 83118, 0, 0, 0, 83116, - 0, 41230, 68299, 0, 43571, 0, 6219, 0, 9980, 41232, 92245, 0, 66036, - 41229, 118967, 0, 120666, 94016, 0, 12711, 0, 0, 74289, 68472, 42857, - 66950, 0, 0, 0, 127306, 119006, 0, 11380, 72348, 0, 0, 0, 0, 0, 0, 0, - 983579, 12722, 0, 922, 0, 0, 983127, 74958, 3218, 120471, 120470, 120469, - 120476, 120475, 8569, 11404, 70450, 120463, 3214, 120461, 120468, 74910, - 3207, 120465, 78729, 78728, 78727, 0, 120460, 7425, 3205, 0, 78737, - 78736, 71729, 43383, 78733, 78732, 2606, 78730, 73897, 0, 11496, 1173, 0, - 0, 129135, 0, 0, 0, 120737, 120953, 120872, 120629, 378, 2610, 0, 0, 0, - 0, 0, 37, 7068, 0, 120480, 70421, 3209, 120477, 0, 120483, 9768, 120481, - 0, 0, 0, 0, 0, 0, 65510, 0, 100625, 0, 0, 0, 100627, 0, 126633, 0, 7060, - 100628, 0, 127752, 0, 69284, 70428, 71463, 0, 7380, 0, 0, 100593, 126997, - 0, 124900, 0, 71465, 121030, 3243, 0, 0, 0, 7050, 0, 70050, 0, 0, 122983, - 71466, 8203, 71102, 68241, 0, 65211, 194599, 983406, 118636, 0, 779, - 125061, 64367, 100906, 69901, 8193, 55279, 0, 0, 0, 7065, 0, 4346, 0, 0, - 908, 0, 0, 8982, 0, 0, 0, 782, 0, 10883, 0, 0, 129396, 65542, 121302, 0, - 68650, 100575, 92244, 0, 0, 111351, 0, 4376, 0, 11787, 12961, 0, 0, - 42888, 0, 100610, 6231, 0, 65713, 100608, 1783, 0, 68238, 0, 0, 0, - 194945, 0, 0, 0, 68653, 0, 983051, 0, 764, 0, 0, 43531, 0, 9033, 0, 0, - 6223, 11042, 0, 0, 0, 0, 0, 917792, 0, 0, 0, 0, 0, 0, 120648, 0, 0, 0, 0, - 0, 0, 71971, 0, 1478, 78923, 11825, 2607, 0, 0, 0, 74543, 0, 0, 100588, - 6132, 0, 0, 0, 70058, 0, 0, 0, 43537, 6761, 10093, 4369, 0, 0, 73735, - 100564, 3947, 110778, 0, 0, 0, 0, 100942, 0, 0, 0, 0, 0, 0, 7686, 0, 0, - 0, 100934, 0, 100944, 66577, 41221, 0, 42281, 0, 74024, 12293, 0, 94014, - 11794, 0, 120893, 1737, 0, 0, 0, 7205, 0, 9335, 12850, 77810, 2272, 7055, - 0, 0, 0, 67751, 0, 124910, 6780, 65067, 0, 1327, 68393, 983574, 0, 41217, - 0, 10018, 0, 0, 0, 100611, 68176, 41219, 0, 4147, 983171, 41216, 983712, - 2616, 70197, 68461, 65234, 0, 0, 0, 0, 119660, 0, 0, 0, 0, 127930, - 119580, 70675, 64943, 2608, 1470, 0, 0, 6227, 0, 0, 74775, 0, 0, 72320, - 101024, 0, 73822, 67456, 0, 0, 0, 0, 10876, 92482, 0, 0, 5834, 0, 6222, - 0, 0, 12086, 0, 1600, 64309, 0, 0, 68883, 127957, 93836, 0, 8882, 0, - 129415, 2570, 0, 0, 194606, 0, 0, 1234, 0, 13115, 110743, 110740, 100923, - 5002, 110739, 41286, 100926, 127019, 0, 0, 0, 0, 0, 0, 0, 41289, 0, 0, - 75051, 41272, 0, 0, 0, 0, 0, 124978, 0, 41279, 0, 0, 0, 11081, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9637, 7112, 77975, 128984, 0, 10886, 0, 8548, 983860, - 0, 0, 0, 8076, 43048, 8290, 8291, 43051, 92570, 0, 2596, 0, 0, 41293, 0, - 0, 2393, 7058, 66432, 0, 68673, 0, 0, 0, 0, 0, 128558, 0, 0, 0, 0, 0, - 64696, 0, 0, 121086, 74165, 0, 0, 0, 0, 0, 0, 7063, 983183, 64893, 73096, - 0, 68038, 113757, 709, 0, 0, 1876, 0, 0, 120868, 8137, 110662, 67752, - 70850, 100832, 245, 100831, 11456, 41233, 7070, 0, 94046, 6136, 100835, - 0, 100781, 41235, 73474, 0, 100782, 100642, 432, 0, 100784, 65437, 0, - 100647, 128909, 0, 100641, 100649, 0, 100648, 0, 43215, 0, 0, 0, 0, 9052, - 0, 0, 110826, 110827, 74784, 10580, 0, 100845, 0, 64640, 983176, 74455, - 0, 129670, 70035, 0, 12652, 12199, 127030, 0, 2566, 11971, 0, 0, 1065, 0, - 0, 0, 2576, 0, 66819, 0, 984005, 129852, 0, 0, 983050, 983845, 0, 2921, - 119104, 0, 5772, 12968, 70055, 0, 0, 0, 2580, 983841, 0, 0, 70032, 0, 0, - 0, 128148, 0, 0, 121308, 11346, 0, 12054, 100824, 92426, 101112, 0, - 13091, 0, 0, 100821, 100828, 0, 127026, 128334, 74821, 0, 66295, 68037, - 68047, 127865, 13090, 0, 67492, 0, 118985, 0, 0, 0, 0, 0, 127824, 0, 0, - 100776, 119319, 42356, 42432, 100778, 92823, 0, 0, 0, 78752, 70030, - 66914, 0, 0, 7061, 0, 3854, 0, 70020, 68413, 0, 42319, 0, 0, 7067, 0, 0, - 0, 0, 0, 0, 127797, 9029, 43543, 92820, 2353, 119316, 0, 100769, 0, - 100768, 983178, 0, 0, 43664, 0, 0, 0, 12277, 0, 78122, 11066, 65233, 0, - 41224, 0, 0, 3747, 10522, 0, 77722, 1691, 41226, 0, 77724, 0, 41223, - 121135, 121299, 697, 0, 121051, 4244, 0, 0, 0, 13121, 128573, 0, 0, 0, 0, - 0, 0, 129879, 0, 65816, 68111, 0, 127933, 0, 0, 0, 0, 0, 0, 66895, 74602, - 0, 7123, 70038, 5785, 9198, 0, 100810, 0, 7383, 64656, 0, 0, 0, 0, 0, 0, - 0, 0, 13122, 0, 191, 70060, 8585, 126610, 64411, 0, 0, 64850, 41072, - 118996, 0, 0, 0, 0, 78907, 127010, 100753, 0, 100756, 683, 396, 0, - 100758, 0, 100757, 43058, 100760, 343, 7129, 42680, 0, 0, 0, 0, 0, - 100761, 0, 74040, 0, 1724, 0, 119321, 0, 0, 2203, 0, 0, 0, 6592, 0, - 983044, 0, 0, 0, 0, 3730, 1778, 0, 0, 128854, 121254, 0, 9018, 0, 0, 0, - 0, 92763, 5547, 0, 0, 128950, 0, 0, 284, 8108, 0, 0, 74001, 0, 66460, - 7174, 92703, 126072, 0, 0, 4394, 127480, 0, 0, 0, 101082, 66459, 0, 7180, - 101084, 0, 92812, 68800, 42471, 0, 0, 67232, 64304, 42243, 101094, 2583, - 0, 77728, 0, 0, 0, 71702, 3855, 0, 0, 0, 0, 0, 0, 0, 92416, 7132, 0, - 92743, 0, 64756, 3798, 6578, 0, 0, 92481, 9774, 1275, 0, 119273, 983056, - 0, 120515, 7873, 77719, 129754, 0, 0, 77717, 0, 73994, 73992, 0, 0, 0, - 41851, 0, 41846, 126485, 92337, 7633, 41849, 68385, 70726, 3224, 0, - 69806, 0, 0, 0, 1510, 68129, 0, 0, 0, 0, 12109, 0, 0, 0, 0, 0, 78377, - 1910, 8671, 78374, 127118, 70290, 0, 0, 0, 2654, 7893, 0, 0, 0, 72394, 0, - 67394, 0, 118970, 70066, 78372, 78371, 78370, 78369, 78368, 0, 0, 0, - 1733, 0, 2568, 0, 0, 0, 0, 41486, 0, 127839, 7116, 0, 0, 0, 7185, 0, 0, - 0, 0, 0, 120575, 120829, 0, 0, 0, 0, 92489, 0, 0, 0, 70022, 7171, 0, 340, - 0, 0, 72980, 0, 128535, 0, 124979, 94073, 0, 0, 0, 11392, 92509, 0, 0, 0, - 0, 0, 0, 0, 100632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11948, 0, 6999, 617, - 983825, 0, 3675, 10600, 0, 0, 74616, 2617, 0, 0, 0, 128446, 0, 0, 8630, - 194771, 7288, 983828, 5545, 983818, 2586, 0, 0, 73123, 983851, 0, 0, 0, - 70847, 0, 0, 0, 0, 11195, 71708, 0, 7835, 70040, 0, 0, 92285, 0, 0, - 72973, 0, 0, 100852, 71118, 10029, 983167, 0, 0, 70033, 11359, 0, 0, - 194782, 0, 0, 118975, 0, 0, 3903, 100893, 983858, 0, 120555, 0, 93036, - 110645, 0, 983565, 0, 0, 194773, 0, 0, 0, 127238, 983822, 100919, 0, - 100918, 64752, 0, 983139, 100920, 118642, 43045, 100904, 0, 0, 0, 66394, - 7128, 0, 0, 0, 0, 0, 43044, 2604, 0, 100851, 43046, 121421, 69985, 11768, - 43043, 10470, 0, 7122, 194789, 4390, 454, 41397, 194792, 0, 78762, 0, 0, - 120576, 64572, 0, 68091, 2394, 2575, 113749, 0, 0, 74802, 100913, 129280, - 0, 0, 11989, 0, 0, 128856, 0, 0, 8249, 128172, 0, 0, 6640, 74806, 2598, - 513, 0, 6586, 127521, 129301, 120710, 65008, 0, 0, 92515, 0, 194795, - 66755, 0, 126585, 0, 43152, 78637, 0, 194797, 0, 69893, 6582, 0, 0, - 12839, 0, 78906, 983221, 0, 2444, 119489, 66620, 0, 0, 0, 0, 69894, 0, 0, - 0, 0, 4238, 11071, 9459, 68437, 78140, 78139, 0, 10079, 128985, 0, 0, 0, - 0, 11907, 43928, 0, 0, 0, 0, 92490, 43929, 0, 43926, 64498, 0, 9506, - 6978, 126234, 0, 0, 0, 0, 43934, 0, 1122, 65564, 0, 71055, 0, 0, 1920, 0, - 43930, 827, 0, 0, 0, 0, 6577, 1304, 64733, 0, 10606, 0, 0, 69503, 9329, - 92997, 9239, 74422, 0, 129373, 1222, 11076, 0, 69229, 43615, 8262, 72280, - 64627, 19909, 983554, 72279, 0, 287, 0, 233, 0, 0, 42816, 0, 0, 65140, - 128158, 8830, 0, 0, 10524, 41175, 125033, 72294, 0, 5296, 0, 127559, 0, - 0, 0, 127154, 74858, 6516, 6515, 6514, 6513, 6512, 0, 70870, 0, 0, 0, - 12122, 92462, 100868, 43976, 1785, 92507, 0, 0, 917771, 5138, 0, 0, 0, - 100884, 0, 0, 0, 123564, 0, 5134, 69980, 322, 4643, 5132, 0, 194942, 0, - 5143, 0, 72309, 119628, 0, 0, 72112, 0, 129964, 0, 0, 0, 0, 0, 0, 73097, - 0, 0, 0, 127923, 0, 0, 0, 0, 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, - 100875, 68231, 74489, 100872, 120746, 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, - 3351, 120892, 127351, 10610, 5414, 93789, 0, 4286, 5421, 127344, 67867, - 0, 127794, 0, 6653, 122958, 0, 64510, 0, 41868, 0, 128823, 0, 0, 11613, - 70737, 12603, 7131, 11108, 4566, 0, 0, 0, 0, 0, 124938, 127369, 0, 0, - 5200, 0, 129484, 0, 9183, 127361, 74458, 73075, 395, 5482, 1376, 4349, 0, - 0, 5196, 0, 6113, 42009, 5205, 0, 120530, 0, 118973, 70467, 0, 0, 129691, - 0, 9126, 70498, 0, 0, 0, 0, 0, 3203, 192, 0, 3385, 120785, 128620, 5383, - 0, 0, 0, 5738, 69449, 3336, 0, 5361, 9633, 0, 0, 0, 0, 8581, 0, 1260, - 3149, 5359, 12962, 74955, 10441, 5357, 0, 0, 0, 5364, 0, 11431, 0, 9101, - 0, 0, 0, 0, 78378, 121155, 42917, 0, 129179, 0, 0, 0, 43360, 78385, - 78384, 78383, 78382, 78381, 78380, 78379, 9319, 7097, 0, 127748, 0, 0, 0, - 120632, 0, 71205, 0, 0, 0, 1720, 0, 0, 0, 8622, 0, 70430, 68772, 0, 0, 0, - 73084, 0, 0, 11921, 0, 11769, 68782, 0, 0, 0, 0, 194571, 41586, 0, 0, 0, - 3356, 194572, 64709, 194575, 0, 7134, 0, 78389, 0, 677, 0, 0, 0, 129474, - 68747, 0, 68751, 3349, 74125, 0, 8927, 0, 0, 0, 0, 0, 0, 0, 6806, 0, - 8384, 68755, 0, 0, 0, 0, 0, 124924, 0, 7113, 7586, 0, 10852, 0, 0, 4606, - 0, 0, 70084, 0, 0, 1046, 7124, 121192, 68753, 0, 5171, 65539, 0, 0, 0, - 42394, 0, 74849, 127823, 0, 5169, 11935, 0, 0, 3175, 0, 1537, 0, 5176, - 8905, 4136, 4871, 78388, 0, 0, 122661, 0, 1128, 0, 0, 0, 74066, 0, 73069, - 0, 0, 3662, 113767, 3378, 0, 71298, 0, 127995, 6320, 71302, 983163, - 10163, 0, 5165, 5126, 0, 66902, 41389, 0, 71368, 3374, 113740, 0, 7119, - 0, 0, 3507, 0, 7629, 6848, 19925, 0, 68463, 183, 127208, 127209, 70811, - 10636, 0, 128465, 2250, 0, 78772, 0, 0, 0, 78768, 6580, 4332, 123584, 0, - 10726, 66686, 127203, 127204, 127205, 127206, 0, 70813, 127201, 127202, - 0, 0, 5448, 41058, 5446, 0, 0, 71369, 5442, 7135, 0, 0, 5451, 0, 78470, - 0, 0, 0, 0, 11243, 10859, 65867, 10345, 10409, 123606, 0, 0, 129077, - 42181, 0, 0, 2060, 0, 7111, 0, 0, 0, 0, 72741, 0, 205, 93784, 72346, - 93771, 0, 9862, 6588, 43257, 0, 0, 0, 5505, 93760, 5503, 65376, 0, 7125, - 9819, 0, 0, 0, 5507, 12044, 194567, 0, 0, 0, 7109, 0, 0, 7911, 10329, - 10393, 8991, 125104, 69778, 11133, 129619, 8550, 0, 5592, 2919, 0, 0, - 5595, 0, 0, 4367, 0, 0, 5591, 41060, 5594, 0, 0, 13142, 5590, 0, 72274, - 118909, 75069, 123586, 9731, 71225, 64633, 0, 0, 71217, 121361, 71227, 0, - 0, 0, 0, 7137, 0, 0, 0, 10551, 10710, 0, 0, 0, 120570, 0, 92364, 9936, - 3348, 0, 0, 1444, 119058, 0, 74206, 983107, 0, 1442, 129080, 0, 120959, - 0, 0, 0, 0, 0, 0, 0, 3334, 73068, 118803, 0, 0, 71219, 69770, 1651, 0, - 8861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43626, 0, 0, 3344, 0, 0, 12920, 0, - 0, 0, 71853, 3438, 128711, 0, 0, 0, 0, 129068, 0, 0, 65117, 0, 0, 0, 0, - 66366, 128915, 0, 69772, 0, 0, 0, 0, 4973, 8784, 0, 0, 0, 0, 0, 0, 0, - 125198, 983288, 0, 0, 66413, 0, 0, 0, 0, 122663, 9243, 2464, 0, 0, 3372, - 0, 0, 0, 70364, 7121, 0, 0, 0, 92163, 0, 0, 0, 0, 0, 0, 0, 3354, 0, 0, - 983104, 101233, 0, 3876, 0, 127983, 6858, 43696, 43380, 0, 74240, 0, 0, - 0, 983985, 75074, 6589, 0, 0, 120993, 0, 0, 69609, 0, 66962, 0, 10630, - 71960, 0, 121293, 0, 0, 121287, 917942, 121337, 121215, 0, 0, 0, 0, 0, - 917940, 3366, 0, 917938, 0, 0, 0, 71062, 0, 121197, 0, 6925, 71856, 0, - 917929, 66780, 66274, 0, 72768, 0, 917930, 129482, 11138, 0, 6754, 7118, - 0, 64672, 65296, 0, 118957, 0, 0, 12296, 68457, 121320, 0, 5282, 0, - 72278, 0, 0, 0, 0, 0, 0, 66355, 0, 0, 68073, 64343, 0, 92744, 195058, - 195029, 0, 0, 195056, 195027, 0, 0, 128814, 195025, 6584, 195026, 10657, - 0, 74544, 0, 1200, 12243, 92269, 195062, 0, 129300, 11545, 0, 120493, - 3343, 4424, 11047, 0, 69863, 3896, 0, 0, 2947, 0, 0, 42221, 0, 68139, - 13059, 7942, 0, 3381, 0, 0, 0, 0, 0, 0, 78235, 0, 0, 0, 7044, 65800, - 78236, 0, 7045, 7175, 7047, 127884, 11791, 0, 0, 3881, 0, 0, 127395, 0, - 0, 67075, 7106, 72000, 0, 0, 74211, 41897, 92513, 0, 73040, 66745, 0, 0, - 0, 0, 121245, 0, 64354, 73083, 8777, 0, 129108, 8884, 2385, 73067, 92450, - 0, 0, 0, 42027, 12114, 0, 0, 64936, 0, 0, 0, 0, 0, 126605, 0, 0, 0, 0, - 73064, 0, 0, 0, 0, 0, 0, 0, 73057, 0, 123587, 0, 0, 0, 0, 0, 70803, 0, 0, - 124953, 0, 0, 0, 7048, 11087, 123600, 92536, 7043, 9600, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 42050, 0, 55289, 0, 0, 657, 0, 195054, 4461, 92903, 0, 92904, - 126490, 0, 4468, 0, 0, 0, 4456, 73070, 10720, 123588, 0, 123544, 0, 0, 0, - 195046, 260, 7714, 74163, 2045, 0, 65064, 4466, 0, 0, 128087, 129768, - 41403, 0, 0, 0, 41406, 120692, 0, 0, 73939, 0, 0, 0, 41404, 1165, 0, - 4451, 13087, 0, 11258, 0, 73855, 0, 43014, 5439, 12061, 74586, 3375, - 128869, 0, 0, 0, 0, 0, 0, 0, 113823, 67078, 0, 67079, 0, 0, 0, 0, 68459, - 0, 0, 0, 0, 0, 0, 7280, 0, 0, 0, 4868, 8297, 0, 0, 42791, 0, 66737, - 66739, 0, 0, 5182, 0, 0, 72764, 0, 4465, 0, 12135, 0, 4464, 0, 0, 977, - 4458, 43827, 0, 0, 120888, 0, 344, 67463, 0, 0, 0, 0, 92240, 0, 64443, - 126995, 73078, 129525, 0, 0, 0, 43026, 7612, 119591, 64413, 0, 0, 0, 0, - 0, 0, 0, 0, 123622, 0, 119160, 10204, 127947, 73063, 0, 0, 127236, 0, - 68746, 0, 8852, 0, 0, 0, 0, 128427, 123597, 7932, 92858, 128463, 0, 0, - 72453, 0, 0, 0, 0, 74893, 9567, 0, 73095, 0, 8650, 0, 0, 0, 69900, - 118872, 0, 70868, 0, 6719, 0, 0, 0, 72836, 0, 0, 118991, 0, 123594, - 73815, 4420, 0, 10583, 7760, 0, 0, 128752, 71711, 0, 128407, 0, 0, 77809, - 9066, 0, 74795, 0, 0, 0, 0, 0, 0, 0, 42825, 41854, 5304, 0, 124942, 6919, - 8619, 0, 10038, 66454, 9592, 129049, 0, 0, 110771, 110777, 110772, 0, 0, - 0, 0, 0, 78498, 110773, 43624, 0, 7779, 0, 0, 9479, 78493, 0, 66956, - 2224, 0, 0, 0, 0, 0, 42378, 3368, 0, 66804, 7697, 69237, 0, 2030, 0, - 68236, 8370, 0, 66953, 0, 0, 983355, 127903, 983353, 983352, 5174, 42831, - 983349, 70439, 983347, 8881, 119047, 0, 70433, 0, 0, 0, 0, 0, 0, 9576, 0, - 3347, 4160, 5154, 0, 3794, 0, 0, 0, 0, 0, 127916, 73073, 8381, 4572, - 69564, 126101, 0, 0, 0, 0, 0, 0, 0, 92283, 0, 0, 5799, 983344, 70100, - 983342, 983341, 983340, 43031, 64425, 65128, 983336, 0, 73059, 0, 68616, - 0, 0, 0, 0, 119826, 0, 0, 123604, 0, 0, 283, 68665, 0, 532, 0, 0, 983827, - 0, 0, 3370, 73077, 119132, 5443, 71431, 0, 118630, 0, 0, 0, 2298, 0, 0, - 0, 983335, 983334, 983333, 983332, 7144, 983330, 119600, 983328, 983327, - 983326, 0, 78816, 128833, 0, 0, 0, 0, 0, 0, 0, 0, 73088, 0, 123592, - 983952, 0, 0, 0, 0, 5186, 7360, 127837, 0, 12108, 0, 65124, 0, 0, 0, - 6326, 43344, 0, 0, 42562, 0, 0, 0, 983325, 65495, 983323, 101066, 983321, - 101065, 983319, 65490, 983317, 125034, 0, 101070, 127178, 55245, 128927, - 1630, 128232, 65483, 0, 0, 0, 65476, 0, 0, 119214, 9283, 10183, 0, 0, - 65499, 0, 64593, 66758, 3376, 0, 0, 0, 101077, 43872, 12940, 0, 0, 78587, - 101078, 5957, 0, 8926, 983315, 983314, 983313, 10745, 10174, 983310, - 113793, 983308, 983307, 983306, 0, 123593, 5056, 0, 0, 0, 120773, 0, - 9812, 0, 4460, 127792, 73066, 0, 128038, 0, 123608, 0, 64278, 0, 0, 0, - 66760, 0, 0, 70122, 0, 0, 917627, 0, 73823, 101071, 127922, 2276, 0, - 42579, 0, 983305, 983304, 127831, 983302, 983301, 983300, 983299, 983298, - 74207, 121255, 10482, 12863, 73002, 2412, 0, 9522, 0, 983906, 120674, - 101059, 3384, 101058, 10702, 830, 0, 128166, 0, 8451, 0, 0, 121380, - 69739, 128957, 0, 0, 0, 0, 0, 0, 0, 4243, 92454, 73093, 0, 129705, 4441, - 0, 983295, 983294, 66618, 983292, 125141, 411, 983289, 68068, 983287, - 4056, 983913, 0, 92666, 0, 983916, 983968, 0, 0, 3364, 42265, 64437, - 129635, 118816, 0, 9684, 216, 0, 1401, 0, 0, 0, 122643, 0, 0, 0, 11126, - 5768, 3191, 0, 0, 0, 0, 0, 0, 65895, 0, 0, 3338, 73935, 983283, 983282, - 983281, 129605, 983279, 983278, 2794, 8807, 0, 0, 110720, 0, 8312, 0, - 110718, 11953, 11662, 0, 0, 0, 0, 9534, 66767, 129040, 0, 11113, 0, 0, - 73082, 0, 981, 0, 4330, 119244, 120536, 1824, 0, 0, 7034, 41683, 123166, - 0, 73754, 0, 0, 74478, 128259, 983273, 983260, 983259, 43831, 983257, - 66752, 983255, 983254, 0, 70288, 65343, 0, 0, 43225, 0, 0, 0, 0, 126129, - 0, 128608, 0, 0, 0, 120726, 0, 983852, 11746, 0, 5216, 0, 0, 0, 0, 3468, - 127149, 9230, 65942, 0, 0, 5803, 120677, 0, 0, 13124, 0, 0, 0, 42843, 0, - 0, 0, 66753, 11739, 128318, 0, 128444, 0, 0, 0, 12448, 0, 121441, 13057, - 73852, 124994, 0, 0, 0, 0, 0, 0, 126612, 0, 68903, 0, 129470, 0, 917992, - 0, 0, 0, 0, 0, 0, 0, 92457, 0, 0, 0, 0, 0, 0, 0, 0, 125078, 0, 0, 0, - 10970, 92208, 0, 0, 0, 19944, 0, 9009, 8551, 0, 0, 0, 7575, 67484, 0, - 128899, 0, 129609, 78847, 0, 78846, 73502, 0, 69256, 0, 0, 0, 0, 9775, - 100682, 129191, 119052, 68629, 194703, 0, 0, 78850, 92880, 0, 0, 0, 0, 0, - 0, 0, 71273, 6184, 41540, 3303, 66182, 11786, 66180, 66203, 3422, 0, - 68290, 43007, 4478, 66178, 0, 0, 126216, 0, 4477, 0, 69608, 66184, 66183, - 66204, 66194, 0, 66198, 41880, 66188, 66197, 78148, 66195, 66190, 66191, - 41111, 66189, 73788, 7788, 0, 0, 0, 0, 0, 2221, 78163, 6535, 78161, - 78162, 430, 78160, 78156, 78158, 0, 0, 4945, 0, 4950, 0, 78165, 0, 67118, - 0, 5964, 12908, 0, 0, 0, 74477, 83390, 0, 4949, 0, 443, 0, 4944, 5467, - 119603, 983265, 0, 9364, 0, 119148, 4946, 0, 3788, 126106, 983718, 0, - 120847, 129858, 74441, 0, 0, 12072, 92248, 0, 983708, 0, 128676, 12091, - 0, 0, 0, 4673, 0, 4678, 0, 0, 65059, 43860, 0, 0, 0, 128151, 1199, 0, - 8356, 0, 0, 4677, 0, 0, 0, 2192, 78173, 78175, 78171, 78172, 72255, - 78170, 78166, 4674, 128450, 194944, 0, 124970, 0, 119579, 0, 129919, - 1855, 0, 0, 127806, 0, 0, 68912, 72323, 0, 12988, 121000, 0, 0, 0, 4654, - 6840, 983432, 0, 73993, 0, 4649, 65209, 983908, 93839, 4648, 122635, - 121169, 983436, 126231, 983427, 66846, 7828, 4650, 983426, 72879, 0, - 4653, 7822, 0, 0, 43187, 0, 983586, 6821, 0, 0, 0, 0, 0, 0, 66756, - 983433, 0, 0, 0, 8547, 0, 42165, 0, 119228, 6836, 0, 0, 4662, 0, 0, 0, - 9146, 599, 4657, 0, 120754, 0, 4656, 0, 0, 7811, 40994, 0, 6414, 5967, - 4658, 3725, 0, 5814, 4661, 127760, 194961, 0, 0, 64904, 0, 10833, 0, 0, - 4867, 128717, 0, 11459, 3054, 0, 40996, 0, 7605, 4622, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 19926, 0, 0, 65307, 4617, 0, 0, 0, 4616, 10518, 0, 127160, 0, - 5958, 0, 983449, 4618, 0, 983442, 120675, 4621, 0, 983444, 522, 125213, - 11139, 65803, 194972, 0, 12201, 6135, 121060, 983425, 0, 983093, 0, - 983423, 983416, 983437, 4638, 983421, 0, 78242, 5965, 78240, 66569, - 68646, 0, 983455, 74392, 5335, 0, 0, 4633, 0, 119045, 983451, 4632, 0, - 5542, 5333, 0, 983428, 68648, 5331, 4634, 0, 92870, 5338, 4637, 0, 0, - 43477, 0, 42493, 0, 42361, 0, 0, 73853, 0, 0, 0, 74204, 11343, 0, 10358, - 10422, 4758, 0, 1608, 5252, 0, 0, 4753, 78239, 11344, 78237, 0, 5231, - 74384, 0, 0, 118676, 0, 0, 0, 0, 71991, 5229, 4757, 0, 0, 5227, 4752, 0, - 65235, 5234, 73044, 0, 0, 0, 0, 0, 0, 7460, 0, 917936, 0, 0, 74760, - 65189, 0, 92230, 0, 0, 5574, 128980, 0, 65139, 5577, 0, 0, 118871, 68641, - 8965, 7635, 0, 5316, 70021, 5314, 74555, 5572, 0, 5312, 0, 5525, 5330, - 5319, 68292, 0, 65066, 0, 0, 983496, 0, 0, 127851, 0, 74851, 0, 0, 64609, - 0, 0, 128593, 0, 129339, 0, 8632, 0, 0, 0, 195012, 5735, 195013, 1692, - 70151, 4610, 122653, 4305, 0, 4609, 43478, 4614, 77753, 118534, 5287, - 5309, 5285, 0, 5961, 4647, 5283, 10743, 0, 71889, 601, 4613, 77759, 0, - 9208, 4608, 74044, 71107, 5190, 0, 0, 92410, 43965, 2265, 0, 0, 0, 0, 0, - 0, 0, 129953, 0, 0, 5960, 0, 8992, 65293, 0, 1782, 0, 0, 0, 0, 0, 5501, - 0, 42508, 69759, 120749, 129120, 0, 195023, 77740, 43900, 77741, 0, - 68134, 111180, 74209, 0, 64740, 0, 0, 0, 983935, 3767, 5737, 0, 4865, 0, - 5740, 0, 5736, 7724, 0, 7193, 0, 0, 5739, 77744, 4866, 0, 0, 0, 4869, - 67093, 0, 0, 128514, 6650, 983488, 0, 983479, 78376, 4870, 0, 68661, - 6716, 983478, 2190, 69786, 68676, 0, 10122, 4864, 66568, 0, 0, 0, 9603, - 68652, 126213, 42734, 745, 0, 124131, 124130, 4777, 0, 77788, 68631, - 42775, 68196, 0, 124128, 124129, 0, 5966, 0, 4778, 127890, 0, 0, 4781, - 127196, 64407, 0, 74132, 8577, 71221, 0, 71223, 0, 4782, 0, 0, 120757, - 68618, 43472, 43056, 68622, 0, 92986, 4776, 0, 11492, 0, 0, 13176, 0, 0, - 0, 73558, 0, 0, 0, 4849, 8242, 9561, 73922, 0, 0, 0, 0, 5963, 0, 125201, - 0, 4850, 72121, 0, 590, 4853, 0, 4854, 0, 5164, 0, 1605, 5124, 0, 111165, - 0, 8471, 0, 111164, 12445, 3785, 0, 111162, 0, 0, 4848, 2530, 0, 2068, - 1964, 0, 0, 10796, 0, 0, 0, 0, 0, 4794, 0, 0, 0, 4797, 68040, 111152, - 43465, 4792, 0, 0, 0, 0, 0, 110842, 983102, 92963, 0, 0, 0, 4221, 92360, - 118869, 0, 0, 0, 70042, 0, 0, 0, 0, 10739, 65090, 0, 119327, 126541, 0, - 0, 119326, 0, 0, 4937, 43376, 0, 0, 10597, 983445, 11722, 9248, 129566, - 42879, 11725, 0, 0, 7579, 11141, 73958, 4941, 0, 917538, 9140, 4936, - 5261, 0, 0, 72298, 0, 4942, 0, 4938, 0, 0, 5259, 9369, 983434, 111182, - 5257, 78932, 6844, 4964, 5264, 0, 0, 0, 41411, 0, 121473, 73684, 128233, - 9482, 4873, 41991, 64707, 42526, 127989, 64480, 64725, 983447, 0, 0, 0, - 0, 0, 0, 73043, 0, 389, 10893, 7521, 0, 4872, 5463, 0, 3125, 111124, 0, - 4878, 5459, 4604, 0, 0, 5465, 0, 0, 0, 0, 9563, 0, 0, 128419, 125273, - 82963, 0, 0, 0, 67735, 0, 0, 0, 0, 0, 73560, 0, 129707, 0, 917833, 0, - 917836, 0, 0, 3082, 0, 0, 0, 0, 118621, 7079, 5856, 917842, 5163, 0, 0, - 1817, 66724, 0, 0, 10564, 7763, 13077, 124115, 0, 68140, 111137, 0, - 77782, 0, 111139, 123548, 77787, 121457, 0, 0, 0, 983190, 73081, 0, 0, - 983118, 124114, 0, 42156, 0, 0, 0, 983080, 0, 0, 0, 119254, 120693, 0, - 69386, 0, 118881, 0, 78189, 0, 78186, 78188, 129654, 0, 0, 0, 110877, 0, - 3108, 9745, 0, 0, 0, 118825, 92785, 0, 122954, 0, 0, 10972, 92786, 0, - 42768, 715, 983114, 121117, 9453, 5348, 10943, 0, 983170, 92784, 0, 0, - 983154, 0, 0, 11551, 128464, 0, 0, 9051, 0, 71728, 0, 120791, 119523, 0, - 6404, 66458, 68376, 11984, 9156, 65222, 74454, 78180, 0, 3128, 4789, - 5067, 5066, 0, 4784, 0, 8827, 1146, 5065, 78196, 78192, 78193, 78190, - 78191, 5064, 5326, 0, 9450, 5063, 120361, 78200, 78201, 5062, 69733, - 74146, 0, 0, 0, 0, 77992, 0, 3933, 77768, 0, 12337, 0, 125023, 0, 0, 0, - 194759, 0, 0, 82993, 42130, 0, 5151, 917832, 120357, 0, 73523, 0, 7620, - 3800, 0, 0, 0, 127952, 0, 0, 4786, 127991, 4185, 0, 128742, 0, 983194, - 73978, 0, 4593, 77715, 77727, 124909, 0, 110715, 10532, 77732, 110714, - 110711, 110712, 64759, 1325, 5166, 9888, 0, 5148, 0, 0, 78205, 78206, - 64140, 78204, 64131, 3119, 917814, 0, 983438, 917820, 12095, 0, 0, 636, - 128002, 0, 983469, 0, 78531, 7836, 42741, 64137, 0, 118969, 0, 92431, 0, - 0, 0, 0, 0, 8618, 0, 11865, 0, 0, 0, 3937, 12312, 128261, 0, 0, 0, 912, - 6349, 4536, 71964, 0, 126594, 0, 0, 0, 3935, 120665, 0, 0, 0, 0, 118859, - 0, 121116, 0, 0, 12046, 12599, 0, 0, 0, 0, 7227, 0, 0, 0, 983066, 0, 0, - 0, 113817, 2179, 78246, 0, 0, 0, 0, 0, 127405, 101531, 0, 101530, 43907, - 0, 0, 0, 0, 4644, 8818, 0, 0, 0, 0, 93066, 66452, 126081, 1644, 101043, - 9658, 43744, 11385, 65947, 983174, 43983, 0, 0, 0, 8962, 0, 0, 2466, - 42039, 67669, 0, 0, 42117, 100698, 0, 0, 0, 0, 43745, 5318, 0, 77723, 0, - 0, 0, 7054, 64147, 0, 917804, 68195, 6698, 0, 0, 0, 70849, 11981, 12202, - 0, 121364, 0, 7059, 11608, 975, 0, 65843, 170, 0, 67239, 42708, 0, 0, - 6058, 0, 0, 0, 70507, 0, 0, 9818, 0, 0, 42106, 0, 983065, 4738, 42105, - 7062, 0, 4737, 11779, 4742, 120564, 92391, 0, 41374, 41375, 983381, 6715, - 12700, 7049, 983379, 0, 0, 0, 4741, 42108, 983370, 64159, 4736, 64148, 0, - 849, 0, 128247, 983366, 0, 120913, 917997, 0, 983384, 9496, 66371, - 983408, 983382, 11322, 0, 93008, 3928, 983153, 0, 10706, 7198, 0, 4842, - 12053, 0, 0, 4841, 0, 4171, 12008, 68416, 3923, 1490, 0, 0, 983398, - 40972, 5245, 72288, 983400, 126578, 0, 4845, 8332, 40974, 0, 4840, 9077, - 2252, 2408, 72851, 4825, 0, 917574, 0, 0, 126251, 0, 0, 983358, 0, - 983359, 0, 4826, 42440, 0, 0, 1274, 0, 74315, 0, 120384, 118614, 121200, - 0, 0, 0, 4830, 983393, 129044, 0, 0, 119082, 0, 64105, 0, 0, 4824, - 120397, 0, 0, 1888, 64127, 7861, 125111, 78524, 41836, 110613, 10873, - 72439, 0, 64098, 12214, 124134, 41834, 0, 358, 128120, 41833, 11442, 0, - 0, 0, 0, 64115, 0, 0, 0, 120721, 119053, 0, 119055, 119054, 0, 0, 0, 0, - 4017, 12827, 5241, 0, 73042, 41118, 3924, 0, 11366, 0, 0, 0, 0, 41116, - 69455, 0, 0, 0, 0, 11917, 0, 74000, 4721, 123551, 983937, 0, 0, 0, 0, 0, - 0, 122907, 0, 128702, 4722, 6816, 124974, 0, 4725, 67099, 4726, 0, - 129856, 123171, 0, 123194, 0, 0, 0, 4015, 0, 8052, 78766, 123538, 0, - 128294, 0, 0, 4720, 73090, 125003, 0, 0, 1656, 41831, 0, 0, 41843, 92846, - 0, 1452, 13111, 0, 0, 0, 8552, 64113, 41845, 64073, 120354, 0, 0, 120066, - 120067, 7064, 64070, 9948, 0, 0, 0, 92828, 2420, 92811, 0, 0, 0, 120052, - 120053, 120050, 74920, 3938, 120057, 120054, 92829, 120060, 71920, - 120058, 120059, 120064, 72203, 7955, 64074, 4713, 128196, 983108, 0, 0, - 0, 65152, 10198, 120044, 120045, 120042, 6713, 4532, 120049, 120046, - 120047, 4717, 7046, 0, 66450, 4712, 75055, 0, 121085, 0, 8155, 4718, - 3942, 4714, 9625, 0, 6383, 0, 12006, 0, 0, 0, 0, 0, 65414, 0, 0, 129061, - 66437, 66025, 74115, 0, 0, 11228, 4809, 0, 68211, 72352, 0, 0, 983101, - 65405, 129912, 0, 0, 2163, 4545, 0, 917566, 0, 4813, 78699, 0, 0, 4808, - 0, 0, 65475, 0, 0, 4814, 72240, 4810, 0, 0, 68784, 10761, 67514, 3522, 0, - 78693, 65404, 0, 0, 0, 0, 0, 6691, 70125, 0, 126223, 0, 0, 0, 43858, - 129914, 0, 12992, 65407, 0, 0, 3919, 72379, 0, 92845, 0, 0, 0, 12235, - 110748, 0, 0, 64091, 68739, 64080, 0, 64090, 0, 0, 0, 0, 0, 8454, 0, 0, - 983877, 0, 0, 120398, 4780, 0, 0, 92764, 64621, 6732, 0, 0, 0, 0, 121363, - 0, 0, 120817, 6976, 0, 119005, 0, 93809, 0, 93808, 0, 12526, 120399, - 2315, 0, 1938, 0, 0, 0, 0, 0, 0, 0, 111135, 93794, 0, 0, 0, 93810, 0, - 2291, 0, 0, 0, 0, 129429, 0, 10799, 0, 0, 66372, 0, 4193, 0, 0, 983057, - 7998, 0, 0, 0, 0, 2316, 0, 0, 0, 0, 120106, 0, 0, 74140, 0, 0, 0, 0, - 3762, 93813, 120672, 93820, 0, 0, 0, 70098, 3780, 12808, 8163, 983155, 0, - 0, 3906, 12349, 0, 8326, 0, 65498, 3763, 0, 5618, 0, 3779, 0, 43613, 0, - 128007, 0, 0, 0, 0, 280, 0, 126252, 983453, 13072, 1894, 0, 0, 65478, - 43310, 7231, 0, 11773, 0, 0, 0, 101517, 122662, 0, 7559, 11652, 10009, - 110765, 110766, 110763, 110764, 4470, 110762, 0, 0, 983446, 0, 5249, 0, - 0, 8756, 0, 0, 41694, 120585, 92349, 0, 0, 0, 69685, 123549, 983450, - 113794, 0, 6808, 41319, 13125, 66332, 127977, 0, 2290, 0, 983418, 0, 0, - 3943, 0, 41205, 0, 0, 0, 0, 5352, 0, 0, 41207, 0, 7384, 69647, 41204, - 123552, 41209, 69637, 0, 43607, 0, 0, 5420, 0, 10134, 0, 0, 4018, 7150, - 0, 0, 0, 0, 0, 129606, 2561, 65023, 0, 7148, 12076, 0, 0, 129201, 0, - 6276, 1706, 0, 0, 7146, 0, 128277, 41819, 74991, 0, 10847, 41822, 72248, - 860, 0, 0, 0, 69641, 10753, 41820, 126118, 0, 71898, 0, 92617, 128567, 0, - 121514, 43016, 0, 0, 92225, 0, 0, 0, 0, 4022, 0, 0, 110807, 0, 41691, 0, - 75060, 11866, 0, 65292, 0, 110812, 0, 3911, 110811, 110808, 110809, 0, - 125191, 7000, 3904, 118997, 72261, 0, 0, 0, 13123, 10846, 0, 0, 0, 0, 0, - 74082, 0, 123542, 0, 0, 3777, 128329, 0, 9636, 71726, 0, 0, 9367, 593, 0, - 3999, 0, 41713, 0, 0, 67677, 0, 0, 0, 9763, 120280, 120283, 12347, 124, - 12981, 41127, 92527, 0, 0, 0, 0, 0, 43987, 0, 0, 1769, 41715, 2463, 2151, - 0, 0, 71222, 1538, 93044, 0, 0, 123543, 7795, 120300, 0, 92493, 10955, 0, - 0, 72375, 78208, 9498, 78207, 127033, 78210, 120288, 3939, 120290, - 120285, 8943, 120287, 120286, 120297, 4491, 120299, 42602, 120293, - 120292, 120295, 120294, 0, 0, 0, 0, 0, 0, 1511, 9324, 0, 0, 0, 0, 0, - 64536, 0, 0, 0, 124935, 6822, 12862, 0, 0, 42143, 41828, 0, 917629, - 70864, 118879, 0, 0, 0, 41826, 128413, 0, 0, 13279, 7917, 0, 0, 0, 0, 0, - 92800, 92332, 0, 0, 43515, 0, 0, 0, 4013, 0, 66980, 0, 72224, 125266, 0, - 68243, 2432, 92834, 0, 0, 0, 0, 69952, 0, 0, 0, 10949, 0, 0, 0, 0, 0, 0, - 0, 128574, 43233, 0, 42517, 0, 0, 0, 0, 0, 64468, 119359, 6474, 119358, - 43497, 12656, 128122, 119353, 0, 1665, 0, 0, 0, 64512, 0, 0, 5256, 0, 0, - 0, 2859, 123563, 0, 0, 0, 0, 92801, 128220, 0, 770, 0, 811, 0, 0, 917551, - 42244, 64427, 0, 72222, 0, 3895, 0, 74341, 12087, 0, 42859, 10193, 3116, - 7747, 0, 0, 43496, 0, 0, 0, 0, 41877, 0, 65382, 64614, 0, 64296, 0, 6345, - 0, 2663, 0, 121234, 0, 0, 10150, 0, 64308, 1522, 597, 0, 0, 41201, 64731, - 0, 0, 41198, 123537, 71483, 3092, 0, 0, 4783, 71448, 92213, 0, 0, 10812, - 0, 0, 0, 3078, 0, 0, 0, 0, 0, 71703, 394, 3088, 0, 0, 0, 3991, 0, 129072, - 0, 424, 67652, 72377, 0, 0, 0, 0, 0, 0, 42231, 2209, 128215, 72983, 0, - 41840, 129136, 5344, 1298, 0, 13155, 0, 128973, 41838, 0, 8488, 1003, - 41837, 0, 0, 0, 48, 0, 0, 8493, 0, 0, 0, 65487, 118550, 8465, 10332, - 13172, 0, 0, 10449, 126989, 127014, 69606, 69447, 3984, 129159, 0, 0, 0, - 0, 0, 0, 0, 0, 64758, 0, 100947, 0, 0, 9096, 0, 0, 9172, 128545, 0, 0, - 5955, 67666, 0, 0, 0, 0, 0, 74426, 3926, 71734, 0, 8798, 100946, 92165, - 0, 0, 120696, 0, 0, 0, 118805, 10353, 10417, 0, 123560, 0, 128629, 4019, - 0, 0, 0, 8219, 68402, 0, 0, 121301, 128218, 0, 0, 0, 0, 0, 0, 0, 110625, - 42474, 10642, 3909, 9950, 0, 128139, 69619, 68678, 92917, 0, 1049, 43517, - 65707, 11943, 41806, 0, 68635, 3921, 0, 11775, 121352, 69820, 1038, - 42303, 9823, 0, 2145, 4008, 68624, 0, 121025, 0, 0, 5153, 41805, 0, 0, - 763, 9211, 0, 0, 0, 0, 2188, 127142, 0, 0, 65179, 0, 8621, 0, 118878, 0, - 0, 0, 0, 182, 0, 0, 0, 0, 72978, 9058, 8489, 0, 66935, 5969, 65909, - 10848, 4570, 0, 128614, 4255, 0, 0, 41189, 4003, 69785, 68109, 13293, - 41192, 0, 0, 42251, 0, 0, 126085, 11287, 6128, 121315, 11034, 0, 68207, - 0, 65506, 42382, 0, 0, 66872, 9932, 43516, 0, 125098, 0, 41814, 0, 71234, - 64835, 12117, 127040, 127041, 10540, 127043, 9063, 78000, 0, 0, 0, 12897, - 0, 0, 0, 6065, 0, 0, 0, 8692, 41186, 41816, 0, 41818, 41187, 0, 42196, 0, - 110690, 110691, 126115, 0, 0, 125235, 4710, 0, 5956, 7621, 110641, 92624, - 4705, 716, 74918, 110693, 4704, 124916, 0, 127112, 161, 67468, 0, 0, - 4706, 0, 0, 0, 4709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1700, 119223, 0, 0, - 128119, 4004, 0, 73071, 69383, 69914, 8506, 128237, 0, 126996, 2538, 937, - 0, 4734, 0, 0, 0, 0, 0, 4729, 0, 0, 0, 4728, 0, 72809, 120644, 0, 8109, - 43105, 11249, 4730, 447, 0, 1513, 4733, 0, 0, 0, 0, 0, 0, 0, 8565, 2469, - 0, 6690, 0, 0, 43439, 78218, 43103, 78217, 2674, 0, 11922, 0, 0, 3510, 0, - 129368, 0, 5605, 42095, 126572, 0, 9098, 120512, 0, 121272, 68891, 74570, - 0, 67708, 0, 119346, 0, 5959, 0, 0, 66275, 43371, 0, 0, 0, 0, 0, 12769, - 69793, 0, 1283, 0, 4779, 0, 3719, 4006, 0, 0, 71186, 68204, 124957, 0, - 119331, 43028, 65493, 0, 125058, 5962, 65485, 92616, 0, 43501, 5827, 0, - 120951, 0, 65494, 0, 129365, 0, 0, 43879, 0, 0, 0, 0, 983205, 65467, 0, - 0, 0, 0, 521, 0, 0, 983928, 0, 0, 483, 7096, 0, 0, 928, 0, 0, 0, 0, - 92983, 3989, 73972, 122980, 0, 0, 0, 12145, 0, 73932, 0, 0, 3769, 67460, - 0, 0, 0, 0, 0, 65290, 92223, 0, 65855, 0, 0, 0, 0, 128811, 0, 0, 0, 0, 0, - 0, 73838, 0, 0, 13007, 67506, 0, 0, 12661, 7608, 75032, 12213, 0, 0, 0, - 0, 12195, 4001, 3112, 67474, 0, 7590, 0, 0, 421, 0, 0, 0, 4130, 127775, - 7595, 42588, 7600, 0, 0, 0, 0, 65851, 42607, 0, 92403, 8680, 0, 42134, 0, - 0, 2846, 92605, 0, 0, 0, 0, 12979, 0, 0, 92558, 3740, 69843, 120437, 0, - 120451, 65923, 120435, 0, 120434, 0, 93800, 3118, 74265, 93795, 93816, - 93823, 93797, 8127, 92912, 93792, 7943, 93821, 93799, 10618, 2584, 93793, - 0, 0, 9998, 0, 0, 0, 66350, 0, 0, 0, 121374, 8279, 128169, 0, 4975, - 70075, 0, 118675, 1631, 0, 0, 0, 6290, 128994, 66386, 0, 64645, 0, 0, 0, - 0, 0, 9242, 93807, 93802, 93801, 983269, 93803, 3122, 93804, 7793, 0, 0, - 0, 0, 12604, 92885, 6615, 67650, 0, 3986, 44025, 0, 8912, 0, 7409, 0, 0, - 0, 0, 0, 0, 8540, 11498, 0, 0, 0, 0, 0, 13060, 120682, 0, 0, 0, 0, 0, - 121345, 0, 0, 7020, 120353, 3765, 92881, 0, 1606, 120348, 120351, 3093, - 110593, 0, 0, 0, 0, 0, 0, 92892, 120337, 69402, 120339, 4023, 120333, - 120332, 120335, 92250, 120345, 12810, 120347, 120346, 4455, 120340, - 120343, 120342, 66660, 0, 0, 0, 0, 113720, 13089, 74355, 120329, 120328, - 42758, 12196, 128429, 0, 0, 0, 0, 128867, 94179, 0, 3120, 9797, 0, 0, - 11086, 10389, 0, 101025, 4895, 128153, 124941, 4359, 0, 0, 3509, 70037, - 486, 0, 0, 0, 0, 0, 7004, 0, 0, 0, 0, 4855, 128200, 0, 0, 0, 0, 0, 0, - 10381, 70839, 0, 0, 0, 0, 125121, 70837, 125070, 129431, 983377, 983365, - 0, 983364, 0, 120063, 0, 0, 0, 75048, 0, 74900, 0, 0, 120978, 12161, - 983356, 0, 10339, 0, 77808, 0, 0, 917846, 77806, 0, 43032, 125010, 0, - 983383, 12671, 11384, 0, 0, 120901, 64797, 0, 5820, 0, 0, 0, 0, 0, - 120650, 42137, 9893, 8851, 12664, 0, 0, 13192, 0, 41799, 65530, 0, 0, - 43039, 3114, 0, 0, 0, 0, 0, 926, 77803, 72004, 77805, 77799, 77800, - 77801, 77802, 43037, 41798, 77797, 77798, 123214, 41801, 0, 0, 0, 4200, - 12699, 8331, 70118, 3091, 92980, 66298, 70293, 8360, 0, 78044, 0, 4229, - 64543, 126227, 65563, 0, 129310, 2861, 43793, 10095, 121428, 9195, - 121381, 121132, 0, 129578, 0, 0, 43041, 0, 43794, 0, 83167, 0, 43797, - 8209, 0, 129132, 12973, 0, 0, 0, 0, 0, 121235, 5760, 0, 743, 0, 0, 0, - 118712, 0, 0, 83170, 128589, 129537, 0, 119063, 0, 0, 0, 19919, 0, 64532, - 0, 43710, 0, 0, 9483, 71115, 0, 43697, 0, 0, 83211, 0, 0, 0, 7247, 0, 0, - 0, 0, 0, 113674, 0, 7471, 120823, 128743, 12682, 0, 0, 65679, 983144, 0, - 0, 83201, 1099, 74241, 0, 10501, 0, 0, 113743, 0, 64743, 128476, 67663, - 0, 0, 92219, 0, 83197, 64897, 9973, 1818, 0, 0, 8272, 127812, 0, 4218, - 3087, 0, 127234, 122935, 101300, 65181, 9954, 10465, 0, 0, 0, 9106, 0, - 67406, 0, 0, 0, 0, 43038, 0, 0, 265, 70208, 0, 0, 0, 0, 0, 69405, 0, 59, - 0, 0, 0, 0, 126239, 41810, 0, 126492, 0, 41809, 41888, 0, 41795, 0, - 42213, 0, 0, 43033, 511, 42963, 0, 13127, 0, 0, 0, 0, 111107, 100489, - 4467, 41812, 41215, 0, 41211, 917783, 4453, 69575, 0, 129883, 0, 983412, - 41213, 92864, 118716, 0, 0, 129730, 41841, 6617, 130041, 0, 92995, 462, - 0, 10493, 0, 55248, 0, 0, 74471, 6644, 0, 0, 0, 983388, 100484, 9581, - 67104, 3098, 0, 0, 983415, 125250, 0, 120621, 0, 0, 0, 129584, 101011, 0, - 118789, 74473, 3755, 64661, 7748, 7235, 3966, 0, 0, 127510, 0, 0, 0, - 5726, 66456, 42175, 100486, 0, 42212, 92681, 121443, 2851, 43017, 120108, - 121056, 4373, 0, 0, 9587, 0, 6671, 128840, 3100, 0, 917790, 0, 0, 0, - 917789, 70209, 8190, 12083, 917791, 0, 6689, 64629, 0, 0, 0, 4419, - 917787, 101017, 0, 69851, 0, 0, 8891, 3080, 0, 2347, 0, 0, 8990, 0, - 121201, 0, 92528, 249, 129008, 0, 69424, 0, 0, 0, 55253, 0, 0, 11173, - 995, 0, 121047, 119861, 0, 73708, 0, 0, 19945, 0, 558, 983399, 12273, 0, - 983881, 0, 69912, 120861, 129492, 67274, 94178, 0, 68019, 43030, 3129, 0, - 2102, 0, 0, 121450, 0, 7725, 0, 11120, 0, 126111, 69246, 0, 0, 0, 41894, - 0, 41898, 0, 41893, 74921, 128678, 3540, 11848, 0, 73005, 120848, 0, 0, - 126113, 73959, 0, 0, 128735, 120858, 0, 0, 9699, 128656, 41896, 0, 83196, - 69230, 74951, 0, 72736, 0, 0, 3095, 983689, 11946, 983885, 0, 0, 0, 0, 0, - 113677, 3672, 111309, 0, 0, 0, 128539, 8890, 93826, 0, 128182, 0, 0, 0, - 126568, 0, 0, 983617, 9516, 983441, 72109, 0, 42220, 0, 4450, 0, 11547, - 43417, 128542, 356, 0, 0, 0, 0, 64901, 0, 0, 0, 0, 0, 0, 111302, 65940, - 2541, 71231, 0, 123215, 126470, 3549, 0, 0, 0, 2743, 0, 0, 0, 9097, - 128896, 43015, 0, 0, 776, 2524, 0, 8573, 100665, 126494, 0, 0, 42694, - 71122, 8952, 10814, 118818, 0, 43646, 128598, 66944, 0, 0, 128380, - 100663, 0, 65853, 42707, 1897, 93071, 0, 0, 71907, 69410, 0, 125106, 0, - 0, 0, 68473, 66778, 43573, 92638, 0, 0, 0, 120955, 73986, 0, 0, 43022, 0, - 74841, 0, 67714, 0, 0, 0, 0, 0, 4553, 0, 0, 0, 0, 0, 19921, 0, 0, 983687, - 4567, 41891, 0, 983819, 55249, 194663, 0, 194662, 0, 194665, 43042, - 121291, 1377, 12869, 0, 0, 9250, 0, 0, 0, 129779, 125039, 194642, 0, - 74995, 0, 194644, 0, 0, 101328, 194668, 121166, 0, 70275, 1898, 69556, 0, - 0, 802, 0, 0, 0, 6648, 0, 2528, 0, 0, 194646, 194625, 101330, 68804, 844, - 0, 68824, 0, 68818, 194650, 0, 0, 0, 983743, 65464, 0, 0, 0, 0, 83221, 0, - 0, 100680, 42954, 0, 64371, 70665, 0, 194654, 0, 0, 0, 0, 0, 6196, 6945, - 0, 0, 0, 120491, 0, 68846, 6210, 0, 70274, 0, 0, 0, 68067, 68834, 194715, - 588, 9760, 129112, 0, 983723, 119505, 0, 127992, 0, 0, 118905, 0, 0, - 92485, 110839, 69396, 0, 3394, 70734, 194639, 0, 0, 0, 0, 0, 0, 194656, - 7817, 1841, 11055, 195001, 194979, 194983, 127011, 67403, 194987, 7701, - 194998, 0, 194995, 1946, 121404, 0, 0, 917631, 0, 0, 10934, 0, 70376, 0, - 0, 8071, 3538, 0, 2287, 65328, 0, 0, 7614, 0, 0, 0, 12009, 43968, 0, - 67852, 0, 0, 10841, 123640, 0, 0, 0, 0, 8960, 0, 0, 65317, 128829, 0, 0, - 70374, 0, 0, 0, 65315, 0, 0, 0, 0, 0, 119621, 0, 11849, 12447, 0, 0, - 110741, 0, 0, 0, 129976, 42767, 0, 0, 0, 43695, 120520, 11975, 194941, - 983448, 0, 2555, 0, 128640, 70070, 42936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 66714, 0, 0, 70076, 65596, 121034, 66710, 67658, 0, 126994, 65338, - 7792, 0, 0, 67871, 119027, 0, 8233, 43572, 0, 0, 0, 3442, 110933, 2841, - 12543, 0, 1473, 42820, 64329, 127832, 917772, 126126, 7937, 0, 1048, 0, - 0, 983943, 0, 3406, 1054, 100701, 1040, 65450, 0, 92329, 1069, 917763, - 128367, 128940, 0, 917765, 0, 983724, 9693, 110873, 0, 0, 0, 983948, - 4353, 118653, 1059, 127530, 0, 0, 0, 127093, 118862, 120500, 10646, - 118708, 100710, 917762, 70424, 74830, 0, 0, 983720, 10221, 100706, 68255, - 0, 0, 74346, 119619, 100707, 64945, 12921, 0, 0, 0, 0, 0, 983795, 43020, - 0, 0, 74254, 0, 983785, 0, 0, 983792, 0, 71954, 0, 0, 0, 0, 122625, 0, - 120503, 70663, 0, 2755, 0, 0, 0, 4857, 0, 4428, 0, 0, 983791, 0, 0, 0, - 43842, 0, 122899, 0, 7978, 0, 70392, 127080, 11924, 43812, 0, 65015, - 67472, 563, 68340, 0, 12798, 0, 100727, 0, 0, 0, 74110, 0, 94051, 0, 694, - 0, 9876, 0, 119168, 0, 0, 0, 92361, 0, 0, 7229, 0, 0, 0, 0, 64811, 0, - 119087, 126478, 0, 7381, 0, 2525, 4852, 11586, 68465, 41605, 126089, 0, - 11582, 7151, 10155, 92578, 188, 0, 11592, 0, 74015, 0, 0, 4858, 122645, - 0, 0, 4861, 0, 2786, 121431, 4856, 8051, 0, 119609, 0, 113797, 71133, 0, - 78448, 0, 0, 67842, 68084, 0, 0, 0, 0, 0, 10234, 5843, 0, 71865, 66728, - 0, 3157, 0, 0, 75035, 72788, 983750, 0, 10822, 5149, 129517, 0, 65142, - 129454, 4565, 0, 0, 0, 12657, 0, 0, 386, 0, 8834, 120974, 0, 43574, 0, 0, - 0, 70113, 7220, 11839, 124984, 74883, 194752, 0, 65241, 74503, 8160, 0, - 194753, 0, 0, 0, 0, 0, 121265, 6847, 13303, 0, 0, 194755, 0, 118865, 0, - 194761, 0, 0, 74505, 0, 0, 0, 100518, 194721, 8780, 100512, 0, 68745, - 110626, 66697, 0, 2672, 3735, 983641, 0, 68752, 11205, 10724, 41202, 0, - 100714, 0, 0, 0, 0, 194765, 3842, 0, 78183, 12442, 78182, 9791, 78181, 0, - 42516, 67730, 64821, 195059, 78178, 0, 78464, 119219, 78465, 127466, - 194690, 195063, 0, 0, 0, 0, 78540, 78541, 78538, 1962, 78490, 78476, - 65930, 11660, 0, 2072, 0, 0, 78544, 194704, 78542, 10669, 110859, 110860, - 110857, 110858, 129749, 110856, 4105, 0, 194699, 0, 0, 0, 13148, 195068, - 78479, 9226, 0, 0, 10765, 127486, 71919, 6263, 195050, 0, 195041, 0, 0, - 0, 0, 0, 0, 92312, 7886, 0, 6682, 0, 6680, 195042, 126473, 195052, 6679, - 74412, 0, 72206, 74421, 66281, 0, 0, 127478, 0, 0, 92861, 6681, 0, 12693, - 0, 0, 0, 0, 0, 65442, 129055, 0, 9989, 74415, 194673, 0, 0, 983788, 0, 0, - 0, 0, 7042, 127240, 119026, 7968, 0, 983768, 194741, 194736, 983793, 0, - 69889, 74389, 128696, 0, 0, 128979, 5781, 0, 78199, 0, 124145, 11091, 0, - 2719, 0, 0, 0, 64495, 0, 0, 0, 65169, 42845, 0, 128551, 983766, 2200, - 72435, 0, 0, 0, 917855, 66670, 0, 983709, 0, 0, 0, 7902, 0, 65265, 0, 0, - 0, 0, 0, 0, 0, 12994, 0, 10828, 983974, 0, 4307, 3482, 0, 0, 72389, 0, - 64299, 74573, 41194, 7343, 0, 0, 41195, 0, 8169, 0, 8841, 66770, 516, - 72981, 41197, 119051, 34, 128850, 120186, 11504, 1612, 120187, 120182, - 120181, 120184, 12001, 120178, 120177, 120180, 120179, 71966, 120173, - 7749, 120175, 0, 1758, 0, 10667, 0, 120197, 0, 1935, 11517, 120193, - 120196, 78925, 120190, 120189, 120192, 120191, 1217, 64702, 128075, 825, - 0, 129824, 0, 0, 66748, 0, 11050, 0, 123187, 0, 0, 74554, 110577, 0, - 8677, 123188, 11313, 123185, 3403, 0, 123186, 64364, 92683, 0, 0, 0, 0, - 123189, 0, 0, 983880, 0, 69408, 41850, 0, 3433, 127965, 0, 1594, 65607, - 0, 66392, 0, 129291, 74565, 41353, 125119, 78926, 0, 0, 0, 918, 127280, - 41351, 0, 0, 12140, 0, 12668, 72395, 0, 128753, 0, 127302, 0, 127288, - 129497, 127235, 573, 0, 0, 11417, 0, 127283, 0, 0, 0, 72410, 0, 11482, 0, - 3981, 74345, 0, 0, 0, 0, 0, 0, 125238, 0, 0, 42195, 0, 123190, 129764, - 64602, 0, 0, 121366, 0, 121061, 128690, 0, 8423, 0, 448, 66907, 9717, 0, - 0, 0, 0, 0, 0, 0, 71910, 129898, 0, 0, 120679, 65013, 78169, 0, 72390, 0, - 0, 127917, 0, 74892, 0, 0, 127798, 0, 0, 66982, 0, 0, 0, 12197, 125074, - 0, 121447, 0, 0, 0, 0, 0, 0, 0, 74563, 64828, 11419, 0, 8592, 0, 0, 0, - 11381, 0, 0, 74529, 0, 0, 83254, 0, 72796, 0, 83257, 0, 0, 0, 129437, - 65672, 0, 0, 0, 0, 0, 0, 0, 0, 9505, 0, 0, 756, 0, 125243, 100358, - 110852, 7261, 0, 0, 0, 0, 0, 64401, 65830, 41365, 0, 0, 0, 127834, 0, 0, - 0, 0, 0, 74626, 123155, 11578, 0, 2170, 0, 0, 0, 0, 74568, 0, 113684, - 1794, 68310, 120218, 120219, 120220, 120221, 120222, 120223, 3617, - 120011, 64886, 94061, 78202, 120213, 66999, 10225, 983060, 0, 65223, - 983058, 0, 0, 4452, 127779, 0, 0, 66981, 0, 0, 0, 11425, 0, 0, 1231, 0, - 0, 0, 124121, 8192, 124118, 0, 0, 10616, 8694, 0, 68867, 128332, 123595, - 120200, 120201, 120202, 120203, 9878, 120205, 119626, 120207, 0, 8799, - 42131, 0, 127163, 0, 120198, 120199, 837, 120015, 72384, 0, 983836, 2180, - 11427, 0, 78154, 0, 70171, 0, 78150, 42606, 0, 119615, 78147, 64637, - 78146, 43060, 78145, 125009, 3392, 0, 194783, 119067, 119650, 65468, - 43498, 126083, 0, 0, 0, 194928, 194937, 194938, 64681, 194930, 83264, - 92451, 0, 194955, 83262, 983751, 8973, 0, 194967, 70177, 194968, 0, 4800, - 195018, 0, 0, 11820, 6852, 122981, 0, 4802, 4111, 111268, 0, 4805, - 127308, 68193, 7885, 121220, 0, 0, 0, 4767, 0, 0, 0, 0, 0, 125234, - 100366, 43453, 0, 41340, 0, 0, 10005, 65856, 41333, 0, 9518, 0, 0, 0, - 42520, 100850, 0, 0, 917562, 100506, 0, 0, 0, 0, 0, 0, 9167, 42151, - 124958, 0, 2026, 100848, 124139, 0, 100534, 12768, 0, 7582, 0, 0, 0, 0, - 129557, 0, 120539, 68879, 0, 43547, 119992, 8546, 126071, 78520, 7604, - 78518, 78519, 78514, 78517, 78511, 78512, 73802, 128140, 0, 6708, 10535, - 0, 68218, 55274, 68221, 92296, 0, 0, 0, 0, 0, 72385, 0, 0, 0, 73727, 0, - 120706, 74442, 66943, 0, 0, 4351, 0, 119887, 119888, 0, 119886, 119891, - 68866, 119889, 11433, 119895, 119896, 0, 119894, 65578, 194693, 0, 0, - 983070, 10681, 0, 0, 128737, 0, 983111, 0, 6722, 129364, 0, 119997, - 41546, 64860, 68394, 0, 41549, 118619, 72386, 0, 0, 0, 0, 64710, 41547, - 0, 0, 0, 78530, 78532, 78528, 78529, 71343, 78527, 78523, 78525, 3537, - 119908, 119905, 7155, 2264, 0, 78533, 67755, 0, 0, 0, 0, 0, 0, 0, 64715, - 0, 0, 537, 0, 4179, 0, 0, 0, 0, 0, 0, 0, 0, 12081, 0, 0, 4048, 7053, 0, - 0, 70459, 0, 124975, 0, 3059, 0, 0, 43491, 983833, 0, 0, 127993, 4100, - 920, 1811, 1355, 0, 0, 64383, 10078, 69398, 0, 118651, 0, 65870, 0, - 129565, 0, 72400, 42918, 0, 66789, 0, 12865, 0, 73938, +static const unsigned short dawg_codepoint_to_pos_index2[] = { + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 29174, 13037, 26950, 24736, 10779, 26523, 358, 1041, 19550, + 27163, 2511, 26774, 8150, 15996, 13206, 29017, 10563, 10548, 10560, + 10557, 10542, 10539, 10554, 10551, 10566, 10545, 7753, 27749, 19776, + 12475, 13751, 26948, 8149, 18159, 18205, 18215, 18231, 18246, 18291, + 18295, 18312, 18326, 18355, 18360, 18372, 18390, 18399, 18415, 18465, + 18473, 18476, 18496, 18519, 18548, 18587, 18598, 18607, 18610, 18624, + 19518, 27073, 27177, 6518, 20535, 13722, 18716, 18766, 18786, 18809, + 18845, 18904, 18912, 18930, 18949, 18986, 18992, 19006, 19044, 19057, + 19081, 19138, 19149, 19155, 19193, 19234, 19307, 19355, 19369, 19378, + 19386, 19402, 19466, 33652, 27135, 32321, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 24729, + 16349, 5830, 26815, 9647, 34209, 4636, 27731, 10531, 8344, 13111, 19565, + 24711, 28968, 26996, 22169, 10248, 26786, 29740, 29739, 4, 22895, 26671, + 22898, 5826, 29743, 21136, 27214, 33780, 33778, 33786, 16352, 18188, + 18189, 18177, 18191, 18170, 18172, 18193, 18216, 18277, 18278, 18249, + 18264, 18342, 18343, 18332, 18330, 18288, 18413, 18454, 18455, 18422, + 18440, 18429, 23603, 18438, 18579, 18580, 18549, 18552, 18619, 18540, + 19224, 18747, 18748, 18736, 18750, 18727, 18729, 18753, 18787, 18878, + 18879, 18848, 18863, 18967, 18968, 18950, 18952, 18903, 19076, 19120, + 19121, 19082, 19106, 19089, 10690, 19104, 19342, 19345, 19310, 19313, + 19397, 19256, 19388, 18175, 18734, 18160, 18717, 18185, 18744, 18220, + 18792, 18218, 18789, 18224, 18797, 18219, 18791, 18238, 18817, 18235, + 18811, 18267, 18867, 18280, 18881, 18259, 18858, 18274, 18875, 18258, + 18857, 18297, 18914, 18300, 18917, 18304, 18922, 18296, 18913, 18315, + 18933, 18322, 18942, 18336, 18964, 18334, 18959, 18345, 18970, 18339, + 18961, 18329, 18833, 18636, 19422, 18356, 18987, 18361, 18993, 19005, + 18386, 19023, 18382, 19010, 18384, 19013, 18379, 19020, 18381, 19031, + 18408, 19069, 18400, 19058, 18402, 19062, 19077, 18290, 18886, 18418, + 19099, 18457, 19123, 18435, 19095, 18637, 19425, 18485, 19172, 18477, + 19156, 18478, 19158, 18502, 19194, 18501, 19200, 18499, 19198, 18497, + 19196, 18520, 19235, 18523, 19239, 18530, 19251, 18576, 19339, 18568, + 19329, 18582, 19347, 18583, 19338, 18559, 19320, 18573, 19334, 18599, + 19370, 18611, 19387, 18612, 18627, 19403, 18630, 19409, 18626, 19406, + 19036, 18775, 18211, 18206, 18767, 18543, 19259, 18460, 18222, 18795, + 18198, 18243, 18239, 18812, 19264, 18494, 18518, 18459, 18292, 18907, + 18303, 18310, 18948, 18353, 18346, 18371, 19004, 19009, 19032, 18537, + 18406, 19063, 18421, 18447, 19113, 18462, 19135, 18471, 19146, 18713, + 18544, 19260, 18289, 18653, 19247, 18529, 19248, 18528, 18561, 19322, + 18586, 18591, 18616, 19392, 18633, 19412, 18282, 18284, 18896, 18901, + 18706, 18545, 19261, 18652, 18705, 18707, 18708, 18645, 18655, 18245, + 18233, 18839, 18389, 18380, 19043, 18414, 18403, 19080, 18183, 18742, + 18333, 18951, 18428, 19088, 18551, 19312, 18556, 19317, 18555, 19316, + 18553, 19314, 18554, 19315, 19296, 18171, 18728, 18167, 18724, 18195, + 18756, 18305, 18923, 18298, 18915, 18362, 18994, 18436, 19102, 18437, + 19103, 18283, 18898, 18989, 18244, 18232, 18838, 18299, 18916, 18324, + 18606, 18407, 19068, 18173, 18730, 18194, 18755, 18439, 19105, 18169, + 18726, 18190, 18749, 18263, 18862, 18279, 18880, 18327, 18958, 18344, + 18969, 18434, 19094, 18456, 19122, 18482, 19162, 18487, 19173, 18558, + 19319, 18581, 19346, 18500, 19199, 18522, 19237, 18623, 19401, 18316, + 18934, 18404, 18816, 18464, 19137, 18635, 19416, 18166, 18723, 18247, + 18846, 18430, 19090, 18443, 19109, 18431, 19091, 18432, 19092, 18620, + 19398, 19012, 19061, 19238, 18830, 18843, 19154, 18192, 18225, 18798, + 18374, 18524, 19206, 19411, 18306, 18924, 18212, 18585, 18539, 18281, + 18883, 18359, 18991, 18512, 19152, 18489, 19176, 18622, 19396, 19288, + 18758, 19289, 18774, 19126, 18790, 18813, 18821, 19185, 19215, 19219, + 19132, 19180, 19182, 18805, 18831, 18921, 19222, 18682, 18928, 19192, + 19265, 18941, 18947, 18971, 18982, 18660, 19018, 19007, 19026, 19033, + 19291, 19292, 19052, 19065, 19074, 18693, 18778, 18667, 18804, 19148, + 19276, 19279, 19282, 19167, 19168, 19163, 19183, 18669, 18661, 19212, + 18889, 18832, 19232, 18893, 19283, 19250, 19308, 19349, 19362, 19285, + 19300, 19293, 18700, 19415, 19405, 18895, 18897, 18709, 18711, 18650, + 18702, 18648, 18680, 18803, 18683, 18689, 18988, 19298, 18662, 19151, + 18710, 18654, 18840, 18826, 18841, 19303, 19252, 19302, 18910, 19040, + 19041, 18647, 18649, 19266, 19267, 23222, 23223, 23231, 23253, 23280, + 23283, 23178, 23300, 23302, 23151, 23094, 23308, 23005, 23159, 23161, + 23137, 23110, 23157, 23139, 23163, 23310, 23096, 23086, 5759, 23314, + 23140, 23004, 23109, 23135, 23126, 23132, 23131, 23307, 23117, 23038, + 23037, 23309, 23095, 23150, 23148, 4629, 10885, 27334, 25266, 28928, + 10944, 23164, 23087, 23221, 23233, 23260, 23301, 23257, 23101, 23116, + 23144, 23129, 23106, 23316, 23315, 23313, 23311, 23093, 23122, 23134, + 23124, 23127, 23128, 23147, 23146, 23145, 23130, 23156, 23007, 23107, + 23008, 23108, 23166, 23149, 23123, 7961, 7759, 7843, 8125, 8067, 8087, + 7769, 7868, 7865, 7974, 8112, 7894, 7775, 8140, 7893, 7895, 7777, 7977, + 8133, 7780, 8095, 7781, 7962, 7760, 8052, 8108, 8046, 7976, 8049, 8135, + 7899, 8092, 8076, 8091, 8096, 7871, 7867, 8111, 7782, 7845, 8085, 8139, + 7772, 7980, 7776, 7844, 7771, 7978, 8129, 8072, 8066, 7896, 8128, 8116, + 8064, 8115, 8063, 8103, 7979, 8119, 8123, 8147, 8141, 7882, 7963, 7761, + 7971, 7970, 7973, 7972, 7773, 7908, 7892, 8045, 8078, 7975, 7768, 8053, + 8134, 7966, 8099, 8050, 7909, 8146, 8041, 8100, 8098, 8104, 7870, 7765, + 7887, 8114, 7876, 7875, 7879, 7880, 7888, 7877, 7886, 7993, 8001, 8006, + 8014, 8017, 7999, 8031, 8033, 8035, 8020, 8023, 8038, 8039, 13936, 14200, + 13831, 14067, 14018, 14014, 13925, 14182, 35762, 35762, 14257, 14207, + 14208, 14206, 14262, 13939, 35762, 35762, 35762, 35762, 14222, 13952, + 13829, 13805, 13862, 13852, 13876, 35762, 13908, 35762, 13923, 13898, + 14114, 13808, 13935, 13933, 13931, 13853, 13937, 13832, 13929, 13863, + 13932, 13938, 13940, 13941, 13942, 13899, 13928, 13909, 35762, 13911, + 13930, 13914, 13926, 13934, 13927, 13878, 13868, 13919, 14064, 14079, + 14104, 14123, 14134, 14039, 14199, 14197, 14069, 14070, 14201, 14080, + 14194, 14105, 14145, 14202, 14203, 14204, 14205, 14172, 14185, 14186, + 14196, 14192, 14195, 14125, 14183, 14198, 14184, 14147, 14110, 14130, + 14181, 14143, 14171, 13947, 14259, 14218, 14226, 14224, 14225, 14034, + 14035, 13999, 14010, 14066, 14009, 14191, 14012, 14068, 14011, 14146, + 14008, 14189, 8225, 8319, 8203, 8297, 8199, 8293, 8197, 8291, 8195, 8289, + 8224, 8318, 8194, 8288, 13998, 14037, 14015, 14013, 13948, 14016, 14038, + 13913, 14193, 13943, 13912, 14190, 14036, 13945, 13946, 13944, 9913, + 9915, 9862, 9901, 9837, 9866, 9853, 9972, 9985, 9809, 9812, 9826, 9940, + 9910, 9953, 9870, 9838, 9854, 9986, 9895, 9874, 9912, 9979, 9975, 9908, + 9951, 9925, 9876, 9892, 9881, 9944, 9813, 9887, 9890, 9823, 9832, 9894, + 9902, 9829, 9855, 9958, 9956, 9906, 9969, 9961, 9875, 9974, 9966, 9997, + 10013, 10186, 10054, 10033, 10071, 10179, 10175, 10067, 10129, 10084, + 10035, 10051, 10040, 10110, 10115, 10046, 10049, 10147, 10157, 10053, + 10061, 10153, 10014, 10136, 10134, 10065, 10169, 10139, 10034, 10174, + 10166, 10072, 10074, 10021, 10060, 10162, 10025, 10012, 10172, 10185, + 10103, 10109, 10150, 10099, 10069, 10131, 10029, 9945, 10111, 9968, + 10168, 9921, 10080, 9808, 10101, 9917, 10076, 9850, 10009, 9918, 10077, + 9941, 10100, 9816, 10119, 9984, 10184, 9923, 10082, 9924, 10083, 9836, + 10161, 9817, 10124, 9946, 10112, 9948, 10114, 9938, 10097, 10217, 7836, + 7830, 7833, 7831, 7832, 7786, 7839, 9952, 10130, 9965, 10143, 9888, + 10047, 9897, 10056, 9899, 10058, 9896, 10055, 9981, 10181, 9977, 10177, + 9926, 10085, 9928, 10087, 9929, 10088, 9848, 10007, 9883, 10042, 9991, + 10190, 9814, 10116, 9844, 10003, 9891, 10050, 9825, 10149, 9963, 10141, + 9964, 10142, 9903, 10062, 9990, 10189, 9857, 10016, 9858, 10017, 9954, + 10132, 9841, 10000, 9842, 10001, 9994, 9982, 10182, 9927, 10086, 9879, + 10038, 9886, 10045, 9885, 10044, 9939, 10098, 9893, 10052, 10118, 9840, + 9999, 9839, 9998, 9989, 10188, 9914, 10073, 9949, 10127, 9950, 10128, + 9980, 10180, 9976, 10176, 9843, 10002, 9911, 10070, 9909, 10068, 9947, + 10113, 9846, 10005, 9847, 10006, 9889, 10048, 9835, 10160, 9834, 10159, + 9833, 10158, 9856, 10015, 9898, 10057, 9970, 10170, 9900, 10059, 9904, + 10063, 9905, 10064, 9932, 10091, 9931, 10090, 9937, 10096, 9930, 10089, + 9933, 10092, 9934, 10093, 9935, 10094, 9936, 10095, 9821, 10123, 9880, + 10039, 9810, 10104, 9822, 10126, 9967, 10167, 9988, 10187, 9987, 10165, + 9845, 10004, 9877, 10036, 9882, 10041, 9815, 10117, 9955, 10133, 9884, + 10043, 9868, 10027, 9872, 10031, 9878, 10037, 35762, 2429, 2436, 2420, + 2442, 2416, 2440, 2417, 2418, 2407, 2439, 2435, 2432, 2434, 2412, 2424, + 2441, 2422, 2419, 2410, 2437, 2408, 2438, 2427, 2431, 2411, 2426, 2421, + 2415, 2428, 2430, 2406, 2414, 2413, 2409, 2425, 2423, 2443, 2433, 35762, + 35762, 2493, 2405, 2445, 2446, 2444, 2497, 2404, 2466, 2469, 2479, 2457, + 2485, 2453, 2483, 2454, 2455, 2468, 2482, 2478, 2475, 2477, 2449, 2461, + 2484, 2459, 2456, 2447, 2480, 2472, 2481, 2464, 2471, 2448, 2463, 2458, + 2452, 2465, 2470, 2467, 2451, 2450, 2474, 2462, 2460, 2486, 2476, 2487, + 2473, 2496, 2494, 35762, 35762, 27207, 19558, 2495, 35762, 15349, 15352, + 15353, 15360, 15361, 15357, 15364, 15362, 15347, 15359, 15356, 15340, + 15341, 15342, 15350, 15355, 15348, 15337, 15345, 15346, 15343, 15344, + 15339, 15351, 15354, 15358, 15365, 15366, 15338, 15363, 15444, 15460, + 15448, 15446, 15447, 15449, 15462, 15458, 15452, 15454, 15450, 15451, + 15456, 15445, 15463, 15469, 15457, 15466, 15459, 15461, 15467, 15443, + 15442, 15468, 15455, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 15367, 15374, 15417, 15415, 15392, 15423, 15397, 15394, 15409, + 15434, 15383, 15377, 15419, 15389, 15421, 15388, 15395, 15399, 15373, + 15385, 15380, 15387, 15413, 15390, 15407, 15401, 15411, 35762, 35762, + 35762, 35762, 15470, 15438, 15441, 15439, 15465, 15464, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 2249, + 2283, 1081, 2284, 2285, 2248, 2392, 2393, 2259, 2390, 2391, 2582, 1056, + 1063, 2253, 2289, 2282, 2288, 2280, 2281, 2290, 2310, 2296, 2325, 2292, + 2341, 2340, 2276, 1367, 1072, 2380, 2388, 1322, 1275, 1139, 1129, 1554, + 1132, 1570, 1111, 1153, 1497, 1496, 1517, 1301, 1260, 1341, 1178, 1514, + 1419, 1596, 1453, 1466, 1445, 1193, 1475, 1591, 1101, 1247, 1328, 1325, + 1222, 1221, 1220, 2368, 1227, 1410, 1312, 1346, 1359, 1383, 1277, 1549, + 1147, 1561, 1079, 1061, 1091, 1073, 1057, 1087, 2277, 2345, 2102, 1086, + 1085, 2344, 2266, 2103, 2389, 2384, 2383, 2385, 2260, 1074, 2387, 2400, + 2402, 2399, 2398, 2395, 2394, 2397, 2396, 2403, 2401, 2257, 1068, 2382, + 1082, 1205, 1207, 1472, 1144, 1136, 1135, 1297, 1298, 1300, 1535, 1299, + 1523, 1529, 1173, 1505, 1504, 1398, 1509, 1168, 1270, 1268, 1378, 1208, + 1267, 1484, 1491, 1202, 1187, 1179, 1180, 1190, 1199, 1213, 1183, 1186, + 1436, 1422, 1433, 1430, 1423, 1431, 1426, 1309, 1429, 1454, 1457, 1458, + 1448, 1447, 1478, 1104, 1206, 1230, 1228, 1542, 1232, 1405, 1413, 1414, + 1323, 1474, 1317, 1316, 1368, 1314, 1238, 1241, 1369, 1240, 1254, 1239, + 1350, 1348, 1352, 1351, 1392, 1384, 1439, 1393, 1389, 1288, 1486, 1285, + 1278, 1279, 1500, 1558, 1335, 1588, 1534, 1585, 1338, 1557, 1541, 1216, + 1579, 1575, 1551, 1600, 1580, 1562, 1565, 1083, 1152, 2299, 2298, 2301, + 2300, 2327, 2309, 2307, 1071, 2367, 2324, 2323, 2293, 2302, 2339, 2303, + 2343, 2342, 2321, 2304, 2255, 1070, 1069, 2264, 2338, 1182, 1427, 13052, + 13054, 13051, 13050, 13047, 13046, 13049, 13048, 13055, 13053, 1467, + 1194, 1249, 2287, 2286, 1284, 29867, 29941, 29938, 29939, 29935, 29876, + 29863, 29864, 29940, 29937, 29862, 29872, 29871, 29870, 35762, 29860, + 29908, 29904, 29918, 29914, 29915, 29878, 29877, 29879, 29921, 29919, + 29880, 29911, 29912, 29916, 29917, 29909, 29881, 29893, 29920, 29900, + 29907, 29922, 29894, 29898, 29906, 29910, 29899, 29905, 29913, 29895, + 29897, 29896, 29927, 29926, 29925, 29930, 29929, 29928, 29932, 29931, + 29866, 29865, 29875, 29874, 29873, 29869, 29868, 29933, 29947, 29948, + 29934, 29945, 29944, 29943, 29942, 29924, 29923, 29946, 29861, 35762, + 35762, 29901, 29902, 29903, 1159, 1162, 1157, 1158, 1160, 1161, 1155, + 1269, 1266, 1185, 1181, 1424, 1460, 1106, 1102, 1105, 1233, 1231, 1330, + 1326, 1324, 1362, 1361, 1390, 1387, 1388, 1353, 1425, 1428, 1459, 1265, + 1263, 1456, 1420, 1264, 1138, 1137, 1219, 1218, 1217, 1553, 1552, 1564, + 1563, 1261, 1461, 1455, 1313, 31890, 31903, 31899, 31916, 31915, 31894, + 31891, 31879, 31910, 31895, 31884, 31883, 31906, 31893, 31886, 31887, + 31904, 31882, 31912, 31905, 31917, 31898, 31897, 31896, 31908, 31889, + 31892, 31907, 31913, 31902, 31901, 31881, 31909, 31914, 31880, 31888, + 31885, 31911, 31875, 31874, 31921, 31877, 31922, 31920, 31876, 31878, + 31919, 31918, 31923, 31900, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 24597, 24599, + 24596, 24595, 24592, 24591, 24594, 24593, 24600, 24598, 24632, 24619, + 24633, 24618, 24634, 24616, 24615, 24603, 24608, 24621, 24627, 24629, + 24607, 24617, 24602, 24614, 24613, 24628, 24620, 24622, 24624, 24625, + 24610, 24626, 24611, 24609, 24623, 24630, 24631, 24612, 24605, 24604, + 24606, 24584, 24585, 24586, 24582, 24579, 24580, 24581, 24583, 24587, + 24636, 24635, 24638, 24637, 24588, 24639, 24601, 35762, 35762, 24589, + 24590, 24640, 27560, 27547, 27561, 27549, 27552, 27548, 27563, 27551, + 27558, 27567, 27553, 27554, 27564, 27566, 27555, 27550, 27568, 27559, + 27565, 27562, 27556, 27557, 27570, 27571, 27574, 27569, 27575, 27572, + 27594, 27604, 27599, 27593, 27603, 27598, 27592, 27602, 27576, 27600, + 27596, 27606, 27577, 27595, 27605, 27597, 27601, 27573, 35762, 35762, + 27584, 27578, 27580, 27583, 27581, 27585, 27607, 27590, 27588, 27591, + 27587, 27589, 27582, 27586, 27579, 35762, 20924, 20911, 20913, 20912, + 20914, 20923, 20921, 20926, 20906, 20904, 20903, 20915, 20916, 20917, + 20907, 20925, 20918, 20909, 20919, 20920, 20908, 20905, 20922, 20927, + 20910, 20931, 20929, 20928, 35762, 35762, 20930, 35762, 29886, 29891, + 29887, 29889, 29885, 29884, 29888, 29892, 29883, 29882, 29890, 35762, + 35762, 35762, 35762, 35762, 1125, 1115, 1126, 1142, 1124, 1112, 1121, + 1118, 1122, 1120, 1143, 1117, 1128, 1114, 1116, 1127, 1113, 1119, 1123, + 2369, 2370, 2372, 1522, 2265, 2258, 1391, 1262, 1479, 1477, 1327, 2386, + 35762, 2254, 2256, 35762, 35762, 35762, 35762, 35762, 35762, 2311, 2332, + 2331, 2334, 2101, 2349, 1064, 1084, 1156, 1163, 1302, 1476, 1229, 1411, + 1347, 1360, 1576, 1578, 1432, 1550, 1444, 1358, 1184, 1446, 1242, 1473, + 1599, 1103, 1315, 1412, 1154, 1399, 1502, 1421, 1577, 1099, 1097, 1100, + 1400, 1503, 1524, 1485, 1329, 1248, 1098, 1304, 1303, 1349, 1259, 2291, + 2294, 2322, 2317, 2326, 1095, 1094, 2348, 1096, 1093, 2337, 2312, 2308, + 2329, 2328, 2305, 2330, 2313, 2315, 2314, 2316, 2319, 2318, 2295, 2306, + 1067, 2381, 1052, 1050, 1054, 1053, 1051, 1055, 2375, 2377, 2379, 2374, + 2376, 2378, 2252, 2251, 2250, 2320, 1076, 1075, 1088, 1606, 2261, 1605, + 2263, 1065, 1066, 2262, 1060, 2104, 10466, 10454, 10468, 10473, 10389, + 10363, 10364, 10433, 10434, 10412, 10413, 10428, 10430, 10371, 10390, + 10441, 10365, 10372, 10391, 10395, 10366, 10406, 10405, 10384, 10382, + 10418, 10369, 10373, 10403, 10401, 10419, 10425, 10424, 10377, 10376, + 10417, 10427, 10426, 10379, 10378, 10420, 10416, 10436, 10435, 10400, + 10399, 10387, 10411, 10409, 10408, 10423, 10422, 10421, 10432, 10392, + 10393, 10394, 10386, 10486, 10485, 10470, 10467, 10476, 10498, 10499, + 10488, 10489, 10494, 10495, 10482, 10492, 10500, 10477, 10483, 10493, + 10484, 10478, 10472, 10487, 10479, 10514, 10475, 10474, 10358, 10355, + 10481, 10491, 10490, 10440, 10404, 10381, 10438, 10374, 10407, 10439, + 10410, 10429, 10431, 10496, 10497, 10502, 10501, 10509, 10511, 10508, + 10507, 10504, 10503, 10506, 10505, 10512, 10510, 10356, 10471, 10370, + 10397, 10396, 10367, 10415, 10414, 10388, 10437, 10385, 10383, 10402, + 10380, 10375, 10398, 3530, 3599, 3598, 3602, 35762, 3553, 3554, 3567, + 3568, 3565, 3566, 3547, 3549, 35762, 35762, 3589, 3555, 35762, 35762, + 3590, 3556, 3540, 3537, 3581, 3580, 3569, 3579, 3578, 3583, 3582, 3571, + 3562, 3561, 3558, 3557, 3570, 3564, 3563, 3560, 3559, 3572, 35762, 3585, + 3584, 3577, 3576, 3588, 3552, 3541, 35762, 3587, 35762, 35762, 35762, + 3573, 3574, 3575, 3586, 35762, 35762, 3600, 3597, 3604, 3613, 3614, 3611, + 3612, 3607, 3608, 35762, 35762, 3615, 3605, 35762, 35762, 3616, 3606, + 3601, 3538, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 3528, + 35762, 35762, 35762, 35762, 3545, 3544, 35762, 3551, 3548, 3550, 3609, + 3610, 35762, 35762, 3623, 3625, 3622, 3621, 3618, 3617, 3620, 3619, 3626, + 3624, 3543, 3542, 3592, 3591, 3531, 3535, 3534, 3533, 3532, 3536, 3603, + 3627, 3546, 3529, 3596, 35762, 35762, 14491, 14492, 14497, 35762, 14445, + 14446, 14459, 14460, 14457, 14458, 35762, 35762, 35762, 35762, 14478, + 14447, 35762, 35762, 14477, 14448, 14442, 14441, 14439, 14438, 14463, + 14470, 14469, 14472, 14471, 14465, 14454, 14453, 14450, 14449, 14464, + 14456, 14455, 14452, 14451, 14466, 35762, 14474, 14473, 14468, 14467, + 14481, 14483, 14444, 35762, 14462, 14461, 35762, 14482, 14475, 35762, + 14476, 14480, 35762, 35762, 14494, 35762, 14498, 14503, 14504, 14501, + 14502, 35762, 35762, 35762, 35762, 14506, 14499, 35762, 35762, 14505, + 14500, 14496, 35762, 35762, 35762, 14493, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 14440, 14437, 14484, 14443, 35762, 14479, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 14516, 14518, 14515, 14514, + 14511, 14510, 14513, 14512, 14519, 14517, 14507, 14436, 14508, 14520, + 14509, 14495, 14435, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 14331, 14338, 14341, 35762, 14281, 14282, 14300, + 14301, 14298, 14299, 14293, 14295, 14357, 35762, 14328, 14283, 14358, + 35762, 14329, 14284, 14321, 14320, 14317, 14316, 14305, 14315, 14314, + 14319, 14318, 14307, 14290, 14289, 14286, 14285, 14306, 14292, 14291, + 14288, 14287, 14308, 35762, 14323, 14322, 14313, 14312, 14325, 14327, + 14326, 35762, 14303, 14302, 35762, 14297, 14309, 14310, 14311, 14324, + 35762, 35762, 14339, 14337, 14344, 14353, 14354, 14351, 14352, 14347, + 14348, 14342, 35762, 14355, 14345, 14343, 35762, 14356, 14346, 14340, + 35762, 35762, 14371, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 14294, 14296, + 14349, 14350, 35762, 35762, 14367, 14369, 14366, 14365, 14362, 14361, + 14364, 14363, 14370, 14368, 14359, 14360, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 14304, 14336, 14335, 14332, 14334, 14330, 14333, + 35762, 25865, 25864, 25869, 35762, 25814, 25815, 25833, 25834, 25831, + 25832, 25826, 25828, 35762, 35762, 25859, 25816, 35762, 35762, 25860, + 25817, 25853, 25852, 25849, 25848, 25837, 25847, 25846, 25851, 25850, + 25839, 25823, 25822, 25819, 25818, 25838, 25825, 25824, 25821, 25820, + 25840, 35762, 25855, 25854, 25845, 25844, 25857, 25813, 25811, 35762, + 25836, 25835, 35762, 25830, 25841, 25842, 25843, 25856, 35762, 35762, + 25866, 25863, 25870, 25879, 25880, 25877, 25878, 25873, 25874, 35762, + 35762, 25881, 25871, 35762, 35762, 25882, 25872, 25868, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 25867, 25800, 25801, 35762, 35762, + 35762, 35762, 25810, 25809, 35762, 25812, 25827, 25829, 25875, 25876, + 35762, 35762, 25889, 25891, 25888, 25887, 25884, 25883, 25886, 25885, + 25892, 25890, 25808, 25858, 25805, 25804, 25807, 25802, 25803, 25806, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 30505, 30522, 35762, 30473, 30474, 30481, 30482, 30477, 30478, 35762, + 35762, 35762, 30486, 30487, 30475, 35762, 30479, 30480, 30476, 30491, + 35762, 35762, 35762, 30463, 30488, 35762, 30490, 35762, 30464, 30466, + 35762, 35762, 35762, 30462, 30467, 35762, 35762, 35762, 30465, 30461, + 30493, 35762, 35762, 35762, 30492, 30495, 30472, 30471, 30470, 30469, + 30468, 30494, 30483, 30484, 30485, 30489, 35762, 35762, 35762, 35762, + 30792, 30799, 30800, 30795, 30796, 35762, 35762, 35762, 30801, 30802, + 30793, 35762, 30797, 30798, 30794, 30521, 35762, 35762, 30808, 35762, + 35762, 35762, 35762, 35762, 35762, 30397, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 30434, 30436, 30433, 30432, 30429, 30428, 30431, 30430, 30437, 30435, + 30499, 30497, 30498, 30427, 30807, 30806, 30426, 30424, 30396, 30502, + 30500, 35762, 35762, 35762, 35762, 35762, 31755, 31756, 31760, 31763, + 31754, 31718, 31719, 31731, 31732, 31727, 31728, 31722, 31724, 35762, + 31748, 31749, 31720, 35762, 31729, 31730, 31721, 31745, 31744, 31741, + 31740, 31707, 31739, 31738, 31743, 31742, 31709, 31714, 31713, 31698, + 31697, 31708, 31717, 31715, 31701, 31699, 31705, 35762, 31747, 31746, + 31737, 31736, 31751, 31752, 31712, 31711, 31704, 31703, 31702, 31726, + 31733, 31734, 31735, 31750, 35762, 35762, 31761, 31759, 31764, 31775, + 31776, 31771, 31772, 31767, 31768, 35762, 31777, 31778, 31765, 35762, + 31773, 31774, 31766, 31762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 31753, 31689, 35762, 31716, 31700, 31710, 35762, 35762, 31706, + 35762, 35762, 31723, 31725, 31769, 31770, 35762, 35762, 31785, 31787, + 31784, 31783, 31780, 31779, 31782, 31781, 31788, 31786, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 31757, 31696, 31694, 31692, 31690, + 31695, 31693, 31691, 31758, 16808, 16807, 16811, 16816, 16809, 16761, + 16762, 16782, 16783, 16778, 16779, 16773, 16775, 35762, 16799, 16800, + 16763, 35762, 16780, 16781, 16764, 16796, 16795, 16792, 16791, 16756, + 16790, 16789, 16794, 16793, 16758, 16770, 16769, 16766, 16765, 16757, + 16772, 16771, 16768, 16767, 16754, 35762, 16798, 16797, 16788, 16787, + 16803, 16804, 16760, 16759, 16753, 16752, 35762, 16777, 16784, 16785, + 16786, 16802, 35762, 35762, 16812, 16810, 16818, 16829, 16830, 16825, + 16826, 16821, 16822, 35762, 16831, 16832, 16819, 35762, 16827, 16828, + 16820, 16815, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 16805, + 16817, 35762, 35762, 35762, 35762, 35762, 35762, 16755, 16801, 35762, + 16774, 16776, 16823, 16824, 35762, 35762, 16839, 16841, 16838, 16837, + 16834, 16833, 16836, 16835, 16842, 16840, 35762, 16813, 16814, 16806, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 20866, 20868, 20873, 20871, 20823, 20797, 20799, 20843, + 20844, 20839, 20840, 20824, 20826, 35762, 20858, 20859, 20800, 35762, + 20841, 20842, 20801, 20855, 20854, 20851, 20850, 20831, 20812, 20811, + 20853, 20852, 20832, 20820, 20818, 20815, 20814, 20830, 20822, 20821, + 20817, 20816, 20833, 20829, 20857, 20856, 20849, 20848, 20861, 20862, + 20838, 20837, 20836, 20835, 20834, 20828, 20845, 20846, 20847, 20860, + 20819, 20869, 20867, 20872, 20875, 20886, 20887, 20882, 20883, 20878, + 20879, 35762, 20888, 20889, 20876, 35762, 20884, 20885, 20877, 20870, + 20813, 20874, 35762, 35762, 35762, 35762, 20809, 20810, 20804, 20772, + 20789, 20787, 20794, 20784, 20785, 20795, 20788, 20798, 20825, 20827, + 20880, 20881, 35762, 35762, 20780, 20782, 20779, 20778, 20775, 20774, + 20777, 20776, 20783, 20781, 20865, 20863, 20864, 20792, 20791, 20796, + 20786, 20790, 20793, 20773, 20806, 20805, 20807, 20802, 20803, 20808, + 35762, 28828, 28827, 28829, 35762, 28773, 28770, 28758, 28757, 28781, + 28780, 28783, 28782, 28779, 28778, 28777, 28776, 28775, 28774, 28771, + 28802, 28801, 28772, 35762, 35762, 35762, 28767, 28792, 28765, 28790, + 28815, 28805, 28764, 28789, 28766, 28791, 28812, 28813, 28806, 28759, + 28784, 28761, 28786, 28796, 28803, 28760, 28785, 28762, 28787, 28799, + 35762, 28804, 28768, 28793, 28763, 28788, 28794, 28769, 28811, 28809, + 35762, 28798, 35762, 35762, 28810, 28814, 28797, 28800, 28808, 28795, + 28807, 35762, 35762, 35762, 28826, 35762, 35762, 35762, 35762, 28846, + 28838, 28833, 28839, 28834, 28840, 35762, 28835, 35762, 28836, 28841, + 28832, 28845, 28842, 28843, 28844, 28837, 35762, 35762, 35762, 35762, + 35762, 35762, 28822, 28824, 28821, 28820, 28817, 28816, 28819, 28818, + 28825, 28823, 35762, 35762, 28830, 28831, 28847, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 31942, + 31939, 31937, 31936, 31938, 31940, 31956, 31925, 31927, 31926, 31985, + 31928, 31997, 31929, 31994, 31990, 31987, 31988, 31958, 31930, 31993, + 31992, 31989, 31991, 31959, 31924, 31965, 31962, 31931, 31963, 31932, + 31964, 31954, 31998, 31966, 31967, 31944, 31946, 31995, 31983, 31982, + 31984, 31935, 31943, 31999, 31934, 31960, 31968, 31948, 31971, 31973, + 31978, 31979, 31975, 31976, 31974, 31977, 31961, 35762, 35762, 35762, + 35762, 32000, 31980, 31972, 31981, 31970, 31969, 31945, 31953, 31952, + 31951, 31949, 31950, 31947, 31986, 31957, 31996, 31933, 32007, 32009, + 32006, 32005, 32002, 32001, 32004, 32003, 32010, 32008, 31955, 31941, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 18051, 18049, 35762, + 18050, 35762, 18064, 18079, 18083, 18063, 18073, 35762, 18065, 18080, + 18061, 18059, 18058, 18056, 18055, 18060, 18084, 18076, 18074, 18075, + 18057, 18081, 18082, 18069, 18067, 18046, 18068, 18045, 18062, 18085, + 18088, 18053, 35762, 18054, 35762, 18087, 18070, 18071, 18072, 18077, + 18066, 18089, 18078, 18115, 18097, 18102, 18098, 18100, 18110, 18111, + 18104, 18105, 18106, 18107, 18092, 18103, 18091, 18090, 35762, 35762, + 18108, 18109, 18112, 18101, 18099, 35762, 18113, 35762, 18096, 18093, + 18094, 18095, 18126, 18127, 18114, 35762, 18122, 18124, 18121, 18120, + 18117, 18116, 18119, 18118, 18125, 18123, 35762, 35762, 18042, 18041, + 18048, 18047, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 32233, 32140, 32138, 32139, 32148, 32136, + 32133, 32137, 32158, 32128, 32126, 32149, 32164, 32159, 32154, 32162, + 32153, 32157, 32156, 32132, 32141, 32124, 32123, 32051, 32052, 32050, + 32172, 32173, 32174, 32176, 32177, 32175, 32073, 32075, 32072, 32071, + 32068, 32067, 32070, 32069, 32076, 32074, 32065, 32062, 32061, 32058, + 32057, 32060, 32059, 32066, 32064, 32063, 32129, 32151, 32131, 32150, + 32134, 32161, 32142, 32143, 32144, 32145, 32183, 32169, 32082, 32080, + 32110, 32109, 32092, 32108, 32107, 32117, 35762, 32094, 32102, 32101, + 32087, 32086, 32093, 32104, 32103, 32091, 32090, 32095, 32112, 32111, + 32106, 32105, 32119, 32100, 32099, 32089, 32088, 32120, 32113, 32114, + 32115, 32121, 32084, 32118, 32096, 32097, 32098, 32116, 32122, 32079, + 32085, 32081, 32083, 35762, 35762, 35762, 35762, 32257, 32253, 32254, + 32249, 32250, 32245, 32246, 32247, 32248, 32255, 32256, 32251, 32252, + 32180, 32181, 32243, 32244, 32171, 32185, 32146, 32155, 32167, 32182, + 32168, 32170, 32165, 32166, 32184, 32232, 32231, 32230, 32197, 32196, + 32216, 32215, 32198, 32214, 32213, 32223, 35762, 32200, 32208, 32207, + 32190, 32189, 32199, 32210, 32209, 32194, 32193, 32201, 32218, 32217, + 32212, 32211, 32225, 32206, 32205, 32192, 32191, 32227, 32219, 32220, + 32221, 32228, 32226, 32224, 32202, 32203, 32204, 32222, 32229, 32195, + 32187, 32188, 32186, 35762, 32077, 32078, 32053, 32054, 32056, 32055, + 32234, 32241, 32239, 32242, 32240, 32235, 32238, 32237, 32236, 35762, + 32179, 32178, 32127, 32130, 32152, 32147, 32135, 27208, 19559, 27209, + 19560, 32163, 32160, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 23897, 23876, 23875, 23874, 23906, 23974, 23973, 23976, 23975, 23907, + 23904, 23952, 23951, 23958, 23957, 23905, 23936, 23953, 23960, 23959, + 23908, 23978, 23977, 23972, 23971, 23903, 23980, 23910, 23970, 23956, + 23935, 23979, 23969, 23866, 23930, 23967, 23968, 23965, 23966, 23869, + 23902, 23981, 23868, 24063, 24047, 24070, 24071, 24068, 24069, 24059, + 24044, 24052, 24053, 24060, 23988, 24007, 24012, 24011, 23987, 23861, + 23859, 23860, 23858, 23873, 24078, 24080, 24077, 24076, 24073, 24072, + 24075, 24074, 24081, 24079, 24010, 23999, 24017, 24021, 24016, 24020, + 23911, 23934, 23961, 23962, 23963, 23964, 24064, 24065, 24066, 24067, + 23901, 23900, 23898, 23899, 23864, 23863, 23862, 23933, 24054, 24032, + 24033, 23955, 23954, 24061, 24062, 24002, 24003, 24004, 24005, 24006, + 23872, 23871, 23870, 24048, 24050, 24051, 24049, 23925, 23924, 23923, + 23921, 23929, 23913, 23926, 23914, 23916, 23927, 23919, 23917, 23928, + 23865, 24058, 24055, 24056, 24057, 23994, 23995, 23996, 23997, 23992, + 23993, 23991, 23909, 24008, 24028, 24030, 24027, 24026, 24023, 24022, + 24025, 24024, 24031, 24029, 23989, 23990, 24045, 24046, 24019, 24018, + 13332, 13358, 13343, 13364, 13365, 13363, 13353, 13354, 13366, 13347, + 13356, 13359, 13361, 13367, 13349, 13352, 13357, 13351, 13355, 13368, + 13348, 13346, 13342, 13362, 13350, 13338, 13341, 13345, 13340, 13339, + 13360, 13344, 13333, 13337, 13335, 13370, 13334, 13336, 35762, 13369, + 35762, 35762, 35762, 35762, 35762, 13331, 35762, 35762, 13415, 13446, + 13423, 13452, 13421, 13451, 13444, 13441, 13453, 13433, 13435, 13447, + 13449, 13454, 13437, 13443, 13445, 13439, 13442, 13412, 13436, 13432, + 13422, 13450, 13438, 13416, 13419, 13431, 13418, 13417, 13448, 13430, + 13426, 13429, 13427, 13456, 13424, 13428, 13457, 13455, 13420, 13440, + 13414, 13504, 23112, 13413, 13425, 13434, 14693, 14767, 14701, 14772, + 14765, 14729, 14696, 14711, 14769, 14743, 14761, 14675, 14673, 14759, + 14660, 14695, 14779, 14708, 14782, 14703, 14768, 14705, 14704, 14776, + 14739, 14763, 14742, 14688, 14698, 14692, 14721, 14726, 14725, 14712, + 14716, 14714, 14717, 14718, 14715, 14723, 14722, 14724, 14719, 14690, + 14691, 14750, 14756, 14755, 14748, 14753, 14744, 14745, 14747, 14758, + 14752, 14751, 14749, 14754, 14746, 14757, 14665, 14664, 14670, 14669, + 14728, 14685, 14684, 14682, 14677, 14687, 14678, 14771, 14681, 14680, + 14683, 14676, 14780, 14674, 14667, 14663, 14672, 14668, 14661, 14662, + 14666, 14671, 14709, 14689, 14770, 14781, 14694, 14707, 14702, 14706, + 14773, 14784, 15022, 14928, 14938, 14986, 14990, 14940, 14939, 14992, + 14991, 14967, 15019, 15020, 14977, 14998, 14978, 15018, 15017, 15021, + 15007, 14944, 14996, 14951, 14936, 14937, 14988, 14987, 14942, 14943, + 14941, 14994, 14995, 14975, 14974, 14970, 14968, 14976, 14999, 15000, + 15001, 15006, 15005, 14983, 14984, 14982, 14979, 14985, 15012, 15011, + 15010, 15009, 15008, 15016, 15014, 14950, 14947, 14997, 14952, 14954, + 14961, 14965, 14963, 14953, 14929, 14931, 14934, 14933, 14966, 14935, + 14989, 14993, 14972, 14973, 14804, 14905, 14807, 14827, 14830, 14834, + 14909, 14855, 14856, 14861, 14865, 14874, 14877, 14870, 14882, 14814, + 14844, 14847, 14883, 14900, 14796, 14787, 14790, 14813, 14918, 14840, + 14791, 14806, 14808, 14833, 14832, 14836, 14835, 14831, 14916, 14910, + 14858, 14881, 14875, 14876, 14895, 14862, 14864, 14869, 14868, 14859, + 14873, 14871, 14860, 14878, 14824, 14821, 14815, 14820, 14819, 14817, + 14822, 14826, 14803, 14845, 14849, 14854, 14802, 14885, 14893, 14886, + 14889, 14837, 14798, 14799, 14908, 14797, 14919, 14923, 14926, 14842, + 14801, 14794, 14792, 14793, 14795, 14927, 14810, 14811, 14809, 14805, + 14812, 14906, 12703, 12710, 12709, 12704, 12708, 12707, 12705, 12706, + 12930, 12938, 12937, 12931, 12935, 12934, 12932, 12936, 12696, 12702, + 12700, 12697, 12699, 12698, 12701, 12687, 12747, 12755, 12754, 12748, + 12752, 12751, 12749, 12745, 12859, 12866, 12864, 12860, 12862, 12861, + 12865, 12863, 12834, 12843, 12842, 12835, 12839, 12838, 12836, 12840, + 12874, 12880, 12879, 12875, 12849, 12844, 12876, 12878, 12850, 12858, + 12857, 12851, 12855, 12854, 12852, 12856, 12826, 12833, 12832, 12827, + 12831, 12830, 12828, 12829, 12814, 35762, 12818, 12815, 12817, 12816, + 35762, 35762, 12807, 12813, 12811, 12808, 12810, 12809, 12812, 35762, + 12802, 35762, 12806, 12803, 12805, 12804, 35762, 35762, 12537, 12544, + 12543, 12538, 12542, 12541, 12539, 12528, 12999, 13006, 13004, 13000, + 13002, 13001, 13005, 13003, 12912, 12920, 12919, 12913, 12917, 12916, + 12914, 12918, 12575, 12583, 12582, 12576, 12580, 12579, 12577, 12581, + 12967, 12974, 12973, 12968, 12972, 12971, 12969, 12970, 12955, 35762, + 12959, 12956, 12958, 12957, 35762, 35762, 12765, 12773, 12772, 12766, + 12770, 12769, 12767, 12771, 12756, 12764, 12763, 12757, 12761, 12760, + 12758, 12762, 12657, 12665, 12664, 12658, 12662, 12661, 12659, 12663, + 12735, 12742, 12741, 12736, 12740, 12739, 12737, 12738, 12723, 35762, + 12727, 12724, 12726, 12725, 35762, 35762, 12716, 12722, 12720, 12717, + 12719, 12718, 12721, 35762, 12711, 35762, 12715, 12712, 12714, 12713, + 35762, 35762, 12939, 12946, 12945, 12940, 12944, 12943, 12941, 12942, + 12775, 12781, 12779, 12776, 12778, 12777, 12780, 35762, 12990, 12998, + 12997, 12991, 12995, 12994, 12992, 12996, 12975, 12982, 12980, 12976, + 12978, 12977, 12981, 12979, 12947, 12954, 12953, 12948, 12952, 12951, + 12949, 12950, 12605, 12613, 12612, 12606, 12610, 12609, 12607, 12611, + 12590, 12598, 12597, 12591, 12595, 12594, 12592, 12596, 12921, 12929, + 12928, 12922, 12926, 12925, 12923, 12927, 12678, 12626, 12684, 12679, + 12683, 12682, 12680, 12681, 12666, 35762, 12670, 12667, 12669, 12668, + 35762, 35762, 12650, 12656, 12654, 12651, 12653, 12652, 12655, 12646, + 12881, 12889, 12888, 12882, 12886, 12885, 12883, 12887, 12566, 12574, + 12573, 12567, 12571, 12570, 12568, 12572, 12774, 12789, 12788, 12782, + 12786, 12785, 12783, 12787, 12904, 12911, 12909, 12905, 12907, 12906, + 12910, 12908, 12896, 12903, 12902, 12897, 12901, 12900, 12898, 12899, + 12618, 12625, 12623, 12619, 12621, 12620, 12624, 12616, 12794, 12801, + 12800, 12795, 12799, 12798, 12796, 12792, 12841, 12753, 12622, 35762, + 35762, 12506, 12508, 12507, 12525, 13028, 13026, 12509, 12524, 12510, + 12523, 13027, 12522, 13024, 13022, 13021, 13018, 13017, 13020, 13019, + 13025, 13023, 12511, 12514, 12513, 12518, 12517, 12521, 12520, 12516, + 12519, 12515, 12512, 35762, 35762, 35762, 12847, 12746, 12744, 12743, + 12845, 12529, 12527, 12526, 12846, 12617, 12615, 12614, 12848, 12793, + 12791, 12790, 13016, 13007, 13013, 13014, 13009, 13011, 13015, 13010, + 13008, 13012, 35762, 35762, 35762, 35762, 35762, 35762, 6081, 6082, 6083, + 6084, 6085, 6086, 6044, 6080, 6045, 6046, 6047, 6048, 6049, 6009, 6010, + 6011, 6012, 6013, 6014, 6050, 6051, 6052, 6053, 6054, 6055, 6056, 6057, + 6058, 6059, 6060, 6015, 6008, 6016, 6017, 6018, 6019, 6020, 6021, 6062, + 6063, 6064, 6065, 6066, 6067, 6023, 6022, 6024, 6025, 6026, 6027, 6028, + 6002, 6041, 6003, 6042, 6004, 6043, 6005, 6006, 6007, 6001, 6029, 6030, + 6031, 6032, 6033, 6034, 6035, 6036, 6037, 6038, 6039, 6040, 6068, 6069, + 6070, 6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 6079, 6061, 35762, + 35762, 6161, 6162, 6163, 6164, 6165, 6147, 35762, 35762, 5223, 5195, + 4968, 5225, 5226, 5375, 5389, 5672, 5179, 5039, 4966, 4967, 5549, 5639, + 5659, 5637, 5660, 5638, 5641, 5635, 5642, 5636, 5304, 5656, 5633, 5657, + 5634, 5305, 4970, 5673, 5691, 5212, 5211, 5213, 5214, 5206, 5207, 5204, + 5203, 5216, 5210, 5215, 5205, 5197, 5227, 5388, 4974, 5409, 5402, 5407, + 5408, 5404, 5405, 5663, 5037, 5038, 5400, 5401, 5399, 5578, 5397, 5576, + 5398, 5577, 5392, 5574, 5393, 5575, 5395, 5572, 5396, 5573, 5662, 5391, + 5571, 5030, 5548, 5531, 5546, 5547, 5544, 5545, 5670, 5001, 5014, 5529, + 5530, 5539, 5631, 5537, 5629, 5538, 5630, 5535, 5627, 5536, 5628, 5533, + 5625, 5534, 5626, 5310, 5491, 5526, 5527, 5528, 5525, 5246, 5240, 5244, + 5245, 5242, 5243, 5665, 5238, 5239, 5237, 5623, 5235, 5621, 5236, 5622, + 5233, 5619, 5234, 5620, 5230, 5617, 5231, 5618, 5307, 5228, 5229, 5471, + 5472, 5473, 5470, 5194, 5181, 5192, 5193, 5190, 5191, 5664, 4998, 5180, + 5188, 5616, 5186, 5614, 5187, 5615, 5184, 5612, 5185, 5613, 5182, 5610, + 5183, 5611, 5306, 4997, 5447, 5272, 5280, 5289, 5290, 5275, 5276, 5667, + 5278, 5279, 5288, 5570, 5286, 5568, 5287, 5569, 5284, 5566, 5285, 5567, + 5282, 5564, 5283, 5565, 5308, 5271, 5563, 5291, 4972, 5448, 5364, 5325, + 5362, 5363, 5352, 5353, 5668, 5296, 5324, 5361, 5589, 5355, 5587, 5356, + 5588, 5309, 5292, 5070, 5365, 5270, 5257, 5268, 5269, 5266, 5267, 5666, + 5255, 5256, 5265, 5557, 5263, 5555, 5264, 5556, 5261, 5553, 5262, 5554, + 5259, 5551, 5260, 5552, 5247, 5550, 5273, 5490, 5450, 5488, 5489, 5469, + 5474, 5669, 5430, 5449, 5483, 5609, 5481, 5607, 5482, 5608, 5479, 5605, + 5480, 5606, 5477, 5603, 5478, 5604, 5302, 5429, 4973, 5476, 4993, 5277, + 5297, 5303, 5300, 5301, 5298, 5299, 5468, 5466, 5467, 5460, 5461, 5463, + 5464, 5459, 5602, 5457, 5600, 5458, 5601, 5452, 5598, 5453, 5599, 5455, + 5596, 5456, 5597, 5451, 5690, 5676, 5688, 5689, 5678, 5679, 5671, 5674, + 5675, 5687, 5586, 5685, 5584, 5686, 5585, 5683, 5582, 5684, 5583, 5681, + 5580, 5682, 5581, 5311, 5661, 4994, 5579, 5446, 5428, 5412, 5562, 5422, + 5426, 5427, 5424, 5425, 5560, 5420, 5421, 5558, 5414, 5591, 5410, 5590, + 5274, 5222, 5201, 5202, 5217, 5219, 5220, 5199, 5200, 5221, 5632, 5198, + 5510, 5295, 5508, 5293, 5509, 5294, 5506, 5507, 5504, 5505, 5502, 5624, + 5492, 5523, 5524, 5520, 5518, 5517, 5541, 5542, 5543, 5540, 5350, 5348, + 5349, 5346, 5347, 5344, 5345, 5343, 5351, 5224, 5369, 5373, 5374, 5371, + 5372, 5367, 5368, 5366, 5515, 5516, 5511, 5514, 5593, 5594, 5595, 5592, + 5330, 5334, 5335, 5332, 5333, 5328, 5329, 5327, 5336, 5444, 5445, 5440, + 5443, 5652, 5653, 5654, 5651, 5643, 5253, 5254, 5251, 5252, 5249, 5250, + 5248, 5500, 5498, 5499, 5496, 5497, 5494, 5495, 5493, 4971, 4990, 4991, + 4992, 4989, 4978, 4979, 4980, 4977, 4986, 4987, 4988, 4985, 4982, 4983, + 4984, 4981, 5435, 5436, 5432, 5434, 5020, 5019, 5015, 5016, 5018, 5017, + 5166, 5165, 5161, 5162, 5164, 5163, 5172, 5171, 5167, 5168, 5170, 5169, + 5036, 5035, 5031, 5032, 5034, 5033, 5130, 5129, 5125, 5126, 5128, 5127, + 5124, 5123, 5119, 5120, 5122, 5121, 5093, 5092, 5088, 5089, 5091, 5090, + 5087, 5029, 5028, 5025, 5026, 5027, 5023, 5066, 5065, 5061, 5062, 5064, + 5063, 5060, 5059, 5055, 5056, 5058, 5057, 5054, 5073, 5072, 5067, 5068, + 5071, 5069, 5160, 5159, 5155, 5156, 5158, 5157, 5178, 5177, 5173, 5174, + 5176, 5175, 5053, 5437, 5052, 5047, 5048, 5051, 5439, 5050, 5046, 5045, + 5041, 5042, 5044, 5043, 5148, 5147, 5143, 5144, 5146, 5145, 5007, 5006, + 5002, 5003, 5005, 5004, 5142, 5141, 5137, 5138, 5140, 5139, 5106, 5105, + 5101, 5102, 5104, 5103, 5112, 5111, 5107, 5108, 5110, 5109, 5100, 5099, + 5095, 5096, 5098, 5097, 5094, 5040, 5013, 5012, 5008, 5009, 5011, 5010, + 5086, 5085, 5081, 5082, 5084, 5083, 5080, 5079, 5075, 5076, 5078, 5077, + 5074, 5136, 5135, 5131, 5132, 5134, 5133, 5154, 5153, 5149, 5150, 5152, + 5151, 5118, 5117, 5113, 5114, 5116, 5115, 5189, 5218, 5370, 5331, 5341, + 5342, 5339, 5340, 5337, 5338, 5650, 5648, 5649, 5646, 5647, 5644, 5645, + 5655, 4976, 25265, 25240, 25251, 25247, 25257, 25254, 25260, 25263, + 25264, 25243, 25242, 25262, 25248, 25253, 25258, 25252, 25239, 25255, + 25261, 25245, 25249, 25244, 25256, 25259, 25250, 25246, 25241, 25237, + 25238, 35762, 35762, 35762, 27467, 27523, 27517, 27521, 27520, 27515, + 27513, 27460, 27445, 27491, 27444, 27443, 27488, 27503, 27490, 27494, + 27495, 27497, 27483, 27449, 27482, 27468, 27461, 27469, 27471, 27516, + 27473, 27472, 27486, 27500, 27512, 27502, 27454, 27476, 27457, 27480, + 27470, 27485, 27506, 27477, 27519, 27446, 27509, 27508, 27504, 27447, + 27525, 27514, 27505, 27452, 27511, 27499, 27455, 27493, 27458, 27518, + 27487, 27501, 27484, 27453, 27475, 27474, 27456, 27492, 27459, 27479, + 27451, 27450, 27448, 27510, 27489, 27507, 27478, 27522, 27524, 27526, + 27527, 27442, 27528, 27529, 27441, 27481, 27498, 27496, 27465, 27464, + 27466, 27463, 27462, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 30050, 30067, 30068, 30058, 30056, 30052, 30064, 30055, 30053, 30061, + 30054, 30060, 30066, 30062, 30059, 30065, 30063, 30057, 30071, 30072, + 30070, 30069, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 30051, 15194, 15195, 15196, 15185, 15183, 15179, 15191, 15182, + 15180, 15188, 15181, 15187, 15193, 15189, 15186, 15192, 15190, 15184, + 15198, 15199, 15197, 26633, 26634, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 4689, 4690, 4691, 4680, 4678, 4674, 4686, + 4677, 4675, 4683, 4676, 4682, 4688, 4684, 4681, 4687, 4685, 4679, 4692, + 4693, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 30086, 30087, 30088, 30078, 30077, 30073, 30083, + 30076, 30074, 30081, 30075, 30080, 30085, 35762, 30079, 30084, 30082, + 35762, 30089, 30090, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 17762, 17760, 17763, 17761, 17764, + 17758, 17756, 17759, 17757, 17766, 17780, 17776, 17781, 17777, 17765, + 17778, 17774, 17779, 17775, 17767, 17788, 17768, 17770, 17769, 17784, + 17787, 17785, 17783, 17786, 17772, 17771, 17773, 17789, 17782, 17790, + 17737, 17735, 17745, 17746, 17741, 17744, 17742, 17743, 17754, 17755, + 17752, 17753, 17747, 17736, 17740, 17739, 17738, 17857, 17856, 17858, + 17863, 17865, 17869, 17871, 17873, 17875, 17874, 17866, 17870, 17864, + 17876, 17860, 17861, 17868, 17862, 17811, 17805, 17810, 17812, 17807, + 17796, 17804, 17806, 17801, 17793, 17794, 17813, 17800, 17795, 17802, + 17797, 17799, 17808, 17798, 17809, 17803, 17734, 17791, 17792, 35762, + 35762, 17883, 17885, 17882, 17881, 17878, 17877, 17880, 17879, 17886, + 17884, 35762, 35762, 35762, 35762, 35762, 35762, 17835, 17834, 17831, + 17833, 17832, 17826, 17829, 17830, 17828, 17827, 35762, 35762, 35762, + 35762, 35762, 35762, 23479, 23491, 23487, 23336, 23486, 23337, 23484, + 23475, 23488, 23489, 23490, 23335, 23334, 23333, 23485, 23332, 23328, + 23330, 23327, 23326, 23323, 23322, 23325, 23324, 23331, 23329, 35762, + 35762, 35762, 35762, 35762, 35762, 23340, 23454, 23471, 23456, 23458, + 23457, 23459, 23455, 23465, 23368, 23460, 23466, 23467, 23463, 23372, + 23453, 23415, 23414, 23445, 23461, 23369, 23464, 23470, 23468, 23469, + 23462, 23451, 23450, 23444, 23448, 23449, 23447, 23452, 23446, 23371, + 23424, 23442, 23443, 23431, 23433, 23432, 23434, 23418, 23435, 23438, + 23439, 23427, 23437, 23426, 23420, 23429, 23422, 23425, 23441, 23440, + 23436, 23428, 23430, 23421, 23423, 23419, 23413, 23398, 23399, 23407, + 23406, 23403, 23411, 23394, 23396, 23412, 23401, 23393, 23408, 23410, + 23409, 23395, 23397, 23392, 23405, 23402, 23400, 23404, 23391, 23389, + 23390, 23388, 23387, 23370, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 23342, 23344, 23346, 23353, 23352, 23360, 23356, 23341, 23351, + 23367, 23354, 23366, 23358, 23357, 23348, 23355, 23359, 23345, 23362, + 23361, 23365, 23363, 23364, 23343, 23417, 23416, 23380, 23385, 23376, + 23381, 23377, 23373, 23378, 23374, 23386, 23375, 23383, 23384, 23350, + 23349, 23379, 23347, 23382, 35762, 35762, 35762, 35762, 35762, 5390, + 4975, 4969, 5658, 5406, 5403, 5394, 5532, 5241, 5232, 5281, 5354, 5326, + 5258, 5475, 5431, 5462, 5465, 5454, 5680, 5677, 5423, 5359, 5379, 5360, + 5380, 5357, 5377, 5358, 5378, 5419, 5417, 5418, 5415, 5416, 5413, 5386, + 5387, 5384, 5383, 5385, 5376, 5381, 5382, 5196, 5640, 5209, 5208, 5411, + 5561, 5559, 5503, 5501, 5522, 5521, 5519, 5513, 5512, 5442, 5441, 5433, + 5022, 4999, 5024, 5021, 5438, 5049, 4995, 4996, 5000, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 19858, 19825, + 19824, 19805, 19804, 19811, 19819, 19818, 19823, 19822, 19810, 19808, + 19806, 19821, 19820, 19812, 19827, 19826, 19817, 19816, 19830, 19809, + 19831, 19829, 19832, 19813, 19814, 19815, 19828, 19803, 19807, 35762, + 19849, 19856, 19857, 19855, 19850, 19853, 19851, 19854, 19852, 19848, + 19846, 19847, 35762, 35762, 35762, 35762, 19840, 19837, 19839, 19845, + 19838, 19843, 19842, 19844, 19841, 19834, 19833, 19835, 35762, 35762, + 35762, 35762, 19836, 35762, 35762, 35762, 19859, 19860, 19867, 19869, + 19866, 19865, 19862, 19861, 19864, 19863, 19870, 19868, 30111, 30123, + 30106, 30103, 30121, 30124, 30105, 30104, 30118, 30113, 30112, 30119, + 30116, 30122, 30117, 30120, 30110, 30102, 30107, 30091, 30125, 30095, + 30096, 30114, 30109, 30108, 30115, 30094, 30092, 30093, 35762, 35762, + 30097, 30098, 30099, 30100, 30101, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 24411, 24433, 24393, 24395, + 24398, 24415, 24417, 24420, 24401, 24397, 24413, 24423, 24419, 24435, + 24402, 24400, 24399, 24424, 24422, 24421, 24404, 24403, 24410, 24426, + 24425, 24432, 24407, 24412, 24409, 24429, 24434, 24431, 24408, 24406, + 24405, 24430, 24428, 24427, 24392, 24394, 24414, 24416, 24396, 24418, + 35762, 35762, 35762, 35762, 24456, 24441, 24445, 24451, 24454, 24457, + 24443, 24447, 24448, 24452, 24444, 24442, 24455, 24450, 24449, 24453, + 24446, 24391, 24386, 24385, 24390, 24389, 24388, 24387, 24438, 24439, + 35762, 35762, 35762, 35762, 35762, 35762, 24464, 24466, 24463, 24462, + 24459, 24458, 24461, 24460, 24467, 24465, 24440, 35762, 35762, 35762, + 24436, 24437, 17836, 17855, 17848, 17851, 17853, 17846, 17844, 17842, + 17838, 17840, 17825, 17823, 17815, 17819, 17821, 17817, 17849, 17854, + 17847, 17850, 17852, 17845, 17843, 17841, 17837, 17839, 17824, 17822, + 17814, 17818, 17820, 17816, 4658, 4655, 4647, 4646, 4660, 4652, 4645, + 4644, 4663, 4654, 4651, 4650, 4653, 4657, 4649, 4648, 4665, 4661, 4659, + 4664, 4662, 4666, 4656, 4669, 4671, 4668, 4670, 4667, 35762, 35762, 4673, + 4672, 30159, 30157, 30158, 30175, 30174, 30173, 30199, 30165, 30164, + 30178, 30185, 30177, 30200, 30193, 30160, 30205, 30176, 30192, 30169, + 30168, 30182, 30181, 30201, 30204, 30167, 30166, 30170, 30180, 30183, + 30179, 30206, 30186, 30172, 30191, 30194, 30187, 30189, 30207, 30161, + 30162, 30163, 30171, 30190, 30208, 30184, 30197, 30198, 30195, 30196, + 30203, 30202, 30188, 30156, 30131, 30130, 30128, 30219, 30126, 30127, + 30129, 30132, 30133, 30134, 35762, 30227, 30234, 30238, 30235, 30244, + 30250, 30251, 30249, 30248, 30246, 30247, 30239, 30240, 30243, 30252, + 30236, 30242, 30237, 30245, 30241, 30218, 30230, 30231, 30211, 30212, + 30213, 30222, 30221, 30214, 35762, 35762, 30135, 30142, 30144, 30141, + 30140, 30137, 30136, 30139, 30138, 30145, 30143, 35762, 35762, 35762, + 35762, 35762, 35762, 30152, 30154, 30151, 30150, 30147, 30146, 30149, + 30148, 30155, 30153, 35762, 35762, 35762, 35762, 35762, 35762, 30228, + 30229, 30226, 30217, 30210, 30232, 30223, 30220, 30215, 30216, 30224, + 30225, 30209, 30233, 35762, 35762, 7898, 7866, 7982, 7900, 8132, 8145, + 8144, 8084, 7881, 8061, 8120, 8090, 7885, 8089, 8088, 8030, 8024, 8047, + 8106, 8048, 8107, 8118, 8077, 7981, 8093, 7884, 7883, 8130, 8008, 8009, + 8010, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 2698, 2697, 2700, 2696, 2699, 2608, 2609, 2625, 2626, 2629, 2630, 2647, + 2648, 2638, 2639, 2622, 2612, 2627, 2628, 2633, 2635, 2623, 2624, 2642, + 2615, 2616, 2631, 2632, 2643, 2654, 2653, 2619, 2618, 2641, 2652, 2655, + 2617, 2620, 2640, 2644, 2645, 2613, 2614, 2660, 2662, 2646, 2637, 2661, + 2650, 2651, 2649, 2659, 2701, 2712, 2715, 2716, 2706, 2707, 2704, 2705, + 2702, 2703, 2708, 2709, 2711, 2710, 2713, 2714, 2717, 2634, 2636, 2656, + 2621, 2657, 2658, 2610, 2611, 35762, 35762, 35762, 2725, 2727, 2724, + 2723, 2720, 2719, 2722, 2721, 2728, 2726, 2694, 2691, 2718, 2605, 2607, + 2606, 2693, 2680, 2678, 2681, 2672, 2673, 2679, 2675, 2677, 2676, 2674, + 2670, 2669, 2665, 2663, 2667, 2666, 2664, 2668, 2671, 2690, 2689, 2688, + 2687, 2682, 2684, 2685, 2686, 2683, 2695, 2692, 35762, 29705, 29703, + 29704, 29656, 29691, 29693, 29658, 29692, 29668, 29669, 29676, 29684, + 29679, 29670, 29677, 29681, 29690, 29671, 29685, 29678, 29672, 29683, + 29661, 29686, 29674, 29682, 29689, 29665, 29663, 29687, 29667, 29688, + 29680, 29651, 29652, 29653, 29711, 29710, 29712, 29709, 29707, 29708, + 29702, 29706, 29654, 29655, 29675, 29666, 29719, 29721, 29718, 29717, + 29714, 29713, 29716, 29715, 29722, 29720, 29650, 29664, 29662, 29673, + 29659, 29660, 3488, 3474, 3482, 3466, 3454, 3478, 3477, 3463, 3469, 3462, + 3455, 3486, 3472, 3464, 3481, 3465, 3483, 3480, 3485, 3470, 3453, 3468, + 3475, 3458, 3476, 3471, 3456, 3487, 3473, 3460, 3484, 3467, 3461, 3479, + 3459, 3457, 3489, 3490, 3497, 3503, 3500, 3504, 3505, 3501, 3506, 3502, + 3498, 3499, 3451, 3452, 3491, 3492, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 3496, 3494, 3495, 3493, 19688, 19687, 19686, 19700, + 19699, 19705, 19715, 19714, 19718, 19706, 19713, 19712, 19694, 19707, + 19691, 19690, 19689, 19698, 19697, 19696, 19695, 19704, 19703, 19709, + 19708, 19693, 19723, 19720, 19719, 19702, 19701, 19721, 19717, 19716, + 19722, 19724, 19733, 19732, 19738, 19740, 19736, 19737, 19734, 19735, + 19739, 19677, 19682, 19681, 19679, 19683, 19684, 19685, 19680, 19678, + 19731, 19730, 35762, 35762, 35762, 19725, 19728, 19729, 19727, 19726, + 19747, 19749, 19746, 19745, 19742, 19741, 19744, 19743, 19750, 19748, + 35762, 35762, 35762, 19711, 19710, 19692, 25311, 25313, 25310, 25309, + 25306, 25305, 25308, 25307, 25314, 25312, 25284, 25275, 25273, 25272, + 25274, 25285, 25269, 25268, 25270, 25271, 25287, 25283, 25281, 25280, + 25282, 25289, 25295, 25296, 25294, 25297, 25286, 25279, 25276, 25278, + 25277, 25288, 25290, 25291, 25293, 25292, 25299, 25300, 25298, 25304, + 25303, 25315, 25302, 25301, 10125, 10102, 10108, 10164, 10146, 10154, + 10144, 10145, 10163, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 13460, 13491, 13468, 13497, 13466, 13496, 13489, 13486, 13498, 13478, + 13480, 13492, 13494, 13499, 13482, 13488, 13490, 13484, 13487, 13500, + 13481, 13477, 13467, 13495, 13483, 13461, 13464, 13476, 13463, 13462, + 13493, 13475, 13471, 13474, 13472, 13502, 13469, 13473, 13503, 13501, + 13465, 13485, 13459, 35762, 35762, 13458, 13470, 13479, 29701, 29699, + 29700, 29698, 29697, 29696, 29695, 29694, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 33625, 33638, 33627, 33605, 33619, 33633, + 33634, 33635, 33620, 33636, 33623, 33631, 33626, 33624, 33632, 33630, + 33629, 33637, 33618, 33616, 33607, 33614, 33606, 33617, 33615, 33596, + 33597, 33599, 33600, 33612, 33610, 33611, 33609, 33598, 33602, 33608, + 33621, 33604, 33613, 33601, 33628, 33622, 33603, 35762, 35762, 35762, + 35762, 35762, 18684, 18685, 19290, 18681, 18686, 18687, 18658, 18657, + 19275, 19268, 18690, 18691, 18664, 18692, 18670, 18665, 18666, 19225, + 19226, 19227, 19270, 18668, 19262, 18784, 18694, 18671, 18679, 18674, + 18697, 19230, 19229, 19228, 18698, 18699, 18701, 18659, 18712, 18646, + 14004, 14007, 14003, 14006, 14002, 9995, 23018, 23019, 23009, 23010, + 23021, 23022, 23012, 23024, 23014, 23025, 23026, 23027, 23028, 23029, + 23030, 23013, 23016, 23017, 23031, 23011, 23033, 23034, 23036, 23167, + 23274, 23168, 23276, 23171, 23196, 23210, 23264, 23249, 23279, 23217, + 23287, 23298, 23227, 23214, 23247, 23250, 23271, 23173, 23251, 23266, + 23291, 23265, 23277, 23295, 23169, 23175, 23218, 23201, 23219, 23195, + 19431, 19439, 19441, 19442, 14213, 14209, 14212, 14211, 14210, 19351, + 18770, 18819, 18905, 19047, 19067, 19144, 19171, 19164, 19209, 19245, + 19413, 19297, 23085, 18976, 19255, 18714, 18983, 19140, 18715, 19350, + 18771, 18823, 18906, 18919, 19002, 19029, 19048, 19073, 19145, 19174, + 19210, 18892, 19358, 19385, 19414, 18733, 18759, 18822, 18882, 19133, + 19181, 19218, 18973, 19129, 18894, 19337, 18900, 23275, 23176, 23194, + 23212, 23258, 23215, 23202, 23263, 23286, 23229, 23230, 23177, 23179, + 23232, 23236, 23238, 23182, 23228, 23278, 23246, 23245, 23188, 23172, + 23252, 23262, 23211, 23267, 23293, 23294, 23190, 23297, 23288, 23207, + 23209, 23208, 23213, 23290, 7874, 7873, 8122, 8121, 8074, 7965, 8073, + 7758, 7964, 7757, 8022, 7770, 8075, 7897, 8086, 8113, 7983, 8137, 8138, + 8005, 7996, 7997, 7998, 8000, 8007, 8003, 8032, 7988, 8034, 8011, 7989, + 7990, 8036, 7991, 7992, 8021, 8025, 8013, 8040, 7995, 8027, 8028, 8026, + 8004, 8012, 8016, 8037, 8002, 8019, 8029, 7994, 8015, 8018, 8136, 7987, + 7986, 7869, 8142, 7872, 7864, 7878, 7767, 8042, 8097, 18174, 18731, + 18210, 18773, 18209, 18772, 18208, 18769, 18217, 18788, 18242, 18825, + 18241, 18824, 18240, 18820, 18236, 18814, 18237, 18815, 18268, 18868, + 18269, 18869, 18257, 18856, 18266, 18866, 18248, 18847, 18293, 18908, + 18301, 18918, 18320, 18938, 18319, 18937, 18317, 18935, 18314, 18932, + 18313, 18931, 18337, 18965, 18331, 18953, 18368, 19000, 18365, 18997, + 18369, 19001, 18376, 19014, 18377, 19015, 18387, 19024, 18383, 19011, + 18391, 19045, 18393, 19050, 18392, 19049, 18411, 19072, 18410, 19071, + 18405, 19064, 18401, 19059, 18442, 19108, 18441, 19107, 18419, 19100, + 18420, 19101, 18470, 19143, 18472, 19147, 18481, 19161, 18479, 19159, + 18480, 19160, 18486, 19166, 18506, 19204, 18504, 19202, 18503, 19195, + 18498, 19197, 18505, 19203, 18526, 19243, 18525, 19242, 18527, 19246, + 18521, 19236, 18557, 19318, 18578, 19341, 18550, 19311, 18577, 19340, + 18569, 19330, 18590, 19361, 18589, 19357, 18603, 19374, 18604, 19375, + 18600, 19371, 18602, 19373, 18601, 19372, 18609, 19380, 18608, 19379, + 18614, 19390, 18625, 19404, 18629, 19408, 18631, 19410, 18939, 19241, + 19376, 19400, 18732, 19038, 19037, 19039, 18515, 18829, 18168, 18725, + 18184, 18743, 18180, 18739, 18179, 18738, 18178, 18737, 18182, 18741, + 18181, 18740, 18163, 18720, 18162, 18719, 18161, 18718, 18165, 18722, + 18164, 18721, 18262, 18861, 18273, 18874, 18265, 18865, 18253, 18852, + 18252, 18851, 18251, 18850, 18256, 18855, 18255, 18854, 18338, 18966, + 18328, 18957, 18433, 19093, 18453, 19119, 18425, 19085, 18424, 19084, + 18423, 19083, 18427, 19087, 18426, 19086, 18450, 19116, 18449, 19115, + 18448, 19114, 18452, 19118, 18451, 19117, 18560, 19321, 18567, 19328, + 18564, 19325, 18563, 19324, 18562, 19323, 18566, 19327, 18565, 19326, + 18615, 19391, 18613, 19389, 18617, 19393, 18621, 19399, 18396, 19053, + 18397, 19054, 18618, 19394, 14051, 14043, 14056, 14048, 14052, 14044, + 14054, 14046, 13817, 13809, 13820, 13812, 13818, 13810, 13822, 13814, + 14074, 14071, 14076, 14073, 14075, 14072, 35762, 35762, 13857, 13854, + 13859, 13856, 13858, 13855, 35762, 35762, 14089, 14081, 14094, 14086, + 14090, 14082, 14092, 14084, 13841, 13833, 13844, 13836, 13842, 13834, + 13846, 13838, 14115, 14106, 14118, 14109, 14117, 14108, 14116, 14107, + 13869, 13864, 13872, 13867, 13871, 13866, 13870, 13865, 14176, 14173, + 14178, 14175, 14177, 14174, 35762, 35762, 13903, 13900, 13905, 13902, + 13904, 13901, 35762, 35762, 14135, 14126, 14138, 14129, 14137, 14128, + 14136, 14127, 35762, 13915, 35762, 13918, 35762, 13917, 35762, 13916, + 14156, 14148, 14161, 14153, 14157, 14149, 14159, 14151, 13887, 13879, + 13890, 13882, 13888, 13880, 13892, 13884, 14041, 14061, 14078, 14077, + 14101, 14099, 14121, 14122, 14180, 14179, 14141, 14142, 14168, 14166, + 35762, 35762, 14058, 14050, 14057, 14049, 14053, 14045, 14055, 14047, + 13824, 13816, 13821, 13813, 13819, 13811, 13823, 13815, 14096, 14088, + 14095, 14087, 14091, 14083, 14093, 14085, 13848, 13840, 13845, 13837, + 13843, 13835, 13847, 13839, 14163, 14155, 14162, 14154, 14158, 14150, + 14160, 14152, 13894, 13886, 13891, 13883, 13889, 13881, 13893, 13885, + 14040, 14065, 14042, 14063, 14062, 35762, 14059, 14060, 13826, 13830, + 13827, 13828, 13825, 14000, 14028, 14029, 14033, 13949, 14102, 14103, + 14100, 35762, 14097, 14098, 13861, 13860, 13851, 13850, 13849, 14032, + 14031, 14030, 14120, 14124, 14113, 14112, 35762, 35762, 14119, 14111, + 13873, 13877, 13874, 13875, 35762, 13957, 13956, 13955, 14140, 14144, + 14133, 14132, 14188, 14187, 14139, 14131, 13920, 13924, 13921, 13922, + 13910, 13951, 13950, 14227, 35762, 35762, 14169, 14170, 14167, 35762, + 14164, 14165, 13907, 13906, 13897, 13896, 13895, 14025, 13954, 35762, + 12447, 12444, 12449, 12446, 32044, 13184, 28853, 13117, 26923, 32017, + 14524, 35568, 35567, 35569, 19570, 27221, 15992, 24652, 13116, 12448, + 12445, 15946, 10941, 10915, 19515, 27171, 28728, 28726, 19475, 27145, + 10914, 10909, 10223, 10908, 4694, 32505, 25769, 32572, 15964, 15995, + 19876, 26269, 19569, 27220, 26798, 19568, 27219, 24257, 26502, 26503, + 26884, 10923, 32519, 27088, 27082, 27096, 5706, 28727, 28729, 27105, + 10945, 16335, 26084, 32621, 5992, 5707, 2513, 15994, 13188, 19523, 27182, + 10946, 26947, 13036, 32418, 27087, 3828, 3867, 20532, 27093, 7742, 32569, + 8148, 29770, 16351, 13152, 32024, 26943, 13177, 13139, 32573, 13178, + 10887, 32530, 33645, 22296, 34177, 13310, 16353, 16355, 16354, 35762, + 19567, 27218, 13132, 26797, 16249, 7, 16248, 6, 24252, 24650, 29741, + 29729, 35762, 35762, 29736, 29735, 29738, 29737, 29728, 29742, 29732, + 29733, 29727, 29731, 29734, 29730, 29615, 29617, 29614, 29613, 29610, + 29609, 29612, 29611, 29604, 29616, 29605, 29606, 29603, 29607, 29608, + 35762, 19428, 19429, 19437, 19443, 19427, 19430, 19433, 19434, 19435, + 19436, 19438, 19426, 19440, 35762, 35762, 35762, 13033, 7755, 8394, + 13194, 20484, 22903, 24185, 26526, 27538, 34181, 24384, 10881, 13034, + 18028, 32539, 11052, 13505, 26527, 14277, 2524, 16001, 5825, 20485, + 29183, 31790, 16239, 32540, 24700, 20985, 27407, 18155, 3742, 29165, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 8051, 8105, 8065, 8117, 7763, 7779, + 8044, 8102, 8110, 7778, 7762, 8124, 7910, 7901, 7904, 7907, 7902, 8054, + 7903, 7905, 7906, 8094, 7891, 7764, 8131, 8143, 8056, 8062, 8109, 8055, + 8043, 8101, 7766, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 0, 100, 10957, 10247, + 5829, 5708, 4959, 13035, 27726, 10249, 27723, 27715, 3917, 10958, 26688, + 26689, 27716, 3918, 27717, 27724, 20657, 10959, 24743, 29081, 27719, + 10955, 10960, 27720, 3919, 10961, 26860, 27066, 27750, 31685, 32492, + 33639, 10962, 26078, 26086, 16350, 3920, 32563, 17143, 951, 27712, 3916, + 12503, 27722, 27713, 27714, 32547, 27718, 27725, 346, 3633, 13508, 10236, + 16246, 27395, 13096, 10969, 10968, 10954, 10956, 10970, 32556, 32557, + 27092, 32558, 10967, 10963, 10964, 10965, 10966, 26888, 32542, 26504, + 2584, 32560, 29846, 33781, 33779, 33783, 33784, 33789, 33777, 33788, + 33787, 33775, 33782, 33774, 33776, 33785, 33773, 33790, 13189, 27365, + 27376, 27377, 27364, 27361, 27370, 27372, 27380, 27381, 27373, 27379, + 27375, 27358, 27366, 27362, 27368, 28915, 28919, 28920, 28914, 28911, + 28923, 28922, 28910, 28924, 28921, 28909, 28918, 28913, 28916, 28912, + 28917, 27369, 27363, 27374, 27378, 19187, 27371, 27360, 27359, 27367, + 33791, 32551, 32550, 35762, 35762, 35762, 35762, 19571, 32718, 27223, + 10989, 19497, 32643, 24682, 24656, 29055, 29069, 19591, 27245, 19654, + 27322, 19651, 32768, 27321, 11022, 19594, 27248, 19602, 32731, 27230, + 11003, 32644, 19600, 27254, 19587, 27241, 19505, 19500, 11026, 32728, + 32729, 10998, 10999, 27237, 10990, 960, 7726, 24684, 19582, 965, 7728, + 19620, 19614, 32745, 32742, 27282, 27276, 11039, 11036, 27256, 32720, + 19604, 19666, 32771, 27288, 11047, 19621, 27271, 19657, 19504, 27264, + 19655, 32735, 27262, 11029, 19502, 32646, 24694, 24668, 29066, 29078, + 19641, 27312, 19670, 27292, 32721, 10991, 19661, 32736, 27268, 11030, + 19581, 27236, 19652, 32772, 27323, 11024, 32773, 32775, 32776, 32777, + 32779, 32780, 27324, 24683, 29058, 32648, 27132, 11001, 32032, 19601, + 27255, 19499, 19585, 27239, 19498, 19665, 27287, 19507, 13172, 8153, + 26414, 32012, 32011, 12437, 16167, 24141, 12386, 24703, 28895, 8161, + 10707, 28888, 12451, 24100, 24088, 24092, 22907, 22914, 10882, 10689, + 27755, 2512, 27333, 4695, 29403, 8400, 13183, 26887, 16240, 27122, 947, + 22170, 29184, 10693, 10708, 26273, 24708, 20493, 20500, 16328, 32623, + 16313, 10912, 32529, 8167, 29763, 33769, 7729, 7720, 962, 32013, 3634, + 26977, 26886, 10883, 13038, 13330, 15982, 32322, 27094, 16347, 28848, + 34185, 24713, 22913, 2517, 24704, 1043, 1046, 24340, 351, 24705, 353, + 32520, 348, 12489, 13328, 10699, 1047, 13329, 1044, 16130, 7754, 12487, + 27331, 27332, 8346, 12504, 12490, 29565, 10252, 12473, 22181, 26949, + 24715, 16006, 24716, 29596, 19770, 13741, 19772, 13744, 19761, 13734, + 23857, 23856, 3632, 24714, 24718, 24717, 24345, 24342, 19769, 13740, + 24344, 24341, 19771, 13742, 24346, 24343, 26861, 29633, 26870, 29642, + 26869, 29641, 10710, 10713, 29621, 29749, 24701, 24702, 29627, 29755, + 24338, 24339, 29626, 29754, 23611, 23612, 23613, 29276, 29365, 29278, + 29367, 29214, 29221, 6503, 6449, 6508, 6241, 6254, 6504, 6230, 6513, + 6255, 29532, 29525, 29546, 29480, 27197, 19537, 10976, 32652, 2518, + 22922, 32536, 13173, 32523, 10939, 10712, 24712, 10715, 24337, 26871, + 29643, 24698, 8162, 24699, 8163, 25799, 16129, 23614, 15761, 16336, + 34206, 24186, 24655, 27128, 27193, 24097, 24098, 24099, 24093, 10529, + 10884, 29567, 10691, 4099, 19549, 27158, 19513, 27169, 27095, 9642, 9641, + 10933, 10932, 10911, 10936, 26682, 12474, 19775, 13750, 33682, 33681, + 19759, 13745, 12472, 12471, 12469, 12470, 10711, 10714, 24709, 24710, + 29277, 29366, 19760, 13733, 26868, 29640, 24706, 10705, 24707, 10706, + 33644, 22899, 32651, 10979, 12387, 12389, 28896, 12392, 12391, 28897, + 12390, 12388, 8164, 8165, 28889, 8166, 28890, 35480, 10530, 12384, 15976, + 32636, 10980, 26885, 26521, 33954, 19471, 27140, 19548, 27149, 4090, + 4087, 32441, 32438, 27085, 29309, 2508, 27736, 27732, 31683, 26806, + 33693, 26685, 32554, 33945, 15974, 32437, 32440, 4086, 4089, 32434, 4080, + 13198, 28954, 32637, 25791, 12500, 34190, 17145, 19564, 27213, 12499, + 3630, 10218, 349, 29856, 32456, 10700, 8172, 28880, 8348, 8349, 991, + 1029, 1015, 1003, 1004, 1020, 1001, 971, 976, 1026, 1031, 1017, 1016, + 1011, 1018, 999, 1023, 1012, 1019, 974, 983, 982, 1005, 1008, 984, 1037, + 1010, 1034, 980, 1009, 1007, 1035, 987, 1006, 1022, 981, 988, 997, 975, + 1036, 1021, 972, 1002, 1033, 978, 1027, 996, 973, 985, 998, 1039, 1038, + 977, 979, 1040, 1028, 1025, 1014, 1013, 986, 1032, 989, 1024, 994, 993, + 1030, 990, 995, 992, 24719, 27127, 27937, 3526, 33656, 16312, 8170, + 10615, 12443, 8152, 34095, 12465, 354, 15472, 6285, 6507, 4635, 32622, + 23495, 15998, 25787, 25788, 26426, 26427, 10610, 28971, 1000, 10244, + 26872, 24569, 26874, 7749, 19552, 19553, 19551, 27165, 27166, 27164, + 19520, 19527, 19519, 27179, 27186, 27178, 19469, 19467, 19468, 9644, + 27138, 27136, 27137, 16323, 15947, 32688, 32704, 29646, 29644, 32443, + 4081, 4082, 26958, 19555, 27199, 15955, 15956, 15957, 15958, 10263, + 10266, 10267, 10256, 10260, 10268, 10257, 10261, 10264, 10255, 10259, + 10254, 10258, 10262, 10265, 29244, 27067, 13061, 33653, 22739, 22731, + 22738, 22732, 22736, 22737, 22735, 22734, 22733, 11219, 13313, 32436, + 4085, 32429, 4084, 32444, 4092, 34104, 3631, 29592, 13145, 8, 12385, + 10245, 3856, 3821, 3900, 3804, 3857, 3822, 3859, 357, 29590, 32330, + 15975, 3840, 3843, 3845, 3837, 10937, 3879, 3751, 26820, 26817, 26818, + 26819, 25220, 29841, 29849, 29850, 29830, 29828, 29831, 29842, 29816, + 29817, 29835, 29837, 29836, 29834, 29818, 29847, 29848, 29820, 29824, + 29823, 29822, 29821, 29839, 29853, 29829, 29819, 29827, 29851, 29832, + 29833, 29844, 29843, 29845, 29854, 29825, 3924, 25774, 29840, 29826, + 29852, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 25232, 25227, 25230, 25231, + 25224, 25225, 25223, 25222, 25229, 25226, 25228, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 6251, 6248, 6247, + 6244, 6243, 6246, 6245, 6252, 6250, 6472, 6452, 6497, 6485, 6467, 6455, + 6471, 6469, 6451, 6498, 6486, 26360, 26358, 26357, 26354, 26353, 26356, + 26355, 26361, 26359, 26352, 26343, 26351, 26349, 26344, 26345, 26347, + 26348, 26342, 26346, 26350, 10550, 10562, 10559, 10544, 10541, 10556, + 10553, 10568, 10547, 24739, 24732, 24740, 24738, 24733, 24734, 24735, + 24737, 24731, 24742, 24741, 26388, 26389, 26390, 26391, 26392, 26393, + 26394, 26395, 26396, 26397, 26398, 26399, 26400, 26401, 26402, 26403, + 26404, 26405, 26406, 26407, 26408, 26409, 26410, 26411, 26412, 26413, + 6395, 6396, 6397, 6398, 6399, 6400, 6401, 6402, 6403, 6404, 6405, 6406, + 6407, 6408, 6409, 6410, 6411, 6412, 6413, 6414, 6415, 6416, 6417, 6418, + 6419, 6420, 6421, 6422, 6423, 6424, 6425, 6426, 6427, 6428, 6429, 6430, + 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, + 6443, 6444, 6445, 6446, 6249, 24266, 24264, 24262, 24267, 24268, 24270, + 24271, 24265, 24269, 24263, 10903, 10901, 10900, 10897, 10896, 10899, + 10898, 10904, 10902, 10895, 24261, 4206, 4153, 4202, 4149, 4196, 4148, + 4195, 4147, 4194, 4146, 4193, 4145, 4190, 4123, 4117, 4144, 4189, 4121, + 4115, 4143, 4201, 4227, 4221, 4138, 4200, 4225, 4219, 4136, 4205, 4243, + 4220, 4116, 4240, 4122, 4226, 4152, 4204, 4242, 4218, 4114, 4239, 4120, + 4224, 4151, 4188, 4157, 4211, 4125, 4119, 4214, 4160, 4142, 4199, 4156, + 4210, 4228, 4222, 4213, 4159, 4137, 4203, 4158, 4212, 4241, 4217, 4118, + 4238, 4162, 4216, 4155, 4209, 4124, 4223, 4215, 4161, 4150, 4186, 4140, + 4185, 4139, 4113, 4109, 4130, 4127, 4105, 4129, 4126, 4104, 4233, 4230, + 4108, 4232, 4229, 4107, 4245, 4236, 4112, 4244, 4235, 4111, 4131, 4128, + 4103, 4234, 4231, 4106, 4246, 4237, 4110, 4164, 4163, 4165, 4166, 4182, + 4181, 4183, 4191, 4197, 4208, 4187, 4132, 4134, 4154, 4141, 4192, 4198, + 4133, 4135, 32667, 20583, 20582, 20585, 20538, 20581, 20586, 20584, + 13205, 19514, 19535, 19546, 19485, 19534, 19495, 19496, 27152, 19790, + 22298, 10230, 32691, 27161, 26940, 26941, 26932, 26933, 26934, 26935, + 26936, 26937, 26938, 26939, 3877, 34082, 34091, 34085, 29418, 29427, + 29417, 29424, 29426, 29416, 3875, 34079, 3871, 34073, 3908, 34115, 3853, + 34063, 3902, 34111, 3901, 34110, 3858, 34070, 3863, 34069, 3862, 34068, + 3806, 34028, 3805, 34027, 3826, 34054, 3825, 34053, 3824, 34052, 3796, + 34017, 34018, 13136, 20588, 34004, 10886, 6224, 4698, 3747, 6216, 6225, + 6217, 6222, 6221, 6223, 19483, 27150, 16343, 16341, 32670, 20536, 32689, + 32706, 20579, 20559, 32672, 20539, 3833, 3832, 3903, 3904, 33970, 29421, + 29428, 29423, 29420, 34094, 34112, 32659, 32660, 18152, 34092, 34088, + 34089, 34093, 34011, 34009, 34010, 34012, 32687, 32711, 20557, 34059, + 3850, 34058, 3849, 20564, 3881, 7743, 32616, 28961, 8155, 3890, 34101, + 19800, 32049, 29647, 2509, 10270, 8173, 25795, 3896, 34103, 2731, 2737, + 2738, 27545, 32618, 15970, 34076, 3888, 27911, 27090, 3831, 3869, 34051, + 34108, 34072, 34026, 28859, 5822, 26956, 3744, 4958, 970, 25895, 6179, + 8381, 8380, 29568, 13106, 102, 14650, 26492, 35478, 32508, 32509, 32514, + 32511, 32513, 32512, 32510, 32507, 33966, 34038, 34080, 3876, 34099, + 13129, 18156, 22729, 13112, 11215, 20893, 16465, 27615, 32781, 24571, + 26787, 2507, 31672, 13327, 5696, 19675, 33695, 20488, 27708, 27543, 5702, + 2585, 26680, 33976, 33992, 33995, 33971, 33979, 33989, 3767, 3783, 3786, + 3762, 3770, 3780, 3889, 34041, 34022, 3795, 34081, 3816, 3801, 34013, + 15971, 26945, 12340, 3512, 3513, 23616, 23615, 23617, 33964, 11220, + 32632, 26984, 26985, 26986, 26987, 26988, 26989, 26990, 26991, 3906, + 26983, 26419, 26524, 33967, 10532, 10533, 10534, 10535, 10536, 10537, + 34006, 34008, 3748, 3750, 23492, 23493, 10572, 10575, 10574, 10573, + 34032, 3812, 14651, 968, 8389, 29561, 27703, 345, 13151, 13323, 29562, + 2520, 13149, 26075, 32026, 32025, 33939, 15829, 10972, 10973, 16327, + 20892, 20891, 20890, 33657, 15965, 22307, 22284, 22297, 21059, 10694, + 32634, 8372, 13311, 24381, 5832, 26228, 16466, 33685, 6182, 3851, 27758, + 27748, 26951, 27752, 28966, 3449, 29494, 34029, 34030, 3809, 3810, 28962, + 29649, 26961, 3883, 32048, 32546, 32545, 34023, 8390, 10614, 25794, + 26665, 5764, 15471, 6237, 5833, 24643, 355, 3897, 34106, 3829, 34049, + 11061, 15328, 19472, 29537, 13100, 3894, 27063, 27064, 2516, 15256, + 26499, 27211, 19562, 16348, 3760, 27916, 6214, 5824, 15934, 13324, 13325, + 20988, 23510, 32617, 13185, 13146, 13114, 27699, 29243, 28857, 16005, + 26511, 31791, 16363, 15232, 13312, 9637, 34033, 3884, 32665, 3887, 20580, + 34074, 34042, 31684, 31671, 226, 12462, 26972, 26966, 33687, 34188, + 20578, 26501, 32705, 34062, 3914, 5998, 15254, 23610, 15290, 2741, 15246, + 26077, 15336, 25778, 15292, 18638, 27761, 26074, 20894, 29566, 13181, + 13179, 15275, 13175, 3813, 34037, 29173, 29594, 6510, 25776, 3761, 26076, + 15294, 26677, 27763, 15245, 25777, 12339, 12336, 12334, 28851, 12335, + 15268, 32567, 28854, 31677, 25775, 15320, 28849, 3811, 34034, 12337, + 6499, 15319, 28964, 32320, 15253, 29172, 15313, 2730, 12338, 15270, 8386, + 27762, 24329, 20577, 32703, 20562, 32708, 3915, 34066, 34031, 3798, + 15272, 19797, 22304, 15335, 15303, 15304, 15264, 15265, 15287, 15286, + 9649, 15273, 15279, 15249, 27392, 13150, 27391, 22291, 22294, 22285, + 22286, 22292, 22295, 15283, 15296, 15282, 15295, 19789, 19787, 22290, + 22293, 10597, 10595, 10594, 10591, 10590, 10593, 10592, 10598, 10596, + 10589, 10608, 10605, 10604, 10601, 10600, 10603, 10602, 10609, 10607, + 10599, 10587, 10584, 10583, 10580, 10579, 10582, 10581, 10588, 10586, + 10578, 15331, 15334, 15291, 15261, 15309, 15297, 15316, 11053, 15300, + 32502, 15322, 10233, 15260, 3864, 32040, 32043, 3865, 15247, 15248, + 29555, 15259, 27216, 19557, 2597, 13196, 15288, 15327, 24721, 9643, + 24723, 6286, 34117, 3921, 3923, 3922, 15250, 15252, 15251, 31678, 15321, + 33960, 15332, 25789, 10905, 32023, 34105, 26505, 25785, 25784, 19512, + 27168, 25896, 27074, 29760, 33643, 21756, 20508, 21577, 29522, 29523, + 34021, 969, 12394, 20576, 32684, 19494, 27159, 13204, 18144, 18143, + 19453, 19452, 19493, 20523, 20512, 32653, 20589, 34014, 34015, 34016, + 34087, 34090, 21757, 21751, 21760, 21754, 21759, 21753, 21758, 21752, + 21761, 21755, 32749, 11043, 964, 7722, 27131, 20513, 20518, 20511, 20515, + 20520, 20510, 20514, 20519, 20516, 20521, 20522, 4624, 4369, 4497, 4370, + 4561, 4434, 4498, 4371, 4593, 4466, 4530, 4403, 4562, 4435, 4499, 4372, + 4609, 4482, 4546, 4419, 4578, 4451, 4515, 4388, 4594, 4467, 4531, 4404, + 4563, 4436, 4500, 4373, 4617, 4490, 4554, 4427, 4586, 4459, 4523, 4396, + 4602, 4475, 4539, 4412, 4571, 4444, 4508, 4381, 4610, 4483, 4547, 4420, + 4579, 4452, 4516, 4389, 4595, 4468, 4532, 4405, 4564, 4437, 4501, 4374, + 4621, 4494, 4558, 4431, 4590, 4463, 4527, 4400, 4606, 4479, 4543, 4416, + 4575, 4448, 4512, 4385, 4614, 4487, 4551, 4424, 4583, 4456, 4520, 4393, + 4599, 4472, 4536, 4409, 4568, 4441, 4505, 4378, 4618, 4491, 4555, 4428, + 4587, 4460, 4524, 4397, 4603, 4476, 4540, 4413, 4572, 4445, 4509, 4382, + 4611, 4484, 4548, 4421, 4580, 4453, 4517, 4390, 4596, 4469, 4533, 4406, + 4565, 4438, 4502, 4375, 4623, 4496, 4560, 4433, 4592, 4465, 4529, 4402, + 4608, 4481, 4545, 4418, 4577, 4450, 4514, 4387, 4616, 4489, 4553, 4426, + 4585, 4458, 4522, 4395, 4601, 4474, 4538, 4411, 4570, 4443, 4507, 4380, + 4620, 4493, 4557, 4430, 4589, 4462, 4526, 4399, 4605, 4478, 4542, 4415, + 4574, 4447, 4511, 4384, 4613, 4486, 4550, 4423, 4582, 4455, 4519, 4392, + 4598, 4471, 4535, 4408, 4567, 4440, 4504, 4377, 4622, 4495, 4559, 4432, + 4591, 4464, 4528, 4401, 4607, 4480, 4544, 4417, 4576, 4449, 4513, 4386, + 4615, 4488, 4552, 4425, 4584, 4457, 4521, 4394, 4600, 4473, 4537, 4410, + 4569, 4442, 4506, 4379, 4619, 4492, 4556, 4429, 4588, 4461, 4525, 4398, + 4604, 4477, 4541, 4414, 4573, 4446, 4510, 4383, 4612, 4485, 4549, 4422, + 4581, 4454, 4518, 4391, 4597, 4470, 4534, 4407, 4566, 4439, 4503, 4376, + 27318, 27317, 19656, 27263, 19503, 27319, 19658, 27265, 11000, 32730, + 32767, 11021, 19660, 27267, 19640, 27311, 27320, 27238, 32732, 11004, + 27250, 27249, 27313, 27315, 27314, 19605, 27257, 19659, 27266, 19583, + 27235, 19603, 27231, 24681, 24661, 24687, 24660, 29059, 29071, 24686, + 24659, 29056, 29070, 27337, 13098, 29057, 24657, 13099, 27338, 24658, + 24685, 33948, 2500, 2499, 2502, 2503, 27217, 19556, 32426, 4083, 32428, + 32427, 20560, 20555, 961, 7719, 27226, 19572, 27924, 27242, 19588, 27234, + 19501, 32770, 19462, 19461, 32641, 32640, 19463, 32642, 19460, 32639, + 19619, 27281, 32744, 11038, 19613, 27275, 32741, 11035, 19618, 27280, + 32743, 11037, 19612, 27274, 32740, 11034, 19615, 32739, 27279, 11032, + 19617, 19611, 27277, 27272, 19616, 19610, 27278, 27273, 32738, 11033, + 27143, 12479, 32324, 19576, 27228, 27227, 19756, 19579, 13729, 29620, + 19578, 29746, 19547, 27148, 32650, 10978, 32522, 35491, 35492, 19539, + 27201, 19541, 27203, 35486, 35482, 35487, 35483, 19524, 27183, 19522, + 27180, 19521, 27181, 19456, 27124, 19457, 27130, 10918, 10943, 19465, + 27134, 10893, 33670, 22179, 27129, 22180, 948, 5, 29185, 29186, 32543, + 27080, 949, 27081, 25218, 25217, 22178, 22177, 22172, 22171, 22176, + 22174, 22175, 22173, 27103, 12441, 12440, 12438, 12439, 6226, 6514, 6501, + 6505, 6502, 6227, 6219, 6228, 32635, 6509, 6232, 6447, 6515, 6218, 6220, + 29486, 29481, 29552, 29538, 29539, 32578, 32501, 32499, 27540, 32498, + 27194, 19529, 33640, 4100, 4101, 3913, 32331, 32332, 34046, 3820, 19544, + 27206, 19473, 27144, 16164, 32258, 16241, 10971, 29429, 16166, 27943, + 12480, 12481, 16007, 13613, 32015, 10983, 10984, 3799, 3834, 34007, 3749, + 12493, 12496, 12492, 12495, 12491, 12494, 27409, 27075, 29018, 27076, + 3737, 3736, 10925, 32518, 19563, 27212, 32333, 22915, 24087, 24085, + 24086, 24095, 24094, 24090, 24091, 32580, 32579, 24089, 23317, 29645, + 26942, 13142, 16322, 16314, 6519, 966, 19872, 19873, 19874, 16315, 26944, + 16319, 16316, 16320, 16318, 16321, 16317, 16463, 18145, 35488, 35489, + 35490, 26779, 26784, 26782, 26778, 26781, 26780, 26783, 22908, 22909, + 22911, 22910, 26775, 26776, 33684, 23609, 23608, 27747, 28939, 23604, + 23605, 6448, 23606, 6242, 26777, 22912, 23607, 16337, 27222, 35484, 362, + 16333, 32627, 32628, 16332, 16331, 32629, 32625, 16330, 32624, 16329, + 32626, 16334, 7735, 7741, 10926, 10927, 7736, 20496, 20504, 10916, 10917, + 32576, 32577, 28879, 28878, 20501, 20498, 20506, 20497, 20505, 20495, + 20499, 20494, 28929, 20503, 20502, 35485, 35481, 12485, 16008, 32516, + 32517, 32326, 32325, 28723, 8174, 12486, 352, 1045, 12476, 26785, 12477, + 10906, 32571, 32034, 12484, 12488, 19773, 13748, 19774, 13749, 19765, + 13735, 19768, 13738, 19766, 13736, 19767, 13737, 19764, 13739, 19758, + 13731, 19757, 13730, 19755, 13727, 19753, 13725, 19752, 13724, 19751, + 13728, 19754, 13726, 28864, 28862, 28865, 28863, 10953, 10952, 10949, + 10948, 28722, 28721, 28720, 28719, 10919, 10921, 10920, 13743, 13732, + 19762, 13746, 19763, 13747, 28937, 18153, 28938, 18154, 12482, 26864, + 29636, 26865, 29637, 26867, 29639, 26863, 29635, 26866, 29638, 26862, + 29634, 10922, 10931, 29631, 29759, 29629, 29757, 29630, 29758, 29628, + 29756, 29623, 29751, 29624, 29752, 29622, 29750, 29625, 29753, 29311, + 29398, 7730, 7732, 7731, 7733, 29618, 29745, 29619, 29744, 29748, 29747, + 12393, 26683, 32496, 13170, 24654, 27928, 27929, 27925, 26506, 33642, + 10940, 33641, 10938, 20507, 27930, 27927, 27926, 10907, 10935, 10929, + 27084, 10709, 33655, 33654, 10977, 26272, 26271, 32521, 32524, 32515, + 32528, 32527, 10951, 10950, 32525, 18142, 10934, 34113, 24096, 24670, + 24696, 29068, 29080, 19506, 19609, 32734, 11028, 24667, 24693, 29065, + 29077, 19508, 32645, 27246, 27247, 19592, 19593, 29422, 29415, 29425, + 29419, 10525, 10526, 10524, 10523, 10889, 3836, 34047, 3911, 34116, 3854, + 34064, 34044, 3817, 15945, 3835, 3839, 34056, 3842, 34060, 3872, 3873, + 34077, 3819, 34045, 3907, 34114, 19459, 32027, 19458, 20517, 19648, + 19647, 19649, 19650, 19584, 19596, 19595, 19643, 19645, 19644, 19580, + 33947, 12478, 27077, 19573, 27233, 27232, 19674, 27327, 27078, 27224, + 32323, 19575, 19574, 27225, 11017, 27923, 27921, 34057, 3874, 34078, + 3861, 34067, 15280, 15293, 15257, 15255, 15258, 28866, 2595, 28867, 2594, + 3628, 27922, 19625, 32753, 27296, 11006, 19510, 32649, 24691, 24665, + 29063, 29075, 19637, 32764, 27308, 11018, 7727, 959, 19636, 32755, 27307, + 11008, 35762, 35762, 24692, 24666, 29064, 29076, 19627, 32763, 27298, + 11016, 15962, 33664, 19626, 32754, 27297, 11007, 19638, 32765, 27309, + 11019, 19608, 32733, 27260, 11027, 956, 957, 955, 958, 27068, 27069, + 24566, 24567, 13176, 27261, 35762, 29855, 32038, 32042, 32039, 32041, + 3827, 3905, 3866, 3807, 11010, 11011, 32757, 32758, 19630, 27301, 19629, + 27300, 3752, 3753, 3754, 3755, 3756, 3758, 3757, 3759, 27115, 27116, + 27113, 27114, 27110, 27112, 27109, 27111, 32774, 32638, 26082, 26081, + 26083, 2736, 6517, 6231, 3878, 3797, 32544, 15944, 3912, 3846, 3838, + 3841, 3844, 24572, 32430, 4077, 19785, 27393, 34036, 27394, 29383, 32620, + 14275, 26791, 26790, 26789, 26788, 32495, 26891, 2515, 15999, 26664, + 24349, 34061, 3800, 32537, 9639, 15230, 35570, 18035, 1042, 97, 33772, + 26801, 19484, 27151, 29569, 29570, 19646, 32769, 27316, 11023, 12498, + 12497, 27759, 27535, 27533, 27534, 27532, 27536, 27537, 12483, 32631, + 27757, 10974, 26424, 27091, 15473, 13513, 13515, 13549, 13523, 13519, + 13550, 13557, 13520, 13556, 13529, 13525, 13524, 13518, 13560, 13531, + 13532, 13533, 13534, 13536, 13538, 13542, 13546, 13559, 13521, 13558, + 13535, 13537, 13539, 13548, 13517, 13541, 13552, 13551, 13553, 13543, + 13555, 13544, 13545, 13554, 13527, 13514, 13526, 13522, 13528, 13540, + 13547, 13530, 13516, 13561, 13563, 13597, 13571, 13567, 13598, 13605, + 13568, 13604, 13577, 13573, 13572, 13566, 13608, 13579, 13580, 13581, + 13582, 13584, 13586, 13590, 13594, 13607, 13569, 13606, 13583, 13585, + 13587, 13596, 13565, 13589, 13600, 13599, 13601, 13591, 13603, 13592, + 13593, 13602, 13575, 13562, 13574, 13570, 13576, 13588, 13595, 13578, + 13564, 18375, 19017, 18378, 18467, 18483, 18751, 19240, 18318, 18936, + 18364, 18996, 18628, 19407, 18197, 18395, 18532, 18533, 19360, 18605, + 19377, 19359, 18323, 18943, 19305, 18864, 19281, 19097, 18675, 19432, + 23035, 18508, 18632, 8182, 8276, 8232, 8326, 8196, 8290, 8193, 8287, + 8237, 8331, 8227, 8321, 8231, 8325, 8198, 8292, 8229, 8323, 8235, 8329, + 8201, 8295, 8206, 8300, 8238, 8332, 8239, 8333, 8202, 8296, 8207, 8301, + 8234, 8328, 8236, 8330, 8228, 8322, 8230, 8324, 8240, 8334, 8204, 8298, + 8200, 8294, 8233, 8327, 8223, 8317, 8190, 8284, 8218, 8312, 8186, 8280, + 8191, 8285, 8192, 8286, 8187, 8281, 8216, 8310, 8226, 8320, 8188, 8282, + 8214, 8308, 8217, 8311, 8181, 8275, 8189, 8283, 8209, 8303, 8210, 8304, + 8205, 8299, 8212, 8306, 8211, 8305, 8208, 8302, 8215, 8309, 8213, 8307, + 8221, 8315, 8219, 8313, 8220, 8314, 8222, 8316, 8336, 8337, 8338, 8340, + 8341, 8335, 8339, 8184, 8278, 8185, 8279, 8180, 8179, 8178, 8183, 8277, + 35762, 35762, 35762, 35762, 35762, 8274, 8271, 8272, 8273, 8269, 8270, + 8342, 13372, 13398, 13383, 13404, 13405, 13403, 13393, 13394, 13406, + 13387, 13396, 13399, 13401, 13407, 13389, 13392, 13397, 13391, 13395, + 13408, 13388, 13386, 13382, 13402, 13390, 13378, 13381, 13385, 13380, + 13379, 13400, 13384, 13373, 13377, 13375, 13410, 13374, 13376, 35762, + 13409, 35762, 35762, 35762, 35762, 35762, 13371, 35762, 35762, 32273, + 32284, 32285, 32278, 32280, 32263, 32302, 32274, 32277, 32275, 32276, + 32312, 32301, 32281, 32267, 32283, 32286, 32262, 32271, 32287, 32300, + 32282, 32268, 32307, 32272, 32313, 32295, 32261, 32269, 32303, 32304, + 32305, 32266, 32270, 32306, 32315, 32297, 32298, 32279, 32265, 32260, + 32288, 32290, 32289, 32291, 32292, 32299, 32293, 32308, 32309, 32310, + 32294, 32264, 32296, 32311, 32314, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 32316, 32317, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 32259, 12933, + 12750, 12837, 12877, 12853, 12540, 12915, 12578, 12768, 12759, 12660, + 12993, 12608, 12593, 12924, 12884, 12569, 12784, 12797, 12645, 12649, + 12648, 12647, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 12867, 12873, 12871, 12868, 12870, 12869, 12872, 35762, 12559, + 12565, 12563, 12560, 12562, 12561, 12564, 35762, 12983, 12989, 12987, + 12984, 12986, 12985, 12988, 35762, 12552, 12558, 12556, 12553, 12555, + 12554, 12557, 35762, 12819, 12825, 12823, 12820, 12822, 12821, 12824, + 35762, 12728, 12734, 12732, 12729, 12731, 12730, 12733, 35762, 12960, + 12966, 12964, 12961, 12963, 12962, 12965, 35762, 12671, 12677, 12675, + 12672, 12674, 12673, 12676, 35762, 7788, 7826, 7823, 7790, 7820, 7821, + 7827, 7794, 7795, 7796, 7803, 7825, 7797, 7791, 7819, 7816, 7818, 7822, + 7806, 7805, 7824, 7792, 7828, 7802, 7789, 7815, 7811, 7813, 7800, 7814, + 7787, 7799, 27126, 27125, 19528, 27187, 19477, 27141, 26965, 26964, + 10892, 19531, 27192, 26974, 19511, 27167, 11222, 26270, 13169, 27086, + 15997, 10891, 11005, 32717, 10894, 10942, 16344, 26229, 15993, 32329, + 19492, 27157, 32328, 32327, 19554, 27198, 32439, 32442, 4088, 4091, + 19516, 27172, 19476, 27146, 32574, 25768, 29482, 13140, 27101, 33667, + 27330, 34176, 32548, 26963, 26973, 32559, 10224, 10225, 32549, 32433, + 32584, 32045, 29582, 33669, 34159, 5701, 10910, 27100, 10913, 10231, + 10930, 16345, 16346, 20533, 20534, 10928, 10888, 32526, 22281, 26268, + 26922, 8345, 8383, 8382, 32417, 22280, 22282, 19526, 27185, 19525, 27184, + 32431, 32432, 4078, 4079, 25219, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 7615, + 7568, 7618, 7617, 7616, 7611, 7539, 7636, 7650, 7649, 7572, 7619, 7632, + 7631, 7601, 7600, 7599, 7598, 7628, 7637, 7627, 7626, 7587, 7586, 7590, + 7614, 35762, 7571, 7634, 7608, 7573, 7606, 7566, 7642, 7641, 7580, 7610, + 7609, 7620, 7570, 7574, 7595, 7537, 7579, 7630, 7629, 7542, 7625, 7553, + 7648, 7647, 7646, 7645, 7603, 7633, 7613, 7578, 7651, 7541, 7540, 7602, + 7607, 7584, 7583, 7582, 7638, 7569, 7644, 7643, 7557, 7621, 7589, 7556, + 7555, 7581, 7565, 7622, 7640, 7639, 7567, 7549, 7597, 7596, 7552, 7550, + 7605, 7604, 7612, 7543, 7559, 7551, 7561, 7547, 7577, 7576, 7575, 7545, + 7588, 7564, 7538, 7585, 7546, 7563, 7554, 7623, 7624, 7548, 7594, 7544, + 7592, 7560, 7593, 7562, 7635, 7591, 7558, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 16662, 16644, + 16578, 16698, 16686, 16630, 16730, 16645, 16658, 16641, 16593, 16597, + 16582, 16567, 16633, 16719, 16665, 16636, 16670, 16747, 16704, 16675, + 16627, 16732, 16576, 16687, 16563, 16667, 16538, 16656, 16592, 16590, + 16685, 16613, 16615, 16595, 16545, 16744, 16570, 16678, 16632, 16714, + 16637, 16565, 16703, 16654, 16676, 16745, 16663, 16728, 16588, 16692, + 16579, 16647, 16731, 16694, 16553, 16712, 16554, 16706, 16624, 16621, + 16584, 16622, 16555, 16673, 16684, 16577, 16540, 16715, 16660, 16717, + 16683, 16657, 16727, 16638, 16707, 16572, 16738, 16583, 16566, 16612, + 16561, 16705, 16737, 16604, 16562, 16599, 16581, 16620, 16699, 16601, + 16569, 16585, 16668, 16634, 16648, 16722, 16711, 16643, 16749, 16602, + 16549, 16695, 16580, 16740, 16716, 16575, 16598, 16700, 16536, 16709, + 16702, 16726, 16616, 16560, 16710, 16541, 16677, 16696, 16635, 16661, + 16691, 16610, 16666, 16539, 16669, 16589, 16556, 16649, 16650, 16688, + 16537, 16652, 16723, 16664, 16550, 16708, 16568, 16617, 16721, 16631, + 16546, 16736, 16564, 16739, 16689, 16629, 16701, 16733, 16557, 16671, + 16542, 16690, 16680, 16679, 16611, 16552, 16559, 16543, 16653, 16735, + 16571, 16743, 16574, 16734, 16614, 16646, 16619, 16655, 16697, 16693, + 16672, 16548, 16746, 16600, 16639, 16718, 16642, 16713, 16640, 16742, + 16607, 16591, 16625, 16608, 16628, 16551, 16720, 16623, 16603, 16681, + 16558, 16618, 16605, 16544, 16682, 16573, 16741, 16626, 16748, 16651, + 16547, 16596, 16609, 16725, 16587, 16674, 16659, 16594, 16724, 16586, + 16729, 16606, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 16031, 16029, + 16030, 16028, 16043, 16039, 16038, 16035, 16036, 16037, 16033, 16032, + 16040, 16034, 16044, 16042, 16128, 16027, 16126, 10698, 16362, 16127, + 16026, 16046, 19455, 27123, 19474, 27142, 19470, 27139, 19538, 27200, + 19464, 27133, 26803, 13506, 19536, 27196, 19540, 27202, 19543, 27205, + 19542, 27204, 33946, 27083, 10924, 20531, 26804, 15127, 15120, 15117, + 15123, 15122, 15125, 15124, 15128, 15126, 16124, 16123, 16045, 16122, + 14786, 14785, 33952, 33647, 33650, 33648, 33651, 33649, 6500, 16120, + 15121, 15119, 15118, 33646, 21138, 26422, 16125, 16121, 35762, 15849, + 15835, 15851, 15929, 15853, 15931, 15850, 15928, 15852, 15930, 15890, + 15880, 15892, 15882, 15894, 15884, 15891, 15881, 15893, 15883, 15854, + 15915, 15856, 15917, 15858, 15919, 15855, 15916, 15857, 15918, 15910, + 15875, 15912, 15877, 15848, 15914, 15879, 15911, 15876, 15913, 15878, + 15870, 15872, 15874, 15871, 15873, 15885, 15865, 15900, 15887, 15859, + 15902, 15889, 15868, 15904, 15886, 15866, 15901, 15888, 15867, 15903, + 15895, 15897, 15899, 15896, 15898, 15842, 15924, 15844, 15926, 15843, + 15925, 15905, 15907, 15909, 15906, 15908, 15838, 15920, 15922, 15921, + 15923, 15869, 15927, 15845, 15846, 35762, 35762, 7985, 7984, 16987, + 16986, 15933, 15932, 15834, 16984, 16914, 16843, 16916, 16977, 16918, + 16979, 16915, 16976, 16917, 16978, 16939, 16929, 16941, 16931, 16943, + 16933, 16940, 16930, 16942, 16932, 16919, 16964, 16921, 16966, 16923, + 16968, 16920, 16965, 16922, 16967, 16954, 16924, 16956, 16926, 16901, + 16958, 16928, 16955, 16925, 16957, 16927, 16881, 16883, 16885, 16882, + 16884, 16934, 16858, 16944, 16936, 16852, 16946, 16938, 16861, 16948, + 16935, 16859, 16945, 16937, 16860, 16947, 16876, 16862, 16879, 16877, + 16878, 16906, 16973, 16908, 16975, 16907, 16974, 16949, 16951, 16953, + 16950, 16952, 16902, 16969, 16971, 16970, 16972, 16880, 16963, 16896, + 16897, 16959, 16961, 16960, 16962, 16983, 16985, 16982, 16980, 16981, + 35762, 35762, 35762, 35762, 35762, 4063, 4071, 4070, 4068, 4067, 4074, + 4039, 4059, 4027, 4055, 4069, 4065, 4072, 4076, 4052, 4058, 4062, 4073, + 4051, 4057, 4061, 4007, 4043, 4019, 4024, 4008, 4025, 4010, 4050, 4012, + 4020, 4013, 4021, 4026, 4032, 4017, 4038, 4075, 4040, 4029, 4035, 4046, + 4042, 35762, 15039, 15083, 15040, 15045, 15046, 15048, 15075, 15086, + 15061, 15062, 15064, 15066, 15073, 15069, 15065, 15072, 15041, 15051, + 15085, 15052, 15076, 15088, 15033, 15028, 15082, 15027, 15038, 15074, + 15059, 15112, 15023, 15026, 15109, 15110, 15030, 15029, 15096, 15095, + 15113, 15092, 15093, 15114, 15101, 15115, 15091, 15090, 15094, 15105, + 15031, 15111, 15032, 15116, 15084, 15047, 15050, 15049, 15063, 15070, + 15067, 15068, 15071, 15042, 15044, 15043, 15037, 15058, 15056, 15053, + 15054, 15057, 15055, 15035, 15036, 15078, 15079, 15081, 15080, 15077, + 15060, 15089, 15098, 15100, 15099, 15034, 15087, 15097, 15102, 15103, + 15104, 15107, 15106, 15108, 15024, 15025, 35762, 16020, 16023, 16022, + 16018, 16016, 16012, 16019, 16014, 16010, 16013, 16021, 16017, 16011, + 16024, 16025, 16015, 4064, 4053, 4066, 4030, 4023, 4022, 4049, 4045, + 4037, 4014, 4033, 4018, 4036, 4041, 4009, 4011, 4016, 4048, 4044, 4034, + 4005, 4006, 4004, 4003, 4028, 4060, 4054, 4002, 4031, 4056, 4047, 4015, + 7680, 7683, 7684, 7682, 7671, 7656, 7662, 7653, 7661, 7675, 7663, 7659, + 7654, 7660, 7657, 7686, 7652, 7670, 7666, 7678, 7685, 7655, 7665, 7674, + 7673, 7679, 7677, 7667, 7669, 7681, 7676, 7672, 7664, 7658, 7668, 7687, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 16041, 16899, 16911, 16912, 16900, 16910, 16886, 16888, 16890, + 16887, 16889, 16913, 16891, 16893, 16895, 16892, 16894, 26284, 26288, + 26300, 26294, 26286, 26292, 26296, 26302, 26277, 26275, 26282, 26298, + 26290, 26280, 26285, 26289, 26301, 26295, 26287, 26293, 26297, 26303, + 26278, 26276, 26283, 26299, 26291, 26281, 26279, 26341, 26340, 35762, + 26339, 26335, 26333, 26314, 26312, 26332, 26324, 26309, 26318, 26334, + 26317, 26311, 26337, 26336, 26316, 26308, 26331, 26329, 26338, 26326, + 26319, 26327, 26310, 26305, 26315, 26322, 26306, 26328, 26330, 26307, + 26320, 26304, 26313, 26321, 26325, 26323, 6319, 6307, 6329, 6308, 6473, + 6487, 6475, 6457, 6454, 6470, 6468, 6450, 26421, 6488, 6494, 6493, 6490, + 6489, 6492, 6491, 6496, 6495, 6474, 6476, 6482, 6481, 6478, 6477, 6267, + 6271, 6283, 6277, 6269, 6275, 6279, 6260, 6258, 6256, 6265, 6281, 6273, + 6263, 6268, 6272, 6284, 6278, 6270, 6276, 6280, 6261, 6259, 6257, 6266, + 6282, 6274, 6264, 6394, 6393, 6262, 18033, 6342, 6337, 6335, 6304, 6302, + 6334, 6325, 6299, 6317, 6336, 6315, 6301, 6339, 6338, 6313, 6297, 6328, + 6333, 6306, 6330, 6318, 6331, 6300, 6293, 6309, 6324, 6314, 6303, 6327, + 6298, 6341, 6290, 6340, 6321, 6294, 6292, 6305, 6295, 6310, 6311, 6323, + 6312, 6322, 6332, 6326, 6296, 6320, 6288, 6316, 6480, 6479, 6484, 6483, + 6456, 6458, 6464, 6463, 6460, 6459, 6462, 6461, 6466, 6465, 6453, 16111, + 16114, 16115, 16053, 16116, 16112, 16113, 16052, 16118, 16119, 16117, + 16085, 29271, 29240, 29242, 19871, 6388, 6390, 6392, 6389, 6391, 6351, + 6353, 6355, 6352, 6354, 6371, 6373, 6375, 6372, 6374, 6376, 6378, 6380, + 6377, 6379, 6361, 6363, 6365, 6362, 6364, 6346, 6348, 6350, 6347, 6349, + 6356, 6358, 6360, 6357, 6359, 6385, 6387, 6386, 6366, 6368, 6370, 6367, + 6369, 6381, 6383, 6382, 6384, 29238, 29202, 29200, 29199, 29201, 29274, + 29275, 29434, 29241, 29234, 29364, 29368, 29281, 29283, 29282, 29246, + 29247, 29251, 29250, 29284, 29249, 29285, 29288, 29286, 29287, 29252, + 29253, 29295, 29296, 29297, 29294, 29293, 29404, 29405, 29408, 29406, + 29407, 29225, 29229, 29230, 29413, 29357, 29358, 29259, 29371, 29372, + 29206, 29380, 29378, 29379, 29209, 29266, 29265, 29208, 29267, 29260, + 29377, 29375, 29261, 29376, 29374, 29211, 29381, 29210, 29264, 29382, + 29262, 29263, 29321, 29322, 29325, 29324, 29323, 29331, 29332, 29333, + 29328, 29329, 29330, 29432, 29431, 29433, 29399, 29400, 29402, 29401, + 29397, 29396, 29414, 16109, 16110, 16092, 16094, 16101, 16100, 16107, + 16105, 16096, 16103, 16095, 16098, 16091, 16093, 16102, 16099, 16108, + 16106, 16097, 16104, 16086, 16090, 16089, 16088, 16087, 29269, 29224, + 29204, 29207, 29369, 29385, 29226, 29228, 29227, 29279, 29235, 29239, + 29236, 29237, 29216, 29373, 29356, 29338, 29320, 29280, 29302, 29326, + 29256, 29213, 29299, 29386, 29359, 29339, 29340, 29353, 29303, 29272, + 29298, 29350, 29254, 29412, 29341, 29354, 29233, 29305, 29245, 29360, + 29342, 29335, 29217, 29289, 29337, 29219, 29319, 29292, 29336, 29218, + 29318, 29291, 29315, 29316, 29370, 29301, 29352, 29255, 29393, 29394, + 29395, 29390, 29361, 29343, 29355, 29391, 29362, 29344, 29346, 29307, + 29347, 29392, 29363, 29345, 29348, 29308, 29349, 29300, 29317, 29203, + 29212, 29222, 29223, 29220, 29215, 29231, 29257, 29258, 29268, 29273, + 29304, 29290, 29306, 29312, 29313, 29310, 29314, 29327, 29334, 29351, + 29387, 29388, 29384, 29389, 29409, 29410, 29430, 29205, 29198, 16084, + 16069, 16057, 16076, 16075, 16082, 16080, 16071, 16078, 16070, 16073, + 16068, 16056, 16077, 16074, 16083, 16081, 16072, 16079, 16058, 16066, + 16064, 16063, 16060, 16059, 16062, 16061, 16067, 16065, 16054, 16055, + 29248, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 15811, + 15814, 15775, 15825, 15822, 15770, 15808, 15787, 15804, 15821, 15799, + 15805, 15780, 15782, 15792, 15826, 15779, 15823, 15763, 15769, 15767, + 15786, 15806, 15800, 15789, 15785, 15793, 15784, 15809, 15812, 15791, + 15777, 15801, 15783, 15798, 15778, 15813, 15796, 15794, 15773, 15772, + 15790, 15768, 15771, 15781, 15797, 15795, 15815, 15802, 15810, 15807, + 15819, 15774, 15817, 15765, 15816, 15818, 15820, 15776, 15824, 15788, + 15803, 15764, 15766, 34695, 34702, 34694, 34701, 34699, 34700, 34697, + 34698, 35470, 35471, 35468, 35469, 35467, 35465, 35466, 35474, 35475, + 35472, 35473, 35477, 35476, 35342, 34362, 34363, 34356, 34361, 34359, + 34360, 34357, 34358, 34366, 34367, 34364, 34365, 34347, 34345, 34346, + 34370, 34371, 34368, 34369, 34355, 34353, 34354, 34351, 34352, 34344, + 34350, 34349, 34348, 34376, 34377, 34372, 34375, 34374, 34373, 35074, + 35075, 35069, 35073, 35072, 35070, 35071, 35078, 35079, 35076, 35077, + 35063, 35061, 35062, 35082, 35083, 35080, 35081, 35067, 35068, 35060, + 35066, 35065, 35064, 35088, 35089, 35084, 35087, 35086, 35085, 34330, + 34331, 34324, 34329, 34327, 34328, 34325, 34326, 34334, 34335, 34332, + 34333, 34315, 34313, 34314, 34338, 34339, 34336, 34337, 34323, 34321, + 34322, 34319, 34320, 34312, 34318, 34317, 34316, 34342, 34343, 34340, + 34341, 34877, 34878, 34872, 34876, 34875, 34873, 34874, 34881, 34882, + 34879, 34880, 34885, 34886, 34883, 34884, 34891, 34892, 34887, 34890, + 34889, 34888, 34897, 34898, 34893, 34896, 34895, 34894, 34620, 34621, + 34615, 34619, 34618, 34616, 34617, 34624, 34625, 34622, 34623, 34609, + 34607, 34608, 34628, 34629, 34626, 34627, 34613, 34614, 34606, 34612, + 34611, 34610, 34634, 34630, 34633, 34632, 34631, 34856, 34857, 34851, + 34855, 34854, 34852, 34853, 34860, 34861, 34858, 34859, 34844, 34845, + 34842, 34843, 34864, 34865, 34862, 34863, 34871, 34870, 34849, 34850, + 34841, 34848, 34847, 34846, 34868, 34869, 34866, 34867, 34501, 34502, + 34499, 34500, 34497, 34498, 34495, 34496, 34494, 34492, 34493, 34511, + 34512, 34507, 34510, 34509, 34508, 34505, 34506, 34503, 34504, 35320, + 35321, 35314, 35319, 35317, 35318, 35315, 35316, 35324, 35325, 35322, + 35323, 35328, 35329, 35326, 35327, 35313, 35312, 35334, 35335, 35330, + 35333, 35332, 35331, 35340, 35341, 35336, 35339, 35338, 35337, 34479, + 34480, 34474, 34478, 34477, 34475, 34476, 34486, 34487, 34484, 34485, + 34468, 34467, 34490, 34491, 34488, 34489, 34483, 34481, 34482, 34472, + 34473, 34466, 34471, 34470, 34469, 35299, 35300, 35294, 35298, 35297, + 35295, 35296, 35306, 35307, 35304, 35305, 35287, 35288, 35285, 35286, + 35310, 35311, 35308, 35309, 35303, 35301, 35302, 35292, 35293, 35284, + 35291, 35290, 35289, 34453, 34454, 34448, 34452, 34451, 34449, 34450, + 34460, 34461, 34458, 34459, 34442, 34440, 34441, 34464, 34465, 34462, + 34463, 34457, 34455, 34456, 34446, 34447, 34439, 34445, 34444, 34443, + 34903, 34904, 34899, 34902, 34901, 34900, 34910, 34911, 34908, 34909, + 34914, 34915, 34912, 34913, 34907, 34905, 34906, 34920, 34921, 34916, + 34919, 34918, 34917, 34650, 34651, 34644, 34649, 34647, 34648, 34645, + 34646, 34654, 34655, 34652, 34653, 34639, 34638, 34636, 34637, 34635, + 34643, 34641, 34642, 34640, 35048, 35049, 35043, 35047, 35046, 35044, + 35045, 35052, 35050, 35051, 35037, 35035, 35036, 35058, 35059, 35056, + 35057, 35055, 35053, 35054, 35041, 35042, 35034, 35040, 35039, 35038, + 34588, 34589, 34583, 34587, 34586, 34584, 34585, 34598, 34599, 34596, + 34597, 34577, 34575, 34576, 34595, 34593, 34594, 34592, 34590, 34591, + 34581, 34582, 34574, 34580, 34579, 34578, 34604, 34605, 34600, 34603, + 34602, 34601, 34803, 34804, 34797, 34802, 34800, 34801, 34798, 34799, + 34807, 34808, 34805, 34806, 34787, 34788, 34785, 34786, 34811, 34812, + 34809, 34810, 34796, 34794, 34795, 34792, 34793, 34784, 34791, 34790, + 34789, 34817, 34818, 34813, 34816, 34815, 34814, 34557, 34558, 34551, + 34556, 34554, 34555, 34552, 34553, 34561, 34562, 34559, 34560, 34544, + 34545, 34542, 34543, 34569, 34570, 34567, 34568, 34565, 34566, 34563, + 34564, 34549, 34550, 34541, 34548, 34547, 34546, 34770, 34771, 34765, + 34769, 34768, 34766, 34767, 34774, 34775, 34772, 34773, 34759, 34757, + 34758, 34782, 34783, 34780, 34781, 34778, 34779, 34776, 34777, 34763, + 34764, 34756, 34762, 34761, 34760, 34517, 34518, 34513, 34516, 34514, + 34515, 34531, 34532, 34529, 34530, 34522, 34523, 34520, 34521, 34539, + 34540, 34537, 34538, 34535, 34536, 34533, 34534, 34527, 34528, 34519, + 34526, 34525, 34524, 34840, 34839, 34833, 34834, 34831, 34832, 34822, + 34820, 34821, 34837, 34838, 34835, 34836, 34830, 34828, 34829, 34826, + 34827, 34819, 34825, 34824, 34823, 34669, 34670, 34663, 34668, 34666, + 34667, 34664, 34665, 34673, 34674, 34671, 34672, 34658, 34659, 34656, + 34657, 34677, 34678, 34675, 34676, 34662, 34660, 34661, 34930, 34928, + 34929, 34933, 34934, 34931, 34932, 34923, 34924, 34922, 34937, 34938, + 34935, 34936, 34927, 34925, 34926, 34573, 34572, 34571, 34688, 34689, + 34686, 34687, 34681, 34682, 34679, 34680, 34692, 34693, 34690, 34691, + 34685, 34683, 34684, 35354, 35355, 35352, 35353, 35345, 35343, 35344, + 35351, 35349, 35350, 35348, 35346, 35347, 35417, 35418, 35412, 35416, + 35415, 35413, 35414, 35453, 35454, 35451, 35452, 35406, 35404, 35405, + 35457, 35458, 35455, 35456, 35450, 35448, 35449, 35410, 35411, 35403, + 35409, 35408, 35407, 35463, 35464, 35459, 35462, 35461, 35460, 34423, + 34424, 34417, 34422, 34420, 34421, 34418, 34419, 34427, 34428, 34425, + 34426, 34408, 34406, 34407, 34431, 34432, 34429, 34430, 34416, 34414, + 34415, 34412, 34413, 34405, 34411, 34410, 34409, 34437, 34438, 34433, + 34436, 34435, 34434, 35431, 35432, 35425, 35430, 35428, 35429, 35426, + 35427, 35435, 35436, 35433, 35434, 35424, 35422, 35423, 35421, 35419, + 35420, 35441, 35437, 35440, 35439, 35438, 35446, 35447, 35442, 35445, + 35444, 35443, 35020, 35021, 35015, 35019, 35018, 35016, 35017, 35024, + 35025, 35022, 35023, 35008, 35007, 35014, 35013, 35033, 35032, 35012, + 35006, 35011, 35010, 35009, 35030, 35031, 35026, 35029, 35028, 35027, + 35265, 35266, 35260, 35264, 35263, 35261, 35262, 35272, 35273, 35270, + 35271, 35254, 35252, 35253, 35276, 35277, 35274, 35275, 35269, 35267, + 35268, 35258, 35259, 35251, 35257, 35256, 35255, 35282, 35283, 35278, + 35281, 35280, 35279, 35201, 35202, 35196, 35200, 35199, 35197, 35198, + 35208, 35209, 35206, 35207, 35212, 35213, 35210, 35211, 35205, 35203, + 35204, 35216, 35217, 35214, 35215, 35222, 35223, 35218, 35221, 35220, + 35219, 35387, 35388, 35385, 35386, 35379, 35377, 35378, 35395, 35396, + 35393, 35394, 35391, 35392, 35389, 35390, 35383, 35384, 35376, 35382, + 35381, 35380, 35401, 35402, 35397, 35400, 35399, 35398, 34389, 34390, + 34387, 34388, 34381, 34382, 34379, 34380, 34397, 34398, 34395, 34396, + 34393, 34394, 34391, 34392, 34386, 34378, 34385, 34384, 34383, 34403, + 34404, 34399, 34402, 34401, 34400, 35169, 35168, 35148, 35147, 35160, + 35161, 35158, 35159, 35156, 35157, 35154, 35155, 35152, 35153, 35146, + 35151, 35150, 35149, 35166, 35167, 35162, 35165, 35164, 35163, 34969, + 34970, 34967, 34968, 34966, 34964, 34965, 34973, 34974, 34971, 34972, + 34979, 34980, 34975, 34978, 34977, 34976, 34985, 34986, 34981, 34984, + 34983, 34982, 35235, 35236, 35233, 35234, 35227, 35225, 35226, 35243, + 35244, 35241, 35242, 35239, 35240, 35237, 35238, 35231, 35232, 35224, + 35230, 35229, 35228, 35249, 35250, 35245, 35248, 35247, 35246, 35184, + 35185, 35182, 35183, 35173, 35171, 35172, 35188, 35189, 35186, 35187, + 35181, 35179, 35180, 35177, 35178, 35170, 35176, 35175, 35174, 35194, + 35195, 35190, 35193, 35192, 35191, 34744, 34745, 34738, 34743, 34741, + 34742, 34739, 34740, 34731, 34732, 34729, 34730, 34748, 34749, 34746, + 34747, 34736, 34737, 34728, 34735, 34734, 34733, 34754, 34755, 34750, + 34753, 34752, 34751, 35106, 35107, 35100, 35105, 35103, 35104, 35101, + 35102, 35093, 35094, 35091, 35092, 35110, 35111, 35108, 35109, 35098, + 35099, 35090, 35097, 35096, 35095, 35116, 35117, 35112, 35115, 35114, + 35113, 34718, 34719, 34712, 34717, 34715, 34716, 34713, 34714, 34706, + 34704, 34705, 34722, 34723, 34720, 34721, 34710, 34711, 34703, 34709, + 34708, 34707, 34726, 34727, 34724, 34725, 34952, 34953, 34946, 34951, + 34949, 34950, 34947, 34948, 34941, 34940, 34956, 34957, 34954, 34955, + 34945, 34939, 34944, 34943, 34942, 34962, 34963, 34958, 34961, 34960, + 34959, 35000, 35001, 34994, 34999, 34997, 34998, 34995, 34996, 34990, + 34988, 34989, 35004, 35005, 35002, 35003, 34992, 34993, 34987, 34991, + 35362, 35363, 35356, 35361, 35359, 35360, 35357, 35358, 35375, 35374, + 35366, 35367, 35364, 35365, 35372, 35373, 35368, 35371, 35370, 35369, + 35134, 35135, 35128, 35133, 35131, 35132, 35129, 35130, 35121, 35122, + 35119, 35120, 35138, 35139, 35136, 35137, 35126, 35127, 35118, 35125, + 35124, 35123, 35144, 35145, 35140, 35143, 35142, 35141, 35762, 35762, + 35762, 34309, 34282, 34280, 34287, 34261, 34297, 34268, 34270, 34286, + 34273, 34284, 34257, 34285, 34303, 34291, 34272, 34298, 34271, 34304, + 34262, 34265, 34258, 34267, 34288, 34299, 34311, 34276, 34307, 34292, + 34275, 34302, 34300, 34296, 34301, 34308, 34279, 34289, 34278, 34269, + 34277, 34310, 34266, 34293, 34283, 34260, 34259, 34264, 34274, 34294, + 34305, 34295, 34263, 34306, 34290, 34281, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 20474, 20463, 20462, 20446, 20444, + 20443, 20457, 20461, 20460, 20476, 20455, 20454, 20445, 20442, 20441, + 20478, 20453, 20477, 20465, 20468, 20469, 20452, 20459, 20480, 20458, + 20475, 20479, 20464, 20467, 20456, 20470, 20471, 20450, 20451, 20481, + 20472, 20447, 20448, 20449, 20473, 20437, 20440, 20438, 20436, 20439, + 20435, 20482, 20483, 33047, 33048, 32884, 33033, 33034, 33007, 32810, + 32817, 32920, 32893, 32927, 32867, 32993, 33021, 32845, 32838, 32796, + 32789, 32911, 33014, 32803, 32946, 32831, 32824, 32859, 32852, 32986, + 33000, 32965, 33028, 32906, 32952, 32873, 32934, 32979, 32972, 33056, + 33057, 32888, 32889, 33042, 33043, 33009, 32812, 32819, 32922, 32899, + 32929, 32870, 32995, 33023, 32847, 32840, 32798, 32791, 32915, 33016, + 32805, 32948, 32833, 32826, 32861, 32854, 32988, 33002, 32967, 33030, + 32907, 32957, 32878, 32936, 32981, 32974, 33054, 33055, 32959, 32886, + 32887, 33040, 33041, 33008, 32811, 32818, 32921, 32897, 32898, 32928, + 32869, 32994, 33022, 32846, 32839, 32797, 32790, 32914, 33015, 32804, + 32947, 32832, 32825, 32860, 32853, 32987, 33001, 32966, 33029, 32903, + 32904, 32956, 32877, 32935, 32980, 32973, 33051, 33052, 32882, 33037, + 33038, 33005, 32808, 32815, 32918, 32896, 32925, 32865, 32991, 33019, + 32843, 32836, 32794, 32787, 32913, 33012, 32801, 32944, 32829, 32822, + 32857, 32850, 32984, 32998, 32963, 33026, 32902, 32955, 32876, 32932, + 32977, 32970, 33058, 33059, 32890, 32891, 33044, 33045, 33010, 32813, + 32820, 32923, 32900, 32930, 32871, 32996, 33024, 32848, 32841, 32799, + 32792, 32916, 33017, 32806, 32949, 32834, 32827, 32862, 32855, 32989, + 33003, 32968, 33031, 32908, 32958, 32879, 32937, 32982, 32975, 33050, + 33053, 32961, 32880, 32881, 33036, 33039, 33004, 32807, 32814, 32917, + 32895, 32924, 32863, 32864, 32990, 33018, 32842, 32835, 32793, 32786, + 32912, 33011, 32800, 32938, 32828, 32821, 32856, 32849, 32983, 32997, + 32962, 33025, 32901, 32954, 32875, 32931, 32976, 32969, 33046, 33049, + 32960, 32883, 32885, 33032, 33035, 33006, 32809, 32816, 32919, 32892, + 32894, 32926, 32866, 32868, 32992, 33020, 32844, 32837, 32795, 32788, + 32909, 33013, 32802, 32945, 32830, 32823, 32858, 32851, 32985, 32999, + 32964, 33027, 32905, 32951, 32953, 32872, 32874, 32933, 32978, 32971, + 32950, 32910, 32783, 32784, 32785, 32941, 32942, 32939, 33063, 33066, + 33069, 33068, 33072, 33064, 33071, 33062, 33060, 33067, 33070, 33061, + 33065, 33079, 33081, 33078, 33077, 33074, 33073, 33076, 33075, 33082, + 33080, 32943, 32940, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 9978, 10178, 9867, 10026, 9818, 10120, 9922, 10081, + 9863, 10022, 9943, 10106, 9851, 10010, 9811, 10107, 9971, 10171, 9919, + 10078, 9820, 10122, 9920, 10079, 9859, 10018, 9852, 10011, 9916, 10075, + 9973, 10173, 9819, 10121, 9962, 10140, 9959, 10137, 9960, 10138, 9942, + 10105, 9849, 10008, 9864, 10023, 9993, 7842, 7834, 7785, 7835, 28868, + 7809, 7798, 7812, 7808, 7817, 7810, 7807, 7804, 7840, 7829, 9992, 9996, + 9873, 10032, 9871, 10030, 9983, 10183, 9861, 10020, 9869, 10028, 9824, + 10148, 9831, 10156, 9828, 10152, 9827, 10151, 9830, 10155, 9907, 10066, + 9957, 10135, 9865, 10024, 9860, 10019, 23047, 23084, 7793, 7801, 3393, + 2760, 3396, 2762, 3392, 3368, 3385, 3395, 2789, 3394, 2765, 3365, 3371, + 3370, 2763, 2769, 3384, 2788, 2782, 2768, 3380, 2776, 3375, 3381, 3374, + 3378, 2758, 2754, 2786, 2785, 2780, 3387, 3377, 3388, 3389, 2787, 2752, + 3361, 2781, 2784, 3364, 3390, 3362, 2749, 3373, 2767, 2774, 2791, 3367, + 3372, 2753, 2777, 2778, 2779, 3376, 3363, 2751, 2750, 3391, 2790, 2766, + 3366, 2764, 2755, 2771, 3369, 2770, 2773, 3386, 2761, 2775, 2772, 3383, + 2759, 3382, 2783, 3379, 2748, 2756, 2757, 2745, 2744, 3397, 3399, 2747, + 2746, 3398, 3400, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 23044, 23040, 23043, 23039, 23045, 23041, 23046, 23042, 23099, 23114, + 23142, 23121, 23104, 23098, 23113, 23141, 23120, 23103, 23100, 23115, + 23143, 23125, 23105, 23092, 23090, 23091, 23136, 23155, 23152, 23154, + 23153, 23133, 23303, 23304, 18285, 18884, 18286, 18885, 18325, 18946, + 18547, 19306, 18546, 19263, 18227, 18806, 18228, 18807, 18688, 18696, + 18201, 18762, 18202, 18763, 18203, 18764, 18199, 18760, 18200, 18761, + 18204, 18765, 18493, 19188, 18366, 18998, 18363, 18995, 18367, 18999, + 18213, 18783, 18385, 19022, 18416, 19096, 18417, 19098, 18463, 19136, + 18468, 19141, 18466, 19139, 18469, 19142, 18475, 19153, 18474, 19150, + 18490, 19178, 18495, 19191, 18588, 19356, 18597, 19368, 18592, 19363, + 18541, 19257, 18542, 19258, 18596, 19367, 18287, 18902, 18354, 18985, + 18229, 18808, 23312, 18844, 19042, 19056, 19079, 19190, 18673, 19301, + 19353, 18347, 18974, 18348, 18975, 18349, 18531, 19269, 18536, 19299, + 18350, 18977, 18351, 18978, 18352, 18979, 23119, 23088, 23165, 18514, + 19213, 18534, 19027, 18704, 18409, 19070, 18223, 18796, 18793, 18940, + 18207, 18768, 18294, 18909, 18593, 19364, 18594, 19365, 18595, 19366, + 18302, 18920, 18370, 19003, 18412, 19075, 18488, 19175, 18510, 19211, + 18321, 18492, 18517, 18373, 18513, 18695, 18535, 18538, 18357, 18230, + 18214, 18785, 18461, 19134, 18584, 19344, 18307, 18925, 18308, 18926, + 18309, 18927, 18458, 19125, 18196, 18757, 18221, 18511, 18634, 18234, + 18810, 18507, 19205, 35762, 35762, 35762, 35762, 35762, 18226, 18802, + 35762, 18837, 35762, 18834, 18398, 19055, 18516, 19231, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 23020, 23023, 23032, 18491, 19179, 18644, 23015, 23244, + 18678, 18642, 18643, 18640, 18641, 18639, 29798, 29800, 29810, 29802, + 29799, 29801, 29809, 29790, 29789, 29786, 29785, 29808, 29784, 29783, + 29788, 29787, 29778, 29777, 29772, 29771, 29780, 29779, 29774, 29773, + 29796, 29792, 29791, 29782, 29781, 29795, 29776, 29794, 29775, 29797, + 29793, 29812, 29814, 29815, 29813, 29811, 29803, 29804, 29805, 29806, + 29807, 35762, 35762, 35762, 24678, 24677, 24680, 24675, 24676, 24679, + 24672, 24671, 24674, 24673, 35762, 35762, 35762, 35762, 35762, 35762, + 26558, 26557, 26546, 26547, 26534, 26536, 26568, 26549, 26556, 26555, + 26539, 26550, 26560, 26559, 26565, 26570, 26552, 26551, 26538, 26573, + 26561, 26562, 26540, 26575, 26572, 26569, 26541, 26542, 26567, 26531, + 26576, 26578, 26563, 26577, 26571, 26574, 26566, 26545, 26564, 26583, + 26584, 26554, 26553, 26537, 26548, 26532, 26544, 26543, 26533, 26582, + 26585, 26535, 26581, 26586, 26580, 26579, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 27667, 27669, 27616, 27617, 27637, 27638, + 27633, 27634, 27628, 27629, 27630, 27631, 27660, 27661, 27618, 27635, + 27636, 27619, 27657, 27656, 27653, 27652, 27641, 27651, 27650, 27655, + 27654, 27643, 27625, 27624, 27621, 27620, 27642, 27627, 27626, 27623, + 27622, 27644, 27659, 27658, 27649, 27648, 27663, 27665, 27664, 27640, + 27632, 27645, 27646, 27647, 27662, 27639, 27682, 27683, 27694, 27695, + 27690, 27691, 27686, 27687, 27688, 27689, 27696, 27697, 27684, 27692, + 27693, 27685, 27668, 27666, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 27671, 27670, 27678, 27680, 27677, 27676, 27673, 27672, + 27675, 27674, 27681, 27679, 35762, 35762, 35762, 35762, 35762, 35762, + 7860, 7862, 7859, 7858, 7855, 7854, 7857, 7856, 7863, 7861, 7851, 7852, + 7847, 7848, 7849, 7850, 7846, 7853, 10463, 10456, 10465, 10458, 10457, + 10455, 10462, 10359, 10357, 10362, 10464, 10513, 10368, 10480, 17118, + 17120, 17117, 17116, 17113, 17112, 17115, 17114, 17121, 17119, 17082, + 17081, 17092, 17078, 17086, 17085, 17099, 17079, 17088, 17074, 17080, + 17084, 17083, 17094, 17091, 17089, 17095, 17098, 17093, 17097, 17087, + 17075, 17096, 17090, 17100, 17076, 17101, 17077, 17110, 17107, 17109, + 17108, 17111, 17106, 17104, 17105, 17102, 17103, 27041, 27038, 27032, + 27046, 27037, 27034, 27043, 27035, 27028, 27036, 27040, 27030, 27045, + 27044, 27042, 27048, 27047, 27039, 27027, 27031, 27033, 27029, 27049, + 27056, 27058, 27051, 27054, 27057, 27055, 27053, 27052, 27024, 27023, + 27026, 27025, 27059, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 27050, 14774, 14777, 14778, 14775, 14732, + 14733, 14741, 14735, 14737, 14740, 14734, 14730, 14736, 14738, 14731, + 14697, 14699, 14700, 14713, 14720, 14727, 14762, 14679, 14686, 14760, + 14764, 14710, 14783, 14766, 35762, 35762, 35762, 16437, 16435, 16439, + 16438, 16409, 16377, 16376, 16378, 16418, 16397, 16383, 16384, 16416, + 16410, 16417, 16379, 16380, 16381, 16393, 16394, 16382, 16391, 16392, + 16407, 16386, 16408, 16385, 16405, 16406, 16372, 16373, 16388, 16403, + 16404, 16374, 16375, 16387, 16395, 16396, 16389, 16390, 16413, 16415, + 16398, 16399, 16412, 16414, 16401, 16402, 16400, 16411, 16436, 16442, + 16444, 16445, 16446, 16440, 16441, 16443, 16448, 16447, 16368, 16369, + 16370, 16433, 16371, 16419, 16422, 16431, 16424, 16429, 16427, 16425, + 16423, 16420, 16421, 16426, 16434, 35762, 16432, 16455, 16457, 16454, + 16453, 16450, 16449, 16452, 16451, 16458, 16456, 35762, 35762, 35762, + 35762, 16428, 16430, 23922, 23920, 23915, 23912, 23918, 23998, 23986, + 23938, 23950, 23946, 23945, 23948, 23947, 23940, 23939, 23937, 24040, + 24042, 24039, 24038, 24035, 24034, 24037, 24036, 24043, 24041, 23949, + 23942, 23941, 23944, 23943, 35762, 5944, 5962, 5964, 5961, 5945, 5963, + 5953, 5952, 5949, 5948, 5924, 5925, 5947, 5946, 5951, 5950, 5926, 5928, + 5927, 5955, 5954, 5941, 5940, 5929, 5930, 5939, 5935, 5934, 5933, 5938, + 5937, 5931, 5932, 5936, 5960, 5958, 5957, 5959, 5942, 5943, 5956, 5969, + 5972, 5973, 5978, 5976, 5975, 5974, 5970, 5971, 5977, 5912, 5910, 5909, + 5911, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 5918, 5917, 5914, 5906, 5916, 5922, 5913, 5920, 5923, 5921, 5919, 5915, + 5908, 5907, 35762, 35762, 5985, 5987, 5984, 5983, 5980, 5979, 5982, 5981, + 5988, 5986, 35762, 35762, 5965, 5967, 5966, 5968, 23892, 23885, 23884, + 23889, 23888, 23882, 23881, 23880, 23878, 23877, 23879, 23883, 23894, + 23887, 23886, 23891, 23985, 23895, 23896, 23893, 23982, 23983, 23984, + 24013, 24015, 24014, 23867, 24009, 24000, 24001, 23931, 23932, 30279, + 30255, 30278, 30254, 30277, 30253, 30292, 30268, 30286, 30262, 30281, + 30257, 30280, 30256, 30297, 30273, 30287, 30263, 30290, 30266, 30285, + 30261, 30284, 30260, 30288, 30264, 30289, 30265, 30283, 30259, 30282, + 30258, 30291, 30267, 30295, 30271, 30299, 30275, 30296, 30272, 30294, + 30270, 30298, 30274, 30293, 30269, 30300, 30276, 30301, 30313, 30321, + 30318, 30317, 30323, 30324, 30302, 30322, 30319, 30320, 30312, 30316, + 30315, 30314, 30311, 30308, 30309, 30310, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 30304, 30305, 30307, 30306, 30303, 22359, 22360, 22318, 22335, 22346, + 22345, 22322, 22321, 22334, 22340, 22341, 22373, 22375, 22365, 22367, + 22366, 22313, 22310, 22312, 22362, 22363, 22377, 22378, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 12895, 12893, + 12892, 12891, 12890, 12894, 35762, 35762, 12589, 12587, 12586, 12585, + 12584, 12588, 35762, 35762, 12604, 12602, 12601, 12600, 12599, 12603, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 12545, + 12551, 12549, 12546, 12548, 12547, 12550, 35762, 12530, 12536, 12534, + 12531, 12533, 12532, 12535, 35762, 18776, 18752, 18782, 18777, 18873, + 19035, 19223, 19025, 19016, 19019, 19046, 19060, 18887, 18780, 18781, + 19130, 18981, 19272, 19271, 19273, 19274, 19233, 18672, 19177, 18835, + 19157, 18836, 19220, 19221, 18779, 19343, 19309, 19352, 19295, 19348, + 18799, 18800, 18801, 19384, 19381, 19382, 19383, 19395, 23002, 23225, + 23234, 23235, 23292, 19214, 18984, 19131, 19354, 18980, 14005, 18842, + 19304, 19277, 23289, 23138, 23162, 35762, 35762, 35762, 35762, 6167, + 6168, 6169, 6170, 6171, 6172, 6130, 6166, 6131, 6132, 6133, 6134, 6135, + 6095, 6096, 6097, 6098, 6099, 6100, 6136, 6137, 6138, 6139, 6140, 6141, + 6142, 6143, 6144, 6145, 6146, 6101, 6094, 6102, 6103, 6104, 6105, 6106, + 6107, 6148, 6149, 6150, 6151, 6152, 6153, 6109, 6108, 6110, 6111, 6112, + 6113, 6114, 6088, 6127, 6089, 6128, 6090, 6129, 6091, 6092, 6093, 6087, + 6115, 6116, 6117, 6118, 6119, 6120, 6121, 6122, 6123, 6124, 6125, 6126, + 6154, 6155, 6156, 6157, 6158, 6159, 6160, 22327, 22339, 22349, 22351, + 22336, 22330, 22317, 22342, 22329, 22332, 22344, 22355, 22357, 22353, + 22358, 22347, 22338, 22356, 22324, 22325, 22354, 22316, 22326, 22320, + 22323, 22319, 22315, 22328, 22350, 22352, 22337, 22331, 22343, 22333, + 22348, 22369, 22372, 22364, 22371, 22370, 22374, 22368, 22376, 22314, + 22361, 22311, 35762, 35762, 22385, 22387, 22384, 22383, 22380, 22379, + 22382, 22381, 22388, 22386, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 14971, 14969, 15002, 15003, + 15004, 14980, 14981, 15013, 15015, 14948, 14946, 14945, 14949, 14955, + 14956, 14958, 14957, 14962, 14959, 14960, 14964, 14932, 14930, 35762, + 35762, 35762, 35762, 14828, 14829, 14897, 14898, 14917, 14911, 14912, + 14915, 14914, 14913, 14872, 14857, 14896, 14863, 14867, 14866, 14880, + 14879, 14800, 14825, 14818, 14903, 14816, 14823, 14853, 14846, 14852, + 14907, 14848, 14851, 14850, 14891, 14884, 14901, 14902, 14890, 14888, + 14887, 14892, 14894, 14839, 14838, 14924, 14925, 14789, 14788, 14904, + 14843, 14841, 35762, 35762, 35762, 35762, 7281, 7282, 7283, 7284, 7285, + 7286, 7287, 7288, 7289, 7290, 7291, 7292, 7293, 7294, 7295, 7296, 7297, + 7298, 7299, 7300, 7301, 7302, 7303, 7304, 7305, 7306, 7307, 7308, 7309, + 7310, 7311, 7312, 7313, 7314, 7315, 7316, 7317, 7318, 7319, 7320, 7321, + 7322, 7323, 7324, 7325, 7326, 7327, 7328, 7329, 7330, 7331, 7332, 7333, + 7334, 7335, 7336, 7337, 7338, 7339, 7340, 7341, 7342, 7343, 7344, 7345, + 7346, 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, 7355, 7356, 7357, + 7358, 7359, 7360, 7361, 7362, 7363, 7364, 7365, 7366, 7367, 7368, 7369, + 7370, 7371, 7372, 7373, 7374, 7375, 7376, 7377, 7378, 7379, 7380, 7381, + 7382, 7383, 7384, 7385, 7386, 7387, 7388, 7389, 7390, 7391, 7392, 7393, + 7394, 7395, 7396, 7397, 7398, 7399, 7400, 7401, 7402, 7403, 7404, 7405, + 7406, 7407, 7408, 7409, 7410, 7411, 7412, 7413, 7414, 7415, 7416, 7417, + 7418, 7419, 7420, 7421, 7422, 7423, 7424, 7425, 7426, 7427, 7428, 7429, + 7430, 7431, 7432, 7433, 7434, 7435, 7436, 7437, 7438, 7439, 7440, 7441, + 7442, 7443, 7444, 7445, 7446, 7447, 7448, 7449, 7450, 7451, 7452, 7453, + 7454, 7455, 7456, 7457, 7458, 7459, 7460, 7461, 7462, 7463, 7464, 7465, + 7466, 7467, 7468, 7469, 7470, 7471, 7472, 7473, 7474, 7475, 7476, 7477, + 7478, 7479, 7480, 7481, 7482, 7483, 7484, 7485, 7486, 7487, 7488, 7489, + 7490, 7491, 7492, 7493, 7494, 7495, 7496, 7497, 7498, 7499, 7500, 7501, + 7502, 7503, 7504, 7505, 7506, 7507, 7508, 7509, 7510, 7511, 7512, 7513, + 7514, 7515, 7516, 7517, 7518, 7519, 7520, 7521, 7522, 7523, 7524, 7525, + 7526, 7527, 7528, 7529, 7530, 7531, 7532, 7533, 7534, 7535, 7536, 7079, + 7080, 7081, 7082, 7083, 7084, 7085, 7086, 7087, 7088, 7089, 7090, 7091, + 7092, 7093, 7094, 7095, 7096, 7097, 7098, 7099, 7100, 7101, 7102, 7103, + 7104, 7105, 7106, 7107, 7108, 7109, 7110, 7111, 7112, 7113, 7114, 7115, + 7116, 7117, 7118, 7119, 7120, 7121, 7122, 7123, 7124, 7125, 7126, 7127, + 7128, 7129, 7130, 7131, 7132, 7133, 7134, 7135, 7136, 7137, 7138, 7139, + 7140, 7141, 7142, 7143, 7144, 7145, 7146, 7147, 7148, 7149, 7150, 7151, + 7152, 7153, 7154, 7155, 7156, 7157, 7158, 7159, 7160, 7161, 7162, 7163, + 7164, 7165, 7166, 7167, 7168, 7169, 7170, 7171, 7172, 7173, 7174, 7065, + 7066, 7067, 7068, 7069, 7070, 7071, 7072, 7073, 7074, 7075, 7076, 7077, + 7078, 35762, 35762, 7175, 7176, 7177, 7178, 7179, 7180, 7181, 7182, 7183, + 7184, 7185, 7186, 7187, 7188, 7189, 7190, 7191, 7192, 7193, 7194, 7195, + 7196, 7197, 7198, 7199, 7200, 7201, 7202, 7203, 7204, 7205, 7206, 7207, + 7208, 7209, 7210, 7211, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, + 7220, 7221, 7222, 7223, 7224, 7225, 7226, 7227, 7228, 7229, 7230, 7231, + 7232, 7233, 7234, 7235, 7236, 7237, 7238, 7239, 7240, 7241, 7242, 7243, + 7244, 7245, 7246, 7247, 7248, 7249, 7250, 7251, 7252, 7253, 7254, 7255, + 7256, 7257, 7258, 7259, 7260, 7261, 7262, 7263, 7264, 7265, 7266, 7267, + 7268, 7269, 7270, 7271, 7272, 7273, 7274, 7275, 7276, 7277, 7278, 7279, + 7280, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 19417, + 19420, 19421, 19418, 19419, 19423, 19424, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 2490, 2491, 2489, + 2492, 2488, 35762, 35762, 35762, 35762, 35762, 15435, 15453, 15440, + 15371, 15427, 15430, 15432, 15431, 15426, 15433, 15429, 15428, 15372, + 15405, 15406, 15403, 15404, 15369, 15370, 15368, 15376, 15418, 15416, + 15393, 15425, 15398, 35762, 15410, 15436, 15384, 15379, 15420, 35762, + 15422, 35762, 15396, 15400, 35762, 15386, 15382, 35762, 15414, 15391, + 15408, 15402, 15412, 15424, 15375, 15378, 15381, 15437, 1146, 1145, 1176, + 1174, 1175, 1177, 1403, 1401, 1402, 1404, 1171, 1169, 1170, 1172, 1532, + 1530, 1531, 1533, 1512, 1510, 1511, 1513, 1527, 1525, 1526, 1528, 1545, + 1543, 1544, 1546, 1408, 1406, 1407, 1409, 1211, 1209, 1210, 1212, 1381, + 1379, 1380, 1382, 1489, 1487, 1488, 1490, 1494, 1492, 1493, 1495, 1201, + 1200, 1192, 1191, 1215, 1214, 1204, 1203, 1311, 1310, 1438, 1437, 1333, + 1331, 1332, 1334, 1245, 1243, 1244, 1246, 1257, 1255, 1256, 1258, 1372, + 1370, 1371, 1373, 1386, 1385, 1442, 1440, 1441, 1443, 1287, 1286, 1282, + 1280, 1281, 1283, 1291, 1289, 1290, 1292, 1569, 1568, 1567, 1566, 2352, + 2351, 2360, 2359, 2356, 2355, 2354, 2353, 2364, 2363, 2350, 2358, 2357, + 2366, 2362, 2361, 2365, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 1376, + 1374, 1375, 1377, 1538, 1537, 1590, 1589, 1587, 1586, 1536, 1548, 1547, + 1337, 1336, 1340, 1339, 1603, 1601, 1602, 1604, 1539, 1540, 2043, 2042, + 2045, 2044, 2064, 2063, 2072, 2071, 2062, 2061, 2068, 2067, 2048, 2046, + 2047, 2097, 2095, 2096, 1225, 1223, 1224, 1226, 2054, 2052, 2058, 2041, + 2066, 1645, 1636, 1641, 1648, 1643, 1654, 2006, 1994, 2001, 2014, 2017, + 2022, 2024, 2029, 2026, 2035, 1723, 1729, 1708, 1703, 1762, 1758, 1764, + 1913, 1906, 1918, 1926, 1885, 1889, 1667, 1659, 1663, 1669, 1987, 1982, + 2099, 1616, 1612, 1697, 1693, 1681, 1686, 1677, 1684, 1679, 1688, 1867, + 1863, 1865, 1869, 1738, 1740, 1748, 1746, 1743, 1754, 1736, 1757, 1790, + 1782, 1794, 1800, 1774, 1803, 1821, 1810, 1815, 1825, 1804, 1826, 1842, + 1832, 1854, 1847, 1850, 1857, 1718, 1714, 1715, 1716, 2082, 2075, 2084, + 2090, 2039, 2094, 2023, 1880, 1628, 1934, 1937, 1941, 1935, 1938, 1940, + 2070, 2069, 2056, 2060, 2040, 2065, 1652, 1651, 1646, 1650, 1642, 1653, + 2020, 2019, 2012, 2018, 2016, 2021, 2033, 2032, 2027, 2031, 2025, 2034, + 1678, 1687, 1864, 1868, 1737, 1741, 1752, 1735, 1756, 1798, 1773, 1802, + 1805, 1823, 1855, 1852, 1845, 1851, 1849, 1856, 1627, 2092, 2079, 2088, + 2078, 2038, 2093, 2053, 2051, 2055, 2057, 2049, 1644, 1635, 1640, 1647, + 1637, 2005, 1993, 2000, 2013, 1995, 2028, 1722, 1728, 1707, 1702, 1761, + 1763, 1912, 1905, 1917, 1925, 1884, 1892, 1888, 1666, 1658, 1662, 1668, + 1986, 2098, 1615, 1611, 1696, 1692, 1680, 1685, 1676, 1683, 1866, 1862, + 1739, 1747, 1745, 1742, 1753, 1789, 1781, 1793, 1799, 1783, 1820, 1809, + 1814, 1824, 1841, 1831, 1853, 1846, 1833, 1717, 1713, 1719, 2081, 2074, + 2083, 2089, 2076, 2059, 2050, 1649, 1638, 2015, 1996, 2030, 2036, 1927, + 1909, 1964, 1944, 1744, 1755, 1801, 1848, 1834, 2091, 2077, 1942, 1936, + 1939, 1985, 1989, 1618, 1620, 1695, 1699, 1929, 1933, 1966, 1974, 1705, + 1710, 1731, 1733, 1760, 1766, 1891, 1896, 1665, 1673, 1955, 1950, 1969, + 1963, 1972, 1931, 1894, 1671, 1984, 1988, 1617, 1619, 1694, 1698, 1928, + 1932, 1965, 1973, 1704, 1709, 1730, 1732, 1759, 1765, 1890, 1895, 1664, + 1672, 1953, 1948, 1967, 1961, 1971, 1930, 1893, 1670, 1954, 1949, 1968, + 1962, 1908, 1943, 1981, 1914, 1907, 1919, 1956, 1951, 1970, 1983, 2100, + 1629, 1630, 25893, 25894, 1877, 1872, 1876, 1873, 1874, 1875, 1903, 1622, + 1624, 1623, 1621, 1871, 1902, 1625, 1976, 1878, 2003, 1992, 1991, 1990, + 1998, 2008, 2010, 2009, 1725, 1724, 1701, 1700, 1904, 1911, 1910, 1921, + 1920, 1922, 1924, 1923, 1882, 1881, 1887, 1946, 1945, 1952, 1958, 1957, + 1960, 1959, 1656, 1661, 1660, 1978, 1977, 1979, 1980, 1614, 1609, 1608, + 1607, 1689, 1691, 1690, 1675, 1674, 1860, 1858, 1779, 1780, 1777, 1784, + 1785, 1792, 1791, 1796, 1795, 1806, 1807, 1808, 1818, 1816, 1811, 1812, + 35762, 35762, 1817, 1711, 1712, 1829, 1828, 1839, 1838, 1837, 1844, 1843, + 2086, 2085, 1639, 2004, 2002, 1999, 1997, 2011, 2007, 1727, 1720, 1726, + 1915, 1883, 1947, 1657, 1788, 1797, 2073, 2080, 2087, 1822, 1861, 1830, + 1859, 1778, 1610, 1751, 1835, 1813, 1786, 1750, 1787, 1836, 1721, 1706, + 1819, 1682, 1634, 1749, 1613, 1886, 1916, 1840, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 1898, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 1899, 1870, 1631, 1632, + 1827, 1897, 1879, 1626, 2037, 1900, 1901, 1734, 27339, 1655, 1975, 1633, + 33083, 33194, 33262, 33273, 33284, 33295, 33306, 33317, 33328, 33084, + 33095, 33106, 33117, 33128, 33139, 33150, 26827, 26832, 26833, 26826, + 26857, 26828, 26859, 26835, 26849, 26831, 35762, 35762, 35762, 35762, + 35762, 35762, 8057, 8059, 7889, 7890, 8068, 8070, 7783, 8058, 8060, 8126, + 8127, 8069, 8071, 7784, 7837, 7838, 26858, 26829, 26830, 26844, 26856, + 26841, 26853, 26839, 26851, 26843, 26855, 26836, 26845, 26837, 26846, + 26840, 26852, 26838, 26850, 26834, 26847, 27753, 34075, 26842, 26854, + 10235, 5828, 33955, 10947, 10234, 5827, 33953, 28892, 28901, 28935, + 35762, 28926, 28893, 28936, 28899, 28900, 28903, 28907, 28902, 28906, + 28904, 28908, 28934, 28883, 28885, 28933, 28931, 28905, 28930, 28898, + 35762, 28925, 28894, 28932, 28891, 35762, 35762, 35762, 35762, 1080, + 2371, 1062, 2373, 1092, 35762, 1077, 1078, 1058, 1059, 1089, 1090, 2278, + 2279, 2346, 2347, 1276, 1141, 1140, 1131, 1130, 1556, 1555, 1134, 1133, + 1573, 1571, 1572, 1574, 1151, 1150, 1166, 1164, 1165, 1167, 1499, 1498, + 1508, 1506, 1507, 1501, 1520, 1518, 1519, 1521, 1307, 1305, 1306, 1308, + 1273, 1271, 1272, 1274, 1344, 1342, 1343, 1345, 1189, 1188, 1516, 1515, + 1435, 1434, 1598, 1597, 1464, 1462, 1463, 1465, 1470, 1468, 1469, 1471, + 1451, 1449, 1450, 1452, 1197, 1195, 1196, 1198, 1482, 1480, 1481, 1483, + 1594, 1592, 1593, 1595, 1109, 1107, 1108, 1110, 1252, 1250, 1251, 1253, + 1236, 1234, 1235, 1237, 1417, 1415, 1416, 1418, 1320, 1318, 1319, 1321, + 1356, 1354, 1355, 1357, 1365, 1363, 1364, 1366, 1396, 1394, 1395, 1397, + 1295, 1293, 1294, 1296, 1560, 1559, 1149, 1148, 1583, 1581, 1582, 1584, + 1772, 1771, 1768, 1767, 1770, 1769, 1776, 1775, 35762, 35762, 35566, + 35762, 13299, 13303, 13271, 13287, 13273, 13285, 13284, 13214, 13277, + 13286, 13274, 13209, 13302, 13308, 13281, 13294, 13296, 13293, 13292, + 13289, 13288, 13291, 13290, 13297, 13295, 13210, 13280, 13216, 13298, + 13301, 13304, 13208, 13217, 13218, 13219, 13220, 13221, 13222, 13223, + 13224, 13225, 13226, 13227, 13228, 13229, 13230, 13231, 13232, 13233, + 13234, 13235, 13236, 13237, 13238, 13239, 13240, 13241, 13242, 13215, + 13279, 13278, 13207, 13269, 13300, 13243, 13244, 13245, 13246, 13247, + 13248, 13249, 13250, 13251, 13252, 13253, 13254, 13255, 13256, 13257, + 13258, 13259, 13260, 13261, 13262, 13263, 13264, 13265, 13266, 13267, + 13268, 13212, 13309, 13275, 13306, 13213, 13276, 14644, 14637, 14639, + 14643, 14635, 14627, 14582, 14584, 14586, 14583, 14585, 14578, 14580, + 14579, 14581, 14636, 14628, 14630, 14632, 14629, 14631, 14603, 14605, + 14607, 14604, 14606, 14587, 14589, 14591, 14588, 14590, 14618, 14620, + 14622, 14619, 14621, 14593, 14595, 14597, 14594, 14596, 14598, 14600, + 14602, 14599, 14601, 14608, 14610, 14612, 14609, 14611, 14623, 14625, + 14624, 14613, 14615, 14617, 14614, 14616, 14626, 14592, 14634, 14633, + 14577, 14527, 14544, 14528, 14529, 14530, 14531, 14565, 14546, 14535, + 14540, 14539, 14538, 14542, 14536, 14537, 14541, 14563, 14533, 14545, + 14534, 14548, 14547, 14562, 14557, 14543, 14556, 14526, 14564, 14532, + 14571, 35762, 35762, 35762, 14572, 14573, 14551, 14552, 14559, 14558, + 35762, 35762, 14550, 14549, 14574, 14568, 14569, 14575, 35762, 35762, + 14554, 14576, 14567, 14566, 14570, 14555, 35762, 35762, 14560, 14553, + 14561, 35762, 35762, 35762, 13211, 13272, 13270, 13283, 13307, 13282, + 13305, 35762, 14642, 14638, 14641, 14640, 14647, 14645, 14646, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 16324, + 16326, 16325, 25221, 27062, 35762, 35762, 20348, 20374, 20367, 20400, + 20358, 20349, 20378, 20344, 20356, 20386, 20389, 20383, 35762, 20372, + 20399, 20403, 20382, 20397, 20404, 20411, 20414, 20359, 20410, 20357, + 20360, 20343, 20366, 20369, 20392, 20393, 20351, 20408, 20373, 20354, + 20390, 20352, 20409, 20368, 20376, 35762, 20401, 20365, 20385, 20350, + 20361, 20375, 20346, 20380, 20355, 20387, 20388, 20345, 20371, 20347, + 20398, 20391, 20405, 20379, 20381, 35762, 20353, 20407, 35762, 20364, + 20363, 20377, 20413, 20406, 20416, 20384, 20362, 20394, 20402, 20370, + 20395, 20396, 20412, 20415, 35762, 35762, 20426, 20427, 20429, 20428, + 20417, 20418, 20425, 20419, 20420, 20430, 20421, 20422, 20423, 20424, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 20232, 20231, 20233, 20220, 20221, 20222, + 20223, 20224, 20225, 20226, 20228, 20227, 20230, 20229, 20238, 20235, + 20236, 20234, 20237, 20337, 20338, 20240, 20239, 20241, 20340, 20339, + 20243, 20244, 20245, 20242, 20246, 20249, 20248, 20250, 20251, 20252, + 20341, 20253, 20254, 20247, 20257, 20258, 20256, 20255, 20259, 20260, + 20261, 20262, 20263, 20264, 20267, 20268, 20269, 20266, 20270, 20265, + 20271, 20272, 20273, 20274, 20275, 20276, 20277, 20278, 20279, 20280, + 20282, 20281, 20283, 20284, 20286, 20287, 20288, 20285, 20289, 20290, + 20291, 20292, 20294, 20293, 20295, 20296, 20342, 20297, 20298, 20300, + 20301, 20302, 20299, 20303, 20304, 20305, 20306, 20307, 20335, 20315, + 20316, 20317, 20318, 20319, 20320, 20321, 20322, 20323, 20324, 20325, + 20326, 20327, 20328, 20329, 20330, 20331, 20332, 20333, 20334, 20308, + 20309, 20310, 20311, 20312, 20313, 20314, 20336, 35762, 35762, 35762, + 35762, 35762, 112, 113, 159, 35762, 35762, 35762, 35762, 156, 151, 146, + 126, 121, 139, 134, 114, 129, 154, 149, 144, 124, 119, 140, 135, 115, + 130, 157, 152, 147, 127, 122, 142, 137, 117, 132, 158, 153, 148, 128, + 123, 143, 138, 118, 133, 155, 150, 145, 125, 120, 141, 136, 116, 131, + 35762, 35762, 35762, 111, 107, 109, 110, 108, 103, 104, 105, 106, 13770, + 13767, 13771, 13757, 13752, 13758, 13761, 13753, 13763, 13772, 13755, + 13765, 13759, 13768, 13762, 13764, 13774, 13756, 13766, 13760, 13769, + 13773, 13754, 13775, 13787, 13796, 13786, 13782, 13795, 13777, 13783, + 13799, 13803, 13804, 13785, 13788, 13794, 13793, 13801, 13802, 13784, + 13791, 13797, 13792, 13781, 13800, 13789, 13776, 13778, 13798, 13790, + 13779, 13780, 14022, 14023, 14221, 14217, 14258, 14223, 13953, 14027, + 14220, 14216, 13959, 13958, 14019, 14001, 14017, 14026, 14021, 13807, + 13806, 14260, 14219, 14261, 14024, 14215, 13997, 24651, 35762, 27384, + 27387, 27382, 27385, 27356, 27386, 27354, 27357, 27383, 27355, 27388, + 27353, 2510, 35762, 35762, 35762, 14214, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 26611, 26612, 26623, 26592, 26595, 26626, 26604, + 26603, 26624, 26631, 26590, 26617, 26596, 26609, 26610, 26619, 26608, + 26589, 26593, 26600, 26598, 26620, 26597, 26588, 26618, 26605, 26606, + 26591, 26594, 26616, 26630, 26601, 26625, 26587, 26613, 26632, 26614, + 26615, 26607, 26629, 26628, 26602, 26621, 26622, 26627, 26599, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 20605, + 20607, 20600, 20601, 20612, 20611, 20614, 20622, 20624, 20603, 20615, + 20598, 20618, 20616, 20596, 20609, 20597, 20610, 20621, 20617, 20599, + 20619, 20620, 20602, 20604, 20606, 20608, 20613, 20623, 35762, 35762, + 35762, 5738, 5749, 5740, 5711, 5734, 5750, 5712, 5739, 5756, 5754, 5714, + 5755, 5741, 5729, 5724, 5725, 5723, 5709, 5732, 5722, 5757, 5719, 5731, + 5748, 5728, 5752, 5742, 5737, 5746, 5747, 5720, 5733, 5744, 5745, 5726, + 5727, 5721, 5753, 5710, 5730, 5735, 5751, 5715, 5716, 5717, 5718, 5713, + 5743, 5736, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 8241, 8267, 8265, 8264, + 8261, 8260, 8263, 8262, 8268, 8266, 8259, 8258, 8256, 8247, 8245, 8254, + 8252, 8243, 8249, 8250, 8257, 8255, 8246, 8244, 8253, 8251, 8242, 8248, + 35762, 35762, 35762, 35762, 25459, 25453, 25439, 25454, 25426, 25456, + 25458, 25455, 25450, 25446, 25438, 25434, 25435, 25436, 25428, 25460, + 25449, 25442, 25440, 25430, 25427, 25451, 25444, 25432, 25448, 25437, + 25433, 25431, 25452, 25447, 25445, 25429, 25464, 25462, 25463, 25461, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 25457, + 25443, 25441, 13617, 13633, 13641, 13635, 13616, 13626, 13620, 13619, + 13628, 13638, 13642, 13639, 13636, 13624, 13640, 13631, 13625, 13623, + 13627, 13637, 13629, 13630, 13632, 13621, 13618, 13634, 13622, 35762, + 35762, 35762, 35762, 35762, 25531, 25530, 25527, 25500, 25501, 25523, + 25498, 25524, 25499, 25503, 25532, 25525, 25506, 25507, 25514, 25508, + 25526, 25511, 25513, 25534, 25497, 25510, 25509, 25521, 25518, 25528, + 25529, 25502, 25533, 25512, 25515, 25516, 25517, 25520, 25505, 25522, + 25519, 25504, 8083, 8081, 8079, 8080, 8082, 35762, 35762, 35762, 35762, + 35762, 32585, 32588, 32592, 32596, 32589, 32593, 32611, 32607, 32594, + 32604, 32606, 32595, 32601, 32597, 32612, 32590, 32609, 32608, 32600, + 32586, 32610, 32599, 32587, 32598, 32603, 32591, 32605, 32613, 32614, + 32602, 35762, 32615, 25540, 25582, 25583, 25563, 25564, 25561, 25562, + 25560, 25575, 25552, 25553, 25557, 25558, 25547, 25550, 25551, 25556, + 25579, 25544, 25576, 25565, 25566, 25569, 25570, 25571, 25580, 25554, + 25555, 25567, 25568, 25578, 25574, 25581, 25572, 25573, 25577, 35762, + 35762, 35762, 35762, 25541, 25542, 25543, 25559, 25548, 25549, 25545, + 25546, 25584, 25539, 25536, 25537, 25535, 25538, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 10286, + 10285, 10281, 10282, 10283, 10284, 10292, 10291, 10287, 10288, 10289, + 10290, 10309, 10294, 10308, 10305, 10310, 10303, 10300, 10296, 10301, + 10299, 10302, 10307, 10306, 10276, 10304, 10275, 10295, 10271, 10298, + 10272, 10297, 10279, 10277, 10278, 10273, 10274, 10293, 10280, 10326, + 10325, 10321, 10322, 10323, 10324, 10332, 10331, 10327, 10328, 10329, + 10330, 10349, 10334, 10348, 10345, 10350, 10343, 10340, 10336, 10341, + 10339, 10342, 10347, 10346, 10316, 10344, 10315, 10335, 10311, 10338, + 10312, 10337, 10319, 10317, 10318, 10313, 10314, 10333, 10320, 27890, + 27896, 27907, 27904, 27894, 27893, 27892, 27871, 27899, 27877, 27906, + 27902, 27905, 27908, 27895, 27903, 27882, 27901, 27898, 27876, 27881, + 27883, 27880, 27875, 27869, 27866, 27888, 27897, 27886, 27870, 27891, + 27909, 27873, 27867, 27879, 27910, 27887, 27884, 27885, 27868, 27864, + 27889, 27865, 27874, 27863, 27872, 27878, 27900, 25971, 25989, 25995, + 25993, 25996, 25977, 25974, 25994, 25979, 25978, 25975, 25973, 25991, + 25990, 25981, 25976, 25984, 25980, 25985, 25986, 25992, 25997, 25970, + 25987, 25998, 25982, 25999, 25972, 25988, 25983, 35762, 35762, 26006, + 26008, 26005, 26004, 26001, 26000, 26003, 26002, 26009, 26007, 35762, + 35762, 35762, 35762, 35762, 35762, 25898, 25899, 25900, 25901, 25926, + 25919, 25905, 25902, 25908, 25918, 25917, 25932, 25911, 25906, 25910, + 25927, 25928, 25929, 25912, 25913, 25930, 25907, 25923, 25922, 25916, + 25904, 25915, 25903, 25914, 25920, 25933, 25931, 25909, 25921, 25925, + 25924, 35762, 35762, 35762, 35762, 25934, 25935, 25936, 25937, 25962, + 25955, 25941, 25938, 25944, 25954, 25953, 25968, 25947, 25942, 25946, + 25963, 25964, 25965, 25948, 25949, 25966, 25943, 25959, 25958, 25952, + 25940, 25951, 25939, 25950, 25956, 25969, 25967, 25945, 25957, 25961, + 25960, 35762, 35762, 35762, 35762, 12376, 12367, 12356, 12355, 12358, + 12347, 12357, 12354, 12353, 12368, 12344, 12343, 12369, 12377, 12370, + 12360, 12346, 12345, 12371, 12350, 12349, 12348, 12378, 12372, 12373, + 12352, 12351, 12362, 12361, 12364, 12363, 12379, 12374, 12375, 12380, + 12366, 12365, 12342, 12341, 12359, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 5770, 5819, 5786, 5782, 5784, 5809, 5783, 5807, + 5804, 5773, 5806, 5808, 5787, 5798, 5794, 5789, 5817, 5781, 5772, 5790, + 5793, 5795, 5820, 5811, 5769, 5775, 5776, 5778, 5812, 5810, 5815, 5779, + 5799, 5791, 5818, 5803, 5814, 5780, 5774, 5797, 5785, 5816, 5801, 5813, + 5802, 5800, 5788, 5777, 5771, 5805, 5796, 5792, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 5821, 33727, + 33696, 33697, 33707, 33706, 33709, 33708, 33699, 33698, 33716, 33724, + 35762, 33715, 33714, 33700, 33701, 33717, 33725, 33703, 33702, 33718, + 33705, 33704, 33728, 33719, 33726, 33720, 35762, 33711, 33710, 33713, + 33712, 33729, 33721, 33722, 35762, 33730, 33723, 35762, 33762, 33731, + 33732, 33742, 33741, 33744, 33743, 33734, 33733, 33751, 33759, 35762, + 33750, 33749, 33735, 33736, 33752, 33760, 33738, 33737, 33753, 33740, + 33739, 33763, 33754, 33761, 33755, 35762, 33746, 33745, 33748, 33747, + 33764, 33756, 33757, 35762, 33765, 33758, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 20199, 20200, 20201, 20202, 20203, 20204, 20205, + 20206, 20207, 20138, 20139, 20140, 20141, 20142, 20151, 20143, 20144, + 20145, 20146, 20147, 20148, 20149, 20150, 20152, 20153, 20154, 20155, + 20219, 20156, 20157, 20158, 20159, 20160, 20161, 20162, 20163, 20164, + 20165, 20166, 20167, 20168, 20169, 20170, 20171, 20172, 20173, 20174, + 20175, 20176, 20177, 20178, 20179, 20180, 20181, 20182, 20183, 20184, + 20185, 20186, 20187, 20188, 20189, 20190, 20191, 20192, 20193, 20194, + 20195, 20196, 20197, 20198, 19879, 20215, 20208, 19880, 20209, 20210, + 20211, 20212, 19881, 20216, 20217, 20213, 20214, 20218, 19885, 19886, + 19887, 19888, 19889, 19890, 19891, 19892, 19882, 19883, 19884, 19896, + 19897, 19898, 19893, 19894, 19895, 19899, 19900, 19901, 19902, 19903, + 19904, 19907, 19908, 19909, 19910, 19911, 19912, 19913, 19914, 19915, + 19916, 19917, 19918, 19919, 19920, 19921, 19922, 19923, 19924, 19925, + 19926, 19927, 19928, 19929, 19930, 19931, 19932, 19933, 19934, 19935, + 19936, 19937, 19938, 19939, 19940, 19941, 19942, 19943, 19944, 19945, + 19946, 19947, 19948, 19949, 19950, 19951, 19952, 19953, 19954, 19955, + 19956, 19905, 19906, 19957, 19958, 19959, 19960, 19961, 19962, 19963, + 19964, 19965, 19966, 19967, 19968, 19969, 19970, 19971, 19972, 19973, + 19974, 19975, 19976, 19977, 19978, 19979, 19980, 19981, 19982, 19983, + 19984, 19985, 19986, 19987, 19988, 19989, 20021, 20022, 20023, 20024, + 20025, 20026, 20027, 20028, 20029, 19990, 19991, 19992, 19993, 19994, + 19995, 19996, 19997, 19998, 19999, 20000, 20001, 20002, 20003, 20004, + 20005, 20006, 20007, 20008, 20009, 20010, 20011, 20012, 20013, 20014, + 20015, 20016, 20017, 20018, 20019, 20020, 20036, 20037, 20038, 20039, + 20040, 20041, 20042, 20043, 20044, 20045, 20046, 20047, 20048, 20049, + 20050, 20051, 20052, 20053, 20054, 20055, 20030, 20031, 20032, 20033, + 20034, 20035, 20056, 20057, 20058, 20059, 20060, 20061, 20062, 20063, + 20098, 20099, 20100, 20101, 20102, 20103, 20104, 20105, 20106, 20107, + 20064, 20065, 20066, 20067, 20068, 20069, 20070, 20071, 20072, 20073, + 20074, 20075, 20076, 20077, 20078, 20079, 20080, 20081, 20082, 20083, + 20089, 20090, 20091, 20092, 20093, 20094, 20095, 20096, 20097, 20084, + 20085, 20086, 20087, 20088, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 20119, 20114, 20117, 20116, 20120, 20115, 20113, + 20118, 20112, 20108, 20111, 20110, 20109, 20126, 20121, 20125, 20122, + 20123, 20124, 20127, 20129, 20128, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 20130, 20131, 20132, 20133, 20134, + 20135, 20136, 20137, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 23185, 23306, 23305, + 23170, 23186, 23174, 35762, 23204, 23206, 23205, 23200, 23199, 23197, + 23198, 23259, 23192, 23216, 23256, 23180, 23220, 23181, 23224, 23187, + 23226, 23203, 23240, 23241, 23239, 23183, 23237, 23242, 23243, 23284, + 23285, 23248, 23184, 23193, 23299, 23281, 23282, 23255, 23254, 23189, + 23269, 23272, 23273, 23270, 23268, 23296, 35762, 23191, 23111, 23158, + 23006, 23089, 23118, 23003, 23160, 23261, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 9704, 9705, 9706, 9707, 9708, 9698, + 35762, 35762, 9699, 35762, 9654, 9655, 9656, 9657, 9658, 9659, 9660, + 9661, 9662, 9663, 9664, 9665, 9666, 9667, 9668, 9669, 9670, 9671, 9672, + 9673, 9674, 9675, 9676, 9677, 9678, 9679, 9680, 9681, 9682, 9683, 9684, + 9685, 9686, 9687, 9688, 9689, 9690, 9691, 9692, 9693, 9694, 9695, 9696, + 9697, 35762, 9702, 9703, 35762, 35762, 35762, 9700, 35762, 35762, 9701, + 16146, 16157, 16148, 16142, 16154, 16159, 16149, 16155, 16140, 16153, + 16156, 16143, 16161, 16158, 16150, 16147, 16160, 16151, 16144, 16145, + 16152, 16141, 35762, 16162, 16137, 16133, 16136, 16134, 16132, 16138, + 16139, 16135, 26241, 26252, 26243, 26237, 26249, 26254, 26244, 26250, + 26235, 26248, 26251, 26238, 26256, 26234, 26253, 26245, 26242, 26255, + 26246, 26239, 26240, 26247, 26236, 26233, 26257, 26264, 26259, 26260, + 26263, 26262, 26261, 26258, 24101, 24116, 24106, 24127, 24118, 24112, + 24108, 24124, 24129, 24119, 24125, 24110, 24104, 24123, 24105, 24126, + 24102, 24113, 24109, 24131, 24107, 24128, 24120, 24117, 24130, 24121, + 24114, 24115, 24103, 24122, 24111, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 24136, 24133, 24134, 24139, 24140, 24138, 24135, + 24132, 24137, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 15202, 15218, 15210, 15209, 15215, 15220, 15204, 15216, 15205, 15214, + 15217, 15207, 15222, 15219, 15211, 15203, 15221, 15212, 15208, 35762, + 15213, 15206, 35762, 35762, 35762, 35762, 35762, 15223, 15227, 15226, + 15225, 15224, 26635, 26654, 26650, 26637, 26638, 26646, 26647, 26639, + 26645, 26648, 26651, 26653, 26656, 26652, 26643, 26636, 26655, 26641, + 26640, 26649, 26642, 26644, 26661, 26660, 26657, 26662, 26658, 26659, + 35762, 35762, 35762, 26663, 20631, 20637, 20641, 20639, 20633, 20649, + 20642, 20650, 20643, 20627, 20644, 20635, 20645, 20647, 20630, 20625, + 20648, 20640, 20646, 20629, 20626, 20632, 20634, 20628, 20636, 20638, + 35762, 35762, 35762, 35762, 35762, 20651, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 22722, 22723, 22724, 22725, 22721, 22720, 22696, 22697, 22718, 22717, + 22700, 22701, 22702, 22703, 22698, 22699, 22716, 22713, 22712, 22704, + 22705, 22706, 22714, 22719, 22707, 22708, 22709, 22710, 22711, 22715, + 22726, 22727, 22618, 22639, 22640, 22641, 22638, 22637, 22630, 22634, + 22633, 22623, 22624, 22636, 22632, 22628, 22627, 22625, 22619, 22626, + 22629, 22635, 22620, 22621, 22622, 22631, 35762, 35762, 35762, 35762, + 22606, 22611, 22643, 22642, 22692, 22684, 22678, 22655, 22649, 22672, + 22666, 22644, 22661, 22690, 22688, 22682, 22659, 22653, 22676, 22670, + 35762, 35762, 22693, 22685, 22679, 22656, 22650, 22673, 22667, 22646, + 22663, 22695, 22687, 22681, 22658, 22652, 22675, 22669, 22648, 22665, + 22691, 22689, 22683, 22660, 22654, 22677, 22671, 22645, 22662, 22694, + 22686, 22680, 22657, 22651, 22674, 22668, 22647, 22664, 22610, 22616, + 22615, 22609, 22608, 22613, 22612, 22607, 22617, 22614, 17200, 17222, + 17224, 17220, 35762, 17221, 17223, 35762, 35762, 35762, 35762, 35762, + 17225, 17216, 17219, 17218, 17166, 17164, 17188, 17187, 35762, 17186, + 17185, 17194, 35762, 17174, 17170, 17169, 17177, 17176, 17173, 17172, + 17171, 17179, 17178, 17175, 17190, 17189, 17184, 17183, 17196, 17198, + 17197, 17195, 17192, 17180, 17181, 17182, 17199, 17193, 17165, 17167, + 17168, 17191, 35762, 35762, 17214, 17215, 17217, 35762, 35762, 35762, + 35762, 17226, 17163, 17162, 17161, 17160, 17202, 17201, 17203, 17204, + 17227, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 17208, 17213, + 17206, 17205, 17212, 17210, 17209, 17207, 17211, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 25648, 25644, 25649, 25654, 25645, 25652, + 25638, 25646, 25650, 25642, 25637, 25633, 25651, 25634, 25636, 25635, + 25653, 25626, 25627, 25629, 25632, 25630, 25631, 25641, 25643, 25628, + 25647, 25640, 25639, 25656, 25655, 25657, 25470, 25488, 25469, 25479, + 25491, 25492, 25481, 25485, 25483, 25476, 25480, 25472, 25487, 25471, + 25493, 25482, 25484, 25465, 25466, 25489, 25468, 25490, 25467, 25475, + 25477, 25473, 25486, 25474, 25478, 25496, 25495, 25494, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 20932, 20936, 20935, 20940, 20939, 20937, 20961, 20964, 20980, 20944, + 20943, 20942, 20941, 20962, 20954, 20960, 20946, 20956, 20945, 20958, + 20938, 20953, 20967, 20963, 20950, 20934, 20933, 20966, 20965, 20951, + 20948, 20957, 20947, 20959, 20952, 20949, 20955, 20982, 20981, 35762, + 35762, 35762, 35762, 20968, 20972, 20971, 20970, 20969, 20979, 20977, + 20975, 20974, 20973, 20978, 20976, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 2526, 2527, 2533, 2529, 2532, 2528, 2530, + 2531, 2569, 2570, 2559, 2560, 2561, 2562, 2557, 2558, 2574, 2547, 2546, + 2545, 2536, 2534, 2535, 2571, 2573, 2556, 2554, 2566, 2565, 2555, 2577, + 2572, 2564, 2563, 2541, 2540, 2539, 2544, 2543, 2542, 2576, 2537, 2552, + 2553, 2579, 2578, 2575, 2551, 2568, 2549, 2567, 2548, 2550, 2538, 35762, + 35762, 35762, 2580, 32334, 28927, 18140, 18135, 18141, 18136, 16288, + 16299, 16290, 16284, 16296, 16301, 16291, 16297, 16282, 16295, 16298, + 16285, 16303, 16300, 16292, 16289, 16302, 16293, 16286, 16287, 16294, + 16283, 35762, 35762, 16308, 16305, 16306, 16311, 16307, 16304, 16309, + 16310, 16257, 16271, 16262, 16258, 16268, 16261, 16263, 16269, 16255, + 16267, 16270, 16259, 16260, 16272, 16264, 16273, 16265, 16266, 16256, + 35762, 35762, 35762, 35762, 35762, 16278, 16275, 16276, 16281, 16277, + 16274, 16279, 16280, 26895, 26909, 26900, 26896, 26906, 26899, 26901, + 26907, 26905, 26908, 26897, 26898, 26910, 26902, 26912, 26903, 26904, + 26911, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 26920, 26921, + 26893, 26894, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 26917, 26914, 26915, 26919, 26916, 26913, + 26918, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 25658, 25700, 25701, 25690, 25726, 25719, 25693, 25694, 25728, + 25671, 25711, 25659, 25704, 25673, 25713, 25661, 25705, 25672, 25712, + 25660, 25689, 25725, 25679, 25718, 25668, 25708, 25662, 25706, 25695, + 25729, 25674, 25714, 25663, 25684, 25687, 25675, 25664, 25702, 25682, + 25721, 25680, 25720, 25683, 25722, 25710, 25681, 25703, 25688, 25696, + 25691, 25686, 25724, 25676, 25715, 25692, 25727, 25697, 25730, 25677, + 25716, 25665, 25669, 25666, 25670, 25709, 25685, 25723, 25678, 25717, + 25667, 25707, 25698, 25699, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 25318, + 25321, 25344, 25319, 25333, 25329, 25335, 25345, 25320, 25323, 25365, + 25346, 25347, 25336, 25337, 25348, 25366, 25367, 25349, 25350, 25322, + 25362, 25338, 25339, 25324, 25326, 25330, 25358, 25360, 25354, 25356, + 25359, 25351, 25325, 25352, 25368, 25331, 25332, 25340, 25327, 25341, + 25334, 25361, 25364, 25355, 25357, 25353, 25342, 25343, 25328, 25363, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 25369, 25372, 25395, 25370, 25384, 25380, 25386, + 25396, 25371, 25374, 25416, 25397, 25398, 25387, 25388, 25399, 25417, + 25418, 25400, 25401, 25373, 25413, 25389, 25390, 25375, 25377, 25381, + 25409, 25411, 25405, 25407, 25410, 25402, 25376, 25403, 25419, 25382, + 25383, 25391, 25378, 25392, 25385, 25412, 25415, 25406, 25408, 25404, + 25393, 25394, 25379, 25414, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 25422, 25421, 25425, 25420, 25423, 25424, 15157, 15144, 15152, + 15136, 15135, 15149, 15145, 15148, 15133, 15146, 15130, 15129, 15138, + 15137, 15156, 15143, 15142, 15134, 15147, 15150, 15151, 15141, 15154, + 15131, 15155, 15132, 15139, 15140, 15153, 15164, 15166, 15168, 15165, + 15167, 15159, 15158, 15163, 15160, 15162, 15161, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 15175, 15177, 15174, 15173, 15170, + 15169, 15172, 15171, 15178, 15176, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 27439, + 27437, 27436, 27433, 27432, 27435, 27434, 27440, 27438, 27431, 27430, + 27428, 27419, 27417, 27426, 27424, 27415, 27421, 27422, 27429, 27427, + 27418, 27416, 27425, 27423, 27414, 27420, 27411, 27412, 27410, 27413, + 35762, 34219, 34253, 34233, 34232, 34238, 34237, 34215, 34214, 34213, + 34224, 34245, 34218, 34249, 34252, 34251, 34248, 34256, 34235, 34234, + 34236, 34217, 34239, 34250, 34220, 34244, 34255, 34240, 34241, 34228, + 34226, 34225, 34227, 34229, 34216, 34231, 34254, 34242, 34243, 34222, + 34223, 34246, 34221, 35762, 34211, 34210, 34212, 35762, 35762, 34230, + 34247, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 2335, 2336, 2333, 25588, 25596, + 25610, 25597, 25601, 25607, 25598, 25613, 25602, 25608, 25606, 25609, + 25600, 25615, 25611, 25590, 25591, 25603, 25589, 25587, 25614, 25604, + 25592, 25593, 25599, 25605, 25612, 25594, 25595, 25622, 25620, 25617, + 25625, 25624, 25621, 25619, 25618, 25623, 25586, 25616, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 28985, 28999, 28987, 28996, + 29003, 28991, 28997, 28995, 28998, 28988, 29005, 29001, 28992, 28986, + 29004, 28993, 28990, 28994, 29002, 29000, 28989, 28984, 28979, 28977, + 28980, 28978, 28983, 28982, 28974, 28973, 28975, 28981, 28976, 29006, + 29009, 29008, 29007, 29012, 29013, 29010, 29014, 29011, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 25735, 25747, 25745, 25750, 25739, 25744, 25743, 25746, 25737, 25752, + 25748, 25740, 25751, 25741, 25736, 25742, 25749, 25738, 25734, 25733, + 25732, 25731, 25756, 25753, 25754, 25755, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 6190, 6184, 6198, 6192, 6187, 6195, 6201, + 6183, 6193, 6196, 6194, 6197, 6188, 6203, 6199, 6185, 6191, 6202, 6189, + 6186, 6200, 6208, 6205, 6206, 6210, 6207, 6204, 6209, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 12403, 12414, + 12405, 12399, 12411, 12416, 12406, 12412, 12397, 12410, 12413, 12400, + 12418, 12415, 12407, 12404, 12417, 12408, 12401, 12402, 12409, 12398, + 12419, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 4335, 4339, 4337, 4336, 4338, 4261, 4262, 4280, 4281, 4278, 4279, 4273, + 4274, 4275, 4276, 4307, 4263, 4254, 4264, 4300, 4299, 4296, 4295, 4284, + 4294, 4293, 4298, 4297, 4286, 4270, 4269, 4266, 4265, 4285, 4272, 4271, + 4268, 4267, 4287, 4302, 4301, 4292, 4291, 4304, 4306, 4305, 4283, 4277, + 4288, 4289, 4290, 4303, 4282, 4255, 4260, 4259, 4344, 4343, 4353, 4354, + 4351, 4352, 4347, 4348, 4349, 4350, 4355, 4345, 4340, 4346, 4356, 4358, + 4357, 4332, 4331, 4330, 4333, 4329, 35762, 35762, 35762, 35762, 4325, + 4323, 4320, 4311, 4313, 4318, 4316, 4308, 4314, 4324, 4322, 4321, 4310, + 4312, 4319, 4317, 4309, 4315, 4326, 4327, 4365, 4367, 4364, 4363, 4360, + 4359, 4362, 4361, 4368, 4366, 4334, 4257, 4258, 4341, 4342, 4256, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 4328, 16513, + 16515, 16517, 16473, 16474, 16483, 16484, 16481, 16482, 16511, 16475, + 16512, 16476, 16501, 16500, 16497, 16496, 16485, 16495, 16494, 16499, + 16498, 16487, 16478, 16477, 16470, 16468, 16469, 16504, 16486, 16480, + 16479, 16472, 16471, 16488, 16503, 16502, 16493, 16492, 16508, 16510, + 16505, 16507, 16509, 16489, 16490, 16491, 16506, 16523, 16528, 16529, + 16526, 16527, 16530, 16524, 16531, 16525, 16516, 16514, 16534, 16535, + 16532, 16518, 16519, 16521, 16520, 16522, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 16533, 35762, 35762, 29037, + 29038, 29027, 29028, 29029, 29030, 29023, 29024, 29034, 29026, 29039, + 29035, 29040, 29036, 29031, 29033, 29032, 29025, 29041, 29020, 29042, + 29044, 29043, 29021, 29022, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 29051, 29053, 29050, 29049, 29046, 29045, 29048, 29047, 29054, + 29052, 35762, 35762, 35762, 35762, 35762, 35762, 5873, 5875, 5874, 5869, + 5871, 5872, 5870, 5858, 5857, 5854, 5853, 5839, 5852, 5851, 5856, 5855, + 5841, 5844, 5843, 5836, 5835, 5840, 5846, 5845, 5838, 5837, 5842, 5862, + 5861, 5850, 5849, 5864, 5847, 5848, 5865, 5860, 5868, 5866, 5863, 5877, + 5885, 5886, 5881, 5882, 5883, 5879, 5887, 5880, 5888, 5905, 5904, 5889, + 5903, 35762, 5898, 5900, 5897, 5896, 5893, 5892, 5895, 5894, 5901, 5899, + 5876, 5891, 5890, 5902, 5859, 5878, 5884, 5867, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 20693, 20695, 20697, 20694, 20696, + 20685, 20684, 20681, 20680, 20679, 20678, 20683, 20682, 20664, 20673, + 20672, 20669, 20668, 20663, 20675, 20674, 20671, 20670, 20665, 20687, + 20686, 20677, 20676, 20690, 20667, 20689, 20692, 20691, 20688, 20666, + 20700, 20701, 20699, 20698, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 27836, 27835, 27841, 27780, 27781, 27799, 27800, + 27797, 27798, 27792, 27793, 27794, 27795, 27826, 27782, 27827, 27783, + 27819, 27818, 27815, 27814, 27803, 27813, 27812, 27817, 27816, 27805, + 27789, 27788, 27785, 27784, 27804, 27791, 27790, 27787, 27786, 27806, + 27821, 27820, 27811, 27810, 27823, 27825, 27824, 27802, 27801, 27796, + 27807, 27808, 27809, 27822, 27845, 27854, 27855, 27852, 27853, 27848, + 27849, 27850, 27851, 27856, 27846, 27857, 27847, 27840, 27834, 27838, + 27839, 27860, 27766, 27765, 27858, 27831, 27828, 27837, 27843, 27777, + 27842, 27844, 27832, 27773, 27775, 27772, 27771, 27768, 27767, 27770, + 27769, 27776, 27774, 27778, 27833, 27779, 27859, 27829, 27830, 35762, + 28741, 28739, 28738, 28735, 28734, 28737, 28736, 28742, 28740, 28753, + 28752, 28751, 28747, 28746, 28750, 28749, 28745, 28748, 28743, 28744, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 17905, 17906, 17932, 17934, 17931, 17907, 17933, 17908, 17922, + 17921, 17897, 17895, 17896, 17915, 17920, 17919, 17904, 17903, 35762, + 17917, 17910, 17909, 17900, 17899, 17916, 17912, 17911, 17902, 17898, + 17901, 17918, 17924, 17923, 17894, 17892, 17893, 17926, 17930, 17928, + 17914, 17929, 17891, 17925, 17913, 17942, 17945, 17946, 17949, 17947, + 17943, 17948, 17944, 17939, 17937, 17938, 17935, 17889, 17888, 17950, + 17940, 17887, 17951, 17936, 17927, 17890, 17941, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 23597, + 23599, 23600, 23598, 23588, 23587, 23586, 35762, 23585, 35762, 23584, + 23583, 23576, 23575, 35762, 23570, 23578, 23577, 23566, 23564, 23565, + 23569, 23580, 23579, 23568, 23567, 23571, 23590, 23589, 23582, 35762, + 23581, 23593, 23596, 23574, 23592, 23595, 23594, 23591, 23573, 23572, + 23601, 35762, 35762, 35762, 35762, 35762, 35762, 17968, 17969, 17978, + 17979, 17976, 17977, 17997, 17970, 17998, 17971, 17987, 17986, 17957, + 17955, 17956, 17980, 17985, 17984, 17960, 17959, 17958, 17982, 17973, + 17972, 17963, 17961, 17966, 17962, 17981, 17975, 17974, 17965, 17964, + 17983, 17989, 17988, 17954, 17952, 17953, 17994, 17996, 17967, 17993, + 17995, 17990, 17991, 17992, 18001, 18002, 18007, 18008, 18005, 18006, + 18009, 18003, 18010, 18004, 18000, 17999, 35762, 35762, 35762, 35762, + 35762, 18017, 18019, 18016, 18015, 18012, 18011, 18014, 18013, 18020, + 18018, 35762, 35762, 35762, 35762, 35762, 35762, 13699, 13700, 13703, + 13706, 35762, 13656, 13657, 13670, 13671, 13668, 13669, 13651, 13653, + 35762, 35762, 13694, 13658, 35762, 35762, 13693, 13659, 13690, 13689, + 13686, 13685, 13674, 13684, 13683, 13688, 13687, 13676, 13665, 13664, + 13661, 13660, 13675, 13667, 13666, 13663, 13662, 13677, 35762, 13692, + 13691, 13682, 13681, 13696, 13698, 13697, 35762, 13673, 13672, 35762, + 13655, 13678, 13679, 13680, 13695, 35762, 7774, 13704, 13702, 13707, + 13716, 13717, 13714, 13715, 13710, 13711, 35762, 35762, 13719, 13708, + 35762, 35762, 13718, 13709, 13705, 35762, 35762, 13721, 35762, 35762, + 35762, 35762, 35762, 35762, 13720, 35762, 35762, 35762, 35762, 35762, + 13701, 13650, 13649, 13652, 13654, 13712, 13713, 35762, 35762, 7954, + 7955, 7953, 7952, 7951, 7950, 7949, 35762, 35762, 35762, 7960, 7957, + 7958, 7956, 7959, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 24495, 24496, 24509, 24510, 24507, 24508, 24491, 24492, 24493, + 24494, 24535, 24497, 24536, 24498, 24523, 24522, 24519, 24518, 24484, + 24483, 24517, 24516, 24521, 24520, 24486, 24485, 24504, 24503, 24500, + 24499, 24488, 24506, 24505, 24502, 24501, 24489, 24487, 24529, 24528, + 24515, 24514, 24527, 24526, 24534, 24531, 24530, 24525, 24524, 24533, + 24511, 24512, 24513, 24532, 24549, 24558, 24559, 24556, 24557, 24552, + 24553, 24554, 24555, 24560, 24550, 24561, 24551, 24544, 24539, 24538, + 24545, 24540, 24537, 24542, 24565, 24546, 24471, 24469, 24564, 24482, + 24562, 24478, 24480, 24477, 24476, 24473, 24472, 24475, 24474, 24481, + 24479, 24470, 24548, 35762, 24563, 24547, 24490, 24541, 24543, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 32336, + 32337, 32338, 32356, 32357, 32354, 32355, 32349, 32350, 32351, 32352, + 32382, 32339, 32383, 32340, 32374, 32373, 32370, 32369, 32358, 32368, + 32367, 32372, 32371, 32360, 32346, 32345, 32342, 32341, 32359, 32348, + 32347, 32344, 32343, 32361, 32376, 32375, 32366, 32365, 32379, 32381, + 32380, 32378, 32353, 32362, 32363, 32364, 32377, 32390, 32401, 32402, + 32399, 32400, 32395, 32396, 32397, 32398, 32403, 32393, 32391, 32404, + 32394, 32392, 32386, 32385, 32389, 32388, 32387, 32384, 32415, 32335, + 32416, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 32411, + 32413, 32410, 32409, 32406, 32405, 32408, 32407, 32414, 32412, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 27949, 27951, 27972, 27973, 27970, + 27971, 27965, 27966, 27967, 27968, 27998, 27952, 27999, 27953, 27990, + 27989, 27986, 27985, 27974, 27984, 27983, 27988, 27987, 27976, 27959, + 27958, 27962, 27961, 27975, 27960, 27955, 27964, 27963, 27977, 27992, + 27991, 27982, 27981, 27995, 27997, 27996, 27994, 27969, 27978, 27979, + 27980, 27993, 28027, 28034, 28035, 28032, 28033, 28030, 28031, 35762, + 35762, 28036, 28028, 28037, 28029, 28020, 28022, 28024, 28023, 28021, + 28019, 27947, 27946, 28018, 28017, 28000, 28001, 28002, 27948, 28015, + 28014, 28012, 28010, 28011, 28003, 28004, 28013, 28016, 28008, 28009, + 28007, 28006, 28005, 27954, 27956, 27957, 27950, 28025, 28026, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 22953, 22954, 22972, 22973, 22970, 22971, 22965, + 22966, 22967, 22968, 22999, 22955, 23000, 22956, 22992, 22991, 22988, + 22987, 22976, 22986, 22985, 22990, 22989, 22978, 22962, 22961, 22958, + 22957, 22977, 22964, 22963, 22960, 22959, 22979, 22994, 22993, 22984, + 22983, 22996, 22998, 22997, 22975, 22969, 22980, 22981, 22982, 22995, + 22974, 22928, 22937, 22938, 22935, 22936, 22931, 22932, 22933, 22934, + 22939, 22929, 22940, 22930, 22924, 22927, 22926, 22923, 22942, 22941, + 23001, 22925, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 22949, 22951, 22948, 22947, 22944, 22943, 22946, + 22945, 22952, 22950, 35762, 35762, 35762, 35762, 35762, 35762, 23481, + 23476, 23321, 23482, 23480, 23478, 23477, 23338, 23339, 23472, 23474, + 23473, 23483, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 30326, 30328, 30343, 30344, 30341, 30342, 30368, 30329, 30369, + 30330, 30358, 30357, 30354, 30353, 30345, 30352, 30351, 30356, 30355, + 30347, 30338, 30337, 30334, 30333, 30346, 30340, 30339, 30336, 30335, + 30348, 30360, 30359, 30350, 30349, 30365, 30367, 30332, 30364, 30366, + 30361, 30362, 30363, 30331, 30371, 30373, 30374, 30379, 30380, 30377, + 30378, 30381, 30375, 30382, 30376, 30372, 30370, 30327, 30325, 35762, + 35762, 35762, 35762, 35762, 35762, 30389, 30391, 30388, 30387, 30384, + 30383, 30386, 30385, 30392, 30390, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 191, 190, + 178, 181, 175, 167, 193, 192, 183, 195, 189, 184, 174, 196, 177, 197, + 180, 194, 164, 171, 170, 187, 166, 186, 182, 188, 165, 35762, 35762, 162, + 163, 161, 203, 204, 210, 211, 208, 209, 212, 207, 213, 205, 206, 200, + 35762, 35762, 35762, 35762, 222, 224, 221, 220, 217, 216, 219, 218, 225, + 223, 215, 214, 198, 199, 201, 202, 185, 173, 172, 169, 168, 179, 176, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 10719, 10720, 10733, 10734, 10731, + 10732, 10759, 10721, 10760, 10722, 10751, 10750, 10747, 10746, 10735, + 10745, 10744, 10749, 10748, 10737, 10728, 10727, 10724, 10723, 10736, + 10730, 10729, 10726, 10725, 10738, 10753, 10752, 10743, 10742, 10756, + 10758, 10718, 10755, 10757, 10739, 10740, 10741, 10754, 10717, 10763, + 10768, 10769, 10766, 10767, 10761, 10762, 10770, 10764, 10771, 10765, + 10774, 10776, 10775, 10773, 10772, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 33866, 33855, 33884, 33874, 33876, + 33877, 33883, 33873, 33859, 33868, 33856, 33886, 33882, 33861, 33875, + 33872, 33860, 33869, 33878, 33867, 33885, 33858, 33857, 33880, 33881, + 33864, 33863, 33862, 33865, 33870, 33871, 33879, 33898, 33887, 33916, + 33906, 33908, 33909, 33915, 33905, 33891, 33900, 33888, 33918, 33914, + 33893, 33907, 33904, 33892, 33901, 33910, 33899, 33917, 33890, 33889, + 33912, 33913, 33896, 33895, 33894, 33897, 33902, 33903, 33911, 33925, + 33927, 33924, 33923, 33920, 33919, 33922, 33921, 33928, 33926, 33937, + 33936, 33935, 33931, 33930, 33934, 33933, 33929, 33932, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 33938, 10633, 10634, 10641, 10642, 10639, 10640, 10668, 35762, 35762, + 10669, 35762, 35762, 10659, 10658, 10657, 10656, 10645, 10655, 10654, + 10663, 35762, 10647, 10629, 35762, 10636, 10635, 10646, 10630, 10628, + 10638, 10637, 10648, 10661, 10660, 10653, 10652, 10664, 10632, 10631, + 10665, 10644, 10666, 10649, 10650, 10651, 10662, 10643, 10667, 10674, + 10678, 10679, 10676, 10677, 10680, 35762, 10675, 10681, 35762, 35762, + 10673, 10671, 10670, 10682, 10687, 10684, 10688, 10683, 10672, 10617, + 10685, 10686, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 10624, 10626, 10623, 10622, 10619, 10618, 10621, 10620, 10627, + 10625, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 24192, 24193, 24206, 24207, 24204, 24205, 24187, 24188, 35762, + 35762, 24232, 24194, 24233, 24195, 24226, 24225, 24222, 24221, 24210, + 24220, 24219, 24224, 24223, 24212, 24201, 24200, 24197, 24196, 24211, + 24203, 24202, 24199, 24198, 24213, 24228, 24227, 24218, 24217, 24230, + 24231, 24191, 24209, 24189, 24214, 24215, 24216, 24229, 24208, 24190, + 24242, 24247, 24248, 24245, 24246, 24240, 24241, 35762, 35762, 24249, + 24243, 24250, 24244, 24236, 24238, 24237, 24235, 24234, 24251, 24239, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35543, 35564, 35561, + 35560, 35563, 35559, 35558, 35556, 35557, 35562, 35555, 35511, 35510, + 35530, 35529, 35512, 35528, 35527, 35537, 35514, 35522, 35521, 35504, + 35503, 35513, 35524, 35523, 35508, 35507, 35515, 35532, 35531, 35526, + 35525, 35539, 35520, 35519, 35506, 35505, 35533, 35534, 35535, 35542, + 35540, 35538, 35541, 35516, 35517, 35518, 35536, 35509, 35502, 35552, + 35549, 35550, 35551, 35548, 35553, 35499, 35498, 35496, 35495, 35497, + 35501, 35494, 35547, 35545, 35544, 35546, 35500, 35493, 35554, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 29142, 29163, 29161, + 29160, 29162, 29158, 29159, 29156, 29157, 29155, 29154, 29164, 29109, + 29108, 29128, 29127, 29110, 29126, 29125, 29130, 29129, 29112, 29120, + 29119, 29103, 29102, 29111, 29122, 29121, 29106, 29104, 29113, 29132, + 29131, 29124, 29123, 29138, 29118, 29117, 29105, 29133, 29134, 29135, + 29141, 29139, 29137, 29140, 29114, 29115, 29116, 29136, 29107, 29147, + 29149, 29085, 29084, 29082, 29083, 29093, 29094, 29089, 29092, 29088, + 29091, 29096, 29097, 29095, 29087, 29086, 29090, 29150, 29148, 29098, + 29151, 29146, 29145, 29144, 29143, 29101, 29100, 29099, 29152, 29153, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 5316, 5317, 5314, 5315, 5312, 5313, 5322, 5323, + 5320, 5321, 5318, 5319, 5485, 5486, 5487, 5484, 26453, 26451, 26460, + 26461, 26457, 26465, 26464, 26446, 26459, 26458, 26450, 26463, 26456, + 26449, 26455, 26454, 26447, 26452, 26462, 26441, 26448, 26466, 26467, + 26442, 26468, 26444, 26445, 26443, 26437, 26434, 26438, 26436, 26432, + 26435, 26439, 26433, 26440, 26474, 26473, 26484, 26475, 26476, 26485, + 26481, 26480, 26482, 26483, 26477, 26431, 26478, 26479, 26470, 26469, + 26429, 26471, 26472, 26430, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 10360, 10361, 10450, 10451, 10452, 10453, 10460, 10459, 10461, + 10469, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 3641, 3642, 3655, 3656, + 3653, 3654, 3637, 3638, 3639, 35762, 3681, 3643, 3682, 3644, 3673, 3672, + 3669, 3668, 3657, 3667, 3666, 3671, 3670, 3659, 3650, 3649, 3646, 3645, + 3658, 3652, 3651, 3648, 3647, 3660, 3675, 3674, 3665, 3664, 3678, 3680, + 3679, 3677, 3640, 3661, 3662, 3663, 3676, 3709, 3714, 3715, 3712, 3713, + 3706, 3707, 3708, 35762, 3716, 3710, 3717, 3711, 3703, 3702, 3705, 3704, + 3701, 3719, 3718, 3730, 3731, 3732, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 3726, 3728, 3725, 3724, 3721, 3720, + 3723, 3722, 3729, 3727, 3700, 3698, 3695, 3686, 3688, 3693, 3691, 3683, + 3689, 3699, 3697, 3696, 3685, 3687, 3694, 3692, 3684, 3690, 3733, 35762, + 35762, 35762, 21057, 21058, 21003, 21002, 21012, 20997, 21001, 21000, + 21014, 20998, 20994, 20993, 20996, 20999, 21005, 21004, 21011, 21016, + 20992, 20991, 20995, 21018, 21008, 21009, 21010, 21019, 21017, 21015, + 21006, 21007, 21013, 21020, 35762, 35762, 21035, 21034, 21043, 21029, + 21033, 21032, 21045, 21030, 21026, 21025, 21028, 21031, 21037, 21036, + 21042, 21047, 21024, 21023, 21027, 21049, 21040, 21041, 35762, 21050, + 21048, 21046, 21038, 21039, 21044, 21051, 21052, 21054, 21056, 21053, + 21055, 21022, 21021, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 21069, 21070, 21079, 21080, + 21077, 21078, 21106, 35762, 21071, 21107, 35762, 21072, 21085, 21084, + 21098, 21097, 21086, 21096, 21095, 21063, 21062, 21088, 21065, 21064, + 21074, 21073, 21087, 21068, 21066, 21076, 21075, 21089, 21100, 21099, + 21094, 21093, 21102, 21105, 21103, 21082, 21104, 21090, 21091, 21092, + 21101, 21081, 21083, 21061, 21067, 21116, 21121, 21122, 21119, 21120, + 21115, 35762, 35762, 35762, 21123, 35762, 21117, 21124, 35762, 21118, + 21114, 21113, 21112, 21110, 21111, 21125, 21109, 21108, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 21132, 21134, 21131, 21130, + 21127, 21126, 21129, 21128, 21135, 21133, 35762, 35762, 35762, 35762, + 35762, 35762, 14372, 14373, 14388, 14389, 14384, 14385, 35762, 14405, + 14374, 35762, 14404, 14375, 14411, 14410, 14393, 14392, 14407, 14401, + 14400, 14383, 14382, 14391, 14397, 14396, 14379, 14378, 14387, 14395, + 14394, 14381, 14380, 14390, 14399, 14398, 14377, 14376, 14386, 14403, + 14402, 14406, 14408, 14409, 14414, 14419, 14420, 14417, 14418, 35762, + 14422, 14415, 35762, 14421, 14416, 14413, 14412, 14423, 14434, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 14430, 14432, 14429, 14428, + 14425, 14424, 14427, 14426, 14433, 14431, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 20755, 20753, 20747, 20758, + 20750, 20757, 20761, 20752, 20749, 20751, 20754, 20748, 20763, 20759, + 20756, 20762, 20760, 20764, 20770, 20767, 20769, 20766, 20768, 20765, + 20746, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 17048, 17050, + 17046, 17049, 16988, 16989, 17008, 17009, 17006, 17007, 17002, 17003, + 17004, 17005, 17033, 16990, 17034, 35762, 17024, 17023, 17022, 17021, + 17010, 17020, 17019, 16993, 16992, 17012, 16999, 16998, 16995, 16994, + 17011, 17001, 17000, 16997, 16996, 17013, 17026, 17025, 17018, 17017, + 17029, 17032, 17030, 17028, 17031, 17014, 17015, 17016, 17027, 16991, + 17052, 17051, 17059, 17060, 17057, 17058, 17054, 35762, 35762, 35762, + 17055, 17053, 17056, 17047, 17073, 17062, 17061, 17041, 17044, 17040, + 17042, 17038, 17037, 17045, 17036, 17039, 17043, 17035, 17069, 17071, + 17068, 17067, 17064, 17063, 17066, 17065, 17072, 17070, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 20466, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 30449, 30445, 30439, 30448, 30441, 30450, 30454, 30456, 30451, 30446, + 30447, 30452, 30440, 30457, 30455, 30442, 30453, 30443, 30444, 30458, + 30459, 30523, 30506, 30504, 30513, 30512, 30508, 30514, 30510, 30509, + 30516, 30517, 30518, 30515, 30507, 30520, 30438, 30425, 30496, 30503, + 30804, 30805, 30423, 30398, 30524, 30803, 30460, 30525, 30511, 30519, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 30501, 8517, 8525, 8523, 8519, 8524, 8520, 8518, + 8521, 8522, 8586, 8526, 8535, 8534, 8528, 8527, 8539, 8529, 8530, 8538, + 8532, 8533, 8540, 8541, 8546, 8543, 8542, 8544, 8545, 8548, 8550, 8552, + 8551, 8553, 8559, 8556, 8557, 8561, 8554, 8555, 8560, 8558, 8563, 8562, + 8564, 8566, 8567, 8571, 8570, 8568, 8569, 8572, 8585, 8573, 8574, 8575, + 8584, 8576, 8580, 8581, 8579, 8577, 8578, 8583, 8582, 8587, 8588, 8599, + 8590, 8594, 8595, 8596, 8597, 8598, 8600, 8603, 8602, 8601, 8604, 8606, + 8607, 8608, 8609, 8610, 8611, 8612, 8613, 8614, 8615, 8616, 8617, 8618, + 8619, 8620, 8621, 8622, 8623, 8638, 8624, 8625, 8635, 8629, 8626, 8627, + 8628, 8636, 8633, 8637, 8634, 8630, 8632, 8645, 8641, 8642, 8643, 8646, + 8657, 8647, 8650, 8651, 8653, 8654, 8655, 8658, 8661, 8659, 8660, 8662, + 8663, 8665, 8666, 8695, 8702, 8696, 8697, 8698, 8699, 8700, 8701, 8703, + 8705, 8704, 8706, 8709, 8710, 8713, 8707, 8708, 8714, 8759, 8758, 8760, + 8715, 8718, 8719, 8720, 8716, 8717, 8721, 8724, 8722, 8725, 8727, 8736, + 8737, 8738, 8739, 8757, 8740, 8741, 8754, 8755, 8753, 8742, 8743, 8744, + 8745, 8746, 8747, 8748, 8751, 8752, 8761, 8851, 8762, 8763, 8765, 8764, + 8771, 8766, 8768, 8770, 8774, 8773, 8775, 8776, 8783, 8777, 8778, 8782, + 8786, 8787, 8784, 8785, 8793, 8790, 8794, 8795, 8796, 8797, 8798, 8800, + 8801, 8803, 8802, 8805, 8804, 8807, 8806, 8808, 8809, 8811, 8812, 8816, + 8818, 8822, 8823, 8836, 8828, 8829, 8824, 8825, 8826, 8830, 8834, 8831, + 8832, 8833, 8837, 8838, 8840, 8841, 8842, 8843, 8844, 8845, 8855, 8846, + 8847, 8850, 8849, 8848, 8852, 8853, 8854, 8856, 8857, 8860, 8861, 8862, + 8863, 8864, 8866, 8865, 8882, 8873, 8874, 8867, 8868, 8870, 8871, 8869, + 8872, 8881, 8875, 8880, 8878, 8877, 8879, 8884, 8903, 8885, 8886, 8887, + 8890, 8889, 8891, 8892, 8894, 8895, 8896, 8904, 8897, 8898, 8899, 8902, + 8901, 8900, 8905, 8906, 8908, 8909, 8910, 8911, 8913, 8917, 8914, 8918, + 8916, 8915, 8919, 8920, 8921, 8922, 8926, 8925, 8923, 8924, 8927, 8928, + 8930, 8949, 8951, 8931, 8933, 8932, 8934, 8935, 8938, 8939, 8937, 8936, + 8940, 8941, 8942, 8943, 8946, 8944, 8945, 8947, 8948, 8952, 8953, 8950, + 8954, 8955, 8956, 8957, 8959, 8962, 8961, 8963, 8964, 8966, 8967, 8968, + 8972, 8971, 8969, 8970, 8973, 8977, 8976, 8975, 8978, 8979, 8981, 8982, + 8986, 8983, 8984, 8989, 8987, 8990, 8991, 8993, 8992, 8994, 8995, 9017, + 9016, 9019, 9020, 9001, 9002, 8999, 9000, 8998, 8996, 9004, 9003, 9005, + 9007, 9013, 9014, 9011, 9012, 9021, 9022, 9023, 9040, 9026, 9027, 9028, + 9024, 9025, 9029, 9030, 9031, 9032, 9033, 9034, 9035, 9036, 9037, 9038, + 9063, 9041, 9044, 9042, 9043, 9049, 9050, 9047, 9048, 9045, 9046, 9051, + 9052, 9060, 9053, 9054, 9061, 9058, 9059, 9062, 9055, 9056, 9057, 9064, + 9065, 9066, 9067, 9068, 9069, 9070, 9072, 9073, 9071, 9074, 9075, 9116, + 9117, 9078, 9079, 9076, 9077, 9082, 9083, 9081, 9087, 9084, 9086, 9085, + 9091, 9092, 9090, 9088, 9089, 9093, 9094, 9095, 9096, 9097, 9098, 9099, + 9118, 9104, 9100, 9101, 9102, 9103, 9105, 9107, 9106, 9108, 9109, 9111, + 9110, 9112, 9114, 9113, 9119, 9120, 9123, 9124, 9121, 9122, 9198, 9193, + 9194, 9195, 9196, 9197, 9199, 9202, 9200, 9201, 9203, 9245, 9204, 9234, + 9235, 9211, 9213, 9230, 9214, 9236, 9218, 9216, 9217, 9219, 9220, 9221, + 9222, 9231, 9232, 9225, 9226, 9228, 9237, 9205, 9206, 9210, 9208, 9246, + 9238, 9240, 9239, 9241, 9247, 9248, 9242, 9243, 9244, 9249, 9250, 9251, + 9254, 9255, 9256, 9252, 9253, 9257, 9258, 9260, 9262, 9263, 9281, 9279, + 9280, 9283, 9282, 9264, 9271, 9269, 9270, 9265, 9266, 9272, 9273, 9274, + 9275, 9276, 9278, 9284, 9293, 9285, 9287, 9288, 9286, 9289, 9291, 9290, + 9292, 9295, 9297, 9296, 9298, 9299, 9332, 9334, 9300, 9302, 9301, 9304, + 9307, 9305, 9306, 9310, 9314, 9317, 9316, 9319, 9322, 9320, 9321, 9325, + 9327, 9333, 9335, 9336, 9340, 9347, 9345, 9343, 9344, 9346, 9349, 9348, + 9341, 9342, 9350, 9353, 9359, 9354, 9357, 9352, 9351, 9360, 9358, 9355, + 9356, 9361, 9362, 9363, 9364, 9365, 9366, 9367, 9369, 9372, 9373, 9376, + 9377, 9378, 9374, 9375, 9370, 9371, 9379, 9380, 9381, 9382, 9383, 9384, + 9386, 9387, 9388, 9389, 9390, 9394, 9391, 9415, 9408, 9409, 9414, 9397, + 9396, 9410, 9413, 9411, 9400, 9399, 9402, 9404, 9405, 9406, 9407, 9403, + 9416, 9392, 9417, 9418, 9419, 9420, 9421, 9422, 9430, 9428, 9426, 9429, + 9425, 9427, 9423, 9424, 9431, 9433, 9434, 9435, 9442, 9437, 9438, 9446, + 9447, 9443, 9445, 9444, 9448, 9450, 9449, 9451, 9462, 9453, 9452, 9461, + 9459, 9454, 9455, 9456, 9458, 9457, 9460, 9466, 9463, 9465, 9464, 9467, + 9468, 9469, 9470, 9473, 9474, 9476, 9477, 9478, 9479, 9481, 9480, 9482, + 9489, 9483, 9484, 9490, 9485, 9486, 9487, 9488, 9491, 9495, 9492, 9493, + 9494, 9496, 9497, 9498, 9499, 9505, 9503, 9501, 9502, 9500, 9504, 9506, + 9508, 9525, 9526, 9509, 9514, 9516, 9510, 9513, 9511, 9512, 9517, 9523, + 9524, 9518, 9521, 9522, 9527, 9533, 9532, 9528, 9530, 9529, 9614, 9615, + 9534, 9535, 9540, 9541, 9538, 9539, 9542, 9536, 9537, 9543, 9546, 9547, + 9549, 9550, 9551, 9555, 9552, 9553, 9554, 9544, 9545, 9556, 9558, 9557, + 9559, 9561, 9562, 9563, 9569, 9568, 9564, 9565, 9566, 9601, 9570, 9571, + 9572, 9573, 9574, 9593, 9576, 9577, 9579, 9578, 9580, 9581, 9597, 9582, + 9584, 9583, 9596, 9586, 9594, 9598, 9589, 9588, 9595, 9590, 9592, 9591, + 9599, 9600, 9602, 9606, 9604, 9605, 9603, 9609, 9608, 9607, 9613, 9610, + 9611, 9612, 9616, 9618, 9617, 9621, 9619, 9636, 9622, 9625, 9627, 9623, + 9624, 9628, 9626, 9629, 9631, 9633, 9634, 9635, 9039, 8536, 8547, 8565, + 8631, 8640, 8656, 8664, 8756, 8749, 8767, 8769, 8859, 8883, 8929, 8958, + 8960, 8974, 8980, 9015, 8988, 9018, 8997, 9006, 9010, 9080, 9209, 9212, + 9227, 9259, 9277, 9294, 9303, 9331, 9329, 9308, 9339, 9368, 9385, 9395, + 9515, 9548, 9531, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 8501, 8496, 8433, 8419, 8480, 8476, 8408, + 8453, 8500, 8441, 8425, 8486, 8475, 8407, 8452, 8439, 8423, 8482, 8472, + 8402, 8449, 8462, 8506, 8498, 8435, 8421, 8484, 8474, 8404, 8451, 8463, + 8507, 8499, 8436, 8422, 8508, 8490, 8491, 8437, 8413, 8479, 8471, 8401, + 8448, 8466, 8509, 8492, 8493, 8438, 8414, 8477, 8478, 8461, 8504, 8487, + 8488, 8428, 8418, 8494, 8495, 8429, 8432, 8430, 8431, 8485, 8470, 8468, + 8469, 8405, 8406, 8444, 8446, 8447, 8445, 8502, 8497, 8434, 8420, 8481, + 8460, 8503, 8489, 8426, 8427, 8416, 8417, 8443, 8442, 8456, 8505, 8465, + 8511, 8415, 8464, 8510, 8457, 8458, 8454, 8455, 8459, 8467, 8409, 8412, + 8411, 8410, 8440, 8424, 8483, 8473, 8403, 8450, 35762, 8516, 8515, 8514, + 8512, 8513, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 8537, 8531, 8549, 8589, 8591, 8592, 8593, 8605, + 8644, 8639, 8649, 8648, 8652, 8669, 8667, 8668, 8670, 8671, 8689, 8675, + 8672, 8673, 8674, 8691, 8692, 8690, 8679, 8678, 8676, 8677, 8682, 8680, + 8681, 8683, 8684, 8685, 8686, 8693, 8694, 8688, 8687, 8712, 8711, 8723, + 8726, 8731, 8735, 8728, 8732, 8733, 8729, 8730, 8734, 8750, 8772, 8779, + 8780, 8781, 8788, 8789, 8792, 8791, 8799, 8810, 8813, 8814, 8815, 8817, + 8819, 8820, 8821, 8827, 8835, 8839, 8858, 8876, 8888, 8893, 8907, 8912, + 8965, 8985, 9008, 9009, 9115, 9135, 9125, 9126, 9134, 9130, 9131, 9132, + 9129, 9128, 9127, 9133, 9137, 9136, 9143, 9144, 9138, 9139, 9140, 9145, + 9141, 9142, 9146, 9147, 9148, 9149, 9150, 9151, 9158, 9152, 9157, 9156, + 9154, 9153, 9155, 9159, 9160, 9165, 9166, 9161, 9162, 9163, 9164, 9192, + 9188, 9167, 9175, 9176, 9174, 9173, 9177, 9168, 9169, 9171, 9172, 9170, + 9189, 9178, 9185, 9187, 9182, 9183, 9186, 9181, 9184, 9180, 9179, 9190, + 9191, 9207, 9233, 9215, 9223, 9224, 9229, 9261, 9268, 9267, 9328, 9309, + 9311, 9330, 9312, 9313, 9315, 9318, 9323, 9324, 9326, 9393, 9412, 9398, + 9401, 9432, 9436, 9439, 9440, 9441, 9472, 9471, 9475, 9507, 9519, 9520, + 9560, 9567, 9575, 9587, 9585, 9620, 9630, 9632, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 9709, + 9710, 9711, 9712, 9713, 9714, 9715, 9716, 9719, 9720, 9717, 9718, 9721, + 9722, 9723, 9724, 9725, 9726, 9727, 9728, 9729, 9730, 9731, 9732, 9733, + 9734, 9735, 9736, 9737, 9738, 9739, 9740, 9741, 9742, 9743, 9744, 9745, + 9746, 9747, 9748, 9749, 9750, 9751, 9752, 9753, 9754, 9755, 9775, 9776, + 9777, 9778, 9779, 9780, 9781, 9782, 9783, 9758, 9759, 9760, 9761, 9762, + 9756, 9757, 9763, 9764, 9765, 9784, 9785, 9786, 9787, 9788, 9789, 9790, + 9791, 9792, 9793, 9766, 9767, 9768, 9769, 9770, 9771, 9772, 9773, 9774, + 9794, 9795, 9796, 9797, 9798, 9799, 9800, 9801, 9802, 9803, 9804, 9805, + 9806, 9807, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 11228, 11229, 11230, 11231, 11226, + 11227, 11223, 11224, 11225, 11232, 11233, 11234, 11239, 11240, 11241, + 11242, 11235, 11236, 11243, 11244, 11237, 11238, 11245, 11246, 11273, + 11274, 11275, 11276, 11277, 11278, 11279, 11280, 11281, 11282, 11263, + 11264, 11261, 11262, 11265, 11266, 11267, 11268, 11269, 11270, 11271, + 11247, 11248, 11255, 11249, 11250, 11251, 11252, 11256, 11253, 11254, + 11257, 11258, 11259, 11260, 11283, 11284, 11285, 11286, 11287, 11288, + 11289, 11290, 11291, 11292, 11293, 11294, 11295, 11296, 11297, 11298, + 11299, 11300, 11301, 11302, 11272, 11342, 11343, 11344, 11345, 11340, + 11341, 11346, 11347, 11348, 11349, 11354, 11350, 11351, 11352, 11353, + 11355, 11356, 11357, 11358, 11359, 11360, 11361, 11362, 11363, 11364, + 11365, 11366, 11367, 11368, 11369, 11370, 11371, 11372, 11373, 11374, + 11375, 11376, 11377, 11380, 11381, 11382, 11383, 11384, 11385, 11386, + 11378, 11379, 11387, 11460, 11461, 11462, 11463, 11464, 11465, 11466, + 11467, 11468, 11469, 11451, 11452, 11453, 11454, 11455, 11456, 11457, + 11449, 11450, 11458, 11459, 11392, 11388, 11389, 11393, 11394, 11390, + 11391, 11395, 11396, 11397, 11398, 11399, 11404, 11405, 11406, 11407, + 11408, 11409, 11400, 11401, 11410, 11402, 11403, 11411, 11412, 11413, + 11414, 11415, 11416, 11417, 11418, 11419, 11420, 11421, 11426, 11422, + 11423, 11427, 11424, 11425, 11428, 11429, 11430, 11431, 11432, 11442, + 11443, 11444, 11445, 11446, 11447, 11448, 11433, 11434, 11435, 11436, + 11437, 11438, 11439, 11440, 11441, 11474, 11475, 11476, 11477, 11478, + 11479, 11480, 11470, 11471, 11472, 11473, 11506, 11507, 11508, 11509, + 11510, 11511, 11502, 11503, 11504, 11505, 11512, 11513, 11481, 11482, + 11485, 11486, 11487, 11488, 11489, 11490, 11491, 11483, 11484, 11492, + 11495, 11496, 11497, 11498, 11493, 11494, 11499, 11500, 11501, 11517, + 11518, 11519, 11520, 11521, 11522, 11523, 11524, 11525, 11526, 11529, + 11530, 11531, 11527, 11528, 11532, 11533, 11534, 11535, 11536, 11537, + 11573, 11571, 11572, 11574, 11575, 11576, 11577, 11578, 11579, 11580, + 11581, 11544, 11538, 11539, 11545, 11546, 11547, 11548, 11549, 11540, + 11541, 11542, 11543, 11550, 11557, 11558, 11559, 11560, 11561, 11551, + 11552, 11553, 11554, 11555, 11556, 11562, 11563, 11568, 11564, 11565, + 11566, 11567, 11569, 11570, 11588, 11589, 11590, 11591, 11592, 11586, + 11587, 11583, 11584, 11585, 11593, 11594, 11597, 11595, 11596, 11598, + 11599, 11600, 11601, 11602, 11603, 11604, 11605, 11630, 11631, 11634, + 11635, 11636, 11637, 11638, 11632, 11633, 11639, 11640, 11641, 11610, + 11611, 11612, 11613, 11614, 11615, 11606, 11607, 11608, 11609, 11616, + 11617, 11622, 11623, 11624, 11618, 11619, 11625, 11620, 11621, 11626, + 11627, 11628, 11629, 11642, 11643, 11644, 11645, 11646, 11649, 11650, + 11651, 11652, 11653, 11647, 11648, 11654, 11655, 11663, 11664, 11665, + 11666, 11659, 11660, 11667, 11668, 11669, 11661, 11662, 11670, 11671, + 11672, 11673, 11674, 11675, 11676, 11677, 12318, 12319, 12320, 12321, + 12322, 12323, 12324, 12325, 11689, 11685, 11686, 11690, 11691, 11692, + 11687, 11688, 11693, 11694, 11696, 11697, 11698, 11701, 11699, 11700, + 11702, 11703, 11704, 11705, 11706, 11707, 11717, 11718, 11725, 11708, + 11709, 11710, 11711, 11712, 11713, 11714, 11715, 11716, 11726, 11727, + 11719, 11720, 11721, 11722, 11723, 11724, 11728, 11729, 11736, 11737, + 11730, 11731, 11738, 11732, 11733, 11739, 11740, 11741, 11734, 11735, + 11742, 11748, 11746, 11747, 11749, 11743, 11744, 11745, 11750, 11751, + 11752, 11753, 11754, 11755, 11756, 11757, 11758, 11759, 11760, 11761, + 11818, 11819, 11820, 11821, 11822, 11823, 11824, 11825, 11826, 11781, + 11782, 11783, 11784, 11785, 11786, 11787, 11788, 11778, 11779, 11780, + 11789, 11806, 11807, 11808, 11809, 11810, 11804, 11805, 11811, 11812, + 11813, 11814, 11798, 11799, 11800, 11790, 11791, 11792, 11793, 11794, + 11795, 11801, 11796, 11797, 11802, 11803, 11815, 11816, 11817, 11829, + 11830, 11831, 11832, 11827, 11828, 11833, 11834, 11835, 11836, 11839, + 11840, 11841, 11842, 11843, 11844, 11845, 11837, 11838, 11846, 11847, + 11848, 11866, 11867, 11868, 11869, 11870, 11871, 11872, 11873, 11874, + 11849, 11850, 11851, 11852, 11855, 11856, 11857, 11858, 11859, 11860, + 11853, 11854, 11861, 11864, 11865, 11862, 11863, 11882, 11883, 11886, + 11887, 11888, 11884, 11885, 11875, 11876, 11877, 11878, 11879, 11880, + 11881, 11889, 11890, 11891, 11892, 11893, 11894, 11895, 11898, 11899, + 11900, 11901, 11902, 11903, 11904, 11905, 11896, 11897, 11906, 11907, + 11914, 11915, 11916, 11908, 11909, 11910, 11911, 11917, 11918, 11919, + 11912, 11913, 11925, 11926, 11929, 11930, 11927, 11928, 11931, 11932, + 11920, 11921, 11922, 11923, 11924, 11933, 11934, 11935, 11940, 11941, + 11942, 11943, 11944, 11945, 11946, 11947, 11948, 11949, 11936, 11937, + 11938, 11939, 11951, 11952, 11955, 11953, 11954, 11956, 11957, 11958, + 11959, 11960, 11961, 11962, 11963, 12326, 12327, 12328, 12329, 12330, + 12331, 12332, 11969, 11967, 11968, 11964, 11965, 11966, 11970, 11971, + 11972, 11973, 11974, 11975, 11976, 11977, 11980, 11981, 11982, 11983, + 11984, 11978, 11979, 11985, 11986, 11987, 11988, 11989, 11990, 11991, + 11992, 11993, 11994, 11995, 11996, 11997, 12002, 11998, 11999, 12003, + 12004, 12005, 12000, 12001, 12006, 12007, 12008, 12014, 12015, 12016, + 12017, 12009, 12010, 12011, 12018, 12019, 12012, 12013, 12020, 12021, + 12025, 12026, 12027, 12028, 12029, 12030, 12022, 12023, 12024, 12031, + 12032, 12033, 12036, 12037, 12038, 12039, 12040, 12034, 12035, 12041, + 12042, 12043, 12044, 12045, 12046, 12047, 12048, 12049, 12050, 12051, + 12060, 12061, 12052, 12053, 12062, 12063, 12064, 12054, 12055, 12056, + 12057, 12058, 12059, 12069, 12065, 12066, 12070, 12071, 12072, 12073, + 12067, 12068, 12074, 12075, 12076, 12086, 12087, 12088, 12089, 12090, + 12091, 12092, 12093, 12094, 12095, 12081, 12082, 12077, 12078, 12079, + 12080, 12083, 12084, 12085, 12100, 12101, 12102, 12103, 12104, 12097, + 12098, 12099, 12105, 12106, 12107, 12134, 12135, 12136, 12137, 12138, + 12139, 12140, 12141, 12142, 12143, 12112, 12113, 12114, 12108, 12109, + 12115, 12116, 12117, 12118, 12119, 12110, 12111, 12122, 12123, 12120, + 12121, 12124, 12125, 12126, 12127, 12128, 12129, 12130, 12131, 12132, + 12133, 12147, 12148, 12149, 12150, 12151, 12152, 12153, 12154, 12155, + 12156, 12157, 12158, 12159, 12160, 12161, 12162, 12144, 12145, 12146, + 12163, 12164, 12173, 12165, 12166, 12167, 12168, 12170, 12171, 12172, + 12174, 12175, 12176, 12177, 12178, 12179, 12180, 12181, 12182, 12183, + 12184, 12185, 12186, 12187, 12188, 12189, 12190, 12191, 12192, 12193, + 12200, 12201, 12194, 12195, 12202, 12203, 12204, 12205, 12196, 12197, + 12198, 12199, 12206, 12207, 12208, 12209, 12214, 12210, 12211, 12215, + 12216, 12217, 12212, 12213, 12218, 12219, 12220, 12221, 12227, 12228, + 12223, 12224, 12229, 12230, 12231, 12232, 12233, 12225, 12226, 12234, + 12235, 12242, 12243, 12244, 12236, 12237, 12245, 12246, 12238, 12239, + 12240, 12241, 12247, 12250, 12251, 12252, 12253, 12248, 12249, 12254, + 12263, 12264, 12265, 12256, 12257, 12258, 12266, 12259, 12260, 12267, + 12261, 12262, 12268, 12269, 12270, 12271, 12272, 12273, 12274, 12275, + 12276, 12289, 12277, 12278, 12279, 12280, 12281, 12282, 12283, 12284, + 12285, 12286, 12287, 12288, 12290, 12291, 12292, 12293, 12313, 12314, + 12315, 12316, 12317, 12294, 12295, 12296, 12297, 12298, 12299, 12300, + 12301, 12302, 12303, 12304, 12305, 12306, 12307, 12308, 12309, 12310, + 12311, 12312, 11306, 11307, 11308, 11309, 11310, 11311, 11303, 11304, + 11305, 11312, 11313, 11317, 11318, 11319, 11320, 11321, 11322, 11323, + 11324, 11325, 11326, 11327, 11328, 11329, 11330, 11331, 11332, 11333, + 11334, 11335, 11336, 11314, 11315, 11316, 12169, 12222, 11658, 11683, + 11680, 11682, 11679, 11950, 11337, 11514, 11684, 11681, 11678, 11339, + 11516, 11338, 11515, 11777, 11582, 11656, 11695, 11657, 12096, 12255, + 11773, 11764, 11768, 11775, 11771, 11765, 11770, 11767, 11774, 11763, + 11769, 11776, 11772, 11766, 11762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 435, 436, 437, 438, 439, 440, 441, + 442, 443, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 365, + 366, 367, 368, 369, 370, 363, 364, 371, 372, 373, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 413, 414, 381, 377, 378, 382, 383, 384, 379, + 380, 374, 375, 376, 385, 386, 387, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 392, 393, 394, 395, 396, 397, 388, 389, 390, 391, 398, + 399, 400, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 405, 406, 407, 408, 409, 410, + 411, 401, 402, 403, 404, 412, 485, 486, 487, 488, 489, 490, 491, 474, + 475, 476, 477, 482, 483, 484, 492, 478, 479, 480, 481, 493, 494, 495, + 496, 497, 500, 501, 502, 503, 498, 499, 504, 505, 506, 507, 510, 511, + 512, 513, 514, 508, 509, 515, 516, 517, 518, 521, 522, 523, 524, 525, + 519, 520, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, + 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, + 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, + 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, + 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 597, 598, 590, 591, + 592, 599, 600, 601, 602, 593, 594, 603, 595, 596, 608, 609, 610, 611, + 612, 604, 605, 606, 607, 613, 614, 615, 641, 642, 643, 644, 645, 646, + 647, 639, 640, 648, 649, 661, 662, 663, 664, 665, 666, 667, 668, 669, + 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, + 684, 685, 686, 687, 688, 689, 690, 652, 653, 654, 655, 656, 657, 658, + 650, 651, 659, 660, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, + 630, 631, 632, 633, 634, 635, 636, 637, 638, 628, 629, 620, 621, 622, + 623, 616, 617, 624, 625, 626, 627, 618, 619, 703, 704, 705, 706, 707, + 708, 709, 710, 711, 701, 702, 795, 796, 797, 798, 799, 800, 801, 802, + 803, 804, 714, 715, 716, 717, 718, 719, 720, 721, 722, 712, 713, 741, + 742, 738, 739, 740, 743, 744, 745, 734, 735, 736, 737, 746, 747, 748, + 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 725, 726, 727, 728, + 729, 730, 731, 732, 733, 723, 724, 753, 754, 755, 756, 749, 750, 757, + 758, 759, 751, 752, 760, 786, 784, 785, 787, 788, 789, 790, 791, 792, + 793, 794, 767, 763, 764, 768, 761, 762, 769, 770, 765, 766, 771, 772, + 773, 775, 776, 777, 774, 778, 779, 780, 781, 782, 783, 846, 847, 848, + 849, 850, 851, 852, 853, 854, 855, 815, 816, 817, 818, 819, 820, 821, + 822, 823, 824, 825, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, + 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, + 880, 881, 882, 883, 884, 885, 826, 827, 830, 831, 832, 833, 834, 835, + 828, 829, 836, 837, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, + 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 838, 839, 840, 841, 842, 843, 844, 845, + 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, + 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, + 945, 916, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 2827, 2794, 2852, 2853, 2823, + 2860, 2871, 2842, 2859, 2854, 2855, 2807, 2872, 2829, 2808, 2813, 2820, + 2866, 2838, 2797, 2832, 2867, 2828, 2804, 2805, 2836, 2810, 2851, 2793, + 2850, 2819, 2843, 2874, 2792, 2837, 2868, 2822, 2821, 2817, 2795, 2849, + 2826, 2856, 2809, 2846, 2857, 2873, 2802, 2863, 2870, 2811, 2798, 2825, + 2800, 2818, 2861, 2803, 2876, 2878, 2799, 2864, 2814, 2858, 2835, 2862, + 2840, 2847, 2831, 2875, 2830, 2812, 2844, 2815, 2841, 2869, 2865, 2848, + 2833, 2806, 2839, 2796, 2834, 2877, 2801, 2845, 2824, 2816, 2910, 2926, + 2924, 2923, 2889, 2895, 2884, 2930, 2894, 2886, 2916, 2929, 2888, 2914, + 2915, 2879, 2919, 2927, 2921, 2922, 2901, 2898, 2913, 2882, 2880, 2881, + 2887, 2917, 2934, 2908, 2906, 2931, 2920, 2928, 2900, 2904, 2905, 2902, + 2925, 2897, 2903, 2912, 2918, 2899, 2932, 2896, 2933, 2883, 2893, 2892, + 2890, 2907, 2911, 2891, 2885, 2909, 2986, 3006, 3027, 3023, 2985, 2974, + 2987, 2935, 2963, 2937, 3007, 3003, 2960, 3008, 2978, 2957, 2940, 2936, + 2942, 3026, 3005, 2968, 2998, 2966, 3028, 2947, 2948, 3012, 2979, 3016, + 2994, 3020, 3015, 2981, 3022, 2972, 2954, 3004, 2982, 2950, 2965, 2970, + 3001, 3017, 2984, 3031, 2975, 3000, 2997, 3030, 3021, 2962, 3032, 2990, + 2949, 3019, 2995, 2992, 2944, 2980, 2956, 2967, 2952, 2946, 2991, 2989, + 3024, 2983, 2999, 3002, 2945, 2996, 2976, 2953, 3029, 2977, 3013, 3011, + 2964, 2955, 2959, 2941, 2961, 2943, 2958, 3025, 2993, 2971, 2969, 3014, + 2939, 2938, 2988, 2973, 2951, 3009, 3010, 3018, 3060, 3144, 3093, 3067, + 3094, 3053, 3092, 3098, 3080, 3107, 3143, 3089, 3123, 3090, 3037, 3136, + 3121, 3096, 3128, 3041, 3145, 3043, 3130, 3065, 3075, 3056, 3062, 3132, + 3149, 3091, 3038, 3086, 3138, 3036, 3088, 3033, 3076, 3070, 3048, 3077, + 3072, 3071, 3113, 3069, 3066, 3054, 3099, 3058, 3046, 3105, 3134, 3133, + 3146, 3039, 3120, 3137, 3085, 3064, 3100, 3040, 3116, 3111, 3106, 3051, + 3079, 3068, 3083, 3147, 3115, 3148, 3078, 3102, 3127, 3044, 3082, 3087, + 3139, 3061, 3045, 3101, 3135, 3057, 3081, 3049, 3084, 3097, 3095, 3035, + 3042, 3117, 3141, 3140, 3108, 3119, 3050, 3063, 3055, 3129, 3074, 3125, + 3122, 3047, 3110, 3126, 3103, 3112, 3109, 3124, 3114, 3073, 3052, 3118, + 3142, 3104, 3059, 3131, 3034, 3203, 3280, 3190, 3177, 3287, 3180, 3243, + 3269, 3259, 3229, 3206, 3254, 3274, 3215, 3170, 3290, 3262, 3208, 3244, + 3279, 3172, 3182, 3231, 3221, 3187, 3218, 3222, 3230, 3261, 3228, 3247, + 3270, 3211, 3194, 3164, 3217, 3225, 3188, 3181, 3209, 3205, 3271, 3263, + 3257, 3202, 3210, 3295, 3163, 3284, 3291, 3251, 3283, 3167, 3268, 3277, + 3285, 3288, 3176, 3253, 3273, 3161, 3223, 3264, 3193, 3191, 3236, 3240, + 3160, 3282, 3171, 3303, 3234, 3296, 3192, 3204, 3249, 3299, 3179, 3153, + 3159, 3220, 3169, 3186, 3216, 3165, 3155, 3232, 3245, 3293, 3207, 3235, + 3237, 3252, 3196, 3154, 3239, 3197, 3162, 3152, 3200, 3255, 3219, 3173, + 3250, 3233, 3292, 3212, 3241, 3151, 3158, 3226, 3304, 3281, 3306, 3305, + 3178, 3242, 3272, 3275, 3201, 3267, 3294, 3213, 3300, 3297, 3298, 3302, + 3301, 3168, 3246, 3227, 3256, 3289, 3157, 3286, 3184, 3195, 3260, 3258, + 3214, 3224, 3265, 3266, 3150, 3238, 3248, 3183, 3175, 3198, 3185, 3189, + 3276, 3174, 3199, 3278, 3156, 3166, 3311, 3360, 3313, 3358, 3338, 3351, + 3332, 3315, 3341, 3340, 3320, 3350, 3330, 3326, 3317, 3348, 3343, 3349, + 3346, 3309, 3308, 3328, 3327, 3325, 3353, 3345, 3354, 3329, 3334, 3331, + 3355, 3335, 3342, 3333, 3337, 3307, 3323, 3324, 3344, 3336, 3359, 3356, + 3316, 3314, 3312, 3318, 3339, 3321, 3322, 3319, 3352, 3310, 3347, 3357, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 23535, 23527, 23548, + 23525, 23549, 23536, 23551, 23531, 23522, 23539, 23537, 23547, 23521, + 23529, 23524, 23526, 23532, 23530, 23528, 23541, 23544, 23533, 23543, + 23550, 23542, 23523, 23546, 23545, 23538, 23540, 23534, 35762, 23560, + 23562, 23559, 23558, 23555, 23554, 23557, 23556, 23563, 23561, 35762, + 35762, 35762, 35762, 23553, 23552, 30867, 30864, 30865, 30866, 30819, + 30816, 30817, 30818, 30871, 30868, 30869, 30870, 30859, 30856, 30857, + 30858, 30863, 30860, 30861, 30862, 30855, 30852, 30853, 30854, 30815, + 30812, 30813, 30814, 30847, 30844, 30845, 30846, 30820, 30825, 30836, + 30837, 30848, 30851, 30849, 30850, 30843, 30840, 30841, 30842, 30831, + 30828, 30829, 30830, 30882, 30881, 30880, 30832, 30839, 30889, 30887, + 30884, 30834, 30883, 30885, 30827, 30835, 30824, 30826, 30823, 30874, + 30878, 30886, 30833, 30838, 30876, 30873, 30879, 30822, 30872, 30888, + 30821, 30877, 30875, 30890, 35762, 30897, 30899, 30896, 30895, 30892, + 30891, 30894, 30893, 30900, 30898, 35762, 35762, 35762, 35762, 35762, + 35762, 3421, 3426, 3442, 3444, 3434, 3432, 3424, 3418, 3425, 3438, 3433, + 3429, 3440, 3423, 3419, 3441, 3428, 3439, 3443, 3437, 3431, 3445, 3430, + 3446, 3435, 3436, 3427, 3422, 3420, 3447, 35762, 35762, 3414, 3416, 3417, + 3415, 3413, 3448, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 26200, 26201, 26206, 26207, 26194, 26195, 26210, 26211, + 26202, 26203, 26192, 26193, 26212, 26213, 26196, 26197, 26208, 26209, + 26214, 26215, 26204, 26205, 26198, 26199, 26216, 26217, 26190, 26191, + 26136, 26127, 26133, 26124, 26129, 26135, 26128, 26132, 26138, 26122, + 26134, 26120, 26125, 26123, 26131, 26126, 26130, 26139, 26137, 26121, + 26144, 26143, 26141, 26140, 26142, 26146, 26145, 26176, 26177, 26155, + 26175, 26173, 26181, 26183, 26182, 26184, 26174, 26166, 26179, 26164, + 26186, 26159, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 26224, 26226, 26223, 26222, 26219, 26218, 26221, 26220, + 26227, 26225, 35762, 26151, 26148, 26150, 26153, 26147, 26149, 26152, + 35762, 26178, 26185, 26163, 26171, 26187, 26162, 26169, 26180, 26168, + 26189, 26170, 26165, 26172, 26188, 26167, 26161, 26154, 26157, 26158, + 26160, 26156, 35762, 35762, 35762, 35762, 35762, 26108, 26115, 26107, + 26106, 26116, 26104, 26101, 26119, 26111, 26109, 26117, 26103, 26102, + 26112, 26118, 26114, 26110, 26105, 26113, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 22208, 22212, 22215, 22216, 22186, 22218, 22194, 22209, + 22213, 22204, 22203, 22205, 22193, 22185, 22206, 22202, 22199, 22200, + 22214, 22196, 22207, 22210, 22192, 22190, 22217, 22201, 22198, 22188, + 22211, 22197, 22187, 22195, 22266, 22270, 22273, 22274, 22244, 22276, + 22252, 22267, 22271, 22262, 22261, 22263, 22251, 22243, 22264, 22260, + 22257, 22258, 22272, 22254, 22265, 22268, 22250, 22248, 22275, 22259, + 22256, 22246, 22269, 22255, 22245, 22253, 22230, 22224, 22222, 22220, + 22227, 22226, 22229, 22228, 22232, 22231, 22235, 22237, 22234, 22233, + 22238, 22239, 22241, 22242, 22236, 22240, 22225, 22223, 22221, 22219, + 22279, 22277, 22278, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 22822, 22748, 22810, 22821, 22826, 22825, + 22745, 22827, 22802, 22801, 22799, 22756, 22805, 22806, 22798, 22755, + 22764, 22772, 22808, 22744, 22769, 22768, 22763, 22762, 22761, 22760, + 22786, 22754, 22785, 22753, 22828, 22759, 22809, 22820, 22819, 22767, + 22766, 22743, 22824, 22830, 22758, 22757, 22795, 22751, 22771, 22770, + 22794, 22750, 22803, 22807, 22779, 22782, 22783, 22817, 22815, 22796, + 22752, 22804, 22784, 22818, 22816, 22814, 22812, 22742, 22813, 22811, + 22829, 22746, 22823, 22747, 22781, 22749, 22800, 22797, 22780, 35762, + 35762, 35762, 35762, 22834, 22765, 22833, 22832, 22831, 22839, 22845, + 22844, 22840, 22841, 22866, 22870, 22887, 22886, 22848, 22851, 22852, + 22868, 22855, 22856, 22857, 22858, 22859, 22862, 22864, 22865, 22861, + 22872, 22873, 22874, 22875, 22880, 22876, 22877, 22881, 22883, 22842, + 22843, 22850, 22885, 22849, 22884, 22846, 22854, 22847, 22871, 22888, + 22889, 22878, 22882, 22869, 22867, 22890, 22863, 22853, 22860, 22879, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 22838, 22836, 22837, + 22835, 22787, 22788, 22789, 22790, 22791, 22792, 22793, 22773, 22774, + 22775, 22776, 22777, 22778, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 31669, 25140, + 25317, 25316, 17699, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 33692, 33691, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 30901, 30902, 30903, 30904, 30905, 30906, 30907, 30908, 30909, 30910, + 30911, 30912, 30913, 30914, 30915, 30916, 30917, 30918, 30919, 30920, + 30921, 30922, 30923, 30924, 30925, 30926, 30927, 30928, 30929, 30930, + 30931, 30932, 30933, 30934, 30935, 30936, 30937, 30938, 30939, 30940, + 30941, 30942, 30943, 30944, 30945, 30946, 30947, 30948, 30949, 30950, + 30951, 30952, 30953, 30954, 30955, 30956, 30957, 30958, 30959, 30960, + 30961, 30962, 30963, 30964, 30965, 30966, 30967, 30968, 30969, 30970, + 30971, 30972, 30973, 30974, 30975, 30976, 30977, 30978, 30979, 30980, + 30981, 30982, 30983, 30984, 30985, 30986, 30987, 30988, 30989, 30990, + 30991, 30992, 30993, 30994, 30995, 30996, 30997, 30998, 30999, 31000, + 31001, 31002, 31003, 31004, 31005, 31006, 31007, 31008, 31009, 31010, + 31011, 31012, 31013, 31014, 31015, 31016, 31017, 31018, 31019, 31020, + 31021, 31022, 31023, 31024, 31025, 31026, 31027, 31028, 31029, 31030, + 31031, 31032, 31033, 31034, 31035, 31036, 31037, 31038, 31039, 31040, + 31041, 31042, 31043, 31044, 31045, 31046, 31047, 31048, 31049, 31050, + 31051, 31052, 31053, 31054, 31055, 31056, 31057, 31058, 31059, 31060, + 31061, 31062, 31063, 31064, 31065, 31066, 31067, 31068, 31069, 31070, + 31071, 31072, 31073, 31074, 31075, 31076, 31077, 31078, 31079, 31080, + 31081, 31082, 31083, 31084, 31085, 31086, 31087, 31088, 31089, 31090, + 31091, 31092, 31093, 31094, 31095, 31096, 31097, 31098, 31099, 31100, + 31101, 31102, 31103, 31104, 31105, 31106, 31107, 31108, 31109, 31110, + 31111, 31112, 31113, 31114, 31115, 31116, 31117, 31118, 31119, 31120, + 31121, 31122, 31123, 31124, 31125, 31126, 31127, 31128, 31129, 31130, + 31131, 31132, 31133, 31134, 31135, 31136, 31137, 31138, 31139, 31140, + 31141, 31142, 31143, 31144, 31145, 31146, 31147, 31148, 31149, 31150, + 31151, 31152, 31153, 31154, 31155, 31156, 31157, 31158, 31159, 31160, + 31161, 31162, 31163, 31164, 31165, 31166, 31167, 31168, 31169, 31170, + 31171, 31172, 31173, 31174, 31175, 31176, 31177, 31178, 31179, 31180, + 31181, 31182, 31183, 31184, 31185, 31186, 31187, 31188, 31189, 31190, + 31191, 31192, 31193, 31194, 31195, 31196, 31197, 31198, 31199, 31200, + 31201, 31202, 31203, 31204, 31205, 31206, 31207, 31208, 31209, 31210, + 31211, 31212, 31213, 31214, 31215, 31216, 31217, 31218, 31219, 31220, + 31221, 31222, 31223, 31224, 31225, 31226, 31227, 31228, 31229, 31230, + 31231, 31232, 31233, 31234, 31235, 31236, 31237, 31238, 31239, 31240, + 31241, 31242, 31243, 31244, 31245, 31246, 31247, 31248, 31249, 31250, + 31251, 31252, 31253, 31254, 31255, 31256, 31257, 31258, 31259, 31260, + 31261, 31262, 31263, 31264, 31265, 31266, 31267, 31268, 31269, 31270, + 31271, 31272, 31273, 31274, 31275, 31276, 31277, 31278, 31279, 31280, + 31281, 31282, 31283, 31284, 31285, 31286, 31287, 31288, 31289, 31290, + 31291, 31292, 31293, 31294, 31295, 31296, 31297, 31298, 31299, 31300, + 31301, 31302, 31303, 31304, 31305, 31306, 31307, 31308, 31309, 31310, + 31311, 31312, 31313, 31314, 31315, 31316, 31317, 31318, 31319, 31320, + 31321, 31322, 31323, 31324, 31325, 31326, 31327, 31328, 31329, 31330, + 31331, 31332, 31333, 31334, 31335, 31336, 31337, 31338, 31339, 31340, + 31341, 31342, 31343, 31344, 31345, 31346, 31347, 31348, 31349, 31350, + 31351, 31352, 31353, 31354, 31355, 31356, 31357, 31358, 31359, 31360, + 31361, 31362, 31363, 31364, 31365, 31366, 31367, 31368, 31369, 31370, + 31371, 31372, 31373, 31374, 31375, 31376, 31377, 31378, 31379, 31380, + 31381, 31382, 31383, 31384, 31385, 31386, 31387, 31388, 31389, 31390, + 31391, 31392, 31393, 31394, 31395, 31396, 31397, 31398, 31399, 31400, + 31401, 31402, 31403, 31404, 31405, 31406, 31407, 31408, 31409, 31410, + 31411, 31412, 31413, 31414, 31415, 31416, 31417, 31418, 31419, 31420, + 31421, 31422, 31423, 31424, 31425, 31426, 31427, 31428, 31429, 31430, + 31431, 31432, 31433, 31434, 31435, 31436, 31437, 31438, 31439, 31440, + 31441, 31442, 31443, 31444, 31445, 31446, 31447, 31448, 31449, 31450, + 31451, 31452, 31453, 31454, 31455, 31456, 31457, 31458, 31459, 31460, + 31461, 31462, 31463, 31464, 31465, 31466, 31467, 31468, 31469, 31470, + 31471, 31472, 31473, 31474, 31475, 31476, 31477, 31478, 31479, 31480, + 31481, 31482, 31483, 31484, 31485, 31486, 31487, 31488, 31489, 31490, + 31491, 31492, 31493, 31494, 31495, 31496, 31497, 31498, 31499, 31500, + 31501, 31502, 31503, 31504, 31505, 31506, 31507, 31508, 31509, 31510, + 31511, 31512, 31513, 31514, 31515, 31516, 31517, 31518, 31519, 31520, + 31521, 31522, 31523, 31524, 31525, 31526, 31527, 31528, 31529, 31530, + 31531, 31532, 31533, 31534, 31535, 31536, 31537, 31538, 31539, 31540, + 31541, 31542, 31543, 31544, 31545, 31546, 31547, 31548, 31549, 31550, + 31551, 31552, 31553, 31554, 31555, 31556, 31557, 31558, 31559, 31560, + 31561, 31562, 31563, 31564, 31565, 31566, 31567, 31568, 31569, 31570, + 31571, 31572, 31573, 31574, 31575, 31576, 31577, 31578, 31579, 31580, + 31581, 31582, 31583, 31584, 31585, 31586, 31587, 31588, 31589, 31590, + 31591, 31592, 31593, 31594, 31595, 31596, 31597, 31598, 31599, 31600, + 31601, 31602, 31603, 31604, 31605, 31606, 31607, 31608, 31609, 31610, + 31611, 31612, 31613, 31614, 31615, 31616, 31617, 31618, 31619, 31620, + 31621, 31622, 31623, 31624, 31625, 31626, 31627, 31628, 31629, 31630, + 31631, 31632, 31633, 31634, 31635, 31636, 31637, 31638, 31639, 31640, + 31641, 31642, 31643, 31644, 31645, 31646, 31647, 31648, 31649, 31650, + 31651, 31652, 31653, 31654, 31655, 31656, 31657, 31658, 31659, 31660, + 31661, 31662, 31663, 31664, 31665, 31666, 31667, 31668, 17229, 17230, + 17231, 17232, 17233, 17234, 17235, 17236, 17237, 17238, 17239, 17240, + 17241, 17242, 17243, 17244, 17245, 17246, 17247, 17248, 17249, 17250, + 17251, 17252, 17253, 17254, 17255, 17256, 17257, 17258, 17259, 17260, + 17261, 17262, 17263, 17264, 17265, 17266, 17267, 17268, 17269, 17270, + 17271, 17272, 17273, 17274, 17275, 17276, 17277, 17278, 17279, 17280, + 17281, 17282, 17283, 17284, 17285, 17286, 17287, 17288, 17289, 17290, + 17291, 17292, 17293, 17294, 17295, 17296, 17297, 17298, 17299, 17300, + 17301, 17302, 17303, 17304, 17305, 17306, 17307, 17308, 17309, 17310, + 17311, 17312, 17313, 17314, 17315, 17316, 17317, 17318, 17319, 17320, + 17321, 17322, 17323, 17324, 17325, 17326, 17327, 17328, 17329, 17330, + 17331, 17332, 17333, 17334, 17335, 17336, 17337, 17338, 17339, 17340, + 17341, 17342, 17343, 17344, 17345, 17346, 17347, 17348, 17349, 17350, + 17351, 17352, 17353, 17354, 17355, 17356, 17357, 17358, 17359, 17360, + 17361, 17362, 17363, 17364, 17365, 17366, 17367, 17368, 17369, 17370, + 17371, 17372, 17373, 17374, 17375, 17376, 17377, 17378, 17379, 17380, + 17381, 17382, 17383, 17384, 17385, 17386, 17387, 17388, 17389, 17390, + 17391, 17392, 17393, 17394, 17395, 17396, 17397, 17398, 17399, 17400, + 17401, 17402, 17403, 17404, 17405, 17406, 17407, 17408, 17409, 17410, + 17411, 17412, 17413, 17414, 17415, 17416, 17417, 17418, 17419, 17420, + 17421, 17422, 17423, 17424, 17425, 17426, 17427, 17428, 17429, 17430, + 17431, 17432, 17433, 17434, 17435, 17436, 17437, 17438, 17439, 17440, + 17441, 17442, 17443, 17444, 17445, 17446, 17447, 17448, 17449, 17450, + 17451, 17452, 17453, 17454, 17455, 17456, 17457, 17458, 17459, 17460, + 17461, 17462, 17463, 17464, 17465, 17466, 17467, 17468, 17469, 17470, + 17471, 17472, 17473, 17474, 17475, 17476, 17477, 17478, 17479, 17480, + 17481, 17482, 17483, 17484, 17491, 17492, 17493, 17494, 17495, 17496, + 17497, 17498, 17499, 17500, 17501, 17502, 17503, 17504, 17505, 17506, + 17507, 17508, 17509, 17510, 17511, 17512, 17513, 17514, 17515, 17516, + 17517, 17518, 17519, 17520, 17521, 17522, 17523, 17524, 17525, 17526, + 17527, 17528, 17529, 17530, 17531, 17532, 17533, 17534, 17535, 17536, + 17537, 17538, 17539, 17540, 17541, 17542, 17543, 17544, 17545, 17546, + 17547, 17548, 17549, 17550, 17551, 17552, 17553, 17554, 17555, 17556, + 17557, 17558, 17559, 17560, 17561, 17562, 17563, 17564, 17565, 17566, + 17567, 17568, 17569, 17570, 17571, 17572, 17573, 17574, 17575, 17576, + 17577, 17578, 17579, 17580, 17581, 17582, 17583, 17584, 17585, 17586, + 17587, 17588, 17589, 17590, 17591, 17592, 17593, 17594, 17595, 17596, + 17597, 17598, 17599, 17600, 17601, 17602, 17603, 17604, 17605, 17606, + 17607, 17608, 17609, 17610, 17611, 17612, 17613, 17614, 17615, 17616, + 17617, 17618, 17619, 17620, 17621, 17622, 17623, 17624, 17625, 17626, + 17627, 17628, 17629, 17630, 17631, 17632, 17633, 17634, 17635, 17636, + 17637, 17638, 17639, 17640, 17641, 17642, 17643, 17644, 17645, 17646, + 17647, 17648, 17649, 17650, 17651, 17652, 17653, 17654, 17655, 17656, + 17657, 17658, 17659, 17660, 17661, 17662, 17663, 17664, 17665, 17666, + 17667, 17668, 17669, 17670, 17671, 17672, 17673, 17674, 17675, 17676, + 17677, 17678, 17679, 17680, 17681, 17682, 17683, 17684, 17685, 17686, + 17687, 17688, 17689, 17690, 17691, 17692, 17693, 17694, 17695, 17696, + 17697, 17698, 17485, 17486, 17487, 17488, 17489, 17490, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 16870, 16871, 16872, 16873, 35762, 16874, 16875, 16863, 16864, 16865, + 16866, 16867, 35762, 16868, 16869, 35762, 16851, 15837, 15476, 15477, + 15478, 15475, 15757, 15758, 15759, 15760, 15749, 15750, 15751, 15752, + 15753, 15744, 15745, 15746, 15747, 15748, 15754, 15755, 15756, 15515, + 15519, 15520, 15521, 15522, 15523, 15524, 15525, 15526, 15516, 15517, + 15518, 15531, 15532, 15533, 15534, 15535, 15536, 15537, 15538, 15545, + 15546, 15547, 15548, 15549, 15550, 15551, 15539, 15540, 15541, 15542, + 15543, 15544, 15528, 15529, 15530, 15527, 15640, 15641, 15642, 15643, + 15644, 15645, 15646, 15647, 15656, 15657, 15658, 15659, 15660, 15661, + 15648, 15649, 15650, 15651, 15652, 15653, 15654, 15655, 15662, 15663, + 15664, 15665, 15666, 15667, 15668, 15669, 15670, 15671, 15672, 15673, + 15702, 15703, 15704, 15705, 15695, 15696, 15697, 15698, 15699, 15700, + 15701, 15691, 15692, 15693, 15694, 15690, 15674, 15675, 15676, 15677, + 15678, 15679, 15680, 15681, 15682, 15684, 15685, 15686, 15687, 15688, + 15689, 15683, 15594, 15595, 15596, 15597, 15598, 15599, 15600, 15601, + 15602, 15587, 15588, 15589, 15590, 15591, 15592, 15593, 15586, 15608, + 15609, 15610, 15580, 15581, 15582, 15583, 15584, 15585, 15579, 15603, + 15604, 15605, 15606, 15607, 15487, 15490, 15491, 15492, 15493, 15494, + 15495, 15496, 15497, 15488, 15489, 15508, 15509, 15510, 15511, 15512, + 15513, 15514, 15498, 15499, 15500, 15501, 15502, 15503, 15504, 15505, + 15506, 15507, 15479, 15480, 15481, 15482, 15483, 15484, 15485, 15486, + 15561, 15562, 15563, 15564, 15565, 15566, 15567, 15568, 15569, 15570, + 15571, 15572, 15573, 15574, 15575, 15576, 15577, 15578, 15553, 15554, + 15552, 15555, 15556, 15557, 15558, 15559, 15560, 15728, 15729, 15730, + 15731, 15732, 15727, 15739, 15740, 15741, 15742, 15733, 15734, 15735, + 15736, 15737, 15738, 15632, 15633, 15634, 15635, 15625, 15626, 15627, + 15628, 15629, 15630, 15631, 15619, 15620, 15621, 15622, 15623, 15624, + 15636, 15637, 15638, 15639, 15613, 15614, 15615, 15616, 15617, 15618, + 15706, 15707, 15708, 15709, 15710, 15711, 15712, 15713, 15714, 15715, + 15723, 15724, 15725, 15726, 15716, 15717, 15718, 15719, 15720, 15721, + 15722, 15611, 15612, 15836, 16849, 16848, 16850, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 15847, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 15840, 15839, 15841, 35762, 35762, 16898, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 16904, 16903, 16905, 16909, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 24744, 24745, 24746, 24747, 24748, 24749, + 24750, 24751, 24752, 24753, 24754, 24755, 24756, 24757, 24758, 24759, + 24760, 24761, 24762, 24763, 24764, 24765, 24766, 24767, 24768, 24769, + 24770, 24771, 24772, 24773, 24774, 24775, 24776, 24777, 24778, 24779, + 24780, 24781, 24782, 24783, 24784, 24785, 24786, 24787, 24788, 24789, + 24790, 24791, 24792, 24793, 24794, 24795, 24796, 24797, 24798, 24799, + 24800, 24801, 24802, 24803, 24804, 24805, 24806, 24807, 24808, 24809, + 24810, 24811, 24812, 24813, 24814, 24815, 24816, 24817, 24818, 24819, + 24820, 24821, 24822, 24823, 24824, 24825, 24826, 24827, 24828, 24829, + 24830, 24831, 24832, 24833, 24834, 24835, 24836, 24837, 24838, 24839, + 24840, 24841, 24842, 24843, 24844, 24845, 24846, 24847, 24848, 24849, + 24850, 24851, 24852, 24853, 24854, 24855, 24856, 24857, 24858, 24859, + 24860, 24861, 24862, 24863, 24864, 24865, 24866, 24867, 24868, 24869, + 24870, 24871, 24872, 24873, 24874, 24875, 24876, 24877, 24878, 24879, + 24880, 24881, 24882, 24883, 24884, 24885, 24886, 24887, 24888, 24889, + 24890, 24891, 24892, 24893, 24894, 24895, 24896, 24897, 24898, 24899, + 24900, 24901, 24902, 24903, 24904, 24905, 24906, 24907, 24908, 24909, + 24910, 24911, 24912, 24913, 24914, 24915, 24916, 24917, 24918, 24919, + 24920, 24921, 24922, 24923, 24924, 24925, 24926, 24927, 24928, 24929, + 24930, 24931, 24932, 24933, 24934, 24935, 24936, 24937, 24938, 24939, + 24940, 24941, 24942, 24943, 24944, 24945, 24946, 24947, 24948, 24949, + 24950, 24951, 24952, 24953, 24954, 24955, 24956, 24957, 24958, 24959, + 24960, 24961, 24962, 24963, 24964, 24965, 24966, 24967, 24968, 24969, + 24970, 24971, 24972, 24973, 24974, 24975, 24976, 24977, 24978, 24979, + 24980, 24981, 24982, 24983, 24984, 24985, 24986, 24987, 24988, 24989, + 24990, 24991, 24992, 24993, 24994, 24995, 24996, 24997, 24998, 24999, + 25000, 25001, 25002, 25003, 25004, 25005, 25006, 25007, 25008, 25009, + 25010, 25011, 25012, 25013, 25014, 25015, 25016, 25017, 25018, 25019, + 25020, 25021, 25022, 25023, 25024, 25025, 25026, 25027, 25028, 25029, + 25030, 25031, 25032, 25033, 25034, 25035, 25036, 25037, 25038, 25039, + 25040, 25041, 25042, 25043, 25044, 25045, 25046, 25047, 25048, 25049, + 25050, 25051, 25052, 25053, 25054, 25055, 25056, 25057, 25058, 25059, + 25060, 25061, 25062, 25063, 25064, 25065, 25066, 25067, 25068, 25069, + 25070, 25071, 25072, 25073, 25074, 25075, 25076, 25077, 25078, 25079, + 25080, 25081, 25082, 25083, 25084, 25085, 25086, 25087, 25088, 25089, + 25090, 25091, 25092, 25093, 25094, 25095, 25096, 25097, 25098, 25099, + 25100, 25101, 25102, 25103, 25104, 25105, 25106, 25107, 25108, 25109, + 25110, 25111, 25112, 25113, 25114, 25115, 25116, 25117, 25118, 25119, + 25120, 25121, 25122, 25123, 25124, 25125, 25126, 25127, 25128, 25129, + 25130, 25131, 25132, 25133, 25134, 25135, 25136, 25137, 25138, 25139, + 35762, 35762, 35762, 35762, 11196, 11194, 11143, 11176, 11103, 11116, + 11120, 11201, 11097, 11184, 11105, 11147, 11146, 11098, 11104, 11118, + 11150, 11179, 11172, 11099, 11119, 11173, 11197, 11123, 11151, 11124, + 11129, 11107, 11152, 11125, 11130, 11110, 11153, 11127, 11132, 11108, + 11109, 11161, 11162, 11128, 11133, 11114, 11165, 11126, 11131, 11111, + 11154, 11115, 11112, 11113, 11159, 11160, 11157, 11158, 11178, 11177, + 11186, 11192, 11189, 11164, 11163, 11117, 11106, 11155, 11156, 11095, + 11170, 11140, 11138, 11096, 11198, 11100, 11199, 11175, 11183, 11101, + 11167, 11148, 11166, 11121, 11200, 11180, 11102, 11195, 11181, 11122, + 11149, 11182, 11174, 11139, 11142, 11141, 11191, 11187, 11193, 11190, + 11188, 11137, 11136, 11135, 11134, 11145, 11144, 11168, 11171, 11169, + 11185, 35762, 35762, 35762, 35762, 35762, 11080, 11093, 11092, 11087, + 11094, 11074, 11067, 11066, 11063, 11065, 11068, 11069, 11064, 35762, + 35762, 35762, 11076, 11072, 11075, 11070, 11079, 11078, 11071, 11077, + 11073, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 11081, 11085, + 11088, 11083, 11091, 11090, 11084, 11089, 11086, 11082, 35762, 35762, + 11205, 11202, 11203, 11204, 27932, 27931, 27933, 27934, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35578, 35583, 35617, 35580, 35585, 35613, 35607, 35601, 35624, 35603, + 35597, 35621, 35579, 35584, 35618, 35581, 35586, 35614, 35608, 35602, + 35625, 35604, 35598, 35622, 35619, 35605, 35612, 35599, 35600, 35623, + 35606, 35582, 35628, 35593, 35610, 35620, 35631, 35630, 35596, 35629, + 35590, 35589, 35627, 35611, 35609, 35588, 35762, 35762, 35633, 35634, + 35635, 35626, 35576, 35591, 35594, 35595, 35573, 35574, 35592, 35615, + 35616, 35577, 35632, 35575, 35587, 35572, 35754, 35755, 35752, 35753, + 35756, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35652, 35653, 35669, 35641, 35650, 35749, 35704, 35705, 35672, 35673, + 35706, 35636, 35670, 35750, 35648, 35645, 35647, 35646, 35644, 35746, + 35745, 35748, 35747, 35742, 35741, 35744, 35743, 35642, 35676, 35638, + 35649, 35637, 35674, 35687, 35688, 35686, 35685, 35639, 35683, 35684, + 35682, 35680, 35681, 35679, 35678, 35689, 35691, 35692, 35690, 35654, + 35677, 35643, 35651, 35751, 35693, 35698, 35695, 35699, 35696, 35701, + 35702, 35697, 35694, 35700, 35675, 35703, 35736, 35733, 35724, 35734, + 35735, 35725, 35713, 35712, 35740, 35710, 35709, 35707, 35711, 35708, + 35727, 35732, 35726, 35730, 35731, 35728, 35729, 35656, 35660, 35659, + 35658, 35657, 35739, 35737, 35738, 35663, 35668, 35667, 35666, 35665, + 35664, 35714, 35723, 35716, 35721, 35715, 35719, 35720, 35717, 35718, + 35722, 35655, 35662, 35640, 35661, 35671, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 4893, 4765, 4886, 4868, 4869, + 4937, 4938, 4818, 4915, 4875, 4949, 4950, 4841, 4720, 4771, 4918, 4819, + 4723, 4724, 4913, 4925, 4864, 4801, 4892, 4744, 4941, 4813, 4827, 4823, + 4916, 4878, 4907, 4871, 4940, 4726, 4728, 4828, 4894, 4879, 4936, 4718, + 4896, 4910, 4912, 4866, 4920, 4848, 4766, 4928, 4919, 4838, 4719, 4778, + 4809, 4930, 4816, 4884, 4888, 4831, 4742, 4895, 4873, 4876, 4815, 4953, + 4883, 4832, 4931, 4908, 4807, 4814, 4865, 4870, 4882, 4834, 4881, 4839, + 4885, 4822, 4826, 4952, 4725, 4721, 4951, 4840, 4774, 4745, 4863, 4939, + 4880, 4889, 4872, 4717, 4849, 4877, 4874, 4770, 4842, 4716, 4932, 4773, + 4911, 4914, 4743, 4772, 4897, 4954, 4934, 4890, 4929, 4933, 4887, 4935, + 4891, 4804, 4730, 4769, 4867, 4922, 4923, 4921, 4924, 4817, 4767, 4942, + 4943, 4906, 4830, 4763, 4835, 4836, 4837, 4727, 4729, 4762, 4927, 4917, + 4833, 4843, 4847, 4846, 4845, 4844, 4803, 4800, 4799, 4757, 4759, 4760, + 4758, 4926, 4731, 4811, 4750, 4714, 4708, 4709, 4712, 4713, 4711, 4710, + 4715, 4856, 4851, 4852, 4850, 4861, 4860, 4859, 4858, 4862, 4854, 4812, + 4722, 4777, 4776, 4775, 4857, 4855, 4853, 4805, 4806, 4768, 4810, 4808, + 4779, 4786, 4782, 4790, 4785, 4794, 4784, 4783, 4780, 4781, 4788, 4789, + 4796, 4793, 4791, 4740, 4741, 4739, 4787, 4795, 4948, 4753, 4751, 4754, + 4756, 4755, 4752, 4944, 4946, 4945, 4947, 4797, 4798, 4747, 4746, 4748, + 4749, 4902, 4905, 4903, 4904, 4898, 4901, 4899, 4900, 4761, 4764, 4909, + 4738, 4732, 4737, 4735, 4734, 4733, 4736, 4820, 4824, 4821, 4825, 4829, + 4802, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 23803, 23680, 23696, 23788, 23675, 23800, 23738, 23789, 23787, + 23676, 23672, 23799, 23666, 23784, 23785, 23786, 23691, 23692, 23629, + 23630, 23625, 23624, 23755, 23826, 23823, 23698, 23697, 23804, 23805, + 23699, 23708, 23709, 23710, 23669, 23701, 23702, 23703, 23682, 23683, + 35762, 35762, 23746, 23679, 23681, 23707, 23706, 23751, 23750, 23802, + 23801, 23778, 23779, 23665, 23671, 23767, 23768, 23782, 23783, 23747, + 23849, 23721, 23781, 23690, 23807, 23825, 23809, 23754, 23847, 23770, + 23670, 23810, 23811, 23834, 23835, 23838, 23839, 23836, 23837, 23830, + 23831, 23832, 23833, 23744, 23745, 23840, 23841, 23769, 23845, 23752, + 23749, 23633, 23634, 23628, 23848, 23720, 23780, 23689, 23806, 23824, + 23808, 23753, 23654, 23655, 23658, 23659, 23660, 23693, 23694, 23695, + 23637, 23644, 23645, 23646, 23647, 23648, 23622, 23687, 23623, 23688, + 23621, 23685, 23620, 23684, 23635, 23653, 23661, 23652, 23638, 23639, + 23636, 23663, 23718, 23717, 23642, 23664, 23649, 23656, 23662, 23641, + 23657, 23790, 23813, 23852, 23777, 23740, 23700, 23668, 23677, 23714, + 23713, 23829, 23842, 23851, 23843, 23844, 23756, 23759, 23760, 23761, + 23762, 23763, 23764, 23765, 23766, 23757, 23758, 23722, 23748, 23686, + 23678, 23640, 23643, 23650, 23651, 23772, 23771, 23719, 23712, 23711, + 23850, 23673, 23674, 23739, 23735, 23626, 23793, 23795, 23741, 23743, + 23796, 23798, 23704, 23705, 23737, 23736, 23627, 23794, 23742, 23797, + 23821, 23820, 23822, 23819, 23815, 23816, 23817, 23818, 23667, 23715, + 23716, 23812, 23846, 23774, 23632, 23791, 23631, 23827, 23775, 23776, + 23792, 23828, 23773, 23723, 23726, 23730, 23733, 23732, 23731, 23727, + 23728, 23724, 23725, 23729, 23814, 23734, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 14240, 14228, 14251, + 14252, 14234, 14253, 14254, 14255, 14256, 14241, 14242, 14243, 14244, + 14245, 14246, 14247, 14248, 14249, 14250, 14229, 14230, 14231, 14232, + 14233, 14235, 14236, 14237, 14238, 14239, 13960, 13968, 13981, 13989, + 13995, 13996, 13961, 13962, 13963, 13964, 13965, 13966, 13967, 13969, + 13970, 13971, 13972, 13973, 13974, 13975, 13976, 13977, 13978, 13979, + 13980, 13982, 13983, 13984, 13985, 13986, 13987, 13988, 13990, 13991, + 13992, 13993, 13994, 7968, 7967, 7969, 14020, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 17140, 17141, + 17138, 17136, 17127, 17126, 17133, 17131, 17122, 17129, 17139, 17124, + 17137, 17135, 17128, 17125, 17134, 17132, 17123, 17130, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 22166, 22167, 22164, 22162, 22153, 22152, 22159, 22157, 22148, 22155, + 22165, 22150, 22163, 22161, 22154, 22151, 22160, 22158, 22149, 22156, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 23494, 10576, 10577, 10571, 10570, 10569, 31810, 31830, + 31851, 31799, 31844, 31808, 31794, 31853, 31798, 31812, 31818, 31841, + 31842, 31856, 31862, 31809, 31840, 31870, 31828, 31795, 31858, 31860, + 31827, 31873, 31807, 31822, 31819, 31800, 31814, 31797, 31855, 31848, + 31802, 31845, 31834, 31868, 31857, 31831, 31859, 31847, 31861, 31836, + 31824, 31867, 31837, 31823, 31854, 31863, 31833, 31869, 31806, 31850, + 31826, 31872, 31816, 31801, 31838, 31835, 31849, 31793, 31821, 31820, + 31871, 31865, 31843, 31813, 31811, 31817, 31825, 31864, 31866, 31839, + 31805, 31803, 31832, 31796, 31804, 31852, 31815, 31846, 31829, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 8366, 8364, 8363, + 8360, 8359, 8362, 8361, 8367, 8365, 8357, 8355, 8354, 8351, 8350, 8353, + 8352, 8358, 8356, 16051, 16050, 16049, 16048, 16047, 30395, 30394, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 21146, 21148, 21176, 21139, 21152, 21184, + 21155, 21185, 21157, 21186, 21159, 21161, 21178, 21180, 21163, 21166, + 21187, 21170, 21172, 21142, 21174, 21188, 21189, 21182, 21190, 21150, + 21194, 21196, 21229, 21191, 21200, 21203, 21205, 21237, 21207, 21238, + 21209, 21211, 21231, 21233, 21213, 21216, 21239, 21220, 21222, 21224, + 21227, 21240, 21241, 21235, 21242, 21198, 21634, 21636, 21666, 21640, + 21642, 21674, 21645, 21675, 21647, 21676, 21649, 21651, 21668, 21670, + 21653, 21656, 21677, 21660, 21662, 21630, 21664, 21678, 21679, 21672, + 21680, 21638, 21582, 21584, 21617, 21578, 21588, 21591, 21593, 35762, + 21595, 21625, 21597, 21599, 21619, 21621, 21601, 21604, 21626, 21608, + 21610, 21612, 21615, 21627, 21628, 21623, 21629, 21586, 21299, 21301, + 21331, 21305, 21307, 21339, 21310, 21340, 21312, 21341, 21314, 21316, + 21333, 21335, 21318, 21321, 21342, 21325, 21327, 21295, 21329, 21343, + 21344, 21337, 21345, 21303, 21353, 21355, 21390, 21359, 21361, 21364, + 21366, 21398, 21368, 21399, 21370, 21372, 21392, 21394, 21374, 21377, + 21400, 21381, 21383, 21385, 21388, 21401, 21402, 21396, 21403, 21357, + 22106, 35762, 22107, 22108, 35762, 35762, 22109, 35762, 35762, 22110, + 22111, 35762, 35762, 22112, 22113, 22114, 22115, 35762, 22116, 22117, + 22118, 22119, 22120, 22121, 22122, 22123, 22124, 22125, 22126, 22127, + 35762, 22128, 35762, 22129, 22130, 22131, 22132, 22133, 22134, 22135, + 35762, 22136, 22137, 22138, 22139, 22140, 22141, 22142, 22143, 22144, + 22145, 22146, 21243, 21244, 21245, 21246, 21247, 21248, 21249, 21250, + 21251, 21252, 21253, 21254, 21255, 21256, 21257, 21258, 21259, 21260, + 21261, 21262, 21263, 21264, 21265, 21266, 21267, 21268, 21269, 21270, + 21271, 21272, 21273, 21274, 21275, 21276, 21277, 21278, 21279, 21280, + 21281, 21282, 21283, 21284, 21285, 21286, 21287, 21288, 21289, 21290, + 21291, 21292, 21293, 21294, 21530, 21531, 35762, 21532, 21533, 21534, + 21535, 35762, 35762, 21536, 21537, 21538, 21539, 21540, 21541, 21542, + 21543, 35762, 21544, 21545, 21546, 21547, 21548, 21549, 21550, 35762, + 21551, 21552, 21553, 21554, 21555, 21556, 21557, 21558, 21559, 21560, + 21561, 21562, 21563, 21564, 21565, 21566, 21567, 21568, 21569, 21570, + 21571, 21572, 21573, 21574, 21575, 21576, 21475, 21476, 35762, 21477, + 21478, 21479, 21480, 35762, 21481, 21482, 21483, 21484, 21485, 35762, + 21486, 35762, 35762, 35762, 21487, 21488, 21489, 21490, 21491, 21492, + 21493, 35762, 21494, 21495, 21496, 21497, 21498, 21499, 21500, 21501, + 21502, 21503, 21504, 21505, 21506, 21507, 21508, 21509, 21510, 21511, + 21512, 21513, 21514, 21515, 21516, 21517, 21518, 21519, 21413, 21414, + 21415, 21416, 21417, 21418, 21419, 21420, 21421, 21422, 21423, 21424, + 21425, 21426, 21427, 21428, 21429, 21430, 21431, 21432, 21433, 21434, + 21435, 21436, 21437, 21438, 21439, 21440, 21441, 21442, 21443, 21444, + 21445, 21446, 21447, 21448, 21449, 21450, 21451, 21452, 21453, 21454, + 21455, 21456, 21457, 21458, 21459, 21460, 21461, 21462, 21463, 21464, + 22044, 22045, 22046, 22047, 22048, 22049, 22050, 22051, 22052, 22053, + 22054, 22055, 22056, 22057, 22058, 22059, 22060, 22061, 22062, 22063, + 22064, 22065, 22066, 22067, 22068, 22069, 22070, 22071, 22072, 22073, + 22074, 22075, 22076, 22077, 22078, 22079, 22080, 22081, 22082, 22083, + 22084, 22085, 22086, 22087, 22088, 22089, 22090, 22091, 22092, 22093, + 22094, 22095, 21876, 21878, 21908, 21882, 21884, 21916, 21887, 21917, + 21889, 21918, 21891, 21893, 21910, 21912, 21895, 21898, 21919, 21902, + 21904, 21872, 21906, 21920, 21921, 21914, 21922, 21880, 21930, 21932, + 21967, 21936, 21938, 21941, 21943, 21975, 21945, 21976, 21947, 21949, + 21969, 21971, 21951, 21954, 21977, 21958, 21960, 21962, 21965, 21978, + 21979, 21973, 21980, 21934, 21992, 21993, 21994, 21995, 21996, 21997, + 21998, 21999, 22000, 22001, 22002, 22003, 22004, 22005, 22006, 22007, + 22008, 22009, 22010, 22011, 22012, 22013, 22014, 22015, 22016, 22017, + 22018, 22019, 22020, 22021, 22022, 22023, 22024, 22025, 22026, 22027, + 22028, 22029, 22030, 22031, 22032, 22033, 22034, 22035, 22036, 22037, + 22038, 22039, 22040, 22041, 22042, 22043, 21766, 21768, 21798, 21772, + 21774, 21806, 21777, 21807, 21779, 21808, 21781, 21783, 21800, 21802, + 21785, 21788, 21809, 21792, 21794, 21762, 21796, 21810, 21811, 21804, + 21812, 21770, 21820, 21822, 21857, 21826, 21828, 21831, 21833, 21865, + 21835, 21866, 21837, 21839, 21859, 21861, 21841, 21844, 21867, 21848, + 21850, 21852, 21855, 21868, 21869, 21863, 21870, 21824, 21689, 21690, + 21691, 21692, 21693, 21694, 21695, 21696, 21697, 21698, 21699, 21700, + 21701, 21702, 21703, 21704, 21705, 21706, 21707, 21708, 21709, 21710, + 21711, 21712, 21713, 21714, 21715, 21716, 21717, 21718, 21719, 21720, + 21721, 21722, 21723, 21724, 21725, 21726, 21727, 21728, 21729, 21730, + 21731, 21732, 21733, 21734, 21735, 21736, 21737, 21738, 21739, 21740, + 21579, 21580, 35762, 35762, 21147, 21149, 21156, 21141, 21153, 21151, + 21154, 21143, 21158, 21160, 21162, 21179, 21181, 21183, 21164, 21169, + 21171, 21144, 21173, 21145, 21175, 21167, 21177, 21168, 21165, 21407, + 21195, 21197, 21206, 21193, 21201, 21199, 21202, 21225, 21208, 21210, + 21212, 21232, 21234, 21236, 21214, 21219, 21221, 21204, 21223, 21226, + 21228, 21217, 21230, 21218, 21215, 21409, 21405, 21412, 21406, 21408, + 21411, 21410, 21635, 21637, 21646, 21641, 21643, 21639, 21644, 21631, + 21648, 21650, 21652, 21669, 21671, 21673, 21654, 21659, 21661, 21632, + 21663, 21633, 21665, 21657, 21667, 21658, 21655, 21683, 21583, 21585, + 21594, 21581, 21589, 21587, 21590, 21613, 21596, 21598, 21600, 21620, + 21622, 21624, 21602, 21607, 21609, 21592, 21611, 21614, 21616, 21605, + 21618, 21606, 21603, 21685, 21681, 21688, 21682, 21684, 21687, 21686, + 21300, 21302, 21311, 21306, 21308, 21304, 21309, 21296, 21313, 21315, + 21317, 21334, 21336, 21338, 21319, 21324, 21326, 21297, 21328, 21298, + 21330, 21322, 21332, 21323, 21320, 21348, 21354, 21356, 21367, 21360, + 21362, 21358, 21363, 21386, 21369, 21371, 21373, 21393, 21395, 21397, + 21375, 21380, 21382, 21365, 21384, 21387, 21389, 21378, 21391, 21379, + 21376, 21350, 21346, 21404, 21347, 21349, 21352, 21351, 21877, 21879, + 21888, 21883, 21885, 21881, 21886, 21873, 21890, 21892, 21894, 21911, + 21913, 21915, 21896, 21901, 21903, 21874, 21905, 21875, 21907, 21899, + 21909, 21900, 21897, 21925, 21931, 21933, 21944, 21937, 21939, 21935, + 21940, 21963, 21946, 21948, 21950, 21970, 21972, 21974, 21952, 21957, + 21959, 21942, 21961, 21964, 21966, 21955, 21968, 21956, 21953, 21927, + 21923, 21981, 21924, 21926, 21929, 21928, 21767, 21769, 21778, 21773, + 21775, 21771, 21776, 21763, 21780, 21782, 21784, 21801, 21803, 21805, + 21786, 21791, 21793, 21764, 21795, 21765, 21797, 21789, 21799, 21790, + 21787, 21815, 21821, 21823, 21834, 21827, 21829, 21825, 21830, 21853, + 21836, 21838, 21840, 21860, 21862, 21864, 21842, 21847, 21849, 21832, + 21851, 21854, 21856, 21845, 21858, 21846, 21843, 21817, 21813, 21871, + 21814, 21816, 21819, 21818, 21140, 21192, 35762, 35762, 21471, 21473, + 21470, 21469, 21466, 21465, 21468, 21467, 21474, 21472, 21526, 21528, + 21525, 21524, 21521, 21520, 21523, 21522, 21529, 21527, 22102, 22104, + 22101, 22100, 22097, 22096, 22099, 22098, 22105, 22103, 21988, 21990, + 21987, 21986, 21983, 21982, 21985, 21984, 21991, 21989, 21747, 21749, + 21746, 21745, 21742, 21741, 21744, 21743, 21750, 21748, 28184, 28140, + 28165, 28381, 28336, 28122, 28185, 28149, 28298, 28250, 28226, 28187, + 28190, 28147, 28191, 28141, 28192, 28214, 28209, 28247, 28188, 28194, + 28203, 28204, 28195, 28201, 28205, 28143, 28277, 28186, 28215, 28144, + 28224, 28193, 28223, 28210, 28249, 28248, 28189, 28208, 28218, 28219, + 28222, 28221, 28289, 28197, 28198, 28199, 28271, 28239, 28202, 28206, + 28200, 28196, 28270, 28231, 28269, 28268, 28228, 28227, 28230, 28220, + 28217, 28216, 28266, 28265, 28267, 28238, 28314, 28318, 28317, 28315, + 28316, 28159, 28305, 28335, 28307, 28320, 28312, 28321, 28313, 28322, + 28311, 28169, 28170, 28334, 28380, 28308, 28309, 28310, 28306, 28332, + 28319, 28330, 28323, 28331, 28329, 28327, 28324, 28325, 28326, 28328, + 28156, 28162, 28160, 28161, 28365, 28364, 28172, 28164, 28175, 28178, + 28173, 28176, 28174, 28177, 28182, 28179, 28139, 28374, 28379, 28376, + 28378, 28353, 28355, 28333, 28363, 28356, 28360, 28354, 28362, 28361, + 28359, 28121, 28211, 28146, 28338, 28124, 28347, 28213, 28212, 28339, + 28252, 28255, 28254, 28253, 28262, 28302, 28151, 28375, 28133, 28258, + 28261, 28256, 28257, 28350, 28260, 28349, 28132, 28131, 28259, 28150, + 28348, 28130, 28225, 28145, 28340, 28357, 28123, 28207, 28142, 28278, + 28358, 28134, 28286, 28282, 28284, 28155, 28377, 28135, 28279, 28281, + 28280, 28285, 28283, 28373, 28251, 28148, 28180, 28367, 28368, 28366, + 28168, 28346, 28126, 28125, 28275, 28351, 28273, 28154, 28263, 28274, + 28372, 28272, 28276, 28264, 28152, 28181, 28171, 28352, 28137, 28138, + 28136, 28153, 28157, 28158, 28370, 28371, 28369, 28337, 28240, 28342, + 28243, 28244, 28245, 28242, 28246, 28241, 28235, 28236, 28237, 28234, + 28232, 28163, 28233, 28229, 28166, 28167, 28344, 28345, 28341, 28343, + 28128, 28129, 28127, 28287, 28292, 28295, 28296, 28297, 28303, 28288, + 28290, 28291, 28299, 28294, 28300, 28301, 28293, 28183, 28304, 28695, + 28694, 28693, 28715, 28714, 28713, 28670, 28669, 28668, 28054, 28053, + 28052, 28656, 28655, 28654, 28666, 28667, 28662, 28665, 28661, 28664, + 28663, 28111, 28114, 28110, 28113, 28112, 28660, 28530, 28531, 28532, + 28533, 28528, 28529, 28534, 28574, 28479, 28592, 28591, 28589, 28590, + 28593, 28568, 28571, 28569, 28570, 28567, 28598, 28597, 28595, 28596, + 28544, 28543, 28542, 28548, 28547, 28546, 28545, 28566, 28565, 28564, + 28541, 28540, 28539, 28614, 28613, 28612, 28588, 28587, 28586, 28711, + 28710, 28709, 28708, 28707, 28706, 28712, 28705, 28704, 28703, 28448, + 28447, 28445, 28446, 28452, 28451, 28449, 28450, 28440, 28439, 28437, + 28438, 28444, 28443, 28441, 28442, 28502, 28501, 28499, 28500, 28503, + 28517, 28520, 28518, 28519, 28476, 28507, 28506, 28505, 28504, 28462, + 28475, 28474, 28473, 28463, 28461, 28460, 28459, 28526, 28525, 28524, + 28523, 28522, 28521, 28698, 28697, 28696, 28701, 28700, 28699, 28702, + 28561, 28560, 28558, 28559, 28552, 28551, 28549, 28550, 28557, 28556, + 28579, 28578, 28575, 28580, 28585, 28582, 28581, 28601, 28600, 28599, + 28604, 28603, 28602, 28555, 28563, 28562, 28651, 28648, 28647, 28594, + 28554, 28577, 28584, 28609, 28653, 28650, 28646, 28553, 28576, 28583, + 28608, 28652, 28649, 28645, 28607, 28606, 28605, 28466, 28465, 28483, + 28481, 28482, 28480, 28492, 28490, 28491, 28489, 28509, 28508, 28640, + 28637, 28643, 28468, 28467, 28484, 28485, 28487, 28486, 28496, 28494, + 28495, 28493, 28511, 28510, 28641, 28638, 28644, 28472, 28471, 28469, + 28470, 28464, 28488, 28497, 28512, 28513, 28514, 28639, 28636, 28642, + 28498, 28538, 28536, 28537, 28535, 28458, 28456, 28454, 28457, 28455, + 28453, 28611, 28610, 28516, 28515, 28573, 28572, 28478, 28477, 28070, + 28069, 28065, 28068, 28072, 28071, 28066, 28067, 28064, 28073, 28383, + 28390, 28388, 28387, 28385, 28386, 28384, 28389, 28103, 28101, 28102, + 28079, 28078, 28077, 28062, 28060, 28061, 28063, 28118, 28117, 28116, + 28097, 28098, 28094, 28075, 28074, 28093, 28095, 28092, 28096, 28076, + 28091, 28089, 28090, 28086, 28088, 28087, 28080, 28082, 28081, 28084, + 28083, 28085, 28057, 28056, 28055, 28680, 28679, 28681, 28100, 28617, + 28616, 28619, 28618, 28047, 28049, 28046, 28048, 28051, 28050, 28412, + 28410, 28411, 28417, 28419, 28418, 28414, 28416, 28415, 28431, 28430, + 28429, 28423, 28424, 28425, 28426, 28427, 28428, 28420, 28422, 28421, + 28432, 28433, 28434, 28401, 28399, 28400, 28413, 28436, 28435, 28688, + 28687, 28685, 28686, 28684, 28689, 28683, 28682, 28672, 28677, 28675, + 28676, 28673, 28674, 28678, 28615, 28527, 28620, 28382, 28099, 28658, + 28657, 28120, 28115, 28659, 28691, 28690, 28692, 28716, 28391, 28392, + 28393, 28394, 28395, 28396, 28397, 28398, 28109, 28409, 28408, 28403, + 28406, 28405, 28402, 28404, 28407, 28059, 28119, 28671, 28058, 28717, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 28104, 28105, 28106, 28107, 28108, + 35762, 28628, 28629, 28630, 28631, 28632, 28633, 28634, 28635, 28621, + 28622, 28623, 28624, 28625, 28626, 28627, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 18911, 19184, 18676, 19189, + 18663, 19034, 19294, 19186, 19280, 19249, 18656, 18890, 18891, 19284, + 18651, 18703, 18677, 19028, 18827, 19008, 18888, 19278, 19165, 19253, + 18899, 18828, 18972, 19124, 19254, 18794, 19201, 35762, 35762, 35762, + 35762, 35762, 35762, 18818, 19021, 19066, 19170, 19208, 19244, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 7924, 7926, 7936, 7930, 7912, 7937, 7944, 35762, 7943, + 7917, 7914, 7913, 7911, 7948, 7932, 7931, 7933, 7947, 7934, 7935, 7919, + 7922, 7946, 7928, 7945, 35762, 35762, 7920, 7923, 7927, 7921, 7939, 7938, + 7940, 35762, 7942, 7918, 35762, 7941, 7916, 7925, 7915, 7929, 35762, + 35762, 35762, 35762, 35762, 23081, 23050, 23078, 23076, 23052, 23074, + 23071, 23072, 23073, 23080, 23057, 23058, 23082, 23061, 23059, 23054, + 23067, 23083, 23056, 23079, 23066, 23075, 23065, 23068, 23053, 23070, + 23051, 23064, 23048, 23077, 23049, 23062, 23060, 10214, 10192, 10212, + 10199, 10195, 10209, 10206, 10207, 10208, 10213, 10197, 10215, 10211, + 10198, 10216, 10196, 10201, 10205, 10210, 10204, 10202, 10203, 10200, + 10191, 10194, 10193, 23055, 23069, 23063, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 7841, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 25172, 25156, 25147, 25158, 25165, 25155, 25160, 25151, + 25177, 25181, 25183, 25186, 25150, 25145, 25180, 25170, 25154, 25153, + 25184, 25146, 25157, 25178, 25164, 25182, 25185, 25152, 25174, 25159, + 25149, 25169, 25148, 25166, 25171, 25173, 25179, 25163, 25161, 25162, + 25187, 25188, 25167, 25168, 25175, 25176, 25189, 35762, 35762, 35762, + 25198, 25202, 25201, 25204, 25203, 25200, 25199, 25194, 25192, 25191, + 25195, 25193, 25196, 25197, 35762, 35762, 25211, 25213, 25210, 25209, + 25206, 25205, 25208, 25207, 25214, 25212, 35762, 35762, 35762, 35762, + 25190, 25144, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 32479, 32462, 32482, 32472, 32476, 32473, 32478, 32466, + 32465, 32481, 32469, 32484, 32483, 32475, 32474, 32480, 32477, 32463, + 32457, 32464, 32458, 32486, 32467, 32459, 32468, 32460, 32485, 32471, + 32461, 32470, 32487, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 33793, 33792, 33824, 33825, 33826, 33828, 33817, 33820, 33806, 33809, + 33821, 33813, 33810, 33827, 33823, 33822, 33830, 33835, 33834, 33833, + 33819, 33798, 33797, 33832, 33831, 33818, 33829, 33801, 33803, 33807, + 33814, 33805, 33812, 33811, 33800, 33795, 33796, 33804, 33799, 33802, + 33794, 33808, 33815, 33816, 33839, 33840, 33837, 33838, 33847, 33849, + 33846, 33845, 33842, 33841, 33844, 33843, 33850, 33848, 35762, 35762, + 35762, 35762, 35762, 33836, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 24159, 24162, 24161, 24163, 24160, 24142, 24146, 24144, + 24143, 24145, 24154, 24157, 24155, 24158, 24156, 24164, 24165, 24166, + 24167, 24168, 24147, 24149, 24152, 24153, 24148, 24151, 24150, 24172, + 24169, 24173, 24171, 24170, 24180, 24182, 24179, 24178, 24175, 24174, + 24177, 24176, 24183, 24181, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 12689, 12695, 12693, 12690, 12692, 12691, + 12694, 35762, 12644, 12688, 12686, 12685, 35762, 12632, 12631, 35762, + 12643, 12642, 12641, 12628, 12627, 12640, 12639, 12638, 12637, 12636, + 12635, 12630, 12629, 12634, 12633, 35762, 22398, 22399, 22400, 22466, + 22487, 22475, 22440, 22573, 22401, 22402, 22406, 22525, 22510, 22515, + 22439, 22591, 22542, 22461, 22445, 22536, 22405, 22403, 22404, 22451, + 22495, 22548, 22586, 22411, 22407, 22415, 22552, 22490, 22501, 22528, + 22416, 22413, 22412, 22565, 22503, 22563, 22541, 22532, 22530, 22531, + 22592, 22571, 22410, 22425, 22417, 22564, 22509, 22534, 22470, 22593, + 22421, 22422, 22423, 22479, 22471, 22455, 22556, 22507, 22408, 22414, + 22409, 22482, 22577, 22578, 22418, 22419, 22420, 22493, 22448, 22498, + 22465, 22426, 22424, 22427, 22551, 22508, 22557, 22459, 22569, 22428, + 22432, 22436, 22505, 22477, 22545, 22526, 22429, 22433, 22434, 22476, + 22468, 22533, 22486, 22594, 22497, 22435, 22430, 22431, 22513, 22566, + 22572, 22444, 22584, 22437, 22496, 22446, 22543, 22483, 22522, 22453, + 22535, 22485, 22452, 22590, 22442, 22488, 22438, 22484, 22512, 22538, + 22550, 22520, 22555, 22523, 22481, 22499, 22580, 22549, 22516, 22559, + 22587, 22562, 22560, 22583, 22456, 22570, 22463, 22491, 22447, 22478, + 22454, 22502, 22458, 22537, 22457, 22517, 22443, 22581, 22472, 22567, + 22568, 22585, 22558, 22500, 22540, 22529, 22492, 22467, 22441, 22506, + 22514, 22553, 22519, 22449, 22544, 22489, 22504, 22473, 22474, 22576, + 22518, 22521, 22524, 22588, 22511, 22460, 22462, 22547, 22589, 22539, + 22527, 22579, 22582, 22554, 22574, 22480, 22546, 22469, 22561, 22450, + 22575, 22494, 22464, 35762, 35762, 22602, 22600, 22599, 22596, 22595, + 22598, 22597, 22603, 22601, 22393, 22392, 22396, 22394, 22391, 22395, + 22397, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 27, 9, 24, 14, 29, 21, 34, 28, 37, 39, 35, 40, 41, 10, 30, + 32, 18, 15, 31, 42, 13, 25, 36, 23, 12, 20, 33, 19, 38, 17, 11, 26, 16, + 22, 62, 44, 59, 49, 64, 56, 69, 63, 72, 74, 70, 75, 76, 45, 65, 67, 53, + 50, 66, 77, 48, 60, 71, 58, 47, 55, 68, 54, 73, 52, 46, 61, 51, 57, 85, + 86, 79, 84, 43, 78, 83, 82, 35762, 35762, 35762, 35762, 93, 95, 92, 91, + 88, 87, 90, 89, 96, 94, 35762, 35762, 35762, 35762, 80, 81, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 16234, 16220, 16215, 16195, 16190, 16208, 16203, 16183, 16198, + 16223, 16218, 16213, 16193, 16188, 16209, 16204, 16184, 16199, 16235, + 16221, 16216, 16196, 16191, 16211, 16206, 16186, 16201, 16236, 16222, + 16217, 16197, 16192, 16212, 16207, 16187, 16202, 16224, 16219, 16214, + 16194, 16189, 16210, 16205, 16185, 16200, 16181, 16182, 16172, 16179, + 16180, 16232, 16230, 16229, 16226, 16225, 16228, 16227, 16233, 16231, + 16238, 16174, 16173, 16175, 16237, 16178, 16177, 16176, 16171, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 26069, 26064, 26059, 26039, 26034, + 26052, 26047, 26027, 26042, 26067, 26062, 26057, 26037, 26032, 26053, + 26048, 26028, 26043, 26070, 26065, 26060, 26040, 26035, 26055, 26050, + 26030, 26045, 26071, 26066, 26061, 26041, 26036, 26056, 26051, 26031, + 26046, 26068, 26063, 26058, 26038, 26033, 26054, 26049, 26029, 26044, + 26026, 26019, 26021, 26011, 26013, 26014, 26016, 26023, 26022, 26017, + 26012, 26015, 26020, 26018, 26025, 26024, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 2231, 2240, 2237, 2135, 35762, 2247, 2235, 2239, 2227, 2243, 2234, 2183, + 2238, 2245, 2210, 2232, 2241, 2211, 2246, 2242, 2209, 2230, 2229, 2233, + 2228, 2134, 2236, 2244, 2105, 2107, 2106, 2108, 35762, 2147, 2145, 35762, + 2142, 35762, 35762, 2141, 35762, 2149, 2144, 2152, 2146, 2151, 2139, + 2154, 2148, 2140, 2153, 35762, 2138, 2137, 2136, 2143, 35762, 2155, + 35762, 2150, 35762, 35762, 35762, 35762, 35762, 35762, 2219, 35762, + 35762, 35762, 35762, 2220, 35762, 2221, 35762, 2224, 35762, 2223, 2216, + 2226, 35762, 2217, 2225, 35762, 2215, 35762, 35762, 2218, 35762, 2214, + 35762, 2222, 35762, 2212, 35762, 2213, 35762, 2202, 2199, 35762, 2196, + 35762, 35762, 2195, 2190, 2204, 2198, 35762, 2200, 2206, 2193, 2208, + 2203, 2194, 2207, 35762, 2192, 2191, 2189, 2197, 35762, 2188, 2201, 2205, + 2186, 35762, 2187, 35762, 2160, 2172, 2170, 2180, 2163, 2182, 2168, 2162, + 2166, 2175, 35762, 2178, 2171, 2177, 2157, 2161, 2173, 2158, 2181, 2174, + 2156, 2167, 2165, 2159, 2164, 2179, 2169, 2176, 35762, 35762, 35762, + 35762, 35762, 2122, 2119, 2130, 35762, 2133, 2117, 2121, 2115, 2125, + 35762, 2128, 2120, 2127, 2110, 2132, 2123, 2111, 2131, 2124, 2109, 2116, + 2114, 2112, 2113, 2129, 2118, 2126, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 2184, 2185, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 20707, 20723, 20738, 20714, 20742, 20741, 20739, + 20719, 20736, 20733, 20712, 20709, 20728, 20725, 20705, 20716, 20720, + 20737, 20734, 20713, 20710, 20729, 20726, 20706, 20717, 20718, 20735, + 20732, 20711, 20708, 20727, 20724, 20704, 20715, 20722, 20721, 20702, + 20745, 20731, 20730, 20743, 20740, 20744, 20703, 35762, 35762, 35762, + 35762, 10829, 10780, 10781, 10782, 10783, 10784, 10785, 10786, 10787, + 10788, 10789, 10790, 10791, 10792, 10793, 10794, 10795, 10796, 10797, + 10798, 10799, 10800, 10801, 10802, 10803, 10804, 10805, 10806, 10807, + 10808, 10809, 10810, 10811, 10812, 10813, 10814, 10815, 10816, 10817, + 10818, 10819, 10820, 10821, 10822, 10823, 10824, 10825, 10826, 10827, + 10828, 10879, 10830, 10831, 10832, 10833, 10834, 10835, 10836, 10837, + 10838, 10839, 10840, 10841, 10842, 10843, 10844, 10845, 10846, 10847, + 10848, 10849, 10850, 10851, 10852, 10853, 10854, 10855, 10856, 10857, + 10858, 10859, 10860, 10861, 10862, 10863, 10864, 10865, 10866, 10867, + 10868, 10869, 10870, 10871, 10872, 10873, 10874, 10875, 10876, 10877, + 10878, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 26691, 26761, 26736, 26732, 26695, 26700, 26720, + 26716, 26712, 26765, 26728, 26769, 26704, 26724, 26708, 35762, 35762, + 26762, 26737, 26733, 26696, 26701, 26721, 26717, 26713, 26766, 26729, + 26770, 26705, 26725, 26709, 26692, 35762, 26763, 26738, 26734, 26697, + 26702, 26722, 26718, 26714, 26767, 26730, 26771, 26706, 26726, 26710, + 26690, 35762, 26760, 26735, 26731, 26694, 26699, 26719, 26715, 26711, + 26764, 26727, 26768, 26703, 26723, 26707, 26693, 26698, 26742, 26739, + 26753, 26754, 26755, 26756, 26757, 26758, 26759, 26743, 26744, 26745, + 26746, 26747, 26748, 26749, 26750, 26751, 26752, 26740, 26741, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 10565, + 10564, 10549, 10561, 10558, 10543, 10540, 10555, 10552, 10567, 10546, + 10606, 10585, 6512, 6229, 6253, 26362, 26363, 26364, 26365, 26366, 26367, + 26368, 26369, 26370, 26371, 26372, 26373, 26374, 26375, 26376, 26377, + 26378, 26379, 26380, 26381, 26382, 26383, 26384, 26385, 26386, 26387, + 32455, 6343, 6344, 6240, 6511, 8343, 29496, 29497, 29498, 29499, 29500, + 29501, 29502, 29503, 29504, 29505, 29506, 29507, 29508, 29509, 29510, + 29511, 29512, 29513, 29514, 29515, 29516, 29517, 29518, 29519, 29520, + 29521, 29490, 29526, 29541, 29542, 29531, 29553, 24272, 24273, 24274, + 24275, 24276, 24277, 24278, 24279, 24280, 24281, 24282, 24283, 24284, + 24285, 24286, 24287, 24288, 24289, 24290, 24291, 24292, 24293, 24294, + 24295, 24296, 24297, 26969, 26970, 26971, 6239, 6238, 6287, 24303, 24304, + 24305, 24306, 24307, 24308, 24309, 24310, 24311, 24312, 24313, 24314, + 24315, 24316, 24317, 24318, 24319, 24320, 24321, 24322, 24323, 24324, + 24325, 24326, 24327, 24328, 8387, 24332, 24334, 24335, 24331, 24333, + 29232, 29479, 29478, 29485, 29554, 29527, 29528, 29530, 29540, 29548, + 29551, 29543, 29533, 29545, 29483, 29547, 29484, 29534, 29544, 29536, + 29529, 29495, 29489, 29488, 29487, 29524, 29535, 29549, 29550, 21137, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 26997, 26998, 26999, 27000, + 27001, 27002, 27003, 27004, 27005, 27006, 27007, 27008, 27009, 27010, + 27011, 27012, 27013, 27014, 27015, 27016, 27017, 27018, 27019, 27020, + 27021, 27022, 29270, 29491, 29493, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 29457, 29452, + 29444, 29492, 29438, 29450, 29473, 29449, 29437, 29462, 29470, 29461, + 29442, 29453, 29454, 29460, 29441, 29471, 29468, 29475, 29451, 29446, + 29465, 29455, 29458, 29435, 29436, 29477, 29448, 29439, 29443, 29459, + 29474, 29456, 29469, 29472, 29445, 29466, 29464, 29463, 29467, 29440, + 29447, 29476, 35762, 35762, 35762, 35762, 32452, 32446, 32447, 32449, + 32453, 32450, 32454, 32448, 32451, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 6291, 6289, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 27401, 27402, + 27399, 27403, 27398, 27400, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 10219, 13162, + 7734, 24578, 29724, 29723, 6522, 29725, 26962, 4630, 33941, 33767, 22902, + 11218, 11216, 11217, 13610, 24383, 33853, 13131, 33854, 13203, 33852, + 18158, 33851, 8377, 24382, 13130, 18157, 13202, 29648, 13611, 27918, + 32014, 3808, 34096, 34100, 34097, 34098, 7747, 7746, 7745, 7744, 13161, + 34162, 15972, 31673, 4706, 6175, 27734, 13062, 10243, 26230, 5823, 15969, + 32566, 6173, 27389, 15937, 29726, 3985, 11212, 11213, 15762, 13180, + 20989, 13101, 19445, 23855, 32421, 2525, 13723, 22390, 33944, 30811, + 19779, 3406, 26676, 26994, 14263, 26496, 26493, 6174, 29593, 14654, + 28875, 22182, 26811, 27117, 27118, 8177, 9648, 29581, 29170, 4628, 13193, + 27405, 10228, 26088, 29766, 13201, 13137, 28969, 27862, 16002, 10975, + 8176, 6212, 5698, 20592, 9650, 15943, 27935, 3629, 26809, 8175, 13167, + 31675, 27701, 34164, 7751, 32533, 3520, 7693, 2589, 13168, 4093, 26799, + 27108, 34184, 3740, 16359, 6213, 13107, 13127, 13126, 2729, 26420, 8156, + 30810, 8388, 26675, 16364, 5760, 34161, 23499, 27706, 13648, 15234, 4095, + 22901, 27061, 23619, 29597, 19778, 8168, 3510, 3511, 13122, 98, 5758, + 13113, 27348, 13135, 22894, 23520, 6215, 15233, 2506, 32435, 6520, 32420, + 7689, 26525, 33689, 10611, 28881, 3739, 13322, 4098, 13153, 23854, 23602, + 27700, 14279, 23618, 32538, 33694, 23853, 27530, 31789, 28856, 3412, + 6176, 28963, 27531, 29764, 29196, 32535, 15967, 360, 27408, 29769, 33963, + 13647, 26952, 26953, 8379, 33768, 13141, 16004, 29954, 28960, 4964, 3516, + 4705, 15979, 6521, 10520, 7690, 10351, 10352, 24253, 29579, 15978, 15977, + 25236, 16361, 13032, 15980, 3401, 2522, 15973, 20528, 8171, 27705, 10269, + 13097, 16357, 16360, 13031, 34065, 3855, 33950, 33949, 27390, 3870, + 18037, 2600, 4102, 359, 12426, 12427, 12428, 12429, 12430, 26976, 23515, + 26091, 33942, 8370, 32318, 19676, 26978, 5765, 11054, 8391, 34118, 28957, + 28958, 15966, 26981, 13615, 27940, 23497, 27352, 6181, 10716, 26667, + 4252, 12395, 25234, 29191, 4643, 954, 15942, 18039, 13134, 32534, 3986, + 32564, 15201, 2588, 13197, 3741, 26497, 18034, 26821, 11056, 2598, 10778, + 23517, 8371, 32319, 26979, 5766, 11055, 29195, 15968, 23498, 10777, + 26669, 13200, 14652, 34183, 3515, 26267, 26668, 26486, 6180, 13059, + 13057, 11211, 24730, 23518, 32422, 34107, 34024, 34050, 34071, 13138, + 33951, 26087, 32046, 32047, 7688, 25781, 8393, 34173, 13058, 24573, + 29951, 16461, 11062, 18029, 3745, 34172, 26925, 14658, 26816, 20983, + 2519, 15833, 34174, 34171, 13166, 4701, 4700, 4250, 13510, 20896, 34169, + 13105, 20902, 32581, 32582, 26796, 34170, 4631, 26510, 20899, 20900, + 25760, 25758, 2587, 8159, 26878, 16366, 16365, 14521, 2590, 13045, 356, + 16131, 28858, 16247, 14278, 10227, 20434, 24184, 13093, 14525, 3410, + 29949, 26672, 18026, 20527, 27328, 13326, 18021, 4094, 8369, 33961, 3517, + 4637, 32575, 29171, 14276, 15236, 3988, 14265, 34208, 26924, 15235, + 27104, 15237, 10528, 12383, 952, 4249, 28870, 7756, 29192, 11058, 10232, + 26670, 13148, 10696, 29182, 32021, 34035, 15989, 23319, 9646, 15266, + 8376, 3403, 3405, 3404, 3402, 23318, 5994, 27730, 26520, 4632, 22904, + 13154, 25792, 11209, 13118, 25779, 26095, 26097, 4961, 31676, 5703, 5993, + 5995, 3408, 7694, 26927, 27396, 26488, 29591, 32504, 3999, 19777, 24727, + 24728, 7740, 25773, 14264, 3987, 25796, 4000, 24255, 27727, 22741, 31681, + 26098, 13104, 27614, 26928, 6000, 26073, 16356, 26487, 13060, 16163, + 12464, 7737, 7738, 25783, 25782, 26805, 26802, 24568, 22918, 22919, + 33686, 22920, 24648, 967, 4962, 4963, 33688, 31688, 26955, 33690, 13121, + 26800, 26892, 32568, 7724, 7725, 7721, 963, 20529, 15828, 29177, 29176, + 29178, 29179, 3509, 12381, 19566, 27215, 20492, 7739, 17144, 20489, + 25786, 3523, 3525, 3998, 20432, 26957, 2592, 12459, 25762, 29019, 32445, + 24647, 17159, 16250, 16251, 16254, 16253, 16252, 13123, 12382, 34187, + 14648, 25141, 15981, 26681, 22893, 31687, 8398, 28852, 16367, 32506, + 3880, 34083, 18148, 18130, 18138, 18131, 28887, 28886, 32658, 10981, + 32656, 10982, 20561, 32707, 6236, 8385, 8384, 24720, 24722, 29838, 34048, + 15281, 5831, 26089, 11049, 17142, 23504, 29859, 22604, 4096, 7705, 7715, + 7717, 7701, 7699, 7709, 7707, 7697, 7703, 7711, 7695, 7713, 7706, 7716, + 7718, 7702, 7700, 7710, 7708, 7698, 7704, 7712, 7696, 7714, 27173, 27174, + 27175, 4696, 4697, 27336, 3997, 5697, 20986, 3882, 24646, 15941, 20897, + 28873, 10229, 29187, 29188, 16462, 20901, 19490, 31682, 27156, 34102, + 3895, 31686, 7691, 2593, 29563, 12463, 13160, 26500, 20431, 3852, 20554, + 20540, 20552, 20553, 20558, 19545, 32555, 26967, 27089, 27097, 27098, + 27102, 27099, 26968, 34025, 28043, 28042, 28039, 28038, 3830, 3868, + 28045, 28044, 28041, 28040, 3898, 3802, 3815, 10353, 17146, 32037, 26875, + 26822, 3818, 34039, 28970, 31670, 34167, 25770, 32570, 32033, 32490, + 25585, 15229, 27711, 26876, 13103, 25793, 10702, 10703, 10704, 13190, + 13192, 13191, 3814, 13164, 25780, 5704, 5705, 13119, 12431, 12432, 12433, + 24724, 24725, 24726, 12442, 12435, 12436, 10701, 26094, 26099, 33957, + 29190, 29189, 10354, 22905, 22168, 26080, 7723, 5695, 16165, 10246, 8151, + 25757, 27347, 26096, 29589, 10226, 20433, 29180, 32029, 32028, 32030, + 32031, 19517, 27176, 32583, 32035, 19533, 27189, 19454, 27121, 23501, + 19802, 19801, 2734, 2740, 2735, 2739, 2732, 19799, 2733, 34178, 23514, + 32489, 29577, 28855, 23519, 14268, 14270, 13084, 28945, 28947, 28946, + 28948, 28944, 28943, 34165, 28949, 13064, 27060, 28942, 28952, 28955, + 24380, 13056, 32619, 13067, 26498, 8157, 8158, 18022, 13094, 18023, + 18024, 13081, 13082, 13083, 10613, 34179, 953, 26814, 8397, 26522, 13088, + 10612, 13199, 950, 13110, 33959, 28872, 32419, 14273, 20591, 13072, + 15988, 13074, 13065, 2514, 13155, 28871, 10697, 13091, 13069, 14272, + 5767, 28940, 28941, 5768, 18025, 26813, 8396, 33958, 28876, 28877, 32716, + 13087, 13077, 13071, 26519, 27735, 15239, 29175, 15200, 26517, 26516, + 26512, 26514, 24689, 29073, 24663, 29061, 32553, 32562, 32552, 32561, + 24688, 29072, 24662, 29060, 15317, 15310, 15314, 15307, 24690, 29074, + 24664, 29062, 15318, 15311, 15315, 15308, 15939, 15940, 29015, 29016, + 19669, 32750, 27291, 11044, 27721, 15312, 19781, 15289, 15244, 29767, + 27608, 27609, 27610, 15333, 27611, 15301, 33677, 33674, 5996, 27070, + 27346, 15474, 29580, 26960, 15831, 15832, 32497, 22740, 19788, 29578, + 32493, 32494, 4699, 25767, 32532, 4702, 22906, 361, 13124, 26794, 25765, + 31674, 25766, 2521, 25763, 26993, 10251, 2505, 32491, 23496, 23511, + 29765, 23512, 160, 27917, 27404, 29181, 15963, 33668, 8160, 26795, 32503, + 11050, 24644, 28956, 24649, 26926, 11048, 26807, 24653, 3735, 24642, + 3734, 23513, 26529, 24645, 6178, 22605, 34175, 27065, 2591, 32488, 33940, + 27939, 3507, 3508, 26428, 9651, 2604, 19491, 32500, 26889, 6345, 4251, + 13511, 8368, 28869, 27920, 3527, 3636, 26686, 25233, 27919, 29599, 26100, + 15935, 15991, 12396, 35762, 35762, 35762, 35762, 34168, 26772, 33965, + 27329, 14649, 27913, 25267, 23509, 26959, 23506, 32654, 32657, 32655, + 28884, 24697, 227, 228, 35762, 35762, 35762, 27613, 25764, 10538, 26425, + 27709, 23507, 5700, 28874, 13159, 28861, 2523, 26666, 27349, 35762, + 35762, 35762, 295, 243, 344, 342, 339, 237, 235, 236, 233, 234, 332, 334, + 335, 321, 288, 250, 281, 282, 283, 265, 309, 286, 336, 337, 307, 308, + 270, 323, 276, 277, 259, 300, 256, 278, 319, 257, 258, 255, 310, 317, + 338, 329, 279, 238, 318, 311, 316, 333, 298, 299, 297, 301, 302, 303, + 230, 231, 284, 312, 241, 304, 305, 240, 246, 326, 327, 296, 247, 248, + 249, 232, 343, 322, 328, 271, 340, 289, 254, 331, 253, 325, 252, 330, + 313, 280, 324, 341, 274, 242, 291, 251, 290, 239, 314, 315, 320, 294, + 268, 266, 267, 293, 292, 260, 261, 262, 263, 264, 229, 244, 245, 306, + 275, 287, 269, 285, 273, 272, 20525, 25235, 20594, 35762, 35762, 35762, + 35762, 15228, 20771, 13645, 26946, 25897, 3823, 3899, 3860, 3803, 3885, + 22283, 3994, 15329, 33678, 13042, 34005, 27397, 3893, 3886, 19796, 22308, + 3995, 15330, 33679, 13043, 34084, 34086, 29411, 3891, 3909, 3847, 34019, + 34020, 10527, 3892, 3910, 3848, 34055, 32018, 19798, 22309, 3996, 33683, + 33680, 13044, 32016, 19791, 22301, 3990, 15302, 33675, 13039, 19784, + 22289, 3993, 15277, 33673, 13041, 19792, 22300, 3991, 15306, 33676, + 13040, 19782, 22306, 3992, 15271, 33672, 19794, 22303, 32036, 22302, + 19786, 22288, 13182, 22287, 27071, 19783, 15276, 22299, 15305, 28850, + 22305, 15269, 33671, 15267, 19793, 15324, 15323, 6506, 24298, 6516, + 24299, 24576, 35762, 35762, 35762, 35762, 35762, 35762, 18137, 18150, + 18133, 18146, 18128, 18149, 18132, 18139, 18151, 18134, 18147, 18129, + 35762, 35762, 35762, 35762, 15274, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 19590, 32726, 27244, 10996, 19597, 32723, 27251, 10993, 19586, 32722, + 27240, 10992, 35762, 35762, 35762, 35762, 19589, 32725, 27243, 10995, + 19599, 32727, 27253, 10997, 15285, 15326, 15299, 15263, 15284, 15325, + 15298, 15262, 19633, 32760, 27304, 11013, 19632, 32759, 27303, 11012, + 19631, 32756, 27302, 11009, 19635, 32762, 27306, 11015, 19634, 32761, + 27305, 11014, 19663, 32737, 27270, 11031, 19671, 32752, 27293, 11046, + 19673, 32748, 27326, 11042, 19623, 32746, 27284, 11040, 19624, 32747, + 27285, 11041, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 19672, 32751, 27294, 11045, 24695, 24669, 29067, 29079, 19509, 32647, + 35762, 35762, 35762, 35762, 35762, 35762, 34121, 34136, 34126, 34131, + 34146, 34141, 34151, 34156, 34123, 34138, 34128, 34133, 34148, 34143, + 34153, 34158, 34122, 34137, 34127, 34132, 34147, 34142, 34152, 34157, + 34119, 34134, 34124, 34129, 34144, 34139, 34149, 34154, 34120, 34135, + 34125, 34130, 34145, 34140, 34150, 34155, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 19639, 32766, 27310, 11020, 19653, 32778, + 27325, 11025, 19598, 32724, 27252, 10994, 15240, 15243, 15242, 15241, + 19607, 27259, 19642, 27295, 19664, 27290, 19668, 27286, 19606, 27258, + 19662, 27269, 33969, 33968, 35762, 35762, 2501, 2498, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 6234, 6235, 6233, 19481, 19479, + 19480, 19482, 19478, 10985, 10987, 10986, 10988, 26673, 34040, 4639, + 26674, 35571, 23320, 13085, 24574, 32019, 13068, 27406, 15990, 28718, + 4960, 26975, 19561, 27210, 14659, 14655, 16358, 13066, 7748, 24254, + 27351, 11059, 20652, 13092, 28959, 13076, 14271, 14269, 13086, 27751, + 28950, 13073, 27938, 26823, 4627, 26265, 27760, 26877, 20898, 23505, + 27942, 26507, 16464, 13115, 22921, 34186, 33943, 14657, 10692, 34160, + 11060, 7692, 32565, 29194, 13614, 27340, 13133, 27733, 32020, 4247, + 21060, 9645, 18038, 28972, 13158, 8392, 2581, 9652, 2599, 26808, 5763, + 2602, 14266, 27764, 29598, 12333, 13609, 26494, 18027, 26266, 11206, + 13174, 30393, 6211, 4097, 9638, 7752, 4638, 26684, 26873, 9653, 27612, + 5699, 19446, 20987, 23500, 2603, 28951, 34207, 28953, 13078, 13090, + 26079, 13195, 24577, 10616, 13095, 13080, 27702, 18036, 13643, 15936, + 13143, 8399, 20486, 27707, 32541, 32633, 11221, 11207, 3450, 27861, + 26090, 13187, 4704, 10522, 13644, 20487, 27106, 27941, 29556, 13512, + 35565, 15827, 27698, 29952, 8378, 16750, 20658, 26491, 15938, 26423, + 26954, 20590, 23503, 22896, 2601, 29768, 20895, 11051, 28882, 26072, + 25798, 28860, 13147, 26085, 3518, 3746, 27729, 14280, 26890, 12422, + 12423, 12425, 12424, 4253, 19780, 13165, 32423, 29761, 29762, 27541, + 11214, 23508, 20984, 22183, 22184, 5999, 9640, 27544, 3635, 13321, 25772, + 13102, 33956, 4703, 22147, 16003, 4641, 32531, 29564, 18031, 10521, + 13070, 101, 6177, 25759, 3514, 26515, 26508, 26518, 26509, 20662, 13108, + 33339, 22728, 12420, 13507, 35757, 4625, 25797, 3738, 27704, 13612, 8374, + 28967, 26995, 13128, 16467, 31792, 26528, 11208, 8154, 2583, 13125, + 32425, 4634, 20661, 20593, 20524, 29193, 2742, 27542, 31680, 4640, 3411, + 27350, 3409, 29197, 26982, 24256, 24357, 24368, 24371, 24360, 24350, + 24365, 33980, 3771, 24351, 33977, 33993, 33996, 33972, 33985, 33990, + 3768, 3784, 3787, 3763, 3776, 3781, 24358, 24369, 24372, 24361, 24356, + 24366, 33981, 3772, 24352, 33999, 34002, 34003, 33998, 34000, 34001, + 3790, 3793, 3794, 3789, 3791, 3792, 24375, 24378, 24379, 24374, 24376, + 24377, 33982, 3773, 24353, 33978, 33994, 33997, 33973, 33983, 33991, + 3769, 3785, 3788, 3764, 3774, 3782, 24359, 24370, 24373, 24362, 24354, + 24367, 33984, 3775, 24355, 33974, 3765, 24363, 33975, 3766, 24364, 33987, + 33988, 33986, 3778, 3779, 3777, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 34202, 34205, 34201, 34203, + 34200, 34199, 34204, 34195, 34198, 34194, 34196, 34193, 34192, 34197, + 35762, 35762, 2743, 25771, 4633, 27936, 32022, 19795, 14267, 26678, + 11057, 99, 29583, 34191, 8395, 35762, 35762, 35762, 35479, 18030, 26274, + 4001, 20660, 26679, 24347, 20990, 13156, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 27335, 5834, 26980, 2586, 10695, 3407, 22900, 1, + 20509, 8373, 5761, 27710, 18040, 15983, 22916, 34163, 26792, 27756, + 18032, 4707, 23516, 32424, 15231, 26687, 27345, 22917, 16009, 20530, + 14653, 13163, 14523, 17228, 13157, 34180, 3521, 7750, 26810, 34182, + 13109, 20526, 8347, 12434, 24348, 16000, 16460, 34166, 35762, 13646, 946, + 20595, 26530, 26825, 26824, 26513, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 23502, 10880, 3989, 3524, 25761, 13144, 30809, + 13186, 31679, 26812, 3519, 16459, 13509, 26495, 35762, 35762, 35762, + 35762, 22389, 27546, 13075, 13079, 13089, 10890, 3743, 4642, 27912, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 14656, 27283, 19622, + 26231, 26232, 16170, 15238, 19667, 27289, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 3925, 3955, 3926, 3970, 3941, 3956, 3927, 3978, + 3948, 3964, 3934, 3971, 3942, 3957, 3928, 3982, 3952, 3967, 3938, 3975, + 3961, 3931, 3979, 3949, 3965, 3935, 3972, 3943, 3958, 3929, 3984, 3954, + 3969, 3940, 3977, 3947, 3963, 3933, 3981, 3951, 3937, 3974, 3945, 3960, + 3930, 3983, 3953, 3968, 3939, 3976, 3946, 3962, 3932, 3980, 3950, 3966, + 3936, 3973, 3944, 3959, 20541, 20542, 20549, 20551, 20546, 20574, 20575, + 20571, 20573, 20569, 20572, 20565, 20568, 20566, 20570, 20567, 20545, + 20548, 20543, 20547, 20544, 20550, 32692, 32693, 32700, 32702, 32697, + 32682, 32683, 32679, 32681, 32677, 32680, 32673, 32676, 32674, 32678, + 32675, 32696, 32699, 32694, 32698, 32695, 32701, 32664, 19447, 32661, + 19449, 19530, 32715, 27195, 20587, 33658, 33659, 33660, 33661, 33662, + 33663, 15949, 15950, 15951, 15952, 15953, 15954, 19448, 19450, 27120, + 27119, 32663, 15948, 32690, 32713, 32666, 32714, 32712, 27160, 27190, + 27147, 27191, 27170, 19489, 27155, 32671, 20537, 16342, 32668, 32669, + 35762, 19488, 5997, 16338, 15278, 32685, 32709, 32662, 19451, 32686, + 32710, 20563, 20556, 4173, 4177, 4169, 4172, 4174, 4179, 4170, 4167, + 4176, 4178, 4180, 4175, 4168, 4171, 4184, 4207, 2504, 16339, 19487, + 27154, 16340, 19577, 27229, 11002, 32719, 19486, 27153, 33766, 27162, + 24301, 24300, 24302, 34043, 19532, 22897, 27188, 24330, 29584, 29585, + 29587, 29588, 29586, 34109, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 27743, 27745, 27742, 27741, 27738, 27737, 27740, 27739, 27746, + 27744, 35762, 35762, 35762, 35762, 35762, 35762, 6553, 6554, 6555, 6556, + 6557, 6558, 6559, 6560, 6561, 6562, 6563, 6564, 6565, 6566, 6567, 6568, + 6569, 6570, 6571, 6572, 6573, 6574, 6575, 6576, 6577, 6578, 6579, 6580, + 6581, 6582, 6583, 6584, 6585, 6586, 6587, 6588, 6589, 6590, 6591, 6592, + 6593, 6594, 6595, 6596, 6597, 6598, 6599, 6600, 6601, 6602, 6603, 6604, + 6605, 6606, 6607, 6608, 6609, 6610, 6611, 6612, 6613, 6614, 6615, 6616, + 6617, 6618, 6619, 6620, 6621, 6622, 6623, 6624, 6625, 6626, 6627, 6628, + 6629, 6630, 6631, 6632, 6633, 6634, 6635, 6636, 6637, 6638, 6639, 6640, + 6641, 6642, 6643, 6644, 6645, 6646, 6647, 6648, 6649, 6650, 6651, 6652, + 6653, 6654, 6655, 6656, 6657, 6658, 6659, 6660, 6661, 6662, 6663, 6664, + 6665, 6666, 6667, 6668, 6669, 6670, 6671, 6672, 6673, 6674, 6675, 6676, + 6677, 6678, 6679, 6680, 6681, 6682, 6683, 6684, 6685, 6686, 6687, 6688, + 6689, 6690, 6691, 6692, 6693, 6694, 6695, 6696, 6697, 6698, 6699, 6700, + 6701, 6702, 6703, 6704, 6705, 6706, 6707, 6708, 6709, 6710, 6711, 6712, + 6713, 6714, 6715, 6716, 6717, 6718, 6719, 6720, 6721, 6722, 6723, 6724, + 6725, 6726, 6727, 6728, 6729, 6730, 6731, 6732, 6733, 6734, 6735, 6736, + 6737, 6738, 6739, 6740, 6741, 6742, 6743, 6744, 6745, 6746, 6747, 6748, + 6749, 6750, 6751, 6752, 6753, 6754, 6755, 6756, 6757, 6758, 6759, 6760, + 6761, 6762, 6763, 6764, 6765, 6766, 6767, 6768, 6769, 6770, 6771, 6772, + 6773, 6774, 6775, 6776, 6777, 6778, 6779, 6780, 6781, 6782, 6783, 6784, + 6785, 6786, 6787, 6788, 6789, 6790, 6791, 6792, 6793, 6794, 6795, 6796, + 6797, 6798, 6799, 6800, 6801, 6802, 6803, 6804, 6805, 6806, 6807, 6808, + 6809, 6810, 6811, 6812, 6813, 6814, 6815, 6816, 6817, 6818, 6819, 6820, + 6821, 6822, 6823, 6824, 6825, 6826, 6827, 6828, 6829, 6830, 6831, 6832, + 6833, 6834, 6835, 6836, 6837, 6838, 6839, 6840, 6841, 6842, 6843, 6844, + 6845, 6846, 6847, 6848, 6849, 6850, 6851, 6852, 6853, 6854, 6855, 6856, + 6857, 6858, 6859, 6860, 6861, 6862, 6863, 6864, 6865, 6866, 6867, 6868, + 6869, 6870, 6871, 6872, 6873, 6874, 6875, 6876, 6877, 6878, 6879, 6880, + 6881, 6882, 6883, 6884, 6885, 6886, 6887, 6888, 6889, 6890, 6891, 6892, + 6893, 6894, 6895, 6896, 6897, 6898, 6899, 6900, 6901, 6902, 6903, 6904, + 6905, 6906, 6907, 6908, 6909, 6910, 6911, 6912, 6913, 6914, 6915, 6916, + 6917, 6918, 6919, 6920, 6921, 6922, 6923, 6924, 6925, 6926, 6927, 6928, + 6929, 6930, 6931, 6932, 6933, 6934, 6935, 6936, 6937, 6938, 6939, 6940, + 6941, 6942, 6943, 6944, 6945, 6946, 6947, 6948, 6949, 6950, 6951, 6952, + 6953, 6954, 6955, 6956, 6957, 6958, 6959, 6960, 6961, 6962, 6963, 6964, + 6965, 6966, 6967, 6968, 6969, 6970, 6971, 6972, 6973, 6974, 6975, 6976, + 6977, 6978, 6979, 6980, 6981, 6982, 6983, 6984, 6985, 6986, 6987, 6988, + 6989, 6990, 6991, 6992, 6993, 6994, 6995, 6996, 6997, 6998, 6999, 7000, + 7001, 7002, 7003, 7004, 7005, 7006, 7007, 7008, 7009, 7010, 7011, 7012, + 7013, 7014, 7015, 7016, 7017, 7018, 7019, 7020, 7021, 7022, 7023, 7024, + 7025, 7026, 7027, 7028, 7029, 7030, 7031, 7032, 7033, 7034, 7035, 7036, + 7037, 7038, 7039, 7040, 7041, 7042, 7043, 7044, 7045, 7046, 7047, 7048, + 7049, 7050, 7051, 7052, 7053, 7054, 7055, 7056, 7057, 7058, 7059, 7060, + 7061, 7062, 7063, 7064, 6537, 6538, 6539, 6540, 6541, 6542, 6543, 6544, + 6545, 6546, 6547, 6548, 6549, 6550, 6551, 6552, 6523, 6524, 6525, 6526, + 6527, 6528, 6529, 6530, 6531, 6532, 6533, 6534, 6535, 6536, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 19444, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 30045, 29974, 30037, 30046, + 29962, 30035, 29956, 29955, 30032, 30040, 29957, 30036, 29960, 29977, + 30048, 30044, 29969, 29971, 29968, 29967, 29964, 29963, 29966, 29965, + 29972, 29970, 29961, 30043, 30030, 29973, 29976, 30038, 29959, 29978, + 29979, 29980, 29981, 29982, 29983, 29984, 29985, 29986, 29987, 29988, + 29989, 29990, 29991, 29992, 29993, 29994, 29995, 29996, 29997, 29998, + 29999, 30000, 30001, 30002, 30003, 30033, 30042, 30041, 29958, 30034, + 29975, 30004, 30005, 30006, 30007, 30008, 30009, 30010, 30011, 30012, + 30013, 30014, 30015, 30016, 30017, 30018, 30019, 30020, 30021, 30022, + 30023, 30024, 30025, 30026, 30027, 30028, 30029, 30031, 30049, 30039, + 30047, 5694, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 33161, 33172, 33183, 33195, 33206, 33217, 33228, 33239, 33250, 33258, + 33259, 33260, 33261, 33263, 33264, 33265, 33266, 33267, 33268, 33269, + 33270, 33271, 33272, 33274, 33275, 33276, 33277, 33278, 33279, 33280, + 33281, 33282, 33283, 33285, 33286, 33287, 33288, 33289, 33290, 33291, + 33292, 33293, 33294, 33296, 33297, 33298, 33299, 33300, 33301, 33302, + 33303, 33304, 33305, 33307, 33308, 33309, 33310, 33311, 33312, 33313, + 33314, 33315, 33316, 33318, 33319, 33320, 33321, 33322, 33323, 33324, + 33325, 33326, 33327, 33329, 33330, 33331, 33332, 33333, 33334, 33335, + 33336, 33337, 33338, 33085, 33086, 33087, 33088, 33089, 33090, 33091, + 33092, 33093, 33094, 33096, 33097, 33098, 33099, 33100, 33101, 33102, + 33103, 33104, 33105, 33107, 33108, 33109, 33110, 33111, 33112, 33113, + 33114, 33115, 33116, 33118, 33119, 33120, 33121, 33122, 33123, 33124, + 33125, 33126, 33127, 33129, 33130, 33131, 33132, 33133, 33134, 33135, + 33136, 33137, 33138, 33140, 33141, 33142, 33143, 33144, 33145, 33146, + 33147, 33148, 33149, 33151, 33152, 33153, 33154, 33155, 33156, 33157, + 33158, 33159, 33160, 33162, 33163, 33164, 33165, 33166, 33167, 33168, + 33169, 33170, 33171, 33173, 33174, 33175, 33176, 33177, 33178, 33179, + 33180, 33181, 33182, 33184, 33185, 33186, 33187, 33188, 33189, 33190, + 33191, 33192, 33193, 33196, 33197, 33198, 33199, 33200, 33201, 33202, + 33203, 33204, 33205, 33207, 33208, 33209, 33210, 33211, 33212, 33213, + 33214, 33215, 33216, 33218, 33219, 33220, 33221, 33222, 33223, 33224, + 33225, 33226, 33227, 33229, 33230, 33231, 33232, 33233, 33234, 33235, + 33236, 33237, 33238, 33240, 33241, 33242, 33243, 33244, 33245, 33246, + 33247, 33248, 33249, 33251, 33252, 33253, 33254, 33255, 33256, 33257, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 25143, 25142, 29575, 29166, + 29576, 29601, 12457, 13030, 12455, 12468, 12461, 12460, 3, 2, 347, 3522, + 2596, 4957, 5989, 15959, 15985, 29953, 19875, 24468, 12458, 20659, 25216, + 12466, 19877, 33665, 33770, 13171, 13320, 5762, 8375, 27914, 20491, + 28965, 27915, 20490, 27945, 10237, 11210, 10519, 10238, 10518, 10239, + 10517, 10240, 10515, 10241, 24336, 24258, 29858, 29857, 12456, 13029, + 5692, 4965, 12454, 12467, 12421, 29632, 29602, 12502, 12501, 16242, + 13120, 13318, 16243, 14274, 14522, 16244, 26992, 27539, 16245, 32630, + 32782, 29168, 10253, 10250, 26093, 26092, 15830, 15984, 4626, 4956, + 24641, 24260, 16169, 16168, 24570, 24575, 29572, 29559, 12453, 12505, + 5991, 15961, 15987, 5990, 15960, 15986, 19878, 33666, 33771, 26416, + 26415, 26793, 26417, 26418, 26773, 27072, 27079, 27107, 28731, 28732, + 29557, 28730, 28733, 29558, 10516, 10242, 26881, 26882, 26929, 26880, + 26883, 26930, 27754, 29600, 5693, 10222, 22730, 24084, 29571, 29574, + 29169, 12452, 12450, 13063, 29573, 29167, 28725, 29950, 28724, 27728, + 8169, 10221, 29595, 29560, 25790, 26010, 26879, 26931, 1048, 1049, 24259, + 27944, 18311, 18929, 10220, 2297, 350, 29936, 16751, 18043, 18044, 18086, + 18052, 32125, 14921, 14922, 14899, 14920, 13314, 13315, 13316, 24082, + 13317, 29657, 35760, 35759, 35761, 20655, 27343, 20653, 27341, 26489, + 20656, 27344, 25215, 24083, 34189, 20654, 27342, 13319, 26490, 33962, + 22891, 22892, 19628, 27299, 34696, 23890, 33340, 33451, 33519, 33530, + 33541, 33552, 33563, 33574, 33585, 33341, 33352, 33363, 33374, 33385, + 33396, 33407, 26848, 4955, 4248, 35758, 9338, 9337, 22191, 22189, 22249, + 22247, 15743, 4792, 33418, 33429, 33440, 33452, 33463, 33474, 33485, + 33496, 33507, 33515, 33516, 33517, 33518, 33520, 33521, 33522, 33523, + 33524, 33525, 33526, 33527, 33528, 33529, 33531, 33532, 33533, 33534, + 33535, 33536, 33537, 33538, 33539, 33540, 33542, 33543, 33544, 33545, + 33546, 33547, 33548, 33549, 33550, 33551, 33553, 33554, 33555, 33556, + 33557, 33558, 33559, 33560, 33561, 33562, 33564, 33565, 33566, 33567, + 33568, 33569, 33570, 33571, 33572, 33573, 33575, 33576, 33577, 33578, + 33579, 33580, 33581, 33582, 33583, 33584, 33586, 33587, 33588, 33589, + 33590, 33591, 33592, 33593, 33594, 33595, 33342, 33343, 33344, 33345, + 33346, 33347, 33348, 33349, 33350, 33351, 33353, 33354, 33355, 33356, + 33357, 33358, 33359, 33360, 33361, 33362, 33364, 33365, 33366, 33367, + 33368, 33369, 33370, 33371, 33372, 33373, 33375, 33376, 33377, 33378, + 33379, 33380, 33381, 33382, 33383, 33384, 33386, 33387, 33388, 33389, + 33390, 33391, 33392, 33393, 33394, 33395, 33397, 33398, 33399, 33400, + 33401, 33402, 33403, 33404, 33405, 33406, 33408, 33409, 33410, 33411, + 33412, 33413, 33414, 33415, 33416, 33417, 33419, 33420, 33421, 33422, + 33423, 33424, 33425, 33426, 33427, 33428, 33430, 33431, 33432, 33433, + 33434, 33435, 33436, 33437, 33438, 33439, 33441, 33442, 33443, 33444, + 33445, 33446, 33447, 33448, 33449, 33450, 33453, 33454, 33455, 33456, + 33457, 33458, 33459, 33460, 33461, 33462, 33464, 33465, 33466, 33467, + 33468, 33469, 33470, 33471, 33472, 33473, 33475, 33476, 33477, 33478, + 33479, 33480, 33481, 33482, 33483, 33484, 33486, 33487, 33488, 33489, + 33490, 33491, 33492, 33493, 33494, 33495, 33497, 33498, 33499, 33500, + 33501, 33502, 33503, 33504, 33505, 33506, 33508, 33509, 33510, 33511, + 33512, 33513, 33514, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 17147, 17148, 17155, 17157, 17154, 17153, 17150, 17149, + 17152, 17151, 17158, 17156, 18176, 18735, 18335, 18960, 18570, 19331, + 18270, 18870, 18271, 18871, 18272, 18872, 18444, 19110, 18445, 19111, + 18446, 19112, 18509, 19207, 18254, 18853, 18250, 18849, 18955, 19078, + 18186, 18745, 18187, 18746, 18275, 18876, 18276, 18877, 18260, 18859, + 18261, 18860, 18954, 18956, 18340, 18962, 18341, 18963, 18358, 18990, + 18388, 19030, 18394, 19051, 18484, 19169, 18574, 19335, 18575, 19336, + 18571, 19332, 18572, 19333, 18754, 19127, 19128, 19286, 19287, 19216, + 19217, 18944, 18945, 2267, 2270, 2268, 2272, 2274, 2271, 2273, 2269, + 2275, 10448, 10443, 10442, 10449, 10444, 10445, 10447, 10446, 3594, 3593, + 3595, 14488, 14487, 14486, 14485, 14490, 14489, 25862, 25861, 3539, + 30399, 30407, 30416, 30408, 30410, 30405, 30409, 30404, 30420, 30419, + 30422, 30414, 30401, 30421, 30403, 30402, 30415, 30406, 30418, 30412, + 30413, 30411, 30417, 30400, 30538, 30545, 30546, 30541, 30542, 30547, + 30548, 30539, 30543, 30544, 30540, 30604, 30611, 30612, 30607, 30608, + 30613, 30614, 30605, 30609, 30610, 30606, 30715, 30722, 30723, 30718, + 30719, 30724, 30725, 30716, 30720, 30721, 30717, 30615, 30622, 30623, + 30618, 30619, 30624, 30625, 30616, 30620, 30621, 30617, 30693, 30700, + 30701, 30696, 30697, 30702, 30703, 30694, 30698, 30699, 30695, 30593, + 30600, 30601, 30596, 30597, 30602, 30603, 30594, 30598, 30599, 30595, + 30704, 30711, 30712, 30707, 30708, 30713, 30714, 30705, 30709, 30710, + 30706, 30626, 30633, 30634, 30629, 30630, 30635, 30636, 30627, 30631, + 30632, 30628, 30759, 30766, 30767, 30762, 30763, 30768, 30769, 30760, + 30764, 30765, 30761, 30748, 30755, 30756, 30751, 30752, 30757, 30758, + 30749, 30753, 30754, 30750, 30781, 30788, 30789, 30784, 30785, 30790, + 30791, 30782, 30786, 30787, 30783, 30648, 30655, 30656, 30651, 30652, + 30657, 30658, 30649, 30653, 30654, 30650, 30571, 30578, 30579, 30574, + 30575, 30580, 30581, 30572, 30576, 30577, 30573, 30770, 30777, 30778, + 30773, 30774, 30779, 30780, 30771, 30775, 30776, 30772, 30549, 30556, + 30557, 30552, 30553, 30558, 30559, 30550, 30554, 30555, 30551, 30560, + 30567, 30568, 30563, 30564, 30569, 30570, 30561, 30565, 30566, 30562, + 30637, 30644, 30645, 30640, 30641, 30646, 30647, 30638, 30642, 30643, + 30639, 30582, 30589, 30590, 30585, 30586, 30591, 30592, 30583, 30587, + 30588, 30584, 30737, 30744, 30745, 30740, 30741, 30746, 30747, 30738, + 30742, 30743, 30739, 30659, 30667, 30668, 30662, 30663, 30669, 30670, + 30660, 30664, 30665, 30661, 30671, 30678, 30679, 30674, 30675, 30680, + 30681, 30672, 30676, 30677, 30673, 30682, 30689, 30690, 30685, 30686, + 30691, 30692, 30683, 30687, 30688, 30684, 30726, 30733, 30734, 30729, + 30730, 30735, 30736, 30727, 30731, 30732, 30728, 30526, 30527, 30534, + 30535, 30530, 30531, 30536, 30537, 30528, 30532, 30533, 30529, 30666, + 28756, 28754, 28755, 13411, 17710, 17708, 17711, 17709, 17700, 17706, + 17704, 17707, 17705, 17701, 17721, 17717, 17722, 17718, 17702, 17719, + 17715, 17720, 17716, 17703, 17732, 17712, 17714, 17713, 17728, 17731, + 17729, 17724, 17730, 17725, 17726, 17727, 17733, 17723, 17872, 17749, + 17750, 17751, 17748, 17867, 17859, 15860, 15862, 15864, 15861, 15863, + 16853, 16855, 16857, 16854, 16856, 16846, 16845, 16844, 16847, 23097, + 23102, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, 35762, + 35762, 35762, }; -#define code_magic 47 -#define code_size 65536 -#define code_poly 65581 static const unsigned int aliases_start = 0xf0000; static const unsigned int aliases_end = 0xf01d9; diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 3935c00fc26530..0bb5e12d7c3dd9 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -62,7 +62,12 @@ pass */ -#define Py_LIMITED_API 0x030b0000 +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 +#endif #include "Python.h" #include diff --git a/Modules/xxlimited_35.c b/Modules/xxlimited_35.c index 1ff3ef1cb6f296..754a368f77e940 100644 --- a/Modules/xxlimited_35.c +++ b/Modules/xxlimited_35.c @@ -5,7 +5,11 @@ * See the xxlimited module for an extension module template. */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED #define Py_LIMITED_API 0x03050000 +#endif #include "Python.h" @@ -293,7 +297,6 @@ xx_modexec(PyObject *m) static PyModuleDef_Slot xx_slots[] = { {Py_mod_exec, xx_modexec}, - {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index 9b76afa0e56f76..fe9a6d8d4150ab 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -1896,12 +1896,20 @@ zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) Py_BEGIN_ALLOW_THREADS /* Avoid truncation of length for very large buffers. crc32() takes - length as an unsigned int, which may be narrower than Py_ssize_t. */ - while ((size_t)len > UINT_MAX) { - value = crc32(value, buf, UINT_MAX); - buf += (size_t) UINT_MAX; - len -= (size_t) UINT_MAX; + length as an unsigned int, which may be narrower than Py_ssize_t. + We further limit size due to bugs in Apple's macOS zlib. + See /~https://github.com/python/cpython/issues/105967. + */ +#define ZLIB_CRC_CHUNK_SIZE 0x40000000 +#if ZLIB_CRC_CHUNK_SIZE > INT_MAX +# error "unsupported less than 32-bit platform?" +#endif + while ((size_t)len > ZLIB_CRC_CHUNK_SIZE) { + value = crc32(value, buf, ZLIB_CRC_CHUNK_SIZE); + buf += (size_t) ZLIB_CRC_CHUNK_SIZE; + len -= (size_t) ZLIB_CRC_CHUNK_SIZE; } +#undef ZLIB_CRC_CHUNK_SIZE value = crc32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { diff --git a/Objects/abstract.c b/Objects/abstract.c index 55d3b3ada296be..1ec5c5b8c3dc2f 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2,8 +2,10 @@ #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_crossinterp.h" // _Py_CallInInterpreter() #include "pycore_object.h" // _Py_CheckSlotResult() #include "pycore_long.h" // _Py_IsNegative #include "pycore_pyerrors.h" // _PyErr_Occurred() @@ -202,12 +204,7 @@ int PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result) { if (PyDict_CheckExact(obj)) { - *result = PyDict_GetItemWithError(obj, key); /* borrowed */ - if (*result) { - Py_INCREF(*result); - return 1; - } - return PyErr_Occurred() ? -1 : 0; + return PyDict_GetItemRef(obj, key, result); } *result = PyObject_GetItem(obj, key); @@ -806,6 +803,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) { @@ -1162,29 +1180,10 @@ PyNumber_Multiply(PyObject *v, PyObject *w) return result; } -PyObject * -PyNumber_MatrixMultiply(PyObject *v, PyObject *w) -{ - return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@"); -} - -PyObject * -PyNumber_FloorDivide(PyObject *v, PyObject *w) -{ - return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); -} - -PyObject * -PyNumber_TrueDivide(PyObject *v, PyObject *w) -{ - return binary_op(v, w, NB_SLOT(nb_true_divide), "/"); -} - -PyObject * -PyNumber_Remainder(PyObject *v, PyObject *w) -{ - return binary_op(v, w, NB_SLOT(nb_remainder), "%"); -} +BINARY_FUNC(PyNumber_MatrixMultiply, nb_matrix_multiply, "@") +BINARY_FUNC(PyNumber_FloorDivide, nb_floor_divide, "//") +BINARY_FUNC(PyNumber_TrueDivide, nb_true_divide, "/") +BINARY_FUNC(PyNumber_Remainder, nb_remainder, "%") PyObject * PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) @@ -1361,73 +1360,27 @@ _PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs) /* Unary operators and functions */ -PyObject * -PyNumber_Negative(PyObject *o) -{ - if (o == NULL) { - return null_error(); - } - - PyNumberMethods *m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_negative) { - PyObject *res = (*m->nb_negative)(o); - assert(_Py_CheckSlotResult(o, "__neg__", res != NULL)); - return res; - } - - return type_error("bad operand type for unary -: '%.200s'", o); -} - -PyObject * -PyNumber_Positive(PyObject *o) -{ - if (o == NULL) { - return null_error(); - } - - PyNumberMethods *m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_positive) { - PyObject *res = (*m->nb_positive)(o); - assert(_Py_CheckSlotResult(o, "__pos__", res != NULL)); - return res; - } - - return type_error("bad operand type for unary +: '%.200s'", o); -} - -PyObject * -PyNumber_Invert(PyObject *o) -{ - if (o == NULL) { - return null_error(); - } - - PyNumberMethods *m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_invert) { - PyObject *res = (*m->nb_invert)(o); - assert(_Py_CheckSlotResult(o, "__invert__", res != NULL)); - return res; - } - - return type_error("bad operand type for unary ~: '%.200s'", o); -} - -PyObject * -PyNumber_Absolute(PyObject *o) -{ - if (o == NULL) { - return null_error(); - } - - PyNumberMethods *m = Py_TYPE(o)->tp_as_number; - if (m && m->nb_absolute) { - PyObject *res = m->nb_absolute(o); - assert(_Py_CheckSlotResult(o, "__abs__", res != NULL)); - return res; - } - - return type_error("bad operand type for abs(): '%.200s'", o); -} +#define UNARY_FUNC(func, op, meth_name, descr) \ + PyObject * \ + func(PyObject *o) { \ + if (o == NULL) { \ + return null_error(); \ + } \ + \ + PyNumberMethods *m = Py_TYPE(o)->tp_as_number; \ + if (m && m->op) { \ + PyObject *res = (*m->op)(o); \ + assert(_Py_CheckSlotResult(o, #meth_name, res != NULL)); \ + return res; \ + } \ + \ + return type_error("bad operand type for "descr": '%.200s'", o); \ + } + +UNARY_FUNC(PyNumber_Negative, nb_negative, __neg__, "unary -") +UNARY_FUNC(PyNumber_Positive, nb_positive, __pow__, "unary +") +UNARY_FUNC(PyNumber_Invert, nb_invert, __invert__, "unary ~") +UNARY_FUNC(PyNumber_Absolute, nb_absolute, __abs__, "abs()") int @@ -2445,31 +2398,53 @@ PyMapping_HasKeyWithError(PyObject *obj, PyObject *key) } int -PyMapping_HasKeyString(PyObject *o, const char *key) +PyMapping_HasKeyString(PyObject *obj, const char *key) { - PyObject *v; - - v = PyMapping_GetItemString(o, key); - if (v) { - Py_DECREF(v); - return 1; + PyObject *value; + int rc; + if (obj == NULL) { + // For backward compatibility. + // PyMapping_GetOptionalItemString() crashes if obj is NULL. + null_error(); + rc = -1; } - PyErr_Clear(); - return 0; + else { + rc = PyMapping_GetOptionalItemString(obj, key, &value); + } + if (rc < 0) { + PyErr_FormatUnraisable( + "Exception ignored in PyMapping_HasKeyString(); consider using " + "PyMapping_HasKeyStringWithError(), " + "PyMapping_GetOptionalItemString() or PyMapping_GetItemString()"); + return 0; + } + Py_XDECREF(value); + return rc; } int -PyMapping_HasKey(PyObject *o, PyObject *key) +PyMapping_HasKey(PyObject *obj, PyObject *key) { - PyObject *v; - - v = PyObject_GetItem(o, key); - if (v) { - Py_DECREF(v); - return 1; + PyObject *value; + int rc; + if (obj == NULL || key == NULL) { + // For backward compatibility. + // PyMapping_GetOptionalItem() crashes if any of them is NULL. + null_error(); + rc = -1; } - PyErr_Clear(); - return 0; + else { + rc = PyMapping_GetOptionalItem(obj, key, &value); + } + if (rc < 0) { + PyErr_FormatUnraisable( + "Exception ignored in PyMapping_HasKey(); consider using " + "PyMapping_HasKeyWithError(), " + "PyMapping_GetOptionalItem() or PyObject_GetItem()"); + return 0; + } + Py_XDECREF(value); + return rc; } /* This function is quite similar to PySequence_Fast(), but specialized to be diff --git a/Objects/boolobject.c b/Objects/boolobject.c index e2e359437f0edf..fb48dcbeca7850 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -110,9 +110,10 @@ bool_xor(PyObject *a, PyObject *b) /* Doc string */ PyDoc_STRVAR(bool_doc, -"bool(x) -> bool\n\ +"bool(object=False, /)\n\ +--\n\ \n\ -Returns True when the argument x is true, False otherwise.\n\ +Returns True when the argument is true, False otherwise.\n\ The builtins True and False are the only two instances of the class bool.\n\ The class bool is a subclass of the class int, and cannot be subclassed."); diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 67073190cc889d..659de7d3dd5a99 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2007,7 +2007,10 @@ static PyObject * bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/ { - return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); + self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator + PyObject* ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes); + self->ob_exports--; // unexport `self` + return ret; } /*[clinic input] diff --git a/Objects/cellobject.c b/Objects/cellobject.c index f516707f6f8086..f1a43be38b2b58 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -1,6 +1,7 @@ /* Cell object implementation */ #include "Python.h" +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" PyObject * diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index 7039db09721998..d95245067e2608 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, @@ -161,10 +162,6 @@ bytearray_removeprefix(PyByteArrayObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &prefix, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&prefix, 'C')) { - _PyArg_BadArgument("removeprefix", "argument", "contiguous buffer", arg); - goto exit; - } return_value = bytearray_removeprefix_impl(self, &prefix); exit: @@ -201,10 +198,6 @@ bytearray_removesuffix(PyByteArrayObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &suffix, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&suffix, 'C')) { - _PyArg_BadArgument("removesuffix", "argument", "contiguous buffer", arg); - goto exit; - } return_value = bytearray_removesuffix_impl(self, &suffix); exit: @@ -315,17 +308,9 @@ bytearray_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &frm, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&frm, 'C')) { - _PyArg_BadArgument("maketrans", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&to, 'C')) { - _PyArg_BadArgument("maketrans", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = bytearray_maketrans_impl(&frm, &to); exit: @@ -375,17 +360,9 @@ bytearray_replace(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nar if (PyObject_GetBuffer(args[0], &old, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&old, 'C')) { - _PyArg_BadArgument("replace", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&new, 'C')) { - _PyArg_BadArgument("replace", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (nargs < 3) { goto skip_optional; } @@ -1284,4 +1261,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=94b9b5f492b5fed6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0797a5e03cda2a16 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index e2f9ba6c1e55bd..1e45be3e7aefb3 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(bytes___bytes____doc__, "__bytes__($self, /)\n" @@ -140,10 +141,6 @@ bytes_partition(PyBytesObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &sep, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&sep, 'C')) { - _PyArg_BadArgument("partition", "argument", "contiguous buffer", arg); - goto exit; - } return_value = bytes_partition_impl(self, &sep); exit: @@ -183,10 +180,6 @@ bytes_rpartition(PyBytesObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &sep, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&sep, 'C')) { - _PyArg_BadArgument("rpartition", "argument", "contiguous buffer", arg); - goto exit; - } return_value = bytes_rpartition_impl(self, &sep); exit: @@ -502,17 +495,9 @@ bytes_maketrans(void *null, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &frm, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&frm, 'C')) { - _PyArg_BadArgument("maketrans", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&to, 'C')) { - _PyArg_BadArgument("maketrans", "argument 2", "contiguous buffer", args[1]); - goto exit; - } return_value = bytes_maketrans_impl(&frm, &to); exit: @@ -562,17 +547,9 @@ bytes_replace(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs) if (PyObject_GetBuffer(args[0], &old, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&old, 'C')) { - _PyArg_BadArgument("replace", "argument 1", "contiguous buffer", args[0]); - goto exit; - } if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&new, 'C')) { - _PyArg_BadArgument("replace", "argument 2", "contiguous buffer", args[1]); - goto exit; - } if (nargs < 3) { goto skip_optional; } @@ -628,10 +605,6 @@ bytes_removeprefix(PyBytesObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &prefix, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&prefix, 'C')) { - _PyArg_BadArgument("removeprefix", "argument", "contiguous buffer", arg); - goto exit; - } return_value = bytes_removeprefix_impl(self, &prefix); exit: @@ -668,10 +641,6 @@ bytes_removesuffix(PyBytesObject *self, PyObject *arg) if (PyObject_GetBuffer(arg, &suffix, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&suffix, 'C')) { - _PyArg_BadArgument("removesuffix", "argument", "contiguous buffer", arg); - goto exit; - } return_value = bytes_removesuffix_impl(self, &suffix); exit: @@ -1060,4 +1029,4 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=8a9f5c28cbfe7592 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8a49dbbd78914a6f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/classobject.c.h b/Objects/clinic/classobject.c.h index 48cfd6c7b78ca3..3e149c97324a6a 100644 --- a/Objects/clinic/classobject.c.h +++ b/Objects/clinic/classobject.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(method___reduce____doc__, "__reduce__($self, /)\n" "--\n" @@ -80,4 +82,4 @@ instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a0d17bad3b0734d9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a5e3f2d0726f189 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index b20b066f494901..68e2d7f528c061 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" @@ -463,4 +464,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=b9ccfbfabe1a5f46 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d604263a3ca72a0f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h index 788f30d54450f5..49b50304021f7b 100644 --- a/Objects/clinic/complexobject.c.h +++ b/Objects/clinic/complexobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_BadArgument() PyDoc_STRVAR(complex_conjugate__doc__, "conjugate($self, /)\n" @@ -156,4 +157,4 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=002c74f8a33b6697 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=04e6261649967b30 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/descrobject.c.h b/Objects/clinic/descrobject.c.h index 4f18fd77a2c7a0..02fb440d9c83af 100644 --- a/Objects/clinic/descrobject.c.h +++ b/Objects/clinic/descrobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static PyObject * mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); @@ -166,4 +167,4 @@ property_init(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a97dc44d12f9f9b6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a4664ccf3da10f5a input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index eda86c31fcc578..641514235c2341 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(dict_fromkeys__doc__, "fromkeys($type, iterable, value=None, /)\n" "--\n" @@ -191,4 +193,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=582766ac0154c8bf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=17c3c4cf9a9b95a7 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/enumobject.c.h b/Objects/clinic/enumobject.c.h index 97f20c63cd4adf..09774a73c8145c 100644 --- a/Objects/clinic/enumobject.c.h +++ b/Objects/clinic/enumobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(enum_new__doc__, "enumerate(iterable, start=0)\n" @@ -106,4 +107,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=661b29708f501d19 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c48a9a482a52e91 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index c40eff85cf3552..10f6149cc88c22 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(float_is_integer__doc__, "is_integer($self, /)\n" "--\n" @@ -316,4 +318,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=eb093cc601cc5426 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c79743c8551c30d9 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index 1be45674286905..138f87716acbf7 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(func_new__doc__, "function(code, globals, name=None, argdefs=None, closure=None)\n" @@ -103,4 +104,4 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=b2d676ff51c992d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ff7b995500d2bee6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index b6f0c5c0c42dd4..54e6060451f3ff 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(list_insert__doc__, "insert($self, index, object, /)\n" @@ -49,22 +50,22 @@ list_insert(PyListObject *self, PyObject *const *args, Py_ssize_t nargs) return return_value; } -PyDoc_STRVAR(list_clear__doc__, +PyDoc_STRVAR(py_list_clear__doc__, "clear($self, /)\n" "--\n" "\n" "Remove all items from list."); -#define LIST_CLEAR_METHODDEF \ - {"clear", (PyCFunction)list_clear, METH_NOARGS, list_clear__doc__}, +#define PY_LIST_CLEAR_METHODDEF \ + {"clear", (PyCFunction)py_list_clear, METH_NOARGS, py_list_clear__doc__}, static PyObject * -list_clear_impl(PyListObject *self); +py_list_clear_impl(PyListObject *self); static PyObject * -list_clear(PyListObject *self, PyObject *Py_UNUSED(ignored)) +py_list_clear(PyListObject *self, PyObject *Py_UNUSED(ignored)) { - return list_clear_impl(self); + return py_list_clear_impl(self); } PyDoc_STRVAR(list_copy__doc__, @@ -94,14 +95,14 @@ PyDoc_STRVAR(list_append__doc__, #define LIST_APPEND_METHODDEF \ {"append", (PyCFunction)list_append, METH_O, list_append__doc__}, -PyDoc_STRVAR(list_extend__doc__, +PyDoc_STRVAR(py_list_extend__doc__, "extend($self, iterable, /)\n" "--\n" "\n" "Extend list by appending elements from the iterable."); -#define LIST_EXTEND_METHODDEF \ - {"extend", (PyCFunction)list_extend, METH_O, list_extend__doc__}, +#define PY_LIST_EXTEND_METHODDEF \ + {"extend", (PyCFunction)py_list_extend, METH_O, py_list_extend__doc__}, PyDoc_STRVAR(list_pop__doc__, "pop($self, index=-1, /)\n" @@ -383,4 +384,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=e2d9f4092498a5ca input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f2d7b63119464ff4 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 9288648fe3b7c2..4a3d71c6111af5 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static PyObject * long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); @@ -475,4 +476,4 @@ int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) { return int_is_integer_impl(self); } -/*[clinic end generated code: output=009a537ab558763c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7e6e57246e55911f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index 74c749e0b6ccc8..f199434dacb9e8 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(memoryview__doc__, "memoryview(object)\n" @@ -412,4 +413,4 @@ memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs exit: return return_value; } -/*[clinic end generated code: output=7ebdadda3b0fcd35 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7e76a09106921ba2 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index ce21e4728dcb9e..3c0bbe22d5ebab 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(module___init____doc__, "module(name, doc=None)\n" @@ -73,4 +74,4 @@ module___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=9d3d7854d17a033c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e8a71bfbed774c15 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h index 643f504535d257..5ef5380656905a 100644 --- a/Objects/clinic/odictobject.c.h +++ b/Objects/clinic/odictobject.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "fromkeys($type, /, iterable, value=None)\n" @@ -331,4 +332,4 @@ OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=6d7ae9fb552c6108 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=eff78d2a3f9379bd input=a9049054013a1b77]*/ diff --git a/Objects/clinic/structseq.c.h b/Objects/clinic/structseq.c.h index 2571888454cb79..cec49ebccccb24 100644 --- a/Objects/clinic/structseq.c.h +++ b/Objects/clinic/structseq.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); @@ -61,4 +62,4 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=2f88fe2a6f5c13a8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5bf39b3f06a34ce4 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/tupleobject.c.h b/Objects/clinic/tupleobject.c.h index f21712746a5ad1..5d6a2c481a5f2a 100644 --- a/Objects/clinic/tupleobject.c.h +++ b/Objects/clinic/tupleobject.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(tuple_index__doc__, "index($self, value, start=0, stop=sys.maxsize, /)\n" "--\n" @@ -112,4 +114,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) { return tuple___getnewargs___impl(self); } -/*[clinic end generated code: output=7c5d9d12e0cf6a83 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a6a9abba5d121f4c input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typeobject.c.h b/Objects/clinic/typeobject.c.h index eb0b22a943ae8f..1fa153598db213 100644 --- a/Objects/clinic/typeobject.c.h +++ b/Objects/clinic/typeobject.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_BadArgument() + PyDoc_STRVAR(type___instancecheck____doc__, "__instancecheck__($self, instance, /)\n" "--\n" @@ -260,4 +262,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=943f639f264362d9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b56c87f9cace1921 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typevarobject.c.h b/Objects/clinic/typevarobject.c.h index 4762cd63545b60..2bb0a98a2ed64c 100644 --- a/Objects/clinic/typevarobject.c.h +++ b/Objects/clinic/typevarobject.c.h @@ -6,9 +6,10 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywordsWithVararg() PyDoc_STRVAR(typevar_new__doc__, -"typevar(name, *constraints, *, bound=None, covariant=False,\n" +"typevar(name, *constraints, bound=None, covariant=False,\n" " contravariant=False, infer_variance=False)\n" "--\n" "\n" @@ -590,4 +591,4 @@ typealias_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=db0b327ebbb1488f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a582d9d89ad787b input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 42b8a3c69cad8a..7711434f17c2bc 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(EncodingMap_size__doc__, "size($self, /)\n" @@ -1504,4 +1505,4 @@ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=4acdcfdc93f2a0f6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=873d8b3d09af3095 input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index f662b8e354bb1e..dc46b773c26528 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -7,13 +7,12 @@ #include "pycore_frame.h" // FRAME_SPECIALS_SIZE #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs #include "pycore_opcode_metadata.h" // _PyOpcode_Deopt, _PyOpcode_Caches +#include "pycore_opcode_utils.h" // RESUME_AT_FUNC_START #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "clinic/codeobject.c.h" -static PyObject* code_repr(PyCodeObject *co); - static const char * code_event_name(PyCodeEvent event) { switch (event) { @@ -41,21 +40,9 @@ notify_code_watchers(PyCodeEvent event, PyCodeObject *co) // callback must be non-null if the watcher bit is set assert(cb != NULL); if (cb(event, co) < 0) { - // Don't risk resurrecting the object if an unraisablehook keeps - // a reference; pass a string as context. - PyObject *context = NULL; - PyObject *repr = code_repr(co); - if (repr) { - context = PyUnicode_FromFormat( - "%s watcher callback for %U", - code_event_name(event), repr); - Py_DECREF(repr); - } - if (context == NULL) { - context = Py_NewRef(Py_None); - } - PyErr_WriteUnraisable(context); - Py_DECREF(context); + PyErr_FormatUnraisable( + "Exception ignored in %s watcher callback for %R", + code_event_name(event), co); } } i++; @@ -656,6 +643,35 @@ PyUnstable_Code_NewWithPosOnlyArgs( _Py_set_localsplus_info(offset, name, CO_FAST_FREE, localsplusnames, localspluskinds); } + + // gh-110543: Make sure the CO_FAST_HIDDEN flag is set correctly. + if (!(flags & CO_OPTIMIZED)) { + Py_ssize_t code_len = PyBytes_GET_SIZE(code); + _Py_CODEUNIT *code_data = (_Py_CODEUNIT *)PyBytes_AS_STRING(code); + Py_ssize_t num_code_units = code_len / sizeof(_Py_CODEUNIT); + int extended_arg = 0; + for (int i = 0; i < num_code_units; i += 1 + _PyOpcode_Caches[code_data[i].op.code]) { + _Py_CODEUNIT *instr = &code_data[i]; + uint8_t opcode = instr->op.code; + if (opcode == EXTENDED_ARG) { + extended_arg = extended_arg << 8 | instr->op.arg; + continue; + } + if (opcode == LOAD_FAST_AND_CLEAR) { + int oparg = extended_arg << 8 | instr->op.arg; + if (oparg >= nlocalsplus) { + PyErr_Format(PyExc_ValueError, + "code: LOAD_FAST_AND_CLEAR oparg %d out of range", + oparg); + goto error; + } + _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, oparg); + _PyLocals_SetKind(localspluskinds, oparg, kind | CO_FAST_HIDDEN); + } + extended_arg = 0; + } + } + // If any cells were args then nlocalsplus will have shrunk. if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) { if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0 @@ -733,7 +749,7 @@ PyUnstable_Code_New(int argcount, int kwonlyargcount, // test.test_code.CodeLocationTest.test_code_new_empty to keep it in sync! static const uint8_t assert0[6] = { - RESUME, 0, + RESUME, RESUME_AT_FUNC_START, LOAD_ASSERTION_ERROR, 0, RAISE_VARARGS, 1 }; diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 56ce34f80ca8e9..57921b110591e5 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -6,6 +6,7 @@ #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_modsupport.h" // _PyArg_UnpackStack() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() @@ -1540,6 +1541,9 @@ property_deleter(PyObject *self, PyObject *deleter) PyDoc_STRVAR(set_name_doc, + "__set_name__($self, owner, name, /)\n" + "--\n" + "\n" "Method to set name of a property."); static PyObject * diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 1fb795f5097897..70f424e07ece9a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -117,7 +117,7 @@ As a consequence of this, split keys have a maximum size of 16. #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_code.h" // stats -#include "pycore_dict.h" // PyDictKeysObject +#include "pycore_dict.h" // export _PyDict_SizeOf() #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() @@ -1663,8 +1663,8 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, * function hits a stack-depth error, which can cause this to return NULL * even if the key is present. */ -PyObject * -PyDict_GetItem(PyObject *op, PyObject *key) +static PyObject * +dict_getitem(PyObject *op, PyObject *key, const char *warnmsg) { if (!PyDict_Check(op)) { return NULL; @@ -1675,7 +1675,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { - PyErr_Clear(); + PyErr_FormatUnraisable(warnmsg); return NULL; } } @@ -1696,12 +1696,24 @@ PyDict_GetItem(PyObject *op, PyObject *key) ix = _Py_dict_lookup(mp, key, hash, &value); /* Ignore any exception raised by the lookup */ + PyObject *exc2 = _PyErr_Occurred(tstate); + if (exc2 && !PyErr_GivenExceptionMatches(exc2, PyExc_KeyError)) { + PyErr_FormatUnraisable(warnmsg); + } _PyErr_SetRaisedException(tstate, exc); assert(ix >= 0 || value == NULL); return value; // borrowed reference } +PyObject * +PyDict_GetItem(PyObject *op, PyObject *key) +{ + return dict_getitem(op, key, + "Exception ignored in PyDict_GetItem(); consider using " + "PyDict_GetItemRef() or PyDict_GetItemWithError()"); +} + Py_ssize_t _PyDict_LookupIndex(PyDictObject *mp, PyObject *key) { @@ -1830,6 +1842,20 @@ _PyDict_GetItemIdWithError(PyObject *dp, _Py_Identifier *key) return _PyDict_GetItem_KnownHash(dp, kv, hash); // borrowed reference } +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; +} + + /* Fast version of global value lookup (LOAD_GLOBAL). * Lookup in globals, then builtins. * @@ -2214,64 +2240,119 @@ PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) return _PyDict_Next(op, ppos, pkey, pvalue, NULL); } + /* Internal version of dict.pop(). */ -PyObject * -_PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *deflt) +int +_PyDict_Pop_KnownHash(PyDictObject *mp, PyObject *key, Py_hash_t hash, + PyObject **result) { - Py_ssize_t ix; - PyObject *old_value; - PyDictObject *mp; - PyInterpreterState *interp = _PyInterpreterState_GET(); - - assert(PyDict_Check(dict)); - mp = (PyDictObject *)dict; + assert(PyDict_Check(mp)); if (mp->ma_used == 0) { - if (deflt) { - return Py_NewRef(deflt); + if (result) { + *result = NULL; } - _PyErr_SetKeyError(key); - return NULL; + return 0; } - ix = _Py_dict_lookup(mp, key, hash, &old_value); - if (ix == DKIX_ERROR) - return NULL; + + PyObject *old_value; + Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &old_value); + if (ix == DKIX_ERROR) { + if (result) { + *result = NULL; + } + return -1; + } + if (ix == DKIX_EMPTY || old_value == NULL) { - if (deflt) { - return Py_NewRef(deflt); + if (result) { + *result = NULL; } - _PyErr_SetKeyError(key); - return NULL; + return 0; } + assert(old_value != NULL); + PyInterpreterState *interp = _PyInterpreterState_GET(); uint64_t new_version = _PyDict_NotifyEvent( interp, PyDict_EVENT_DELETED, mp, key, NULL); delitem_common(mp, hash, ix, Py_NewRef(old_value), new_version); ASSERT_CONSISTENT(mp); - return old_value; + if (result) { + *result = old_value; + } + else { + Py_DECREF(old_value); + } + return 1; } -PyObject * -_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) + +int +PyDict_Pop(PyObject *op, PyObject *key, PyObject **result) { - Py_hash_t hash; + if (!PyDict_Check(op)) { + if (result) { + *result = NULL; + } + PyErr_BadInternalCall(); + return -1; + } + PyDictObject *dict = (PyDictObject *)op; - if (((PyDictObject *)dict)->ma_used == 0) { - if (deflt) { - return Py_NewRef(deflt); + if (dict->ma_used == 0) { + if (result) { + *result = NULL; } - _PyErr_SetKeyError(key); - return NULL; + return 0; } + + Py_hash_t hash; if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); - if (hash == -1) - return NULL; + if (hash == -1) { + if (result) { + *result = NULL; + } + return -1; + } + } + return _PyDict_Pop_KnownHash(dict, key, hash, result); +} + + +int +PyDict_PopString(PyObject *op, const char *key, PyObject **result) +{ + PyObject *key_obj = PyUnicode_FromString(key); + if (key_obj == NULL) { + if (result != NULL) { + *result = NULL; + } + return -1; } - return _PyDict_Pop_KnownHash(dict, key, hash, deflt); + + int res = PyDict_Pop(op, key_obj, result); + Py_DECREF(key_obj); + return res; } + +PyObject * +_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value) +{ + PyObject *result; + if (PyDict_Pop(dict, key, &result) == 0) { + if (default_value != NULL) { + return Py_NewRef(default_value); + } + _PyErr_SetKeyError(key); + return NULL; + } + return result; +} + + /* Internal version of dict.from_keys(). It is subclass-friendly. */ PyObject * _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) @@ -3925,10 +4006,14 @@ PyDict_GetItemString(PyObject *v, const char *key) PyObject *kv, *rv; kv = PyUnicode_FromString(key); if (kv == NULL) { - PyErr_Clear(); + PyErr_FormatUnraisable( + "Exception ignored in PyDict_GetItemString(); consider using " + "PyDict_GetItemRefString()"); return NULL; } - rv = PyDict_GetItem(v, kv); + rv = dict_getitem(v, kv, + "Exception ignored in PyDict_GetItemString(); consider using " + "PyDict_GetItemRefString()"); Py_DECREF(kv); return rv; // borrowed reference } @@ -5649,7 +5734,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) { @@ -5672,7 +5757,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) { @@ -5912,14 +5997,9 @@ _PyDict_SendEvent(int watcher_bits, // unraisablehook keep a reference to it, so we don't pass the // dict as context, just an informative string message. Dict // repr can call arbitrary code, so we invent a simpler version. - PyObject *context = PyUnicode_FromFormat( - "%s watcher callback for ", + PyErr_FormatUnraisable( + "Exception ignored in %s watcher callback for ", dict_event_name(event), mp); - if (context == NULL) { - context = Py_NewRef(Py_None); - } - PyErr_WriteUnraisable(context); - Py_DECREF(context); } } watcher_bits >>= 1; diff --git a/Objects/exceptions.c b/Objects/exceptions.c index a2f53c69eb5bcb..4b7ec6b58fc789 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -8,10 +8,11 @@ #include #include "pycore_abstract.h" // _PyObject_RealIsSubclass() #include "pycore_ceval.h" // _Py_EnterRecursiveCall -#include "pycore_pyerrors.h" // struct _PyErr_SetRaisedException #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_initconfig.h" +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" +#include "pycore_pyerrors.h" // struct _PyErr_SetRaisedException #include "osdefs.h" // SEP @@ -875,13 +876,9 @@ BaseExceptionGroup_str(PyBaseExceptionGroupObject *self) } static PyObject * -BaseExceptionGroup_derive(PyObject *self_, PyObject *args) +BaseExceptionGroup_derive(PyObject *self_, PyObject *excs) { PyBaseExceptionGroupObject *self = _PyBaseExceptionGroupObject_cast(self_); - PyObject *excs = NULL; - if (!PyArg_ParseTuple(args, "O", &excs)) { - return NULL; - } PyObject *init_args = PyTuple_Pack(2, self->msg, excs); if (!init_args) { return NULL; @@ -1175,13 +1172,8 @@ exceptiongroup_split_recursive(PyObject *exc, } static PyObject * -BaseExceptionGroup_split(PyObject *self, PyObject *args) +BaseExceptionGroup_split(PyObject *self, PyObject *matcher_value) { - PyObject *matcher_value = NULL; - if (!PyArg_UnpackTuple(args, "split", 1, 1, &matcher_value)) { - return NULL; - } - _exceptiongroup_split_matcher_type matcher_type; if (get_matcher_type(matcher_value, &matcher_type) < 0) { return NULL; @@ -1206,13 +1198,8 @@ BaseExceptionGroup_split(PyObject *self, PyObject *args) } static PyObject * -BaseExceptionGroup_subgroup(PyObject *self, PyObject *args) +BaseExceptionGroup_subgroup(PyObject *self, PyObject *matcher_value) { - PyObject *matcher_value = NULL; - if (!PyArg_UnpackTuple(args, "subgroup", 1, 1, &matcher_value)) { - return NULL; - } - _exceptiongroup_split_matcher_type matcher_type; if (get_matcher_type(matcher_value, &matcher_type) < 0) { return NULL; @@ -1487,9 +1474,9 @@ static PyMemberDef BaseExceptionGroup_members[] = { static PyMethodDef BaseExceptionGroup_methods[] = { {"__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, - {"derive", (PyCFunction)BaseExceptionGroup_derive, METH_VARARGS}, - {"split", (PyCFunction)BaseExceptionGroup_split, METH_VARARGS}, - {"subgroup", (PyCFunction)BaseExceptionGroup_subgroup, METH_VARARGS}, + {"derive", (PyCFunction)BaseExceptionGroup_derive, METH_O}, + {"split", (PyCFunction)BaseExceptionGroup_split, METH_O}, + {"subgroup", (PyCFunction)BaseExceptionGroup_subgroup, METH_O}, {NULL} }; @@ -3695,10 +3682,6 @@ _PyExc_FiniTypes(PyInterpreterState *interp) PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - if (preallocate_memerrors() < 0) { return _PyStatus_NO_MEMORY(); } diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 066172baf9f027..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 */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 776c7092edd057..364cf1553bb5d4 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -646,7 +646,7 @@ float_rem(PyObject *v, PyObject *w) CONVERT_TO_DOUBLE(w, wx); if (wx == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "float modulo"); + "float modulo by zero"); return NULL; } mod = fmod(vx, wx); diff --git a/Objects/frame_layout.md b/Objects/frame_layout.md index 2f95214db56498..b348e85689f507 100644 --- a/Objects/frame_layout.md +++ b/Objects/frame_layout.md @@ -130,3 +130,28 @@ returns. This extra frame is inserted so that `RETURN_VALUE`, `YIELD_VALUE`, and `RETURN_GENERATOR` do not need to check whether the current frame is the entry frame. The shim frame points to a special code object containing the `INTERPRETER_EXIT` instruction which cleans up the shim frame and returns. + + +### The Instruction Pointer + +`_PyInterpreterFrame` has two fields which are used to maintain the instruction +pointer: `instr_ptr` and `return_offset`. + +When a frame is executing, `instr_ptr` points to the instruction currently being +executed. In a suspended frame, it points to the instruction that would execute +if the frame were to resume. After `frame.f_lineno` is set, `instr_ptr` points to +the next instruction to be executed. During a call to a python function, +`instr_ptr` points to the call instruction, because this is what we would expect +to see in an exception traceback. + +The `return_offset` field determines where a `RETURN` should go in the caller, +relative to `instr_ptr`. It is only meaningful to the callee, so it needs to +be set in any instruction that implements a call (to a Python function), +including CALL, SEND and BINARY_SUBSCR_GETITEM, among others. If there is no +callee, then return_offset is meaningless. It is necessary to have a separate +field for the return offset because (1) if we apply this offset to `instr_ptr` +while executing the `RETURN`, this is too early and would lose us information +about the previous instruction which we could need for introspecting and +debugging. (2) `SEND` needs to pass two offsets to the generator: one for +`RETURN` and one for `YIELD`. It uses the `oparg` for one, and the +`return_offset` for the other. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index d75444393f3697..be330a775872c2 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -127,10 +127,13 @@ frame_settrace_opcodes(PyFrameObject *f, PyObject* value, void *Py_UNUSED(ignore } if (value == Py_True) { f->f_trace_opcodes = 1; - _PyInterpreterState_GET()->f_opcode_trace_set = true; + if (f->f_trace) { + return _PyEval_SetOpcodeTrace(f, true); + } } else { f->f_trace_opcodes = 0; + return _PyEval_SetOpcodeTrace(f, false); } return 0; } @@ -329,6 +332,8 @@ mark_stacks(PyCodeObject *code_obj, int len) switch (opcode) { case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: + case POP_JUMP_IF_NONE: + case POP_JUMP_IF_NOT_NONE: { int64_t target_stack; int j = next_i + oparg; @@ -606,7 +611,7 @@ 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 FRAME_STATE_SUSPENDED(gen->gi_frame_state); } return false; } @@ -803,13 +808,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore while (start_stack > best_stack) { if (top_of_stack(start_stack) == Except) { /* Pop exception stack as well as the evaluation stack */ - PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_StackItem *exc_info = tstate->exc_info; - PyObject *value = exc_info->exc_value; PyObject *exc = _PyFrame_StackPop(f->f_frame); assert(PyExceptionInstance_Check(exc) || exc == Py_None); - exc_info->exc_value = exc; - Py_XDECREF(value); + PyThreadState *tstate = _PyThreadState_GET(); + Py_XSETREF(tstate->exc_info->exc_value, exc); } else { PyObject *v = _PyFrame_StackPop(f->f_frame); @@ -819,7 +821,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore } /* Finally set the new lasti and return OK. */ f->f_lineno = 0; - f->f_frame->prev_instr = _PyCode_CODE(code) + best_addr; + f->f_frame->instr_ptr = _PyCode_CODE(code) + best_addr; return 0; } @@ -840,6 +842,9 @@ frame_settrace(PyFrameObject *f, PyObject* v, void *closure) } if (v != f->f_trace) { Py_XSETREF(f->f_trace, Py_XNewRef(v)); + if (v != NULL && f->f_trace_opcodes) { + return _PyEval_SetOpcodeTrace(f, true); + } } return 0; } @@ -932,6 +937,9 @@ frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) if (gen->gi_frame_state == FRAME_EXECUTING) { goto running; } + if (FRAME_STATE_SUSPENDED(gen->gi_frame_state)) { + goto suspended; + } _PyGen_Finalize((PyObject *)gen); } else if (f->f_frame->owner == FRAME_OWNED_BY_THREAD) { @@ -946,6 +954,10 @@ frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) PyErr_SetString(PyExc_RuntimeError, "cannot clear an executing frame"); return NULL; +suspended: + PyErr_SetString(PyExc_RuntimeError, + "cannot clear a suspended frame"); + return NULL; } PyDoc_STRVAR(clear__doc__, @@ -1077,7 +1089,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; f->f_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; // This frame needs to be "complete", so pretend that the first RESUME ran: - f->f_frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; + f->f_frame->instr_ptr = _PyCode_CODE(code) + code->_co_firsttraceable + 1; assert(!_PyFrame_IsIncomplete(f->f_frame)); Py_DECREF(func); _PyObject_GC_TRACK(f); @@ -1091,7 +1103,7 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) assert(_PyOpcode_Deopt[opcode] == opcode); int check_oparg = 0; for (_Py_CODEUNIT *instruction = _PyCode_CODE(_PyFrame_GetCode(frame)); - instruction < frame->prev_instr; instruction++) + instruction < frame->instr_ptr; instruction++) { int check_opcode = _PyOpcode_Deopt[instruction->op.code]; check_oparg |= instruction->op.arg; @@ -1133,7 +1145,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame) frame->localsplus[offset + i] = Py_NewRef(o); } // COPY_FREE_VARS doesn't have inline CACHEs, either: - frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)); + frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)); } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 231a9c141d0c0b..4d88dd2229295d 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -3,12 +3,11 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_Occurred() -static PyObject* func_repr(PyFunctionObject *op); - static const char * func_event_name(PyFunction_WatchEvent event) { switch (event) { @@ -34,21 +33,9 @@ notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event, // callback must be non-null if the watcher bit is set assert(cb != NULL); if (cb(event, func, new_value) < 0) { - // Don't risk resurrecting the func if an unraisablehook keeps a - // reference; pass a string as context. - PyObject *context = NULL; - PyObject *repr = func_repr(func); - if (repr != NULL) { - context = PyUnicode_FromFormat( - "%s watcher callback for %U", - func_event_name(event), repr); - Py_DECREF(repr); - } - if (context == NULL) { - context = Py_NewRef(Py_None); - } - PyErr_WriteUnraisable(context); - Py_DECREF(context); + PyErr_FormatUnraisable( + "Exception ignored in %s watcher callback for function %U at %p", + func_event_name(event), func->func_qualname, func); } } i++; @@ -105,8 +92,8 @@ PyFunction_ClearWatcher(int watcher_id) PyFunctionObject * _PyFunction_FromConstructor(PyFrameConstructor *constr) { - PyObject *module = Py_XNewRef(PyDict_GetItemWithError(constr->fc_globals, &_Py_ID(__name__))); - if (!module && PyErr_Occurred()) { + PyObject *module; + if (PyDict_GetItemRef(constr->fc_globals, &_Py_ID(__name__), &module) < 0) { return NULL; } @@ -171,12 +158,11 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname Py_INCREF(doc); // __module__: Use globals['__name__'] if it exists, or NULL. - PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); + PyObject *module; PyObject *builtins = NULL; - if (module == NULL && _PyErr_Occurred(tstate)) { + if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &module) < 0) { goto error; } - Py_XINCREF(module); builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref if (builtins == NULL) { @@ -288,7 +274,7 @@ _PyFunction_LookupByVersion(uint32_t version) PyFunctionObject *func = interp->func_state.func_version_cache[ version % FUNC_VERSION_CACHE_SIZE]; if (func != NULL && func->func_version == version) { - return (PyFunctionObject *)Py_NewRef(func); + return func; } return NULL; } @@ -570,6 +556,20 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) nclosure, nfree); return -1; } + + PyObject *func_code = PyFunction_GET_CODE(op); + int old_flags = ((PyCodeObject *)func_code)->co_flags; + int new_flags = ((PyCodeObject *)value)->co_flags; + int mask = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR; + if ((old_flags & mask) != (new_flags & mask)) { + if (PyErr_Warn(PyExc_DeprecationWarning, + "Assigning a code object of non-matching type is deprecated " + "(e.g., from a generator to a plain function)") < 0) + { + return -1; + } + } + handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value); _PyFunction_SetVersion(op, 0); Py_XSETREF(op->func_code, Py_NewRef(value)); @@ -1109,10 +1109,6 @@ cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) } if (type == NULL) type = (PyObject *)(Py_TYPE(obj)); - if (Py_TYPE(cm->cm_callable)->tp_descr_get != NULL) { - return Py_TYPE(cm->cm_callable)->tp_descr_get(cm->cm_callable, type, - type); - } return PyMethod_New(cm->cm_callable, type); } @@ -1167,7 +1163,8 @@ cm_repr(classmethod *cm) } PyDoc_STRVAR(classmethod_doc, -"classmethod(function) -> method\n\ +"classmethod(function, /)\n\ +--\n\ \n\ Convert a function to be a class method.\n\ \n\ @@ -1362,7 +1359,8 @@ sm_repr(staticmethod *sm) } PyDoc_STRVAR(staticmethod_doc, -"staticmethod(function) -> method\n\ +"staticmethod(function, /)\n\ +--\n\ \n\ Convert a function to be a static method.\n\ \n\ diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index bf13ed3650bac5..c045d495e85526 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_GetBuiltin() +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" #include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check diff --git a/Objects/genobject.c b/Objects/genobject.c index 40033d10bea9ee..9614713883741c 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -7,12 +7,12 @@ #include "pycore_ceval.h" // _PyEval_EvalFrame() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_genobject.h" // struct _Py_async_gen_state +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "opcode.h" // SEND -#include "frameobject.h" // _PyInterpreterFrame_GetLine #include "pystats.h" static PyObject *gen_close(PyGenObject *, PyObject *); @@ -40,19 +40,12 @@ PyGen_GetCode(PyGenObject *gen) { return res; } -static inline int -exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) -{ - Py_VISIT(exc_state->exc_value); - return 0; -} - static int gen_traverse(PyGenObject *gen, visitproc visit, void *arg) { Py_VISIT(gen->gi_name); Py_VISIT(gen->gi_qualname); - if (gen->gi_frame_state < FRAME_CLEARED) { + if (gen->gi_frame_state != FRAME_CLEARED) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe); assert(frame->frame_obj == NULL || frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR); @@ -63,7 +56,8 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) } /* No need to visit cr_origin, because it's just tuples/str/int, so can't participate in a reference cycle. */ - return exc_state_traverse(&gen->gi_exc_state, visit, arg); + Py_VISIT(gen->gi_exc_state.exc_value); + return 0; } void @@ -71,7 +65,7 @@ _PyGen_Finalize(PyObject *self) { PyGenObject *gen = (PyGenObject *)self; - if (gen->gi_frame_state >= FRAME_COMPLETED) { + if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { /* Generator isn't paused, so no need to close */ return; } @@ -144,7 +138,7 @@ gen_dealloc(PyGenObject *gen) and GC_Del. */ Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer); } - if (gen->gi_frame_state < FRAME_CLEARED) { + if (gen->gi_frame_state != FRAME_CLEARED) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; gen->gi_frame_state = FRAME_CLEARED; frame->previous = NULL; @@ -168,7 +162,6 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, { PyThreadState *tstate = _PyThreadState_GET(); _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - PyObject *result; *presult = NULL; if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) { @@ -195,7 +188,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, PyErr_SetString(PyExc_ValueError, msg); return PYGEN_ERROR; } - if (gen->gi_frame_state >= FRAME_COMPLETED) { + if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { if (PyCoro_CheckExact(gen) && !closing) { /* `gen` is an exhausted coroutine: raise an error, except when called from gen_close(), which should @@ -213,10 +206,12 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, return PYGEN_ERROR; } - assert(gen->gi_frame_state < FRAME_EXECUTING); + assert((gen->gi_frame_state == FRAME_CREATED) || + FRAME_STATE_SUSPENDED(gen->gi_frame_state)); + /* Push arg onto the frame's value stack */ - result = arg ? arg : Py_None; - _PyFrame_StackPush(frame, Py_NewRef(result)); + PyObject *arg_obj = arg ? arg : Py_None; + _PyFrame_StackPush(frame, Py_NewRef(arg_obj)); _PyErr_StackItem *prev_exc_info = tstate->exc_info; gen->gi_exc_state.previous_item = prev_exc_info; @@ -229,7 +224,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, gen->gi_frame_state = FRAME_EXECUTING; EVAL_CALL_STAT_INC(EVAL_CALL_GENERATOR); - result = _PyEval_EvalFrame(tstate, frame, exc); + PyObject *result = _PyEval_EvalFrame(tstate, frame, exc); assert(tstate->exc_info == prev_exc_info); assert(gen->gi_exc_state.previous_item == NULL); assert(gen->gi_frame_state != FRAME_EXECUTING); @@ -238,7 +233,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ if (result) { - if (gen->gi_frame_state == FRAME_SUSPENDED) { + if (FRAME_STATE_SUSPENDED(gen->gi_frame_state)) { *presult = result; return PYGEN_NEXT; } @@ -340,53 +335,33 @@ is_resume(_Py_CODEUNIT *instr) ); } -static inline bool -is_yield(_Py_CODEUNIT *instr) -{ - return instr->op.code == YIELD_VALUE || instr->op.code == INSTRUMENTED_YIELD_VALUE; -} - PyObject * _PyGen_yf(PyGenObject *gen) { - PyObject *yf = NULL; - - if (gen->gi_frame_state < FRAME_CLEARED) { + if (gen->gi_frame_state == FRAME_SUSPENDED_YIELD_FROM) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - - if (gen->gi_frame_state == FRAME_CREATED) { - /* Return immediately if the frame didn't start yet. SEND - always come after LOAD_CONST: a code object should not start - with SEND */ - assert(_PyCode_CODE(_PyGen_GetCode(gen))[0].op.code != SEND); - return NULL; - } - _Py_CODEUNIT next = frame->prev_instr[1]; - if (!is_resume(&next) || next.op.arg < 2) - { - /* Not in a yield from */ - return NULL; - } - yf = Py_NewRef(_PyFrame_StackPeek(frame)); + assert(is_resume(frame->instr_ptr)); + assert((frame->instr_ptr->op.arg & RESUME_OPARG_LOCATION_MASK) >= RESUME_AFTER_YIELD_FROM); + return Py_NewRef(_PyFrame_StackPeek(frame)); } - - return yf; + return NULL; } static PyObject * gen_close(PyGenObject *gen, PyObject *args) { PyObject *retval; - PyObject *yf = _PyGen_yf(gen); int err = 0; + if (gen->gi_frame_state == FRAME_CREATED) { gen->gi_frame_state = FRAME_COMPLETED; Py_RETURN_NONE; } - if (gen->gi_frame_state >= FRAME_COMPLETED) { + if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { Py_RETURN_NONE; } + PyObject *yf = _PyGen_yf(gen); if (yf) { PyFrameState state = gen->gi_frame_state; gen->gi_frame_state = FRAME_EXECUTING; @@ -395,16 +370,15 @@ gen_close(PyGenObject *gen, PyObject *args) Py_DECREF(yf); } _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - /* It is possible for the previous instruction to not be a - * YIELD_VALUE if the debugger has changed the lineno. */ - if (err == 0 && is_yield(frame->prev_instr)) { - assert(is_resume(frame->prev_instr + 1)); - int exception_handler_depth = frame->prev_instr[0].op.code; - assert(exception_handler_depth > 0); + if (is_resume(frame->instr_ptr)) { /* We can safely ignore the outermost try block - * as it automatically generated to handle + * as it is automatically generated to handle * StopIteration. */ - if (exception_handler_depth == 1) { + int oparg = frame->instr_ptr->op.arg; + if (oparg & RESUME_OPARG_DEPTH1_MASK) { + // RESUME after YIELD_VALUE and exception depth is 1 + assert((oparg & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START); + gen->gi_frame_state = FRAME_COMPLETED; Py_RETURN_NONE; } } @@ -749,7 +723,7 @@ gen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored)) static PyObject * gen_getsuspended(PyGenObject *gen, void *Py_UNUSED(ignored)) { - return PyBool_FromLong(gen->gi_frame_state == FRAME_SUSPENDED); + return PyBool_FromLong(FRAME_STATE_SUSPENDED(gen->gi_frame_state)); } static PyObject * @@ -758,7 +732,7 @@ _gen_getframe(PyGenObject *gen, const char *const name) if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { return NULL; } - if (gen->gi_frame_state == FRAME_CLEARED) { + if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { Py_RETURN_NONE; } return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe)); @@ -1104,7 +1078,7 @@ coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored)) static PyObject * cr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored)) { - if (coro->cr_frame_state == FRAME_SUSPENDED) { + if (FRAME_STATE_SUSPENDED(coro->cr_frame_state)) { Py_RETURN_TRUE; } Py_RETURN_FALSE; @@ -1541,7 +1515,7 @@ ag_getcode(PyGenObject *gen, void *Py_UNUSED(ignored)) static PyObject * ag_getsuspended(PyAsyncGenObject *ag, void *Py_UNUSED(ignored)) { - if (ag->ag_frame_state == FRAME_SUSPENDED) { + if (FRAME_STATE_SUSPENDED(ag->ag_frame_state)) { Py_RETURN_TRUE; } Py_RETURN_FALSE; @@ -2113,7 +2087,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) return NULL; } - if (gen->gi_frame_state >= FRAME_COMPLETED) { + if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetNone(PyExc_StopIteration); return NULL; diff --git a/Objects/listobject.c b/Objects/listobject.c index ad1840b01226ec..2d04218439bd20 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -592,26 +592,33 @@ list_repeat(PyListObject *a, Py_ssize_t n) return (PyObject *) np; } -static int -_list_clear(PyListObject *a) +static void +list_clear(PyListObject *a) { - Py_ssize_t i; - PyObject **item = a->ob_item; - if (item != NULL) { - /* Because XDECREF can recursively invoke operations on - this list, we make it empty first. */ - i = Py_SIZE(a); - Py_SET_SIZE(a, 0); - a->ob_item = NULL; - a->allocated = 0; - while (--i >= 0) { - Py_XDECREF(item[i]); - } - PyMem_Free(item); + PyObject **items = a->ob_item; + if (items == NULL) { + return; + } + + /* Because XDECREF can recursively invoke operations on + this list, we make it empty first. */ + Py_ssize_t i = Py_SIZE(a); + Py_SET_SIZE(a, 0); + a->ob_item = NULL; + a->allocated = 0; + while (--i >= 0) { + Py_XDECREF(items[i]); } - /* Never fails; the return value can be ignored. - Note that there is no guarantee that the list is actually empty - at this point, because XDECREF may have populated it again! */ + PyMem_Free(items); + + // Note that there is no guarantee that the list is actually empty + // at this point, because XDECREF may have populated it indirectly again! +} + +static int +list_clear_slot(PyListObject *self) +{ + list_clear(self); return 0; } @@ -675,7 +682,8 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) d = n - norig; if (Py_SIZE(a) + d == 0) { Py_XDECREF(v_as_SF); - return _list_clear(a); + list_clear(a); + return 0; } item = a->ob_item; /* recycle the items that we are about to remove */ @@ -745,7 +753,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n) } if (n < 1) { - (void)_list_clear(self); + list_clear(self); return Py_NewRef(self); } @@ -801,16 +809,16 @@ list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object) } /*[clinic input] -list.clear +list.clear as py_list_clear Remove all items from list. [clinic start generated code]*/ static PyObject * -list_clear_impl(PyListObject *self) -/*[clinic end generated code: output=67a1896c01f74362 input=ca3c1646856742f6]*/ +py_list_clear_impl(PyListObject *self) +/*[clinic end generated code: output=83726743807e3518 input=378711e10f545c53]*/ { - _list_clear(self); + list_clear(self); Py_RETURN_NONE; } @@ -846,83 +854,61 @@ list_append(PyListObject *self, PyObject *object) Py_RETURN_NONE; } -/*[clinic input] -list.extend - - iterable: object - / - -Extend list by appending elements from the iterable. -[clinic start generated code]*/ - -static PyObject * -list_extend(PyListObject *self, PyObject *iterable) -/*[clinic end generated code: output=630fb3bca0c8e789 input=9ec5ba3a81be3a4d]*/ +static int +list_extend_fast(PyListObject *self, PyObject *iterable) { - PyObject *it; /* iter(v) */ - Py_ssize_t m; /* size of self */ - Py_ssize_t n; /* guess for size of iterable */ - Py_ssize_t i; - PyObject *(*iternext)(PyObject *); + Py_ssize_t n = PySequence_Fast_GET_SIZE(iterable); + if (n == 0) { + /* short circuit when iterable is empty */ + return 0; + } - /* Special cases: - 1) lists and tuples which can use PySequence_Fast ops - 2) extending self to self requires making a copy first - */ - if (PyList_CheckExact(iterable) || PyTuple_CheckExact(iterable) || - (PyObject *)self == iterable) { - PyObject **src, **dest; - iterable = PySequence_Fast(iterable, "argument must be iterable"); - if (!iterable) - return NULL; - n = PySequence_Fast_GET_SIZE(iterable); - if (n == 0) { - /* short circuit when iterable is empty */ - Py_DECREF(iterable); - Py_RETURN_NONE; - } - m = Py_SIZE(self); - /* It should not be possible to allocate a list large enough to cause - an overflow on any relevant platform */ - assert(m < PY_SSIZE_T_MAX - n); - if (self->ob_item == NULL) { - if (list_preallocate_exact(self, n) < 0) { - return NULL; - } - Py_SET_SIZE(self, n); - } - else if (list_resize(self, m + n) < 0) { - Py_DECREF(iterable); - return NULL; - } - /* note that we may still have self == iterable here for the - * situation a.extend(a), but the following code works - * in that case too. Just make sure to resize self - * before calling PySequence_Fast_ITEMS. - */ - /* populate the end of self with iterable's items */ - src = PySequence_Fast_ITEMS(iterable); - dest = self->ob_item + m; - for (i = 0; i < n; i++) { - PyObject *o = src[i]; - dest[i] = Py_NewRef(o); + Py_ssize_t m = Py_SIZE(self); + // It should not be possible to allocate a list large enough to cause + // an overflow on any relevant platform. + assert(m < PY_SSIZE_T_MAX - n); + if (self->ob_item == NULL) { + if (list_preallocate_exact(self, n) < 0) { + return -1; } - Py_DECREF(iterable); - Py_RETURN_NONE; + Py_SET_SIZE(self, n); + } + else if (list_resize(self, m + n) < 0) { + return -1; } - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - iternext = *Py_TYPE(it)->tp_iternext; + // note that we may still have self == iterable here for the + // situation a.extend(a), but the following code works + // in that case too. Just make sure to resize self + // before calling PySequence_Fast_ITEMS. + // + // populate the end of self with iterable's items. + PyObject **src = PySequence_Fast_ITEMS(iterable); + PyObject **dest = self->ob_item + m; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *o = src[i]; + dest[i] = Py_NewRef(o); + } + return 0; +} + +static int +list_extend_iter(PyListObject *self, PyObject *iterable) +{ + PyObject *it = PyObject_GetIter(iterable); + if (it == NULL) { + return -1; + } + PyObject *(*iternext)(PyObject *) = *Py_TYPE(it)->tp_iternext; /* Guess a result list size. */ - n = PyObject_LengthHint(iterable, 8); + Py_ssize_t n = PyObject_LengthHint(iterable, 8); if (n < 0) { Py_DECREF(it); - return NULL; + return -1; } - m = Py_SIZE(self); + + Py_ssize_t m = Py_SIZE(self); if (m > PY_SSIZE_T_MAX - n) { /* m + n overflowed; on the chance that n lied, and there really * is enough room, ignore it. If n was telling the truth, we'll @@ -935,8 +921,10 @@ list_extend(PyListObject *self, PyObject *iterable) } else { /* Make room. */ - if (list_resize(self, m + n) < 0) + if (list_resize(self, m + n) < 0) { goto error; + } + /* Make the list sane again. */ Py_SET_SIZE(self, m); } @@ -953,11 +941,11 @@ list_extend(PyListObject *self, PyObject *iterable) } break; } + if (Py_SIZE(self) < self->allocated) { - /* steals ref */ Py_ssize_t len = Py_SIZE(self); + PyList_SET_ITEM(self, len, item); // steals item ref Py_SET_SIZE(self, len + 1); - PyList_SET_ITEM(self, len, item); } else { if (_PyList_AppendTakeRef(self, item) < 0) @@ -972,28 +960,95 @@ list_extend(PyListObject *self, PyObject *iterable) } Py_DECREF(it); - Py_RETURN_NONE; + return 0; error: Py_DECREF(it); - return NULL; + return -1; +} + + +static int +list_extend(PyListObject *self, PyObject *iterable) +{ + // Special cases: + // 1) lists and tuples which can use PySequence_Fast ops + // 2) extending self to self requires making a copy first + if (PyList_CheckExact(iterable) + || PyTuple_CheckExact(iterable) + || (PyObject *)self == iterable) + { + iterable = PySequence_Fast(iterable, "argument must be iterable"); + if (!iterable) { + return -1; + } + + int res = list_extend_fast(self, iterable); + Py_DECREF(iterable); + return res; + } + else { + return list_extend_iter(self, iterable); + } } + PyObject * _PyList_Extend(PyListObject *self, PyObject *iterable) { - return list_extend(self, iterable); + if (list_extend(self, iterable) < 0) { + return NULL; + } + Py_RETURN_NONE; } + +/*[clinic input] +list.extend as py_list_extend + + iterable: object + / + +Extend list by appending elements from the iterable. +[clinic start generated code]*/ + static PyObject * -list_inplace_concat(PyListObject *self, PyObject *other) +py_list_extend(PyListObject *self, PyObject *iterable) +/*[clinic end generated code: output=b8e0bff0ceae2abd input=9a8376a8633ed3ba]*/ { - PyObject *result; + return _PyList_Extend(self, iterable); +} + - result = list_extend(self, other); - if (result == NULL) - return result; - Py_DECREF(result); +int +PyList_Extend(PyObject *self, PyObject *iterable) +{ + if (!PyList_Check(self)) { + PyErr_BadInternalCall(); + return -1; + } + return list_extend((PyListObject*)self, iterable); +} + + +int +PyList_Clear(PyObject *self) +{ + if (!PyList_Check(self)) { + PyErr_BadInternalCall(); + return -1; + } + list_clear((PyListObject*)self); + return 0; +} + + +static PyObject * +list_inplace_concat(PyListObject *self, PyObject *other) +{ + if (list_extend(self, other) < 0) { + return NULL; + } return Py_NewRef(self); } @@ -1032,7 +1087,8 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) const Py_ssize_t size_after_pop = Py_SIZE(self) - 1; if (size_after_pop == 0) { Py_INCREF(v); - status = _list_clear(self); + list_clear(self); + status = 0; } else { if ((size_after_pop - index) > 0) { @@ -2501,7 +2557,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) self->ob_item = saved_ob_item; self->allocated = saved_allocated; if (final_ob_item != NULL) { - /* we cannot use _list_clear() for this because it does not + /* we cannot use list_clear() for this because it does not guarantee that the list is really empty when it returns */ while (--i >= 0) { Py_XDECREF(final_ob_item[i]); @@ -2789,13 +2845,12 @@ list___init___impl(PyListObject *self, PyObject *iterable) /* Empty previous contents */ if (self->ob_item != NULL) { - (void)_list_clear(self); + list_clear(self); } if (iterable != NULL) { - PyObject *rv = list_extend(self, iterable); - if (rv == NULL) + if (list_extend(self, iterable) < 0) { return -1; - Py_DECREF(rv); + } } return 0; } @@ -2849,11 +2904,11 @@ static PyMethodDef list_methods[] = { PyDoc_STR("__getitem__($self, index, /)\n--\n\nReturn self[index].")}, LIST___REVERSED___METHODDEF LIST___SIZEOF___METHODDEF - LIST_CLEAR_METHODDEF + PY_LIST_CLEAR_METHODDEF LIST_COPY_METHODDEF LIST_APPEND_METHODDEF LIST_INSERT_METHODDEF - LIST_EXTEND_METHODDEF + PY_LIST_EXTEND_METHODDEF LIST_POP_METHODDEF LIST_REMOVE_METHODDEF LIST_INDEX_METHODDEF @@ -3124,7 +3179,7 @@ PyTypeObject PyList_Type = { _Py_TPFLAGS_MATCH_SELF | Py_TPFLAGS_SEQUENCE, /* tp_flags */ list___init____doc__, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ - (inquiry)_list_clear, /* tp_clear */ + (inquiry)list_clear_slot, /* tp_clear */ list_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ list_iter, /* tp_iter */ diff --git a/Objects/longobject.c b/Objects/longobject.c index e73de742229005..fae70dd13bb18a 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5,6 +5,7 @@ #include "Python.h" #include "pycore_bitutils.h" // _Py_popcount32() #include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_call.h" // _PyObject_MakeTpCall #include "pycore_long.h" // _Py_SmallInts #include "pycore_object.h" // _PyObject_Init() #include "pycore_runtime.h" // _PY_NSMALLPOSINTS @@ -6152,6 +6153,29 @@ int_is_integer_impl(PyObject *self) Py_RETURN_TRUE; } +static PyObject * +long_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (kwnames != NULL) { + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_MakeTpCall(tstate, type, args, nargs, kwnames); + } + switch (nargs) { + case 0: + return _PyLong_GetZero(); + case 1: + return PyNumber_Long(args[0]); + case 2: + return long_new_impl(_PyType_CAST(type), args[0], args[1]); + default: + return PyErr_Format(PyExc_TypeError, + "int expected at most 2 argument%s, got %zd", + nargs); + } +} + static PyMethodDef long_methods[] = { {"conjugate", long_long_meth, METH_NOARGS, "Returns self, the complex conjugate of any int."}, @@ -6289,6 +6313,7 @@ PyTypeObject PyLong_Type = { 0, /* tp_alloc */ long_new, /* tp_new */ PyObject_Free, /* tp_free */ + .tp_vectorcall = long_vectorcall, }; static PyTypeObject Int_InfoType; diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index bcdd2ff0ceafe6..6a38952fdc1f3b 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -119,8 +119,9 @@ mbuf_release(_PyManagedBufferObject *self) } static void -mbuf_dealloc(_PyManagedBufferObject *self) +mbuf_dealloc(PyObject *_self) { + _PyManagedBufferObject *self = (_PyManagedBufferObject *)_self; assert(self->exports == 0); mbuf_release(self); if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT) @@ -129,15 +130,17 @@ mbuf_dealloc(_PyManagedBufferObject *self) } static int -mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg) +mbuf_traverse(PyObject *_self, visitproc visit, void *arg) { + _PyManagedBufferObject *self = (_PyManagedBufferObject *)_self; Py_VISIT(self->master.obj); return 0; } static int -mbuf_clear(_PyManagedBufferObject *self) +mbuf_clear(PyObject *_self) { + _PyManagedBufferObject *self = (_PyManagedBufferObject *)_self; assert(self->exports >= 0); mbuf_release(self); return 0; @@ -148,7 +151,7 @@ PyTypeObject _PyManagedBuffer_Type = { "managedbuffer", sizeof(_PyManagedBufferObject), 0, - (destructor)mbuf_dealloc, /* tp_dealloc */ + mbuf_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -165,8 +168,8 @@ PyTypeObject _PyManagedBuffer_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)mbuf_traverse, /* tp_traverse */ - (inquiry)mbuf_clear /* tp_clear */ + mbuf_traverse, /* tp_traverse */ + mbuf_clear /* tp_clear */ }; @@ -1137,8 +1140,9 @@ memoryview_release_impl(PyMemoryViewObject *self) } static void -memory_dealloc(PyMemoryViewObject *self) +memory_dealloc(PyObject *_self) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; assert(self->exports == 0); _PyObject_GC_UNTRACK(self); (void)_memory_release(self); @@ -1149,15 +1153,17 @@ memory_dealloc(PyMemoryViewObject *self) } static int -memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg) +memory_traverse(PyObject *_self, visitproc visit, void *arg) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; Py_VISIT(self->mbuf); return 0; } static int -memory_clear(PyMemoryViewObject *self) +memory_clear(PyObject *_self) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; (void)_memory_release(self); Py_CLEAR(self->mbuf); return 0; @@ -1510,8 +1516,9 @@ memoryview_toreadonly_impl(PyMemoryViewObject *self) /**************************************************************************/ static int -memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) +memory_getbuf(PyObject *_self, Py_buffer *view, int flags) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; Py_buffer *base = &self->view; int baseflags = self->flags; @@ -1589,8 +1596,9 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) } static void -memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) +memory_releasebuf(PyObject *_self, Py_buffer *view) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; self->exports--; return; /* PyBuffer_Release() decrements view->obj after this function returns. */ @@ -1598,8 +1606,8 @@ memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) /* Buffer methods */ static PyBufferProcs memory_as_buffer = { - (getbufferproc)memory_getbuf, /* bf_getbuffer */ - (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */ + memory_getbuf, /* bf_getbuffer */ + memory_releasebuf, /* bf_releasebuffer */ }; @@ -2344,8 +2352,9 @@ memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep, } static PyObject * -memory_repr(PyMemoryViewObject *self) +memory_repr(PyObject *_self) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; if (self->flags & _Py_MEMORYVIEW_RELEASED) return PyUnicode_FromFormat("", self); else @@ -2421,8 +2430,9 @@ ptr_from_tuple(const Py_buffer *view, PyObject *tup) with the type specified by view->format. Otherwise, the item is a sub-view. The function is used in memory_subscript() and memory_as_sequence. */ static PyObject * -memory_item(PyMemoryViewObject *self, Py_ssize_t index) +memory_item(PyObject *_self, Py_ssize_t index) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; Py_buffer *view = &(self->view); const char *fmt; @@ -2546,8 +2556,9 @@ is_multiindex(PyObject *key) 0-d memoryview objects can be referenced using mv[...] or mv[()] but not with anything else. */ static PyObject * -memory_subscript(PyMemoryViewObject *self, PyObject *key) +memory_subscript(PyObject *_self, PyObject *key) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; Py_buffer *view; view = &(self->view); @@ -2575,7 +2586,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) index = PyNumber_AsSsize_t(key, PyExc_IndexError); if (index == -1 && PyErr_Occurred()) return NULL; - return memory_item(self, index); + return memory_item((PyObject *)self, index); } else if (PySlice_Check(key)) { CHECK_RESTRICTED(self); @@ -2608,8 +2619,9 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) } static int -memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) +memory_ass_sub(PyObject *_self, PyObject *key, PyObject *value) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; Py_buffer *view = &(self->view); Py_buffer src; const char *fmt; @@ -2710,8 +2722,9 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) } static Py_ssize_t -memory_length(PyMemoryViewObject *self) +memory_length(PyObject *_self) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED_INT(self); if (self->view.ndim == 0) { PyErr_SetString(PyExc_TypeError, "0-dim memory has no length"); @@ -2722,17 +2735,17 @@ memory_length(PyMemoryViewObject *self) /* As mapping */ static PyMappingMethods memory_as_mapping = { - (lenfunc)memory_length, /* mp_length */ - (binaryfunc)memory_subscript, /* mp_subscript */ - (objobjargproc)memory_ass_sub, /* mp_ass_subscript */ + memory_length, /* mp_length */ + memory_subscript, /* mp_subscript */ + memory_ass_sub, /* mp_ass_subscript */ }; /* As sequence */ static PySequenceMethods memory_as_sequence = { - (lenfunc)memory_length, /* sq_length */ + memory_length, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ - (ssizeargfunc)memory_item, /* sq_item */ + memory_item, /* sq_item */ }; @@ -3034,8 +3047,9 @@ memory_richcompare(PyObject *v, PyObject *w, int op) /**************************************************************************/ static Py_hash_t -memory_hash(PyMemoryViewObject *self) +memory_hash(PyObject *_self) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; if (self->hash == -1) { Py_buffer *view = &self->view; char *mem = view->buf; @@ -3112,8 +3126,9 @@ _IntTupleFromSsizet(int len, Py_ssize_t *vals) } static PyObject * -memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_obj_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; Py_buffer *view = &self->view; CHECK_RELEASED(self); @@ -3124,78 +3139,89 @@ memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) } static PyObject * -memory_nbytes_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_nbytes_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyLong_FromSsize_t(self->view.len); } static PyObject * -memory_format_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_format_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyUnicode_FromString(self->view.format); } static PyObject * -memory_itemsize_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_itemsize_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyLong_FromSsize_t(self->view.itemsize); } static PyObject * -memory_shape_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_shape_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return _IntTupleFromSsizet(self->view.ndim, self->view.shape); } static PyObject * -memory_strides_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_strides_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return _IntTupleFromSsizet(self->view.ndim, self->view.strides); } static PyObject * -memory_suboffsets_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_suboffsets_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets); } static PyObject * -memory_readonly_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_readonly_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyBool_FromLong(self->view.readonly); } static PyObject * -memory_ndim_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) +memory_ndim_get(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyLong_FromLong(self->view.ndim); } static PyObject * -memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy) +memory_c_contiguous(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags)); } static PyObject * -memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy) +memory_f_contiguous(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags)); } static PyObject * -memory_contiguous(PyMemoryViewObject *self, PyObject *dummy) +memory_contiguous(PyObject *_self, void *Py_UNUSED(ignored)) { + PyMemoryViewObject *self = (PyMemoryViewObject *)_self; CHECK_RELEASED(self); return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags)); } @@ -3232,18 +3258,18 @@ PyDoc_STRVAR(memory_contiguous_doc, static PyGetSetDef memory_getsetlist[] = { - {"obj", (getter)memory_obj_get, NULL, memory_obj_doc}, - {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc}, - {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc}, - {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc}, - {"format", (getter)memory_format_get, NULL, memory_format_doc}, - {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc}, - {"shape", (getter)memory_shape_get, NULL, memory_shape_doc}, - {"strides", (getter)memory_strides_get, NULL, memory_strides_doc}, - {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc}, - {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc}, - {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc}, - {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc}, + {"obj", memory_obj_get, NULL, memory_obj_doc}, + {"nbytes", memory_nbytes_get, NULL, memory_nbytes_doc}, + {"readonly", memory_readonly_get, NULL, memory_readonly_doc}, + {"itemsize", memory_itemsize_get, NULL, memory_itemsize_doc}, + {"format", memory_format_get, NULL, memory_format_doc}, + {"ndim", memory_ndim_get, NULL, memory_ndim_doc}, + {"shape", memory_shape_get, NULL, memory_shape_doc}, + {"strides", memory_strides_get, NULL, memory_strides_doc}, + {"suboffsets", memory_suboffsets_get, NULL, memory_suboffsets_doc}, + {"c_contiguous", memory_c_contiguous, NULL, memory_c_contiguous_doc}, + {"f_contiguous", memory_f_contiguous, NULL, memory_f_contiguous_doc}, + {"contiguous", memory_contiguous, NULL, memory_contiguous_doc}, {NULL, NULL, NULL, NULL}, }; @@ -3276,23 +3302,26 @@ typedef struct { } memoryiterobject; static void -memoryiter_dealloc(memoryiterobject *it) +memoryiter_dealloc(PyObject *self) { + memoryiterobject *it = (memoryiterobject *)self; _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); PyObject_GC_Del(it); } static int -memoryiter_traverse(memoryiterobject *it, visitproc visit, void *arg) +memoryiter_traverse(PyObject *self, visitproc visit, void *arg) { + memoryiterobject *it = (memoryiterobject *)self; Py_VISIT(it->it_seq); return 0; } static PyObject * -memoryiter_next(memoryiterobject *it) +memoryiter_next(PyObject *self) { + memoryiterobject *it = (memoryiterobject *)self; PyMemoryViewObject *seq; seq = it->it_seq; if (seq == NULL) { @@ -3347,7 +3376,7 @@ memory_iter(PyObject *seq) return NULL; } it->it_fmt = fmt; - it->it_length = memory_length(obj); + it->it_length = memory_length((PyObject *)obj); it->it_index = 0; it->it_seq = (PyMemoryViewObject*)Py_NewRef(obj); _PyObject_GC_TRACK(it); @@ -3359,12 +3388,12 @@ PyTypeObject _PyMemoryIter_Type = { .tp_name = "memory_iterator", .tp_basicsize = sizeof(memoryiterobject), // methods - .tp_dealloc = (destructor)memoryiter_dealloc, + .tp_dealloc = memoryiter_dealloc, .tp_getattro = PyObject_GenericGetAttr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)memoryiter_traverse, + .tp_traverse = memoryiter_traverse, .tp_iter = PyObject_SelfIter, - .tp_iternext = (iternextfunc)memoryiter_next, + .tp_iternext = memoryiter_next, }; PyTypeObject PyMemoryView_Type = { @@ -3372,16 +3401,16 @@ PyTypeObject PyMemoryView_Type = { "memoryview", /* tp_name */ offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */ sizeof(Py_ssize_t), /* tp_itemsize */ - (destructor)memory_dealloc, /* tp_dealloc */ + memory_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ - (reprfunc)memory_repr, /* tp_repr */ + memory_repr, /* tp_repr */ 0, /* tp_as_number */ &memory_as_sequence, /* tp_as_sequence */ &memory_as_mapping, /* tp_as_mapping */ - (hashfunc)memory_hash, /* tp_hash */ + memory_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ @@ -3390,8 +3419,8 @@ PyTypeObject PyMemoryView_Type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_SEQUENCE, /* tp_flags */ memoryview__doc__, /* tp_doc */ - (traverseproc)memory_traverse, /* tp_traverse */ - (inquiry)memory_clear, /* tp_clear */ + memory_traverse, /* tp_traverse */ + memory_clear, /* tp_clear */ memory_richcompare, /* tp_richcompare */ offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */ memory_iter, /* tp_iter */ diff --git a/Objects/mimalloc/alloc-aligned.c b/Objects/mimalloc/alloc-aligned.c new file mode 100644 index 00000000000000..4c15f4043ec117 --- /dev/null +++ b/Objects/mimalloc/alloc-aligned.c @@ -0,0 +1,298 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/prim.h" // mi_prim_get_default_heap + +#include // memset + +// ------------------------------------------------------ +// Aligned Allocation +// ------------------------------------------------------ + +// Fallback primitive aligned allocation -- split out for better codegen +static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept +{ + mi_assert_internal(size <= PTRDIFF_MAX); + mi_assert_internal(alignment != 0 && _mi_is_power_of_two(alignment)); + + const uintptr_t align_mask = alignment - 1; // for any x, `(x & align_mask) == (x % alignment)` + const size_t padsize = size + MI_PADDING_SIZE; + + // use regular allocation if it is guaranteed to fit the alignment constraints + if (offset==0 && alignment<=padsize && padsize<=MI_MAX_ALIGN_GUARANTEE && (padsize&align_mask)==0) { + void* p = _mi_heap_malloc_zero(heap, size, zero); + mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0); + return p; + } + + void* p; + size_t oversize; + if mi_unlikely(alignment > MI_ALIGNMENT_MAX) { + // use OS allocation for very large alignment and allocate inside a huge page (dedicated segment with 1 page) + // This can support alignments >= MI_SEGMENT_SIZE by ensuring the object can be aligned at a point in the + // first (and single) page such that the segment info is `MI_SEGMENT_SIZE` bytes before it (so it can be found by aligning the pointer down) + if mi_unlikely(offset != 0) { + // todo: cannot support offset alignment for very large alignments yet + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "aligned allocation with a very large alignment cannot be used with an alignment offset (size %zu, alignment %zu, offset %zu)\n", size, alignment, offset); + #endif + return NULL; + } + oversize = (size <= MI_SMALL_SIZE_MAX ? MI_SMALL_SIZE_MAX + 1 /* ensure we use generic malloc path */ : size); + p = _mi_heap_malloc_zero_ex(heap, oversize, false, alignment); // the page block size should be large enough to align in the single huge page block + // zero afterwards as only the area from the aligned_p may be committed! + if (p == NULL) return NULL; + } + else { + // otherwise over-allocate + oversize = size + alignment - 1; + p = _mi_heap_malloc_zero(heap, oversize, zero); + if (p == NULL) return NULL; + } + + // .. and align within the allocation + const uintptr_t poffset = ((uintptr_t)p + offset) & align_mask; + const uintptr_t adjust = (poffset == 0 ? 0 : alignment - poffset); + mi_assert_internal(adjust < alignment); + void* aligned_p = (void*)((uintptr_t)p + adjust); + if (aligned_p != p) { + mi_page_t* page = _mi_ptr_page(p); + mi_page_set_has_aligned(page, true); + _mi_padding_shrink(page, (mi_block_t*)p, adjust + size); + } + // todo: expand padding if overallocated ? + + mi_assert_internal(mi_page_usable_block_size(_mi_ptr_page(p)) >= adjust + size); + mi_assert_internal(p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p), _mi_ptr_page(aligned_p), aligned_p)); + mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0); + mi_assert_internal(mi_usable_size(aligned_p)>=size); + mi_assert_internal(mi_usable_size(p) == mi_usable_size(aligned_p)+adjust); + + // now zero the block if needed + if (alignment > MI_ALIGNMENT_MAX) { + // for the tracker, on huge aligned allocations only from the start of the large block is defined + mi_track_mem_undefined(aligned_p, size); + if (zero) { + _mi_memzero_aligned(aligned_p, mi_usable_size(aligned_p)); + } + } + + if (p != aligned_p) { + mi_track_align(p,aligned_p,adjust,mi_usable_size(aligned_p)); + } + return aligned_p; +} + +// Primitive aligned allocation +static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept +{ + // note: we don't require `size > offset`, we just guarantee that the address at offset is aligned regardless of the allocated size. + if mi_unlikely(alignment == 0 || !_mi_is_power_of_two(alignment)) { // require power-of-two (see ) + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "aligned allocation requires the alignment to be a power-of-two (size %zu, alignment %zu)\n", size, alignment); + #endif + return NULL; + } + + if mi_unlikely(size > PTRDIFF_MAX) { // we don't allocate more than PTRDIFF_MAX (see ) + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "aligned allocation request is too large (size %zu, alignment %zu)\n", size, alignment); + #endif + return NULL; + } + const uintptr_t align_mask = alignment-1; // for any x, `(x & align_mask) == (x % alignment)` + const size_t padsize = size + MI_PADDING_SIZE; // note: cannot overflow due to earlier size > PTRDIFF_MAX check + + // try first if there happens to be a small block available with just the right alignment + if mi_likely(padsize <= MI_SMALL_SIZE_MAX && alignment <= padsize) { + mi_page_t* page = _mi_heap_get_free_small_page(heap, padsize); + const bool is_aligned = (((uintptr_t)page->free+offset) & align_mask)==0; + if mi_likely(page->free != NULL && is_aligned) + { + #if MI_STAT>1 + mi_heap_stat_increase(heap, malloc, size); + #endif + void* p = _mi_page_malloc(heap, page, padsize, zero); // TODO: inline _mi_page_malloc + mi_assert_internal(p != NULL); + mi_assert_internal(((uintptr_t)p + offset) % alignment == 0); + mi_track_malloc(p,size,zero); + return p; + } + } + // fallback + return mi_heap_malloc_zero_aligned_at_fallback(heap, size, alignment, offset, zero); +} + + +// ------------------------------------------------------ +// Optimized mi_heap_malloc_aligned / mi_malloc_aligned +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { + if mi_unlikely(alignment == 0 || !_mi_is_power_of_two(alignment)) return NULL; + #if !MI_PADDING + // without padding, any small sized allocation is naturally aligned (see also `_mi_segment_page_start`) + if mi_likely(_mi_is_power_of_two(size) && size >= alignment && size <= MI_SMALL_SIZE_MAX) + #else + // with padding, we can only guarantee this for fixed alignments + if mi_likely((alignment == sizeof(void*) || (alignment == MI_MAX_ALIGN_SIZE && size > (MI_MAX_ALIGN_SIZE/2))) + && size <= MI_SMALL_SIZE_MAX) + #endif + { + // fast path for common alignment and size + return mi_heap_malloc_small(heap, size); + } + else { + return mi_heap_malloc_aligned_at(heap, size, alignment, 0); + } +} + +// ensure a definition is emitted +#if defined(__cplusplus) +static void* _mi_heap_malloc_aligned = (void*)&mi_heap_malloc_aligned; +#endif + +// ------------------------------------------------------ +// Aligned Allocation +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_zalloc_aligned_at(heap, size, alignment, 0); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_zalloc_aligned_at(heap, total, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_calloc_aligned_at(heap,count,size,alignment,0); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_aligned_at(mi_prim_get_default_heap(), size, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_malloc_aligned(mi_prim_get_default_heap(), size, alignment); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_zalloc_aligned_at(mi_prim_get_default_heap(), size, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_zalloc_aligned(mi_prim_get_default_heap(), size, alignment); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_calloc_aligned_at(mi_prim_get_default_heap(), count, size, alignment, offset); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_calloc_aligned(mi_prim_get_default_heap(), count, size, alignment); +} + + +// ------------------------------------------------------ +// Aligned re-allocation +// ------------------------------------------------------ + +static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept { + mi_assert(alignment > 0); + if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); + if (p == NULL) return mi_heap_malloc_zero_aligned_at(heap,newsize,alignment,offset,zero); + size_t size = mi_usable_size(p); + if (newsize <= size && newsize >= (size - (size / 2)) + && (((uintptr_t)p + offset) % alignment) == 0) { + return p; // reallocation still fits, is aligned and not more than 50% waste + } + else { + // note: we don't zero allocate upfront so we only zero initialize the expanded part + void* newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset); + if (newp != NULL) { + if (zero && newsize > size) { + // also set last word in the previous allocation to zero to ensure any padding is zero-initialized + size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); + _mi_memzero((uint8_t*)newp + start, newsize - start); + } + _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + mi_free(p); // only free if successful + } + return newp; + } +} + +static void* mi_heap_realloc_zero_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept { + mi_assert(alignment > 0); + if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); + size_t offset = ((uintptr_t)p % alignment); // use offset of previous allocation (p can be NULL) + return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,zero); +} + +mi_decl_nodiscard void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,false); +} + +mi_decl_nodiscard void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned(heap,p,newsize,alignment,false); +} + +mi_decl_nodiscard void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned_at(heap, p, newsize, alignment, offset, true); +} + +mi_decl_nodiscard void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned(heap, p, newsize, alignment, true); +} + +mi_decl_nodiscard void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(newcount, size, &total)) return NULL; + return mi_heap_rezalloc_aligned_at(heap, p, total, alignment, offset); +} + +mi_decl_nodiscard void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(newcount, size, &total)) return NULL; + return mi_heap_rezalloc_aligned(heap, p, total, alignment); +} + +mi_decl_nodiscard void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_aligned_at(mi_prim_get_default_heap(), p, newsize, alignment, offset); +} + +mi_decl_nodiscard void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_aligned(mi_prim_get_default_heap(), p, newsize, alignment); +} + +mi_decl_nodiscard void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_rezalloc_aligned_at(mi_prim_get_default_heap(), p, newsize, alignment, offset); +} + +mi_decl_nodiscard void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_rezalloc_aligned(mi_prim_get_default_heap(), p, newsize, alignment); +} + +mi_decl_nodiscard void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_recalloc_aligned_at(mi_prim_get_default_heap(), p, newcount, size, alignment, offset); +} + +mi_decl_nodiscard void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_recalloc_aligned(mi_prim_get_default_heap(), p, newcount, size, alignment); +} diff --git a/Objects/mimalloc/alloc-override.c b/Objects/mimalloc/alloc-override.c new file mode 100644 index 00000000000000..873065dc63495c --- /dev/null +++ b/Objects/mimalloc/alloc-override.c @@ -0,0 +1,297 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#if !defined(MI_IN_ALLOC_C) +#error "this file should be included from 'alloc.c' (so aliases can work)" +#endif + +#if defined(MI_MALLOC_OVERRIDE) && defined(_WIN32) && !(defined(MI_SHARED_LIB) && defined(_DLL)) +#error "It is only possible to override "malloc" on Windows when building as a DLL (and linking the C runtime as a DLL)" +#endif + +#if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) + +#if defined(__APPLE__) +#include +mi_decl_externc void vfree(void* p); +mi_decl_externc size_t malloc_size(const void* p); +mi_decl_externc size_t malloc_good_size(size_t size); +#endif + +// helper definition for C override of C++ new +typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; + +// ------------------------------------------------------ +// Override system malloc +// ------------------------------------------------------ + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) && !MI_TRACK_ENABLED + // gcc, clang: use aliasing to alias the exported function to one of our `mi_` functions + #if (defined(__GNUC__) && __GNUC__ >= 9) + #pragma GCC diagnostic ignored "-Wattributes" // or we get warnings that nodiscard is ignored on a forward + #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun))); + #else + #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"))); + #endif + #define MI_FORWARD1(fun,x) MI_FORWARD(fun) + #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun) + #define MI_FORWARD3(fun,x,y,z) MI_FORWARD(fun) + #define MI_FORWARD0(fun,x) MI_FORWARD(fun) + #define MI_FORWARD02(fun,x,y) MI_FORWARD(fun) +#else + // otherwise use forwarding by calling our `mi_` function + #define MI_FORWARD1(fun,x) { return fun(x); } + #define MI_FORWARD2(fun,x,y) { return fun(x,y); } + #define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); } + #define MI_FORWARD0(fun,x) { fun(x); } + #define MI_FORWARD02(fun,x,y) { fun(x,y); } +#endif + + +#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_OSX_INTERPOSE) + // define MI_OSX_IS_INTERPOSED as we should not provide forwarding definitions for + // functions that are interposed (or the interposing does not work) + #define MI_OSX_IS_INTERPOSED + + mi_decl_externc size_t mi_malloc_size_checked(void *p) { + if (!mi_is_in_heap_region(p)) return 0; + return mi_usable_size(p); + } + + // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` + // See: + struct mi_interpose_s { + const void* replacement; + const void* target; + }; + #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } + #define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) + + __attribute__((used)) static struct mi_interpose_s _mi_interposes[] __attribute__((section("__DATA, __interpose"))) = + { + MI_INTERPOSE_MI(malloc), + MI_INTERPOSE_MI(calloc), + MI_INTERPOSE_MI(realloc), + MI_INTERPOSE_MI(strdup), + MI_INTERPOSE_MI(strndup), + MI_INTERPOSE_MI(realpath), + MI_INTERPOSE_MI(posix_memalign), + MI_INTERPOSE_MI(reallocf), + MI_INTERPOSE_MI(valloc), + MI_INTERPOSE_FUN(malloc_size,mi_malloc_size_checked), + MI_INTERPOSE_MI(malloc_good_size), + #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + MI_INTERPOSE_MI(aligned_alloc), + #endif + #ifdef MI_OSX_ZONE + // we interpose malloc_default_zone in alloc-override-osx.c so we can use mi_free safely + MI_INTERPOSE_MI(free), + MI_INTERPOSE_FUN(vfree,mi_free), + #else + // sometimes code allocates from default zone but deallocates using plain free :-( (like NxHashResizeToCapacity ) + MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us + MI_INTERPOSE_FUN(vfree,mi_cfree), + #endif + }; + + #ifdef __cplusplus + extern "C" { + #endif + void _ZdlPv(void* p); // delete + void _ZdaPv(void* p); // delete[] + void _ZdlPvm(void* p, size_t n); // delete + void _ZdaPvm(void* p, size_t n); // delete[] + void* _Znwm(size_t n); // new + void* _Znam(size_t n); // new[] + void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new nothrow + void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag); // new[] nothrow + #ifdef __cplusplus + } + #endif + __attribute__((used)) static struct mi_interpose_s _mi_cxx_interposes[] __attribute__((section("__DATA, __interpose"))) = + { + MI_INTERPOSE_FUN(_ZdlPv,mi_free), + MI_INTERPOSE_FUN(_ZdaPv,mi_free), + MI_INTERPOSE_FUN(_ZdlPvm,mi_free_size), + MI_INTERPOSE_FUN(_ZdaPvm,mi_free_size), + MI_INTERPOSE_FUN(_Znwm,mi_new), + MI_INTERPOSE_FUN(_Znam,mi_new), + MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow), + MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow), + }; + +#elif defined(_MSC_VER) + // cannot override malloc unless using a dll. + // we just override new/delete which does work in a static library. +#else + // On all other systems forward to our API + mi_decl_export void* malloc(size_t size) MI_FORWARD1(mi_malloc, size) + mi_decl_export void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n) + mi_decl_export void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize) + mi_decl_export void free(void* p) MI_FORWARD0(mi_free, p) +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) +#pragma GCC visibility push(default) +#endif + +// ------------------------------------------------------ +// Override new/delete +// This is not really necessary as they usually call +// malloc/free anyway, but it improves performance. +// ------------------------------------------------------ +#ifdef __cplusplus + // ------------------------------------------------------ + // With a C++ compiler we override the new/delete operators. + // see + // ------------------------------------------------------ + #include + + #ifndef MI_OSX_IS_INTERPOSED + void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p) + void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p) + + void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n) + void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n) + + void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { MI_UNUSED(tag); return mi_new_nothrow(n); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n) + void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n) + #endif + #endif + + #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast(al)); } + + void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + #endif + +#elif (defined(__GNUC__) || defined(__clang__)) + // ------------------------------------------------------ + // Override by defining the mangled C++ names of the operators (as + // used by GCC and CLang). + // See + // ------------------------------------------------------ + + void _ZdlPv(void* p) MI_FORWARD0(mi_free,p) // delete + void _ZdaPv(void* p) MI_FORWARD0(mi_free,p) // delete[] + void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n) + void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n) + void _ZdlPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } + void _ZdaPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } + void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } + void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } + + #if (MI_INTPTR_SIZE==8) + void* _Znwm(size_t n) MI_FORWARD1(mi_new,n) // new 64-bit + void* _Znam(size_t n) MI_FORWARD1(mi_new,n) // new[] 64-bit + void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + #elif (MI_INTPTR_SIZE==4) + void* _Znwj(size_t n) MI_FORWARD1(mi_new,n) // new 64-bit + void* _Znaj(size_t n) MI_FORWARD1(mi_new,n) // new[] 64-bit + void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al) + void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { MI_UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + #else + #error "define overloads for new/delete for this platform (just for performance, can be skipped)" + #endif +#endif // __cplusplus + +// ------------------------------------------------------ +// Further Posix & Unix functions definitions +// ------------------------------------------------------ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef MI_OSX_IS_INTERPOSED + // Forward Posix/Unix calls as well + void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize) + size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p) + #if !defined(__ANDROID__) && !defined(__FreeBSD__) + size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p) + #else + size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p) + #endif + + // No forwarding here due to aliasing/name mangling issues + void* valloc(size_t size) { return mi_valloc(size); } + void vfree(void* p) { mi_free(p); } + size_t malloc_good_size(size_t size) { return mi_malloc_good_size(size); } + int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); } + + // `aligned_alloc` is only available when __USE_ISOC11 is defined. + // Note: it seems __USE_ISOC11 is not defined in musl (and perhaps other libc's) so we only check + // for it if using glibc. + // Note: Conda has a custom glibc where `aligned_alloc` is declared `static inline` and we cannot + // override it, but both _ISOC11_SOURCE and __USE_ISOC11 are undefined in Conda GCC7 or GCC9. + // Fortunately, in the case where `aligned_alloc` is declared as `static inline` it + // uses internally `memalign`, `posix_memalign`, or `_aligned_malloc` so we can avoid overriding it ourselves. + #if !defined(__GLIBC__) || __USE_ISOC11 + void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } + #endif +#endif + +// no forwarding here due to aliasing/name mangling issues +void cfree(void* p) { mi_free(p); } +void* pvalloc(size_t size) { return mi_pvalloc(size); } +void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); } +int reallocarr(void* p, size_t count, size_t size) { return mi_reallocarr(p, count, size); } +void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } +void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } + +#if defined(__wasi__) + // forward __libc interface (see PR #667) + void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc, size) + void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc, count, size) + void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc, p, size) + void __libc_free(void* p) MI_FORWARD0(mi_free, p) + void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } + +#elif defined(__GLIBC__) && defined(__linux__) + // forward __libc interface (needed for glibc-based Linux distributions) + void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size) + void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size) + void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size) + void __libc_free(void* p) MI_FORWARD0(mi_free,p) + void __libc_cfree(void* p) MI_FORWARD0(mi_free,p) + + void* __libc_valloc(size_t size) { return mi_valloc(size); } + void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); } + void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); } + int __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); } +#endif + +#ifdef __cplusplus +} +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) +#pragma GCC visibility pop +#endif + +#endif // MI_MALLOC_OVERRIDE && !_WIN32 diff --git a/Objects/mimalloc/alloc-posix.c b/Objects/mimalloc/alloc-posix.c new file mode 100644 index 00000000000000..225752fd8707fe --- /dev/null +++ b/Objects/mimalloc/alloc-posix.c @@ -0,0 +1,185 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// ------------------------------------------------------------------------ +// mi prefixed publi definitions of various Posix, Unix, and C++ functions +// for convenience and used when overriding these functions. +// ------------------------------------------------------------------------ +#include "mimalloc.h" +#include "mimalloc/internal.h" + +// ------------------------------------------------------ +// Posix & Unix functions definitions +// ------------------------------------------------------ + +#include +#include // memset +#include // getenv + +#ifdef _MSC_VER +#pragma warning(disable:4996) // getenv _wgetenv +#endif + +#ifndef EINVAL +#define EINVAL 22 +#endif +#ifndef ENOMEM +#define ENOMEM 12 +#endif + + +mi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept { + // if (!mi_is_in_heap_region(p)) return 0; + return mi_usable_size(p); +} + +mi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept { + // if (!mi_is_in_heap_region(p)) return 0; + return mi_usable_size(p); +} + +mi_decl_nodiscard size_t mi_malloc_good_size(size_t size) mi_attr_noexcept { + return mi_good_size(size); +} + +void mi_cfree(void* p) mi_attr_noexcept { + if (mi_is_in_heap_region(p)) { + mi_free(p); + } +} + +int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept { + // Note: The spec dictates we should not modify `*p` on an error. (issue#27) + // + if (p == NULL) return EINVAL; + if ((alignment % sizeof(void*)) != 0) return EINVAL; // natural alignment + // it is also required that alignment is a power of 2 and > 0; this is checked in `mi_malloc_aligned` + if (alignment==0 || !_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2 + void* q = mi_malloc_aligned(size, alignment); + if (q==NULL && size != 0) return ENOMEM; + mi_assert_internal(((uintptr_t)q % alignment) == 0); + *p = q; + return 0; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept { + void* p = mi_malloc_aligned(size, alignment); + mi_assert_internal(((uintptr_t)p % alignment) == 0); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept { + return mi_memalign( _mi_os_page_size(), size ); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept { + size_t psize = _mi_os_page_size(); + if (size >= SIZE_MAX - psize) return NULL; // overflow + size_t asize = _mi_align_up(size, psize); + return mi_malloc_aligned(asize, psize); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept { + // C11 requires the size to be an integral multiple of the alignment, see . + // unfortunately, it turns out quite some programs pass a size that is not an integral multiple so skip this check.. + /* if mi_unlikely((size & (alignment - 1)) != 0) { // C11 requires alignment>0 && integral multiple, see + #if MI_DEBUG > 0 + _mi_error_message(EOVERFLOW, "(mi_)aligned_alloc requires the size to be an integral multiple of the alignment (size %zu, alignment %zu)\n", size, alignment); + #endif + return NULL; + } + */ + // C11 also requires alignment to be a power-of-two (and > 0) which is checked in mi_malloc_aligned + void* p = mi_malloc_aligned(size, alignment); + mi_assert_internal(((uintptr_t)p % alignment) == 0); + return p; +} + +mi_decl_nodiscard void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD + void* newp = mi_reallocn(p,count,size); + if (newp==NULL) { errno = ENOMEM; } + return newp; +} + +mi_decl_nodiscard int mi_reallocarr( void* p, size_t count, size_t size ) mi_attr_noexcept { // NetBSD + mi_assert(p != NULL); + if (p == NULL) { + errno = EINVAL; + return EINVAL; + } + void** op = (void**)p; + void* newp = mi_reallocarray(*op, count, size); + if mi_unlikely(newp == NULL) { return errno; } + *op = newp; + return 0; +} + +void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft + void* res = mi_expand(p, newsize); + if (res == NULL) { errno = ENOMEM; } + return res; +} + +mi_decl_nodiscard mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept { + if (s==NULL) return NULL; + size_t len; + for(len = 0; s[len] != 0; len++) { } + size_t size = (len+1)*sizeof(unsigned short); + unsigned short* p = (unsigned short*)mi_malloc(size); + if (p != NULL) { + _mi_memcpy(p,s,size); + } + return p; +} + +mi_decl_nodiscard mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept { + return (unsigned char*)mi_strdup((const char*)s); +} + +int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept { + if (buf==NULL || name==NULL) return EINVAL; + if (size != NULL) *size = 0; + char* p = getenv(name); // mscver warning 4996 + if (p==NULL) { + *buf = NULL; + } + else { + *buf = mi_strdup(p); + if (*buf==NULL) return ENOMEM; + if (size != NULL) *size = _mi_strlen(p); + } + return 0; +} + +int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept { + if (buf==NULL || name==NULL) return EINVAL; + if (size != NULL) *size = 0; +#if !defined(_WIN32) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)) + // not supported + *buf = NULL; + return EINVAL; +#else + unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name); // msvc warning 4996 + if (p==NULL) { + *buf = NULL; + } + else { + *buf = mi_wcsdup(p); + if (*buf==NULL) return ENOMEM; + if (size != NULL) *size = wcslen((const wchar_t*)p); + } + return 0; +#endif +} + +mi_decl_nodiscard void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft + return mi_recalloc_aligned_at(p, newcount, size, alignment, offset); +} + +mi_decl_nodiscard void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft + return mi_recalloc_aligned(p, newcount, size, alignment); +} diff --git a/Objects/mimalloc/alloc.c b/Objects/mimalloc/alloc.c new file mode 100644 index 00000000000000..f96c6f0b37f873 --- /dev/null +++ b/Objects/mimalloc/alloc.c @@ -0,0 +1,1062 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2022, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE // for realpath() on Linux +#endif + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" // _mi_prim_thread_id() + +#include // memset, strlen (for mi_strdup) +#include // malloc, abort + +#define _ZSt15get_new_handlerv _Py__ZSt15get_new_handlerv + +#define MI_IN_ALLOC_C +#include "alloc-override.c" +#undef MI_IN_ALLOC_C + +// ------------------------------------------------------ +// Allocation +// ------------------------------------------------------ + +// Fast allocation in a page: just pop from the free list. +// Fall back to generic allocation only if the list is empty. +extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept { + mi_assert_internal(page->xblock_size==0||mi_page_block_size(page) >= size); + mi_block_t* const block = page->free; + if mi_unlikely(block == NULL) { + return _mi_malloc_generic(heap, size, zero, 0); + } + mi_assert_internal(block != NULL && _mi_ptr_page(block) == page); + // pop from the free list + page->used++; + page->free = mi_block_next(page, block); + mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page); + #if MI_DEBUG>3 + if (page->free_is_zero) { + mi_assert_expensive(mi_mem_is_zero(block+1,size - sizeof(*block))); + } + #endif + + // allow use of the block internally + // note: when tracking we need to avoid ever touching the MI_PADDING since + // that is tracked by valgrind etc. as non-accessible (through the red-zone, see `mimalloc/track.h`) + mi_track_mem_undefined(block, mi_page_usable_block_size(page)); + + // zero the block? note: we need to zero the full block size (issue #63) + if mi_unlikely(zero) { + mi_assert_internal(page->xblock_size != 0); // do not call with zero'ing for huge blocks (see _mi_malloc_generic) + mi_assert_internal(page->xblock_size >= MI_PADDING_SIZE); + if (page->free_is_zero) { + block->next = 0; + mi_track_mem_defined(block, page->xblock_size - MI_PADDING_SIZE); + } + else { + _mi_memzero_aligned(block, page->xblock_size - MI_PADDING_SIZE); + } + } + +#if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN + if (!zero && !mi_page_is_huge(page)) { + memset(block, MI_DEBUG_UNINIT, mi_page_usable_block_size(page)); + } +#elif (MI_SECURE!=0) + if (!zero) { block->next = 0; } // don't leak internal data +#endif + +#if (MI_STAT>0) + const size_t bsize = mi_page_usable_block_size(page); + if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) { + mi_heap_stat_increase(heap, normal, bsize); + mi_heap_stat_counter_increase(heap, normal_count, 1); +#if (MI_STAT>1) + const size_t bin = _mi_bin(bsize); + mi_heap_stat_increase(heap, normal_bins[bin], 1); +#endif + } +#endif + +#if MI_PADDING // && !MI_TRACK_ENABLED + mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page)); + ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE)); + #if (MI_DEBUG>=2) + mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta)); + #endif + mi_track_mem_defined(padding,sizeof(mi_padding_t)); // note: re-enable since mi_page_usable_block_size may set noaccess + padding->canary = (uint32_t)(mi_ptr_encode(page,block,page->keys)); + padding->delta = (uint32_t)(delta); + #if MI_PADDING_CHECK + if (!mi_page_is_huge(page)) { + uint8_t* fill = (uint8_t*)padding - delta; + const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes + for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; } + } + #endif +#endif + + return block; +} + +static inline mi_decl_restrict void* mi_heap_malloc_small_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept { + mi_assert(heap != NULL); + #if MI_DEBUG + const uintptr_t tid = _mi_thread_id(); + mi_assert(heap->thread_id == 0 || heap->thread_id == tid); // heaps are thread local + #endif + mi_assert(size <= MI_SMALL_SIZE_MAX); + #if (MI_PADDING) + if (size == 0) { size = sizeof(void*); } + #endif + mi_page_t* page = _mi_heap_get_free_small_page(heap, size + MI_PADDING_SIZE); + void* const p = _mi_page_malloc(heap, page, size + MI_PADDING_SIZE, zero); + mi_track_malloc(p,size,zero); + #if MI_STAT>1 + if (p != NULL) { + if (!mi_heap_is_initialized(heap)) { heap = mi_prim_get_default_heap(); } + mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); + } + #endif + #if MI_DEBUG>3 + if (p != NULL && zero) { + mi_assert_expensive(mi_mem_is_zero(p, size)); + } + #endif + return p; +} + +// allocate a small block +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return mi_heap_malloc_small_zero(heap, size, false); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept { + return mi_heap_malloc_small(mi_prim_get_default_heap(), size); +} + +// The main allocation function +extern inline void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept { + if mi_likely(size <= MI_SMALL_SIZE_MAX) { + mi_assert_internal(huge_alignment == 0); + return mi_heap_malloc_small_zero(heap, size, zero); + } + else { + mi_assert(heap!=NULL); + mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local + void* const p = _mi_malloc_generic(heap, size + MI_PADDING_SIZE, zero, huge_alignment); // note: size can overflow but it is detected in malloc_generic + mi_track_malloc(p,size,zero); + #if MI_STAT>1 + if (p != NULL) { + if (!mi_heap_is_initialized(heap)) { heap = mi_prim_get_default_heap(); } + mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); + } + #endif + #if MI_DEBUG>3 + if (p != NULL && zero) { + mi_assert_expensive(mi_mem_is_zero(p, size)); + } + #endif + return p; + } +} + +extern inline void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept { + return _mi_heap_malloc_zero_ex(heap, size, zero, 0); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return _mi_heap_malloc_zero(heap, size, false); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept { + return mi_heap_malloc(mi_prim_get_default_heap(), size); +} + +// zero initialized small block +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept { + return mi_heap_malloc_small_zero(mi_prim_get_default_heap(), size, true); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return _mi_heap_malloc_zero(heap, size, true); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept { + return mi_heap_zalloc(mi_prim_get_default_heap(),size); +} + + +// ------------------------------------------------------ +// Check for double free in secure and debug mode +// This is somewhat expensive so only enabled for secure mode 4 +// ------------------------------------------------------ + +#if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0)) +// linear check if the free list contains a specific element +static bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) { + while (list != NULL) { + if (elem==list) return true; + list = mi_block_next(page, list); + } + return false; +} + +static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) { + // The decoded value is in the same page (or NULL). + // Walk the free lists to verify positively if it is already freed + if (mi_list_contains(page, page->free, block) || + mi_list_contains(page, page->local_free, block) || + mi_list_contains(page, mi_page_thread_free(page), block)) + { + _mi_error_message(EAGAIN, "double free detected of block %p with size %zu\n", block, mi_page_block_size(page)); + return true; + } + return false; +} + +#define mi_track_page(page,access) { size_t psize; void* pstart = _mi_page_start(_mi_page_segment(page),page,&psize); mi_track_mem_##access( pstart, psize); } + +static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { + bool is_double_free = false; + mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field + if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer? + (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL? + { + // Suspicous: decoded value a in block is in the same page (or NULL) -- maybe a double free? + // (continue in separate function to improve code generation) + is_double_free = mi_check_is_double_freex(page, block); + } + return is_double_free; +} +#else +static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(page); + MI_UNUSED(block); + return false; +} +#endif + +// --------------------------------------------------------------------------- +// Check for heap block overflow by setting up padding at the end of the block +// --------------------------------------------------------------------------- + +#if MI_PADDING // && !MI_TRACK_ENABLED +static bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) { + *bsize = mi_page_usable_block_size(page); + const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize); + mi_track_mem_defined(padding,sizeof(mi_padding_t)); + *delta = padding->delta; + uint32_t canary = padding->canary; + uintptr_t keys[2]; + keys[0] = page->keys[0]; + keys[1] = page->keys[1]; + bool ok = ((uint32_t)mi_ptr_encode(page,block,keys) == canary && *delta <= *bsize); + mi_track_mem_noaccess(padding,sizeof(mi_padding_t)); + return ok; +} + +// Return the exact usable size of a block. +static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + mi_assert_internal(ok); mi_assert_internal(delta <= bsize); + return (ok ? bsize - delta : 0); +} + +// When a non-thread-local block is freed, it becomes part of the thread delayed free +// list that is freed later by the owning heap. If the exact usable size is too small to +// contain the pointer for the delayed list, then shrink the padding (by decreasing delta) +// so it will later not trigger an overflow error in `mi_free_block`. +void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + mi_assert_internal(ok); + if (!ok || (bsize - delta) >= min_size) return; // usually already enough space + mi_assert_internal(bsize >= min_size); + if (bsize < min_size) return; // should never happen + size_t new_delta = (bsize - min_size); + mi_assert_internal(new_delta < bsize); + mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize); + mi_track_mem_defined(padding,sizeof(mi_padding_t)); + padding->delta = (uint32_t)new_delta; + mi_track_mem_noaccess(padding,sizeof(mi_padding_t)); +} +#else +static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(block); + return mi_page_usable_block_size(page); +} + +void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { + MI_UNUSED(page); + MI_UNUSED(block); + MI_UNUSED(min_size); +} +#endif + +#if MI_PADDING && MI_PADDING_CHECK + +static bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + *size = *wrong = bsize; + if (!ok) return false; + mi_assert_internal(bsize >= delta); + *size = bsize - delta; + if (!mi_page_is_huge(page)) { + uint8_t* fill = (uint8_t*)block + bsize - delta; + const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes + mi_track_mem_defined(fill, maxpad); + for (size_t i = 0; i < maxpad; i++) { + if (fill[i] != MI_DEBUG_PADDING) { + *wrong = bsize - delta + i; + ok = false; + break; + } + } + mi_track_mem_noaccess(fill, maxpad); + } + return ok; +} + +static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { + size_t size; + size_t wrong; + if (!mi_verify_padding(page,block,&size,&wrong)) { + _mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong ); + } +} + +#else + +static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(page); + MI_UNUSED(block); +} + +#endif + +// only maintain stats for smaller objects if requested +#if (MI_STAT>0) +static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) { + #if (MI_STAT < 2) + MI_UNUSED(block); + #endif + mi_heap_t* const heap = mi_heap_get_default(); + const size_t bsize = mi_page_usable_block_size(page); + #if (MI_STAT>1) + const size_t usize = mi_page_usable_size_of(page, block); + mi_heap_stat_decrease(heap, malloc, usize); + #endif + if (bsize <= MI_MEDIUM_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, normal, bsize); + #if (MI_STAT > 1) + mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], 1); + #endif + } + else if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); + } +} +#else +static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) { + MI_UNUSED(page); MI_UNUSED(block); +} +#endif + +#if MI_HUGE_PAGE_ABANDON +#if (MI_STAT>0) +// maintain stats for huge objects +static void mi_stat_huge_free(const mi_page_t* page) { + mi_heap_t* const heap = mi_heap_get_default(); + const size_t bsize = mi_page_block_size(page); // to match stats in `page.c:mi_page_huge_alloc` + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); + } +} +#else +static void mi_stat_huge_free(const mi_page_t* page) { + MI_UNUSED(page); +} +#endif +#endif + +// ------------------------------------------------------ +// Free +// ------------------------------------------------------ + +// multi-threaded free (or free in huge block if compiled with MI_HUGE_PAGE_ABANDON) +static mi_decl_noinline void _mi_free_block_mt(mi_page_t* page, mi_block_t* block) +{ + // The padding check may access the non-thread-owned page for the key values. + // that is safe as these are constant and the page won't be freed (as the block is not freed yet). + mi_check_padding(page, block); + _mi_padding_shrink(page, block, sizeof(mi_block_t)); // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection + + // huge page segments are always abandoned and can be freed immediately + mi_segment_t* segment = _mi_page_segment(page); + if (segment->kind == MI_SEGMENT_HUGE) { + #if MI_HUGE_PAGE_ABANDON + // huge page segments are always abandoned and can be freed immediately + mi_stat_huge_free(page); + _mi_segment_huge_page_free(segment, page, block); + return; + #else + // huge pages are special as they occupy the entire segment + // as these are large we reset the memory occupied by the page so it is available to other threads + // (as the owning thread needs to actually free the memory later). + _mi_segment_huge_page_reset(segment, page, block); + #endif + } + + #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN // note: when tracking, cannot use mi_usable_size with multi-threading + if (segment->kind != MI_SEGMENT_HUGE) { // not for huge segments as we just reset the content + memset(block, MI_DEBUG_FREED, mi_usable_size(block)); + } + #endif + + // Try to put the block on either the page-local thread free list, or the heap delayed free list. + mi_thread_free_t tfreex; + bool use_delayed; + mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free); + do { + use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE); + if mi_unlikely(use_delayed) { + // unlikely: this only happens on the first concurrent free in a page that is in the full list + tfreex = mi_tf_set_delayed(tfree,MI_DELAYED_FREEING); + } + else { + // usual: directly add to page thread_free list + mi_block_set_next(page, block, mi_tf_block(tfree)); + tfreex = mi_tf_set_block(tfree,block); + } + } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); + + if mi_unlikely(use_delayed) { + // racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`) + mi_heap_t* const heap = (mi_heap_t*)(mi_atomic_load_acquire(&page->xheap)); //mi_page_heap(page); + mi_assert_internal(heap != NULL); + if (heap != NULL) { + // add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity) + mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); + do { + mi_block_set_nextx(heap,block,dfree, heap->keys); + } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block)); + } + + // and reset the MI_DELAYED_FREEING flag + tfree = mi_atomic_load_relaxed(&page->xthread_free); + do { + tfreex = tfree; + mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING); + tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE); + } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); + } +} + +// regular free +static inline void _mi_free_block(mi_page_t* page, bool local, mi_block_t* block) +{ + // and push it on the free list + //const size_t bsize = mi_page_block_size(page); + if mi_likely(local) { + // owning thread can free a block directly + if mi_unlikely(mi_check_is_double_free(page, block)) return; + mi_check_padding(page, block); + #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN + if (!mi_page_is_huge(page)) { // huge page content may be already decommitted + memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); + } + #endif + mi_block_set_next(page, block, page->local_free); + page->local_free = block; + page->used--; + if mi_unlikely(mi_page_all_free(page)) { + _mi_page_retire(page); + } + else if mi_unlikely(mi_page_is_in_full(page)) { + _mi_page_unfull(page); + } + } + else { + _mi_free_block_mt(page,block); + } +} + + +// Adjust a block that was allocated aligned, to the actual start of the block in the page. +mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p) { + mi_assert_internal(page!=NULL && p!=NULL); + const size_t diff = (uint8_t*)p - _mi_page_start(segment, page, NULL); + const size_t adjust = (diff % mi_page_block_size(page)); + return (mi_block_t*)((uintptr_t)p - adjust); +} + + +void mi_decl_noinline _mi_free_generic(const mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept { + mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p); + mi_stat_free(page, block); // stat_free may access the padding + mi_track_free_size(block, mi_page_usable_size_of(page,block)); + _mi_free_block(page, is_local, block); +} + +// Get the segment data belonging to a pointer +// This is just a single `and` in assembly but does further checks in debug mode +// (and secure mode) if this was a valid pointer. +static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg) +{ + MI_UNUSED(msg); + mi_assert(p != NULL); + +#if (MI_DEBUG>0) + if mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) { + _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p); + return NULL; + } +#endif + + mi_segment_t* const segment = _mi_ptr_segment(p); + mi_assert_internal(segment != NULL); + +#if 0 && (MI_DEBUG>0) + if mi_unlikely(!mi_is_in_heap_region(p)) { + #if (MI_INTPTR_SIZE == 8 && defined(__linux__)) + if (((uintptr_t)p >> 40) != 0x7F) { // linux tends to align large blocks above 0x7F000000000 (issue #640) + #else + { + #endif + _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n" + "(this may still be a valid very large allocation (over 64MiB))\n", msg, p); + if mi_likely(_mi_ptr_cookie(segment) == segment->cookie) { + _mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p); + } + } + } +#endif +#if (MI_DEBUG>0 || MI_SECURE>=4) + if mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie) { + _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", msg, p); + return NULL; + } +#endif + + return segment; +} + +// Free a block +// fast path written carefully to prevent spilling on the stack +void mi_free(void* p) mi_attr_noexcept +{ + if mi_unlikely(p == NULL) return; + mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free"); + const bool is_local= (_mi_prim_thread_id() == mi_atomic_load_relaxed(&segment->thread_id)); + mi_page_t* const page = _mi_segment_page_of(segment, p); + + if mi_likely(is_local) { // thread-local free? + if mi_likely(page->flags.full_aligned == 0) // and it is not a full page (full pages need to move from the full bin), nor has aligned blocks (aligned blocks need to be unaligned) + { + mi_block_t* const block = (mi_block_t*)p; + if mi_unlikely(mi_check_is_double_free(page, block)) return; + mi_check_padding(page, block); + mi_stat_free(page, block); + #if (MI_DEBUG>0) && !MI_TRACK_ENABLED && !MI_TSAN + memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); + #endif + mi_track_free_size(p, mi_page_usable_size_of(page,block)); // faster then mi_usable_size as we already know the page and that p is unaligned + mi_block_set_next(page, block, page->local_free); + page->local_free = block; + if mi_unlikely(--page->used == 0) { // using this expression generates better code than: page->used--; if (mi_page_all_free(page)) + _mi_page_retire(page); + } + } + else { + // page is full or contains (inner) aligned blocks; use generic path + _mi_free_generic(segment, page, true, p); + } + } + else { + // not thread-local; use generic path + _mi_free_generic(segment, page, false, p); + } +} + +// return true if successful +bool _mi_free_delayed_block(mi_block_t* block) { + // get segment and page + const mi_segment_t* const segment = _mi_ptr_segment(block); + mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(_mi_thread_id() == segment->thread_id); + mi_page_t* const page = _mi_segment_page_of(segment, block); + + // Clear the no-delayed flag so delayed freeing is used again for this page. + // This must be done before collecting the free lists on this page -- otherwise + // some blocks may end up in the page `thread_free` list with no blocks in the + // heap `thread_delayed_free` list which may cause the page to be never freed! + // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`) + if (!_mi_page_try_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */)) { + return false; + } + + // collect all other non-local frees to ensure up-to-date `used` count + _mi_page_free_collect(page, false); + + // and free the block (possibly freeing the page as well since used is updated) + _mi_free_block(page, true, block); + return true; +} + +// Bytes available in a block +mi_decl_noinline static size_t mi_page_usable_aligned_size_of(const mi_segment_t* segment, const mi_page_t* page, const void* p) mi_attr_noexcept { + const mi_block_t* block = _mi_page_ptr_unalign(segment, page, p); + const size_t size = mi_page_usable_size_of(page, block); + const ptrdiff_t adjust = (uint8_t*)p - (uint8_t*)block; + mi_assert_internal(adjust >= 0 && (size_t)adjust <= size); + return (size - adjust); +} + +static inline size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept { + if (p == NULL) return 0; + const mi_segment_t* const segment = mi_checked_ptr_segment(p, msg); + const mi_page_t* const page = _mi_segment_page_of(segment, p); + if mi_likely(!mi_page_has_aligned(page)) { + const mi_block_t* block = (const mi_block_t*)p; + return mi_page_usable_size_of(page, block); + } + else { + // split out to separate routine for improved code generation + return mi_page_usable_aligned_size_of(segment, page, p); + } +} + +mi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept { + return _mi_usable_size(p, "mi_usable_size"); +} + + +// ------------------------------------------------------ +// Allocation extensions +// ------------------------------------------------------ + +void mi_free_size(void* p, size_t size) mi_attr_noexcept { + MI_UNUSED_RELEASE(size); + mi_assert(p == NULL || size <= _mi_usable_size(p,"mi_free_size")); + mi_free(p); +} + +void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept { + MI_UNUSED_RELEASE(alignment); + mi_assert(((uintptr_t)p % alignment) == 0); + mi_free_size(p,size); +} + +void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept { + MI_UNUSED_RELEASE(alignment); + mi_assert(((uintptr_t)p % alignment) == 0); + mi_free(p); +} + +mi_decl_nodiscard extern inline mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count,size,&total)) return NULL; + return mi_heap_zalloc(heap,total); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept { + return mi_heap_calloc(mi_prim_get_default_heap(),count,size); +} + +// Uninitialized `calloc` +mi_decl_nodiscard extern mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_malloc(heap, total); +} + +mi_decl_nodiscard mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept { + return mi_heap_mallocn(mi_prim_get_default_heap(),count,size); +} + +// Expand (or shrink) in place (or fail) +void* mi_expand(void* p, size_t newsize) mi_attr_noexcept { + #if MI_PADDING + // we do not shrink/expand with padding enabled + MI_UNUSED(p); MI_UNUSED(newsize); + return NULL; + #else + if (p == NULL) return NULL; + const size_t size = _mi_usable_size(p,"mi_expand"); + if (newsize > size) return NULL; + return p; // it fits + #endif +} + +void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept { + // if p == NULL then behave as malloc. + // else if size == 0 then reallocate to a zero-sized block (and don't return NULL, just as mi_malloc(0)). + // (this means that returning NULL always indicates an error, and `p` will not have been freed in that case.) + const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL (with size 0) + if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) { // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0) + mi_assert_internal(p!=NULL); + // todo: do not track as the usable size is still the same in the free; adjust potential padding? + // mi_track_resize(p,size,newsize) + // if (newsize < size) { mi_track_mem_noaccess((uint8_t*)p + newsize, size - newsize); } + return p; // reallocation still fits and not more than 50% waste + } + void* newp = mi_heap_malloc(heap,newsize); + if mi_likely(newp != NULL) { + if (zero && newsize > size) { + // also set last word in the previous allocation to zero to ensure any padding is zero-initialized + const size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); + _mi_memzero((uint8_t*)newp + start, newsize - start); + } + else if (newsize == 0) { + ((uint8_t*)newp)[0] = 0; // work around for applications that expect zero-reallocation to be zero initialized (issue #725) + } + if mi_likely(p != NULL) { + const size_t copysize = (newsize > size ? size : newsize); + mi_track_mem_defined(p,copysize); // _mi_useable_size may be too large for byte precise memory tracking.. + _mi_memcpy(newp, p, copysize); + mi_free(p); // only free the original pointer if successful + } + } + return newp; +} + +mi_decl_nodiscard void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + return _mi_heap_realloc_zero(heap, p, newsize, false); +} + +mi_decl_nodiscard void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_realloc(heap, p, total); +} + + +// Reallocate but free `p` on errors +mi_decl_nodiscard void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + void* newp = mi_heap_realloc(heap, p, newsize); + if (newp==NULL && p!=NULL) mi_free(p); + return newp; +} + +mi_decl_nodiscard void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + return _mi_heap_realloc_zero(heap, p, newsize, true); +} + +mi_decl_nodiscard void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_rezalloc(heap, p, total); +} + + +mi_decl_nodiscard void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_realloc(mi_prim_get_default_heap(),p,newsize); +} + +mi_decl_nodiscard void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept { + return mi_heap_reallocn(mi_prim_get_default_heap(),p,count,size); +} + +// Reallocate but free `p` on errors +mi_decl_nodiscard void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_reallocf(mi_prim_get_default_heap(),p,newsize); +} + +mi_decl_nodiscard void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_rezalloc(mi_prim_get_default_heap(), p, newsize); +} + +mi_decl_nodiscard void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { + return mi_heap_recalloc(mi_prim_get_default_heap(), p, count, size); +} + + + +// ------------------------------------------------------ +// strdup, strndup, and realpath +// ------------------------------------------------------ + +// `strdup` using mi_malloc +mi_decl_nodiscard mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept { + if (s == NULL) return NULL; + size_t n = strlen(s); + char* t = (char*)mi_heap_malloc(heap,n+1); + if (t == NULL) return NULL; + _mi_memcpy(t, s, n); + t[n] = 0; + return t; +} + +mi_decl_nodiscard mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept { + return mi_heap_strdup(mi_prim_get_default_heap(), s); +} + +// `strndup` using mi_malloc +mi_decl_nodiscard mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept { + if (s == NULL) return NULL; + const char* end = (const char*)memchr(s, 0, n); // find end of string in the first `n` characters (returns NULL if not found) + const size_t m = (end != NULL ? (size_t)(end - s) : n); // `m` is the minimum of `n` or the end-of-string + mi_assert_internal(m <= n); + char* t = (char*)mi_heap_malloc(heap, m+1); + if (t == NULL) return NULL; + _mi_memcpy(t, s, m); + t[m] = 0; + return t; +} + +mi_decl_nodiscard mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept { + return mi_heap_strndup(mi_prim_get_default_heap(),s,n); +} + +#ifndef __wasi__ +// `realpath` using mi_malloc +#ifdef _WIN32 +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif +#include +mi_decl_nodiscard mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { + // todo: use GetFullPathNameW to allow longer file names + char buf[PATH_MAX]; + DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL); + if (res == 0) { + errno = GetLastError(); return NULL; + } + else if (res > PATH_MAX) { + errno = EINVAL; return NULL; + } + else if (resolved_name != NULL) { + return resolved_name; + } + else { + return mi_heap_strndup(heap, buf, PATH_MAX); + } +} +#else +/* +#include // pathconf +static size_t mi_path_max(void) { + static size_t path_max = 0; + if (path_max <= 0) { + long m = pathconf("/",_PC_PATH_MAX); + if (m <= 0) path_max = 4096; // guess + else if (m < 256) path_max = 256; // at least 256 + else path_max = m; + } + return path_max; +} +*/ +char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { + if (resolved_name != NULL) { + return realpath(fname,resolved_name); + } + else { + char* rname = realpath(fname, NULL); + if (rname == NULL) return NULL; + char* result = mi_heap_strdup(heap, rname); + free(rname); // use regular free! (which may be redirected to our free but that's ok) + return result; + } + /* + const size_t n = mi_path_max(); + char* buf = (char*)mi_malloc(n+1); + if (buf == NULL) { + errno = ENOMEM; + return NULL; + } + char* rname = realpath(fname,buf); + char* result = mi_heap_strndup(heap,rname,n); // ok if `rname==NULL` + mi_free(buf); + return result; + } + */ +} +#endif + +mi_decl_nodiscard mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept { + return mi_heap_realpath(mi_prim_get_default_heap(),fname,resolved_name); +} +#endif + +/*------------------------------------------------------- +C++ new and new_aligned +The standard requires calling into `get_new_handler` and +throwing the bad_alloc exception on failure. If we compile +with a C++ compiler we can implement this precisely. If we +use a C compiler we cannot throw a `bad_alloc` exception +but we call `exit` instead (i.e. not returning). +-------------------------------------------------------*/ + +#ifdef __cplusplus +#include +static bool mi_try_new_handler(bool nothrow) { + #if defined(_MSC_VER) || (__cplusplus >= 201103L) + std::new_handler h = std::get_new_handler(); + #else + std::new_handler h = std::set_new_handler(); + std::set_new_handler(h); + #endif + if (h==NULL) { + _mi_error_message(ENOMEM, "out of memory in 'new'"); + if (!nothrow) { + throw std::bad_alloc(); + } + return false; + } + else { + h(); + return true; + } +} +#else +typedef void (*std_new_handler_t)(void); + +#if (defined(__GNUC__) || (defined(__clang__) && !defined(_MSC_VER))) // exclude clang-cl, see issue #631 +std_new_handler_t __attribute__((weak)) _ZSt15get_new_handlerv(void) { + return NULL; +} +static std_new_handler_t mi_get_new_handler(void) { + return _ZSt15get_new_handlerv(); +} +#else +// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`. +static std_new_handler_t mi_get_new_handler() { + return NULL; +} +#endif + +static bool mi_try_new_handler(bool nothrow) { + std_new_handler_t h = mi_get_new_handler(); + if (h==NULL) { + _mi_error_message(ENOMEM, "out of memory in 'new'"); + if (!nothrow) { + abort(); // cannot throw in plain C, use abort + } + return false; + } + else { + h(); + return true; + } +} +#endif + +mi_decl_export mi_decl_noinline void* mi_heap_try_new(mi_heap_t* heap, size_t size, bool nothrow ) { + void* p = NULL; + while(p == NULL && mi_try_new_handler(nothrow)) { + p = mi_heap_malloc(heap,size); + } + return p; +} + +static mi_decl_noinline void* mi_try_new(size_t size, bool nothrow) { + return mi_heap_try_new(mi_prim_get_default_heap(), size, nothrow); +} + + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) { + void* p = mi_heap_malloc(heap,size); + if mi_unlikely(p == NULL) return mi_heap_try_new(heap, size, false); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new(size_t size) { + return mi_heap_alloc_new(mi_prim_get_default_heap(), size); +} + + +mi_decl_nodiscard mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) { + size_t total; + if mi_unlikely(mi_count_size_overflow(count, size, &total)) { + mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc + return NULL; + } + else { + return mi_heap_alloc_new(heap,total); + } +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new_n(size_t count, size_t size) { + return mi_heap_alloc_new_n(mi_prim_get_default_heap(), size, count); +} + + +mi_decl_nodiscard mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept { + void* p = mi_malloc(size); + if mi_unlikely(p == NULL) return mi_try_new(size, true); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) { + void* p; + do { + p = mi_malloc_aligned(size, alignment); + } + while(p == NULL && mi_try_new_handler(false)); + return p; +} + +mi_decl_nodiscard mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept { + void* p; + do { + p = mi_malloc_aligned(size, alignment); + } + while(p == NULL && mi_try_new_handler(true)); + return p; +} + +mi_decl_nodiscard void* mi_new_realloc(void* p, size_t newsize) { + void* q; + do { + q = mi_realloc(p, newsize); + } while (q == NULL && mi_try_new_handler(false)); + return q; +} + +mi_decl_nodiscard void* mi_new_reallocn(void* p, size_t newcount, size_t size) { + size_t total; + if mi_unlikely(mi_count_size_overflow(newcount, size, &total)) { + mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc + return NULL; + } + else { + return mi_new_realloc(p, total); + } +} + +// ------------------------------------------------------ +// ensure explicit external inline definitions are emitted! +// ------------------------------------------------------ + +#ifdef __cplusplus +void* _mi_externs[] = { + (void*)&_mi_page_malloc, + (void*)&_mi_heap_malloc_zero, + (void*)&_mi_heap_malloc_zero_ex, + (void*)&mi_malloc, + (void*)&mi_malloc_small, + (void*)&mi_zalloc_small, + (void*)&mi_heap_malloc, + (void*)&mi_heap_zalloc, + (void*)&mi_heap_malloc_small, + // (void*)&mi_heap_alloc_new, + // (void*)&mi_heap_alloc_new_n +}; +#endif diff --git a/Objects/mimalloc/arena.c b/Objects/mimalloc/arena.c new file mode 100644 index 00000000000000..f8883603860dce --- /dev/null +++ b/Objects/mimalloc/arena.c @@ -0,0 +1,935 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +"Arenas" are fixed area's of OS memory from which we can allocate +large blocks (>= MI_ARENA_MIN_BLOCK_SIZE, 4MiB). +In contrast to the rest of mimalloc, the arenas are shared between +threads and need to be accessed using atomic operations. + +Arenas are used to for huge OS page (1GiB) reservations or for reserving +OS memory upfront which can be improve performance or is sometimes needed +on embedded devices. We can also employ this with WASI or `sbrk` systems +to reserve large arenas upfront and be able to reuse the memory more effectively. + +The arena allocation needs to be thread safe and we use an atomic bitmap to allocate. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +#include // memset +#include // ENOMEM + +#include "bitmap.h" // atomic bitmap + +/* ----------------------------------------------------------- + Arena allocation +----------------------------------------------------------- */ + +// Block info: bit 0 contains the `in_use` bit, the upper bits the +// size in count of arena blocks. +typedef uintptr_t mi_block_info_t; +#define MI_ARENA_BLOCK_SIZE (MI_SEGMENT_SIZE) // 64MiB (must be at least MI_SEGMENT_ALIGN) +#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2) // 32MiB +#define MI_MAX_ARENAS (112) // not more than 126 (since we use 7 bits in the memid and an arena index + 1) + +// A memory arena descriptor +typedef struct mi_arena_s { + mi_arena_id_t id; // arena id; 0 for non-specific + mi_memid_t memid; // memid of the memory area + _Atomic(uint8_t*) start; // the start of the memory area + size_t block_count; // size of the area in arena blocks (of `MI_ARENA_BLOCK_SIZE`) + size_t field_count; // number of bitmap fields (where `field_count * MI_BITMAP_FIELD_BITS >= block_count`) + size_t meta_size; // size of the arena structure itself (including its bitmaps) + mi_memid_t meta_memid; // memid of the arena structure itself (OS or static allocation) + int numa_node; // associated NUMA node + bool exclusive; // only allow allocations if specifically for this arena + bool is_large; // memory area consists of large- or huge OS pages (always committed) + _Atomic(size_t) search_idx; // optimization to start the search for free blocks + _Atomic(mi_msecs_t) purge_expire; // expiration time when blocks should be decommitted from `blocks_decommit`. + mi_bitmap_field_t* blocks_dirty; // are the blocks potentially non-zero? + mi_bitmap_field_t* blocks_committed; // are the blocks committed? (can be NULL for memory that cannot be decommitted) + mi_bitmap_field_t* blocks_purge; // blocks that can be (reset) decommitted. (can be NULL for memory that cannot be (reset) decommitted) + mi_bitmap_field_t blocks_inuse[1]; // in-place bitmap of in-use blocks (of size `field_count`) +} mi_arena_t; + + +// The available arenas +static mi_decl_cache_align _Atomic(mi_arena_t*) mi_arenas[MI_MAX_ARENAS]; +static mi_decl_cache_align _Atomic(size_t) mi_arena_count; // = 0 + + +//static bool mi_manage_os_memory_ex2(void* start, size_t size, bool is_large, int numa_node, bool exclusive, mi_memid_t memid, mi_arena_id_t* arena_id) mi_attr_noexcept; + +/* ----------------------------------------------------------- + Arena id's + id = arena_index + 1 +----------------------------------------------------------- */ + +static size_t mi_arena_id_index(mi_arena_id_t id) { + return (size_t)(id <= 0 ? MI_MAX_ARENAS : id - 1); +} + +static mi_arena_id_t mi_arena_id_create(size_t arena_index) { + mi_assert_internal(arena_index < MI_MAX_ARENAS); + return (int)arena_index + 1; +} + +mi_arena_id_t _mi_arena_id_none(void) { + return 0; +} + +static bool mi_arena_id_is_suitable(mi_arena_id_t arena_id, bool arena_is_exclusive, mi_arena_id_t req_arena_id) { + return ((!arena_is_exclusive && req_arena_id == _mi_arena_id_none()) || + (arena_id == req_arena_id)); +} + +bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id) { + if (memid.memkind == MI_MEM_ARENA) { + return mi_arena_id_is_suitable(memid.mem.arena.id, memid.mem.arena.is_exclusive, request_arena_id); + } + else { + return mi_arena_id_is_suitable(0, false, request_arena_id); + } +} + +bool _mi_arena_memid_is_os_allocated(mi_memid_t memid) { + return (memid.memkind == MI_MEM_OS); +} + +/* ----------------------------------------------------------- + Arena allocations get a (currently) 16-bit memory id where the + lower 8 bits are the arena id, and the upper bits the block index. +----------------------------------------------------------- */ + +static size_t mi_block_count_of_size(size_t size) { + return _mi_divide_up(size, MI_ARENA_BLOCK_SIZE); +} + +static size_t mi_arena_block_size(size_t bcount) { + return (bcount * MI_ARENA_BLOCK_SIZE); +} + +static size_t mi_arena_size(mi_arena_t* arena) { + return mi_arena_block_size(arena->block_count); +} + +static mi_memid_t mi_memid_create_arena(mi_arena_id_t id, bool is_exclusive, mi_bitmap_index_t bitmap_index) { + mi_memid_t memid = _mi_memid_create(MI_MEM_ARENA); + memid.mem.arena.id = id; + memid.mem.arena.block_index = bitmap_index; + memid.mem.arena.is_exclusive = is_exclusive; + return memid; +} + +static bool mi_arena_memid_indices(mi_memid_t memid, size_t* arena_index, mi_bitmap_index_t* bitmap_index) { + mi_assert_internal(memid.memkind == MI_MEM_ARENA); + *arena_index = mi_arena_id_index(memid.mem.arena.id); + *bitmap_index = memid.mem.arena.block_index; + return memid.mem.arena.is_exclusive; +} + + + +/* ----------------------------------------------------------- + Special static area for mimalloc internal structures + to avoid OS calls (for example, for the arena metadata) +----------------------------------------------------------- */ + +#define MI_ARENA_STATIC_MAX (MI_INTPTR_SIZE*MI_KiB) // 8 KiB on 64-bit + +static uint8_t mi_arena_static[MI_ARENA_STATIC_MAX]; +static _Atomic(size_t) mi_arena_static_top; + +static void* mi_arena_static_zalloc(size_t size, size_t alignment, mi_memid_t* memid) { + *memid = _mi_memid_none(); + if (size == 0 || size > MI_ARENA_STATIC_MAX) return NULL; + if ((mi_atomic_load_relaxed(&mi_arena_static_top) + size) > MI_ARENA_STATIC_MAX) return NULL; + + // try to claim space + if (alignment == 0) { alignment = 1; } + const size_t oversize = size + alignment - 1; + if (oversize > MI_ARENA_STATIC_MAX) return NULL; + const size_t oldtop = mi_atomic_add_acq_rel(&mi_arena_static_top, oversize); + size_t top = oldtop + oversize; + if (top > MI_ARENA_STATIC_MAX) { + // try to roll back, ok if this fails + mi_atomic_cas_strong_acq_rel(&mi_arena_static_top, &top, oldtop); + return NULL; + } + + // success + *memid = _mi_memid_create(MI_MEM_STATIC); + const size_t start = _mi_align_up(oldtop, alignment); + uint8_t* const p = &mi_arena_static[start]; + _mi_memzero(p, size); + return p; +} + +static void* mi_arena_meta_zalloc(size_t size, mi_memid_t* memid, mi_stats_t* stats) { + *memid = _mi_memid_none(); + + // try static + void* p = mi_arena_static_zalloc(size, MI_ALIGNMENT_MAX, memid); + if (p != NULL) return p; + + // or fall back to the OS + return _mi_os_alloc(size, memid, stats); +} + +static void mi_arena_meta_free(void* p, mi_memid_t memid, size_t size, mi_stats_t* stats) { + if (mi_memkind_is_os(memid.memkind)) { + _mi_os_free(p, size, memid, stats); + } + else { + mi_assert(memid.memkind == MI_MEM_STATIC); + } +} + +static void* mi_arena_block_start(mi_arena_t* arena, mi_bitmap_index_t bindex) { + return (arena->start + mi_arena_block_size(mi_bitmap_index_bit(bindex))); +} + + +/* ----------------------------------------------------------- + Thread safe allocation in an arena +----------------------------------------------------------- */ + +// claim the `blocks_inuse` bits +static bool mi_arena_try_claim(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx) +{ + size_t idx = 0; // mi_atomic_load_relaxed(&arena->search_idx); // start from last search; ok to be relaxed as the exact start does not matter + if (_mi_bitmap_try_find_from_claim_across(arena->blocks_inuse, arena->field_count, idx, blocks, bitmap_idx)) { + mi_atomic_store_relaxed(&arena->search_idx, mi_bitmap_index_field(*bitmap_idx)); // start search from found location next time around + return true; + }; + return false; +} + + +/* ----------------------------------------------------------- + Arena Allocation +----------------------------------------------------------- */ + +static mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t arena_index, size_t needed_bcount, + bool commit, mi_memid_t* memid, mi_os_tld_t* tld) +{ + MI_UNUSED(arena_index); + mi_assert_internal(mi_arena_id_index(arena->id) == arena_index); + + mi_bitmap_index_t bitmap_index; + if (!mi_arena_try_claim(arena, needed_bcount, &bitmap_index)) return NULL; + + // claimed it! + void* p = mi_arena_block_start(arena, bitmap_index); + *memid = mi_memid_create_arena(arena->id, arena->exclusive, bitmap_index); + memid->is_pinned = arena->memid.is_pinned; + + // none of the claimed blocks should be scheduled for a decommit + if (arena->blocks_purge != NULL) { + // this is thread safe as a potential purge only decommits parts that are not yet claimed as used (in `blocks_inuse`). + _mi_bitmap_unclaim_across(arena->blocks_purge, arena->field_count, needed_bcount, bitmap_index); + } + + // set the dirty bits (todo: no need for an atomic op here?) + if (arena->memid.initially_zero && arena->blocks_dirty != NULL) { + memid->initially_zero = _mi_bitmap_claim_across(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL); + } + + // set commit state + if (arena->blocks_committed == NULL) { + // always committed + memid->initially_committed = true; + } + else if (commit) { + // commit requested, but the range may not be committed as a whole: ensure it is committed now + memid->initially_committed = true; + bool any_uncommitted; + _mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted); + if (any_uncommitted) { + bool commit_zero = false; + if (!_mi_os_commit(p, mi_arena_block_size(needed_bcount), &commit_zero, tld->stats)) { + memid->initially_committed = false; + } + else { + if (commit_zero) { memid->initially_zero = true; } + } + } + } + else { + // no need to commit, but check if already fully committed + memid->initially_committed = _mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index); + } + + return p; +} + +// allocate in a speficic arena +static void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_node, int numa_node, size_t size, size_t alignment, + bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld ) +{ + MI_UNUSED_RELEASE(alignment); + mi_assert_internal(alignment <= MI_SEGMENT_ALIGN); + const size_t bcount = mi_block_count_of_size(size); + const size_t arena_index = mi_arena_id_index(arena_id); + mi_assert_internal(arena_index < mi_atomic_load_relaxed(&mi_arena_count)); + mi_assert_internal(size <= mi_arena_block_size(bcount)); + + // Check arena suitability + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[arena_index]); + if (arena == NULL) return NULL; + if (!allow_large && arena->is_large) return NULL; + if (!mi_arena_id_is_suitable(arena->id, arena->exclusive, req_arena_id)) return NULL; + if (req_arena_id == _mi_arena_id_none()) { // in not specific, check numa affinity + const bool numa_suitable = (numa_node < 0 || arena->numa_node < 0 || arena->numa_node == numa_node); + if (match_numa_node) { if (!numa_suitable) return NULL; } + else { if (numa_suitable) return NULL; } + } + + // try to allocate + void* p = mi_arena_try_alloc_at(arena, arena_index, bcount, commit, memid, tld); + mi_assert_internal(p == NULL || _mi_is_aligned(p, alignment)); + return p; +} + + +// allocate from an arena with fallback to the OS +static mi_decl_noinline void* mi_arena_try_alloc(int numa_node, size_t size, size_t alignment, + bool commit, bool allow_large, + mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld ) +{ + MI_UNUSED(alignment); + mi_assert_internal(alignment <= MI_SEGMENT_ALIGN); + const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count); + if mi_likely(max_arena == 0) return NULL; + + if (req_arena_id != _mi_arena_id_none()) { + // try a specific arena if requested + if (mi_arena_id_index(req_arena_id) < max_arena) { + void* p = mi_arena_try_alloc_at_id(req_arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + } + else { + // try numa affine allocation + for (size_t i = 0; i < max_arena; i++) { + void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + + // try from another numa node instead.. + if (numa_node >= 0) { // if numa_node was < 0 (no specific affinity requested), all arena's have been tried already + for (size_t i = 0; i < max_arena; i++) { + void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), false /* only proceed if not numa local */, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + } + } + return NULL; +} + +// try to reserve a fresh arena space +static bool mi_arena_reserve(size_t req_size, bool allow_large, mi_arena_id_t req_arena_id, mi_arena_id_t *arena_id) +{ + if (_mi_preloading()) return false; // use OS only while pre loading + if (req_arena_id != _mi_arena_id_none()) return false; + + const size_t arena_count = mi_atomic_load_acquire(&mi_arena_count); + if (arena_count > (MI_MAX_ARENAS - 4)) return false; + + size_t arena_reserve = mi_option_get_size(mi_option_arena_reserve); + if (arena_reserve == 0) return false; + + if (!_mi_os_has_virtual_reserve()) { + arena_reserve = arena_reserve/4; // be conservative if virtual reserve is not supported (for some embedded systems for example) + } + arena_reserve = _mi_align_up(arena_reserve, MI_ARENA_BLOCK_SIZE); + if (arena_count >= 8 && arena_count <= 128) { + arena_reserve = ((size_t)1<<(arena_count/8)) * arena_reserve; // scale up the arena sizes exponentially + } + if (arena_reserve < req_size) return false; // should be able to at least handle the current allocation size + + // commit eagerly? + bool arena_commit = false; + if (mi_option_get(mi_option_arena_eager_commit) == 2) { arena_commit = _mi_os_has_overcommit(); } + else if (mi_option_get(mi_option_arena_eager_commit) == 1) { arena_commit = true; } + + return (mi_reserve_os_memory_ex(arena_reserve, arena_commit, allow_large, false /* exclusive */, arena_id) == 0); +} + + +void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, + mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld) +{ + mi_assert_internal(memid != NULL && tld != NULL); + mi_assert_internal(size > 0); + *memid = _mi_memid_none(); + + const int numa_node = _mi_os_numa_node(tld); // current numa node + + // try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data) + if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0) { + void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + + // otherwise, try to first eagerly reserve a new arena + if (req_arena_id == _mi_arena_id_none()) { + mi_arena_id_t arena_id = 0; + if (mi_arena_reserve(size, allow_large, req_arena_id, &arena_id)) { + // and try allocate in there + mi_assert_internal(req_arena_id == _mi_arena_id_none()); + p = mi_arena_try_alloc_at_id(arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); + if (p != NULL) return p; + } + } + } + + // if we cannot use OS allocation, return NULL + if (mi_option_is_enabled(mi_option_limit_os_alloc) || req_arena_id != _mi_arena_id_none()) { + errno = ENOMEM; + return NULL; + } + + // finally, fall back to the OS + if (align_offset > 0) { + return _mi_os_alloc_aligned_at_offset(size, alignment, align_offset, commit, allow_large, memid, tld->stats); + } + else { + return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld->stats); + } +} + +void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld) +{ + return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, 0, commit, allow_large, req_arena_id, memid, tld); +} + + +void* mi_arena_area(mi_arena_id_t arena_id, size_t* size) { + if (size != NULL) *size = 0; + size_t arena_index = mi_arena_id_index(arena_id); + if (arena_index >= MI_MAX_ARENAS) return NULL; + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[arena_index]); + if (arena == NULL) return NULL; + if (size != NULL) { *size = mi_arena_block_size(arena->block_count); } + return arena->start; +} + + +/* ----------------------------------------------------------- + Arena purge +----------------------------------------------------------- */ + +static long mi_arena_purge_delay(void) { + // <0 = no purging allowed, 0=immediate purging, >0=milli-second delay + return (mi_option_get(mi_option_purge_delay) * mi_option_get(mi_option_arena_purge_mult)); +} + +// reset or decommit in an arena and update the committed/decommit bitmaps +// assumes we own the area (i.e. blocks_in_use is claimed by us) +static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) { + mi_assert_internal(arena->blocks_committed != NULL); + mi_assert_internal(arena->blocks_purge != NULL); + mi_assert_internal(!arena->memid.is_pinned); + const size_t size = mi_arena_block_size(blocks); + void* const p = mi_arena_block_start(arena, bitmap_idx); + bool needs_recommit; + if (_mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx)) { + // all blocks are committed, we can purge freely + needs_recommit = _mi_os_purge(p, size, stats); + } + else { + // some blocks are not committed -- this can happen when a partially committed block is freed + // in `_mi_arena_free` and it is conservatively marked as uncommitted but still scheduled for a purge + // we need to ensure we do not try to reset (as that may be invalid for uncommitted memory), + // and also undo the decommit stats (as it was already adjusted) + mi_assert_internal(mi_option_is_enabled(mi_option_purge_decommits)); + needs_recommit = _mi_os_purge_ex(p, size, false /* allow reset? */, stats); + _mi_stat_increase(&stats->committed, size); + } + + // clear the purged blocks + _mi_bitmap_unclaim_across(arena->blocks_purge, arena->field_count, blocks, bitmap_idx); + // update committed bitmap + if (needs_recommit) { + _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx); + } +} + +// Schedule a purge. This is usually delayed to avoid repeated decommit/commit calls. +// Note: assumes we (still) own the area as we may purge immediately +static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) { + mi_assert_internal(arena->blocks_purge != NULL); + const long delay = mi_arena_purge_delay(); + if (delay < 0) return; // is purging allowed at all? + + if (_mi_preloading() || delay == 0) { + // decommit directly + mi_arena_purge(arena, bitmap_idx, blocks, stats); + } + else { + // schedule decommit + mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire); + if (expire != 0) { + mi_atomic_addi64_acq_rel(&arena->purge_expire, delay/10); // add smallish extra delay + } + else { + mi_atomic_storei64_release(&arena->purge_expire, _mi_clock_now() + delay); + } + _mi_bitmap_claim_across(arena->blocks_purge, arena->field_count, blocks, bitmap_idx, NULL); + } +} + +// purge a range of blocks +// return true if the full range was purged. +// assumes we own the area (i.e. blocks_in_use is claimed by us) +static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx, size_t bitlen, size_t purge, mi_stats_t* stats) { + const size_t endidx = startidx + bitlen; + size_t bitidx = startidx; + bool all_purged = false; + while (bitidx < endidx) { + // count consequetive ones in the purge mask + size_t count = 0; + while (bitidx + count < endidx && (purge & ((size_t)1 << (bitidx + count))) != 0) { + count++; + } + if (count > 0) { + // found range to be purged + const mi_bitmap_index_t range_idx = mi_bitmap_index_create(idx, bitidx); + mi_arena_purge(arena, range_idx, count, stats); + if (count == bitlen) { + all_purged = true; + } + } + bitidx += (count+1); // +1 to skip the zero bit (or end) + } + return all_purged; +} + +// returns true if anything was purged +static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi_stats_t* stats) +{ + if (arena->memid.is_pinned || arena->blocks_purge == NULL) return false; + mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire); + if (expire == 0) return false; + if (!force && expire > now) return false; + + // reset expire (if not already set concurrently) + mi_atomic_casi64_strong_acq_rel(&arena->purge_expire, &expire, 0); + + // potential purges scheduled, walk through the bitmap + bool any_purged = false; + bool full_purge = true; + for (size_t i = 0; i < arena->field_count; i++) { + size_t purge = mi_atomic_load_relaxed(&arena->blocks_purge[i]); + if (purge != 0) { + size_t bitidx = 0; + while (bitidx < MI_BITMAP_FIELD_BITS) { + // find consequetive range of ones in the purge mask + size_t bitlen = 0; + while (bitidx + bitlen < MI_BITMAP_FIELD_BITS && (purge & ((size_t)1 << (bitidx + bitlen))) != 0) { + bitlen++; + } + // try to claim the longest range of corresponding in_use bits + const mi_bitmap_index_t bitmap_index = mi_bitmap_index_create(i, bitidx); + while( bitlen > 0 ) { + if (_mi_bitmap_try_claim(arena->blocks_inuse, arena->field_count, bitlen, bitmap_index)) { + break; + } + bitlen--; + } + // actual claimed bits at `in_use` + if (bitlen > 0) { + // read purge again now that we have the in_use bits + purge = mi_atomic_load_acquire(&arena->blocks_purge[i]); + if (!mi_arena_purge_range(arena, i, bitidx, bitlen, purge, stats)) { + full_purge = false; + } + any_purged = true; + // release the claimed `in_use` bits again + _mi_bitmap_unclaim(arena->blocks_inuse, arena->field_count, bitlen, bitmap_index); + } + bitidx += (bitlen+1); // +1 to skip the zero (or end) + } // while bitidx + } // purge != 0 + } + // if not fully purged, make sure to purge again in the future + if (!full_purge) { + const long delay = mi_arena_purge_delay(); + mi_msecs_t expected = 0; + mi_atomic_casi64_strong_acq_rel(&arena->purge_expire,&expected,_mi_clock_now() + delay); + } + return any_purged; +} + +static void mi_arenas_try_purge( bool force, bool visit_all, mi_stats_t* stats ) { + if (_mi_preloading() || mi_arena_purge_delay() <= 0) return; // nothing will be scheduled + + const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count); + if (max_arena == 0) return; + + // allow only one thread to purge at a time + static mi_atomic_guard_t purge_guard; + mi_atomic_guard(&purge_guard) + { + mi_msecs_t now = _mi_clock_now(); + size_t max_purge_count = (visit_all ? max_arena : 1); + for (size_t i = 0; i < max_arena; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]); + if (arena != NULL) { + if (mi_arena_try_purge(arena, now, force, stats)) { + if (max_purge_count <= 1) break; + max_purge_count--; + } + } + } + } +} + + +/* ----------------------------------------------------------- + Arena free +----------------------------------------------------------- */ + +void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memid, mi_stats_t* stats) { + mi_assert_internal(size > 0 && stats != NULL); + mi_assert_internal(committed_size <= size); + if (p==NULL) return; + if (size==0) return; + const bool all_committed = (committed_size == size); + + if (mi_memkind_is_os(memid.memkind)) { + // was a direct OS allocation, pass through + if (!all_committed && committed_size > 0) { + // if partially committed, adjust the committed stats (as `_mi_os_free` will increase decommit by the full size) + _mi_stat_decrease(&stats->committed, committed_size); + } + _mi_os_free(p, size, memid, stats); + } + else if (memid.memkind == MI_MEM_ARENA) { + // allocated in an arena + size_t arena_idx; + size_t bitmap_idx; + mi_arena_memid_indices(memid, &arena_idx, &bitmap_idx); + mi_assert_internal(arena_idx < MI_MAX_ARENAS); + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t,&mi_arenas[arena_idx]); + mi_assert_internal(arena != NULL); + const size_t blocks = mi_block_count_of_size(size); + + // checks + if (arena == NULL) { + _mi_error_message(EINVAL, "trying to free from non-existent arena: %p, size %zu, memid: 0x%zx\n", p, size, memid); + return; + } + mi_assert_internal(arena->field_count > mi_bitmap_index_field(bitmap_idx)); + if (arena->field_count <= mi_bitmap_index_field(bitmap_idx)) { + _mi_error_message(EINVAL, "trying to free from non-existent arena block: %p, size %zu, memid: 0x%zx\n", p, size, memid); + return; + } + + // need to set all memory to undefined as some parts may still be marked as no_access (like padding etc.) + mi_track_mem_undefined(p,size); + + // potentially decommit + if (arena->memid.is_pinned || arena->blocks_committed == NULL) { + mi_assert_internal(all_committed); + } + else { + mi_assert_internal(arena->blocks_committed != NULL); + mi_assert_internal(arena->blocks_purge != NULL); + + if (!all_committed) { + // mark the entire range as no longer committed (so we recommit the full range when re-using) + _mi_bitmap_unclaim_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx); + mi_track_mem_noaccess(p,size); + if (committed_size > 0) { + // if partially committed, adjust the committed stats (is it will be recommitted when re-using) + // in the delayed purge, we now need to not count a decommit if the range is not marked as committed. + _mi_stat_decrease(&stats->committed, committed_size); + } + // note: if not all committed, it may be that the purge will reset/decommit the entire range + // that contains already decommitted parts. Since purge consistently uses reset or decommit that + // works (as we should never reset decommitted parts). + } + // (delay) purge the entire range + mi_arena_schedule_purge(arena, bitmap_idx, blocks, stats); + } + + // and make it available to others again + bool all_inuse = _mi_bitmap_unclaim_across(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx); + if (!all_inuse) { + _mi_error_message(EAGAIN, "trying to free an already freed arena block: %p, size %zu\n", p, size); + return; + }; + } + else { + // arena was none, external, or static; nothing to do + mi_assert_internal(memid.memkind < MI_MEM_OS); + } + + // purge expired decommits + mi_arenas_try_purge(false, false, stats); +} + +// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit` +// for dynamic libraries that are unloaded and need to release all their allocated memory. +static void mi_arenas_unsafe_destroy(void) { + const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count); + size_t new_max_arena = 0; + for (size_t i = 0; i < max_arena; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]); + if (arena != NULL) { + if (arena->start != NULL && mi_memkind_is_os(arena->memid.memkind)) { + mi_atomic_store_ptr_release(mi_arena_t, &mi_arenas[i], NULL); + _mi_os_free(arena->start, mi_arena_size(arena), arena->memid, &_mi_stats_main); + } + else { + new_max_arena = i; + } + mi_arena_meta_free(arena, arena->meta_memid, arena->meta_size, &_mi_stats_main); + } + } + + // try to lower the max arena. + size_t expected = max_arena; + mi_atomic_cas_strong_acq_rel(&mi_arena_count, &expected, new_max_arena); +} + +// Purge the arenas; if `force_purge` is true, amenable parts are purged even if not yet expired +void _mi_arena_collect(bool force_purge, mi_stats_t* stats) { + mi_arenas_try_purge(force_purge, true /* visit all */, stats); +} + +// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit` +// for dynamic libraries that are unloaded and need to release all their allocated memory. +void _mi_arena_unsafe_destroy_all(mi_stats_t* stats) { + mi_arenas_unsafe_destroy(); + _mi_arena_collect(true /* force purge */, stats); // purge non-owned arenas +} + +// Is a pointer inside any of our arenas? +bool _mi_arena_contains(const void* p) { + const size_t max_arena = mi_atomic_load_relaxed(&mi_arena_count); + for (size_t i = 0; i < max_arena; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]); + if (arena != NULL && arena->start <= (const uint8_t*)p && arena->start + mi_arena_block_size(arena->block_count) > (const uint8_t*)p) { + return true; + } + } + return false; +} + + +/* ----------------------------------------------------------- + Add an arena. +----------------------------------------------------------- */ + +static bool mi_arena_add(mi_arena_t* arena, mi_arena_id_t* arena_id) { + mi_assert_internal(arena != NULL); + mi_assert_internal((uintptr_t)mi_atomic_load_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0); + mi_assert_internal(arena->block_count > 0); + if (arena_id != NULL) { *arena_id = -1; } + + size_t i = mi_atomic_increment_acq_rel(&mi_arena_count); + if (i >= MI_MAX_ARENAS) { + mi_atomic_decrement_acq_rel(&mi_arena_count); + return false; + } + arena->id = mi_arena_id_create(i); + mi_atomic_store_ptr_release(mi_arena_t,&mi_arenas[i], arena); + if (arena_id != NULL) { *arena_id = arena->id; } + return true; +} + +static bool mi_manage_os_memory_ex2(void* start, size_t size, bool is_large, int numa_node, bool exclusive, mi_memid_t memid, mi_arena_id_t* arena_id) mi_attr_noexcept +{ + if (arena_id != NULL) *arena_id = _mi_arena_id_none(); + if (size < MI_ARENA_BLOCK_SIZE) return false; + + if (is_large) { + mi_assert_internal(memid.initially_committed && memid.is_pinned); + } + + const size_t bcount = size / MI_ARENA_BLOCK_SIZE; + const size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS); + const size_t bitmaps = (memid.is_pinned ? 2 : 4); + const size_t asize = sizeof(mi_arena_t) + (bitmaps*fields*sizeof(mi_bitmap_field_t)); + mi_memid_t meta_memid; + mi_arena_t* arena = (mi_arena_t*)mi_arena_meta_zalloc(asize, &meta_memid, &_mi_stats_main); // TODO: can we avoid allocating from the OS? + if (arena == NULL) return false; + + // already zero'd due to os_alloc + // _mi_memzero(arena, asize); + arena->id = _mi_arena_id_none(); + arena->memid = memid; + arena->exclusive = exclusive; + arena->meta_size = asize; + arena->meta_memid = meta_memid; + arena->block_count = bcount; + arena->field_count = fields; + arena->start = (uint8_t*)start; + arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1) + arena->is_large = is_large; + arena->purge_expire = 0; + arena->search_idx = 0; + arena->blocks_dirty = &arena->blocks_inuse[fields]; // just after inuse bitmap + arena->blocks_committed = (arena->memid.is_pinned ? NULL : &arena->blocks_inuse[2*fields]); // just after dirty bitmap + arena->blocks_purge = (arena->memid.is_pinned ? NULL : &arena->blocks_inuse[3*fields]); // just after committed bitmap + // initialize committed bitmap? + if (arena->blocks_committed != NULL && arena->memid.initially_committed) { + memset((void*)arena->blocks_committed, 0xFF, fields*sizeof(mi_bitmap_field_t)); // cast to void* to avoid atomic warning + } + + // and claim leftover blocks if needed (so we never allocate there) + ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount; + mi_assert_internal(post >= 0); + if (post > 0) { + // don't use leftover bits at the end + mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post); + _mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL); + } + return mi_arena_add(arena, arena_id); + +} + +bool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept { + mi_memid_t memid = _mi_memid_create(MI_MEM_EXTERNAL); + memid.initially_committed = is_committed; + memid.initially_zero = is_zero; + memid.is_pinned = is_large; + return mi_manage_os_memory_ex2(start,size,is_large,numa_node,exclusive,memid, arena_id); +} + +// Reserve a range of regular OS memory +int mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept { + if (arena_id != NULL) *arena_id = _mi_arena_id_none(); + size = _mi_align_up(size, MI_ARENA_BLOCK_SIZE); // at least one block + mi_memid_t memid; + void* start = _mi_os_alloc_aligned(size, MI_SEGMENT_ALIGN, commit, allow_large, &memid, &_mi_stats_main); + if (start == NULL) return ENOMEM; + const bool is_large = memid.is_pinned; // todo: use separate is_large field? + if (!mi_manage_os_memory_ex2(start, size, is_large, -1 /* numa node */, exclusive, memid, arena_id)) { + _mi_os_free_ex(start, size, commit, memid, &_mi_stats_main); + _mi_verbose_message("failed to reserve %zu k memory\n", _mi_divide_up(size, 1024)); + return ENOMEM; + } + _mi_verbose_message("reserved %zu KiB memory%s\n", _mi_divide_up(size, 1024), is_large ? " (in large os pages)" : ""); + return 0; +} + + +// Manage a range of regular OS memory +bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept { + return mi_manage_os_memory_ex(start, size, is_committed, is_large, is_zero, numa_node, false /* exclusive? */, NULL); +} + +// Reserve a range of regular OS memory +int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept { + return mi_reserve_os_memory_ex(size, commit, allow_large, false, NULL); +} + + +/* ----------------------------------------------------------- + Debugging +----------------------------------------------------------- */ + +static size_t mi_debug_show_bitmap(const char* prefix, mi_bitmap_field_t* fields, size_t field_count ) { + size_t inuse_count = 0; + for (size_t i = 0; i < field_count; i++) { + char buf[MI_BITMAP_FIELD_BITS + 1]; + uintptr_t field = mi_atomic_load_relaxed(&fields[i]); + for (size_t bit = 0; bit < MI_BITMAP_FIELD_BITS; bit++) { + bool inuse = ((((uintptr_t)1 << bit) & field) != 0); + if (inuse) inuse_count++; + buf[MI_BITMAP_FIELD_BITS - 1 - bit] = (inuse ? 'x' : '.'); + } + buf[MI_BITMAP_FIELD_BITS] = 0; + _mi_verbose_message("%s%s\n", prefix, buf); + } + return inuse_count; +} + +void mi_debug_show_arenas(void) mi_attr_noexcept { + size_t max_arenas = mi_atomic_load_relaxed(&mi_arena_count); + for (size_t i = 0; i < max_arenas; i++) { + mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]); + if (arena == NULL) break; + size_t inuse_count = 0; + _mi_verbose_message("arena %zu: %zu blocks with %zu fields\n", i, arena->block_count, arena->field_count); + inuse_count += mi_debug_show_bitmap(" ", arena->blocks_inuse, arena->field_count); + _mi_verbose_message(" blocks in use ('x'): %zu\n", inuse_count); + } +} + + +/* ----------------------------------------------------------- + Reserve a huge page arena. +----------------------------------------------------------- */ +// reserve at a specific numa node +int mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept { + if (arena_id != NULL) *arena_id = -1; + if (pages==0) return 0; + if (numa_node < -1) numa_node = -1; + if (numa_node >= 0) numa_node = numa_node % _mi_os_numa_node_count(); + size_t hsize = 0; + size_t pages_reserved = 0; + mi_memid_t memid; + void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize, &memid); + if (p==NULL || pages_reserved==0) { + _mi_warning_message("failed to reserve %zu GiB huge pages\n", pages); + return ENOMEM; + } + _mi_verbose_message("numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\n", numa_node, pages_reserved, pages); + + if (!mi_manage_os_memory_ex2(p, hsize, true, numa_node, exclusive, memid, arena_id)) { + _mi_os_free(p, hsize, memid, &_mi_stats_main); + return ENOMEM; + } + return 0; +} + +int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept { + return mi_reserve_huge_os_pages_at_ex(pages, numa_node, timeout_msecs, false, NULL); +} + +// reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected) +int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept { + if (pages == 0) return 0; + + // pages per numa node + size_t numa_count = (numa_nodes > 0 ? numa_nodes : _mi_os_numa_node_count()); + if (numa_count <= 0) numa_count = 1; + const size_t pages_per = pages / numa_count; + const size_t pages_mod = pages % numa_count; + const size_t timeout_per = (timeout_msecs==0 ? 0 : (timeout_msecs / numa_count) + 50); + + // reserve evenly among numa nodes + for (size_t numa_node = 0; numa_node < numa_count && pages > 0; numa_node++) { + size_t node_pages = pages_per; // can be 0 + if (numa_node < pages_mod) node_pages++; + int err = mi_reserve_huge_os_pages_at(node_pages, (int)numa_node, timeout_per); + if (err) return err; + if (pages < node_pages) { + pages = 0; + } + else { + pages -= node_pages; + } + } + + return 0; +} + +int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept { + MI_UNUSED(max_secs); + _mi_warning_message("mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\n"); + if (pages_reserved != NULL) *pages_reserved = 0; + int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0)); + if (err==0 && pages_reserved!=NULL) *pages_reserved = pages; + return err; +} diff --git a/Objects/mimalloc/bitmap.c b/Objects/mimalloc/bitmap.c new file mode 100644 index 00000000000000..ec3c755822dac1 --- /dev/null +++ b/Objects/mimalloc/bitmap.c @@ -0,0 +1,432 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +Concurrent bitmap that can set/reset sequences of bits atomically, +represeted as an array of fields where each field is a machine word (`size_t`) + +There are two api's; the standard one cannot have sequences that cross +between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS). + +The `_across` postfixed functions do allow sequences that can cross over +between the fields. (This is used in arena allocation) +---------------------------------------------------------------------------- */ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "bitmap.h" + +/* ----------------------------------------------------------- + Bitmap definition +----------------------------------------------------------- */ + +// The bit mask for a given number of blocks at a specified bit index. +static inline size_t mi_bitmap_mask_(size_t count, size_t bitidx) { + mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS); + mi_assert_internal(count > 0); + if (count >= MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL; + if (count == 0) return 0; + return ((((size_t)1 << count) - 1) << bitidx); +} + + +/* ----------------------------------------------------------- + Claim a bit sequence atomically +----------------------------------------------------------- */ + +// Try to atomically claim a sequence of `count` bits in a single +// field at `idx` in `bitmap`. Returns `true` on success. +inline bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx) +{ + mi_assert_internal(bitmap_idx != NULL); + mi_assert_internal(count <= MI_BITMAP_FIELD_BITS); + mi_assert_internal(count > 0); + mi_bitmap_field_t* field = &bitmap[idx]; + size_t map = mi_atomic_load_relaxed(field); + if (map==MI_BITMAP_FIELD_FULL) return false; // short cut + + // search for 0-bit sequence of length count + const size_t mask = mi_bitmap_mask_(count, 0); + const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count; + +#ifdef MI_HAVE_FAST_BITSCAN + size_t bitidx = mi_ctz(~map); // quickly find the first zero bit if possible +#else + size_t bitidx = 0; // otherwise start at 0 +#endif + size_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx + + // scan linearly for a free range of zero bits + while (bitidx <= bitidx_max) { + const size_t mapm = (map & m); + if (mapm == 0) { // are the mask bits free at bitidx? + mi_assert_internal((m >> bitidx) == mask); // no overflow? + const size_t newmap = (map | m); + mi_assert_internal((newmap^map) >> bitidx == mask); + if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { // TODO: use weak cas here? + // no success, another thread claimed concurrently.. keep going (with updated `map`) + continue; + } + else { + // success, we claimed the bits! + *bitmap_idx = mi_bitmap_index_create(idx, bitidx); + return true; + } + } + else { + // on to the next bit range +#ifdef MI_HAVE_FAST_BITSCAN + mi_assert_internal(mapm != 0); + const size_t shift = (count == 1 ? 1 : (MI_INTPTR_BITS - mi_clz(mapm) - bitidx)); + mi_assert_internal(shift > 0 && shift <= count); +#else + const size_t shift = 1; +#endif + bitidx += shift; + m <<= shift; + } + } + // no bits found + return false; +} + +// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success. +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +// `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields. +bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) { + size_t idx = start_field_idx; + for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) { + if (idx >= bitmap_fields) { idx = 0; } // wrap + if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + return true; + } + } + return false; +} + +// Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled +bool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, + const size_t start_field_idx, const size_t count, + mi_bitmap_pred_fun_t pred_fun, void* pred_arg, + mi_bitmap_index_t* bitmap_idx) { + size_t idx = start_field_idx; + for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) { + if (idx >= bitmap_fields) idx = 0; // wrap + if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + if (pred_fun == NULL || pred_fun(*bitmap_idx, pred_arg)) { + return true; + } + // predicate returned false, unclaim and look further + _mi_bitmap_unclaim(bitmap, bitmap_fields, count, *bitmap_idx); + } + } + return false; +} + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + // mi_assert_internal((bitmap[idx] & mask) == mask); + const size_t prev = mi_atomic_and_acq_rel(&bitmap[idx], ~mask); + return ((prev & mask) == mask); +} + + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0); + size_t prev = mi_atomic_or_acq_rel(&bitmap[idx], mask); + if (any_zero != NULL) { *any_zero = ((prev & mask) != mask); } + return ((prev & mask) == 0); +} + +// Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one. +static bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + const size_t field = mi_atomic_load_relaxed(&bitmap[idx]); + if (any_ones != NULL) { *any_ones = ((field & mask) != 0); } + return ((field & mask) == mask); +} + +// Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically. +// Returns `true` if successful when all previous `count` bits were 0. +bool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const size_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields); + size_t expected = mi_atomic_load_relaxed(&bitmap[idx]); + do { + if ((expected & mask) != 0) return false; + } + while (!mi_atomic_cas_strong_acq_rel(&bitmap[idx], &expected, expected | mask)); + mi_assert_internal((expected & mask) == 0); + return true; +} + + +bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL); +} + +bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + bool any_ones; + mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones); + return any_ones; +} + + +//-------------------------------------------------------------------------- +// the `_across` functions work on bitmaps where sequences can cross over +// between the fields. This is used in arena allocation +//-------------------------------------------------------------------------- + +// Try to atomically claim a sequence of `count` bits starting from the field +// at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success. +// Only needs to consider crossing into the next fields (see `mi_bitmap_try_find_from_claim_across`) +static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx) +{ + mi_assert_internal(bitmap_idx != NULL); + + // check initial trailing zeros + mi_bitmap_field_t* field = &bitmap[idx]; + size_t map = mi_atomic_load_relaxed(field); + const size_t initial = mi_clz(map); // count of initial zeros starting at idx + mi_assert_internal(initial <= MI_BITMAP_FIELD_BITS); + if (initial == 0) return false; + if (initial >= count) return _mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx); // no need to cross fields (this case won't happen for us) + if (_mi_divide_up(count - initial, MI_BITMAP_FIELD_BITS) >= (bitmap_fields - idx)) return false; // not enough entries + + // scan ahead + size_t found = initial; + size_t mask = 0; // mask bits for the final field + while(found < count) { + field++; + map = mi_atomic_load_relaxed(field); + const size_t mask_bits = (found + MI_BITMAP_FIELD_BITS <= count ? MI_BITMAP_FIELD_BITS : (count - found)); + mi_assert_internal(mask_bits > 0 && mask_bits <= MI_BITMAP_FIELD_BITS); + mask = mi_bitmap_mask_(mask_bits, 0); + if ((map & mask) != 0) return false; // some part is already claimed + found += mask_bits; + } + mi_assert_internal(field < &bitmap[bitmap_fields]); + + // we found a range of contiguous zeros up to the final field; mask contains mask in the final field + // now try to claim the range atomically + mi_bitmap_field_t* const final_field = field; + const size_t final_mask = mask; + mi_bitmap_field_t* const initial_field = &bitmap[idx]; + const size_t initial_idx = MI_BITMAP_FIELD_BITS - initial; + const size_t initial_mask = mi_bitmap_mask_(initial, initial_idx); + + // initial field + size_t newmap; + field = initial_field; + map = mi_atomic_load_relaxed(field); + do { + newmap = (map | initial_mask); + if ((map & initial_mask) != 0) { goto rollback; }; + } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)); + + // intermediate fields + while (++field < final_field) { + newmap = MI_BITMAP_FIELD_FULL; + map = 0; + if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { goto rollback; } + } + + // final field + mi_assert_internal(field == final_field); + map = mi_atomic_load_relaxed(field); + do { + newmap = (map | final_mask); + if ((map & final_mask) != 0) { goto rollback; } + } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)); + + // claimed! + *bitmap_idx = mi_bitmap_index_create(idx, initial_idx); + return true; + +rollback: + // roll back intermediate fields + // (we just failed to claim `field` so decrement first) + while (--field > initial_field) { + newmap = 0; + map = MI_BITMAP_FIELD_FULL; + mi_assert_internal(mi_atomic_load_relaxed(field) == map); + mi_atomic_store_release(field, newmap); + } + if (field == initial_field) { // (if we failed on the initial field, `field + 1 == initial_field`) + map = mi_atomic_load_relaxed(field); + do { + mi_assert_internal((map & initial_mask) == initial_mask); + newmap = (map & ~initial_mask); + } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)); + } + // retry? (we make a recursive call instead of goto to be able to use const declarations) + if (retries <= 2) { + return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx); + } + else { + return false; + } +} + + +// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success. +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) { + mi_assert_internal(count > 0); + if (count <= 2) { + // we don't bother with crossover fields for small counts + return _mi_bitmap_try_find_from_claim(bitmap, bitmap_fields, start_field_idx, count, bitmap_idx); + } + + // visit the fields + size_t idx = start_field_idx; + for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) { + if (idx >= bitmap_fields) { idx = 0; } // wrap + // first try to claim inside a field + if (count <= MI_BITMAP_FIELD_BITS) { + if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + return true; + } + } + // if that fails, then try to claim across fields + if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx)) { + return true; + } + } + return false; +} + +// Helper for masks across fields; returns the mid count, post_mask may be 0 +static size_t mi_bitmap_mask_across(mi_bitmap_index_t bitmap_idx, size_t bitmap_fields, size_t count, size_t* pre_mask, size_t* mid_mask, size_t* post_mask) { + MI_UNUSED(bitmap_fields); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + if mi_likely(bitidx + count <= MI_BITMAP_FIELD_BITS) { + *pre_mask = mi_bitmap_mask_(count, bitidx); + *mid_mask = 0; + *post_mask = 0; + mi_assert_internal(mi_bitmap_index_field(bitmap_idx) < bitmap_fields); + return 0; + } + else { + const size_t pre_bits = MI_BITMAP_FIELD_BITS - bitidx; + mi_assert_internal(pre_bits < count); + *pre_mask = mi_bitmap_mask_(pre_bits, bitidx); + count -= pre_bits; + const size_t mid_count = (count / MI_BITMAP_FIELD_BITS); + *mid_mask = MI_BITMAP_FIELD_FULL; + count %= MI_BITMAP_FIELD_BITS; + *post_mask = (count==0 ? 0 : mi_bitmap_mask_(count, 0)); + mi_assert_internal(mi_bitmap_index_field(bitmap_idx) + mid_count + (count==0 ? 0 : 1) < bitmap_fields); + return mid_count; + } +} + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + size_t idx = mi_bitmap_index_field(bitmap_idx); + size_t pre_mask; + size_t mid_mask; + size_t post_mask; + size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask); + bool all_one = true; + mi_bitmap_field_t* field = &bitmap[idx]; + size_t prev = mi_atomic_and_acq_rel(field++, ~pre_mask); // clear first part + if ((prev & pre_mask) != pre_mask) all_one = false; + while(mid_count-- > 0) { + prev = mi_atomic_and_acq_rel(field++, ~mid_mask); // clear mid part + if ((prev & mid_mask) != mid_mask) all_one = false; + } + if (post_mask!=0) { + prev = mi_atomic_and_acq_rel(field, ~post_mask); // clear end part + if ((prev & post_mask) != post_mask) all_one = false; + } + return all_one; +} + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero) { + size_t idx = mi_bitmap_index_field(bitmap_idx); + size_t pre_mask; + size_t mid_mask; + size_t post_mask; + size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask); + bool all_zero = true; + bool any_zero = false; + _Atomic(size_t)*field = &bitmap[idx]; + size_t prev = mi_atomic_or_acq_rel(field++, pre_mask); + if ((prev & pre_mask) != 0) all_zero = false; + if ((prev & pre_mask) != pre_mask) any_zero = true; + while (mid_count-- > 0) { + prev = mi_atomic_or_acq_rel(field++, mid_mask); + if ((prev & mid_mask) != 0) all_zero = false; + if ((prev & mid_mask) != mid_mask) any_zero = true; + } + if (post_mask!=0) { + prev = mi_atomic_or_acq_rel(field, post_mask); + if ((prev & post_mask) != 0) all_zero = false; + if ((prev & post_mask) != post_mask) any_zero = true; + } + if (pany_zero != NULL) { *pany_zero = any_zero; } + return all_zero; +} + + +// Returns `true` if all `count` bits were 1. +// `any_ones` is `true` if there was at least one bit set to one. +static bool mi_bitmap_is_claimedx_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_ones) { + size_t idx = mi_bitmap_index_field(bitmap_idx); + size_t pre_mask; + size_t mid_mask; + size_t post_mask; + size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask); + bool all_ones = true; + bool any_ones = false; + mi_bitmap_field_t* field = &bitmap[idx]; + size_t prev = mi_atomic_load_relaxed(field++); + if ((prev & pre_mask) != pre_mask) all_ones = false; + if ((prev & pre_mask) != 0) any_ones = true; + while (mid_count-- > 0) { + prev = mi_atomic_load_relaxed(field++); + if ((prev & mid_mask) != mid_mask) all_ones = false; + if ((prev & mid_mask) != 0) any_ones = true; + } + if (post_mask!=0) { + prev = mi_atomic_load_relaxed(field); + if ((prev & post_mask) != post_mask) all_ones = false; + if ((prev & post_mask) != 0) any_ones = true; + } + if (pany_ones != NULL) { *pany_ones = any_ones; } + return all_ones; +} + +bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + return mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, NULL); +} + +bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + bool any_ones; + mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, &any_ones); + return any_ones; +} diff --git a/Objects/mimalloc/bitmap.h b/Objects/mimalloc/bitmap.h new file mode 100644 index 00000000000000..9ba15d5d6f09ea --- /dev/null +++ b/Objects/mimalloc/bitmap.h @@ -0,0 +1,115 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +Concurrent bitmap that can set/reset sequences of bits atomically, +represeted as an array of fields where each field is a machine word (`size_t`) + +There are two api's; the standard one cannot have sequences that cross +between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS). +(this is used in region allocation) + +The `_across` postfixed functions do allow sequences that can cross over +between the fields. (This is used in arena allocation) +---------------------------------------------------------------------------- */ +#pragma once +#ifndef MI_BITMAP_H +#define MI_BITMAP_H + +/* ----------------------------------------------------------- + Bitmap definition +----------------------------------------------------------- */ + +#define MI_BITMAP_FIELD_BITS (8*MI_SIZE_SIZE) +#define MI_BITMAP_FIELD_FULL (~((size_t)0)) // all bits set + +// An atomic bitmap of `size_t` fields +typedef _Atomic(size_t) mi_bitmap_field_t; +typedef mi_bitmap_field_t* mi_bitmap_t; + +// A bitmap index is the index of the bit in a bitmap. +typedef size_t mi_bitmap_index_t; + +// Create a bit index. +static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) { + mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS); + return (idx*MI_BITMAP_FIELD_BITS) + bitidx; +} + +// Create a bit index. +static inline mi_bitmap_index_t mi_bitmap_index_create_from_bit(size_t full_bitidx) { + return mi_bitmap_index_create(full_bitidx / MI_BITMAP_FIELD_BITS, full_bitidx % MI_BITMAP_FIELD_BITS); +} + +// Get the field index from a bit index. +static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) { + return (bitmap_idx / MI_BITMAP_FIELD_BITS); +} + +// Get the bit index in a bitmap field +static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) { + return (bitmap_idx % MI_BITMAP_FIELD_BITS); +} + +// Get the full bit index +static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) { + return bitmap_idx; +} + +/* ----------------------------------------------------------- + Claim a bit sequence atomically +----------------------------------------------------------- */ + +// Try to atomically claim a sequence of `count` bits in a single +// field at `idx` in `bitmap`. Returns `true` on success. +bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx); + +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields. +bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx); + +// Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled +typedef bool (mi_cdecl *mi_bitmap_pred_fun_t)(mi_bitmap_index_t bitmap_idx, void* pred_arg); +bool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_pred_fun_t pred_fun, void* pred_arg, mi_bitmap_index_t* bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +// Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically. +// Returns `true` if successful when all previous `count` bits were 0. +bool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero); + +bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); +bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + + +//-------------------------------------------------------------------------- +// the `_across` functions work on bitmaps where sequences can cross over +// between the fields. This is used in arena allocation +//-------------------------------------------------------------------------- + +// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success. +// Starts at idx, and wraps around to search in all `bitmap_fields` fields. +bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero); + +bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); +bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx); + +#endif diff --git a/Objects/mimalloc/heap.c b/Objects/mimalloc/heap.c new file mode 100644 index 00000000000000..4eb622ed4bad76 --- /dev/null +++ b/Objects/mimalloc/heap.c @@ -0,0 +1,626 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" // mi_prim_get_default_heap + +#include // memset, memcpy + +#if defined(_MSC_VER) && (_MSC_VER < 1920) +#pragma warning(disable:4204) // non-constant aggregate initializer +#endif + +/* ----------------------------------------------------------- + Helpers +----------------------------------------------------------- */ + +// return `true` if ok, `false` to break +typedef bool (heap_page_visitor_fun)(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2); + +// Visit all pages in a heap; returns `false` if break was called. +static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void* arg1, void* arg2) +{ + if (heap==NULL || heap->page_count==0) return 0; + + // visit all pages + #if MI_DEBUG>1 + size_t total = heap->page_count; + size_t count = 0; + #endif + + for (size_t i = 0; i <= MI_BIN_FULL; i++) { + mi_page_queue_t* pq = &heap->pages[i]; + mi_page_t* page = pq->first; + while(page != NULL) { + mi_page_t* next = page->next; // save next in case the page gets removed from the queue + mi_assert_internal(mi_page_heap(page) == heap); + #if MI_DEBUG>1 + count++; + #endif + if (!fn(heap, pq, page, arg1, arg2)) return false; + page = next; // and continue + } + } + mi_assert_internal(count == total); + return true; +} + + +#if MI_DEBUG>=2 +static bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + MI_UNUSED(arg1); + MI_UNUSED(arg2); + MI_UNUSED(pq); + mi_assert_internal(mi_page_heap(page) == heap); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_internal(segment->thread_id == heap->thread_id); + mi_assert_expensive(_mi_page_is_valid(page)); + return true; +} +#endif +#if MI_DEBUG>=3 +static bool mi_heap_is_valid(mi_heap_t* heap) { + mi_assert_internal(heap!=NULL); + mi_heap_visit_pages(heap, &mi_heap_page_is_valid, NULL, NULL); + return true; +} +#endif + + + + +/* ----------------------------------------------------------- + "Collect" pages by migrating `local_free` and `thread_free` + lists and freeing empty pages. This is done when a thread + stops (and in that case abandons pages if there are still + blocks alive) +----------------------------------------------------------- */ + +typedef enum mi_collect_e { + MI_NORMAL, + MI_FORCE, + MI_ABANDON +} mi_collect_t; + + +static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) { + MI_UNUSED(arg2); + MI_UNUSED(heap); + mi_assert_internal(mi_heap_page_is_valid(heap, pq, page, NULL, NULL)); + mi_collect_t collect = *((mi_collect_t*)arg_collect); + _mi_page_free_collect(page, collect >= MI_FORCE); + if (mi_page_all_free(page)) { + // no more used blocks, free the page. + // note: this will free retired pages as well. + _mi_page_free(page, pq, collect >= MI_FORCE); + } + else if (collect == MI_ABANDON) { + // still used blocks but the thread is done; abandon the page + _mi_page_abandon(page, pq); + } + return true; // don't break +} + +static bool mi_heap_page_never_delayed_free(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + MI_UNUSED(arg1); + MI_UNUSED(arg2); + MI_UNUSED(heap); + MI_UNUSED(pq); + _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); + return true; // don't break +} + +static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect) +{ + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + + const bool force = collect >= MI_FORCE; + _mi_deferred_free(heap, force); + + // note: never reclaim on collect but leave it to threads that need storage to reclaim + const bool force_main = + #ifdef NDEBUG + collect == MI_FORCE + #else + collect >= MI_FORCE + #endif + && _mi_is_main_thread() && mi_heap_is_backing(heap) && !heap->no_reclaim; + + if (force_main) { + // the main thread is abandoned (end-of-program), try to reclaim all abandoned segments. + // if all memory is freed by now, all segments should be freed. + _mi_abandoned_reclaim_all(heap, &heap->tld->segments); + } + + // if abandoning, mark all pages to no longer add to delayed_free + if (collect == MI_ABANDON) { + mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, NULL, NULL); + } + + // free all current thread delayed blocks. + // (if abandoning, after this there are no more thread-delayed references into the pages.) + _mi_heap_delayed_free_all(heap); + + // collect retired pages + _mi_heap_collect_retired(heap, force); + + // collect all pages owned by this thread + mi_heap_visit_pages(heap, &mi_heap_page_collect, &collect, NULL); + mi_assert_internal( collect != MI_ABANDON || mi_atomic_load_ptr_acquire(mi_block_t,&heap->thread_delayed_free) == NULL ); + + // collect abandoned segments (in particular, purge expired parts of segments in the abandoned segment list) + // note: forced purge can be quite expensive if many threads are created/destroyed so we do not force on abandonment + _mi_abandoned_collect(heap, collect == MI_FORCE /* force? */, &heap->tld->segments); + + // collect segment local caches + if (force) { + _mi_segment_thread_collect(&heap->tld->segments); + } + + // collect regions on program-exit (or shared library unload) + if (force && _mi_is_main_thread() && mi_heap_is_backing(heap)) { + _mi_thread_data_collect(); // collect thread data cache + _mi_arena_collect(true /* force purge */, &heap->tld->stats); + } +} + +void _mi_heap_collect_abandon(mi_heap_t* heap) { + mi_heap_collect_ex(heap, MI_ABANDON); +} + +void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept { + mi_heap_collect_ex(heap, (force ? MI_FORCE : MI_NORMAL)); +} + +void mi_collect(bool force) mi_attr_noexcept { + mi_heap_collect(mi_prim_get_default_heap(), force); +} + + +/* ----------------------------------------------------------- + Heap new +----------------------------------------------------------- */ + +mi_heap_t* mi_heap_get_default(void) { + mi_thread_init(); + return mi_prim_get_default_heap(); +} + +static bool mi_heap_is_default(const mi_heap_t* heap) { + return (heap == mi_prim_get_default_heap()); +} + + +mi_heap_t* mi_heap_get_backing(void) { + mi_heap_t* heap = mi_heap_get_default(); + mi_assert_internal(heap!=NULL); + mi_heap_t* bheap = heap->tld->heap_backing; + mi_assert_internal(bheap!=NULL); + mi_assert_internal(bheap->thread_id == _mi_thread_id()); + return bheap; +} + +mi_decl_nodiscard mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id) { + mi_heap_t* bheap = mi_heap_get_backing(); + mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t); // todo: OS allocate in secure mode? + if (heap == NULL) return NULL; + _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(mi_heap_t)); + heap->tld = bheap->tld; + heap->thread_id = _mi_thread_id(); + heap->arena_id = arena_id; + _mi_random_split(&bheap->random, &heap->random); + heap->cookie = _mi_heap_random_next(heap) | 1; + heap->keys[0] = _mi_heap_random_next(heap); + heap->keys[1] = _mi_heap_random_next(heap); + heap->no_reclaim = true; // don't reclaim abandoned pages or otherwise destroy is unsafe + // push on the thread local heaps list + heap->next = heap->tld->heaps; + heap->tld->heaps = heap; + return heap; +} + +mi_decl_nodiscard mi_heap_t* mi_heap_new(void) { + return mi_heap_new_in_arena(_mi_arena_id_none()); +} + +bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid) { + return _mi_arena_memid_is_suitable(memid, heap->arena_id); +} + +uintptr_t _mi_heap_random_next(mi_heap_t* heap) { + return _mi_random_next(&heap->random); +} + +// zero out the page queues +static void mi_heap_reset_pages(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + mi_assert_internal(mi_heap_is_initialized(heap)); + // TODO: copy full empty heap instead? + memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct)); + _mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages)); + heap->thread_delayed_free = NULL; + heap->page_count = 0; +} + +// called from `mi_heap_destroy` and `mi_heap_delete` to free the internal heap resources. +static void mi_heap_free(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert_internal(mi_heap_is_initialized(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + if (mi_heap_is_backing(heap)) return; // dont free the backing heap + + // reset default + if (mi_heap_is_default(heap)) { + _mi_heap_set_default_direct(heap->tld->heap_backing); + } + + // remove ourselves from the thread local heaps list + // linear search but we expect the number of heaps to be relatively small + mi_heap_t* prev = NULL; + mi_heap_t* curr = heap->tld->heaps; + while (curr != heap && curr != NULL) { + prev = curr; + curr = curr->next; + } + mi_assert_internal(curr == heap); + if (curr == heap) { + if (prev != NULL) { prev->next = heap->next; } + else { heap->tld->heaps = heap->next; } + } + mi_assert_internal(heap->tld->heaps != NULL); + + // and free the used memory + mi_free(heap); +} + + +/* ----------------------------------------------------------- + Heap destroy +----------------------------------------------------------- */ + +static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + MI_UNUSED(arg1); + MI_UNUSED(arg2); + MI_UNUSED(heap); + MI_UNUSED(pq); + + // ensure no more thread_delayed_free will be added + _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); + + // stats + const size_t bsize = mi_page_block_size(page); + if (bsize > MI_MEDIUM_OBJ_SIZE_MAX) { + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, large, bsize); + } + else { + mi_heap_stat_decrease(heap, huge, bsize); + } + } +#if (MI_STAT) + _mi_page_free_collect(page, false); // update used count + const size_t inuse = page->used; + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, normal, bsize * inuse); +#if (MI_STAT>1) + mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], inuse); +#endif + } + mi_heap_stat_decrease(heap, malloc, bsize * inuse); // todo: off for aligned blocks... +#endif + + /// pretend it is all free now + mi_assert_internal(mi_page_thread_free(page) == NULL); + page->used = 0; + + // and free the page + // mi_page_free(page,false); + page->next = NULL; + page->prev = NULL; + _mi_segment_page_free(page,false /* no force? */, &heap->tld->segments); + + return true; // keep going +} + +void _mi_heap_destroy_pages(mi_heap_t* heap) { + mi_heap_visit_pages(heap, &_mi_heap_page_destroy, NULL, NULL); + mi_heap_reset_pages(heap); +} + +#if MI_TRACK_HEAP_DESTROY +static bool mi_cdecl mi_heap_track_block_free(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) { + MI_UNUSED(heap); MI_UNUSED(area); MI_UNUSED(arg); MI_UNUSED(block_size); + mi_track_free_size(block,mi_usable_size(block)); + return true; +} +#endif + +void mi_heap_destroy(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + mi_assert(heap->no_reclaim); + mi_assert_expensive(mi_heap_is_valid(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + if (!heap->no_reclaim) { + // don't free in case it may contain reclaimed pages + mi_heap_delete(heap); + } + else { + // track all blocks as freed + #if MI_TRACK_HEAP_DESTROY + mi_heap_visit_blocks(heap, true, mi_heap_track_block_free, NULL); + #endif + // free all pages + _mi_heap_destroy_pages(heap); + mi_heap_free(heap); + } +} + +// forcefully destroy all heaps in the current thread +void _mi_heap_unsafe_destroy_all(void) { + mi_heap_t* bheap = mi_heap_get_backing(); + mi_heap_t* curr = bheap->tld->heaps; + while (curr != NULL) { + mi_heap_t* next = curr->next; + if (curr->no_reclaim) { + mi_heap_destroy(curr); + } + else { + _mi_heap_destroy_pages(curr); + } + curr = next; + } +} + +/* ----------------------------------------------------------- + Safe Heap delete +----------------------------------------------------------- */ + +// Transfer the pages from one heap to the other +static void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) { + mi_assert_internal(heap!=NULL); + if (from==NULL || from->page_count == 0) return; + + // reduce the size of the delayed frees + _mi_heap_delayed_free_partial(from); + + // transfer all pages by appending the queues; this will set a new heap field + // so threads may do delayed frees in either heap for a while. + // note: appending waits for each page to not be in the `MI_DELAYED_FREEING` state + // so after this only the new heap will get delayed frees + for (size_t i = 0; i <= MI_BIN_FULL; i++) { + mi_page_queue_t* pq = &heap->pages[i]; + mi_page_queue_t* append = &from->pages[i]; + size_t pcount = _mi_page_queue_append(heap, pq, append); + heap->page_count += pcount; + from->page_count -= pcount; + } + mi_assert_internal(from->page_count == 0); + + // and do outstanding delayed frees in the `from` heap + // note: be careful here as the `heap` field in all those pages no longer point to `from`, + // turns out to be ok as `_mi_heap_delayed_free` only visits the list and calls a + // the regular `_mi_free_delayed_block` which is safe. + _mi_heap_delayed_free_all(from); + #if !defined(_MSC_VER) || (_MSC_VER > 1900) // somehow the following line gives an error in VS2015, issue #353 + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_block_t,&from->thread_delayed_free) == NULL); + #endif + + // and reset the `from` heap + mi_heap_reset_pages(from); +} + +// Safe delete a heap without freeing any still allocated blocks in that heap. +void mi_heap_delete(mi_heap_t* heap) +{ + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + mi_assert_expensive(mi_heap_is_valid(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return; + + if (!mi_heap_is_backing(heap)) { + // tranfer still used pages to the backing heap + mi_heap_absorb(heap->tld->heap_backing, heap); + } + else { + // the backing heap abandons its pages + _mi_heap_collect_abandon(heap); + } + mi_assert_internal(heap->page_count==0); + mi_heap_free(heap); +} + +mi_heap_t* mi_heap_set_default(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + if (heap==NULL || !mi_heap_is_initialized(heap)) return NULL; + mi_assert_expensive(mi_heap_is_valid(heap)); + mi_heap_t* old = mi_prim_get_default_heap(); + _mi_heap_set_default_direct(heap); + return old; +} + + + + +/* ----------------------------------------------------------- + Analysis +----------------------------------------------------------- */ + +// static since it is not thread safe to access heaps from other threads. +static mi_heap_t* mi_heap_of_block(const void* p) { + if (p == NULL) return NULL; + mi_segment_t* segment = _mi_ptr_segment(p); + bool valid = (_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(valid); + if mi_unlikely(!valid) return NULL; + return mi_page_heap(_mi_segment_page_of(segment,p)); +} + +bool mi_heap_contains_block(mi_heap_t* heap, const void* p) { + mi_assert(heap != NULL); + if (heap==NULL || !mi_heap_is_initialized(heap)) return false; + return (heap == mi_heap_of_block(p)); +} + + +static bool mi_heap_page_check_owned(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* p, void* vfound) { + MI_UNUSED(heap); + MI_UNUSED(pq); + bool* found = (bool*)vfound; + mi_segment_t* segment = _mi_page_segment(page); + void* start = _mi_page_start(segment, page, NULL); + void* end = (uint8_t*)start + (page->capacity * mi_page_block_size(page)); + *found = (p >= start && p < end); + return (!*found); // continue if not found +} + +bool mi_heap_check_owned(mi_heap_t* heap, const void* p) { + mi_assert(heap != NULL); + if (heap==NULL || !mi_heap_is_initialized(heap)) return false; + if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false; // only aligned pointers + bool found = false; + mi_heap_visit_pages(heap, &mi_heap_page_check_owned, (void*)p, &found); + return found; +} + +bool mi_check_owned(const void* p) { + return mi_heap_check_owned(mi_prim_get_default_heap(), p); +} + +/* ----------------------------------------------------------- + Visit all heap blocks and areas + Todo: enable visiting abandoned pages, and + enable visiting all blocks of all heaps across threads +----------------------------------------------------------- */ + +// Separate struct to keep `mi_page_t` out of the public interface +typedef struct mi_heap_area_ex_s { + mi_heap_area_t area; + mi_page_t* page; +} mi_heap_area_ex_t; + +static bool mi_heap_area_visit_blocks(const mi_heap_area_ex_t* xarea, mi_block_visit_fun* visitor, void* arg) { + mi_assert(xarea != NULL); + if (xarea==NULL) return true; + const mi_heap_area_t* area = &xarea->area; + mi_page_t* page = xarea->page; + mi_assert(page != NULL); + if (page == NULL) return true; + + _mi_page_free_collect(page,true); + mi_assert_internal(page->local_free == NULL); + if (page->used == 0) return true; + + const size_t bsize = mi_page_block_size(page); + const size_t ubsize = mi_page_usable_block_size(page); // without padding + size_t psize; + uint8_t* pstart = _mi_page_start(_mi_page_segment(page), page, &psize); + + if (page->capacity == 1) { + // optimize page with one block + mi_assert_internal(page->used == 1 && page->free == NULL); + return visitor(mi_page_heap(page), area, pstart, ubsize, arg); + } + + // create a bitmap of free blocks. + #define MI_MAX_BLOCKS (MI_SMALL_PAGE_SIZE / sizeof(void*)) + uintptr_t free_map[MI_MAX_BLOCKS / sizeof(uintptr_t)]; + memset(free_map, 0, sizeof(free_map)); + + #if MI_DEBUG>1 + size_t free_count = 0; + #endif + for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) { + #if MI_DEBUG>1 + free_count++; + #endif + mi_assert_internal((uint8_t*)block >= pstart && (uint8_t*)block < (pstart + psize)); + size_t offset = (uint8_t*)block - pstart; + mi_assert_internal(offset % bsize == 0); + size_t blockidx = offset / bsize; // Todo: avoid division? + mi_assert_internal( blockidx < MI_MAX_BLOCKS); + size_t bitidx = (blockidx / sizeof(uintptr_t)); + size_t bit = blockidx - (bitidx * sizeof(uintptr_t)); + free_map[bitidx] |= ((uintptr_t)1 << bit); + } + mi_assert_internal(page->capacity == (free_count + page->used)); + + // walk through all blocks skipping the free ones + #if MI_DEBUG>1 + size_t used_count = 0; + #endif + for (size_t i = 0; i < page->capacity; i++) { + size_t bitidx = (i / sizeof(uintptr_t)); + size_t bit = i - (bitidx * sizeof(uintptr_t)); + uintptr_t m = free_map[bitidx]; + if (bit == 0 && m == UINTPTR_MAX) { + i += (sizeof(uintptr_t) - 1); // skip a run of free blocks + } + else if ((m & ((uintptr_t)1 << bit)) == 0) { + #if MI_DEBUG>1 + used_count++; + #endif + uint8_t* block = pstart + (i * bsize); + if (!visitor(mi_page_heap(page), area, block, ubsize, arg)) return false; + } + } + mi_assert_internal(page->used == used_count); + return true; +} + +typedef bool (mi_heap_area_visit_fun)(const mi_heap_t* heap, const mi_heap_area_ex_t* area, void* arg); + + +static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) { + MI_UNUSED(heap); + MI_UNUSED(pq); + mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun; + mi_heap_area_ex_t xarea; + const size_t bsize = mi_page_block_size(page); + const size_t ubsize = mi_page_usable_block_size(page); + xarea.page = page; + xarea.area.reserved = page->reserved * bsize; + xarea.area.committed = page->capacity * bsize; + xarea.area.blocks = _mi_page_start(_mi_page_segment(page), page, NULL); + xarea.area.used = page->used; // number of blocks in use (#553) + xarea.area.block_size = ubsize; + xarea.area.full_block_size = bsize; + return fun(heap, &xarea, arg); +} + +// Visit all heap pages as areas +static bool mi_heap_visit_areas(const mi_heap_t* heap, mi_heap_area_visit_fun* visitor, void* arg) { + if (visitor == NULL) return false; + return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, (void*)(visitor), arg); // note: function pointer to void* :-{ +} + +// Just to pass arguments +typedef struct mi_visit_blocks_args_s { + bool visit_blocks; + mi_block_visit_fun* visitor; + void* arg; +} mi_visit_blocks_args_t; + +static bool mi_heap_area_visitor(const mi_heap_t* heap, const mi_heap_area_ex_t* xarea, void* arg) { + mi_visit_blocks_args_t* args = (mi_visit_blocks_args_t*)arg; + if (!args->visitor(heap, &xarea->area, NULL, xarea->area.block_size, args->arg)) return false; + if (args->visit_blocks) { + return mi_heap_area_visit_blocks(xarea, args->visitor, args->arg); + } + else { + return true; + } +} + +// Visit all blocks in a heap +bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) { + mi_visit_blocks_args_t args = { visit_blocks, visitor, arg }; + return mi_heap_visit_areas(heap, &mi_heap_area_visitor, &args); +} diff --git a/Objects/mimalloc/init.c b/Objects/mimalloc/init.c new file mode 100644 index 00000000000000..7dfa7657737117 --- /dev/null +++ b/Objects/mimalloc/init.c @@ -0,0 +1,709 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2022, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/prim.h" + +#include // memcpy, memset +#include // atexit + + +// Empty page used to initialize the small free pages array +const mi_page_t _mi_page_empty = { + 0, false, false, false, + 0, // capacity + 0, // reserved capacity + { 0 }, // flags + false, // is_zero + 0, // retire_expire + NULL, // free + 0, // used + 0, // xblock_size + NULL, // local_free + #if (MI_PADDING || MI_ENCODE_FREELIST) + { 0, 0 }, + #endif + MI_ATOMIC_VAR_INIT(0), // xthread_free + MI_ATOMIC_VAR_INIT(0), // xheap + NULL, NULL + #if MI_INTPTR_SIZE==8 + , { 0 } // padding + #endif +}; + +#define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty) + +#if (MI_SMALL_WSIZE_MAX==128) +#if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8) +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } +#elif (MI_PADDING>0) +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } +#else +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() } +#endif +#else +#error "define right initialization sizes corresponding to MI_SMALL_WSIZE_MAX" +#endif + +// Empty page queues for every bin +#define QNULL(sz) { NULL, NULL, (sz)*sizeof(uintptr_t) } +#define MI_PAGE_QUEUES_EMPTY \ + { QNULL(1), \ + QNULL( 1), QNULL( 2), QNULL( 3), QNULL( 4), QNULL( 5), QNULL( 6), QNULL( 7), QNULL( 8), /* 8 */ \ + QNULL( 10), QNULL( 12), QNULL( 14), QNULL( 16), QNULL( 20), QNULL( 24), QNULL( 28), QNULL( 32), /* 16 */ \ + QNULL( 40), QNULL( 48), QNULL( 56), QNULL( 64), QNULL( 80), QNULL( 96), QNULL( 112), QNULL( 128), /* 24 */ \ + QNULL( 160), QNULL( 192), QNULL( 224), QNULL( 256), QNULL( 320), QNULL( 384), QNULL( 448), QNULL( 512), /* 32 */ \ + QNULL( 640), QNULL( 768), QNULL( 896), QNULL( 1024), QNULL( 1280), QNULL( 1536), QNULL( 1792), QNULL( 2048), /* 40 */ \ + QNULL( 2560), QNULL( 3072), QNULL( 3584), QNULL( 4096), QNULL( 5120), QNULL( 6144), QNULL( 7168), QNULL( 8192), /* 48 */ \ + QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \ + QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \ + QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \ + QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \ + QNULL(MI_MEDIUM_OBJ_WSIZE_MAX + 2) /* Full queue */ } + +#define MI_STAT_COUNT_NULL() {0,0,0,0} + +// Empty statistics +#if MI_STAT>1 +#define MI_STAT_COUNT_END_NULL() , { MI_STAT_COUNT_NULL(), MI_INIT32(MI_STAT_COUNT_NULL) } +#else +#define MI_STAT_COUNT_END_NULL() +#endif + +#define MI_STATS_NULL \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \ + MI_STAT_COUNT_END_NULL() + + +// Empty slice span queues for every bin +#define SQNULL(sz) { NULL, NULL, sz } +#define MI_SEGMENT_SPAN_QUEUES_EMPTY \ + { SQNULL(1), \ + SQNULL( 1), SQNULL( 2), SQNULL( 3), SQNULL( 4), SQNULL( 5), SQNULL( 6), SQNULL( 7), SQNULL( 10), /* 8 */ \ + SQNULL( 12), SQNULL( 14), SQNULL( 16), SQNULL( 20), SQNULL( 24), SQNULL( 28), SQNULL( 32), SQNULL( 40), /* 16 */ \ + SQNULL( 48), SQNULL( 56), SQNULL( 64), SQNULL( 80), SQNULL( 96), SQNULL( 112), SQNULL( 128), SQNULL( 160), /* 24 */ \ + SQNULL( 192), SQNULL( 224), SQNULL( 256), SQNULL( 320), SQNULL( 384), SQNULL( 448), SQNULL( 512), SQNULL( 640), /* 32 */ \ + SQNULL( 768), SQNULL( 896), SQNULL( 1024) /* 35 */ } + + +// -------------------------------------------------------- +// Statically allocate an empty heap as the initial +// thread local value for the default heap, +// and statically allocate the backing heap for the main +// thread so it can function without doing any allocation +// itself (as accessing a thread local for the first time +// may lead to allocation itself on some platforms) +// -------------------------------------------------------- + +mi_decl_cache_align const mi_heap_t _mi_heap_empty = { + NULL, + MI_SMALL_PAGES_EMPTY, + MI_PAGE_QUEUES_EMPTY, + MI_ATOMIC_VAR_INIT(NULL), + 0, // tid + 0, // cookie + 0, // arena id + { 0, 0 }, // keys + { {0}, {0}, 0, true }, // random + 0, // page count + MI_BIN_FULL, 0, // page retired min/max + NULL, // next + false +}; + +#define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats))) +#define tld_empty_os ((mi_os_tld_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,os))) + +mi_decl_cache_align static const mi_tld_t tld_empty = { + 0, + false, + NULL, NULL, + { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, tld_empty_stats, tld_empty_os }, // segments + { 0, tld_empty_stats }, // os + { MI_STATS_NULL } // stats +}; + +mi_threadid_t _mi_thread_id(void) mi_attr_noexcept { + return _mi_prim_thread_id(); +} + +// the thread-local default heap for allocation +mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty; + +extern mi_heap_t _mi_heap_main; + +static mi_tld_t tld_main = { + 0, false, + &_mi_heap_main, & _mi_heap_main, + { MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, &tld_main.stats, &tld_main.os }, // segments + { 0, &tld_main.stats }, // os + { MI_STATS_NULL } // stats +}; + +mi_heap_t _mi_heap_main = { + &tld_main, + MI_SMALL_PAGES_EMPTY, + MI_PAGE_QUEUES_EMPTY, + MI_ATOMIC_VAR_INIT(NULL), + 0, // thread id + 0, // initial cookie + 0, // arena id + { 0, 0 }, // the key of the main heap can be fixed (unlike page keys that need to be secure!) + { {0x846ca68b}, {0}, 0, true }, // random + 0, // page count + MI_BIN_FULL, 0, // page retired min/max + NULL, // next heap + false // can reclaim +}; + +bool _mi_process_is_initialized = false; // set to `true` in `mi_process_init`. + +mi_stats_t _mi_stats_main = { MI_STATS_NULL }; + + +static void mi_heap_main_init(void) { + if (_mi_heap_main.cookie == 0) { + _mi_heap_main.thread_id = _mi_thread_id(); + _mi_heap_main.cookie = 1; + #if defined(_WIN32) && !defined(MI_SHARED_LIB) + _mi_random_init_weak(&_mi_heap_main.random); // prevent allocation failure during bcrypt dll initialization with static linking + #else + _mi_random_init(&_mi_heap_main.random); + #endif + _mi_heap_main.cookie = _mi_heap_random_next(&_mi_heap_main); + _mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main); + _mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main); + } +} + +mi_heap_t* _mi_heap_main_get(void) { + mi_heap_main_init(); + return &_mi_heap_main; +} + + +/* ----------------------------------------------------------- + Initialization and freeing of the thread local heaps +----------------------------------------------------------- */ + +// note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size). +typedef struct mi_thread_data_s { + mi_heap_t heap; // must come first due to cast in `_mi_heap_done` + mi_tld_t tld; + mi_memid_t memid; +} mi_thread_data_t; + + +// Thread meta-data is allocated directly from the OS. For +// some programs that do not use thread pools and allocate and +// destroy many OS threads, this may causes too much overhead +// per thread so we maintain a small cache of recently freed metadata. + +#define TD_CACHE_SIZE (16) +static _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE]; + +static mi_thread_data_t* mi_thread_data_zalloc(void) { + // try to find thread metadata in the cache + bool is_zero = false; + mi_thread_data_t* td = NULL; + for (int i = 0; i < TD_CACHE_SIZE; i++) { + td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); + if (td != NULL) { + // found cached allocation, try use it + td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL); + if (td != NULL) { + break; + } + } + } + + // if that fails, allocate as meta data + if (td == NULL) { + mi_memid_t memid; + td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid, &_mi_stats_main); + if (td == NULL) { + // if this fails, try once more. (issue #257) + td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid, &_mi_stats_main); + if (td == NULL) { + // really out of memory + _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t)); + } + } + if (td != NULL) { + td->memid = memid; + is_zero = memid.initially_zero; + } + } + + if (td != NULL && !is_zero) { + _mi_memzero_aligned(td, sizeof(*td)); + } + return td; +} + +static void mi_thread_data_free( mi_thread_data_t* tdfree ) { + // try to add the thread metadata to the cache + for (int i = 0; i < TD_CACHE_SIZE; i++) { + mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); + if (td == NULL) { + mi_thread_data_t* expected = NULL; + if (mi_atomic_cas_ptr_weak_acq_rel(mi_thread_data_t, &td_cache[i], &expected, tdfree)) { + return; + } + } + } + // if that fails, just free it directly + _mi_os_free(tdfree, sizeof(mi_thread_data_t), tdfree->memid, &_mi_stats_main); +} + +void _mi_thread_data_collect(void) { + // free all thread metadata from the cache + for (int i = 0; i < TD_CACHE_SIZE; i++) { + mi_thread_data_t* td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]); + if (td != NULL) { + td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL); + if (td != NULL) { + _mi_os_free(td, sizeof(mi_thread_data_t), td->memid, &_mi_stats_main); + } + } + } +} + +// Initialize the thread local default heap, called from `mi_thread_init` +static bool _mi_heap_init(void) { + if (mi_heap_is_initialized(mi_prim_get_default_heap())) return true; + if (_mi_is_main_thread()) { + // mi_assert_internal(_mi_heap_main.thread_id != 0); // can happen on freeBSD where alloc is called before any initialization + // the main heap is statically allocated + mi_heap_main_init(); + _mi_heap_set_default_direct(&_mi_heap_main); + //mi_assert_internal(_mi_heap_default->tld->heap_backing == mi_prim_get_default_heap()); + } + else { + // use `_mi_os_alloc` to allocate directly from the OS + mi_thread_data_t* td = mi_thread_data_zalloc(); + if (td == NULL) return false; + + mi_tld_t* tld = &td->tld; + mi_heap_t* heap = &td->heap; + _mi_memcpy_aligned(tld, &tld_empty, sizeof(*tld)); + _mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(*heap)); + heap->thread_id = _mi_thread_id(); + _mi_random_init(&heap->random); + heap->cookie = _mi_heap_random_next(heap) | 1; + heap->keys[0] = _mi_heap_random_next(heap); + heap->keys[1] = _mi_heap_random_next(heap); + heap->tld = tld; + tld->heap_backing = heap; + tld->heaps = heap; + tld->segments.stats = &tld->stats; + tld->segments.os = &tld->os; + tld->os.stats = &tld->stats; + _mi_heap_set_default_direct(heap); + } + return false; +} + +// Free the thread local default heap (called from `mi_thread_done`) +static bool _mi_heap_done(mi_heap_t* heap) { + if (!mi_heap_is_initialized(heap)) return true; + + // reset default heap + _mi_heap_set_default_direct(_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty); + + // switch to backing heap + heap = heap->tld->heap_backing; + if (!mi_heap_is_initialized(heap)) return false; + + // delete all non-backing heaps in this thread + mi_heap_t* curr = heap->tld->heaps; + while (curr != NULL) { + mi_heap_t* next = curr->next; // save `next` as `curr` will be freed + if (curr != heap) { + mi_assert_internal(!mi_heap_is_backing(curr)); + mi_heap_delete(curr); + } + curr = next; + } + mi_assert_internal(heap->tld->heaps == heap && heap->next == NULL); + mi_assert_internal(mi_heap_is_backing(heap)); + + // collect if not the main thread + if (heap != &_mi_heap_main) { + _mi_heap_collect_abandon(heap); + } + + // merge stats + _mi_stats_done(&heap->tld->stats); + + // free if not the main thread + if (heap != &_mi_heap_main) { + // the following assertion does not always hold for huge segments as those are always treated + // as abondened: one may allocate it in one thread, but deallocate in another in which case + // the count can be too large or negative. todo: perhaps not count huge segments? see issue #363 + // mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id()); + mi_thread_data_free((mi_thread_data_t*)heap); + } + else { + #if 0 + // never free the main thread even in debug mode; if a dll is linked statically with mimalloc, + // there may still be delete/free calls after the mi_fls_done is called. Issue #207 + _mi_heap_destroy_pages(heap); + mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main); + #endif + } + return false; +} + + + +// -------------------------------------------------------- +// Try to run `mi_thread_done()` automatically so any memory +// owned by the thread but not yet released can be abandoned +// and re-owned by another thread. +// +// 1. windows dynamic library: +// call from DllMain on DLL_THREAD_DETACH +// 2. windows static library: +// use `FlsAlloc` to call a destructor when the thread is done +// 3. unix, pthreads: +// use a pthread key to call a destructor when a pthread is done +// +// In the last two cases we also need to call `mi_process_init` +// to set up the thread local keys. +// -------------------------------------------------------- + +// Set up handlers so `mi_thread_done` is called automatically +static void mi_process_setup_auto_thread_done(void) { + static bool tls_initialized = false; // fine if it races + if (tls_initialized) return; + tls_initialized = true; + _mi_prim_thread_init_auto_done(); + _mi_heap_set_default_direct(&_mi_heap_main); +} + + +bool _mi_is_main_thread(void) { + return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id()); +} + +static _Atomic(size_t) thread_count = MI_ATOMIC_VAR_INIT(1); + +size_t _mi_current_thread_count(void) { + return mi_atomic_load_relaxed(&thread_count); +} + +// This is called from the `mi_malloc_generic` +void mi_thread_init(void) mi_attr_noexcept +{ + // ensure our process has started already + mi_process_init(); + + // initialize the thread local default heap + // (this will call `_mi_heap_set_default_direct` and thus set the + // fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called) + if (_mi_heap_init()) return; // returns true if already initialized + + _mi_stat_increase(&_mi_stats_main.threads, 1); + mi_atomic_increment_relaxed(&thread_count); + //_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id()); +} + +void mi_thread_done(void) mi_attr_noexcept { + _mi_thread_done(NULL); +} + +void _mi_thread_done(mi_heap_t* heap) +{ + // calling with NULL implies using the default heap + if (heap == NULL) { + heap = mi_prim_get_default_heap(); + if (heap == NULL) return; + } + + // prevent re-entrancy through heap_done/heap_set_default_direct (issue #699) + if (!mi_heap_is_initialized(heap)) { + return; + } + + // adjust stats + mi_atomic_decrement_relaxed(&thread_count); + _mi_stat_decrease(&_mi_stats_main.threads, 1); + + // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps... + if (heap->thread_id != _mi_thread_id()) return; + + // abandon the thread local heap + if (_mi_heap_done(heap)) return; // returns true if already ran +} + +void _mi_heap_set_default_direct(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + #if defined(MI_TLS_SLOT) + mi_prim_tls_slot_set(MI_TLS_SLOT,heap); + #elif defined(MI_TLS_PTHREAD_SLOT_OFS) + *mi_tls_pthread_heap_slot() = heap; + #elif defined(MI_TLS_PTHREAD) + // we use _mi_heap_default_key + #else + _mi_heap_default = heap; + #endif + + // ensure the default heap is passed to `_mi_thread_done` + // setting to a non-NULL value also ensures `mi_thread_done` is called. + _mi_prim_thread_associate_default_heap(heap); +} + + +// -------------------------------------------------------- +// Run functions on process init/done, and thread init/done +// -------------------------------------------------------- +static void mi_cdecl mi_process_done(void); + +static bool os_preloading = true; // true until this module is initialized +static bool mi_redirected = false; // true if malloc redirects to mi_malloc + +// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false. +bool mi_decl_noinline _mi_preloading(void) { + return os_preloading; +} + +mi_decl_nodiscard bool mi_is_redirected(void) mi_attr_noexcept { + return mi_redirected; +} + +// Communicate with the redirection module on Windows +#if defined(_WIN32) && defined(MI_SHARED_LIB) && !defined(MI_WIN_NOREDIRECT) +#ifdef __cplusplus +extern "C" { +#endif +mi_decl_export void _mi_redirect_entry(DWORD reason) { + // called on redirection; careful as this may be called before DllMain + if (reason == DLL_PROCESS_ATTACH) { + mi_redirected = true; + } + else if (reason == DLL_PROCESS_DETACH) { + mi_redirected = false; + } + else if (reason == DLL_THREAD_DETACH) { + mi_thread_done(); + } +} +__declspec(dllimport) bool mi_cdecl mi_allocator_init(const char** message); +__declspec(dllimport) void mi_cdecl mi_allocator_done(void); +#ifdef __cplusplus +} +#endif +#else +static bool mi_allocator_init(const char** message) { + if (message != NULL) *message = NULL; + return true; +} +static void mi_allocator_done(void) { + // nothing to do +} +#endif + +// Called once by the process loader +static void mi_process_load(void) { + mi_heap_main_init(); + #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD) + volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true; + if (dummy == NULL) return; // use dummy or otherwise the access may get optimized away (issue #697) + #endif + os_preloading = false; + mi_assert_internal(_mi_is_main_thread()); + #if !(defined(_WIN32) && defined(MI_SHARED_LIB)) // use Dll process detach (see below) instead of atexit (issue #521) + atexit(&mi_process_done); + #endif + _mi_options_init(); + mi_process_setup_auto_thread_done(); + mi_process_init(); + if (mi_redirected) _mi_verbose_message("malloc is redirected.\n"); + + // show message from the redirector (if present) + const char* msg = NULL; + mi_allocator_init(&msg); + if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) { + _mi_fputs(NULL,NULL,NULL,msg); + } + + // reseed random + _mi_random_reinit_if_weak(&_mi_heap_main.random); +} + +#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) +#include +mi_decl_cache_align bool _mi_cpu_has_fsrm = false; + +static void mi_detect_cpu_features(void) { + // FSRM for fast rep movsb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017)) + int32_t cpu_info[4]; + __cpuid(cpu_info, 7); + _mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see +} +#else +static void mi_detect_cpu_features(void) { + // nothing +} +#endif + +// Initialize the process; called by thread_init or the process loader +void mi_process_init(void) mi_attr_noexcept { + // ensure we are called once + static mi_atomic_once_t process_init; + #if _MSC_VER < 1920 + mi_heap_main_init(); // vs2017 can dynamically re-initialize _mi_heap_main + #endif + if (!mi_atomic_once(&process_init)) return; + _mi_process_is_initialized = true; + _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id()); + mi_process_setup_auto_thread_done(); + + mi_detect_cpu_features(); + _mi_os_init(); + mi_heap_main_init(); + #if MI_DEBUG + _mi_verbose_message("debug level : %d\n", MI_DEBUG); + #endif + _mi_verbose_message("secure level: %d\n", MI_SECURE); + _mi_verbose_message("mem tracking: %s\n", MI_TRACK_TOOL); + #if MI_TSAN + _mi_verbose_message("thread santizer enabled\n"); + #endif + mi_thread_init(); + + #if defined(_WIN32) + // On windows, when building as a static lib the FLS cleanup happens to early for the main thread. + // To avoid this, set the FLS value for the main thread to NULL so the fls cleanup + // will not call _mi_thread_done on the (still executing) main thread. See issue #508. + _mi_prim_thread_associate_default_heap(NULL); + #endif + + mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) + mi_track_init(); + + if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { + size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024); + long reserve_at = mi_option_get(mi_option_reserve_huge_os_pages_at); + if (reserve_at != -1) { + mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500); + } else { + mi_reserve_huge_os_pages_interleave(pages, 0, pages*500); + } + } + if (mi_option_is_enabled(mi_option_reserve_os_memory)) { + long ksize = mi_option_get(mi_option_reserve_os_memory); + if (ksize > 0) { + mi_reserve_os_memory((size_t)ksize*MI_KiB, true /* commit? */, true /* allow large pages? */); + } + } +} + +// Called when the process is done (through `at_exit`) +static void mi_cdecl mi_process_done(void) { + // only shutdown if we were initialized + if (!_mi_process_is_initialized) return; + // ensure we are called once + static bool process_done = false; + if (process_done) return; + process_done = true; + + // release any thread specific resources and ensure _mi_thread_done is called on all but the main thread + _mi_prim_thread_done_auto_done(); + + #ifndef MI_SKIP_COLLECT_ON_EXIT + #if (MI_DEBUG || !defined(MI_SHARED_LIB)) + // free all memory if possible on process exit. This is not needed for a stand-alone process + // but should be done if mimalloc is statically linked into another shared library which + // is repeatedly loaded/unloaded, see issue #281. + mi_collect(true /* force */ ); + #endif + #endif + + // Forcefully release all retained memory; this can be dangerous in general if overriding regular malloc/free + // since after process_done there might still be other code running that calls `free` (like at_exit routines, + // or C-runtime termination code. + if (mi_option_is_enabled(mi_option_destroy_on_exit)) { + mi_collect(true /* force */); + _mi_heap_unsafe_destroy_all(); // forcefully release all memory held by all heaps (of this thread only!) + _mi_arena_unsafe_destroy_all(& _mi_heap_main_get()->tld->stats); + } + + if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) { + mi_stats_print(NULL); + } + mi_allocator_done(); + _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id); + os_preloading = true; // don't call the C runtime anymore +} + + + +#if defined(_WIN32) && defined(MI_SHARED_LIB) + // Windows DLL: easy to hook into process_init and thread_done + __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { + MI_UNUSED(reserved); + MI_UNUSED(inst); + if (reason==DLL_PROCESS_ATTACH) { + mi_process_load(); + } + else if (reason==DLL_PROCESS_DETACH) { + mi_process_done(); + } + else if (reason==DLL_THREAD_DETACH) { + if (!mi_is_redirected()) { + mi_thread_done(); + } + } + return TRUE; + } + +#elif defined(_MSC_VER) + // MSVC: use data section magic for static libraries + // See + static int _mi_process_init(void) { + mi_process_load(); + return 0; + } + typedef int(*_mi_crt_callback_t)(void); + #if defined(_M_X64) || defined(_M_ARM64) + __pragma(comment(linker, "/include:" "_mi_msvc_initu")) + #pragma section(".CRT$XIU", long, read) + #else + __pragma(comment(linker, "/include:" "__mi_msvc_initu")) + #endif + #pragma data_seg(".CRT$XIU") + mi_decl_externc _mi_crt_callback_t _mi_msvc_initu[] = { &_mi_process_init }; + #pragma data_seg() + +#elif defined(__cplusplus) + // C++: use static initialization to detect process start + static bool _mi_process_init(void) { + mi_process_load(); + return (_mi_heap_main.thread_id != 0); + } + static bool mi_initialized = _mi_process_init(); + +#elif defined(__GNUC__) || defined(__clang__) + // GCC,Clang: use the constructor attribute + static void __attribute__((constructor)) _mi_process_init(void) { + mi_process_load(); + } + +#else +#pragma message("define a way to call mi_process_load on your platform") +#endif diff --git a/Objects/mimalloc/options.c b/Objects/mimalloc/options.c new file mode 100644 index 00000000000000..345b560e3e7f4c --- /dev/null +++ b/Objects/mimalloc/options.c @@ -0,0 +1,571 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" // mi_prim_out_stderr + +#include // FILE +#include // abort +#include + + +static long mi_max_error_count = 16; // stop outputting errors after this (use < 0 for no limit) +static long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit) + +static void mi_add_stderr_output(void); + +int mi_version(void) mi_attr_noexcept { + return MI_MALLOC_VERSION; +} + + +// -------------------------------------------------------- +// Options +// These can be accessed by multiple threads and may be +// concurrently initialized, but an initializing data race +// is ok since they resolve to the same value. +// -------------------------------------------------------- +typedef enum mi_init_e { + UNINIT, // not yet initialized + DEFAULTED, // not found in the environment, use default value + INITIALIZED // found in environment or set explicitly +} mi_init_t; + +typedef struct mi_option_desc_s { + long value; // the value + mi_init_t init; // is it initialized yet? (from the environment) + mi_option_t option; // for debugging: the option index should match the option + const char* name; // option name without `mimalloc_` prefix + const char* legacy_name; // potential legacy option name +} mi_option_desc_t; + +#define MI_OPTION(opt) mi_option_##opt, #opt, NULL +#define MI_OPTION_LEGACY(opt,legacy) mi_option_##opt, #opt, #legacy + +static mi_option_desc_t options[_mi_option_last] = +{ + // stable options + #if MI_DEBUG || defined(MI_SHOW_ERRORS) + { 1, UNINIT, MI_OPTION(show_errors) }, + #else + { 0, UNINIT, MI_OPTION(show_errors) }, + #endif + { 0, UNINIT, MI_OPTION(show_stats) }, + { 0, UNINIT, MI_OPTION(verbose) }, + + // the following options are experimental and not all combinations make sense. + { 1, UNINIT, MI_OPTION(eager_commit) }, // commit per segment directly (4MiB) (but see also `eager_commit_delay`) + { 2, UNINIT, MI_OPTION_LEGACY(arena_eager_commit,eager_region_commit) }, // eager commit arena's? 2 is used to enable this only on an OS that has overcommit (i.e. linux) + { 1, UNINIT, MI_OPTION_LEGACY(purge_decommits,reset_decommits) }, // purge decommits memory (instead of reset) (note: on linux this uses MADV_DONTNEED for decommit) + { 0, UNINIT, MI_OPTION_LEGACY(allow_large_os_pages,large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's + { 0, UNINIT, MI_OPTION(reserve_huge_os_pages) }, // per 1GiB huge pages + {-1, UNINIT, MI_OPTION(reserve_huge_os_pages_at) }, // reserve huge pages at node N + { 0, UNINIT, MI_OPTION(reserve_os_memory) }, + { 0, UNINIT, MI_OPTION(deprecated_segment_cache) }, // cache N segments per thread + { 0, UNINIT, MI_OPTION(deprecated_page_reset) }, // reset page memory on free + { 0, UNINIT, MI_OPTION_LEGACY(abandoned_page_purge,abandoned_page_reset) }, // reset free page memory when a thread terminates + { 0, UNINIT, MI_OPTION(deprecated_segment_reset) }, // reset segment memory on free (needs eager commit) +#if defined(__NetBSD__) + { 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed +#else + { 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed (but per page in the segment on demand) +#endif + { 10, UNINIT, MI_OPTION_LEGACY(purge_delay,reset_delay) }, // purge delay in milli-seconds + { 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes. + { 0, UNINIT, MI_OPTION(limit_os_alloc) }, // 1 = do not use OS memory for allocation (but only reserved arenas) + { 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose + { 16, UNINIT, MI_OPTION(max_errors) }, // maximum errors that are output + { 16, UNINIT, MI_OPTION(max_warnings) }, // maximum warnings that are output + { 8, UNINIT, MI_OPTION(max_segment_reclaim)}, // max. number of segment reclaims from the abandoned segments per try. + { 0, UNINIT, MI_OPTION(destroy_on_exit)}, // release all OS memory on process exit; careful with dangling pointer or after-exit frees! + #if (MI_INTPTR_SIZE>4) + { 1024L * 1024L, UNINIT, MI_OPTION(arena_reserve) }, // reserve memory N KiB at a time + #else + { 128L * 1024L, UNINIT, MI_OPTION(arena_reserve) }, + #endif + { 10, UNINIT, MI_OPTION(arena_purge_mult) }, // purge delay multiplier for arena's + { 1, UNINIT, MI_OPTION_LEGACY(purge_extend_delay, decommit_extend_delay) }, +}; + +static void mi_option_init(mi_option_desc_t* desc); + +void _mi_options_init(void) { + // called on process load; should not be called before the CRT is initialized! + // (e.g. do not call this from process_init as that may run before CRT initialization) + mi_add_stderr_output(); // now it safe to use stderr for output + for(int i = 0; i < _mi_option_last; i++ ) { + mi_option_t option = (mi_option_t)i; + long l = mi_option_get(option); MI_UNUSED(l); // initialize + // if (option != mi_option_verbose) + { + mi_option_desc_t* desc = &options[option]; + _mi_verbose_message("option '%s': %ld\n", desc->name, desc->value); + } + } + mi_max_error_count = mi_option_get(mi_option_max_errors); + mi_max_warning_count = mi_option_get(mi_option_max_warnings); +} + +mi_decl_nodiscard long mi_option_get(mi_option_t option) { + mi_assert(option >= 0 && option < _mi_option_last); + if (option < 0 || option >= _mi_option_last) return 0; + mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option + if mi_unlikely(desc->init == UNINIT) { + mi_option_init(desc); + } + return desc->value; +} + +mi_decl_nodiscard long mi_option_get_clamp(mi_option_t option, long min, long max) { + long x = mi_option_get(option); + return (x < min ? min : (x > max ? max : x)); +} + +mi_decl_nodiscard size_t mi_option_get_size(mi_option_t option) { + mi_assert_internal(option == mi_option_reserve_os_memory || option == mi_option_arena_reserve); + long x = mi_option_get(option); + return (x < 0 ? 0 : (size_t)x * MI_KiB); +} + +void mi_option_set(mi_option_t option, long value) { + mi_assert(option >= 0 && option < _mi_option_last); + if (option < 0 || option >= _mi_option_last) return; + mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option + desc->value = value; + desc->init = INITIALIZED; +} + +void mi_option_set_default(mi_option_t option, long value) { + mi_assert(option >= 0 && option < _mi_option_last); + if (option < 0 || option >= _mi_option_last) return; + mi_option_desc_t* desc = &options[option]; + if (desc->init != INITIALIZED) { + desc->value = value; + } +} + +mi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option) { + return (mi_option_get(option) != 0); +} + +void mi_option_set_enabled(mi_option_t option, bool enable) { + mi_option_set(option, (enable ? 1 : 0)); +} + +void mi_option_set_enabled_default(mi_option_t option, bool enable) { + mi_option_set_default(option, (enable ? 1 : 0)); +} + +void mi_option_enable(mi_option_t option) { + mi_option_set_enabled(option,true); +} + +void mi_option_disable(mi_option_t option) { + mi_option_set_enabled(option,false); +} + +static void mi_cdecl mi_out_stderr(const char* msg, void* arg) { + MI_UNUSED(arg); + if (msg != NULL && msg[0] != 0) { + _mi_prim_out_stderr(msg); + } +} + +// Since an output function can be registered earliest in the `main` +// function we also buffer output that happens earlier. When +// an output function is registered it is called immediately with +// the output up to that point. +#ifndef MI_MAX_DELAY_OUTPUT +#define MI_MAX_DELAY_OUTPUT ((size_t)(32*1024)) +#endif +static char out_buf[MI_MAX_DELAY_OUTPUT+1]; +static _Atomic(size_t) out_len; + +static void mi_cdecl mi_out_buf(const char* msg, void* arg) { + MI_UNUSED(arg); + if (msg==NULL) return; + if (mi_atomic_load_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return; + size_t n = _mi_strlen(msg); + if (n==0) return; + // claim space + size_t start = mi_atomic_add_acq_rel(&out_len, n); + if (start >= MI_MAX_DELAY_OUTPUT) return; + // check bound + if (start+n >= MI_MAX_DELAY_OUTPUT) { + n = MI_MAX_DELAY_OUTPUT-start-1; + } + _mi_memcpy(&out_buf[start], msg, n); +} + +static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) { + if (out==NULL) return; + // claim (if `no_more_buf == true`, no more output will be added after this point) + size_t count = mi_atomic_add_acq_rel(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1)); + // and output the current contents + if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT; + out_buf[count] = 0; + out(out_buf,arg); + if (!no_more_buf) { + out_buf[count] = '\n'; // if continue with the buffer, insert a newline + } +} + + +// Once this module is loaded, switch to this routine +// which outputs to stderr and the delayed output buffer. +static void mi_cdecl mi_out_buf_stderr(const char* msg, void* arg) { + mi_out_stderr(msg,arg); + mi_out_buf(msg,arg); +} + + + +// -------------------------------------------------------- +// Default output handler +// -------------------------------------------------------- + +// Should be atomic but gives errors on many platforms as generally we cannot cast a function pointer to a uintptr_t. +// For now, don't register output from multiple threads. +static mi_output_fun* volatile mi_out_default; // = NULL +static _Atomic(void*) mi_out_arg; // = NULL + +static mi_output_fun* mi_out_get_default(void** parg) { + if (parg != NULL) { *parg = mi_atomic_load_ptr_acquire(void,&mi_out_arg); } + mi_output_fun* out = mi_out_default; + return (out == NULL ? &mi_out_buf : out); +} + +void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer + mi_atomic_store_ptr_release(void,&mi_out_arg, arg); + if (out!=NULL) mi_out_buf_flush(out,true,arg); // output all the delayed output now +} + +// add stderr to the delayed output after the module is loaded +static void mi_add_stderr_output(void) { + mi_assert_internal(mi_out_default == NULL); + mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr + mi_out_default = &mi_out_buf_stderr; // and add stderr to the delayed output +} + +// -------------------------------------------------------- +// Messages, all end up calling `_mi_fputs`. +// -------------------------------------------------------- +static _Atomic(size_t) error_count; // = 0; // when >= max_error_count stop emitting errors +static _Atomic(size_t) warning_count; // = 0; // when >= max_warning_count stop emitting warnings + +// When overriding malloc, we may recurse into mi_vfprintf if an allocation +// inside the C runtime causes another message. +// In some cases (like on macOS) the loader already allocates which +// calls into mimalloc; if we then access thread locals (like `recurse`) +// this may crash as the access may call _tlv_bootstrap that tries to +// (recursively) invoke malloc again to allocate space for the thread local +// variables on demand. This is why we use a _mi_preloading test on such +// platforms. However, C code generator may move the initial thread local address +// load before the `if` and we therefore split it out in a separate funcion. +static mi_decl_thread bool recurse = false; + +static mi_decl_noinline bool mi_recurse_enter_prim(void) { + if (recurse) return false; + recurse = true; + return true; +} + +static mi_decl_noinline void mi_recurse_exit_prim(void) { + recurse = false; +} + +static bool mi_recurse_enter(void) { + #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD) + if (_mi_preloading()) return false; + #endif + return mi_recurse_enter_prim(); +} + +static void mi_recurse_exit(void) { + #if defined(__APPLE__) || defined(MI_TLS_RECURSE_GUARD) + if (_mi_preloading()) return; + #endif + mi_recurse_exit_prim(); +} + +void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) { + if (out==NULL || (void*)out==(void*)stdout || (void*)out==(void*)stderr) { // TODO: use mi_out_stderr for stderr? + if (!mi_recurse_enter()) return; + out = mi_out_get_default(&arg); + if (prefix != NULL) out(prefix, arg); + out(message, arg); + mi_recurse_exit(); + } + else { + if (prefix != NULL) out(prefix, arg); + out(message, arg); + } +} + +// Define our own limited `fprintf` that avoids memory allocation. +// We do this using `snprintf` with a limited buffer. +static void mi_vfprintf( mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args ) { + char buf[512]; + if (fmt==NULL) return; + if (!mi_recurse_enter()) return; + vsnprintf(buf,sizeof(buf)-1,fmt,args); + mi_recurse_exit(); + _mi_fputs(out,arg,prefix,buf); +} + +void _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) { + va_list args; + va_start(args,fmt); + mi_vfprintf(out,arg,NULL,fmt,args); + va_end(args); +} + +static void mi_vfprintf_thread(mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args) { + if (prefix != NULL && _mi_strnlen(prefix,33) <= 32 && !_mi_is_main_thread()) { + char tprefix[64]; + snprintf(tprefix, sizeof(tprefix), "%sthread 0x%llx: ", prefix, (unsigned long long)_mi_thread_id()); + mi_vfprintf(out, arg, tprefix, fmt, args); + } + else { + mi_vfprintf(out, arg, prefix, fmt, args); + } +} + +void _mi_trace_message(const char* fmt, ...) { + if (mi_option_get(mi_option_verbose) <= 1) return; // only with verbose level 2 or higher + va_list args; + va_start(args, fmt); + mi_vfprintf_thread(NULL, NULL, "mimalloc: ", fmt, args); + va_end(args); +} + +void _mi_verbose_message(const char* fmt, ...) { + if (!mi_option_is_enabled(mi_option_verbose)) return; + va_list args; + va_start(args,fmt); + mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); + va_end(args); +} + +static void mi_show_error_message(const char* fmt, va_list args) { + if (!mi_option_is_enabled(mi_option_verbose)) { + if (!mi_option_is_enabled(mi_option_show_errors)) return; + if (mi_max_error_count >= 0 && (long)mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; + } + mi_vfprintf_thread(NULL, NULL, "mimalloc: error: ", fmt, args); +} + +void _mi_warning_message(const char* fmt, ...) { + if (!mi_option_is_enabled(mi_option_verbose)) { + if (!mi_option_is_enabled(mi_option_show_errors)) return; + if (mi_max_warning_count >= 0 && (long)mi_atomic_increment_acq_rel(&warning_count) > mi_max_warning_count) return; + } + va_list args; + va_start(args,fmt); + mi_vfprintf_thread(NULL, NULL, "mimalloc: warning: ", fmt, args); + va_end(args); +} + + +#if MI_DEBUG +void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) { + _mi_fprintf(NULL, NULL, "mimalloc: assertion failed: at \"%s\":%u, %s\n assertion: \"%s\"\n", fname, line, (func==NULL?"":func), assertion); + abort(); +} +#endif + +// -------------------------------------------------------- +// Errors +// -------------------------------------------------------- + +static mi_error_fun* volatile mi_error_handler; // = NULL +static _Atomic(void*) mi_error_arg; // = NULL + +static void mi_error_default(int err) { + MI_UNUSED(err); +#if (MI_DEBUG>0) + if (err==EFAULT) { + #ifdef _MSC_VER + __debugbreak(); + #endif + abort(); + } +#endif +#if (MI_SECURE>0) + if (err==EFAULT) { // abort on serious errors in secure mode (corrupted meta-data) + abort(); + } +#endif +#if defined(MI_XMALLOC) + if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode + abort(); + } +#endif +} + +void mi_register_error(mi_error_fun* fun, void* arg) { + mi_error_handler = fun; // can be NULL + mi_atomic_store_ptr_release(void,&mi_error_arg, arg); +} + +void _mi_error_message(int err, const char* fmt, ...) { + // show detailed error message + va_list args; + va_start(args, fmt); + mi_show_error_message(fmt, args); + va_end(args); + // and call the error handler which may abort (or return normally) + if (mi_error_handler != NULL) { + mi_error_handler(err, mi_atomic_load_ptr_acquire(void,&mi_error_arg)); + } + else { + mi_error_default(err); + } +} + +// -------------------------------------------------------- +// Initialize options by checking the environment +// -------------------------------------------------------- +char _mi_toupper(char c) { + if (c >= 'a' && c <= 'z') return (c - 'a' + 'A'); + else return c; +} + +int _mi_strnicmp(const char* s, const char* t, size_t n) { + if (n == 0) return 0; + for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) { + if (_mi_toupper(*s) != _mi_toupper(*t)) break; + } + return (n == 0 ? 0 : *s - *t); +} + +void _mi_strlcpy(char* dest, const char* src, size_t dest_size) { + if (dest==NULL || src==NULL || dest_size == 0) return; + // copy until end of src, or when dest is (almost) full + while (*src != 0 && dest_size > 1) { + *dest++ = *src++; + dest_size--; + } + // always zero terminate + *dest = 0; +} + +void _mi_strlcat(char* dest, const char* src, size_t dest_size) { + if (dest==NULL || src==NULL || dest_size == 0) return; + // find end of string in the dest buffer + while (*dest != 0 && dest_size > 1) { + dest++; + dest_size--; + } + // and catenate + _mi_strlcpy(dest, src, dest_size); +} + +size_t _mi_strlen(const char* s) { + if (s==NULL) return 0; + size_t len = 0; + while(s[len] != 0) { len++; } + return len; +} + +size_t _mi_strnlen(const char* s, size_t max_len) { + if (s==NULL) return 0; + size_t len = 0; + while(s[len] != 0 && len < max_len) { len++; } + return len; +} + +#ifdef MI_NO_GETENV +static bool mi_getenv(const char* name, char* result, size_t result_size) { + MI_UNUSED(name); + MI_UNUSED(result); + MI_UNUSED(result_size); + return false; +} +#else +static bool mi_getenv(const char* name, char* result, size_t result_size) { + if (name==NULL || result == NULL || result_size < 64) return false; + return _mi_prim_getenv(name,result,result_size); +} +#endif + +// TODO: implement ourselves to reduce dependencies on the C runtime +#include // strtol +#include // strstr + + +static void mi_option_init(mi_option_desc_t* desc) { + // Read option value from the environment + char s[64 + 1]; + char buf[64+1]; + _mi_strlcpy(buf, "mimalloc_", sizeof(buf)); + _mi_strlcat(buf, desc->name, sizeof(buf)); + bool found = mi_getenv(buf, s, sizeof(s)); + if (!found && desc->legacy_name != NULL) { + _mi_strlcpy(buf, "mimalloc_", sizeof(buf)); + _mi_strlcat(buf, desc->legacy_name, sizeof(buf)); + found = mi_getenv(buf, s, sizeof(s)); + if (found) { + _mi_warning_message("environment option \"mimalloc_%s\" is deprecated -- use \"mimalloc_%s\" instead.\n", desc->legacy_name, desc->name); + } + } + + if (found) { + size_t len = _mi_strnlen(s, sizeof(buf) - 1); + for (size_t i = 0; i < len; i++) { + buf[i] = _mi_toupper(s[i]); + } + buf[len] = 0; + if (buf[0] == 0 || strstr("1;TRUE;YES;ON", buf) != NULL) { + desc->value = 1; + desc->init = INITIALIZED; + } + else if (strstr("0;FALSE;NO;OFF", buf) != NULL) { + desc->value = 0; + desc->init = INITIALIZED; + } + else { + char* end = buf; + long value = strtol(buf, &end, 10); + if (desc->option == mi_option_reserve_os_memory || desc->option == mi_option_arena_reserve) { + // this option is interpreted in KiB to prevent overflow of `long` + if (*end == 'K') { end++; } + else if (*end == 'M') { value *= MI_KiB; end++; } + else if (*end == 'G') { value *= MI_MiB; end++; } + else { value = (value + MI_KiB - 1) / MI_KiB; } + if (end[0] == 'I' && end[1] == 'B') { end += 2; } + else if (*end == 'B') { end++; } + } + if (*end == 0) { + desc->value = value; + desc->init = INITIALIZED; + } + else { + // set `init` first to avoid recursion through _mi_warning_message on mimalloc_verbose. + desc->init = DEFAULTED; + if (desc->option == mi_option_verbose && desc->value == 0) { + // if the 'mimalloc_verbose' env var has a bogus value we'd never know + // (since the value defaults to 'off') so in that case briefly enable verbose + desc->value = 1; + _mi_warning_message("environment option mimalloc_%s has an invalid value.\n", desc->name); + desc->value = 0; + } + else { + _mi_warning_message("environment option mimalloc_%s has an invalid value.\n", desc->name); + } + } + } + mi_assert_internal(desc->init != UNINIT); + } + else if (!_mi_preloading()) { + desc->init = DEFAULTED; + } +} diff --git a/Objects/mimalloc/os.c b/Objects/mimalloc/os.c new file mode 100644 index 00000000000000..f3bc7184c41c5b --- /dev/null +++ b/Objects/mimalloc/os.c @@ -0,0 +1,690 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + + +/* ----------------------------------------------------------- + Initialization. + On windows initializes support for aligned allocation and + large OS pages (if MIMALLOC_LARGE_OS_PAGES is true). +----------------------------------------------------------- */ + +static mi_os_mem_config_t mi_os_mem_config = { + 4096, // page size + 0, // large page size (usually 2MiB) + 4096, // allocation granularity + true, // has overcommit? (if true we use MAP_NORESERVE on mmap systems) + false, // must free whole? (on mmap systems we can free anywhere in a mapped range, but on Windows we must free the entire span) + true // has virtual reserve? (if true we can reserve virtual address space without using commit or physical memory) +}; + +bool _mi_os_has_overcommit(void) { + return mi_os_mem_config.has_overcommit; +} + +bool _mi_os_has_virtual_reserve(void) { + return mi_os_mem_config.has_virtual_reserve; +} + + +// OS (small) page size +size_t _mi_os_page_size(void) { + return mi_os_mem_config.page_size; +} + +// if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB) +size_t _mi_os_large_page_size(void) { + return (mi_os_mem_config.large_page_size != 0 ? mi_os_mem_config.large_page_size : _mi_os_page_size()); +} + +bool _mi_os_use_large_page(size_t size, size_t alignment) { + // if we have access, check the size and alignment requirements + if (mi_os_mem_config.large_page_size == 0 || !mi_option_is_enabled(mi_option_allow_large_os_pages)) return false; + return ((size % mi_os_mem_config.large_page_size) == 0 && (alignment % mi_os_mem_config.large_page_size) == 0); +} + +// round to a good OS allocation size (bounded by max 12.5% waste) +size_t _mi_os_good_alloc_size(size_t size) { + size_t align_size; + if (size < 512*MI_KiB) align_size = _mi_os_page_size(); + else if (size < 2*MI_MiB) align_size = 64*MI_KiB; + else if (size < 8*MI_MiB) align_size = 256*MI_KiB; + else if (size < 32*MI_MiB) align_size = 1*MI_MiB; + else align_size = 4*MI_MiB; + if mi_unlikely(size >= (SIZE_MAX - align_size)) return size; // possible overflow? + return _mi_align_up(size, align_size); +} + +void _mi_os_init(void) { + _mi_prim_mem_init(&mi_os_mem_config); +} + + +/* ----------------------------------------------------------- + Util +-------------------------------------------------------------- */ +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats); + +static void* mi_align_up_ptr(void* p, size_t alignment) { + return (void*)_mi_align_up((uintptr_t)p, alignment); +} + +static void* mi_align_down_ptr(void* p, size_t alignment) { + return (void*)_mi_align_down((uintptr_t)p, alignment); +} + + +/* ----------------------------------------------------------- + aligned hinting +-------------------------------------------------------------- */ + +// On 64-bit systems, we can do efficient aligned allocation by using +// the 2TiB to 30TiB area to allocate those. +#if (MI_INTPTR_SIZE >= 8) +static mi_decl_cache_align _Atomic(uintptr_t)aligned_base; + +// Return a MI_SEGMENT_SIZE aligned address that is probably available. +// If this returns NULL, the OS will determine the address but on some OS's that may not be +// properly aligned which can be more costly as it needs to be adjusted afterwards. +// For a size > 1GiB this always returns NULL in order to guarantee good ASLR randomization; +// (otherwise an initial large allocation of say 2TiB has a 50% chance to include (known) addresses +// in the middle of the 2TiB - 6TiB address range (see issue #372)) + +#define MI_HINT_BASE ((uintptr_t)2 << 40) // 2TiB start +#define MI_HINT_AREA ((uintptr_t)4 << 40) // upto 6TiB (since before win8 there is "only" 8TiB available to processes) +#define MI_HINT_MAX ((uintptr_t)30 << 40) // wrap after 30TiB (area after 32TiB is used for huge OS pages) + +void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) +{ + if (try_alignment <= 1 || try_alignment > MI_SEGMENT_SIZE) return NULL; + size = _mi_align_up(size, MI_SEGMENT_SIZE); + if (size > 1*MI_GiB) return NULL; // guarantee the chance of fixed valid address is at most 1/(MI_HINT_AREA / 1<<30) = 1/4096. + #if (MI_SECURE>0) + size += MI_SEGMENT_SIZE; // put in `MI_SEGMENT_SIZE` virtual gaps between hinted blocks; this splits VLA's but increases guarded areas. + #endif + + uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size); + if (hint == 0 || hint > MI_HINT_MAX) { // wrap or initialize + uintptr_t init = MI_HINT_BASE; + #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of aligned allocations unless in debug mode + uintptr_t r = _mi_heap_random_next(mi_prim_get_default_heap()); + init = init + ((MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)) % MI_HINT_AREA); // (randomly 20 bits)*4MiB == 0 to 4TiB + #endif + uintptr_t expected = hint + size; + mi_atomic_cas_strong_acq_rel(&aligned_base, &expected, init); + hint = mi_atomic_add_acq_rel(&aligned_base, size); // this may still give 0 or > MI_HINT_MAX but that is ok, it is a hint after all + } + if (hint%try_alignment != 0) return NULL; + return (void*)hint; +} +#else +void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) { + MI_UNUSED(try_alignment); MI_UNUSED(size); + return NULL; +} +#endif + + +/* ----------------------------------------------------------- + Free memory +-------------------------------------------------------------- */ + +static void mi_os_free_huge_os_pages(void* p, size_t size, mi_stats_t* stats); + +static void mi_os_prim_free(void* addr, size_t size, bool still_committed, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + mi_assert_internal((size % _mi_os_page_size()) == 0); + if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr) + int err = _mi_prim_free(addr, size); + if (err != 0) { + _mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr); + } + mi_stats_t* stats = &_mi_stats_main; + if (still_committed) { _mi_stat_decrease(&stats->committed, size); } + _mi_stat_decrease(&stats->reserved, size); +} + +void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* tld_stats) { + if (mi_memkind_is_os(memid.memkind)) { + size_t csize = _mi_os_good_alloc_size(size); + void* base = addr; + // different base? (due to alignment) + if (memid.mem.os.base != NULL) { + mi_assert(memid.mem.os.base <= addr); + mi_assert((uint8_t*)memid.mem.os.base + memid.mem.os.alignment >= (uint8_t*)addr); + base = memid.mem.os.base; + csize += ((uint8_t*)addr - (uint8_t*)memid.mem.os.base); + } + // free it + if (memid.memkind == MI_MEM_OS_HUGE) { + mi_assert(memid.is_pinned); + mi_os_free_huge_os_pages(base, csize, tld_stats); + } + else { + mi_os_prim_free(base, csize, still_committed, tld_stats); + } + } + else { + // nothing to do + mi_assert(memid.memkind < MI_MEM_OS); + } +} + +void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* tld_stats) { + _mi_os_free_ex(p, size, true, memid, tld_stats); +} + + +/* ----------------------------------------------------------- + Primitive allocation from the OS. +-------------------------------------------------------------- */ + +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +static void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, mi_stats_t* stats) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(is_zero != NULL); + mi_assert_internal(is_large != NULL); + if (size == 0) return NULL; + if (!commit) { allow_large = false; } + if (try_alignment == 0) { try_alignment = 1; } // avoid 0 to ensure there will be no divide by zero when aligning + + *is_zero = false; + void* p = NULL; + int err = _mi_prim_alloc(size, try_alignment, commit, allow_large, is_large, is_zero, &p); + if (err != 0) { + _mi_warning_message("unable to allocate OS memory (error: %d (0x%x), size: 0x%zx bytes, align: 0x%zx, commit: %d, allow large: %d)\n", err, err, size, try_alignment, commit, allow_large); + } + mi_stat_counter_increase(stats->mmap_calls, 1); + if (p != NULL) { + _mi_stat_increase(&stats->reserved, size); + if (commit) { + _mi_stat_increase(&stats->committed, size); + // seems needed for asan (or `mimalloc-test-api` fails) + #ifdef MI_TRACK_ASAN + if (*is_zero) { mi_track_mem_defined(p,size); } + else { mi_track_mem_undefined(p,size); } + #endif + } + } + return p; +} + + +// Primitive aligned allocation from the OS. +// This function guarantees the allocated memory is aligned. +static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** base, mi_stats_t* stats) { + mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0)); + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(is_large != NULL); + mi_assert_internal(is_zero != NULL); + mi_assert_internal(base != NULL); + if (!commit) allow_large = false; + if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL; + size = _mi_align_up(size, _mi_os_page_size()); + + // try first with a hint (this will be aligned directly on Win 10+ or BSD) + void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero, stats); + if (p == NULL) return NULL; + + // aligned already? + if (((uintptr_t)p % alignment) == 0) { + *base = p; + } + else { + // if not aligned, free it, overallocate, and unmap around it + // NOTE(sgross): this warning causes issues in Python tests + // _mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\n", size, p, alignment, commit); + mi_os_prim_free(p, size, commit, stats); + if (size >= (SIZE_MAX - alignment)) return NULL; // overflow + const size_t over_size = size + alignment; + + if (mi_os_mem_config.must_free_whole) { // win32 virtualAlloc cannot free parts of an allocate block + // over-allocate uncommitted (virtual) memory + p = mi_os_prim_alloc(over_size, 1 /*alignment*/, false /* commit? */, false /* allow_large */, is_large, is_zero, stats); + if (p == NULL) return NULL; + + // set p to the aligned part in the full region + // note: this is dangerous on Windows as VirtualFree needs the actual base pointer + // this is handled though by having the `base` field in the memid's + *base = p; // remember the base + p = mi_align_up_ptr(p, alignment); + + // explicitly commit only the aligned part + if (commit) { + _mi_os_commit(p, size, NULL, stats); + } + } + else { // mmap can free inside an allocation + // overallocate... + p = mi_os_prim_alloc(over_size, 1, commit, false, is_large, is_zero, stats); + if (p == NULL) return NULL; + + // and selectively unmap parts around the over-allocated area. (noop on sbrk) + void* aligned_p = mi_align_up_ptr(p, alignment); + size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p; + size_t mid_size = _mi_align_up(size, _mi_os_page_size()); + size_t post_size = over_size - pre_size - mid_size; + mi_assert_internal(pre_size < over_size&& post_size < over_size&& mid_size >= size); + if (pre_size > 0) { mi_os_prim_free(p, pre_size, commit, stats); } + if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); } + // we can return the aligned pointer on `mmap` (and sbrk) systems + p = aligned_p; + *base = aligned_p; // since we freed the pre part, `*base == p`. + } + } + + mi_assert_internal(p == NULL || (p != NULL && *base != NULL && ((uintptr_t)p % alignment) == 0)); + return p; +} + + +/* ----------------------------------------------------------- + OS API: alloc and alloc_aligned +----------------------------------------------------------- */ + +void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + *memid = _mi_memid_none(); + mi_stats_t* stats = &_mi_stats_main; + if (size == 0) return NULL; + size = _mi_os_good_alloc_size(size); + bool os_is_large = false; + bool os_is_zero = false; + void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero, stats); + if (p != NULL) { + *memid = _mi_memid_create_os(true, os_is_zero, os_is_large); + } + return p; +} + +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats) +{ + MI_UNUSED(&_mi_os_get_aligned_hint); // suppress unused warnings + MI_UNUSED(tld_stats); + *memid = _mi_memid_none(); + if (size == 0) return NULL; + size = _mi_os_good_alloc_size(size); + alignment = _mi_align_up(alignment, _mi_os_page_size()); + + bool os_is_large = false; + bool os_is_zero = false; + void* os_base = NULL; + void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base, &_mi_stats_main /*tld->stats*/ ); + if (p != NULL) { + *memid = _mi_memid_create_os(commit, os_is_zero, os_is_large); + memid->mem.os.base = os_base; + memid->mem.os.alignment = alignment; + } + return p; +} + +/* ----------------------------------------------------------- + OS aligned allocation with an offset. This is used + for large alignments > MI_ALIGNMENT_MAX. We use a large mimalloc + page where the object can be aligned at an offset from the start of the segment. + As we may need to overallocate, we need to free such pointers using `mi_free_aligned` + to use the actual start of the memory region. +----------------------------------------------------------- */ + +void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats) { + mi_assert(offset <= MI_SEGMENT_SIZE); + mi_assert(offset <= size); + mi_assert((alignment % _mi_os_page_size()) == 0); + *memid = _mi_memid_none(); + if (offset > MI_SEGMENT_SIZE) return NULL; + if (offset == 0) { + // regular aligned allocation + return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld_stats); + } + else { + // overallocate to align at an offset + const size_t extra = _mi_align_up(offset, alignment) - offset; + const size_t oversize = size + extra; + void* const start = _mi_os_alloc_aligned(oversize, alignment, commit, allow_large, memid, tld_stats); + if (start == NULL) return NULL; + + void* const p = (uint8_t*)start + extra; + mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment)); + // decommit the overallocation at the start + if (commit && extra > _mi_os_page_size()) { + _mi_os_decommit(start, extra, tld_stats); + } + return p; + } +} + +/* ----------------------------------------------------------- + OS memory API: reset, commit, decommit, protect, unprotect. +----------------------------------------------------------- */ + +// OS page align within a given area, either conservative (pages inside the area only), +// or not (straddling pages outside the area is possible) +static void* mi_os_page_align_areax(bool conservative, void* addr, size_t size, size_t* newsize) { + mi_assert(addr != NULL && size > 0); + if (newsize != NULL) *newsize = 0; + if (size == 0 || addr == NULL) return NULL; + + // page align conservatively within the range + void* start = (conservative ? mi_align_up_ptr(addr, _mi_os_page_size()) + : mi_align_down_ptr(addr, _mi_os_page_size())); + void* end = (conservative ? mi_align_down_ptr((uint8_t*)addr + size, _mi_os_page_size()) + : mi_align_up_ptr((uint8_t*)addr + size, _mi_os_page_size())); + ptrdiff_t diff = (uint8_t*)end - (uint8_t*)start; + if (diff <= 0) return NULL; + + mi_assert_internal((conservative && (size_t)diff <= size) || (!conservative && (size_t)diff >= size)); + if (newsize != NULL) *newsize = (size_t)diff; + return start; +} + +static void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t* newsize) { + return mi_os_page_align_areax(true, addr, size, newsize); +} + +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + mi_stats_t* stats = &_mi_stats_main; + if (is_zero != NULL) { *is_zero = false; } + _mi_stat_increase(&stats->committed, size); // use size for precise commit vs. decommit + _mi_stat_counter_increase(&stats->commit_calls, 1); + + // page align range + size_t csize; + void* start = mi_os_page_align_areax(false /* conservative? */, addr, size, &csize); + if (csize == 0) return true; + + // commit + bool os_is_zero = false; + int err = _mi_prim_commit(start, csize, &os_is_zero); + if (err != 0) { + _mi_warning_message("cannot commit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); + return false; + } + if (os_is_zero && is_zero != NULL) { + *is_zero = true; + mi_assert_expensive(mi_mem_is_zero(start, csize)); + } + // note: the following seems required for asan (otherwise `mimalloc-test-stress` fails) + #ifdef MI_TRACK_ASAN + if (os_is_zero) { mi_track_mem_defined(start,csize); } + else { mi_track_mem_undefined(start,csize); } + #endif + return true; +} + +static bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, mi_stats_t* tld_stats) { + MI_UNUSED(tld_stats); + mi_stats_t* stats = &_mi_stats_main; + mi_assert_internal(needs_recommit!=NULL); + _mi_stat_decrease(&stats->committed, size); + + // page align + size_t csize; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return true; + + // decommit + *needs_recommit = true; + int err = _mi_prim_decommit(start,csize,needs_recommit); + if (err != 0) { + _mi_warning_message("cannot decommit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); + } + mi_assert_internal(err == 0); + return (err == 0); +} + +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* tld_stats) { + bool needs_recommit; + return mi_os_decommit_ex(addr, size, &needs_recommit, tld_stats); +} + + +// Signal to the OS that the address range is no longer in use +// but may be used later again. This will release physical memory +// pages and reduce swapping while keeping the memory committed. +// We page align to a conservative area inside the range to reset. +bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) { + // page align conservatively within the range + size_t csize; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr) + _mi_stat_increase(&stats->reset, csize); + _mi_stat_counter_increase(&stats->reset_calls, 1); + + #if (MI_DEBUG>1) && !MI_SECURE && !MI_TRACK_ENABLED // && !MI_TSAN + memset(start, 0, csize); // pretend it is eagerly reset + #endif + + int err = _mi_prim_reset(start, csize); + if (err != 0) { + _mi_warning_message("cannot reset OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); + } + return (err == 0); +} + + +// either resets or decommits memory, returns true if the memory needs +// to be recommitted if it is to be re-used later on. +bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats) +{ + if (mi_option_get(mi_option_purge_delay) < 0) return false; // is purging allowed? + _mi_stat_counter_increase(&stats->purge_calls, 1); + _mi_stat_increase(&stats->purged, size); + + if (mi_option_is_enabled(mi_option_purge_decommits) && // should decommit? + !_mi_preloading()) // don't decommit during preloading (unsafe) + { + bool needs_recommit = true; + mi_os_decommit_ex(p, size, &needs_recommit, stats); + return needs_recommit; + } + else { + if (allow_reset) { // this can sometimes be not allowed if the range is not fully committed + _mi_os_reset(p, size, stats); + } + return false; // needs no recommit + } +} + +// either resets or decommits memory, returns true if the memory needs +// to be recommitted if it is to be re-used later on. +bool _mi_os_purge(void* p, size_t size, mi_stats_t * stats) { + return _mi_os_purge_ex(p, size, true, stats); +} + +// Protect a region in memory to be not accessible. +static bool mi_os_protectx(void* addr, size_t size, bool protect) { + // page align conservatively within the range + size_t csize = 0; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return false; + /* + if (_mi_os_is_huge_reserved(addr)) { + _mi_warning_message("cannot mprotect memory allocated in huge OS pages\n"); + } + */ + int err = _mi_prim_protect(start,csize,protect); + if (err != 0) { + _mi_warning_message("cannot %s OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", (protect ? "protect" : "unprotect"), err, err, start, csize); + } + return (err == 0); +} + +bool _mi_os_protect(void* addr, size_t size) { + return mi_os_protectx(addr, size, true); +} + +bool _mi_os_unprotect(void* addr, size_t size) { + return mi_os_protectx(addr, size, false); +} + + + +/* ---------------------------------------------------------------------------- +Support for allocating huge OS pages (1Gib) that are reserved up-front +and possibly associated with a specific NUMA node. (use `numa_node>=0`) +-----------------------------------------------------------------------------*/ +#define MI_HUGE_OS_PAGE_SIZE (MI_GiB) + + +#if (MI_INTPTR_SIZE >= 8) +// To ensure proper alignment, use our own area for huge OS pages +static mi_decl_cache_align _Atomic(uintptr_t) mi_huge_start; // = 0 + +// Claim an aligned address range for huge pages +static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { + if (total_size != NULL) *total_size = 0; + const size_t size = pages * MI_HUGE_OS_PAGE_SIZE; + + uintptr_t start = 0; + uintptr_t end = 0; + uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start); + do { + start = huge_start; + if (start == 0) { + // Initialize the start address after the 32TiB area + start = ((uintptr_t)32 << 40); // 32TiB virtual start address + #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of huge pages unless in debug mode + uintptr_t r = _mi_heap_random_next(mi_prim_get_default_heap()); + start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF)); // (randomly 12bits)*1GiB == between 0 to 4TiB + #endif + } + end = start + size; + mi_assert_internal(end % MI_SEGMENT_SIZE == 0); + } while (!mi_atomic_cas_strong_acq_rel(&mi_huge_start, &huge_start, end)); + + if (total_size != NULL) *total_size = size; + return (uint8_t*)start; +} +#else +static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { + MI_UNUSED(pages); + if (total_size != NULL) *total_size = 0; + return NULL; +} +#endif + +// Allocate MI_SEGMENT_SIZE aligned huge pages +void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_msecs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid) { + *memid = _mi_memid_none(); + if (psize != NULL) *psize = 0; + if (pages_reserved != NULL) *pages_reserved = 0; + size_t size = 0; + uint8_t* start = mi_os_claim_huge_pages(pages, &size); + if (start == NULL) return NULL; // or 32-bit systems + + // Allocate one page at the time but try to place them contiguously + // We allocate one page at the time to be able to abort if it takes too long + // or to at least allocate as many as available on the system. + mi_msecs_t start_t = _mi_clock_start(); + size_t page = 0; + bool all_zero = true; + while (page < pages) { + // allocate a page + bool is_zero = false; + void* addr = start + (page * MI_HUGE_OS_PAGE_SIZE); + void* p = NULL; + int err = _mi_prim_alloc_huge_os_pages(addr, MI_HUGE_OS_PAGE_SIZE, numa_node, &is_zero, &p); + if (!is_zero) { all_zero = false; } + if (err != 0) { + _mi_warning_message("unable to allocate huge OS page (error: %d (0x%x), address: %p, size: %zx bytes)\n", err, err, addr, MI_HUGE_OS_PAGE_SIZE); + break; + } + + // Did we succeed at a contiguous address? + if (p != addr) { + // no success, issue a warning and break + if (p != NULL) { + _mi_warning_message("could not allocate contiguous huge OS page %zu at %p\n", page, addr); + mi_os_prim_free(p, MI_HUGE_OS_PAGE_SIZE, true, &_mi_stats_main); + } + break; + } + + // success, record it + page++; // increase before timeout check (see issue #711) + _mi_stat_increase(&_mi_stats_main.committed, MI_HUGE_OS_PAGE_SIZE); + _mi_stat_increase(&_mi_stats_main.reserved, MI_HUGE_OS_PAGE_SIZE); + + // check for timeout + if (max_msecs > 0) { + mi_msecs_t elapsed = _mi_clock_end(start_t); + if (page >= 1) { + mi_msecs_t estimate = ((elapsed / (page+1)) * pages); + if (estimate > 2*max_msecs) { // seems like we are going to timeout, break + elapsed = max_msecs + 1; + } + } + if (elapsed > max_msecs) { + _mi_warning_message("huge OS page allocation timed out (after allocating %zu page(s))\n", page); + break; + } + } + } + mi_assert_internal(page*MI_HUGE_OS_PAGE_SIZE <= size); + if (pages_reserved != NULL) { *pages_reserved = page; } + if (psize != NULL) { *psize = page * MI_HUGE_OS_PAGE_SIZE; } + if (page != 0) { + mi_assert(start != NULL); + *memid = _mi_memid_create_os(true /* is committed */, all_zero, true /* is_large */); + memid->memkind = MI_MEM_OS_HUGE; + mi_assert(memid->is_pinned); + #ifdef MI_TRACK_ASAN + if (all_zero) { mi_track_mem_defined(start,size); } + #endif + } + return (page == 0 ? NULL : start); +} + +// free every huge page in a range individually (as we allocated per page) +// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems. +static void mi_os_free_huge_os_pages(void* p, size_t size, mi_stats_t* stats) { + if (p==NULL || size==0) return; + uint8_t* base = (uint8_t*)p; + while (size >= MI_HUGE_OS_PAGE_SIZE) { + mi_os_prim_free(base, MI_HUGE_OS_PAGE_SIZE, true, stats); + size -= MI_HUGE_OS_PAGE_SIZE; + base += MI_HUGE_OS_PAGE_SIZE; + } +} + +/* ---------------------------------------------------------------------------- +Support NUMA aware allocation +-----------------------------------------------------------------------------*/ + +_Atomic(size_t) _mi_numa_node_count; // = 0 // cache the node count + +size_t _mi_os_numa_node_count_get(void) { + size_t count = mi_atomic_load_acquire(&_mi_numa_node_count); + if (count <= 0) { + long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly? + if (ncount > 0) { + count = (size_t)ncount; + } + else { + count = _mi_prim_numa_node_count(); // or detect dynamically + if (count == 0) count = 1; + } + mi_atomic_store_release(&_mi_numa_node_count, count); // save it + _mi_verbose_message("using %zd numa regions\n", count); + } + return count; +} + +int _mi_os_numa_node_get(mi_os_tld_t* tld) { + MI_UNUSED(tld); + size_t numa_count = _mi_os_numa_node_count(); + if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0 + // never more than the node count and >= 0 + size_t numa_node = _mi_prim_numa_node(); + if (numa_node >= numa_count) { numa_node = numa_node % numa_count; } + return (int)numa_node; +} diff --git a/Objects/mimalloc/page-queue.c b/Objects/mimalloc/page-queue.c new file mode 100644 index 00000000000000..cb54b3740196e9 --- /dev/null +++ b/Objects/mimalloc/page-queue.c @@ -0,0 +1,332 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + Definition of page queues for each block size +----------------------------------------------------------- */ + +#ifndef MI_IN_PAGE_C +#error "this file should be included from 'page.c'" +#endif + +/* ----------------------------------------------------------- + Minimal alignment in machine words (i.e. `sizeof(void*)`) +----------------------------------------------------------- */ + +#if (MI_MAX_ALIGN_SIZE > 4*MI_INTPTR_SIZE) + #error "define alignment for more than 4x word size for this platform" +#elif (MI_MAX_ALIGN_SIZE > 2*MI_INTPTR_SIZE) + #define MI_ALIGN4W // 4 machine words minimal alignment +#elif (MI_MAX_ALIGN_SIZE > MI_INTPTR_SIZE) + #define MI_ALIGN2W // 2 machine words minimal alignment +#else + // ok, default alignment is 1 word +#endif + + +/* ----------------------------------------------------------- + Queue query +----------------------------------------------------------- */ + + +static inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) { + return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+sizeof(uintptr_t))); +} + +static inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) { + return (pq->block_size == (MI_MEDIUM_OBJ_SIZE_MAX+(2*sizeof(uintptr_t)))); +} + +static inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) { + return (pq->block_size > MI_MEDIUM_OBJ_SIZE_MAX); +} + +/* ----------------------------------------------------------- + Bins +----------------------------------------------------------- */ + +// Return the bin for a given field size. +// Returns MI_BIN_HUGE if the size is too large. +// We use `wsize` for the size in "machine word sizes", +// i.e. byte size == `wsize*sizeof(void*)`. +static inline uint8_t mi_bin(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } + #if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } + #elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } + #else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } + #endif + else if (wsize > MI_MEDIUM_OBJ_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { + #if defined(MI_ALIGN4W) + if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes + #endif + wsize--; + // find the highest bit + uint8_t b = (uint8_t)mi_bsr(wsize); // note: wsize != 0 + // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). + // - adjust with 3 because we use do not round the first 8 sizes + // which each get an exact bin + bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; + mi_assert_internal(bin < MI_BIN_HUGE); + } + mi_assert_internal(bin > 0 && bin <= MI_BIN_HUGE); + return bin; +} + + + +/* ----------------------------------------------------------- + Queue of pages with free blocks +----------------------------------------------------------- */ + +uint8_t _mi_bin(size_t size) { + return mi_bin(size); +} + +size_t _mi_bin_size(uint8_t bin) { + return _mi_heap_empty.pages[bin].block_size; +} + +// Good size for allocation +size_t mi_good_size(size_t size) mi_attr_noexcept { + if (size <= MI_MEDIUM_OBJ_SIZE_MAX) { + return _mi_bin_size(mi_bin(size)); + } + else { + return _mi_align_up(size,_mi_os_page_size()); + } +} + +#if (MI_DEBUG>1) +static bool mi_page_queue_contains(mi_page_queue_t* queue, const mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_page_t* list = queue->first; + while (list != NULL) { + mi_assert_internal(list->next == NULL || list->next->prev == list); + mi_assert_internal(list->prev == NULL || list->prev->next == list); + if (list == page) break; + list = list->next; + } + return (list == page); +} + +#endif + +#if (MI_DEBUG>1) +static bool mi_heap_contains_queue(const mi_heap_t* heap, const mi_page_queue_t* pq) { + return (pq >= &heap->pages[0] && pq <= &heap->pages[MI_BIN_FULL]); +} +#endif + +static mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) { + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : mi_bin(page->xblock_size)); + mi_heap_t* heap = mi_page_heap(page); + mi_assert_internal(heap != NULL && bin <= MI_BIN_FULL); + mi_page_queue_t* pq = &heap->pages[bin]; + mi_assert_internal(bin >= MI_BIN_HUGE || page->xblock_size == pq->block_size); + mi_assert_expensive(mi_page_queue_contains(pq, page)); + return pq; +} + +static mi_page_queue_t* mi_heap_page_queue_of(mi_heap_t* heap, const mi_page_t* page) { + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : mi_bin(page->xblock_size)); + mi_assert_internal(bin <= MI_BIN_FULL); + mi_page_queue_t* pq = &heap->pages[bin]; + mi_assert_internal(mi_page_is_in_full(page) || page->xblock_size == pq->block_size); + return pq; +} + +// The current small page array is for efficiency and for each +// small size (up to 256) it points directly to the page for that +// size without having to compute the bin. This means when the +// current free page queue is updated for a small bin, we need to update a +// range of entries in `_mi_page_small_free`. +static inline void mi_heap_queue_first_update(mi_heap_t* heap, const mi_page_queue_t* pq) { + mi_assert_internal(mi_heap_contains_queue(heap,pq)); + size_t size = pq->block_size; + if (size > MI_SMALL_SIZE_MAX) return; + + mi_page_t* page = pq->first; + if (pq->first == NULL) page = (mi_page_t*)&_mi_page_empty; + + // find index in the right direct page array + size_t start; + size_t idx = _mi_wsize_from_size(size); + mi_page_t** pages_free = heap->pages_free_direct; + + if (pages_free[idx] == page) return; // already set + + // find start slot + if (idx<=1) { + start = 0; + } + else { + // find previous size; due to minimal alignment upto 3 previous bins may need to be skipped + uint8_t bin = mi_bin(size); + const mi_page_queue_t* prev = pq - 1; + while( bin == mi_bin(prev->block_size) && prev > &heap->pages[0]) { + prev--; + } + start = 1 + _mi_wsize_from_size(prev->block_size); + if (start > idx) start = idx; + } + + // set size range to the right page + mi_assert(start <= idx); + for (size_t sz = start; sz <= idx; sz++) { + pages_free[sz] = page; + } +} + +/* +static bool mi_page_queue_is_empty(mi_page_queue_t* queue) { + return (queue->first == NULL); +} +*/ + +static void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(mi_page_queue_contains(queue, page)); + mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_MEDIUM_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); + mi_heap_t* heap = mi_page_heap(page); + + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == queue->last) queue->last = page->prev; + if (page == queue->first) { + queue->first = page->next; + // update first + mi_assert_internal(mi_heap_contains_queue(heap, queue)); + mi_heap_queue_first_update(heap,queue); + } + heap->page_count--; + page->next = NULL; + page->prev = NULL; + // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), NULL); + mi_page_set_in_full(page,false); +} + + +static void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) { + mi_assert_internal(mi_page_heap(page) == heap); + mi_assert_internal(!mi_page_queue_contains(queue, page)); + #if MI_HUGE_PAGE_ABANDON + mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + #endif + mi_assert_internal(page->xblock_size == queue->block_size || + (page->xblock_size > MI_MEDIUM_OBJ_SIZE_MAX) || + (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); + + mi_page_set_in_full(page, mi_page_queue_is_full(queue)); + // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), heap); + page->next = queue->first; + page->prev = NULL; + if (queue->first != NULL) { + mi_assert_internal(queue->first->prev == NULL); + queue->first->prev = page; + queue->first = page; + } + else { + queue->first = queue->last = page; + } + + // update direct + mi_heap_queue_first_update(heap, queue); + heap->page_count++; +} + + +static void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(mi_page_queue_contains(from, page)); + mi_assert_expensive(!mi_page_queue_contains(to, page)); + + mi_assert_internal((page->xblock_size == to->block_size && page->xblock_size == from->block_size) || + (page->xblock_size == to->block_size && mi_page_queue_is_full(from)) || + (page->xblock_size == from->block_size && mi_page_queue_is_full(to)) || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(to)) || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_full(to))); + + mi_heap_t* heap = mi_page_heap(page); + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == from->last) from->last = page->prev; + if (page == from->first) { + from->first = page->next; + // update first + mi_assert_internal(mi_heap_contains_queue(heap, from)); + mi_heap_queue_first_update(heap, from); + } + + page->prev = to->last; + page->next = NULL; + if (to->last != NULL) { + mi_assert_internal(heap == mi_page_heap(to->last)); + to->last->next = page; + to->last = page; + } + else { + to->first = page; + to->last = page; + mi_heap_queue_first_update(heap, to); + } + + mi_page_set_in_full(page, mi_page_queue_is_full(to)); +} + +// Only called from `mi_heap_absorb`. +size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append) { + mi_assert_internal(mi_heap_contains_queue(heap,pq)); + mi_assert_internal(pq->block_size == append->block_size); + + if (append->first==NULL) return 0; + + // set append pages to new heap and count + size_t count = 0; + for (mi_page_t* page = append->first; page != NULL; page = page->next) { + // inline `mi_page_set_heap` to avoid wrong assertion during absorption; + // in this case it is ok to be delayed freeing since both "to" and "from" heap are still alive. + mi_atomic_store_release(&page->xheap, (uintptr_t)heap); + // set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a + // side effect that it spins until any DELAYED_FREEING is finished. This ensures + // that after appending only the new heap will be used for delayed free operations. + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false); + count++; + } + + if (pq->last==NULL) { + // take over afresh + mi_assert_internal(pq->first==NULL); + pq->first = append->first; + pq->last = append->last; + mi_heap_queue_first_update(heap, pq); + } + else { + // append to end + mi_assert_internal(pq->last!=NULL); + mi_assert_internal(append->first!=NULL); + pq->last->next = append->first; + append->first->prev = pq->last; + pq->last = append->last; + } + return count; +} diff --git a/Objects/mimalloc/page.c b/Objects/mimalloc/page.c new file mode 100644 index 00000000000000..4610cf27afff75 --- /dev/null +++ b/Objects/mimalloc/page.c @@ -0,0 +1,939 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + The core of the allocator. Every segment contains + pages of a certain block size. The main function + exported is `mi_malloc_generic`. +----------------------------------------------------------- */ + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +/* ----------------------------------------------------------- + Definition of page queues for each block size +----------------------------------------------------------- */ + +#define MI_IN_PAGE_C +#include "page-queue.c" +#undef MI_IN_PAGE_C + + +/* ----------------------------------------------------------- + Page helpers +----------------------------------------------------------- */ + +// Index a block in a page +static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) { + MI_UNUSED(page); + mi_assert_internal(page != NULL); + mi_assert_internal(i <= page->reserved); + return (mi_block_t*)((uint8_t*)page_start + (i * block_size)); +} + +static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld); +static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld); + +#if (MI_DEBUG>=3) +static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) { + size_t count = 0; + while (head != NULL) { + mi_assert_internal(page == _mi_ptr_page(head)); + count++; + head = mi_block_next(page, head); + } + return count; +} + +/* +// Start of the page available memory +static inline uint8_t* mi_page_area(const mi_page_t* page) { + return _mi_page_start(_mi_page_segment(page), page, NULL); +} +*/ + +static bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) { + size_t psize; + uint8_t* page_area = _mi_page_start(_mi_page_segment(page), page, &psize); + mi_block_t* start = (mi_block_t*)page_area; + mi_block_t* end = (mi_block_t*)(page_area + psize); + while(p != NULL) { + if (p < start || p >= end) return false; + p = mi_block_next(page, p); + } +#if MI_DEBUG>3 // generally too expensive to check this + if (page->free_is_zero) { + const size_t ubsize = mi_page_usable_block_size(page); + for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page, block)) { + mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t))); + } + } +#endif + return true; +} + +static bool mi_page_is_valid_init(mi_page_t* page) { + mi_assert_internal(page->xblock_size > 0); + mi_assert_internal(page->used <= page->capacity); + mi_assert_internal(page->capacity <= page->reserved); + + mi_segment_t* segment = _mi_page_segment(page); + uint8_t* start = _mi_page_start(segment,page,NULL); + mi_assert_internal(start == _mi_segment_page_start(segment,page,NULL)); + //const size_t bsize = mi_page_block_size(page); + //mi_assert_internal(start + page->capacity*page->block_size == page->top); + + mi_assert_internal(mi_page_list_is_valid(page,page->free)); + mi_assert_internal(mi_page_list_is_valid(page,page->local_free)); + + #if MI_DEBUG>3 // generally too expensive to check this + if (page->free_is_zero) { + const size_t ubsize = mi_page_usable_block_size(page); + for(mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) { + mi_assert_expensive(mi_mem_is_zero(block + 1, ubsize - sizeof(mi_block_t))); + } + } + #endif + + #if !MI_TRACK_ENABLED && !MI_TSAN + mi_block_t* tfree = mi_page_thread_free(page); + mi_assert_internal(mi_page_list_is_valid(page, tfree)); + //size_t tfree_count = mi_page_list_count(page, tfree); + //mi_assert_internal(tfree_count <= page->thread_freed + 1); + #endif + + size_t free_count = mi_page_list_count(page, page->free) + mi_page_list_count(page, page->local_free); + mi_assert_internal(page->used + free_count == page->capacity); + + return true; +} + +extern bool _mi_process_is_initialized; // has mi_process_init been called? + +bool _mi_page_is_valid(mi_page_t* page) { + mi_assert_internal(mi_page_is_valid_init(page)); + #if MI_SECURE + mi_assert_internal(page->keys[0] != 0); + #endif + if (mi_page_heap(page)!=NULL) { + mi_segment_t* segment = _mi_page_segment(page); + + mi_assert_internal(!_mi_process_is_initialized || segment->thread_id==0 || segment->thread_id == mi_page_heap(page)->thread_id); + #if MI_HUGE_PAGE_ABANDON + if (segment->kind != MI_SEGMENT_HUGE) + #endif + { + mi_page_queue_t* pq = mi_page_queue_of(page); + mi_assert_internal(mi_page_queue_contains(pq, page)); + mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_MEDIUM_OBJ_SIZE_MAX || mi_page_is_in_full(page)); + mi_assert_internal(mi_heap_contains_queue(mi_page_heap(page),pq)); + } + } + return true; +} +#endif + +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { + while (!_mi_page_try_use_delayed_free(page, delay, override_never)) { + mi_atomic_yield(); + } +} + +bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { + mi_thread_free_t tfreex; + mi_delayed_t old_delay; + mi_thread_free_t tfree; + size_t yield_count = 0; + do { + tfree = mi_atomic_load_acquire(&page->xthread_free); // note: must acquire as we can break/repeat this loop and not do a CAS; + tfreex = mi_tf_set_delayed(tfree, delay); + old_delay = mi_tf_delayed(tfree); + if mi_unlikely(old_delay == MI_DELAYED_FREEING) { + if (yield_count >= 4) return false; // give up after 4 tries + yield_count++; + mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done. + // tfree = mi_tf_set_delayed(tfree, MI_NO_DELAYED_FREE); // will cause CAS to busy fail + } + else if (delay == old_delay) { + break; // avoid atomic operation if already equal + } + else if (!override_never && old_delay == MI_NEVER_DELAYED_FREE) { + break; // leave never-delayed flag set + } + } while ((old_delay == MI_DELAYED_FREEING) || + !mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); + + return true; // success +} + +/* ----------------------------------------------------------- + Page collect the `local_free` and `thread_free` lists +----------------------------------------------------------- */ + +// Collect the local `thread_free` list using an atomic exchange. +// Note: The exchange must be done atomically as this is used right after +// moving to the full list in `mi_page_collect_ex` and we need to +// ensure that there was no race where the page became unfull just before the move. +static void _mi_page_thread_free_collect(mi_page_t* page) +{ + mi_block_t* head; + mi_thread_free_t tfreex; + mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free); + do { + head = mi_tf_block(tfree); + tfreex = mi_tf_set_block(tfree,NULL); + } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tfree, tfreex)); + + // return if the list is empty + if (head == NULL) return; + + // find the tail -- also to get a proper count (without data races) + uint32_t max_count = page->capacity; // cannot collect more than capacity + uint32_t count = 1; + mi_block_t* tail = head; + mi_block_t* next; + while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) { + count++; + tail = next; + } + // if `count > max_count` there was a memory corruption (possibly infinite list due to double multi-threaded free) + if (count > max_count) { + _mi_error_message(EFAULT, "corrupted thread-free list\n"); + return; // the thread-free items cannot be freed + } + + // and append the current local free list + mi_block_set_next(page,tail, page->local_free); + page->local_free = head; + + // update counts now + page->used -= count; +} + +void _mi_page_free_collect(mi_page_t* page, bool force) { + mi_assert_internal(page!=NULL); + + // collect the thread free list + if (force || mi_page_thread_free(page) != NULL) { // quick test to avoid an atomic operation + _mi_page_thread_free_collect(page); + } + + // and the local free list + if (page->local_free != NULL) { + if mi_likely(page->free == NULL) { + // usual case + page->free = page->local_free; + page->local_free = NULL; + page->free_is_zero = false; + } + else if (force) { + // append -- only on shutdown (force) as this is a linear operation + mi_block_t* tail = page->local_free; + mi_block_t* next; + while ((next = mi_block_next(page, tail)) != NULL) { + tail = next; + } + mi_block_set_next(page, tail, page->free); + page->free = page->local_free; + page->local_free = NULL; + page->free_is_zero = false; + } + } + + mi_assert_internal(!force || page->local_free == NULL); +} + + + +/* ----------------------------------------------------------- + Page fresh and retire +----------------------------------------------------------- */ + +// called from segments when reclaiming abandoned pages +void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page) { + mi_assert_expensive(mi_page_is_valid_init(page)); + + mi_assert_internal(mi_page_heap(page) == heap); + mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE); + #if MI_HUGE_PAGE_ABANDON + mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + #endif + + // TODO: push on full queue immediately if it is full? + mi_page_queue_t* pq = mi_page_queue(heap, mi_page_block_size(page)); + mi_page_queue_push(heap, pq, page); + mi_assert_expensive(_mi_page_is_valid(page)); +} + +// allocate a fresh page from a segment +static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size_t block_size, size_t page_alignment) { + #if !MI_HUGE_PAGE_ABANDON + mi_assert_internal(pq != NULL); + mi_assert_internal(mi_heap_contains_queue(heap, pq)); + mi_assert_internal(page_alignment > 0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || block_size == pq->block_size); + #endif + mi_page_t* page = _mi_segment_page_alloc(heap, block_size, page_alignment, &heap->tld->segments, &heap->tld->os); + if (page == NULL) { + // this may be out-of-memory, or an abandoned page was reclaimed (and in our queue) + return NULL; + } + mi_assert_internal(page_alignment >0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || _mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + mi_assert_internal(pq!=NULL || page->xblock_size != 0); + mi_assert_internal(pq!=NULL || mi_page_block_size(page) >= block_size); + // a fresh page was found, initialize it + const size_t full_block_size = ((pq == NULL || mi_page_queue_is_huge(pq)) ? mi_page_block_size(page) : block_size); // see also: mi_segment_huge_page_alloc + mi_assert_internal(full_block_size >= block_size); + mi_page_init(heap, page, full_block_size, heap->tld); + mi_heap_stat_increase(heap, pages, 1); + if (pq != NULL) { mi_page_queue_push(heap, pq, page); } + mi_assert_expensive(_mi_page_is_valid(page)); + return page; +} + +// Get a fresh page to use +static mi_page_t* mi_page_fresh(mi_heap_t* heap, mi_page_queue_t* pq) { + mi_assert_internal(mi_heap_contains_queue(heap, pq)); + mi_page_t* page = mi_page_fresh_alloc(heap, pq, pq->block_size, 0); + if (page==NULL) return NULL; + mi_assert_internal(pq->block_size==mi_page_block_size(page)); + mi_assert_internal(pq==mi_page_queue(heap, mi_page_block_size(page))); + return page; +} + +/* ----------------------------------------------------------- + Do any delayed frees + (put there by other threads if they deallocated in a full page) +----------------------------------------------------------- */ +void _mi_heap_delayed_free_all(mi_heap_t* heap) { + while (!_mi_heap_delayed_free_partial(heap)) { + mi_atomic_yield(); + } +} + +// returns true if all delayed frees were processed +bool _mi_heap_delayed_free_partial(mi_heap_t* heap) { + // take over the list (note: no atomic exchange since it is often NULL) + mi_block_t* block = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); + while (block != NULL && !mi_atomic_cas_ptr_weak_acq_rel(mi_block_t, &heap->thread_delayed_free, &block, NULL)) { /* nothing */ }; + bool all_freed = true; + + // and free them all + while(block != NULL) { + mi_block_t* next = mi_block_nextx(heap,block, heap->keys); + // use internal free instead of regular one to keep stats etc correct + if (!_mi_free_delayed_block(block)) { + // we might already start delayed freeing while another thread has not yet + // reset the delayed_freeing flag; in that case delay it further by reinserting the current block + // into the delayed free list + all_freed = false; + mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); + do { + mi_block_set_nextx(heap, block, dfree, heap->keys); + } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block)); + } + block = next; + } + return all_freed; +} + +/* ----------------------------------------------------------- + Unfull, abandon, free and retire +----------------------------------------------------------- */ + +// Move a page from the full list back to a regular list +void _mi_page_unfull(mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(mi_page_is_in_full(page)); + if (!mi_page_is_in_full(page)) return; + + mi_heap_t* heap = mi_page_heap(page); + mi_page_queue_t* pqfull = &heap->pages[MI_BIN_FULL]; + mi_page_set_in_full(page, false); // to get the right queue + mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page); + mi_page_set_in_full(page, true); + mi_page_queue_enqueue_from(pq, pqfull, page); +} + +static void mi_page_to_full(mi_page_t* page, mi_page_queue_t* pq) { + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(!mi_page_immediate_available(page)); + mi_assert_internal(!mi_page_is_in_full(page)); + + if (mi_page_is_in_full(page)) return; + mi_page_queue_enqueue_from(&mi_page_heap(page)->pages[MI_BIN_FULL], pq, page); + _mi_page_free_collect(page,false); // try to collect right away in case another thread freed just before MI_USE_DELAYED_FREE was set +} + + +// Abandon a page with used blocks at the end of a thread. +// Note: only call if it is ensured that no references exist from +// the `page->heap->thread_delayed_free` into this page. +// Currently only called through `mi_heap_collect_ex` which ensures this. +void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(mi_page_heap(page) != NULL); + + mi_heap_t* pheap = mi_page_heap(page); + + // remove from our page list + mi_segments_tld_t* segments_tld = &pheap->tld->segments; + mi_page_queue_remove(pq, page); + + // page is no longer associated with our heap + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_page_set_heap(page, NULL); + +#if (MI_DEBUG>1) && !MI_TRACK_ENABLED + // check there are no references left.. + for (mi_block_t* block = (mi_block_t*)pheap->thread_delayed_free; block != NULL; block = mi_block_nextx(pheap, block, pheap->keys)) { + mi_assert_internal(_mi_ptr_page(block) != page); + } +#endif + + // and abandon it + mi_assert_internal(mi_page_heap(page) == NULL); + _mi_segment_page_abandon(page,segments_tld); +} + + +// Free a page with no more free blocks +void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(mi_page_all_free(page)); + mi_assert_internal(mi_page_thread_free_flag(page)!=MI_DELAYED_FREEING); + + // no more aligned blocks in here + mi_page_set_has_aligned(page, false); + + mi_heap_t* heap = mi_page_heap(page); + + // remove from the page list + // (no need to do _mi_heap_delayed_free first as all blocks are already free) + mi_segments_tld_t* segments_tld = &heap->tld->segments; + mi_page_queue_remove(pq, page); + + // and free it + mi_page_set_heap(page,NULL); + _mi_segment_page_free(page, force, segments_tld); +} + +// Retire parameters +#define MI_MAX_RETIRE_SIZE (MI_MEDIUM_OBJ_SIZE_MAX) +#define MI_RETIRE_CYCLES (16) + +// Retire a page with no more used blocks +// Important to not retire too quickly though as new +// allocations might coming. +// Note: called from `mi_free` and benchmarks often +// trigger this due to freeing everything and then +// allocating again so careful when changing this. +void _mi_page_retire(mi_page_t* page) mi_attr_noexcept { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(mi_page_all_free(page)); + + mi_page_set_has_aligned(page, false); + + // don't retire too often.. + // (or we end up retiring and re-allocating most of the time) + // NOTE: refine this more: we should not retire if this + // is the only page left with free blocks. It is not clear + // how to check this efficiently though... + // for now, we don't retire if it is the only page left of this size class. + mi_page_queue_t* pq = mi_page_queue_of(page); + if mi_likely(page->xblock_size <= MI_MAX_RETIRE_SIZE && !mi_page_queue_is_special(pq)) { // not too large && not full or huge queue? + if (pq->last==page && pq->first==page) { // the only page in the queue? + mi_stat_counter_increase(_mi_stats_main.page_no_retire,1); + page->retire_expire = 1 + (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4); + mi_heap_t* heap = mi_page_heap(page); + mi_assert_internal(pq >= heap->pages); + const size_t index = pq - heap->pages; + mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE); + if (index < heap->page_retired_min) heap->page_retired_min = index; + if (index > heap->page_retired_max) heap->page_retired_max = index; + mi_assert_internal(mi_page_all_free(page)); + return; // dont't free after all + } + } + _mi_page_free(page, pq, false); +} + +// free retired pages: we don't need to look at the entire queues +// since we only retire pages that are at the head position in a queue. +void _mi_heap_collect_retired(mi_heap_t* heap, bool force) { + size_t min = MI_BIN_FULL; + size_t max = 0; + for(size_t bin = heap->page_retired_min; bin <= heap->page_retired_max; bin++) { + mi_page_queue_t* pq = &heap->pages[bin]; + mi_page_t* page = pq->first; + if (page != NULL && page->retire_expire != 0) { + if (mi_page_all_free(page)) { + page->retire_expire--; + if (force || page->retire_expire == 0) { + _mi_page_free(pq->first, pq, force); + } + else { + // keep retired, update min/max + if (bin < min) min = bin; + if (bin > max) max = bin; + } + } + else { + page->retire_expire = 0; + } + } + } + heap->page_retired_min = min; + heap->page_retired_max = max; +} + + +/* ----------------------------------------------------------- + Initialize the initial free list in a page. + In secure mode we initialize a randomized list by + alternating between slices. +----------------------------------------------------------- */ + +#define MI_MAX_SLICE_SHIFT (6) // at most 64 slices +#define MI_MAX_SLICES (1UL << MI_MAX_SLICE_SHIFT) +#define MI_MIN_SLICES (2) + +static void mi_page_free_list_extend_secure(mi_heap_t* const heap, mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) { + MI_UNUSED(stats); + #if (MI_SECURE<=2) + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->local_free == NULL); + #endif + mi_assert_internal(page->capacity + extend <= page->reserved); + mi_assert_internal(bsize == mi_page_block_size(page)); + void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL); + + // initialize a randomized free list + // set up `slice_count` slices to alternate between + size_t shift = MI_MAX_SLICE_SHIFT; + while ((extend >> shift) == 0) { + shift--; + } + const size_t slice_count = (size_t)1U << shift; + const size_t slice_extend = extend / slice_count; + mi_assert_internal(slice_extend >= 1); + mi_block_t* blocks[MI_MAX_SLICES]; // current start of the slice + size_t counts[MI_MAX_SLICES]; // available objects in the slice + for (size_t i = 0; i < slice_count; i++) { + blocks[i] = mi_page_block_at(page, page_area, bsize, page->capacity + i*slice_extend); + counts[i] = slice_extend; + } + counts[slice_count-1] += (extend % slice_count); // final slice holds the modulus too (todo: distribute evenly?) + + // and initialize the free list by randomly threading through them + // set up first element + const uintptr_t r = _mi_heap_random_next(heap); + size_t current = r % slice_count; + counts[current]--; + mi_block_t* const free_start = blocks[current]; + // and iterate through the rest; use `random_shuffle` for performance + uintptr_t rnd = _mi_random_shuffle(r|1); // ensure not 0 + for (size_t i = 1; i < extend; i++) { + // call random_shuffle only every INTPTR_SIZE rounds + const size_t round = i%MI_INTPTR_SIZE; + if (round == 0) rnd = _mi_random_shuffle(rnd); + // select a random next slice index + size_t next = ((rnd >> 8*round) & (slice_count-1)); + while (counts[next]==0) { // ensure it still has space + next++; + if (next==slice_count) next = 0; + } + // and link the current block to it + counts[next]--; + mi_block_t* const block = blocks[current]; + blocks[current] = (mi_block_t*)((uint8_t*)block + bsize); // bump to the following block + mi_block_set_next(page, block, blocks[next]); // and set next; note: we may have `current == next` + current = next; + } + // prepend to the free list (usually NULL) + mi_block_set_next(page, blocks[current], page->free); // end of the list + page->free = free_start; +} + +static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) +{ + MI_UNUSED(stats); + #if (MI_SECURE <= 2) + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->local_free == NULL); + #endif + mi_assert_internal(page->capacity + extend <= page->reserved); + mi_assert_internal(bsize == mi_page_block_size(page)); + void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL ); + + mi_block_t* const start = mi_page_block_at(page, page_area, bsize, page->capacity); + + // initialize a sequential free list + mi_block_t* const last = mi_page_block_at(page, page_area, bsize, page->capacity + extend - 1); + mi_block_t* block = start; + while(block <= last) { + mi_block_t* next = (mi_block_t*)((uint8_t*)block + bsize); + mi_block_set_next(page,block,next); + block = next; + } + // prepend to free list (usually `NULL`) + mi_block_set_next(page, last, page->free); + page->free = start; +} + +/* ----------------------------------------------------------- + Page initialize and extend the capacity +----------------------------------------------------------- */ + +#define MI_MAX_EXTEND_SIZE (4*1024) // heuristic, one OS page seems to work well. +#if (MI_SECURE>0) +#define MI_MIN_EXTEND (8*MI_SECURE) // extend at least by this many +#else +#define MI_MIN_EXTEND (4) +#endif + +// Extend the capacity (up to reserved) by initializing a free list +// We do at most `MI_MAX_EXTEND` to avoid touching too much memory +// Note: we also experimented with "bump" allocation on the first +// allocations but this did not speed up any benchmark (due to an +// extra test in malloc? or cache effects?) +static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) { + MI_UNUSED(tld); + mi_assert_expensive(mi_page_is_valid_init(page)); + #if (MI_SECURE<=2) + mi_assert(page->free == NULL); + mi_assert(page->local_free == NULL); + if (page->free != NULL) return; + #endif + if (page->capacity >= page->reserved) return; + + size_t page_size; + _mi_page_start(_mi_page_segment(page), page, &page_size); + mi_stat_counter_increase(tld->stats.pages_extended, 1); + + // calculate the extend count + const size_t bsize = (page->xblock_size < MI_HUGE_BLOCK_SIZE ? page->xblock_size : page_size); + size_t extend = page->reserved - page->capacity; + mi_assert_internal(extend > 0); + + size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/(uint32_t)bsize); + if (max_extend < MI_MIN_EXTEND) { max_extend = MI_MIN_EXTEND; } + mi_assert_internal(max_extend > 0); + + if (extend > max_extend) { + // ensure we don't touch memory beyond the page to reduce page commit. + // the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%. + extend = max_extend; + } + + mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved); + mi_assert_internal(extend < (1UL<<16)); + + // and append the extend the free list + if (extend < MI_MIN_SLICES || MI_SECURE==0) { //!mi_option_is_enabled(mi_option_secure)) { + mi_page_free_list_extend(page, bsize, extend, &tld->stats ); + } + else { + mi_page_free_list_extend_secure(heap, page, bsize, extend, &tld->stats); + } + // enable the new free list + page->capacity += (uint16_t)extend; + mi_stat_increase(tld->stats.page_committed, extend * bsize); + mi_assert_expensive(mi_page_is_valid_init(page)); +} + +// Initialize a fresh page +static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi_tld_t* tld) { + mi_assert(page != NULL); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert(segment != NULL); + mi_assert_internal(block_size > 0); + // set fields + mi_page_set_heap(page, heap); + page->xblock_size = (block_size < MI_HUGE_BLOCK_SIZE ? (uint32_t)block_size : MI_HUGE_BLOCK_SIZE); // initialize before _mi_segment_page_start + size_t page_size; + const void* page_start = _mi_segment_page_start(segment, page, &page_size); + MI_UNUSED(page_start); + mi_track_mem_noaccess(page_start,page_size); + mi_assert_internal(mi_page_block_size(page) <= page_size); + mi_assert_internal(page_size <= page->slice_count*MI_SEGMENT_SLICE_SIZE); + mi_assert_internal(page_size / block_size < (1L<<16)); + page->reserved = (uint16_t)(page_size / block_size); + mi_assert_internal(page->reserved > 0); + #if (MI_PADDING || MI_ENCODE_FREELIST) + page->keys[0] = _mi_heap_random_next(heap); + page->keys[1] = _mi_heap_random_next(heap); + #endif + page->free_is_zero = page->is_zero_init; + #if MI_DEBUG>2 + if (page->is_zero_init) { + mi_track_mem_defined(page_start, page_size); + mi_assert_expensive(mi_mem_is_zero(page_start, page_size)); + } + #endif + + mi_assert_internal(page->is_committed); + mi_assert_internal(page->capacity == 0); + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->used == 0); + mi_assert_internal(page->xthread_free == 0); + mi_assert_internal(page->next == NULL); + mi_assert_internal(page->prev == NULL); + mi_assert_internal(page->retire_expire == 0); + mi_assert_internal(!mi_page_has_aligned(page)); + #if (MI_PADDING || MI_ENCODE_FREELIST) + mi_assert_internal(page->keys[0] != 0); + mi_assert_internal(page->keys[1] != 0); + #endif + mi_assert_expensive(mi_page_is_valid_init(page)); + + // initialize an initial free list + mi_page_extend_free(heap,page,tld); + mi_assert(mi_page_immediate_available(page)); +} + + +/* ----------------------------------------------------------- + Find pages with free blocks +-------------------------------------------------------------*/ + +// Find a page with free blocks of `page->block_size`. +static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* pq, bool first_try) +{ + // search through the pages in "next fit" order + #if MI_STAT + size_t count = 0; + #endif + mi_page_t* page = pq->first; + while (page != NULL) + { + mi_page_t* next = page->next; // remember next + #if MI_STAT + count++; + #endif + + // 0. collect freed blocks by us and other threads + _mi_page_free_collect(page, false); + + // 1. if the page contains free blocks, we are done + if (mi_page_immediate_available(page)) { + break; // pick this one + } + + // 2. Try to extend + if (page->capacity < page->reserved) { + mi_page_extend_free(heap, page, heap->tld); + mi_assert_internal(mi_page_immediate_available(page)); + break; + } + + // 3. If the page is completely full, move it to the `mi_pages_full` + // queue so we don't visit long-lived pages too often. + mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page)); + mi_page_to_full(page, pq); + + page = next; + } // for each page + + mi_heap_stat_counter_increase(heap, searches, count); + + if (page == NULL) { + _mi_heap_collect_retired(heap, false); // perhaps make a page available? + page = mi_page_fresh(heap, pq); + if (page == NULL && first_try) { + // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again + page = mi_page_queue_find_free_ex(heap, pq, false); + } + } + else { + mi_assert(pq->first == page); + page->retire_expire = 0; + } + mi_assert_internal(page == NULL || mi_page_immediate_available(page)); + return page; +} + + + +// Find a page with free blocks of `size`. +static inline mi_page_t* mi_find_free_page(mi_heap_t* heap, size_t size) { + mi_page_queue_t* pq = mi_page_queue(heap,size); + mi_page_t* page = pq->first; + if (page != NULL) { + #if (MI_SECURE>=3) // in secure mode, we extend half the time to increase randomness + if (page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) { + mi_page_extend_free(heap, page, heap->tld); + mi_assert_internal(mi_page_immediate_available(page)); + } + else + #endif + { + _mi_page_free_collect(page,false); + } + + if (mi_page_immediate_available(page)) { + page->retire_expire = 0; + return page; // fast path + } + } + return mi_page_queue_find_free_ex(heap, pq, true); +} + + +/* ----------------------------------------------------------- + Users can register a deferred free function called + when the `free` list is empty. Since the `local_free` + is separate this is deterministically called after + a certain number of allocations. +----------------------------------------------------------- */ + +static mi_deferred_free_fun* volatile deferred_free = NULL; +static _Atomic(void*) deferred_arg; // = NULL + +void _mi_deferred_free(mi_heap_t* heap, bool force) { + heap->tld->heartbeat++; + if (deferred_free != NULL && !heap->tld->recurse) { + heap->tld->recurse = true; + deferred_free(force, heap->tld->heartbeat, mi_atomic_load_ptr_relaxed(void,&deferred_arg)); + heap->tld->recurse = false; + } +} + +void mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept { + deferred_free = fn; + mi_atomic_store_ptr_release(void,&deferred_arg, arg); +} + + +/* ----------------------------------------------------------- + General allocation +----------------------------------------------------------- */ + +// Large and huge page allocation. +// Huge pages are allocated directly without being in a queue. +// Because huge pages contain just one block, and the segment contains +// just that page, we always treat them as abandoned and any thread +// that frees the block can free the whole page and segment directly. +// Huge pages are also use if the requested alignment is very large (> MI_ALIGNMENT_MAX). +static mi_page_t* mi_large_huge_page_alloc(mi_heap_t* heap, size_t size, size_t page_alignment) { + size_t block_size = _mi_os_good_alloc_size(size); + mi_assert_internal(mi_bin(block_size) == MI_BIN_HUGE || page_alignment > 0); + bool is_huge = (block_size > MI_LARGE_OBJ_SIZE_MAX || page_alignment > 0); + #if MI_HUGE_PAGE_ABANDON + mi_page_queue_t* pq = (is_huge ? NULL : mi_page_queue(heap, block_size)); + #else + mi_page_queue_t* pq = mi_page_queue(heap, is_huge ? MI_HUGE_BLOCK_SIZE : block_size); // not block_size as that can be low if the page_alignment > 0 + mi_assert_internal(!is_huge || mi_page_queue_is_huge(pq)); + #endif + mi_page_t* page = mi_page_fresh_alloc(heap, pq, block_size, page_alignment); + if (page != NULL) { + mi_assert_internal(mi_page_immediate_available(page)); + + if (is_huge) { + mi_assert_internal(_mi_page_segment(page)->kind == MI_SEGMENT_HUGE); + mi_assert_internal(_mi_page_segment(page)->used==1); + #if MI_HUGE_PAGE_ABANDON + mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue + mi_page_set_heap(page, NULL); + #endif + } + else { + mi_assert_internal(_mi_page_segment(page)->kind != MI_SEGMENT_HUGE); + } + + const size_t bsize = mi_page_usable_block_size(page); // note: not `mi_page_block_size` to account for padding + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_increase(heap, large, bsize); + mi_heap_stat_counter_increase(heap, large_count, 1); + } + else { + mi_heap_stat_increase(heap, huge, bsize); + mi_heap_stat_counter_increase(heap, huge_count, 1); + } + } + return page; +} + + +// Allocate a page +// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. +static mi_page_t* mi_find_page(mi_heap_t* heap, size_t size, size_t huge_alignment) mi_attr_noexcept { + // huge allocation? + const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` + if mi_unlikely(req_size > (MI_MEDIUM_OBJ_SIZE_MAX - MI_PADDING_SIZE) || huge_alignment > 0) { + if mi_unlikely(req_size > PTRDIFF_MAX) { // we don't allocate more than PTRDIFF_MAX (see ) + _mi_error_message(EOVERFLOW, "allocation request is too large (%zu bytes)\n", req_size); + return NULL; + } + else { + return mi_large_huge_page_alloc(heap,size,huge_alignment); + } + } + else { + // otherwise find a page with free blocks in our size segregated queues + #if MI_PADDING + mi_assert_internal(size >= MI_PADDING_SIZE); + #endif + return mi_find_free_page(heap, size); + } +} + +// Generic allocation routine if the fast path (`alloc.c:mi_page_malloc`) does not succeed. +// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. +// The `huge_alignment` is normally 0 but is set to a multiple of MI_SEGMENT_SIZE for +// very large requested alignments in which case we use a huge segment. +void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept +{ + mi_assert_internal(heap != NULL); + + // initialize if necessary + if mi_unlikely(!mi_heap_is_initialized(heap)) { + heap = mi_heap_get_default(); // calls mi_thread_init + if mi_unlikely(!mi_heap_is_initialized(heap)) { return NULL; } + } + mi_assert_internal(mi_heap_is_initialized(heap)); + + // call potential deferred free routines + _mi_deferred_free(heap, false); + + // free delayed frees from other threads (but skip contended ones) + _mi_heap_delayed_free_partial(heap); + + // find (or allocate) a page of the right size + mi_page_t* page = mi_find_page(heap, size, huge_alignment); + if mi_unlikely(page == NULL) { // first time out of memory, try to collect and retry the allocation once more + mi_heap_collect(heap, true /* force */); + page = mi_find_page(heap, size, huge_alignment); + } + + if mi_unlikely(page == NULL) { // out of memory + const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` + _mi_error_message(ENOMEM, "unable to allocate memory (%zu bytes)\n", req_size); + return NULL; + } + + mi_assert_internal(mi_page_immediate_available(page)); + mi_assert_internal(mi_page_block_size(page) >= size); + + // and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc) + if mi_unlikely(zero && page->xblock_size == 0) { + // note: we cannot call _mi_page_malloc with zeroing for huge blocks; we zero it afterwards in that case. + void* p = _mi_page_malloc(heap, page, size, false); + mi_assert_internal(p != NULL); + _mi_memzero_aligned(p, mi_page_usable_block_size(page)); + return p; + } + else { + return _mi_page_malloc(heap, page, size, zero); + } +} diff --git a/Objects/mimalloc/prim/osx/alloc-override-zone.c b/Objects/mimalloc/prim/osx/alloc-override-zone.c new file mode 100644 index 00000000000000..0e0a99d9388c8a --- /dev/null +++ b/Objects/mimalloc/prim/osx/alloc-override-zone.c @@ -0,0 +1,458 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2022, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc/internal.h" + +#if defined(MI_MALLOC_OVERRIDE) + +#if !defined(__APPLE__) +#error "this file should only be included on macOS" +#endif + +/* ------------------------------------------------------ + Override system malloc on macOS + This is done through the malloc zone interface. + It seems to be most robust in combination with interposing + though or otherwise we may get zone errors as there are could + be allocations done by the time we take over the + zone. +------------------------------------------------------ */ + +#include +#include +#include // memset +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) +// only available from OSX 10.6 +extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import)); +#endif + +/* ------------------------------------------------------ + malloc zone members +------------------------------------------------------ */ + +static size_t zone_size(malloc_zone_t* zone, const void* p) { + MI_UNUSED(zone); + if (!mi_is_in_heap_region(p)){ return 0; } // not our pointer, bail out + return mi_usable_size(p); +} + +static void* zone_malloc(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); + return mi_malloc(size); +} + +static void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) { + MI_UNUSED(zone); + return mi_calloc(count, size); +} + +static void* zone_valloc(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); + return mi_malloc_aligned(size, _mi_os_page_size()); +} + +static void zone_free(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); + mi_cfree(p); +} + +static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) { + MI_UNUSED(zone); + return mi_realloc(p, newsize); +} + +static void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) { + MI_UNUSED(zone); + return mi_malloc_aligned(size,alignment); +} + +static void zone_destroy(malloc_zone_t* zone) { + MI_UNUSED(zone); + // todo: ignore for now? +} + +static unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) { + size_t i; + for (i = 0; i < count; i++) { + ps[i] = zone_malloc(zone, size); + if (ps[i] == NULL) break; + } + return i; +} + +static void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) { + for(size_t i = 0; i < count; i++) { + zone_free(zone, ps[i]); + ps[i] = NULL; + } +} + +static size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); MI_UNUSED(size); + mi_collect(false); + return 0; +} + +static void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) { + MI_UNUSED(size); + zone_free(zone,p); +} + +static boolean_t zone_claimed_address(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); + return mi_is_in_heap_region(p); +} + + +/* ------------------------------------------------------ + Introspection members +------------------------------------------------------ */ + +static kern_return_t intro_enumerator(task_t task, void* p, + unsigned type_mask, vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + // todo: enumerate all memory + MI_UNUSED(task); MI_UNUSED(p); MI_UNUSED(type_mask); MI_UNUSED(zone_address); + MI_UNUSED(reader); MI_UNUSED(recorder); + return KERN_SUCCESS; +} + +static size_t intro_good_size(malloc_zone_t* zone, size_t size) { + MI_UNUSED(zone); + return mi_good_size(size); +} + +static boolean_t intro_check(malloc_zone_t* zone) { + MI_UNUSED(zone); + return true; +} + +static void intro_print(malloc_zone_t* zone, boolean_t verbose) { + MI_UNUSED(zone); MI_UNUSED(verbose); + mi_stats_print(NULL); +} + +static void intro_log(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); MI_UNUSED(p); + // todo? +} + +static void intro_force_lock(malloc_zone_t* zone) { + MI_UNUSED(zone); + // todo? +} + +static void intro_force_unlock(malloc_zone_t* zone) { + MI_UNUSED(zone); + // todo? +} + +static void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { + MI_UNUSED(zone); + // todo... + stats->blocks_in_use = 0; + stats->size_in_use = 0; + stats->max_size_in_use = 0; + stats->size_allocated = 0; +} + +static boolean_t intro_zone_locked(malloc_zone_t* zone) { + MI_UNUSED(zone); + return false; +} + + +/* ------------------------------------------------------ + At process start, override the default allocator +------------------------------------------------------ */ + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wc99-extensions" +#endif + +static malloc_introspection_t mi_introspect = { + .enumerator = &intro_enumerator, + .good_size = &intro_good_size, + .check = &intro_check, + .print = &intro_print, + .log = &intro_log, + .force_lock = &intro_force_lock, + .force_unlock = &intro_force_unlock, +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__) + .statistics = &intro_statistics, + .zone_locked = &intro_zone_locked, +#endif +}; + +static malloc_zone_t mi_malloc_zone = { + // note: even with designators, the order is important for C++ compilation + //.reserved1 = NULL, + //.reserved2 = NULL, + .size = &zone_size, + .malloc = &zone_malloc, + .calloc = &zone_calloc, + .valloc = &zone_valloc, + .free = &zone_free, + .realloc = &zone_realloc, + .destroy = &zone_destroy, + .zone_name = "mimalloc", + .batch_malloc = &zone_batch_malloc, + .batch_free = &zone_batch_free, + .introspect = &mi_introspect, +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && !defined(__ppc__) + #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14) + .version = 10, + #else + .version = 9, + #endif + // switch to version 9+ on OSX 10.6 to support memalign. + .memalign = &zone_memalign, + .free_definite_size = &zone_free_definite_size, + .pressure_relief = &zone_pressure_relief, + #if defined(MAC_OS_X_VERSION_10_14) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14) + .claimed_address = &zone_claimed_address, + #endif +#else + .version = 4, +#endif +}; + +#ifdef __cplusplus +} +#endif + + +#if defined(MI_OSX_INTERPOSE) && defined(MI_SHARED_LIB_EXPORT) + +// ------------------------------------------------------ +// Override malloc_xxx and malloc_zone_xxx api's to use only +// our mimalloc zone. Since even the loader uses malloc +// on macOS, this ensures that all allocations go through +// mimalloc (as all calls are interposed). +// The main `malloc`, `free`, etc calls are interposed in `alloc-override.c`, +// Here, we also override macOS specific API's like +// `malloc_zone_calloc` etc. see +// ------------------------------------------------------ + +static inline malloc_zone_t* mi_get_default_zone(void) +{ + static bool init; + if mi_unlikely(!init) { + init = true; + malloc_zone_register(&mi_malloc_zone); // by calling register we avoid a zone error on free (see ) + } + return &mi_malloc_zone; +} + +mi_decl_externc int malloc_jumpstart(uintptr_t cookie); +mi_decl_externc void _malloc_fork_prepare(void); +mi_decl_externc void _malloc_fork_parent(void); +mi_decl_externc void _malloc_fork_child(void); + + +static malloc_zone_t* mi_malloc_create_zone(vm_size_t size, unsigned flags) { + MI_UNUSED(size); MI_UNUSED(flags); + return mi_get_default_zone(); +} + +static malloc_zone_t* mi_malloc_default_zone (void) { + return mi_get_default_zone(); +} + +static malloc_zone_t* mi_malloc_default_purgeable_zone(void) { + return mi_get_default_zone(); +} + +static void mi_malloc_destroy_zone(malloc_zone_t* zone) { + MI_UNUSED(zone); + // nothing. +} + +static kern_return_t mi_malloc_get_all_zones (task_t task, memory_reader_t mr, vm_address_t** addresses, unsigned* count) { + MI_UNUSED(task); MI_UNUSED(mr); + if (addresses != NULL) *addresses = NULL; + if (count != NULL) *count = 0; + return KERN_SUCCESS; +} + +static const char* mi_malloc_get_zone_name(malloc_zone_t* zone) { + return (zone == NULL ? mi_malloc_zone.zone_name : zone->zone_name); +} + +static void mi_malloc_set_zone_name(malloc_zone_t* zone, const char* name) { + MI_UNUSED(zone); MI_UNUSED(name); +} + +static int mi_malloc_jumpstart(uintptr_t cookie) { + MI_UNUSED(cookie); + return 1; // or 0 for no error? +} + +static void mi__malloc_fork_prepare(void) { + // nothing +} +static void mi__malloc_fork_parent(void) { + // nothing +} +static void mi__malloc_fork_child(void) { + // nothing +} + +static void mi_malloc_printf(const char* fmt, ...) { + MI_UNUSED(fmt); +} + +static bool zone_check(malloc_zone_t* zone) { + MI_UNUSED(zone); + return true; +} + +static malloc_zone_t* zone_from_ptr(const void* p) { + MI_UNUSED(p); + return mi_get_default_zone(); +} + +static void zone_log(malloc_zone_t* zone, void* p) { + MI_UNUSED(zone); MI_UNUSED(p); +} + +static void zone_print(malloc_zone_t* zone, bool b) { + MI_UNUSED(zone); MI_UNUSED(b); +} + +static void zone_print_ptr_info(void* p) { + MI_UNUSED(p); +} + +static void zone_register(malloc_zone_t* zone) { + MI_UNUSED(zone); +} + +static void zone_unregister(malloc_zone_t* zone) { + MI_UNUSED(zone); +} + +// use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` +// See: +struct mi_interpose_s { + const void* replacement; + const void* target; +}; +#define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } +#define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) +#define MI_INTERPOSE_ZONE(fun) MI_INTERPOSE_FUN(malloc_##fun,fun) +__attribute__((used)) static const struct mi_interpose_s _mi_zone_interposes[] __attribute__((section("__DATA, __interpose"))) = +{ + + MI_INTERPOSE_MI(malloc_create_zone), + MI_INTERPOSE_MI(malloc_default_purgeable_zone), + MI_INTERPOSE_MI(malloc_default_zone), + MI_INTERPOSE_MI(malloc_destroy_zone), + MI_INTERPOSE_MI(malloc_get_all_zones), + MI_INTERPOSE_MI(malloc_get_zone_name), + MI_INTERPOSE_MI(malloc_jumpstart), + MI_INTERPOSE_MI(malloc_printf), + MI_INTERPOSE_MI(malloc_set_zone_name), + MI_INTERPOSE_MI(_malloc_fork_child), + MI_INTERPOSE_MI(_malloc_fork_parent), + MI_INTERPOSE_MI(_malloc_fork_prepare), + + MI_INTERPOSE_ZONE(zone_batch_free), + MI_INTERPOSE_ZONE(zone_batch_malloc), + MI_INTERPOSE_ZONE(zone_calloc), + MI_INTERPOSE_ZONE(zone_check), + MI_INTERPOSE_ZONE(zone_free), + MI_INTERPOSE_ZONE(zone_from_ptr), + MI_INTERPOSE_ZONE(zone_log), + MI_INTERPOSE_ZONE(zone_malloc), + MI_INTERPOSE_ZONE(zone_memalign), + MI_INTERPOSE_ZONE(zone_print), + MI_INTERPOSE_ZONE(zone_print_ptr_info), + MI_INTERPOSE_ZONE(zone_realloc), + MI_INTERPOSE_ZONE(zone_register), + MI_INTERPOSE_ZONE(zone_unregister), + MI_INTERPOSE_ZONE(zone_valloc) +}; + + +#else + +// ------------------------------------------------------ +// hook into the zone api's without interposing +// This is the official way of adding an allocator but +// it seems less robust than using interpose. +// ------------------------------------------------------ + +static inline malloc_zone_t* mi_get_default_zone(void) +{ + // The first returned zone is the real default + malloc_zone_t** zones = NULL; + unsigned count = 0; + kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count); + if (ret == KERN_SUCCESS && count > 0) { + return zones[0]; + } + else { + // fallback + return malloc_default_zone(); + } +} + +#if defined(__clang__) +__attribute__((constructor(0))) +#else +__attribute__((constructor)) // seems not supported by g++-11 on the M1 +#endif +static void _mi_macos_override_malloc(void) { + malloc_zone_t* purgeable_zone = NULL; + + #if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) + // force the purgeable zone to exist to avoid strange bugs + if (malloc_default_purgeable_zone) { + purgeable_zone = malloc_default_purgeable_zone(); + } + #endif + + // Register our zone. + // thomcc: I think this is still needed to put us in the zone list. + malloc_zone_register(&mi_malloc_zone); + // Unregister the default zone, this makes our zone the new default + // as that was the last registered. + malloc_zone_t *default_zone = mi_get_default_zone(); + // thomcc: Unsure if the next test is *always* false or just false in the + // cases I've tried. I'm also unsure if the code inside is needed. at all + if (default_zone != &mi_malloc_zone) { + malloc_zone_unregister(default_zone); + + // Reregister the default zone so free and realloc in that zone keep working. + malloc_zone_register(default_zone); + } + + // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs + // earlier than the default zone. + if (purgeable_zone != NULL) { + malloc_zone_unregister(purgeable_zone); + malloc_zone_register(purgeable_zone); + } + +} +#endif // MI_OSX_INTERPOSE + +#endif // MI_MALLOC_OVERRIDE diff --git a/Objects/mimalloc/prim/osx/prim.c b/Objects/mimalloc/prim/osx/prim.c new file mode 100644 index 00000000000000..8a2f4e8aa47316 --- /dev/null +++ b/Objects/mimalloc/prim/osx/prim.c @@ -0,0 +1,9 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// We use the unix/prim.c with the mmap API on macOSX +#include "../unix/prim.c" diff --git a/Objects/mimalloc/prim/prim.c b/Objects/mimalloc/prim/prim.c new file mode 100644 index 00000000000000..9a597d8eb603e9 --- /dev/null +++ b/Objects/mimalloc/prim/prim.c @@ -0,0 +1,24 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// Select the implementation of the primitives +// depending on the OS. + +#if defined(_WIN32) +#include "windows/prim.c" // VirtualAlloc (Windows) + +#elif defined(__APPLE__) +#include "osx/prim.c" // macOSX (actually defers to mmap in unix/prim.c) + +#elif defined(__wasi__) +#define MI_USE_SBRK +#include "wasi/prim.c" // memory-grow or sbrk (Wasm) + +#else +#include "unix/prim.c" // mmap() (Linux, macOSX, BSD, Illumnos, Haiku, DragonFly, etc.) + +#endif diff --git a/Objects/mimalloc/prim/readme.md b/Objects/mimalloc/prim/readme.md new file mode 100644 index 00000000000000..380dd3a7178419 --- /dev/null +++ b/Objects/mimalloc/prim/readme.md @@ -0,0 +1,9 @@ +## Portability Primitives + +This is the portability layer where all primitives needed from the OS are defined. + +- `include/mimalloc/prim.h`: primitive portability API definition. +- `prim.c`: Selects one of `unix/prim.c`, `wasi/prim.c`, or `windows/prim.c` depending on the host platform + (and on macOS, `osx/prim.c` defers to `unix/prim.c`). + +Note: still work in progress, there may still be places in the sources that still depend on OS ifdef's. \ No newline at end of file diff --git a/Objects/mimalloc/prim/unix/prim.c b/Objects/mimalloc/prim/unix/prim.c new file mode 100644 index 00000000000000..cffbb2d0b4d7b2 --- /dev/null +++ b/Objects/mimalloc/prim/unix/prim.c @@ -0,0 +1,859 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// This file is included in `src/prim/prim.c` + +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE // ensure mmap flags and syscall are defined +#endif + +#if defined(__sun) +// illumos provides new mman.h api when any of these are defined +// otherwise the old api based on caddr_t which predates the void pointers one. +// stock solaris provides only the former, chose to atomically to discard those +// flags only here rather than project wide tough. +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + +#include // mmap +#include // sysconf + +#if defined(__linux__) + #include + #include + #if defined(__GLIBC__) + #include // linux mmap flags + #else + #include + #endif +#elif defined(__APPLE__) + #include + #if !TARGET_IOS_IPHONE && !TARGET_IOS_SIMULATOR + #include + #endif +#elif defined(__FreeBSD__) || defined(__DragonFly__) + #include + #if __FreeBSD_version >= 1200000 + #include + #include + #endif + #include +#endif + +#if !defined(__HAIKU__) && !defined(__APPLE__) && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__FreeBSD__) + #define MI_HAS_SYSCALL_H + #include +#endif + +//------------------------------------------------------------------------------------ +// Use syscalls for some primitives to allow for libraries that override open/read/close etc. +// and do allocation themselves; using syscalls prevents recursion when mimalloc is +// still initializing (issue #713) +//------------------------------------------------------------------------------------ + +#if defined(MI_HAS_SYSCALL_H) && defined(SYS_open) && defined(SYS_close) && defined(SYS_read) && defined(SYS_access) + +static int mi_prim_open(const char* fpath, int open_flags) { + return syscall(SYS_open,fpath,open_flags,0); +} +static ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) { + return syscall(SYS_read,fd,buf,bufsize); +} +static int mi_prim_close(int fd) { + return syscall(SYS_close,fd); +} +static int mi_prim_access(const char *fpath, int mode) { + return syscall(SYS_access,fpath,mode); +} + +#elif !defined(__APPLE__) && !defined(_AIX) && !defined(__FreeBSD__) // avoid unused warnings + +static int mi_prim_open(const char* fpath, int open_flags) { + return open(fpath,open_flags); +} +static ssize_t mi_prim_read(int fd, void* buf, size_t bufsize) { + return read(fd,buf,bufsize); +} +static int mi_prim_close(int fd) { + return close(fd); +} +static int mi_prim_access(const char *fpath, int mode) { + return access(fpath,mode); +} + +#endif + + + +//--------------------------------------------- +// init +//--------------------------------------------- + +static bool unix_detect_overcommit(void) { + bool os_overcommit = true; +#if defined(__linux__) + int fd = mi_prim_open("/proc/sys/vm/overcommit_memory", O_RDONLY); + if (fd >= 0) { + char buf[32] = {0}; + ssize_t nread = mi_prim_read(fd, &buf, sizeof(buf)); + mi_prim_close(fd); + // + // 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE) + if (nread >= 1) { + os_overcommit = (buf[0] == '0' || buf[0] == '1'); + } + } +#elif defined(__FreeBSD__) + int val = 0; + size_t olen = sizeof(val); + if (sysctlbyname("vm.overcommit", &val, &olen, NULL, 0) == 0) { + os_overcommit = (val != 0); + } +#else + // default: overcommit is true +#endif + return os_overcommit; +} + +void _mi_prim_mem_init( mi_os_mem_config_t* config ) { + long psize = sysconf(_SC_PAGESIZE); + if (psize > 0) { + config->page_size = (size_t)psize; + config->alloc_granularity = (size_t)psize; + } + config->large_page_size = 2*MI_MiB; // TODO: can we query the OS for this? + config->has_overcommit = unix_detect_overcommit(); + config->must_free_whole = false; // mmap can free in parts + config->has_virtual_reserve = true; // todo: check if this true for NetBSD? (for anonymous mmap with PROT_NONE) +} + + +//--------------------------------------------- +// free +//--------------------------------------------- + +int _mi_prim_free(void* addr, size_t size ) { + bool err = (munmap(addr, size) == -1); + return (err ? errno : 0); +} + + +//--------------------------------------------- +// mmap +//--------------------------------------------- + +static int unix_madvise(void* addr, size_t size, int advice) { + #if defined(__sun) + return madvise((caddr_t)addr, size, advice); // Solaris needs cast (issue #520) + #else + return madvise(addr, size, advice); + #endif +} + +static void* unix_mmap_prim(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) { + MI_UNUSED(try_alignment); + void* p = NULL; + #if defined(MAP_ALIGNED) // BSD + if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { + size_t n = mi_bsr(try_alignment); + if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB + p = mmap(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd, 0); + if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { + int err = errno; + _mi_warning_message("unable to directly request aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\n", err, err, size, try_alignment, addr); + } + if (p!=MAP_FAILED) return p; + // fall back to regular mmap + } + } + #elif defined(MAP_ALIGN) // Solaris + if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { + p = mmap((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd, 0); // addr parameter is the required alignment + if (p!=MAP_FAILED) return p; + // fall back to regular mmap + } + #endif + #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED) + // on 64-bit systems, use the virtual address area after 2TiB for 4MiB aligned allocations + if (addr == NULL) { + void* hint = _mi_os_get_aligned_hint(try_alignment, size); + if (hint != NULL) { + p = mmap(hint, size, protect_flags, flags, fd, 0); + if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { + #if MI_TRACK_ENABLED // asan sometimes does not instrument errno correctly? + int err = 0; + #else + int err = errno; + #endif + _mi_warning_message("unable to directly request hinted aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\n", err, err, size, try_alignment, hint); + } + if (p!=MAP_FAILED) return p; + // fall back to regular mmap + } + } + #endif + // regular mmap + p = mmap(addr, size, protect_flags, flags, fd, 0); + if (p!=MAP_FAILED) return p; + // failed to allocate + return NULL; +} + +static int unix_mmap_fd(void) { + #if defined(VM_MAKE_TAG) + // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99) + int os_tag = (int)mi_option_get(mi_option_os_tag); + if (os_tag < 100 || os_tag > 255) { os_tag = 100; } + return VM_MAKE_TAG(os_tag); + #else + return -1; + #endif +} + +static void* unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) { + #if !defined(MAP_ANONYMOUS) + #define MAP_ANONYMOUS MAP_ANON + #endif + #if !defined(MAP_NORESERVE) + #define MAP_NORESERVE 0 + #endif + void* p = NULL; + const int fd = unix_mmap_fd(); + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + if (_mi_os_has_overcommit()) { + flags |= MAP_NORESERVE; + } + #if defined(PROT_MAX) + protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD + #endif + // huge page allocation + if ((large_only || _mi_os_use_large_page(size, try_alignment)) && allow_large) { + static _Atomic(size_t) large_page_try_ok; // = 0; + size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); + if (!large_only && try_ok > 0) { + // If the OS is not configured for large OS pages, or the user does not have + // enough permission, the `mmap` will always fail (but it might also fail for other reasons). + // Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times + // to avoid too many failing calls to mmap. + mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); + } + else { + int lflags = flags & ~MAP_NORESERVE; // using NORESERVE on huge pages seems to fail on Linux + int lfd = fd; + #ifdef MAP_ALIGNED_SUPER + lflags |= MAP_ALIGNED_SUPER; + #endif + #ifdef MAP_HUGETLB + lflags |= MAP_HUGETLB; + #endif + #ifdef MAP_HUGE_1GB + static bool mi_huge_pages_available = true; + if ((size % MI_GiB) == 0 && mi_huge_pages_available) { + lflags |= MAP_HUGE_1GB; + } + else + #endif + { + #ifdef MAP_HUGE_2MB + lflags |= MAP_HUGE_2MB; + #endif + } + #ifdef VM_FLAGS_SUPERPAGE_SIZE_2MB + lfd |= VM_FLAGS_SUPERPAGE_SIZE_2MB; + #endif + if (large_only || lflags != flags) { + // try large OS page allocation + *is_large = true; + p = unix_mmap_prim(addr, size, try_alignment, protect_flags, lflags, lfd); + #ifdef MAP_HUGE_1GB + if (p == NULL && (lflags & MAP_HUGE_1GB) != 0) { + mi_huge_pages_available = false; // don't try huge 1GiB pages again + _mi_warning_message("unable to allocate huge (1GiB) page, trying large (2MiB) pages instead (errno: %i)\n", errno); + lflags = ((lflags & ~MAP_HUGE_1GB) | MAP_HUGE_2MB); + p = unix_mmap_prim(addr, size, try_alignment, protect_flags, lflags, lfd); + } + #endif + if (large_only) return p; + if (p == NULL) { + mi_atomic_store_release(&large_page_try_ok, (size_t)8); // on error, don't try again for the next N allocations + } + } + } + } + // regular allocation + if (p == NULL) { + *is_large = false; + p = unix_mmap_prim(addr, size, try_alignment, protect_flags, flags, fd); + if (p != NULL) { + #if defined(MADV_HUGEPAGE) + // Many Linux systems don't allow MAP_HUGETLB but they support instead + // transparent huge pages (THP). Generally, it is not required to call `madvise` with MADV_HUGE + // though since properly aligned allocations will already use large pages if available + // in that case -- in particular for our large regions (in `memory.c`). + // However, some systems only allow THP if called with explicit `madvise`, so + // when large OS pages are enabled for mimalloc, we call `madvise` anyways. + if (allow_large && _mi_os_use_large_page(size, try_alignment)) { + if (unix_madvise(p, size, MADV_HUGEPAGE) == 0) { + *is_large = true; // possibly + }; + } + #elif defined(__sun) + if (allow_large && _mi_os_use_large_page(size, try_alignment)) { + struct memcntl_mha cmd = {0}; + cmd.mha_pagesize = large_os_page_size; + cmd.mha_cmd = MHA_MAPSIZE_VA; + if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) { + *is_large = true; + } + } + #endif + } + } + return p; +} + +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(commit || !allow_large); + mi_assert_internal(try_alignment > 0); + + *is_zero = true; + int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE); + *addr = unix_mmap(NULL, size, try_alignment, protect_flags, false, allow_large, is_large); + return (*addr != NULL ? 0 : errno); +} + + +//--------------------------------------------- +// Commit/Reset +//--------------------------------------------- + +static void unix_mprotect_hint(int err) { + #if defined(__linux__) && (MI_SECURE>=2) // guard page around every mimalloc page + if (err == ENOMEM) { + _mi_warning_message("The next warning may be caused by a low memory map limit.\n" + " On Linux this is controlled by the vm.max_map_count -- maybe increase it?\n" + " For example: sudo sysctl -w vm.max_map_count=262144\n"); + } + #else + MI_UNUSED(err); + #endif +} + +int _mi_prim_commit(void* start, size_t size, bool* is_zero) { + // commit: ensure we can access the area + // note: we may think that *is_zero can be true since the memory + // was either from mmap PROT_NONE, or from decommit MADV_DONTNEED, but + // we sometimes call commit on a range with still partially committed + // memory and `mprotect` does not zero the range. + *is_zero = false; + int err = mprotect(start, size, (PROT_READ | PROT_WRITE)); + if (err != 0) { + err = errno; + unix_mprotect_hint(err); + } + return err; +} + +int _mi_prim_decommit(void* start, size_t size, bool* needs_recommit) { + int err = 0; + // decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE) + err = unix_madvise(start, size, MADV_DONTNEED); + #if !MI_DEBUG && !MI_SECURE + *needs_recommit = false; + #else + *needs_recommit = true; + mprotect(start, size, PROT_NONE); + #endif + /* + // decommit: use mmap with MAP_FIXED and PROT_NONE to discard the existing memory (and reduce rss) + *needs_recommit = true; + const int fd = unix_mmap_fd(); + void* p = mmap(start, size, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), fd, 0); + if (p != start) { err = errno; } + */ + return err; +} + +int _mi_prim_reset(void* start, size_t size) { + // We try to use `MADV_FREE` as that is the fastest. A drawback though is that it + // will not reduce the `rss` stats in tools like `top` even though the memory is available + // to other processes. With the default `MIMALLOC_PURGE_DECOMMITS=1` we ensure that by + // default `MADV_DONTNEED` is used though. + #if defined(MADV_FREE) + static _Atomic(size_t) advice = MI_ATOMIC_VAR_INIT(MADV_FREE); + int oadvice = (int)mi_atomic_load_relaxed(&advice); + int err; + while ((err = unix_madvise(start, size, oadvice)) != 0 && errno == EAGAIN) { errno = 0; }; + if (err != 0 && errno == EINVAL && oadvice == MADV_FREE) { + // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on + mi_atomic_store_release(&advice, (size_t)MADV_DONTNEED); + err = unix_madvise(start, size, MADV_DONTNEED); + } + #else + int err = unix_madvise(start, size, MADV_DONTNEED); + #endif + return err; +} + +int _mi_prim_protect(void* start, size_t size, bool protect) { + int err = mprotect(start, size, protect ? PROT_NONE : (PROT_READ | PROT_WRITE)); + if (err != 0) { err = errno; } + unix_mprotect_hint(err); + return err; +} + + + +//--------------------------------------------- +// Huge page allocation +//--------------------------------------------- + +#if (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) && !defined(__CYGWIN__) + +#ifndef MPOL_PREFERRED +#define MPOL_PREFERRED 1 +#endif + +#if defined(MI_HAS_SYSCALL_H) && defined(SYS_mbind) +static long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { + return syscall(SYS_mbind, start, len, mode, nmask, maxnode, flags); +} +#else +static long mi_prim_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { + MI_UNUSED(start); MI_UNUSED(len); MI_UNUSED(mode); MI_UNUSED(nmask); MI_UNUSED(maxnode); MI_UNUSED(flags); + return 0; +} +#endif + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + bool is_large = true; + *is_zero = true; + *addr = unix_mmap(hint_addr, size, MI_SEGMENT_SIZE, PROT_READ | PROT_WRITE, true, true, &is_large); + if (*addr != NULL && numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes + unsigned long numa_mask = (1UL << numa_node); + // TODO: does `mbind` work correctly for huge OS pages? should we + // use `set_mempolicy` before calling mmap instead? + // see: + long err = mi_prim_mbind(*addr, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0); + if (err != 0) { + err = errno; + _mi_warning_message("failed to bind huge (1GiB) pages to numa node %d (error: %d (0x%x))\n", numa_node, err, err); + } + } + return (*addr != NULL ? 0 : errno); +} + +#else + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node); + *is_zero = false; + *addr = NULL; + return ENOMEM; +} + +#endif + +//--------------------------------------------- +// NUMA nodes +//--------------------------------------------- + +#if defined(__linux__) + +#include // snprintf + +size_t _mi_prim_numa_node(void) { + #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getcpu) + unsigned long node = 0; + unsigned long ncpu = 0; + long err = syscall(SYS_getcpu, &ncpu, &node, NULL); + if (err != 0) return 0; + return node; + #else + return 0; + #endif +} + +size_t _mi_prim_numa_node_count(void) { + char buf[128]; + unsigned node = 0; + for(node = 0; node < 256; node++) { + // enumerate node entries -- todo: it there a more efficient way to do this? (but ensure there is no allocation) + snprintf(buf, 127, "/sys/devices/system/node/node%u", node + 1); + if (mi_prim_access(buf,R_OK) != 0) break; + } + return (node+1); +} + +#elif defined(__FreeBSD__) && __FreeBSD_version >= 1200000 + +size_t _mi_prim_numa_node(void) { + domainset_t dom; + size_t node; + int policy; + if (cpuset_getdomain(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(dom), &dom, &policy) == -1) return 0ul; + for (node = 0; node < MAXMEMDOM; node++) { + if (DOMAINSET_ISSET(node, &dom)) return node; + } + return 0ul; +} + +size_t _mi_prim_numa_node_count(void) { + size_t ndomains = 0; + size_t len = sizeof(ndomains); + if (sysctlbyname("vm.ndomains", &ndomains, &len, NULL, 0) == -1) return 0ul; + return ndomains; +} + +#elif defined(__DragonFly__) + +size_t _mi_prim_numa_node(void) { + // TODO: DragonFly does not seem to provide any userland means to get this information. + return 0ul; +} + +size_t _mi_prim_numa_node_count(void) { + size_t ncpus = 0, nvirtcoresperphys = 0; + size_t len = sizeof(size_t); + if (sysctlbyname("hw.ncpu", &ncpus, &len, NULL, 0) == -1) return 0ul; + if (sysctlbyname("hw.cpu_topology_ht_ids", &nvirtcoresperphys, &len, NULL, 0) == -1) return 0ul; + return nvirtcoresperphys * ncpus; +} + +#else + +size_t _mi_prim_numa_node(void) { + return 0; +} + +size_t _mi_prim_numa_node_count(void) { + return 1; +} + +#endif + +// ---------------------------------------------------------------- +// Clock +// ---------------------------------------------------------------- + +#include + +#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) + +mi_msecs_t _mi_prim_clock_now(void) { + struct timespec t; + #ifdef CLOCK_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, &t); + #else + clock_gettime(CLOCK_REALTIME, &t); + #endif + return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000); +} + +#else + +// low resolution timer +mi_msecs_t _mi_prim_clock_now(void) { + #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0) + return (mi_msecs_t)clock(); + #elif (CLOCKS_PER_SEC < 1000) + return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC); + #else + return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000); + #endif +} + +#endif + + + + +//---------------------------------------------------------------- +// Process info +//---------------------------------------------------------------- + +#if defined(__unix__) || defined(__unix) || defined(unix) || defined(__APPLE__) || defined(__HAIKU__) +#include +#include +#include + +#if defined(__APPLE__) +#include +#endif + +#if defined(__HAIKU__) +#include +#endif + +static mi_msecs_t timeval_secs(const struct timeval* tv) { + return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L); +} + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + struct rusage rusage; + getrusage(RUSAGE_SELF, &rusage); + pinfo->utime = timeval_secs(&rusage.ru_utime); + pinfo->stime = timeval_secs(&rusage.ru_stime); +#if !defined(__HAIKU__) + pinfo->page_faults = rusage.ru_majflt; +#endif +#if defined(__HAIKU__) + // Haiku does not have (yet?) a way to + // get these stats per process + thread_info tid; + area_info mem; + ssize_t c; + get_thread_info(find_thread(0), &tid); + while (get_next_area_info(tid.team, &c, &mem) == B_OK) { + pinfo->peak_rss += mem.ram_size; + } + pinfo->page_faults = 0; +#elif defined(__APPLE__) + pinfo->peak_rss = rusage.ru_maxrss; // macos reports in bytes + #ifdef MACH_TASK_BASIC_INFO + struct mach_task_basic_info info; + mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; + if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { + pinfo->current_rss = (size_t)info.resident_size; + } + #else + struct task_basic_info info; + mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT; + if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { + pinfo->current_rss = (size_t)info.resident_size; + } + #endif +#else + pinfo->peak_rss = rusage.ru_maxrss * 1024; // Linux/BSD report in KiB +#endif + // use defaults for commit +} + +#else + +#ifndef __wasi__ +// WebAssembly instances are not processes +#pragma message("define a way to get process info") +#endif + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + // use defaults + MI_UNUSED(pinfo); +} + +#endif + + +//---------------------------------------------------------------- +// Output +//---------------------------------------------------------------- + +void _mi_prim_out_stderr( const char* msg ) { + fputs(msg,stderr); +} + + +//---------------------------------------------------------------- +// Environment +//---------------------------------------------------------------- + +#if !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0) +// On Posix systemsr use `environ` to access environment variables +// even before the C runtime is initialized. +#if defined(__APPLE__) && defined(__has_include) && __has_include() +#include +static char** mi_get_environ(void) { + return (*_NSGetEnviron()); +} +#else +extern char** environ; +static char** mi_get_environ(void) { + return environ; +} +#endif +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + if (name==NULL) return false; + const size_t len = _mi_strlen(name); + if (len == 0) return false; + char** env = mi_get_environ(); + if (env == NULL) return false; + // compare up to 10000 entries + for (int i = 0; i < 10000 && env[i] != NULL; i++) { + const char* s = env[i]; + if (_mi_strnicmp(name, s, len) == 0 && s[len] == '=') { // case insensitive + // found it + _mi_strlcpy(result, s + len + 1, result_size); + return true; + } + } + return false; +} +#else +// fallback: use standard C `getenv` but this cannot be used while initializing the C runtime +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + // cannot call getenv() when still initializing the C runtime. + if (_mi_preloading()) return false; + const char* s = getenv(name); + if (s == NULL) { + // we check the upper case name too. + char buf[64+1]; + size_t len = _mi_strnlen(name,sizeof(buf)-1); + for (size_t i = 0; i < len; i++) { + buf[i] = _mi_toupper(name[i]); + } + buf[len] = 0; + s = getenv(buf); + } + if (s == NULL || _mi_strnlen(s,result_size) >= result_size) return false; + _mi_strlcpy(result, s, result_size); + return true; +} +#endif // !MI_USE_ENVIRON + + +//---------------------------------------------------------------- +// Random +//---------------------------------------------------------------- + +#if defined(__APPLE__) + +#include +#if defined(MAC_OS_X_VERSION_10_10) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 +#include +#include +#endif +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + #if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15 + // We prefere CCRandomGenerateBytes as it returns an error code while arc4random_buf + // may fail silently on macOS. See PR #390, and + return (CCRandomGenerateBytes(buf, buf_len) == kCCSuccess); + #else + // fall back on older macOS + arc4random_buf(buf, buf_len); + return true; + #endif +} + +#elif defined(__ANDROID__) || defined(__DragonFly__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__sun) + +#include +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + arc4random_buf(buf, buf_len); + return true; +} + +#elif defined(__linux__) || defined(__HAIKU__) + +#include +#include +#include +#include + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + // Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h` + // and for the latter the actual `getrandom` call is not always defined. + // (see ) + // We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed. + #if defined(MI_HAS_SYSCALL_H) && defined(SYS_getrandom) + #ifndef GRND_NONBLOCK + #define GRND_NONBLOCK (1) + #endif + static _Atomic(uintptr_t) no_getrandom; // = 0 + if (mi_atomic_load_acquire(&no_getrandom)==0) { + ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK); + if (ret >= 0) return (buf_len == (size_t)ret); + if (errno != ENOSYS) return false; + mi_atomic_store_release(&no_getrandom, (uintptr_t)1); // don't call again, and fall back to /dev/urandom + } + #endif + int flags = O_RDONLY; + #if defined(O_CLOEXEC) + flags |= O_CLOEXEC; + #endif + int fd = mi_prim_open("/dev/urandom", flags); + if (fd < 0) return false; + size_t count = 0; + while(count < buf_len) { + ssize_t ret = mi_prim_read(fd, (char*)buf + count, buf_len - count); + if (ret<=0) { + if (errno!=EAGAIN && errno!=EINTR) break; + } + else { + count += ret; + } + } + mi_prim_close(fd); + return (count==buf_len); +} + +#else + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + return false; +} + +#endif + + +//---------------------------------------------------------------- +// Thread init/done +//---------------------------------------------------------------- + +#if defined(MI_USE_PTHREADS) + +// use pthread local storage keys to detect thread ending +// (and used with MI_TLS_PTHREADS for the default heap) +pthread_key_t _mi_heap_default_key = (pthread_key_t)(-1); + +static void mi_pthread_done(void* value) { + if (value!=NULL) { + _mi_thread_done((mi_heap_t*)value); + } +} + +void _mi_prim_thread_init_auto_done(void) { + mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1)); + pthread_key_create(&_mi_heap_default_key, &mi_pthread_done); +} + +void _mi_prim_thread_done_auto_done(void) { + // nothing to do +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + if (_mi_heap_default_key != (pthread_key_t)(-1)) { // can happen during recursive invocation on freeBSD + pthread_setspecific(_mi_heap_default_key, heap); + } +} + +#else + +void _mi_prim_thread_init_auto_done(void) { + // nothing +} + +void _mi_prim_thread_done_auto_done(void) { + // nothing +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + MI_UNUSED(heap); +} + +#endif diff --git a/Objects/mimalloc/prim/wasi/prim.c b/Objects/mimalloc/prim/wasi/prim.c new file mode 100644 index 00000000000000..640dac0493f573 --- /dev/null +++ b/Objects/mimalloc/prim/wasi/prim.c @@ -0,0 +1,276 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// This file is included in `src/prim/prim.c` + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" +#include // sbrk() + +//--------------------------------------------- +// Initialize +//--------------------------------------------- + +void _mi_prim_mem_init( mi_os_mem_config_t* config ) { + config->page_size = 64*MI_KiB; // WebAssembly has a fixed page size: 64KiB + config->alloc_granularity = 16; + config->has_overcommit = false; + config->must_free_whole = true; + config->has_virtual_reserve = false; +} + +//--------------------------------------------- +// Free +//--------------------------------------------- + +int _mi_prim_free(void* addr, size_t size ) { + MI_UNUSED(addr); MI_UNUSED(size); + // wasi heap cannot be shrunk + return 0; +} + + +//--------------------------------------------- +// Allocation: sbrk or memory_grow +//--------------------------------------------- + +#if defined(MI_USE_SBRK) + static void* mi_memory_grow( size_t size ) { + void* p = sbrk(size); + if (p == (void*)(-1)) return NULL; + #if !defined(__wasi__) // on wasi this is always zero initialized already (?) + memset(p,0,size); + #endif + return p; + } +#elif defined(__wasi__) + static void* mi_memory_grow( size_t size ) { + size_t base = (size > 0 ? __builtin_wasm_memory_grow(0,_mi_divide_up(size, _mi_os_page_size())) + : __builtin_wasm_memory_size(0)); + if (base == SIZE_MAX) return NULL; + return (void*)(base * _mi_os_page_size()); + } +#endif + +#if defined(MI_USE_PTHREADS) +static pthread_mutex_t mi_heap_grow_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +static void* mi_prim_mem_grow(size_t size, size_t try_alignment) { + void* p = NULL; + if (try_alignment <= 1) { + // `sbrk` is not thread safe in general so try to protect it (we could skip this on WASM but leave it in for now) + #if defined(MI_USE_PTHREADS) + pthread_mutex_lock(&mi_heap_grow_mutex); + #endif + p = mi_memory_grow(size); + #if defined(MI_USE_PTHREADS) + pthread_mutex_unlock(&mi_heap_grow_mutex); + #endif + } + else { + void* base = NULL; + size_t alloc_size = 0; + // to allocate aligned use a lock to try to avoid thread interaction + // between getting the current size and actual allocation + // (also, `sbrk` is not thread safe in general) + #if defined(MI_USE_PTHREADS) + pthread_mutex_lock(&mi_heap_grow_mutex); + #endif + { + void* current = mi_memory_grow(0); // get current size + if (current != NULL) { + void* aligned_current = mi_align_up_ptr(current, try_alignment); // and align from there to minimize wasted space + alloc_size = _mi_align_up( ((uint8_t*)aligned_current - (uint8_t*)current) + size, _mi_os_page_size()); + base = mi_memory_grow(alloc_size); + } + } + #if defined(MI_USE_PTHREADS) + pthread_mutex_unlock(&mi_heap_grow_mutex); + #endif + if (base != NULL) { + p = mi_align_up_ptr(base, try_alignment); + if ((uint8_t*)p + size > (uint8_t*)base + alloc_size) { + // another thread used wasm_memory_grow/sbrk in-between and we do not have enough + // space after alignment. Give up (and waste the space as we cannot shrink :-( ) + // (in `mi_os_mem_alloc_aligned` this will fall back to overallocation to align) + p = NULL; + } + } + } + /* + if (p == NULL) { + _mi_warning_message("unable to allocate sbrk/wasm_memory_grow OS memory (%zu bytes, %zu alignment)\n", size, try_alignment); + errno = ENOMEM; + return NULL; + } + */ + mi_assert_internal( p == NULL || try_alignment == 0 || (uintptr_t)p % try_alignment == 0 ); + return p; +} + +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) { + MI_UNUSED(allow_large); MI_UNUSED(commit); + *is_large = false; + *is_zero = false; + *addr = mi_prim_mem_grow(size, try_alignment); + return (*addr != NULL ? 0 : ENOMEM); +} + + +//--------------------------------------------- +// Commit/Reset/Protect +//--------------------------------------------- + +int _mi_prim_commit(void* addr, size_t size, bool* is_zero) { + MI_UNUSED(addr); MI_UNUSED(size); + *is_zero = false; + return 0; +} + +int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) { + MI_UNUSED(addr); MI_UNUSED(size); + *needs_recommit = false; + return 0; +} + +int _mi_prim_reset(void* addr, size_t size) { + MI_UNUSED(addr); MI_UNUSED(size); + return 0; +} + +int _mi_prim_protect(void* addr, size_t size, bool protect) { + MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(protect); + return 0; +} + + +//--------------------------------------------- +// Huge pages and NUMA nodes +//--------------------------------------------- + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + MI_UNUSED(hint_addr); MI_UNUSED(size); MI_UNUSED(numa_node); + *is_zero = true; + *addr = NULL; + return ENOSYS; +} + +size_t _mi_prim_numa_node(void) { + return 0; +} + +size_t _mi_prim_numa_node_count(void) { + return 1; +} + + +//---------------------------------------------------------------- +// Clock +//---------------------------------------------------------------- + +#include + +#if defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) + +mi_msecs_t _mi_prim_clock_now(void) { + struct timespec t; + #ifdef CLOCK_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, &t); + #else + clock_gettime(CLOCK_REALTIME, &t); + #endif + return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000); +} + +#else + +// low resolution timer +mi_msecs_t _mi_prim_clock_now(void) { + #if !defined(CLOCKS_PER_SEC) || (CLOCKS_PER_SEC == 1000) || (CLOCKS_PER_SEC == 0) + return (mi_msecs_t)clock(); + #elif (CLOCKS_PER_SEC < 1000) + return (mi_msecs_t)clock() * (1000 / (mi_msecs_t)CLOCKS_PER_SEC); + #else + return (mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000); + #endif +} + +#endif + + +//---------------------------------------------------------------- +// Process info +//---------------------------------------------------------------- + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + // use defaults + MI_UNUSED(pinfo); +} + + +//---------------------------------------------------------------- +// Output +//---------------------------------------------------------------- + +void _mi_prim_out_stderr( const char* msg ) { + fputs(msg,stderr); +} + + +//---------------------------------------------------------------- +// Environment +//---------------------------------------------------------------- + +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + // cannot call getenv() when still initializing the C runtime. + if (_mi_preloading()) return false; + const char* s = getenv(name); + if (s == NULL) { + // we check the upper case name too. + char buf[64+1]; + size_t len = _mi_strnlen(name,sizeof(buf)-1); + for (size_t i = 0; i < len; i++) { + buf[i] = _mi_toupper(name[i]); + } + buf[len] = 0; + s = getenv(buf); + } + if (s == NULL || _mi_strnlen(s,result_size) >= result_size) return false; + _mi_strlcpy(result, s, result_size); + return true; +} + + +//---------------------------------------------------------------- +// Random +//---------------------------------------------------------------- + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + return false; +} + + +//---------------------------------------------------------------- +// Thread init/done +//---------------------------------------------------------------- + +void _mi_prim_thread_init_auto_done(void) { + // nothing +} + +void _mi_prim_thread_done_auto_done(void) { + // nothing +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + MI_UNUSED(heap); +} diff --git a/Objects/mimalloc/prim/windows/etw-mimalloc.wprp b/Objects/mimalloc/prim/windows/etw-mimalloc.wprp new file mode 100644 index 00000000000000..b00cd7adf2285c --- /dev/null +++ b/Objects/mimalloc/prim/windows/etw-mimalloc.wprp @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Objects/mimalloc/prim/windows/etw.h b/Objects/mimalloc/prim/windows/etw.h new file mode 100644 index 00000000000000..4e0a092a10f4ba --- /dev/null +++ b/Objects/mimalloc/prim/windows/etw.h @@ -0,0 +1,905 @@ +//**********************************************************************` +//* This is an include file generated by Message Compiler. *` +//* *` +//* Copyright (c) Microsoft Corporation. All Rights Reserved. *` +//**********************************************************************` +#pragma once + +//***************************************************************************** +// +// Notes on the ETW event code generated by MC: +// +// - Structures and arrays of structures are treated as an opaque binary blob. +// The caller is responsible for packing the data for the structure into a +// single region of memory, with no padding between values. The macro will +// have an extra parameter for the length of the blob. +// - Arrays of nul-terminated strings must be packed by the caller into a +// single binary blob containing the correct number of strings, with a nul +// after each string. The size of the blob is specified in characters, and +// includes the final nul. +// - Arrays of SID are treated as a single binary blob. The caller is +// responsible for packing the SID values into a single region of memory with +// no padding. +// - The length attribute on the data element in the manifest is significant +// for values with intype win:UnicodeString, win:AnsiString, or win:Binary. +// The length attribute must be specified for win:Binary, and is optional for +// win:UnicodeString and win:AnsiString (if no length is given, the strings +// are assumed to be nul-terminated). For win:UnicodeString, the length is +// measured in characters, not bytes. +// - For an array of win:UnicodeString, win:AnsiString, or win:Binary, the +// length attribute applies to every value in the array, so every value in +// the array must have the same length. The values in the array are provided +// to the macro via a single pointer -- the caller is responsible for packing +// all of the values into a single region of memory with no padding between +// values. +// - Values of type win:CountedUnicodeString, win:CountedAnsiString, and +// win:CountedBinary can be generated and collected on Vista or later. +// However, they may not decode properly without the Windows 10 2018 Fall +// Update. +// - Arrays of type win:CountedUnicodeString, win:CountedAnsiString, and +// win:CountedBinary must be packed by the caller into a single region of +// memory. The format for each item is a UINT16 byte-count followed by that +// many bytes of data. When providing the array to the generated macro, you +// must provide the total size of the packed array data, including the UINT16 +// sizes for each item. In the case of win:CountedUnicodeString, the data +// size is specified in WCHAR (16-bit) units. In the case of +// win:CountedAnsiString and win:CountedBinary, the data size is specified in +// bytes. +// +//***************************************************************************** + +#include +#include +#include + +#ifndef ETW_INLINE + #ifdef _ETW_KM_ + // In kernel mode, save stack space by never inlining templates. + #define ETW_INLINE DECLSPEC_NOINLINE __inline + #else + // In user mode, save code size by inlining templates as appropriate. + #define ETW_INLINE __inline + #endif +#endif // ETW_INLINE + +#if defined(__cplusplus) +extern "C" { +#endif + +// +// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro: +// Define this macro to have the compiler skip the generated functions in this +// header. +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// MCGEN_USE_KERNEL_MODE_APIS macro: +// Controls whether the generated code uses kernel-mode or user-mode APIs. +// - Set to 0 to use Windows user-mode APIs such as EventRegister. +// - Set to 1 to use Windows kernel-mode APIs such as EtwRegister. +// Default is based on whether the _ETW_KM_ macro is defined (i.e. by wdm.h). +// Note that the APIs can also be overridden directly, e.g. by setting the +// MCGEN_EVENTWRITETRANSFER or MCGEN_EVENTREGISTER macros. +// +#ifndef MCGEN_USE_KERNEL_MODE_APIS + #ifdef _ETW_KM_ + #define MCGEN_USE_KERNEL_MODE_APIS 1 + #else + #define MCGEN_USE_KERNEL_MODE_APIS 0 + #endif +#endif // MCGEN_USE_KERNEL_MODE_APIS + +// +// MCGEN_HAVE_EVENTSETINFORMATION macro: +// Controls how McGenEventSetInformation uses the EventSetInformation API. +// - Set to 0 to disable the use of EventSetInformation +// (McGenEventSetInformation will always return an error). +// - Set to 1 to directly invoke MCGEN_EVENTSETINFORMATION. +// - Set to 2 to to locate EventSetInformation at runtime via GetProcAddress +// (user-mode) or MmGetSystemRoutineAddress (kernel-mode). +// Default is determined as follows: +// - If MCGEN_EVENTSETINFORMATION has been customized, set to 1 +// (i.e. use MCGEN_EVENTSETINFORMATION). +// - Else if the target OS version has EventSetInformation, set to 1 +// (i.e. use MCGEN_EVENTSETINFORMATION). +// - Else set to 2 (i.e. try to dynamically locate EventSetInformation). +// Note that an McGenEventSetInformation function will only be generated if one +// or more provider in a manifest has provider traits. +// +#ifndef MCGEN_HAVE_EVENTSETINFORMATION + #ifdef MCGEN_EVENTSETINFORMATION // if MCGEN_EVENTSETINFORMATION has been customized, + #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...). + #elif MCGEN_USE_KERNEL_MODE_APIS // else if using kernel-mode APIs, + #if NTDDI_VERSION >= 0x06040000 // if target OS is Windows 10 or later, + #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...). + #else // else + #define MCGEN_HAVE_EVENTSETINFORMATION 2 // find "EtwSetInformation" via MmGetSystemRoutineAddress. + #endif // else (using user-mode APIs) + #else // if target OS and SDK is Windows 8 or later, + #if WINVER >= 0x0602 && defined(EVENT_FILTER_TYPE_SCHEMATIZED) + #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...). + #else // else + #define MCGEN_HAVE_EVENTSETINFORMATION 2 // find "EventSetInformation" via GetModuleHandleExW/GetProcAddress. + #endif + #endif +#endif // MCGEN_HAVE_EVENTSETINFORMATION + +// +// MCGEN Override Macros +// +// The following override macros may be defined before including this header +// to control the APIs used by this header: +// +// - MCGEN_EVENTREGISTER +// - MCGEN_EVENTUNREGISTER +// - MCGEN_EVENTSETINFORMATION +// - MCGEN_EVENTWRITETRANSFER +// +// If the the macro is undefined, the MC implementation will default to the +// corresponding ETW APIs. For example, if the MCGEN_EVENTREGISTER macro is +// undefined, the EventRegister[MyProviderName] macro will use EventRegister +// in user mode and will use EtwRegister in kernel mode. +// +// To prevent issues from conflicting definitions of these macros, the value +// of the override macro will be used as a suffix in certain internal function +// names. Because of this, the override macros must follow certain rules: +// +// - The macro must be defined before any MC-generated header is included and +// must not be undefined or redefined after any MC-generated header is +// included. Different translation units (i.e. different .c or .cpp files) +// may set the macros to different values, but within a translation unit +// (within a single .c or .cpp file), the macro must be set once and not +// changed. +// - The override must be an object-like macro, not a function-like macro +// (i.e. the override macro must not have a parameter list). +// - The override macro's value must be a simple identifier, i.e. must be +// something that starts with a letter or '_' and contains only letters, +// numbers, and '_' characters. +// - If the override macro's value is the name of a second object-like macro, +// the second object-like macro must follow the same rules. (The override +// macro's value can also be the name of a function-like macro, in which +// case the function-like macro does not need to follow the same rules.) +// +// For example, the following will cause compile errors: +// +// #define MCGEN_EVENTWRITETRANSFER MyNamespace::MyClass::MyFunction // Value has non-identifier characters (colon). +// #define MCGEN_EVENTWRITETRANSFER GetEventWriteFunctionPointer(7) // Value has non-identifier characters (parentheses). +// #define MCGEN_EVENTWRITETRANSFER(h,e,a,r,c,d) EventWrite(h,e,c,d) // Override is defined as a function-like macro. +// #define MY_OBJECT_LIKE_MACRO MyNamespace::MyClass::MyEventWriteFunction +// #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // Evaluates to something with non-identifier characters (colon). +// +// The following would be ok: +// +// #define MCGEN_EVENTWRITETRANSFER MyEventWriteFunction1 // OK, suffix will be "MyEventWriteFunction1". +// #define MY_OBJECT_LIKE_MACRO MyEventWriteFunction2 +// #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // OK, suffix will be "MyEventWriteFunction2". +// #define MY_FUNCTION_LIKE_MACRO(h,e,a,r,c,d) MyNamespace::MyClass::MyEventWriteFunction3(h,e,c,d) +// #define MCGEN_EVENTWRITETRANSFER MY_FUNCTION_LIKE_MACRO // OK, suffix will be "MY_FUNCTION_LIKE_MACRO". +// +#ifndef MCGEN_EVENTREGISTER + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTREGISTER EtwRegister + #else + #define MCGEN_EVENTREGISTER EventRegister + #endif +#endif // MCGEN_EVENTREGISTER +#ifndef MCGEN_EVENTUNREGISTER + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTUNREGISTER EtwUnregister + #else + #define MCGEN_EVENTUNREGISTER EventUnregister + #endif +#endif // MCGEN_EVENTUNREGISTER +#ifndef MCGEN_EVENTSETINFORMATION + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTSETINFORMATION EtwSetInformation + #else + #define MCGEN_EVENTSETINFORMATION EventSetInformation + #endif +#endif // MCGEN_EVENTSETINFORMATION +#ifndef MCGEN_EVENTWRITETRANSFER + #if MCGEN_USE_KERNEL_MODE_APIS + #define MCGEN_EVENTWRITETRANSFER EtwWriteTransfer + #else + #define MCGEN_EVENTWRITETRANSFER EventWriteTransfer + #endif +#endif // MCGEN_EVENTWRITETRANSFER + +// +// MCGEN_EVENT_ENABLED macro: +// Override to control how the EventWrite[EventName] macros determine whether +// an event is enabled. The default behavior is for EventWrite[EventName] to +// use the EventEnabled[EventName] macros. +// +#ifndef MCGEN_EVENT_ENABLED +#define MCGEN_EVENT_ENABLED(EventName) EventEnabled##EventName() +#endif + +// +// MCGEN_EVENT_ENABLED_FORCONTEXT macro: +// Override to control how the EventWrite[EventName]_ForContext macros +// determine whether an event is enabled. The default behavior is for +// EventWrite[EventName]_ForContext to use the +// EventEnabled[EventName]_ForContext macros. +// +#ifndef MCGEN_EVENT_ENABLED_FORCONTEXT +#define MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, EventName) EventEnabled##EventName##_ForContext(pContext) +#endif + +// +// MCGEN_ENABLE_CHECK macro: +// Determines whether the specified event would be considered as enabled +// based on the state of the specified context. Slightly faster than calling +// McGenEventEnabled directly. +// +#ifndef MCGEN_ENABLE_CHECK +#define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor)) +#endif + +#if !defined(MCGEN_TRACE_CONTEXT_DEF) +#define MCGEN_TRACE_CONTEXT_DEF +// This structure is for use by MC-generated code and should not be used directly. +typedef struct _MCGEN_TRACE_CONTEXT +{ + TRACEHANDLE RegistrationHandle; + TRACEHANDLE Logger; // Used as pointer to provider traits. + ULONGLONG MatchAnyKeyword; + ULONGLONG MatchAllKeyword; + ULONG Flags; + ULONG IsEnabled; + UCHAR Level; + UCHAR Reserve; + USHORT EnableBitsCount; + PULONG EnableBitMask; + const ULONGLONG* EnableKeyWords; + const UCHAR* EnableLevel; +} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT; +#endif // MCGEN_TRACE_CONTEXT_DEF + +#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF) +#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF +// +// Determines whether an event with a given Level and Keyword would be +// considered as enabled based on the state of the specified context. +// Note that you may want to use MCGEN_ENABLE_CHECK instead of calling this +// function directly. +// +FORCEINLINE +BOOLEAN +McGenLevelKeywordEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ UCHAR Level, + _In_ ULONGLONG Keyword + ) +{ + // + // Check if the event Level is lower than the level at which + // the channel is enabled. + // If the event Level is 0 or the channel is enabled at level 0, + // all levels are enabled. + // + + if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0. + (EnableInfo->Level == 0)) { + + // + // Check if Keyword is enabled + // + + if ((Keyword == (ULONGLONG)0) || + ((Keyword & EnableInfo->MatchAnyKeyword) && + ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) { + return TRUE; + } + } + + return FALSE; +} +#endif // MCGEN_LEVEL_KEYWORD_ENABLED_DEF + +#if !defined(MCGEN_EVENT_ENABLED_DEF) +#define MCGEN_EVENT_ENABLED_DEF +// +// Determines whether the specified event would be considered as enabled based +// on the state of the specified context. Note that you may want to use +// MCGEN_ENABLE_CHECK instead of calling this function directly. +// +FORCEINLINE +BOOLEAN +McGenEventEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ PCEVENT_DESCRIPTOR EventDescriptor + ) +{ + return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword); +} +#endif // MCGEN_EVENT_ENABLED_DEF + +#if !defined(MCGEN_CONTROL_CALLBACK) +#define MCGEN_CONTROL_CALLBACK + +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +VOID +__stdcall +McGenControlCallbackV2( + _In_ LPCGUID SourceId, + _In_ ULONG ControlCode, + _In_ UCHAR Level, + _In_ ULONGLONG MatchAnyKeyword, + _In_ ULONGLONG MatchAllKeyword, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, + _Inout_opt_ PVOID CallbackContext + ) +/*++ + +Routine Description: + + This is the notification callback for Windows Vista and later. + +Arguments: + + SourceId - The GUID that identifies the session that enabled the provider. + + ControlCode - The parameter indicates whether the provider + is being enabled or disabled. + + Level - The level at which the event is enabled. + + MatchAnyKeyword - The bitmask of keywords that the provider uses to + determine the category of events that it writes. + + MatchAllKeyword - This bitmask additionally restricts the category + of events that the provider writes. + + FilterData - The provider-defined data. + + CallbackContext - The context of the callback that is defined when the provider + called EtwRegister to register itself. + +Remarks: + + ETW calls this function to notify provider of enable/disable + +--*/ +{ + PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext; + ULONG Ix; +#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + UNREFERENCED_PARAMETER(SourceId); + UNREFERENCED_PARAMETER(FilterData); +#endif + + if (Ctx == NULL) { + return; + } + + switch (ControlCode) { + + case EVENT_CONTROL_CODE_ENABLE_PROVIDER: + Ctx->Level = Level; + Ctx->MatchAnyKeyword = MatchAnyKeyword; + Ctx->MatchAllKeyword = MatchAllKeyword; + Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER; + + for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) { + if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) { + Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32)); + } else { + Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32)); + } + } + break; + + case EVENT_CONTROL_CODE_DISABLE_PROVIDER: + Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER; + Ctx->Level = 0; + Ctx->MatchAnyKeyword = 0; + Ctx->MatchAllKeyword = 0; + if (Ctx->EnableBitsCount > 0) { +#pragma warning(suppress: 26451) // Arithmetic overflow cannot occur, no matter the value of EnableBitCount + RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG)); + } + break; + + default: + break; + } + +#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + // + // Call user defined callback + // + MCGEN_PRIVATE_ENABLE_CALLBACK_V2( + SourceId, + ControlCode, + Level, + MatchAnyKeyword, + MatchAllKeyword, + FilterData, + CallbackContext + ); +#endif // MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + + return; +} + +#endif // MCGEN_CONTROL_CALLBACK + +#ifndef _mcgen_PENABLECALLBACK + #if MCGEN_USE_KERNEL_MODE_APIS + #define _mcgen_PENABLECALLBACK PETWENABLECALLBACK + #else + #define _mcgen_PENABLECALLBACK PENABLECALLBACK + #endif +#endif // _mcgen_PENABLECALLBACK + +#if !defined(_mcgen_PASTE2) +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_PASTE2(a, b) _mcgen_PASTE2_imp(a, b) +#define _mcgen_PASTE2_imp(a, b) a##b +#endif // _mcgen_PASTE2 + +#if !defined(_mcgen_PASTE3) +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_PASTE3(a, b, c) _mcgen_PASTE3_imp(a, b, c) +#define _mcgen_PASTE3_imp(a, b, c) a##b##_##c +#endif // _mcgen_PASTE3 + +// +// Macro validation +// + +// Validate MCGEN_EVENTREGISTER: + +// Trigger an error if MCGEN_EVENTREGISTER is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER); + +// Trigger an error if MCGEN_EVENTREGISTER is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER) + MCGEN_EVENTREGISTER_must_not_be_redefined_between_headers; + +// Trigger an error if MCGEN_EVENTREGISTER is defined as a function-like macro: +typedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER; +typedef int _mcgen_PASTE2(MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTREGISTER); + +// Validate MCGEN_EVENTUNREGISTER: + +// Trigger an error if MCGEN_EVENTUNREGISTER is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER); + +// Trigger an error if MCGEN_EVENTUNREGISTER is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER) + MCGEN_EVENTUNREGISTER_must_not_be_redefined_between_headers; + +// Trigger an error if MCGEN_EVENTUNREGISTER is defined as a function-like macro: +typedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER; +typedef int _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTUNREGISTER); + +// Validate MCGEN_EVENTSETINFORMATION: + +// Trigger an error if MCGEN_EVENTSETINFORMATION is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION); + +// Trigger an error if MCGEN_EVENTSETINFORMATION is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION) + MCGEN_EVENTSETINFORMATION_must_not_be_redefined_between_headers; + +// Trigger an error if MCGEN_EVENTSETINFORMATION is defined as a function-like macro: +typedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION; +typedef int _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_, MCGEN_EVENTSETINFORMATION); + +// Validate MCGEN_EVENTWRITETRANSFER: + +// Trigger an error if MCGEN_EVENTWRITETRANSFER is not an unqualified (simple) identifier: +struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER); + +// Trigger an error if MCGEN_EVENTWRITETRANSFER is redefined: +typedef struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER) + MCGEN_EVENTWRITETRANSFER_must_not_be_redefined_between_headers;; + +// Trigger an error if MCGEN_EVENTWRITETRANSFER is defined as a function-like macro: +typedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER; +typedef int _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_, MCGEN_EVENTWRITETRANSFER); + +#ifndef McGenEventWrite_def +#define McGenEventWrite_def + +// This macro is for use by MC-generated code and should not be used directly. +#define McGenEventWrite _mcgen_PASTE2(McGenEventWrite_, MCGEN_EVENTWRITETRANSFER) + +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventWrite( + _In_ PMCGEN_TRACE_CONTEXT Context, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ LPCGUID ActivityId, + _In_range_(1, 128) ULONG EventDataCount, + _Pre_cap_(EventDataCount) EVENT_DATA_DESCRIPTOR* EventData + ) +{ + const USHORT UNALIGNED* Traits; + + // Some customized MCGEN_EVENTWRITETRANSFER macros might ignore ActivityId. + UNREFERENCED_PARAMETER(ActivityId); + + Traits = (const USHORT UNALIGNED*)(UINT_PTR)Context->Logger; + + if (Traits == NULL) { + EventData[0].Ptr = 0; + EventData[0].Size = 0; + EventData[0].Reserved = 0; + } else { + EventData[0].Ptr = (ULONG_PTR)Traits; + EventData[0].Size = *Traits; + EventData[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA + } + + return MCGEN_EVENTWRITETRANSFER( + Context->RegistrationHandle, + Descriptor, + ActivityId, + NULL, + EventDataCount, + EventData); +} +#endif // McGenEventWrite_def + +#if !defined(McGenEventRegisterUnregister) +#define McGenEventRegisterUnregister + +// This macro is for use by MC-generated code and should not be used directly. +#define McGenEventRegister _mcgen_PASTE2(McGenEventRegister_, MCGEN_EVENTREGISTER) + +#pragma warning(push) +#pragma warning(disable:6103) +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventRegister( + _In_ LPCGUID ProviderId, + _In_opt_ _mcgen_PENABLECALLBACK EnableCallback, + _In_opt_ PVOID CallbackContext, + _Inout_ PREGHANDLE RegHandle + ) +/*++ + +Routine Description: + + This function registers the provider with ETW. + +Arguments: + + ProviderId - Provider ID to register with ETW. + + EnableCallback - Callback to be used. + + CallbackContext - Context for the callback. + + RegHandle - Pointer to registration handle. + +Remarks: + + Should not be called if the provider is already registered (i.e. should not + be called if *RegHandle != 0). Repeatedly registering a provider is a bug + and may indicate a race condition. However, for compatibility with previous + behavior, this function will return SUCCESS in this case. + +--*/ +{ + ULONG Error; + + if (*RegHandle != 0) + { + Error = 0; // ERROR_SUCCESS + } + else + { + Error = MCGEN_EVENTREGISTER(ProviderId, EnableCallback, CallbackContext, RegHandle); + } + + return Error; +} +#pragma warning(pop) + +// This macro is for use by MC-generated code and should not be used directly. +#define McGenEventUnregister _mcgen_PASTE2(McGenEventUnregister_, MCGEN_EVENTUNREGISTER) + +// This function is for use by MC-generated code and should not be used directly. +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventUnregister(_Inout_ PREGHANDLE RegHandle) +/*++ + +Routine Description: + + Unregister from ETW and set *RegHandle = 0. + +Arguments: + + RegHandle - the pointer to the provider registration handle + +Remarks: + + If provider has not been registered (i.e. if *RegHandle == 0), + return SUCCESS. It is safe to call McGenEventUnregister even if the + call to McGenEventRegister returned an error. + +--*/ +{ + ULONG Error; + + if(*RegHandle == 0) + { + Error = 0; // ERROR_SUCCESS + } + else + { + Error = MCGEN_EVENTUNREGISTER(*RegHandle); + *RegHandle = (REGHANDLE)0; + } + + return Error; +} + +#endif // McGenEventRegisterUnregister + +#ifndef _mcgen_EVENT_BIT_SET + #if defined(_M_IX86) || defined(_M_X64) + // This macro is for use by MC-generated code and should not be used directly. + #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((((const unsigned char*)EnableBits)[BitPosition >> 3] & (1u << (BitPosition & 7))) != 0) + #else // CPU type + // This macro is for use by MC-generated code and should not be used directly. + #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((EnableBits[BitPosition >> 5] & (1u << (BitPosition & 31))) != 0) + #endif // CPU type +#endif // _mcgen_EVENT_BIT_SET + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Provider "microsoft-windows-mimalloc" event count 2 +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +// Provider GUID = 138f4dbb-ee04-4899-aa0a-572ad4475779 +EXTERN_C __declspec(selectany) const GUID ETW_MI_Provider = {0x138f4dbb, 0xee04, 0x4899, {0xaa, 0x0a, 0x57, 0x2a, 0xd4, 0x47, 0x57, 0x79}}; + +#ifndef ETW_MI_Provider_Traits +#define ETW_MI_Provider_Traits NULL +#endif // ETW_MI_Provider_Traits + +// +// Event Descriptors +// +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_ALLOC = {0x64, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0}; +#define ETW_MI_ALLOC_value 0x64 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ETW_MI_FREE = {0x65, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0}; +#define ETW_MI_FREE_value 0x65 + +// +// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro: +// Define this macro to have the compiler skip the generated functions in this +// header. +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Event Enablement Bits +// These variables are for use by MC-generated code and should not be used directly. +// +EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG microsoft_windows_mimallocEnableBits[1]; +EXTERN_C __declspec(selectany) const ULONGLONG microsoft_windows_mimallocKeywords[1] = {0x0}; +EXTERN_C __declspec(selectany) const unsigned char microsoft_windows_mimallocLevels[1] = {4}; + +// +// Provider context +// +EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT ETW_MI_Provider_Context = {0, (ULONG_PTR)ETW_MI_Provider_Traits, 0, 0, 0, 0, 0, 0, 1, microsoft_windows_mimallocEnableBits, microsoft_windows_mimallocKeywords, microsoft_windows_mimallocLevels}; + +// +// Provider REGHANDLE +// +#define microsoft_windows_mimallocHandle (ETW_MI_Provider_Context.RegistrationHandle) + +// +// This macro is set to 0, indicating that the EventWrite[Name] macros do not +// have an Activity parameter. This is controlled by the -km and -um options. +// +#define ETW_MI_Provider_EventWriteActivity 0 + +// +// Register with ETW using the control GUID specified in the manifest. +// Invoke this macro during module initialization (i.e. program startup, +// DLL process attach, or driver load) to initialize the provider. +// Note that if this function returns an error, the error means that +// will not work, but no action needs to be taken -- even if EventRegister +// returns an error, it is generally safe to use EventWrite and +// EventUnregister macros (they will be no-ops if EventRegister failed). +// +#ifndef EventRegistermicrosoft_windows_mimalloc +#define EventRegistermicrosoft_windows_mimalloc() McGenEventRegister(&ETW_MI_Provider, McGenControlCallbackV2, &ETW_MI_Provider_Context, µsoft_windows_mimallocHandle) +#endif + +// +// Register with ETW using a specific control GUID (i.e. a GUID other than what +// is specified in the manifest). Advanced scenarios only. +// +#ifndef EventRegisterByGuidmicrosoft_windows_mimalloc +#define EventRegisterByGuidmicrosoft_windows_mimalloc(Guid) McGenEventRegister(&(Guid), McGenControlCallbackV2, &ETW_MI_Provider_Context, µsoft_windows_mimallocHandle) +#endif + +// +// Unregister with ETW and close the provider. +// Invoke this macro during module shutdown (i.e. program exit, DLL process +// detach, or driver unload) to unregister the provider. +// Note that you MUST call EventUnregister before DLL or driver unload +// (not optional): failure to unregister a provider before DLL or driver unload +// will result in crashes. +// +#ifndef EventUnregistermicrosoft_windows_mimalloc +#define EventUnregistermicrosoft_windows_mimalloc() McGenEventUnregister(µsoft_windows_mimallocHandle) +#endif + +// +// MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION macro: +// Define this macro to enable support for caller-allocated provider context. +// +#ifdef MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION + +// +// Advanced scenarios: Caller-allocated provider context. +// Use when multiple differently-configured provider handles are needed, +// e.g. for container-aware drivers, one context per container. +// +// Usage: +// +// - Caller enables the feature before including this header, e.g. +// #define MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION 1 +// - Caller allocates memory, e.g. pContext = malloc(sizeof(McGenContext_microsoft_windows_mimalloc)); +// - Caller registers the provider, e.g. EventRegistermicrosoft_windows_mimalloc_ForContext(pContext); +// - Caller writes events, e.g. EventWriteMyEvent_ForContext(pContext, ...); +// - Caller unregisters, e.g. EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext); +// - Caller frees memory, e.g. free(pContext); +// + +typedef struct tagMcGenContext_microsoft_windows_mimalloc { + // The fields of this structure are subject to change and should + // not be accessed directly. To access the provider's REGHANDLE, + // use microsoft_windows_mimallocHandle_ForContext(pContext). + MCGEN_TRACE_CONTEXT Context; + ULONG EnableBits[1]; +} McGenContext_microsoft_windows_mimalloc; + +#define EventRegistermicrosoft_windows_mimalloc_ForContext(pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&ETW_MI_Provider, pContext) +#define EventRegisterByGuidmicrosoft_windows_mimalloc_ForContext(Guid, pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)(&(Guid), pContext) +#define EventUnregistermicrosoft_windows_mimalloc_ForContext(pContext) McGenEventUnregister(&(pContext)->Context.RegistrationHandle) + +// +// Provider REGHANDLE for caller-allocated context. +// +#define microsoft_windows_mimallocHandle_ForContext(pContext) ((pContext)->Context.RegistrationHandle) + +// This function is for use by MC-generated code and should not be used directly. +// Initialize and register the caller-allocated context. +__inline +ULONG __stdcall +_mcgen_PASTE2(_mcgen_RegisterForContext_microsoft_windows_mimalloc_, MCGEN_EVENTREGISTER)( + _In_ LPCGUID pProviderId, + _Out_ McGenContext_microsoft_windows_mimalloc* pContext) +{ + RtlZeroMemory(pContext, sizeof(*pContext)); + pContext->Context.Logger = (ULONG_PTR)ETW_MI_Provider_Traits; + pContext->Context.EnableBitsCount = 1; + pContext->Context.EnableBitMask = pContext->EnableBits; + pContext->Context.EnableKeyWords = microsoft_windows_mimallocKeywords; + pContext->Context.EnableLevel = microsoft_windows_mimallocLevels; + return McGenEventRegister( + pProviderId, + McGenControlCallbackV2, + &pContext->Context, + &pContext->Context.RegistrationHandle); +} + +// This function is for use by MC-generated code and should not be used directly. +// Trigger a compile error if called with the wrong parameter type. +FORCEINLINE +_Ret_ McGenContext_microsoft_windows_mimalloc* +_mcgen_CheckContextType_microsoft_windows_mimalloc(_In_ McGenContext_microsoft_windows_mimalloc* pContext) +{ + return pContext; +} + +#endif // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION + +// +// Enablement check macro for event "ETW_MI_ALLOC" +// +#define EventEnabledETW_MI_ALLOC() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0) +#define EventEnabledETW_MI_ALLOC_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0) + +// +// Event write macros for event "ETW_MI_ALLOC" +// +#define EventWriteETW_MI_ALLOC(Address, Size) \ + MCGEN_EVENT_ENABLED(ETW_MI_ALLOC) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) : 0 +#define EventWriteETW_MI_ALLOC_AssumeEnabled(Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&ETW_MI_Provider_Context, &ETW_MI_ALLOC, Address, Size) +#define EventWriteETW_MI_ALLOC_ForContext(pContext, Address, Size) \ + MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_ALLOC) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&(pContext)->Context, &ETW_MI_ALLOC, Address, Size) : 0 +#define EventWriteETW_MI_ALLOC_ForContextAssumeEnabled(pContext, Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_ALLOC, Address, Size) + +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_TEMPLATE_FOR_ETW_MI_ALLOC _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER) + +// +// Enablement check macro for event "ETW_MI_FREE" +// +#define EventEnabledETW_MI_FREE() _mcgen_EVENT_BIT_SET(microsoft_windows_mimallocEnableBits, 0) +#define EventEnabledETW_MI_FREE_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->EnableBits, 0) + +// +// Event write macros for event "ETW_MI_FREE" +// +#define EventWriteETW_MI_FREE(Address, Size) \ + MCGEN_EVENT_ENABLED(ETW_MI_FREE) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) : 0 +#define EventWriteETW_MI_FREE_AssumeEnabled(Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&ETW_MI_Provider_Context, &ETW_MI_FREE, Address, Size) +#define EventWriteETW_MI_FREE_ForContext(pContext, Address, Size) \ + MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ETW_MI_FREE) \ + ? _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&(pContext)->Context, &ETW_MI_FREE, Address, Size) : 0 +#define EventWriteETW_MI_FREE_ForContextAssumeEnabled(pContext, Address, Size) \ + _mcgen_TEMPLATE_FOR_ETW_MI_FREE(&_mcgen_CheckContextType_microsoft_windows_mimalloc(pContext)->Context, &ETW_MI_FREE, Address, Size) + +// This macro is for use by MC-generated code and should not be used directly. +#define _mcgen_TEMPLATE_FOR_ETW_MI_FREE _mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER) + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro: +// Define this macro to have the compiler skip the generated functions in this +// header. +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Template Functions +// + +// +// Function for template "ETW_CUSTOM_HEAP_ALLOC_DATA" (and possibly others). +// This function is for use by MC-generated code and should not be used directly. +// +#ifndef McTemplateU0xx_def +#define McTemplateU0xx_def +ETW_INLINE +ULONG +_mcgen_PASTE2(McTemplateU0xx_, MCGEN_EVENTWRITETRANSFER)( + _In_ PMCGEN_TRACE_CONTEXT Context, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned __int64 _Arg0, + _In_ const unsigned __int64 _Arg1 + ) +{ +#define McTemplateU0xx_ARGCOUNT 2 + + EVENT_DATA_DESCRIPTOR EventData[McTemplateU0xx_ARGCOUNT + 1]; + + EventDataDescCreate(&EventData[1],&_Arg0, sizeof(const unsigned __int64) ); + + EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned __int64) ); + + return McGenEventWrite(Context, Descriptor, NULL, McTemplateU0xx_ARGCOUNT + 1, EventData); +} +#endif // McTemplateU0xx_def + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +#if defined(__cplusplus) +} +#endif diff --git a/Objects/mimalloc/prim/windows/etw.man b/Objects/mimalloc/prim/windows/etw.man new file mode 100644 index 00000000000000..cfd1f8a9eaacd5 Binary files /dev/null and b/Objects/mimalloc/prim/windows/etw.man differ diff --git a/Objects/mimalloc/prim/windows/prim.c b/Objects/mimalloc/prim/windows/prim.c new file mode 100644 index 00000000000000..a038277ad21cb0 --- /dev/null +++ b/Objects/mimalloc/prim/windows/prim.c @@ -0,0 +1,622 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// This file is included in `src/prim/prim.c` + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" +#include // fputs, stderr + + +//--------------------------------------------- +// Dynamically bind Windows API points for portability +//--------------------------------------------- + +// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. +// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility) +// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB) +// We define a minimal MEM_EXTENDED_PARAMETER ourselves in order to be able to compile with older SDK's. +typedef enum MI_MEM_EXTENDED_PARAMETER_TYPE_E { + MiMemExtendedParameterInvalidType = 0, + MiMemExtendedParameterAddressRequirements, + MiMemExtendedParameterNumaNode, + MiMemExtendedParameterPartitionHandle, + MiMemExtendedParameterUserPhysicalHandle, + MiMemExtendedParameterAttributeFlags, + MiMemExtendedParameterMax +} MI_MEM_EXTENDED_PARAMETER_TYPE; + +typedef struct DECLSPEC_ALIGN(8) MI_MEM_EXTENDED_PARAMETER_S { + struct { DWORD64 Type : 8; DWORD64 Reserved : 56; } Type; + union { DWORD64 ULong64; PVOID Pointer; SIZE_T Size; HANDLE Handle; DWORD ULong; } Arg; +} MI_MEM_EXTENDED_PARAMETER; + +typedef struct MI_MEM_ADDRESS_REQUIREMENTS_S { + PVOID LowestStartingAddress; + PVOID HighestEndingAddress; + SIZE_T Alignment; +} MI_MEM_ADDRESS_REQUIREMENTS; + +#define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 + +#include +typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG); +typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG); +static PVirtualAlloc2 pVirtualAlloc2 = NULL; +static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL; + +// Similarly, GetNumaProcesorNodeEx is only supported since Windows 7 +typedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER; + +typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber); +typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber); +typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask); +typedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber); +static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL; +static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL; +static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL; +static PGetNumaProcessorNode pGetNumaProcessorNode = NULL; + +//--------------------------------------------- +// Enable large page support dynamically (if possible) +//--------------------------------------------- + +static bool win_enable_large_os_pages(size_t* large_page_size) +{ + static bool large_initialized = false; + if (large_initialized) return (_mi_os_large_page_size() > 0); + large_initialized = true; + + // Try to see if large OS pages are supported + // To use large pages on Windows, we first need access permission + // Set "Lock pages in memory" permission in the group policy editor + // + unsigned long err = 0; + HANDLE token = NULL; + BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token); + if (ok) { + TOKEN_PRIVILEGES tp; + ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid); + if (ok) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); + if (ok) { + err = GetLastError(); + ok = (err == ERROR_SUCCESS); + if (ok && large_page_size != NULL) { + *large_page_size = GetLargePageMinimum(); + } + } + } + CloseHandle(token); + } + if (!ok) { + if (err == 0) err = GetLastError(); + _mi_warning_message("cannot enable large OS page support, error %lu\n", err); + } + return (ok!=0); +} + + +//--------------------------------------------- +// Initialize +//--------------------------------------------- + +void _mi_prim_mem_init( mi_os_mem_config_t* config ) +{ + config->has_overcommit = false; + config->must_free_whole = true; + config->has_virtual_reserve = true; + // get the page size + SYSTEM_INFO si; + GetSystemInfo(&si); + if (si.dwPageSize > 0) { config->page_size = si.dwPageSize; } + if (si.dwAllocationGranularity > 0) { config->alloc_granularity = si.dwAllocationGranularity; } + // get the VirtualAlloc2 function + HINSTANCE hDll; + hDll = LoadLibrary(TEXT("kernelbase.dll")); + if (hDll != NULL) { + // use VirtualAlloc2FromApp if possible as it is available to Windows store apps + pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2FromApp"); + if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2"); + FreeLibrary(hDll); + } + // NtAllocateVirtualMemoryEx is used for huge page allocation + hDll = LoadLibrary(TEXT("ntdll.dll")); + if (hDll != NULL) { + pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, "NtAllocateVirtualMemoryEx"); + FreeLibrary(hDll); + } + // Try to use Win7+ numa API + hDll = LoadLibrary(TEXT("kernel32.dll")); + if (hDll != NULL) { + pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx"); + pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx"); + pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx"); + pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNode"); + FreeLibrary(hDll); + } + if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { + win_enable_large_os_pages(&config->large_page_size); + } +} + + +//--------------------------------------------- +// Free +//--------------------------------------------- + +int _mi_prim_free(void* addr, size_t size ) { + MI_UNUSED(size); + DWORD errcode = 0; + bool err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); + if (err) { errcode = GetLastError(); } + if (errcode == ERROR_INVALID_ADDRESS) { + // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside + // the memory region returned by VirtualAlloc; in that case we need to free using + // the start of the region. + MEMORY_BASIC_INFORMATION info = { 0 }; + VirtualQuery(addr, &info, sizeof(info)); + if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)MI_SEGMENT_SIZE) { + errcode = 0; + err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0); + if (err) { errcode = GetLastError(); } + } + } + return (int)errcode; +} + + +//--------------------------------------------- +// VirtualAlloc +//--------------------------------------------- + +static void* win_virtual_alloc_prim(void* addr, size_t size, size_t try_alignment, DWORD flags) { + #if (MI_INTPTR_SIZE >= 8) + // on 64-bit systems, try to use the virtual address area after 2TiB for 4MiB aligned allocations + if (addr == NULL) { + void* hint = _mi_os_get_aligned_hint(try_alignment,size); + if (hint != NULL) { + void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); + if (p != NULL) return p; + _mi_verbose_message("warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags); + // fall through on error + } + } + #endif + // on modern Windows try use VirtualAlloc2 for aligned allocation + if (try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) { + MI_MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 }; + reqs.Alignment = try_alignment; + MI_MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} }; + param.Type.Type = MiMemExtendedParameterAddressRequirements; + param.Arg.Pointer = &reqs; + void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1); + if (p != NULL) return p; + _mi_warning_message("unable to allocate aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags); + // fall through on error + } + // last resort + return VirtualAlloc(addr, size, flags, PAGE_READWRITE); +} + +static void* win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) { + mi_assert_internal(!(large_only && !allow_large)); + static _Atomic(size_t) large_page_try_ok; // = 0; + void* p = NULL; + // Try to allocate large OS pages (2MiB) if allowed or required. + if ((large_only || _mi_os_use_large_page(size, try_alignment)) + && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) { + size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); + if (!large_only && try_ok > 0) { + // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive. + // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times. + mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); + } + else { + // large OS pages must always reserve and commit. + *is_large = true; + p = win_virtual_alloc_prim(addr, size, try_alignment, flags | MEM_LARGE_PAGES); + if (large_only) return p; + // fall back to non-large page allocation on error (`p == NULL`). + if (p == NULL) { + mi_atomic_store_release(&large_page_try_ok,10UL); // on error, don't try again for the next N allocations + } + } + } + // Fall back to regular page allocation + if (p == NULL) { + *is_large = ((flags&MEM_LARGE_PAGES) != 0); + p = win_virtual_alloc_prim(addr, size, try_alignment, flags); + } + //if (p == NULL) { _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); } + return p; +} + +int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + mi_assert_internal(commit || !allow_large); + mi_assert_internal(try_alignment > 0); + *is_zero = true; + int flags = MEM_RESERVE; + if (commit) { flags |= MEM_COMMIT; } + *addr = win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large); + return (*addr != NULL ? 0 : (int)GetLastError()); +} + + +//--------------------------------------------- +// Commit/Reset/Protect +//--------------------------------------------- +#ifdef _MSC_VER +#pragma warning(disable:6250) // suppress warning calling VirtualFree without MEM_RELEASE (for decommit) +#endif + +int _mi_prim_commit(void* addr, size_t size, bool* is_zero) { + *is_zero = false; + /* + // zero'ing only happens on an initial commit... but checking upfront seems expensive.. + _MEMORY_BASIC_INFORMATION meminfo; _mi_memzero_var(meminfo); + if (VirtualQuery(addr, &meminfo, size) > 0) { + if ((meminfo.State & MEM_COMMIT) == 0) { + *is_zero = true; + } + } + */ + // commit + void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE); + if (p == NULL) return (int)GetLastError(); + return 0; +} + +int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) { + BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT); + *needs_recommit = true; // for safety, assume always decommitted even in the case of an error. + return (ok ? 0 : (int)GetLastError()); +} + +int _mi_prim_reset(void* addr, size_t size) { + void* p = VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE); + mi_assert_internal(p == addr); + #if 0 + if (p != NULL) { + VirtualUnlock(addr,size); // VirtualUnlock after MEM_RESET removes the memory directly from the working set + } + #endif + return (p != NULL ? 0 : (int)GetLastError()); +} + +int _mi_prim_protect(void* addr, size_t size, bool protect) { + DWORD oldprotect = 0; + BOOL ok = VirtualProtect(addr, size, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect); + return (ok ? 0 : (int)GetLastError()); +} + + +//--------------------------------------------- +// Huge page allocation +//--------------------------------------------- + +static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int numa_node) +{ + const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE; + + win_enable_large_os_pages(NULL); + + MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} }; + // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages + static bool mi_huge_pages_available = true; + if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) { + params[0].Type.Type = MiMemExtendedParameterAttributeFlags; + params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE; + ULONG param_count = 1; + if (numa_node >= 0) { + param_count++; + params[1].Type.Type = MiMemExtendedParameterNumaNode; + params[1].Arg.ULong = (unsigned)numa_node; + } + SIZE_T psize = size; + void* base = hint_addr; + NTSTATUS err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count); + if (err == 0 && base != NULL) { + return base; + } + else { + // fall back to regular large pages + mi_huge_pages_available = false; // don't try further huge pages + _mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err); + } + } + // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation + if (pVirtualAlloc2 != NULL && numa_node >= 0) { + params[0].Type.Type = MiMemExtendedParameterNumaNode; + params[0].Arg.ULong = (unsigned)numa_node; + return (*pVirtualAlloc2)(GetCurrentProcess(), hint_addr, size, flags, PAGE_READWRITE, params, 1); + } + + // otherwise use regular virtual alloc on older windows + return VirtualAlloc(hint_addr, size, flags, PAGE_READWRITE); +} + +int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) { + *is_zero = true; + *addr = _mi_prim_alloc_huge_os_pagesx(hint_addr,size,numa_node); + return (*addr != NULL ? 0 : (int)GetLastError()); +} + + +//--------------------------------------------- +// Numa nodes +//--------------------------------------------- + +size_t _mi_prim_numa_node(void) { + USHORT numa_node = 0; + if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) { + // Extended API is supported + MI_PROCESSOR_NUMBER pnum; + (*pGetCurrentProcessorNumberEx)(&pnum); + USHORT nnode = 0; + BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode); + if (ok) { numa_node = nnode; } + } + else if (pGetNumaProcessorNode != NULL) { + // Vista or earlier, use older API that is limited to 64 processors. Issue #277 + DWORD pnum = GetCurrentProcessorNumber(); + UCHAR nnode = 0; + BOOL ok = pGetNumaProcessorNode((UCHAR)pnum, &nnode); + if (ok) { numa_node = nnode; } + } + return numa_node; +} + +size_t _mi_prim_numa_node_count(void) { + ULONG numa_max = 0; + GetNumaHighestNodeNumber(&numa_max); + // find the highest node number that has actual processors assigned to it. Issue #282 + while(numa_max > 0) { + if (pGetNumaNodeProcessorMaskEx != NULL) { + // Extended API is supported + GROUP_AFFINITY affinity; + if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) { + if (affinity.Mask != 0) break; // found the maximum non-empty node + } + } + else { + // Vista or earlier, use older API that is limited to 64 processors. + ULONGLONG mask; + if (GetNumaNodeProcessorMask((UCHAR)numa_max, &mask)) { + if (mask != 0) break; // found the maximum non-empty node + }; + } + // max node was invalid or had no processor assigned, try again + numa_max--; + } + return ((size_t)numa_max + 1); +} + + +//---------------------------------------------------------------- +// Clock +//---------------------------------------------------------------- + +static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) { + static LARGE_INTEGER mfreq; // = 0 + if (mfreq.QuadPart == 0LL) { + LARGE_INTEGER f; + QueryPerformanceFrequency(&f); + mfreq.QuadPart = f.QuadPart/1000LL; + if (mfreq.QuadPart == 0) mfreq.QuadPart = 1; + } + return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart); +} + +mi_msecs_t _mi_prim_clock_now(void) { + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return mi_to_msecs(t); +} + + +//---------------------------------------------------------------- +// Process Info +//---------------------------------------------------------------- + +#include +#include + +static mi_msecs_t filetime_msecs(const FILETIME* ftime) { + ULARGE_INTEGER i; + i.LowPart = ftime->dwLowDateTime; + i.HighPart = ftime->dwHighDateTime; + mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds + return msecs; +} + +typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD); +static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL; + +void _mi_prim_process_info(mi_process_info_t* pinfo) +{ + FILETIME ct; + FILETIME ut; + FILETIME st; + FILETIME et; + GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut); + pinfo->utime = filetime_msecs(&ut); + pinfo->stime = filetime_msecs(&st); + + // load psapi on demand + if (pGetProcessMemoryInfo == NULL) { + HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll")); + if (hDll != NULL) { + pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo"); + } + } + + // get process info + PROCESS_MEMORY_COUNTERS info; + memset(&info, 0, sizeof(info)); + if (pGetProcessMemoryInfo != NULL) { + pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); + } + pinfo->current_rss = (size_t)info.WorkingSetSize; + pinfo->peak_rss = (size_t)info.PeakWorkingSetSize; + pinfo->current_commit = (size_t)info.PagefileUsage; + pinfo->peak_commit = (size_t)info.PeakPagefileUsage; + pinfo->page_faults = (size_t)info.PageFaultCount; +} + +//---------------------------------------------------------------- +// Output +//---------------------------------------------------------------- + +void _mi_prim_out_stderr( const char* msg ) +{ + // on windows with redirection, the C runtime cannot handle locale dependent output + // after the main thread closes so we use direct console output. + if (!_mi_preloading()) { + // _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console + static HANDLE hcon = INVALID_HANDLE_VALUE; + static bool hconIsConsole; + if (hcon == INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO sbi; + hcon = GetStdHandle(STD_ERROR_HANDLE); + hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi)); + } + const size_t len = _mi_strlen(msg); + if (len > 0 && len < UINT32_MAX) { + DWORD written = 0; + if (hconIsConsole) { + WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL); + } + else if (hcon != INVALID_HANDLE_VALUE) { + // use direct write if stderr was redirected + WriteFile(hcon, msg, (DWORD)len, &written, NULL); + } + else { + // finally fall back to fputs after all + fputs(msg, stderr); + } + } + } +} + + +//---------------------------------------------------------------- +// Environment +//---------------------------------------------------------------- + +// On Windows use GetEnvironmentVariable instead of getenv to work +// reliably even when this is invoked before the C runtime is initialized. +// i.e. when `_mi_preloading() == true`. +// Note: on windows, environment names are not case sensitive. +bool _mi_prim_getenv(const char* name, char* result, size_t result_size) { + result[0] = 0; + size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size); + return (len > 0 && len < result_size); +} + + + +//---------------------------------------------------------------- +// Random +//---------------------------------------------------------------- + +#if defined(MI_USE_RTLGENRANDOM) // || defined(__cplusplus) +// We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using +// dynamic overriding, we observed it can raise an exception when compiled with C++, and +// sometimes deadlocks when also running under the VS debugger. +// In contrast, issue #623 implies that on Windows Server 2019 we need to use BCryptGenRandom. +// To be continued.. +#pragma comment (lib,"advapi32.lib") +#define RtlGenRandom SystemFunction036 +mi_decl_externc BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + return (RtlGenRandom(buf, (ULONG)buf_len) != 0); +} + +#else + +#ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG +#define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 +#endif + +typedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG); +static PBCryptGenRandom pBCryptGenRandom = NULL; + +bool _mi_prim_random_buf(void* buf, size_t buf_len) { + if (pBCryptGenRandom == NULL) { + HINSTANCE hDll = LoadLibrary(TEXT("bcrypt.dll")); + if (hDll != NULL) { + pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, "BCryptGenRandom"); + } + if (pBCryptGenRandom == NULL) return false; + } + return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0); +} + +#endif // MI_USE_RTLGENRANDOM + +//---------------------------------------------------------------- +// Thread init/done +//---------------------------------------------------------------- + +#if !defined(MI_SHARED_LIB) + +// use thread local storage keys to detect thread ending +#include +#if (_WIN32_WINNT < 0x600) // before Windows Vista +WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback ); +WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex ); +WINBASEAPI BOOL WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData ); +WINBASEAPI BOOL WINAPI FlsFree(_In_ DWORD dwFlsIndex); +#endif + +static DWORD mi_fls_key = (DWORD)(-1); + +static void NTAPI mi_fls_done(PVOID value) { + mi_heap_t* heap = (mi_heap_t*)value; + if (heap != NULL) { + _mi_thread_done(heap); + FlsSetValue(mi_fls_key, NULL); // prevent recursion as _mi_thread_done may set it back to the main heap, issue #672 + } +} + +void _mi_prim_thread_init_auto_done(void) { + mi_fls_key = FlsAlloc(&mi_fls_done); +} + +void _mi_prim_thread_done_auto_done(void) { + // call thread-done on all threads (except the main thread) to prevent + // dangling callback pointer if statically linked with a DLL; Issue #208 + FlsFree(mi_fls_key); +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + mi_assert_internal(mi_fls_key != (DWORD)(-1)); + FlsSetValue(mi_fls_key, heap); +} + +#else + +// Dll; nothing to do as in that case thread_done is handled through the DLL_THREAD_DETACH event. + +void _mi_prim_thread_init_auto_done(void) { +} + +void _mi_prim_thread_done_auto_done(void) { +} + +void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) { + MI_UNUSED(heap); +} + +#endif diff --git a/Objects/mimalloc/prim/windows/readme.md b/Objects/mimalloc/prim/windows/readme.md new file mode 100644 index 00000000000000..217c3d174db473 --- /dev/null +++ b/Objects/mimalloc/prim/windows/readme.md @@ -0,0 +1,17 @@ +## Primitives: + +- `prim.c` contains Windows primitives for OS allocation. + +## Event Tracing for Windows (ETW) + +- `etw.h` is generated from `etw.man` which contains the manifest for mimalloc events. + (100 is an allocation, 101 is for a free) + +- `etw-mimalloc.wprp` is a profile for the Windows Performance Recorder (WPR). + In an admin prompt, you can use: + ``` + > wpr -start src\prim\windows\etw-mimalloc.wprp -filemode + > + > wpr -stop test.etl + ``` + and then open `test.etl` in the Windows Performance Analyzer (WPA). \ No newline at end of file diff --git a/Objects/mimalloc/random.c b/Objects/mimalloc/random.c new file mode 100644 index 00000000000000..35a0633a800d6c --- /dev/null +++ b/Objects/mimalloc/random.c @@ -0,0 +1,254 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/prim.h" // _mi_prim_random_buf +#include // memset + +/* ---------------------------------------------------------------------------- +We use our own PRNG to keep predictable performance of random number generation +and to avoid implementations that use a lock. We only use the OS provided +random source to initialize the initial seeds. Since we do not need ultimate +performance but we do rely on the security (for secret cookies in secure mode) +we use a cryptographically secure generator (chacha20). +-----------------------------------------------------------------------------*/ + +#define MI_CHACHA_ROUNDS (20) // perhaps use 12 for better performance? + + +/* ---------------------------------------------------------------------------- +Chacha20 implementation as the original algorithm with a 64-bit nonce +and counter: https://en.wikipedia.org/wiki/Salsa20 +The input matrix has sixteen 32-bit values: +Position 0 to 3: constant key +Position 4 to 11: the key +Position 12 to 13: the counter. +Position 14 to 15: the nonce. + +The implementation uses regular C code which compiles very well on modern compilers. +(gcc x64 has no register spills, and clang 6+ uses SSE instructions) +-----------------------------------------------------------------------------*/ + +static inline uint32_t rotl(uint32_t x, uint32_t shift) { + return (x << shift) | (x >> (32 - shift)); +} + +static inline void qround(uint32_t x[16], size_t a, size_t b, size_t c, size_t d) { + x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 16); + x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 12); + x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 8); + x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 7); +} + +static void chacha_block(mi_random_ctx_t* ctx) +{ + // scramble into `x` + uint32_t x[16]; + for (size_t i = 0; i < 16; i++) { + x[i] = ctx->input[i]; + } + for (size_t i = 0; i < MI_CHACHA_ROUNDS; i += 2) { + qround(x, 0, 4, 8, 12); + qround(x, 1, 5, 9, 13); + qround(x, 2, 6, 10, 14); + qround(x, 3, 7, 11, 15); + qround(x, 0, 5, 10, 15); + qround(x, 1, 6, 11, 12); + qround(x, 2, 7, 8, 13); + qround(x, 3, 4, 9, 14); + } + + // add scrambled data to the initial state + for (size_t i = 0; i < 16; i++) { + ctx->output[i] = x[i] + ctx->input[i]; + } + ctx->output_available = 16; + + // increment the counter for the next round + ctx->input[12] += 1; + if (ctx->input[12] == 0) { + ctx->input[13] += 1; + if (ctx->input[13] == 0) { // and keep increasing into the nonce + ctx->input[14] += 1; + } + } +} + +static uint32_t chacha_next32(mi_random_ctx_t* ctx) { + if (ctx->output_available <= 0) { + chacha_block(ctx); + ctx->output_available = 16; // (assign again to suppress static analysis warning) + } + const uint32_t x = ctx->output[16 - ctx->output_available]; + ctx->output[16 - ctx->output_available] = 0; // reset once the data is handed out + ctx->output_available--; + return x; +} + +static inline uint32_t read32(const uint8_t* p, size_t idx32) { + const size_t i = 4*idx32; + return ((uint32_t)p[i+0] | (uint32_t)p[i+1] << 8 | (uint32_t)p[i+2] << 16 | (uint32_t)p[i+3] << 24); +} + +static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t nonce) +{ + // since we only use chacha for randomness (and not encryption) we + // do not _need_ to read 32-bit values as little endian but we do anyways + // just for being compatible :-) + memset(ctx, 0, sizeof(*ctx)); + for (size_t i = 0; i < 4; i++) { + const uint8_t* sigma = (uint8_t*)"expand 32-byte k"; + ctx->input[i] = read32(sigma,i); + } + for (size_t i = 0; i < 8; i++) { + ctx->input[i + 4] = read32(key,i); + } + ctx->input[12] = 0; + ctx->input[13] = 0; + ctx->input[14] = (uint32_t)nonce; + ctx->input[15] = (uint32_t)(nonce >> 32); +} + +static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) { + memset(ctx_new, 0, sizeof(*ctx_new)); + _mi_memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input)); + ctx_new->input[12] = 0; + ctx_new->input[13] = 0; + ctx_new->input[14] = (uint32_t)nonce; + ctx_new->input[15] = (uint32_t)(nonce >> 32); + mi_assert_internal(ctx->input[14] != ctx_new->input[14] || ctx->input[15] != ctx_new->input[15]); // do not reuse nonces! + chacha_block(ctx_new); +} + + +/* ---------------------------------------------------------------------------- +Random interface +-----------------------------------------------------------------------------*/ + +#if MI_DEBUG>1 +static bool mi_random_is_initialized(mi_random_ctx_t* ctx) { + return (ctx != NULL && ctx->input[0] != 0); +} +#endif + +void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* ctx_new) { + mi_assert_internal(mi_random_is_initialized(ctx)); + mi_assert_internal(ctx != ctx_new); + chacha_split(ctx, (uintptr_t)ctx_new /*nonce*/, ctx_new); +} + +uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { + mi_assert_internal(mi_random_is_initialized(ctx)); + #if MI_INTPTR_SIZE <= 4 + return chacha_next32(ctx); + #elif MI_INTPTR_SIZE == 8 + return (((uintptr_t)chacha_next32(ctx) << 32) | chacha_next32(ctx)); + #else + # error "define mi_random_next for this platform" + #endif +} + + +/* ---------------------------------------------------------------------------- +To initialize a fresh random context. +If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. +-----------------------------------------------------------------------------*/ + +uintptr_t _mi_os_random_weak(uintptr_t extra_seed) { + uintptr_t x = (uintptr_t)&_mi_os_random_weak ^ extra_seed; // ASLR makes the address random + x ^= _mi_prim_clock_now(); + // and do a few randomization steps + uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1; + for (uintptr_t i = 0; i < max; i++) { + x = _mi_random_shuffle(x); + } + mi_assert_internal(x != 0); + return x; +} + +static void mi_random_init_ex(mi_random_ctx_t* ctx, bool use_weak) { + uint8_t key[32] = {0}; + if (use_weak || !_mi_prim_random_buf(key, sizeof(key))) { + // if we fail to get random data from the OS, we fall back to a + // weak random source based on the current time + #if !defined(__wasi__) + if (!use_weak) { _mi_warning_message("unable to use secure randomness\n"); } + #endif + uintptr_t x = _mi_os_random_weak(0); + for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words. + x = _mi_random_shuffle(x); + ((uint32_t*)key)[i] = (uint32_t)x; + } + ctx->weak = true; + } + else { + ctx->weak = false; + } + chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ ); +} + +void _mi_random_init(mi_random_ctx_t* ctx) { + mi_random_init_ex(ctx, false); +} + +void _mi_random_init_weak(mi_random_ctx_t * ctx) { + mi_random_init_ex(ctx, true); +} + +void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx) { + if (ctx->weak) { + _mi_random_init(ctx); + } +} + +/* -------------------------------------------------------- +test vectors from +----------------------------------------------------------- */ +/* +static bool array_equals(uint32_t* x, uint32_t* y, size_t n) { + for (size_t i = 0; i < n; i++) { + if (x[i] != y[i]) return false; + } + return true; +} +static void chacha_test(void) +{ + uint32_t x[4] = { 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 }; + uint32_t x_out[4] = { 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb }; + qround(x, 0, 1, 2, 3); + mi_assert_internal(array_equals(x, x_out, 4)); + + uint32_t y[16] = { + 0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a, + 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0x2a5f714c, + 0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963, + 0x5c971061, 0x3d631689, 0x2098d9d6, 0x91dbd320 }; + uint32_t y_out[16] = { + 0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a, + 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0xcfacafd2, + 0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963, + 0x5c971061, 0xccc07c79, 0x2098d9d6, 0x91dbd320 }; + qround(y, 2, 7, 8, 13); + mi_assert_internal(array_equals(y, y_out, 16)); + + mi_random_ctx_t r = { + { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, + 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, + 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c, + 0x00000001, 0x09000000, 0x4a000000, 0x00000000 }, + {0}, + 0 + }; + uint32_t r_out[16] = { + 0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3, + 0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3, + 0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9, + 0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 }; + chacha_block(&r); + mi_assert_internal(array_equals(r.output, r_out, 16)); +} +*/ diff --git a/Objects/mimalloc/segment-map.c b/Objects/mimalloc/segment-map.c new file mode 100644 index 00000000000000..3cd2127e56c1a7 --- /dev/null +++ b/Objects/mimalloc/segment-map.c @@ -0,0 +1,153 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019-2023, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + The following functions are to reliably find the segment or + block that encompasses any pointer p (or NULL if it is not + in any of our segments). + We maintain a bitmap of all memory with 1 bit per MI_SEGMENT_SIZE (64MiB) + set to 1 if it contains the segment meta data. +----------------------------------------------------------- */ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +#if (MI_INTPTR_SIZE==8) +#define MI_MAX_ADDRESS ((size_t)40 << 40) // 40TB (to include huge page areas) +#else +#define MI_MAX_ADDRESS ((size_t)2 << 30) // 2Gb +#endif + +#define MI_SEGMENT_MAP_BITS (MI_MAX_ADDRESS / MI_SEGMENT_SIZE) +#define MI_SEGMENT_MAP_SIZE (MI_SEGMENT_MAP_BITS / 8) +#define MI_SEGMENT_MAP_WSIZE (MI_SEGMENT_MAP_SIZE / MI_INTPTR_SIZE) + +static _Atomic(uintptr_t) mi_segment_map[MI_SEGMENT_MAP_WSIZE + 1]; // 2KiB per TB with 64MiB segments + +static size_t mi_segment_map_index_of(const mi_segment_t* segment, size_t* bitidx) { + mi_assert_internal(_mi_ptr_segment(segment + 1) == segment); // is it aligned on MI_SEGMENT_SIZE? + if ((uintptr_t)segment >= MI_MAX_ADDRESS) { + *bitidx = 0; + return MI_SEGMENT_MAP_WSIZE; + } + else { + const uintptr_t segindex = ((uintptr_t)segment) / MI_SEGMENT_SIZE; + *bitidx = segindex % MI_INTPTR_BITS; + const size_t mapindex = segindex / MI_INTPTR_BITS; + mi_assert_internal(mapindex < MI_SEGMENT_MAP_WSIZE); + return mapindex; + } +} + +void _mi_segment_map_allocated_at(const mi_segment_t* segment) { + size_t bitidx; + size_t index = mi_segment_map_index_of(segment, &bitidx); + mi_assert_internal(index <= MI_SEGMENT_MAP_WSIZE); + if (index==MI_SEGMENT_MAP_WSIZE) return; + uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]); + uintptr_t newmask; + do { + newmask = (mask | ((uintptr_t)1 << bitidx)); + } while (!mi_atomic_cas_weak_release(&mi_segment_map[index], &mask, newmask)); +} + +void _mi_segment_map_freed_at(const mi_segment_t* segment) { + size_t bitidx; + size_t index = mi_segment_map_index_of(segment, &bitidx); + mi_assert_internal(index <= MI_SEGMENT_MAP_WSIZE); + if (index == MI_SEGMENT_MAP_WSIZE) return; + uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]); + uintptr_t newmask; + do { + newmask = (mask & ~((uintptr_t)1 << bitidx)); + } while (!mi_atomic_cas_weak_release(&mi_segment_map[index], &mask, newmask)); +} + +// Determine the segment belonging to a pointer or NULL if it is not in a valid segment. +static mi_segment_t* _mi_segment_of(const void* p) { + if (p == NULL) return NULL; + mi_segment_t* segment = _mi_ptr_segment(p); + mi_assert_internal(segment != NULL); + size_t bitidx; + size_t index = mi_segment_map_index_of(segment, &bitidx); + // fast path: for any pointer to valid small/medium/large object or first MI_SEGMENT_SIZE in huge + const uintptr_t mask = mi_atomic_load_relaxed(&mi_segment_map[index]); + if mi_likely((mask & ((uintptr_t)1 << bitidx)) != 0) { + return segment; // yes, allocated by us + } + if (index==MI_SEGMENT_MAP_WSIZE) return NULL; + + // TODO: maintain max/min allocated range for efficiency for more efficient rejection of invalid pointers? + + // search downwards for the first segment in case it is an interior pointer + // could be slow but searches in MI_INTPTR_SIZE * MI_SEGMENT_SIZE (512MiB) steps trough + // valid huge objects + // note: we could maintain a lowest index to speed up the path for invalid pointers? + size_t lobitidx; + size_t loindex; + uintptr_t lobits = mask & (((uintptr_t)1 << bitidx) - 1); + if (lobits != 0) { + loindex = index; + lobitidx = mi_bsr(lobits); // lobits != 0 + } + else if (index == 0) { + return NULL; + } + else { + mi_assert_internal(index > 0); + uintptr_t lomask = mask; + loindex = index; + do { + loindex--; + lomask = mi_atomic_load_relaxed(&mi_segment_map[loindex]); + } while (lomask != 0 && loindex > 0); + if (lomask == 0) return NULL; + lobitidx = mi_bsr(lomask); // lomask != 0 + } + mi_assert_internal(loindex < MI_SEGMENT_MAP_WSIZE); + // take difference as the addresses could be larger than the MAX_ADDRESS space. + size_t diff = (((index - loindex) * (8*MI_INTPTR_SIZE)) + bitidx - lobitidx) * MI_SEGMENT_SIZE; + segment = (mi_segment_t*)((uint8_t*)segment - diff); + + if (segment == NULL) return NULL; + mi_assert_internal((void*)segment < p); + bool cookie_ok = (_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(cookie_ok); + if mi_unlikely(!cookie_ok) return NULL; + if (((uint8_t*)segment + mi_segment_size(segment)) <= (uint8_t*)p) return NULL; // outside the range + mi_assert_internal(p >= (void*)segment && (uint8_t*)p < (uint8_t*)segment + mi_segment_size(segment)); + return segment; +} + +// Is this a valid pointer in our heap? +static bool mi_is_valid_pointer(const void* p) { + return ((_mi_segment_of(p) != NULL) || (_mi_arena_contains(p))); +} + +mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept { + return mi_is_valid_pointer(p); +} + +/* +// Return the full segment range belonging to a pointer +static void* mi_segment_range_of(const void* p, size_t* size) { + mi_segment_t* segment = _mi_segment_of(p); + if (segment == NULL) { + if (size != NULL) *size = 0; + return NULL; + } + else { + if (size != NULL) *size = segment->segment_size; + return segment; + } + mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld)); + mi_assert_internal(page == NULL || (mi_segment_page_size(_mi_page_segment(page)) - (MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= block_size); + mi_reset_delayed(tld); + mi_assert_internal(page == NULL || mi_page_not_in_queue(page, tld)); + return page; +} +*/ diff --git a/Objects/mimalloc/segment.c b/Objects/mimalloc/segment.c new file mode 100644 index 00000000000000..033e0f97c36c14 --- /dev/null +++ b/Objects/mimalloc/segment.c @@ -0,0 +1,1617 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" + +#include // memset +#include + +#define MI_PAGE_HUGE_ALIGN (256*1024) + +static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t* stats); + + +// ------------------------------------------------------------------- +// commit mask +// ------------------------------------------------------------------- + +static bool mi_commit_mask_all_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if ((commit->mask[i] & cm->mask[i]) != cm->mask[i]) return false; + } + return true; +} + +static bool mi_commit_mask_any_set(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + if ((commit->mask[i] & cm->mask[i]) != 0) return true; + } + return false; +} + +static void mi_commit_mask_create_intersect(const mi_commit_mask_t* commit, const mi_commit_mask_t* cm, mi_commit_mask_t* res) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + res->mask[i] = (commit->mask[i] & cm->mask[i]); + } +} + +static void mi_commit_mask_clear(mi_commit_mask_t* res, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + res->mask[i] &= ~(cm->mask[i]); + } +} + +static void mi_commit_mask_set(mi_commit_mask_t* res, const mi_commit_mask_t* cm) { + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + res->mask[i] |= cm->mask[i]; + } +} + +static void mi_commit_mask_create(size_t bitidx, size_t bitcount, mi_commit_mask_t* cm) { + mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS); + mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS); + if (bitcount == MI_COMMIT_MASK_BITS) { + mi_assert_internal(bitidx==0); + mi_commit_mask_create_full(cm); + } + else if (bitcount == 0) { + mi_commit_mask_create_empty(cm); + } + else { + mi_commit_mask_create_empty(cm); + size_t i = bitidx / MI_COMMIT_MASK_FIELD_BITS; + size_t ofs = bitidx % MI_COMMIT_MASK_FIELD_BITS; + while (bitcount > 0) { + mi_assert_internal(i < MI_COMMIT_MASK_FIELD_COUNT); + size_t avail = MI_COMMIT_MASK_FIELD_BITS - ofs; + size_t count = (bitcount > avail ? avail : bitcount); + size_t mask = (count >= MI_COMMIT_MASK_FIELD_BITS ? ~((size_t)0) : (((size_t)1 << count) - 1) << ofs); + cm->mask[i] = mask; + bitcount -= count; + ofs = 0; + i++; + } + } +} + +size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total) { + mi_assert_internal((total%MI_COMMIT_MASK_BITS)==0); + size_t count = 0; + for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) { + size_t mask = cm->mask[i]; + if (~mask == 0) { + count += MI_COMMIT_MASK_FIELD_BITS; + } + else { + for (; mask != 0; mask >>= 1) { // todo: use popcount + if ((mask&1)!=0) count++; + } + } + } + // we use total since for huge segments each commit bit may represent a larger size + return ((total / MI_COMMIT_MASK_BITS) * count); +} + + +size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx) { + size_t i = (*idx) / MI_COMMIT_MASK_FIELD_BITS; + size_t ofs = (*idx) % MI_COMMIT_MASK_FIELD_BITS; + size_t mask = 0; + // find first ones + while (i < MI_COMMIT_MASK_FIELD_COUNT) { + mask = cm->mask[i]; + mask >>= ofs; + if (mask != 0) { + while ((mask&1) == 0) { + mask >>= 1; + ofs++; + } + break; + } + i++; + ofs = 0; + } + if (i >= MI_COMMIT_MASK_FIELD_COUNT) { + // not found + *idx = MI_COMMIT_MASK_BITS; + return 0; + } + else { + // found, count ones + size_t count = 0; + *idx = (i*MI_COMMIT_MASK_FIELD_BITS) + ofs; + do { + mi_assert_internal(ofs < MI_COMMIT_MASK_FIELD_BITS && (mask&1) == 1); + do { + count++; + mask >>= 1; + } while ((mask&1) == 1); + if ((((*idx + count) % MI_COMMIT_MASK_FIELD_BITS) == 0)) { + i++; + if (i >= MI_COMMIT_MASK_FIELD_COUNT) break; + mask = cm->mask[i]; + ofs = 0; + } + } while ((mask&1) == 1); + mi_assert_internal(count > 0); + return count; + } +} + + +/* -------------------------------------------------------------------------------- + Segment allocation + + If a thread ends, it "abandons" pages with used blocks + and there is an abandoned segment list whose segments can + be reclaimed by still running threads, much like work-stealing. +-------------------------------------------------------------------------------- */ + + +/* ----------------------------------------------------------- + Slices +----------------------------------------------------------- */ + + +static const mi_slice_t* mi_segment_slices_end(const mi_segment_t* segment) { + return &segment->slices[segment->slice_entries]; +} + +static uint8_t* mi_slice_start(const mi_slice_t* slice) { + mi_segment_t* segment = _mi_ptr_segment(slice); + mi_assert_internal(slice >= segment->slices && slice < mi_segment_slices_end(segment)); + return ((uint8_t*)segment + ((slice - segment->slices)*MI_SEGMENT_SLICE_SIZE)); +} + + +/* ----------------------------------------------------------- + Bins +----------------------------------------------------------- */ +// Use bit scan forward to quickly find the first zero bit if it is available + +static inline size_t mi_slice_bin8(size_t slice_count) { + if (slice_count<=1) return slice_count; + mi_assert_internal(slice_count <= MI_SLICES_PER_SEGMENT); + slice_count--; + size_t s = mi_bsr(slice_count); // slice_count > 1 + if (s <= 2) return slice_count + 1; + size_t bin = ((s << 2) | ((slice_count >> (s - 2))&0x03)) - 4; + return bin; +} + +static inline size_t mi_slice_bin(size_t slice_count) { + mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_SEGMENT_SIZE); + mi_assert_internal(mi_slice_bin8(MI_SLICES_PER_SEGMENT) <= MI_SEGMENT_BIN_MAX); + size_t bin = mi_slice_bin8(slice_count); + mi_assert_internal(bin <= MI_SEGMENT_BIN_MAX); + return bin; +} + +static inline size_t mi_slice_index(const mi_slice_t* slice) { + mi_segment_t* segment = _mi_ptr_segment(slice); + ptrdiff_t index = slice - segment->slices; + mi_assert_internal(index >= 0 && index < (ptrdiff_t)segment->slice_entries); + return index; +} + + +/* ----------------------------------------------------------- + Slice span queues +----------------------------------------------------------- */ + +static void mi_span_queue_push(mi_span_queue_t* sq, mi_slice_t* slice) { + // todo: or push to the end? + mi_assert_internal(slice->prev == NULL && slice->next==NULL); + slice->prev = NULL; // paranoia + slice->next = sq->first; + sq->first = slice; + if (slice->next != NULL) slice->next->prev = slice; + else sq->last = slice; + slice->xblock_size = 0; // free +} + +static mi_span_queue_t* mi_span_queue_for(size_t slice_count, mi_segments_tld_t* tld) { + size_t bin = mi_slice_bin(slice_count); + mi_span_queue_t* sq = &tld->spans[bin]; + mi_assert_internal(sq->slice_count >= slice_count); + return sq; +} + +static void mi_span_queue_delete(mi_span_queue_t* sq, mi_slice_t* slice) { + mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0); + // should work too if the queue does not contain slice (which can happen during reclaim) + if (slice->prev != NULL) slice->prev->next = slice->next; + if (slice == sq->first) sq->first = slice->next; + if (slice->next != NULL) slice->next->prev = slice->prev; + if (slice == sq->last) sq->last = slice->prev; + slice->prev = NULL; + slice->next = NULL; + slice->xblock_size = 1; // no more free +} + + +/* ----------------------------------------------------------- + Invariant checking +----------------------------------------------------------- */ + +static bool mi_slice_is_used(const mi_slice_t* slice) { + return (slice->xblock_size > 0); +} + + +#if (MI_DEBUG>=3) +static bool mi_span_queue_contains(mi_span_queue_t* sq, mi_slice_t* slice) { + for (mi_slice_t* s = sq->first; s != NULL; s = s->next) { + if (s==slice) return true; + } + return false; +} + +static bool mi_segment_is_valid(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(segment != NULL); + mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(segment->abandoned <= segment->used); + mi_assert_internal(segment->thread_id == 0 || segment->thread_id == _mi_thread_id()); + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); // can only decommit committed blocks + //mi_assert_internal(segment->segment_info_size % MI_SEGMENT_SLICE_SIZE == 0); + mi_slice_t* slice = &segment->slices[0]; + const mi_slice_t* end = mi_segment_slices_end(segment); + size_t used_count = 0; + mi_span_queue_t* sq; + while(slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + size_t index = mi_slice_index(slice); + size_t maxindex = (index + slice->slice_count >= segment->slice_entries ? segment->slice_entries : index + slice->slice_count) - 1; + if (mi_slice_is_used(slice)) { // a page in use, we need at least MAX_SLICE_OFFSET valid back offsets + used_count++; + for (size_t i = 0; i <= MI_MAX_SLICE_OFFSET && index + i <= maxindex; i++) { + mi_assert_internal(segment->slices[index + i].slice_offset == i*sizeof(mi_slice_t)); + mi_assert_internal(i==0 || segment->slices[index + i].slice_count == 0); + mi_assert_internal(i==0 || segment->slices[index + i].xblock_size == 1); + } + // and the last entry as well (for coalescing) + const mi_slice_t* last = slice + slice->slice_count - 1; + if (last > slice && last < mi_segment_slices_end(segment)) { + mi_assert_internal(last->slice_offset == (slice->slice_count-1)*sizeof(mi_slice_t)); + mi_assert_internal(last->slice_count == 0); + mi_assert_internal(last->xblock_size == 1); + } + } + else { // free range of slices; only last slice needs a valid back offset + mi_slice_t* last = &segment->slices[maxindex]; + if (segment->kind != MI_SEGMENT_HUGE || slice->slice_count <= (segment->slice_entries - segment->segment_info_slices)) { + mi_assert_internal((uint8_t*)slice == (uint8_t*)last - last->slice_offset); + } + mi_assert_internal(slice == last || last->slice_count == 0 ); + mi_assert_internal(last->xblock_size == 0 || (segment->kind==MI_SEGMENT_HUGE && last->xblock_size==1)); + if (segment->kind != MI_SEGMENT_HUGE && segment->thread_id != 0) { // segment is not huge or abandoned + sq = mi_span_queue_for(slice->slice_count,tld); + mi_assert_internal(mi_span_queue_contains(sq,slice)); + } + } + slice = &segment->slices[maxindex+1]; + } + mi_assert_internal(slice == end); + mi_assert_internal(used_count == segment->used + 1); + return true; +} +#endif + +/* ----------------------------------------------------------- + Segment size calculations +----------------------------------------------------------- */ + +static size_t mi_segment_info_size(mi_segment_t* segment) { + return segment->segment_info_slices * MI_SEGMENT_SLICE_SIZE; +} + +static uint8_t* _mi_segment_page_start_from_slice(const mi_segment_t* segment, const mi_slice_t* slice, size_t xblock_size, size_t* page_size) +{ + ptrdiff_t idx = slice - segment->slices; + size_t psize = (size_t)slice->slice_count * MI_SEGMENT_SLICE_SIZE; + // make the start not OS page aligned for smaller blocks to avoid page/cache effects + // note: the offset must always be an xblock_size multiple since we assume small allocations + // are aligned (see `mi_heap_malloc_aligned`). + size_t start_offset = 0; + if (xblock_size >= MI_INTPTR_SIZE) { + if (xblock_size <= 64) { start_offset = 3*xblock_size; } + else if (xblock_size <= 512) { start_offset = xblock_size; } + } + if (page_size != NULL) { *page_size = psize - start_offset; } + return (uint8_t*)segment + ((idx*MI_SEGMENT_SLICE_SIZE) + start_offset); +} + +// Start of the page available memory; can be used on uninitialized pages +uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) +{ + const mi_slice_t* slice = mi_page_to_slice((mi_page_t*)page); + uint8_t* p = _mi_segment_page_start_from_slice(segment, slice, page->xblock_size, page_size); + mi_assert_internal(page->xblock_size > 0 || _mi_ptr_page(p) == page); + mi_assert_internal(_mi_ptr_segment(p) == segment); + return p; +} + + +static size_t mi_segment_calculate_slices(size_t required, size_t* pre_size, size_t* info_slices) { + size_t page_size = _mi_os_page_size(); + size_t isize = _mi_align_up(sizeof(mi_segment_t), page_size); + size_t guardsize = 0; + + if (MI_SECURE>0) { + // in secure mode, we set up a protected page in between the segment info + // and the page data (and one at the end of the segment) + guardsize = page_size; + if (required > 0) { + required = _mi_align_up(required, MI_SEGMENT_SLICE_SIZE) + page_size; + } + } + + if (pre_size != NULL) *pre_size = isize; + isize = _mi_align_up(isize + guardsize, MI_SEGMENT_SLICE_SIZE); + if (info_slices != NULL) *info_slices = isize / MI_SEGMENT_SLICE_SIZE; + size_t segment_size = (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + guardsize, MI_SEGMENT_SLICE_SIZE) ); + mi_assert_internal(segment_size % MI_SEGMENT_SLICE_SIZE == 0); + return (segment_size / MI_SEGMENT_SLICE_SIZE); +} + + +/* ---------------------------------------------------------------------------- +Segment caches +We keep a small segment cache per thread to increase local +reuse and avoid setting/clearing guard pages in secure mode. +------------------------------------------------------------------------------- */ + +static void mi_segments_track_size(long segment_size, mi_segments_tld_t* tld) { + if (segment_size>=0) _mi_stat_increase(&tld->stats->segments,1); + else _mi_stat_decrease(&tld->stats->segments,1); + tld->count += (segment_size >= 0 ? 1 : -1); + if (tld->count > tld->peak_count) tld->peak_count = tld->count; + tld->current_size += segment_size; + if (tld->current_size > tld->peak_size) tld->peak_size = tld->current_size; +} + +static void mi_segment_os_free(mi_segment_t* segment, mi_segments_tld_t* tld) { + segment->thread_id = 0; + _mi_segment_map_freed_at(segment); + mi_segments_track_size(-((long)mi_segment_size(segment)),tld); + if (MI_SECURE>0) { + // _mi_os_unprotect(segment, mi_segment_size(segment)); // ensure no more guard pages are set + // unprotect the guard pages; we cannot just unprotect the whole segment size as part may be decommitted + size_t os_pagesize = _mi_os_page_size(); + _mi_os_unprotect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize); + uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize; + _mi_os_unprotect(end, os_pagesize); + } + + // purge delayed decommits now? (no, leave it to the arena) + // mi_segment_try_purge(segment,true,tld->stats); + + const size_t size = mi_segment_size(segment); + const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size); + + _mi_abandoned_await_readers(); // wait until safe to free + _mi_arena_free(segment, mi_segment_size(segment), csize, segment->memid, tld->stats); +} + +// called by threads that are terminating +void _mi_segment_thread_collect(mi_segments_tld_t* tld) { + MI_UNUSED(tld); + // nothing to do +} + + +/* ----------------------------------------------------------- + Commit/Decommit ranges +----------------------------------------------------------- */ + +static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uint8_t* p, size_t size, uint8_t** start_p, size_t* full_size, mi_commit_mask_t* cm) { + mi_assert_internal(_mi_ptr_segment(p + 1) == segment); + mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); + mi_commit_mask_create_empty(cm); + if (size == 0 || size > MI_SEGMENT_SIZE || segment->kind == MI_SEGMENT_HUGE) return; + const size_t segstart = mi_segment_info_size(segment); + const size_t segsize = mi_segment_size(segment); + if (p >= (uint8_t*)segment + segsize) return; + + size_t pstart = (p - (uint8_t*)segment); + mi_assert_internal(pstart + size <= segsize); + + size_t start; + size_t end; + if (conservative) { + // decommit conservative + start = _mi_align_up(pstart, MI_COMMIT_SIZE); + end = _mi_align_down(pstart + size, MI_COMMIT_SIZE); + mi_assert_internal(start >= segstart); + mi_assert_internal(end <= segsize); + } + else { + // commit liberal + start = _mi_align_down(pstart, MI_MINIMAL_COMMIT_SIZE); + end = _mi_align_up(pstart + size, MI_MINIMAL_COMMIT_SIZE); + } + if (pstart >= segstart && start < segstart) { // note: the mask is also calculated for an initial commit of the info area + start = segstart; + } + if (end > segsize) { + end = segsize; + } + + mi_assert_internal(start <= pstart && (pstart + size) <= end); + mi_assert_internal(start % MI_COMMIT_SIZE==0 && end % MI_COMMIT_SIZE == 0); + *start_p = (uint8_t*)segment + start; + *full_size = (end > start ? end - start : 0); + if (*full_size == 0) return; + + size_t bitidx = start / MI_COMMIT_SIZE; + mi_assert_internal(bitidx < MI_COMMIT_MASK_BITS); + + size_t bitcount = *full_size / MI_COMMIT_SIZE; // can be 0 + if (bitidx + bitcount > MI_COMMIT_MASK_BITS) { + _mi_warning_message("commit mask overflow: idx=%zu count=%zu start=%zx end=%zx p=0x%p size=%zu fullsize=%zu\n", bitidx, bitcount, start, end, p, size, *full_size); + } + mi_assert_internal((bitidx + bitcount) <= MI_COMMIT_MASK_BITS); + mi_commit_mask_create(bitidx, bitcount, cm); +} + +static bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); + + // commit liberal + uint8_t* start = NULL; + size_t full_size = 0; + mi_commit_mask_t mask; + mi_segment_commit_mask(segment, false /* conservative? */, p, size, &start, &full_size, &mask); + if (mi_commit_mask_is_empty(&mask) || full_size == 0) return true; + + if (!mi_commit_mask_all_set(&segment->commit_mask, &mask)) { + // committing + bool is_zero = false; + mi_commit_mask_t cmask; + mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); + _mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap + if (!_mi_os_commit(start, full_size, &is_zero, stats)) return false; + mi_commit_mask_set(&segment->commit_mask, &mask); + } + + // increase purge expiration when using part of delayed purges -- we assume more allocations are coming soon. + if (mi_commit_mask_any_set(&segment->purge_mask, &mask)) { + segment->purge_expire = _mi_clock_now() + mi_option_get(mi_option_purge_delay); + } + + // always clear any delayed purges in our range (as they are either committed now) + mi_commit_mask_clear(&segment->purge_mask, &mask); + return true; +} + +static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); + // note: assumes commit_mask is always full for huge segments as otherwise the commit mask bits can overflow + if (mi_commit_mask_is_full(&segment->commit_mask) && mi_commit_mask_is_empty(&segment->purge_mask)) return true; // fully committed + mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); + return mi_segment_commit(segment, p, size, stats); +} + +static bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask)); + if (!segment->allow_purge) return true; + + // purge conservative + uint8_t* start = NULL; + size_t full_size = 0; + mi_commit_mask_t mask; + mi_segment_commit_mask(segment, true /* conservative? */, p, size, &start, &full_size, &mask); + if (mi_commit_mask_is_empty(&mask) || full_size==0) return true; + + if (mi_commit_mask_any_set(&segment->commit_mask, &mask)) { + // purging + mi_assert_internal((void*)start != (void*)segment); + mi_assert_internal(segment->allow_decommit); + const bool decommitted = _mi_os_purge(start, full_size, stats); // reset or decommit + if (decommitted) { + mi_commit_mask_t cmask; + mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); + _mi_stat_increase(&_mi_stats_main.committed, full_size - _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for double counting + mi_commit_mask_clear(&segment->commit_mask, &mask); + } + } + + // always clear any scheduled purges in our range + mi_commit_mask_clear(&segment->purge_mask, &mask); + return true; +} + +static void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) { + if (!segment->allow_purge) return; + + if (mi_option_get(mi_option_purge_delay) == 0) { + mi_segment_purge(segment, p, size, stats); + } + else { + // register for future purge in the purge mask + uint8_t* start = NULL; + size_t full_size = 0; + mi_commit_mask_t mask; + mi_segment_commit_mask(segment, true /*conservative*/, p, size, &start, &full_size, &mask); + if (mi_commit_mask_is_empty(&mask) || full_size==0) return; + + // update delayed commit + mi_assert_internal(segment->purge_expire > 0 || mi_commit_mask_is_empty(&segment->purge_mask)); + mi_commit_mask_t cmask; + mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask); // only purge what is committed; span_free may try to decommit more + mi_commit_mask_set(&segment->purge_mask, &cmask); + mi_msecs_t now = _mi_clock_now(); + if (segment->purge_expire == 0) { + // no previous purgess, initialize now + segment->purge_expire = now + mi_option_get(mi_option_purge_delay); + } + else if (segment->purge_expire <= now) { + // previous purge mask already expired + if (segment->purge_expire + mi_option_get(mi_option_purge_extend_delay) <= now) { + mi_segment_try_purge(segment, true, stats); + } + else { + segment->purge_expire = now + mi_option_get(mi_option_purge_extend_delay); // (mi_option_get(mi_option_purge_delay) / 8); // wait a tiny bit longer in case there is a series of free's + } + } + else { + // previous purge mask is not yet expired, increase the expiration by a bit. + segment->purge_expire += mi_option_get(mi_option_purge_extend_delay); + } + } +} + +static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t* stats) { + if (!segment->allow_purge || mi_commit_mask_is_empty(&segment->purge_mask)) return; + mi_msecs_t now = _mi_clock_now(); + if (!force && now < segment->purge_expire) return; + + mi_commit_mask_t mask = segment->purge_mask; + segment->purge_expire = 0; + mi_commit_mask_create_empty(&segment->purge_mask); + + size_t idx; + size_t count; + mi_commit_mask_foreach(&mask, idx, count) { + // if found, decommit that sequence + if (count > 0) { + uint8_t* p = (uint8_t*)segment + (idx*MI_COMMIT_SIZE); + size_t size = count * MI_COMMIT_SIZE; + mi_segment_purge(segment, p, size, stats); + } + } + mi_commit_mask_foreach_end() + mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask)); +} + + +/* ----------------------------------------------------------- + Span free +----------------------------------------------------------- */ + +static bool mi_segment_is_abandoned(mi_segment_t* segment) { + return (segment->thread_id == 0); +} + +// note: can be called on abandoned segments +static void mi_segment_span_free(mi_segment_t* segment, size_t slice_index, size_t slice_count, bool allow_purge, mi_segments_tld_t* tld) { + mi_assert_internal(slice_index < segment->slice_entries); + mi_span_queue_t* sq = (segment->kind == MI_SEGMENT_HUGE || mi_segment_is_abandoned(segment) + ? NULL : mi_span_queue_for(slice_count,tld)); + if (slice_count==0) slice_count = 1; + mi_assert_internal(slice_index + slice_count - 1 < segment->slice_entries); + + // set first and last slice (the intermediates can be undetermined) + mi_slice_t* slice = &segment->slices[slice_index]; + slice->slice_count = (uint32_t)slice_count; + mi_assert_internal(slice->slice_count == slice_count); // no overflow? + slice->slice_offset = 0; + if (slice_count > 1) { + mi_slice_t* last = &segment->slices[slice_index + slice_count - 1]; + last->slice_count = 0; + last->slice_offset = (uint32_t)(sizeof(mi_page_t)*(slice_count - 1)); + last->xblock_size = 0; + } + + // perhaps decommit + if (allow_purge) { + mi_segment_schedule_purge(segment, mi_slice_start(slice), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats); + } + + // and push it on the free page queue (if it was not a huge page) + if (sq != NULL) mi_span_queue_push( sq, slice ); + else slice->xblock_size = 0; // mark huge page as free anyways +} + +/* +// called from reclaim to add existing free spans +static void mi_segment_span_add_free(mi_slice_t* slice, mi_segments_tld_t* tld) { + mi_segment_t* segment = _mi_ptr_segment(slice); + mi_assert_internal(slice->xblock_size==0 && slice->slice_count>0 && slice->slice_offset==0); + size_t slice_index = mi_slice_index(slice); + mi_segment_span_free(segment,slice_index,slice->slice_count,tld); +} +*/ + +static void mi_segment_span_remove_from_queue(mi_slice_t* slice, mi_segments_tld_t* tld) { + mi_assert_internal(slice->slice_count > 0 && slice->slice_offset==0 && slice->xblock_size==0); + mi_assert_internal(_mi_ptr_segment(slice)->kind != MI_SEGMENT_HUGE); + mi_span_queue_t* sq = mi_span_queue_for(slice->slice_count, tld); + mi_span_queue_delete(sq, slice); +} + +// note: can be called on abandoned segments +static mi_slice_t* mi_segment_span_free_coalesce(mi_slice_t* slice, mi_segments_tld_t* tld) { + mi_assert_internal(slice != NULL && slice->slice_count > 0 && slice->slice_offset == 0); + mi_segment_t* segment = _mi_ptr_segment(slice); + bool is_abandoned = mi_segment_is_abandoned(segment); + + // for huge pages, just mark as free but don't add to the queues + if (segment->kind == MI_SEGMENT_HUGE) { + // issue #691: segment->used can be 0 if the huge page block was freed while abandoned (reclaim will get here in that case) + mi_assert_internal((segment->used==0 && slice->xblock_size==0) || segment->used == 1); // decreased right after this call in `mi_segment_page_clear` + slice->xblock_size = 0; // mark as free anyways + // we should mark the last slice `xblock_size=0` now to maintain invariants but we skip it to + // avoid a possible cache miss (and the segment is about to be freed) + return slice; + } + + // otherwise coalesce the span and add to the free span queues + size_t slice_count = slice->slice_count; + mi_slice_t* next = slice + slice->slice_count; + mi_assert_internal(next <= mi_segment_slices_end(segment)); + if (next < mi_segment_slices_end(segment) && next->xblock_size==0) { + // free next block -- remove it from free and merge + mi_assert_internal(next->slice_count > 0 && next->slice_offset==0); + slice_count += next->slice_count; // extend + if (!is_abandoned) { mi_segment_span_remove_from_queue(next, tld); } + } + if (slice > segment->slices) { + mi_slice_t* prev = mi_slice_first(slice - 1); + mi_assert_internal(prev >= segment->slices); + if (prev->xblock_size==0) { + // free previous slice -- remove it from free and merge + mi_assert_internal(prev->slice_count > 0 && prev->slice_offset==0); + slice_count += prev->slice_count; + if (!is_abandoned) { mi_segment_span_remove_from_queue(prev, tld); } + slice = prev; + } + } + + // and add the new free page + mi_segment_span_free(segment, mi_slice_index(slice), slice_count, true, tld); + return slice; +} + + + +/* ----------------------------------------------------------- + Page allocation +----------------------------------------------------------- */ + +// Note: may still return NULL if committing the memory failed +static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) { + mi_assert_internal(slice_index < segment->slice_entries); + mi_slice_t* const slice = &segment->slices[slice_index]; + mi_assert_internal(slice->xblock_size==0 || slice->xblock_size==1); + + // commit before changing the slice data + if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats)) { + return NULL; // commit failed! + } + + // convert the slices to a page + slice->slice_offset = 0; + slice->slice_count = (uint32_t)slice_count; + mi_assert_internal(slice->slice_count == slice_count); + const size_t bsize = slice_count * MI_SEGMENT_SLICE_SIZE; + slice->xblock_size = (uint32_t)(bsize >= MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : bsize); + mi_page_t* page = mi_slice_to_page(slice); + mi_assert_internal(mi_page_block_size(page) == bsize); + + // set slice back pointers for the first MI_MAX_SLICE_OFFSET entries + size_t extra = slice_count-1; + if (extra > MI_MAX_SLICE_OFFSET) extra = MI_MAX_SLICE_OFFSET; + if (slice_index + extra >= segment->slice_entries) extra = segment->slice_entries - slice_index - 1; // huge objects may have more slices than avaiable entries in the segment->slices + + mi_slice_t* slice_next = slice + 1; + for (size_t i = 1; i <= extra; i++, slice_next++) { + slice_next->slice_offset = (uint32_t)(sizeof(mi_slice_t)*i); + slice_next->slice_count = 0; + slice_next->xblock_size = 1; + } + + // and also for the last one (if not set already) (the last one is needed for coalescing and for large alignments) + // note: the cast is needed for ubsan since the index can be larger than MI_SLICES_PER_SEGMENT for huge allocations (see #543) + mi_slice_t* last = slice + slice_count - 1; + mi_slice_t* end = (mi_slice_t*)mi_segment_slices_end(segment); + if (last > end) last = end; + if (last > slice) { + last->slice_offset = (uint32_t)(sizeof(mi_slice_t) * (last - slice)); + last->slice_count = 0; + last->xblock_size = 1; + } + + // and initialize the page + page->is_committed = true; + segment->used++; + return page; +} + +static void mi_segment_slice_split(mi_segment_t* segment, mi_slice_t* slice, size_t slice_count, mi_segments_tld_t* tld) { + mi_assert_internal(_mi_ptr_segment(slice) == segment); + mi_assert_internal(slice->slice_count >= slice_count); + mi_assert_internal(slice->xblock_size > 0); // no more in free queue + if (slice->slice_count <= slice_count) return; + mi_assert_internal(segment->kind != MI_SEGMENT_HUGE); + size_t next_index = mi_slice_index(slice) + slice_count; + size_t next_count = slice->slice_count - slice_count; + mi_segment_span_free(segment, next_index, next_count, false /* don't purge left-over part */, tld); + slice->slice_count = (uint32_t)slice_count; +} + +static mi_page_t* mi_segments_page_find_and_allocate(size_t slice_count, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld) { + mi_assert_internal(slice_count*MI_SEGMENT_SLICE_SIZE <= MI_LARGE_OBJ_SIZE_MAX); + // search from best fit up + mi_span_queue_t* sq = mi_span_queue_for(slice_count, tld); + if (slice_count == 0) slice_count = 1; + while (sq <= &tld->spans[MI_SEGMENT_BIN_MAX]) { + for (mi_slice_t* slice = sq->first; slice != NULL; slice = slice->next) { + if (slice->slice_count >= slice_count) { + // found one + mi_segment_t* segment = _mi_ptr_segment(slice); + if (_mi_arena_memid_is_suitable(segment->memid, req_arena_id)) { + // found a suitable page span + mi_span_queue_delete(sq, slice); + + if (slice->slice_count > slice_count) { + mi_segment_slice_split(segment, slice, slice_count, tld); + } + mi_assert_internal(slice != NULL && slice->slice_count == slice_count && slice->xblock_size > 0); + mi_page_t* page = mi_segment_span_allocate(segment, mi_slice_index(slice), slice->slice_count, tld); + if (page == NULL) { + // commit failed; return NULL but first restore the slice + mi_segment_span_free_coalesce(slice, tld); + return NULL; + } + return page; + } + } + } + sq++; + } + // could not find a page.. + return NULL; +} + + +/* ----------------------------------------------------------- + Segment allocation +----------------------------------------------------------- */ + +static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment, bool eager_delayed, mi_arena_id_t req_arena_id, + size_t* psegment_slices, size_t* ppre_size, size_t* pinfo_slices, + bool commit, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) + +{ + mi_memid_t memid; + bool allow_large = (!eager_delayed && (MI_SECURE == 0)); // only allow large OS pages once we are no longer lazy + size_t align_offset = 0; + size_t alignment = MI_SEGMENT_ALIGN; + + if (page_alignment > 0) { + // mi_assert_internal(huge_page != NULL); + mi_assert_internal(page_alignment >= MI_SEGMENT_ALIGN); + alignment = page_alignment; + const size_t info_size = (*pinfo_slices) * MI_SEGMENT_SLICE_SIZE; + align_offset = _mi_align_up( info_size, MI_SEGMENT_ALIGN ); + const size_t extra = align_offset - info_size; + // recalculate due to potential guard pages + *psegment_slices = mi_segment_calculate_slices(required + extra, ppre_size, pinfo_slices); + } + + const size_t segment_size = (*psegment_slices) * MI_SEGMENT_SLICE_SIZE; + mi_segment_t* segment = (mi_segment_t*)_mi_arena_alloc_aligned(segment_size, alignment, align_offset, commit, allow_large, req_arena_id, &memid, os_tld); + if (segment == NULL) { + return NULL; // failed to allocate + } + + // ensure metadata part of the segment is committed + mi_commit_mask_t commit_mask; + if (memid.initially_committed) { + mi_commit_mask_create_full(&commit_mask); + } + else { + // at least commit the info slices + const size_t commit_needed = _mi_divide_up((*pinfo_slices)*MI_SEGMENT_SLICE_SIZE, MI_COMMIT_SIZE); + mi_assert_internal(commit_needed>0); + mi_commit_mask_create(0, commit_needed, &commit_mask); + mi_assert_internal(commit_needed*MI_COMMIT_SIZE >= (*pinfo_slices)*MI_SEGMENT_SLICE_SIZE); + if (!_mi_os_commit(segment, commit_needed*MI_COMMIT_SIZE, NULL, tld->stats)) { + _mi_arena_free(segment,segment_size,0,memid,tld->stats); + return NULL; + } + } + mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0); + + segment->memid = memid; + segment->allow_decommit = !memid.is_pinned; + segment->allow_purge = segment->allow_decommit && (mi_option_get(mi_option_purge_delay) >= 0); + segment->segment_size = segment_size; + segment->commit_mask = commit_mask; + segment->purge_expire = 0; + mi_commit_mask_create_empty(&segment->purge_mask); + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); // tsan + + mi_segments_track_size((long)(segment_size), tld); + _mi_segment_map_allocated_at(segment); + return segment; +} + + +// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` . +static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld, mi_page_t** huge_page) +{ + mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL)); + + // calculate needed sizes first + size_t info_slices; + size_t pre_size; + size_t segment_slices = mi_segment_calculate_slices(required, &pre_size, &info_slices); + + // Commit eagerly only if not the first N lazy segments (to reduce impact of many threads that allocate just a little) + const bool eager_delay = (// !_mi_os_has_overcommit() && // never delay on overcommit systems + _mi_current_thread_count() > 1 && // do not delay for the first N threads + tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay)); + const bool eager = !eager_delay && mi_option_is_enabled(mi_option_eager_commit); + bool commit = eager || (required > 0); + + // Allocate the segment from the OS + mi_segment_t* segment = mi_segment_os_alloc(required, page_alignment, eager_delay, req_arena_id, + &segment_slices, &pre_size, &info_slices, commit, tld, os_tld); + if (segment == NULL) return NULL; + + // zero the segment info? -- not always needed as it may be zero initialized from the OS + if (!segment->memid.initially_zero) { + ptrdiff_t ofs = offsetof(mi_segment_t, next); + size_t prefix = offsetof(mi_segment_t, slices) - ofs; + size_t zsize = prefix + (sizeof(mi_slice_t) * (segment_slices + 1)); // one more + _mi_memzero((uint8_t*)segment + ofs, zsize); + } + + // initialize the rest of the segment info + const size_t slice_entries = (segment_slices > MI_SLICES_PER_SEGMENT ? MI_SLICES_PER_SEGMENT : segment_slices); + segment->segment_slices = segment_slices; + segment->segment_info_slices = info_slices; + segment->thread_id = _mi_thread_id(); + segment->cookie = _mi_ptr_cookie(segment); + segment->slice_entries = slice_entries; + segment->kind = (required == 0 ? MI_SEGMENT_NORMAL : MI_SEGMENT_HUGE); + + // _mi_memzero(segment->slices, sizeof(mi_slice_t)*(info_slices+1)); + _mi_stat_increase(&tld->stats->page_committed, mi_segment_info_size(segment)); + + // set up guard pages + size_t guard_slices = 0; + if (MI_SECURE>0) { + // in secure mode, we set up a protected page in between the segment info + // and the page data, and at the end of the segment. + size_t os_pagesize = _mi_os_page_size(); + mi_assert_internal(mi_segment_info_size(segment) - os_pagesize >= pre_size); + _mi_os_protect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize); + uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize; + mi_segment_ensure_committed(segment, end, os_pagesize, tld->stats); + _mi_os_protect(end, os_pagesize); + if (slice_entries == segment_slices) segment->slice_entries--; // don't use the last slice :-( + guard_slices = 1; + } + + // reserve first slices for segment info + mi_page_t* page0 = mi_segment_span_allocate(segment, 0, info_slices, tld); + mi_assert_internal(page0!=NULL); if (page0==NULL) return NULL; // cannot fail as we always commit in advance + mi_assert_internal(segment->used == 1); + segment->used = 0; // don't count our internal slices towards usage + + // initialize initial free pages + if (segment->kind == MI_SEGMENT_NORMAL) { // not a huge page + mi_assert_internal(huge_page==NULL); + mi_segment_span_free(segment, info_slices, segment->slice_entries - info_slices, false /* don't purge */, tld); + } + else { + mi_assert_internal(huge_page!=NULL); + mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask)); + mi_assert_internal(mi_commit_mask_is_full(&segment->commit_mask)); + *huge_page = mi_segment_span_allocate(segment, info_slices, segment_slices - info_slices - guard_slices, tld); + mi_assert_internal(*huge_page != NULL); // cannot fail as we commit in advance + } + + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + return segment; +} + + +static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) { + MI_UNUSED(force); + mi_assert_internal(segment != NULL); + mi_assert_internal(segment->next == NULL); + mi_assert_internal(segment->used == 0); + + // Remove the free pages + mi_slice_t* slice = &segment->slices[0]; + const mi_slice_t* end = mi_segment_slices_end(segment); + #if MI_DEBUG>1 + size_t page_count = 0; + #endif + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + mi_assert_internal(mi_slice_index(slice)==0 || slice->xblock_size == 0); // no more used pages .. + if (slice->xblock_size == 0 && segment->kind != MI_SEGMENT_HUGE) { + mi_segment_span_remove_from_queue(slice, tld); + } + #if MI_DEBUG>1 + page_count++; + #endif + slice = slice + slice->slice_count; + } + mi_assert_internal(page_count == 2); // first page is allocated by the segment itself + + // stats + _mi_stat_decrease(&tld->stats->page_committed, mi_segment_info_size(segment)); + + // return it to the OS + mi_segment_os_free(segment, tld); +} + + +/* ----------------------------------------------------------- + Page Free +----------------------------------------------------------- */ + +static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld); + +// note: can be called on abandoned pages +static mi_slice_t* mi_segment_page_clear(mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert_internal(page->xblock_size > 0); + mi_assert_internal(mi_page_all_free(page)); + mi_segment_t* segment = _mi_ptr_segment(page); + mi_assert_internal(segment->used > 0); + + size_t inuse = page->capacity * mi_page_block_size(page); + _mi_stat_decrease(&tld->stats->page_committed, inuse); + _mi_stat_decrease(&tld->stats->pages, 1); + + // reset the page memory to reduce memory pressure? + if (segment->allow_decommit && mi_option_is_enabled(mi_option_deprecated_page_reset)) { + size_t psize; + uint8_t* start = _mi_page_start(segment, page, &psize); + _mi_os_reset(start, psize, tld->stats); + } + + // zero the page data, but not the segment fields + page->is_zero_init = false; + ptrdiff_t ofs = offsetof(mi_page_t, capacity); + _mi_memzero((uint8_t*)page + ofs, sizeof(*page) - ofs); + page->xblock_size = 1; + + // and free it + mi_slice_t* slice = mi_segment_span_free_coalesce(mi_page_to_slice(page), tld); + segment->used--; + // cannot assert segment valid as it is called during reclaim + // mi_assert_expensive(mi_segment_is_valid(segment, tld)); + return slice; +} + +void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld) +{ + mi_assert(page != NULL); + + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + + // mark it as free now + mi_segment_page_clear(page, tld); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + + if (segment->used == 0) { + // no more used pages; remove from the free list and free the segment + mi_segment_free(segment, force, tld); + } + else if (segment->used == segment->abandoned) { + // only abandoned pages; remove from free list and abandon + mi_segment_abandon(segment,tld); + } +} + + +/* ----------------------------------------------------------- +Abandonment + +When threads terminate, they can leave segments with +live blocks (reachable through other threads). Such segments +are "abandoned" and will be reclaimed by other threads to +reuse their pages and/or free them eventually + +We maintain a global list of abandoned segments that are +reclaimed on demand. Since this is shared among threads +the implementation needs to avoid the A-B-A problem on +popping abandoned segments: +We use tagged pointers to avoid accidentally identifying +reused segments, much like stamped references in Java. +Secondly, we maintain a reader counter to avoid resetting +or decommitting segments that have a pending read operation. + +Note: the current implementation is one possible design; +another way might be to keep track of abandoned segments +in the arenas/segment_cache's. This would have the advantage of keeping +all concurrent code in one place and not needing to deal +with ABA issues. The drawback is that it is unclear how to +scan abandoned segments efficiently in that case as they +would be spread among all other segments in the arenas. +----------------------------------------------------------- */ + +// Use the bottom 20-bits (on 64-bit) of the aligned segment pointers +// to put in a tag that increments on update to avoid the A-B-A problem. +#define MI_TAGGED_MASK MI_SEGMENT_MASK +typedef uintptr_t mi_tagged_segment_t; + +static mi_segment_t* mi_tagged_segment_ptr(mi_tagged_segment_t ts) { + return (mi_segment_t*)(ts & ~MI_TAGGED_MASK); +} + +static mi_tagged_segment_t mi_tagged_segment(mi_segment_t* segment, mi_tagged_segment_t ts) { + mi_assert_internal(((uintptr_t)segment & MI_TAGGED_MASK) == 0); + uintptr_t tag = ((ts & MI_TAGGED_MASK) + 1) & MI_TAGGED_MASK; + return ((uintptr_t)segment | tag); +} + +// This is a list of visited abandoned pages that were full at the time. +// this list migrates to `abandoned` when that becomes NULL. The use of +// this list reduces contention and the rate at which segments are visited. +static mi_decl_cache_align _Atomic(mi_segment_t*) abandoned_visited; // = NULL + +// The abandoned page list (tagged as it supports pop) +static mi_decl_cache_align _Atomic(mi_tagged_segment_t) abandoned; // = NULL + +// Maintain these for debug purposes (these counts may be a bit off) +static mi_decl_cache_align _Atomic(size_t) abandoned_count; +static mi_decl_cache_align _Atomic(size_t) abandoned_visited_count; + +// We also maintain a count of current readers of the abandoned list +// in order to prevent resetting/decommitting segment memory if it might +// still be read. +static mi_decl_cache_align _Atomic(size_t) abandoned_readers; // = 0 + +// Push on the visited list +static void mi_abandoned_visited_push(mi_segment_t* segment) { + mi_assert_internal(segment->thread_id == 0); + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t,&segment->abandoned_next) == NULL); + mi_assert_internal(segment->next == NULL); + mi_assert_internal(segment->used > 0); + mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited); + do { + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, anext); + } while (!mi_atomic_cas_ptr_weak_release(mi_segment_t, &abandoned_visited, &anext, segment)); + mi_atomic_increment_relaxed(&abandoned_visited_count); +} + +// Move the visited list to the abandoned list. +static bool mi_abandoned_visited_revisit(void) +{ + // quick check if the visited list is empty + if (mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited) == NULL) return false; + + // grab the whole visited list + mi_segment_t* first = mi_atomic_exchange_ptr_acq_rel(mi_segment_t, &abandoned_visited, NULL); + if (first == NULL) return false; + + // first try to swap directly if the abandoned list happens to be NULL + mi_tagged_segment_t afirst; + mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); + if (mi_tagged_segment_ptr(ts)==NULL) { + size_t count = mi_atomic_load_relaxed(&abandoned_visited_count); + afirst = mi_tagged_segment(first, ts); + if (mi_atomic_cas_strong_acq_rel(&abandoned, &ts, afirst)) { + mi_atomic_add_relaxed(&abandoned_count, count); + mi_atomic_sub_relaxed(&abandoned_visited_count, count); + return true; + } + } + + // find the last element of the visited list: O(n) + mi_segment_t* last = first; + mi_segment_t* next; + while ((next = mi_atomic_load_ptr_relaxed(mi_segment_t, &last->abandoned_next)) != NULL) { + last = next; + } + + // and atomically prepend to the abandoned list + // (no need to increase the readers as we don't access the abandoned segments) + mi_tagged_segment_t anext = mi_atomic_load_relaxed(&abandoned); + size_t count; + do { + count = mi_atomic_load_relaxed(&abandoned_visited_count); + mi_atomic_store_ptr_release(mi_segment_t, &last->abandoned_next, mi_tagged_segment_ptr(anext)); + afirst = mi_tagged_segment(first, anext); + } while (!mi_atomic_cas_weak_release(&abandoned, &anext, afirst)); + mi_atomic_add_relaxed(&abandoned_count, count); + mi_atomic_sub_relaxed(&abandoned_visited_count, count); + return true; +} + +// Push on the abandoned list. +static void mi_abandoned_push(mi_segment_t* segment) { + mi_assert_internal(segment->thread_id == 0); + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); + mi_assert_internal(segment->next == NULL); + mi_assert_internal(segment->used > 0); + mi_tagged_segment_t next; + mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); + do { + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, mi_tagged_segment_ptr(ts)); + next = mi_tagged_segment(segment, ts); + } while (!mi_atomic_cas_weak_release(&abandoned, &ts, next)); + mi_atomic_increment_relaxed(&abandoned_count); +} + +// Wait until there are no more pending reads on segments that used to be in the abandoned list +// called for example from `arena.c` before decommitting +void _mi_abandoned_await_readers(void) { + size_t n; + do { + n = mi_atomic_load_acquire(&abandoned_readers); + if (n != 0) mi_atomic_yield(); + } while (n != 0); +} + +// Pop from the abandoned list +static mi_segment_t* mi_abandoned_pop(void) { + mi_segment_t* segment; + // Check efficiently if it is empty (or if the visited list needs to be moved) + mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); + segment = mi_tagged_segment_ptr(ts); + if mi_likely(segment == NULL) { + if mi_likely(!mi_abandoned_visited_revisit()) { // try to swap in the visited list on NULL + return NULL; + } + } + + // Do a pop. We use a reader count to prevent + // a segment to be decommitted while a read is still pending, + // and a tagged pointer to prevent A-B-A link corruption. + // (this is called from `region.c:_mi_mem_free` for example) + mi_atomic_increment_relaxed(&abandoned_readers); // ensure no segment gets decommitted + mi_tagged_segment_t next = 0; + ts = mi_atomic_load_acquire(&abandoned); + do { + segment = mi_tagged_segment_ptr(ts); + if (segment != NULL) { + mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next); + next = mi_tagged_segment(anext, ts); // note: reads the segment's `abandoned_next` field so should not be decommitted + } + } while (segment != NULL && !mi_atomic_cas_weak_acq_rel(&abandoned, &ts, next)); + mi_atomic_decrement_relaxed(&abandoned_readers); // release reader lock + if (segment != NULL) { + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); + mi_atomic_decrement_relaxed(&abandoned_count); + } + return segment; +} + +/* ----------------------------------------------------------- + Abandon segment/page +----------------------------------------------------------- */ + +static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(segment->used == segment->abandoned); + mi_assert_internal(segment->used > 0); + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); + mi_assert_internal(segment->abandoned_visits == 0); + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + + // remove the free pages from the free page queues + mi_slice_t* slice = &segment->slices[0]; + const mi_slice_t* end = mi_segment_slices_end(segment); + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + if (slice->xblock_size == 0) { // a free page + mi_segment_span_remove_from_queue(slice,tld); + slice->xblock_size = 0; // but keep it free + } + slice = slice + slice->slice_count; + } + + // perform delayed decommits (forcing is much slower on mstress) + mi_segment_try_purge(segment, mi_option_is_enabled(mi_option_abandoned_page_purge) /* force? */, tld->stats); + + // all pages in the segment are abandoned; add it to the abandoned list + _mi_stat_increase(&tld->stats->segments_abandoned, 1); + mi_segments_track_size(-((long)mi_segment_size(segment)), tld); + segment->thread_id = 0; + mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); + segment->abandoned_visits = 1; // from 0 to 1 to signify it is abandoned + mi_abandoned_push(segment); +} + +void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert(page != NULL); + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_assert_internal(mi_page_heap(page) == NULL); + mi_segment_t* segment = _mi_page_segment(page); + + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + segment->abandoned++; + + _mi_stat_increase(&tld->stats->pages_abandoned, 1); + mi_assert_internal(segment->abandoned <= segment->used); + if (segment->used == segment->abandoned) { + // all pages are abandoned, abandon the entire segment + mi_segment_abandon(segment, tld); + } +} + +/* ----------------------------------------------------------- + Reclaim abandoned pages +----------------------------------------------------------- */ + +static mi_slice_t* mi_slices_start_iterate(mi_segment_t* segment, const mi_slice_t** end) { + mi_slice_t* slice = &segment->slices[0]; + *end = mi_segment_slices_end(segment); + mi_assert_internal(slice->slice_count>0 && slice->xblock_size>0); // segment allocated page + slice = slice + slice->slice_count; // skip the first segment allocated page + return slice; +} + +// Possibly free pages and check if free space is available +static bool mi_segment_check_free(mi_segment_t* segment, size_t slices_needed, size_t block_size, mi_segments_tld_t* tld) +{ + mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); + mi_assert_internal(mi_segment_is_abandoned(segment)); + bool has_page = false; + + // for all slices + const mi_slice_t* end; + mi_slice_t* slice = mi_slices_start_iterate(segment, &end); + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + if (mi_slice_is_used(slice)) { // used page + // ensure used count is up to date and collect potential concurrent frees + mi_page_t* const page = mi_slice_to_page(slice); + _mi_page_free_collect(page, false); + if (mi_page_all_free(page)) { + // if this page is all free now, free it without adding to any queues (yet) + mi_assert_internal(page->next == NULL && page->prev==NULL); + _mi_stat_decrease(&tld->stats->pages_abandoned, 1); + segment->abandoned--; + slice = mi_segment_page_clear(page, tld); // re-assign slice due to coalesce! + mi_assert_internal(!mi_slice_is_used(slice)); + if (slice->slice_count >= slices_needed) { + has_page = true; + } + } + else { + if (page->xblock_size == block_size && mi_page_has_any_available(page)) { + // a page has available free blocks of the right size + has_page = true; + } + } + } + else { + // empty span + if (slice->slice_count >= slices_needed) { + has_page = true; + } + } + slice = slice + slice->slice_count; + } + return has_page; +} + +// Reclaim an abandoned segment; returns NULL if the segment was freed +// set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full. +static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) { + mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; } + + segment->thread_id = _mi_thread_id(); + segment->abandoned_visits = 0; + mi_segments_track_size((long)mi_segment_size(segment), tld); + mi_assert_internal(segment->next == NULL); + _mi_stat_decrease(&tld->stats->segments_abandoned, 1); + + // for all slices + const mi_slice_t* end; + mi_slice_t* slice = mi_slices_start_iterate(segment, &end); + while (slice < end) { + mi_assert_internal(slice->slice_count > 0); + mi_assert_internal(slice->slice_offset == 0); + if (mi_slice_is_used(slice)) { + // in use: reclaim the page in our heap + mi_page_t* page = mi_slice_to_page(slice); + mi_assert_internal(page->is_committed); + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_assert_internal(mi_page_heap(page) == NULL); + mi_assert_internal(page->next == NULL && page->prev==NULL); + _mi_stat_decrease(&tld->stats->pages_abandoned, 1); + segment->abandoned--; + // set the heap again and allow delayed free again + mi_page_set_heap(page, heap); + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set) + _mi_page_free_collect(page, false); // ensure used count is up to date + if (mi_page_all_free(page)) { + // if everything free by now, free the page + slice = mi_segment_page_clear(page, tld); // set slice again due to coalesceing + } + else { + // otherwise reclaim it into the heap + _mi_page_reclaim(heap, page); + if (requested_block_size == page->xblock_size && mi_page_has_any_available(page)) { + if (right_page_reclaimed != NULL) { *right_page_reclaimed = true; } + } + } + } + else { + // the span is free, add it to our page queues + slice = mi_segment_span_free_coalesce(slice, tld); // set slice again due to coalesceing + } + mi_assert_internal(slice->slice_count>0 && slice->slice_offset==0); + slice = slice + slice->slice_count; + } + + mi_assert(segment->abandoned == 0); + if (segment->used == 0) { // due to page_clear + mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed)); + mi_segment_free(segment, false, tld); + return NULL; + } + else { + return segment; + } +} + + +void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld) { + mi_segment_t* segment; + while ((segment = mi_abandoned_pop()) != NULL) { + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } +} + +static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slices, size_t block_size, bool* reclaimed, mi_segments_tld_t* tld) +{ + *reclaimed = false; + mi_segment_t* segment; + long max_tries = mi_option_get_clamp(mi_option_max_segment_reclaim, 8, 1024); // limit the work to bound allocation times + while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { + segment->abandoned_visits++; + // todo: an arena exclusive heap will potentially visit many abandoned unsuitable segments + // and push them into the visited list and use many tries. Perhaps we can skip non-suitable ones in a better way? + bool is_suitable = _mi_heap_memid_is_suitable(heap, segment->memid); + bool has_page = mi_segment_check_free(segment,needed_slices,block_size,tld); // try to free up pages (due to concurrent frees) + if (segment->used == 0) { + // free the segment (by forced reclaim) to make it available to other threads. + // note1: we prefer to free a segment as that might lead to reclaiming another + // segment that is still partially used. + // note2: we could in principle optimize this by skipping reclaim and directly + // freeing but that would violate some invariants temporarily) + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else if (has_page && is_suitable) { + // found a large enough free span, or a page of the right block_size with free space + // we return the result of reclaim (which is usually `segment`) as it might free + // the segment due to concurrent frees (in which case `NULL` is returned). + return mi_segment_reclaim(segment, heap, block_size, reclaimed, tld); + } + else if (segment->abandoned_visits > 3 && is_suitable) { + // always reclaim on 3rd visit to limit the abandoned queue length. + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else { + // otherwise, push on the visited list so it gets not looked at too quickly again + mi_segment_try_purge(segment, true /* force? */, tld->stats); // force purge if needed as we may not visit soon again + mi_abandoned_visited_push(segment); + } + } + return NULL; +} + + +void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld) +{ + mi_segment_t* segment; + int max_tries = (force ? 16*1024 : 1024); // limit latency + if (force) { + mi_abandoned_visited_revisit(); + } + while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { + mi_segment_check_free(segment,0,0,tld); // try to free up pages (due to concurrent frees) + if (segment->used == 0) { + // free the segment (by forced reclaim) to make it available to other threads. + // note: we could in principle optimize this by skipping reclaim and directly + // freeing but that would violate some invariants temporarily) + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else { + // otherwise, purge if needed and push on the visited list + // note: forced purge can be expensive if many threads are destroyed/created as in mstress. + mi_segment_try_purge(segment, force, tld->stats); + mi_abandoned_visited_push(segment); + } + } +} + +/* ----------------------------------------------------------- + Reclaim or allocate +----------------------------------------------------------- */ + +static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_slices, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); + mi_assert_internal(block_size <= MI_LARGE_OBJ_SIZE_MAX); + + // 1. try to reclaim an abandoned segment + bool reclaimed; + mi_segment_t* segment = mi_segment_try_reclaim(heap, needed_slices, block_size, &reclaimed, tld); + if (reclaimed) { + // reclaimed the right page right into the heap + mi_assert_internal(segment != NULL); + return NULL; // pretend out-of-memory as the page will be in the page queue of the heap with available blocks + } + else if (segment != NULL) { + // reclaimed a segment with a large enough empty span in it + return segment; + } + // 2. otherwise allocate a fresh segment + return mi_segment_alloc(0, 0, heap->arena_id, tld, os_tld, NULL); +} + + +/* ----------------------------------------------------------- + Page allocation +----------------------------------------------------------- */ + +static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_kind, size_t required, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_assert_internal(required <= MI_LARGE_OBJ_SIZE_MAX && page_kind <= MI_PAGE_LARGE); + + // find a free page + size_t page_size = _mi_align_up(required, (required > MI_MEDIUM_PAGE_SIZE ? MI_MEDIUM_PAGE_SIZE : MI_SEGMENT_SLICE_SIZE)); + size_t slices_needed = page_size / MI_SEGMENT_SLICE_SIZE; + mi_assert_internal(slices_needed * MI_SEGMENT_SLICE_SIZE == page_size); + mi_page_t* page = mi_segments_page_find_and_allocate(slices_needed, heap->arena_id, tld); //(required <= MI_SMALL_SIZE_MAX ? 0 : slices_needed), tld); + if (page==NULL) { + // no free page, allocate a new segment and try again + if (mi_segment_reclaim_or_alloc(heap, slices_needed, block_size, tld, os_tld) == NULL) { + // OOM or reclaimed a good page in the heap + return NULL; + } + else { + // otherwise try again + return mi_segments_page_alloc(heap, page_kind, required, block_size, tld, os_tld); + } + } + mi_assert_internal(page != NULL && page->slice_count*MI_SEGMENT_SLICE_SIZE == page_size); + mi_assert_internal(_mi_ptr_segment(page)->thread_id == _mi_thread_id()); + mi_segment_try_purge(_mi_ptr_segment(page), false, tld->stats); + return page; +} + + + +/* ----------------------------------------------------------- + Huge page allocation +----------------------------------------------------------- */ + +static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_page_t* page = NULL; + mi_segment_t* segment = mi_segment_alloc(size,page_alignment,req_arena_id,tld,os_tld,&page); + if (segment == NULL || page==NULL) return NULL; + mi_assert_internal(segment->used==1); + mi_assert_internal(mi_page_block_size(page) >= size); + #if MI_HUGE_PAGE_ABANDON + segment->thread_id = 0; // huge segments are immediately abandoned + #endif + + // for huge pages we initialize the xblock_size as we may + // overallocate to accommodate large alignments. + size_t psize; + uint8_t* start = _mi_segment_page_start(segment, page, &psize); + page->xblock_size = (psize > MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : (uint32_t)psize); + + // decommit the part of the prefix of a page that will not be used; this can be quite large (close to MI_SEGMENT_SIZE) + if (page_alignment > 0 && segment->allow_decommit) { + uint8_t* aligned_p = (uint8_t*)_mi_align_up((uintptr_t)start, page_alignment); + mi_assert_internal(_mi_is_aligned(aligned_p, page_alignment)); + mi_assert_internal(psize - (aligned_p - start) >= size); + uint8_t* decommit_start = start + sizeof(mi_block_t); // for the free list + ptrdiff_t decommit_size = aligned_p - decommit_start; + _mi_os_reset(decommit_start, decommit_size, &_mi_stats_main); // note: cannot use segment_decommit on huge segments + } + + return page; +} + +#if MI_HUGE_PAGE_ABANDON +// free huge block from another thread +void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) { + // huge page segments are always abandoned and can be freed immediately by any thread + mi_assert_internal(segment->kind==MI_SEGMENT_HUGE); + mi_assert_internal(segment == _mi_page_segment(page)); + mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id)==0); + + // claim it and free + mi_heap_t* heap = mi_heap_get_default(); // issue #221; don't use the internal get_default_heap as we need to ensure the thread is initialized. + // paranoia: if this it the last reference, the cas should always succeed + size_t expected_tid = 0; + if (mi_atomic_cas_strong_acq_rel(&segment->thread_id, &expected_tid, heap->thread_id)) { + mi_block_set_next(page, block, page->free); + page->free = block; + page->used--; + page->is_zero = false; + mi_assert(page->used == 0); + mi_tld_t* tld = heap->tld; + _mi_segment_page_free(page, true, &tld->segments); + } +#if (MI_DEBUG!=0) + else { + mi_assert_internal(false); + } +#endif +} + +#else +// reset memory of a huge block from another thread +void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) { + MI_UNUSED(page); + mi_assert_internal(segment->kind == MI_SEGMENT_HUGE); + mi_assert_internal(segment == _mi_page_segment(page)); + mi_assert_internal(page->used == 1); // this is called just before the free + mi_assert_internal(page->free == NULL); + if (segment->allow_decommit) { + size_t csize = mi_usable_size(block); + if (csize > sizeof(mi_block_t)) { + csize = csize - sizeof(mi_block_t); + uint8_t* p = (uint8_t*)block + sizeof(mi_block_t); + _mi_os_reset(p, csize, &_mi_stats_main); // note: cannot use segment_decommit on huge segments + } + } +} +#endif + +/* ----------------------------------------------------------- + Page allocation and free +----------------------------------------------------------- */ +mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + mi_page_t* page; + if mi_unlikely(page_alignment > MI_ALIGNMENT_MAX) { + mi_assert_internal(_mi_is_power_of_two(page_alignment)); + mi_assert_internal(page_alignment >= MI_SEGMENT_SIZE); + if (page_alignment < MI_SEGMENT_SIZE) { page_alignment = MI_SEGMENT_SIZE; } + page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld,os_tld); + } + else if (block_size <= MI_SMALL_OBJ_SIZE_MAX) { + page = mi_segments_page_alloc(heap,MI_PAGE_SMALL,block_size,block_size,tld,os_tld); + } + else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) { + page = mi_segments_page_alloc(heap,MI_PAGE_MEDIUM,MI_MEDIUM_PAGE_SIZE,block_size,tld, os_tld); + } + else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) { + page = mi_segments_page_alloc(heap,MI_PAGE_LARGE,block_size,block_size,tld, os_tld); + } + else { + page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld,os_tld); + } + mi_assert_internal(page == NULL || _mi_heap_memid_is_suitable(heap, _mi_page_segment(page)->memid)); + mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld)); + return page; +} diff --git a/Objects/mimalloc/static.c b/Objects/mimalloc/static.c new file mode 100644 index 00000000000000..98c4aa18e450cd --- /dev/null +++ b/Objects/mimalloc/static.c @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif +#if defined(__sun) +// same remarks as os.c for the static's context. +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#include "mimalloc.h" +#include "mimalloc/internal.h" + +// For a static override we create a single object file +// containing the whole library. If it is linked first +// it will override all the standard library allocation +// functions (on Unix's). +#include "alloc.c" // includes alloc-override.c +#include "alloc-aligned.c" +#include "alloc-posix.c" +#include "arena.c" +#include "bitmap.c" +#include "heap.c" +#include "init.c" +#include "options.c" +#include "os.c" +#include "page.c" // includes page-queue.c +#include "random.c" +#include "segment.c" +#include "segment-map.c" +#include "stats.c" +#include "prim/prim.c" +#if MI_OSX_ZONE +#include "prim/osx/alloc-override-zone.c" +#endif diff --git a/Objects/mimalloc/stats.c b/Objects/mimalloc/stats.c new file mode 100644 index 00000000000000..e7ea397ec4c384 --- /dev/null +++ b/Objects/mimalloc/stats.c @@ -0,0 +1,467 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2021, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include "mimalloc/atomic.h" +#include "mimalloc/prim.h" + +#include // snprintf +#include // memset + +#if defined(_MSC_VER) && (_MSC_VER < 1920) +#pragma warning(disable:4204) // non-constant aggregate initializer +#endif + +/* ----------------------------------------------------------- + Statistics operations +----------------------------------------------------------- */ + +static bool mi_is_in_main(void* stat) { + return ((uint8_t*)stat >= (uint8_t*)&_mi_stats_main + && (uint8_t*)stat < ((uint8_t*)&_mi_stats_main + sizeof(mi_stats_t))); +} + +static void mi_stat_update(mi_stat_count_t* stat, int64_t amount) { + if (amount == 0) return; + if (mi_is_in_main(stat)) + { + // add atomically (for abandoned pages) + int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount); + mi_atomic_maxi64_relaxed(&stat->peak, current + amount); + if (amount > 0) { + mi_atomic_addi64_relaxed(&stat->allocated,amount); + } + else { + mi_atomic_addi64_relaxed(&stat->freed, -amount); + } + } + else { + // add thread local + stat->current += amount; + if (stat->current > stat->peak) stat->peak = stat->current; + if (amount > 0) { + stat->allocated += amount; + } + else { + stat->freed += -amount; + } + } +} + +void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) { + if (mi_is_in_main(stat)) { + mi_atomic_addi64_relaxed( &stat->count, 1 ); + mi_atomic_addi64_relaxed( &stat->total, (int64_t)amount ); + } + else { + stat->count++; + stat->total += amount; + } +} + +void _mi_stat_increase(mi_stat_count_t* stat, size_t amount) { + mi_stat_update(stat, (int64_t)amount); +} + +void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount) { + mi_stat_update(stat, -((int64_t)amount)); +} + +// must be thread safe as it is called from stats_merge +static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src, int64_t unit) { + if (stat==src) return; + if (src->allocated==0 && src->freed==0) return; + mi_atomic_addi64_relaxed( &stat->allocated, src->allocated * unit); + mi_atomic_addi64_relaxed( &stat->current, src->current * unit); + mi_atomic_addi64_relaxed( &stat->freed, src->freed * unit); + // peak scores do not work across threads.. + mi_atomic_addi64_relaxed( &stat->peak, src->peak * unit); +} + +static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src, int64_t unit) { + if (stat==src) return; + mi_atomic_addi64_relaxed( &stat->total, src->total * unit); + mi_atomic_addi64_relaxed( &stat->count, src->count * unit); +} + +// must be thread safe as it is called from stats_merge +static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) { + if (stats==src) return; + mi_stat_add(&stats->segments, &src->segments,1); + mi_stat_add(&stats->pages, &src->pages,1); + mi_stat_add(&stats->reserved, &src->reserved, 1); + mi_stat_add(&stats->committed, &src->committed, 1); + mi_stat_add(&stats->reset, &src->reset, 1); + mi_stat_add(&stats->purged, &src->purged, 1); + mi_stat_add(&stats->page_committed, &src->page_committed, 1); + + mi_stat_add(&stats->pages_abandoned, &src->pages_abandoned, 1); + mi_stat_add(&stats->segments_abandoned, &src->segments_abandoned, 1); + mi_stat_add(&stats->threads, &src->threads, 1); + + mi_stat_add(&stats->malloc, &src->malloc, 1); + mi_stat_add(&stats->segments_cache, &src->segments_cache, 1); + mi_stat_add(&stats->normal, &src->normal, 1); + mi_stat_add(&stats->huge, &src->huge, 1); + mi_stat_add(&stats->large, &src->large, 1); + + mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1); + mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls, 1); + mi_stat_counter_add(&stats->commit_calls, &src->commit_calls, 1); + mi_stat_counter_add(&stats->reset_calls, &src->reset_calls, 1); + mi_stat_counter_add(&stats->purge_calls, &src->purge_calls, 1); + + mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1); + mi_stat_counter_add(&stats->searches, &src->searches, 1); + mi_stat_counter_add(&stats->normal_count, &src->normal_count, 1); + mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1); + mi_stat_counter_add(&stats->large_count, &src->large_count, 1); +#if MI_STAT>1 + for (size_t i = 0; i <= MI_BIN_HUGE; i++) { + if (src->normal_bins[i].allocated > 0 || src->normal_bins[i].freed > 0) { + mi_stat_add(&stats->normal_bins[i], &src->normal_bins[i], 1); + } + } +#endif +} + +/* ----------------------------------------------------------- + Display statistics +----------------------------------------------------------- */ + +// unit > 0 : size in binary bytes +// unit == 0: count as decimal +// unit < 0 : count in binary +static void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) { + char buf[32]; buf[0] = 0; + int len = 32; + const char* suffix = (unit <= 0 ? " " : "B"); + const int64_t base = (unit == 0 ? 1000 : 1024); + if (unit>0) n *= unit; + + const int64_t pos = (n < 0 ? -n : n); + if (pos < base) { + if (n!=1 || suffix[0] != 'B') { // skip printing 1 B for the unit column + snprintf(buf, len, "%d %-3s", (int)n, (n==0 ? "" : suffix)); + } + } + else { + int64_t divider = base; + const char* magnitude = "K"; + if (pos >= divider*base) { divider *= base; magnitude = "M"; } + if (pos >= divider*base) { divider *= base; magnitude = "G"; } + const int64_t tens = (n / (divider/10)); + const long whole = (long)(tens/10); + const long frac1 = (long)(tens%10); + char unitdesc[8]; + snprintf(unitdesc, 8, "%s%s%s", magnitude, (base==1024 ? "i" : ""), suffix); + snprintf(buf, len, "%ld.%ld %-3s", whole, (frac1 < 0 ? -frac1 : frac1), unitdesc); + } + _mi_fprintf(out, arg, (fmt==NULL ? "%12s" : fmt), buf); +} + + +static void mi_print_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { + mi_printf_amount(n,unit,out,arg,NULL); +} + +static void mi_print_count(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { + if (unit==1) _mi_fprintf(out, arg, "%12s"," "); + else mi_print_amount(n,0,out,arg); +} + +static void mi_stat_print_ex(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg, const char* notok ) { + _mi_fprintf(out, arg,"%10s:", msg); + if (unit > 0) { + mi_print_amount(stat->peak, unit, out, arg); + mi_print_amount(stat->allocated, unit, out, arg); + mi_print_amount(stat->freed, unit, out, arg); + mi_print_amount(stat->current, unit, out, arg); + mi_print_amount(unit, 1, out, arg); + mi_print_count(stat->allocated, unit, out, arg); + if (stat->allocated > stat->freed) { + _mi_fprintf(out, arg, " "); + _mi_fprintf(out, arg, (notok == NULL ? "not all freed" : notok)); + _mi_fprintf(out, arg, "\n"); + } + else { + _mi_fprintf(out, arg, " ok\n"); + } + } + else if (unit<0) { + mi_print_amount(stat->peak, -1, out, arg); + mi_print_amount(stat->allocated, -1, out, arg); + mi_print_amount(stat->freed, -1, out, arg); + mi_print_amount(stat->current, -1, out, arg); + if (unit==-1) { + _mi_fprintf(out, arg, "%24s", ""); + } + else { + mi_print_amount(-unit, 1, out, arg); + mi_print_count((stat->allocated / -unit), 0, out, arg); + } + if (stat->allocated > stat->freed) + _mi_fprintf(out, arg, " not all freed!\n"); + else + _mi_fprintf(out, arg, " ok\n"); + } + else { + mi_print_amount(stat->peak, 1, out, arg); + mi_print_amount(stat->allocated, 1, out, arg); + _mi_fprintf(out, arg, "%11s", " "); // no freed + mi_print_amount(stat->current, 1, out, arg); + _mi_fprintf(out, arg, "\n"); + } +} + +static void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) { + mi_stat_print_ex(stat, msg, unit, out, arg, NULL); +} + +static void mi_stat_peak_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg) { + _mi_fprintf(out, arg, "%10s:", msg); + mi_print_amount(stat->peak, unit, out, arg); + _mi_fprintf(out, arg, "\n"); +} + +static void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg, "%10s:", msg); + mi_print_amount(stat->total, -1, out, arg); + _mi_fprintf(out, arg, "\n"); +} + + +static void mi_stat_counter_print_avg(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg) { + const int64_t avg_tens = (stat->count == 0 ? 0 : (stat->total*10 / stat->count)); + const long avg_whole = (long)(avg_tens/10); + const long avg_frac1 = (long)(avg_tens%10); + _mi_fprintf(out, arg, "%10s: %5ld.%ld avg\n", msg, avg_whole, avg_frac1); +} + + +static void mi_print_header(mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg, "%10s: %11s %11s %11s %11s %11s %11s\n", "heap stats", "peak ", "total ", "freed ", "current ", "unit ", "count "); +} + +#if MI_STAT>1 +static void mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) { + bool found = false; + char buf[64]; + for (size_t i = 0; i <= max; i++) { + if (bins[i].allocated > 0) { + found = true; + int64_t unit = _mi_bin_size((uint8_t)i); + snprintf(buf, 64, "%s %3lu", fmt, (long)i); + mi_stat_print(&bins[i], buf, unit, out, arg); + } + } + if (found) { + _mi_fprintf(out, arg, "\n"); + mi_print_header(out, arg); + } +} +#endif + + + +//------------------------------------------------------------ +// Use an output wrapper for line-buffered output +// (which is nice when using loggers etc.) +//------------------------------------------------------------ +typedef struct buffered_s { + mi_output_fun* out; // original output function + void* arg; // and state + char* buf; // local buffer of at least size `count+1` + size_t used; // currently used chars `used <= count` + size_t count; // total chars available for output +} buffered_t; + +static void mi_buffered_flush(buffered_t* buf) { + buf->buf[buf->used] = 0; + _mi_fputs(buf->out, buf->arg, NULL, buf->buf); + buf->used = 0; +} + +static void mi_cdecl mi_buffered_out(const char* msg, void* arg) { + buffered_t* buf = (buffered_t*)arg; + if (msg==NULL || buf==NULL) return; + for (const char* src = msg; *src != 0; src++) { + char c = *src; + if (buf->used >= buf->count) mi_buffered_flush(buf); + mi_assert_internal(buf->used < buf->count); + buf->buf[buf->used++] = c; + if (c == '\n') mi_buffered_flush(buf); + } +} + +//------------------------------------------------------------ +// Print statistics +//------------------------------------------------------------ + +static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept { + // wrap the output function to be line buffered + char buf[256]; + buffered_t buffer = { out0, arg0, NULL, 0, 255 }; + buffer.buf = buf; + mi_output_fun* out = &mi_buffered_out; + void* arg = &buffer; + + // and print using that + mi_print_header(out,arg); + #if MI_STAT>1 + mi_stats_print_bins(stats->normal_bins, MI_BIN_HUGE, "normal",out,arg); + #endif + #if MI_STAT + mi_stat_print(&stats->normal, "normal", (stats->normal_count.count == 0 ? 1 : -(stats->normal.allocated / stats->normal_count.count)), out, arg); + mi_stat_print(&stats->large, "large", (stats->large_count.count == 0 ? 1 : -(stats->large.allocated / stats->large_count.count)), out, arg); + mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out, arg); + mi_stat_count_t total = { 0,0,0,0 }; + mi_stat_add(&total, &stats->normal, 1); + mi_stat_add(&total, &stats->large, 1); + mi_stat_add(&total, &stats->huge, 1); + mi_stat_print(&total, "total", 1, out, arg); + #endif + #if MI_STAT>1 + mi_stat_print(&stats->malloc, "malloc req", 1, out, arg); + _mi_fprintf(out, arg, "\n"); + #endif + mi_stat_print_ex(&stats->reserved, "reserved", 1, out, arg, ""); + mi_stat_print_ex(&stats->committed, "committed", 1, out, arg, ""); + mi_stat_peak_print(&stats->reset, "reset", 1, out, arg ); + mi_stat_peak_print(&stats->purged, "purged", 1, out, arg ); + mi_stat_print(&stats->page_committed, "touched", 1, out, arg); + mi_stat_print(&stats->segments, "segments", -1, out, arg); + mi_stat_print(&stats->segments_abandoned, "-abandoned", -1, out, arg); + mi_stat_print(&stats->segments_cache, "-cached", -1, out, arg); + mi_stat_print(&stats->pages, "pages", -1, out, arg); + mi_stat_print(&stats->pages_abandoned, "-abandoned", -1, out, arg); + mi_stat_counter_print(&stats->pages_extended, "-extended", out, arg); + mi_stat_counter_print(&stats->page_no_retire, "-noretire", out, arg); + mi_stat_counter_print(&stats->mmap_calls, "mmaps", out, arg); + mi_stat_counter_print(&stats->commit_calls, "commits", out, arg); + mi_stat_counter_print(&stats->reset_calls, "resets", out, arg); + mi_stat_counter_print(&stats->purge_calls, "purges", out, arg); + mi_stat_print(&stats->threads, "threads", -1, out, arg); + mi_stat_counter_print_avg(&stats->searches, "searches", out, arg); + _mi_fprintf(out, arg, "%10s: %5zu\n", "numa nodes", _mi_os_numa_node_count()); + + size_t elapsed; + size_t user_time; + size_t sys_time; + size_t current_rss; + size_t peak_rss; + size_t current_commit; + size_t peak_commit; + size_t page_faults; + mi_process_info(&elapsed, &user_time, &sys_time, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults); + _mi_fprintf(out, arg, "%10s: %5ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000); + _mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, rss: ", "process", + user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults ); + mi_printf_amount((int64_t)peak_rss, 1, out, arg, "%s"); + if (peak_commit > 0) { + _mi_fprintf(out, arg, ", commit: "); + mi_printf_amount((int64_t)peak_commit, 1, out, arg, "%s"); + } + _mi_fprintf(out, arg, "\n"); +} + +static mi_msecs_t mi_process_start; // = 0 + +static mi_stats_t* mi_stats_get_default(void) { + mi_heap_t* heap = mi_heap_get_default(); + return &heap->tld->stats; +} + +static void mi_stats_merge_from(mi_stats_t* stats) { + if (stats != &_mi_stats_main) { + mi_stats_add(&_mi_stats_main, stats); + memset(stats, 0, sizeof(mi_stats_t)); + } +} + +void mi_stats_reset(void) mi_attr_noexcept { + mi_stats_t* stats = mi_stats_get_default(); + if (stats != &_mi_stats_main) { memset(stats, 0, sizeof(mi_stats_t)); } + memset(&_mi_stats_main, 0, sizeof(mi_stats_t)); + if (mi_process_start == 0) { mi_process_start = _mi_clock_start(); }; +} + +void mi_stats_merge(void) mi_attr_noexcept { + mi_stats_merge_from( mi_stats_get_default() ); +} + +void _mi_stats_done(mi_stats_t* stats) { // called from `mi_thread_done` + mi_stats_merge_from(stats); +} + +void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_stats_merge_from(mi_stats_get_default()); + _mi_stats_print(&_mi_stats_main, out, arg); +} + +void mi_stats_print(void* out) mi_attr_noexcept { + // for compatibility there is an `out` parameter (which can be `stdout` or `stderr`) + mi_stats_print_out((mi_output_fun*)out, NULL); +} + +void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { + _mi_stats_print(mi_stats_get_default(), out, arg); +} + + +// ---------------------------------------------------------------- +// Basic timer for convenience; use milli-seconds to avoid doubles +// ---------------------------------------------------------------- + +static mi_msecs_t mi_clock_diff; + +mi_msecs_t _mi_clock_now(void) { + return _mi_prim_clock_now(); +} + +mi_msecs_t _mi_clock_start(void) { + if (mi_clock_diff == 0.0) { + mi_msecs_t t0 = _mi_clock_now(); + mi_clock_diff = _mi_clock_now() - t0; + } + return _mi_clock_now(); +} + +mi_msecs_t _mi_clock_end(mi_msecs_t start) { + mi_msecs_t end = _mi_clock_now(); + return (end - start - mi_clock_diff); +} + + +// -------------------------------------------------------- +// Basic process statistics +// -------------------------------------------------------- + +mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept +{ + mi_process_info_t pinfo; + _mi_memzero_var(pinfo); + pinfo.elapsed = _mi_clock_end(mi_process_start); + pinfo.current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); + pinfo.peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); + pinfo.current_rss = pinfo.current_commit; + pinfo.peak_rss = pinfo.peak_commit; + pinfo.utime = 0; + pinfo.stime = 0; + pinfo.page_faults = 0; + + _mi_prim_process_info(&pinfo); + + if (elapsed_msecs!=NULL) *elapsed_msecs = (pinfo.elapsed < 0 ? 0 : (pinfo.elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.elapsed : PTRDIFF_MAX)); + if (user_msecs!=NULL) *user_msecs = (pinfo.utime < 0 ? 0 : (pinfo.utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.utime : PTRDIFF_MAX)); + if (system_msecs!=NULL) *system_msecs = (pinfo.stime < 0 ? 0 : (pinfo.stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)pinfo.stime : PTRDIFF_MAX)); + if (current_rss!=NULL) *current_rss = pinfo.current_rss; + if (peak_rss!=NULL) *peak_rss = pinfo.peak_rss; + if (current_commit!=NULL) *current_commit = pinfo.current_commit; + if (peak_commit!=NULL) *peak_commit = pinfo.peak_commit; + if (page_faults!=NULL) *page_faults = pinfo.page_faults; +} diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 5b9f74dbddf031..e2741fef6debd3 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -522,6 +522,7 @@ PyModule_GetNameObject(PyObject *mod) } PyObject *name; if (PyDict_GetItemRef(dict, &_Py_ID(__name__), &name) <= 0) { + // error or not found goto error; } if (!PyUnicode_Check(name)) { @@ -562,6 +563,7 @@ PyModule_GetFilenameObject(PyObject *mod) } PyObject *fileobj; if (PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj) <= 0) { + // error or not found goto error; } if (!PyUnicode_Check(fileobj)) { @@ -647,7 +649,7 @@ _PyModule_ClearDict(PyObject *d) PyErr_Clear(); } if (PyDict_SetItem(d, key, Py_None) != 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing module dict"); } } } @@ -668,7 +670,7 @@ _PyModule_ClearDict(PyObject *d) PyErr_Clear(); } if (PyDict_SetItem(d, key, Py_None) != 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing module dict"); } } } @@ -747,27 +749,20 @@ module_repr(PyModuleObject *m) } /* Check if the "_initializing" attribute of the module spec is set to true. - Clear the exception and return 0 if spec is NULL. */ int _PyModuleSpec_IsInitializing(PyObject *spec) { - if (spec != NULL) { - PyObject *value; - int ok = PyObject_GetOptionalAttr(spec, &_Py_ID(_initializing), &value); - if (ok == 0) { - return 0; - } - if (value != NULL) { - int initializing = PyObject_IsTrue(value); - Py_DECREF(value); - if (initializing >= 0) { - return initializing; - } - } + if (spec == NULL) { + return 0; } - PyErr_Clear(); - return 0; + PyObject *value; + int rc = PyObject_GetOptionalAttr(spec, &_Py_ID(_initializing), &value); + if (rc > 0) { + rc = PyObject_IsTrue(value); + Py_DECREF(value); + } + return rc; } /* Check if the submodule name is in the "_uninitialized_submodules" attribute @@ -780,17 +775,13 @@ _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name) return 0; } - PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_uninitialized_submodules)); - if (value == NULL) { - return 0; - } - - int is_uninitialized = PySequence_Contains(value, name); - Py_DECREF(value); - if (is_uninitialized == -1) { - return 0; + PyObject *value; + int rc = PyObject_GetOptionalAttr(spec, &_Py_ID(_uninitialized_submodules), &value); + if (rc > 0) { + rc = PySequence_Contains(value, name); + Py_DECREF(value); } - return is_uninitialized; + return rc; } PyObject* @@ -816,54 +807,56 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress) PyErr_Clear(); } assert(m->md_dict != NULL); - getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__)); + if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__getattr__), &getattr) < 0) { + return NULL; + } if (getattr) { PyObject *result = PyObject_CallOneArg(getattr, name); if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) { // suppress AttributeError PyErr_Clear(); } + Py_DECREF(getattr); return result; } - if (PyErr_Occurred()) { + if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__name__), &mod_name) < 0) { return NULL; } - mod_name = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__name__)); if (mod_name && PyUnicode_Check(mod_name)) { - Py_INCREF(mod_name); - PyObject *spec = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__spec__)); - if (spec == NULL && PyErr_Occurred()) { + PyObject *spec; + if (PyDict_GetItemRef(m->md_dict, &_Py_ID(__spec__), &spec) < 0) { Py_DECREF(mod_name); return NULL; } if (suppress != 1) { - Py_XINCREF(spec); - if (_PyModuleSpec_IsInitializing(spec)) { + int rc = _PyModuleSpec_IsInitializing(spec); + if (rc > 0) { PyErr_Format(PyExc_AttributeError, "partially initialized " "module '%U' has no attribute '%U' " "(most likely due to a circular import)", mod_name, name); } - else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) { - PyErr_Format(PyExc_AttributeError, + else if (rc == 0) { + rc = _PyModuleSpec_IsUninitializedSubmodule(spec, name); + if (rc > 0) { + PyErr_Format(PyExc_AttributeError, "cannot access submodule '%U' of module '%U' " "(most likely due to a circular import)", name, mod_name); - } - else { - PyErr_Format(PyExc_AttributeError, + } + else if (rc == 0) { + PyErr_Format(PyExc_AttributeError, "module '%U' has no attribute '%U'", mod_name, name); + } } - Py_XDECREF(spec); } + Py_XDECREF(spec); Py_DECREF(mod_name); return NULL; } - else if (PyErr_Occurred()) { - return NULL; - } + Py_XDECREF(mod_name); if (suppress != 1) { PyErr_Format(PyExc_AttributeError, "module has no attribute '%U'", name); @@ -902,10 +895,9 @@ module_clear(PyModuleObject *m) { int res = m->md_def->m_clear((PyObject*)m); if (PyErr_Occurred()) { - PySys_FormatStderr("Exception ignored in m_clear of module%s%V\n", - m->md_name ? " " : "", - m->md_name, ""); - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored in m_clear of module%s%V", + m->md_name ? " " : "", + m->md_name, ""); } if (res) return res; @@ -958,11 +950,8 @@ module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored)) return NULL; } - PyObject *annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); - if (annotations) { - Py_INCREF(annotations); - } - else if (!PyErr_Occurred()) { + PyObject *annotations; + if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) == 0) { annotations = PyDict_New(); if (annotations) { int result = PyDict_SetItem( diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index 204c114fd9de2d..b975bcfeea2cdf 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -1,12 +1,12 @@ // namespace object implementation #include "Python.h" +#include "pycore_modsupport.h" // _PyArg_NoPositional() #include "pycore_namespace.h" // _PyNamespace_Type #include // offsetof() - typedef struct { PyObject_HEAD PyObject *ns_dict; diff --git a/Objects/object.c b/Objects/object.c index 3ed272afdced7c..cdb7a08a7828fb 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -13,6 +13,7 @@ #include "pycore_memoryobject.h" // _PyManagedBuffer_Type #include "pycore_namespace.h" // _PyNamespace_Type #include "pycore_object.h" // PyAPI_DATA() _Py_SwappedOp definition +#include "pycore_optimizer.h" // _PyUOpExecutor_Type, _PyUOpOptimizer_Type, ... #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -295,6 +296,126 @@ _Py_DecRef(PyObject *o) Py_DECREF(o); } +#ifdef Py_GIL_DISABLED +# ifdef Py_REF_DEBUG +static inline int +is_shared_refcnt_dead(Py_ssize_t shared) +{ +# if SIZEOF_SIZE_T == 8 + return shared == (Py_ssize_t)0xDDDDDDDDDDDDDDDD; +# else + return shared == (Py_ssize_t)0xDDDDDDDD; +# endif +} +# endif + +void +_Py_DecRefSharedDebug(PyObject *o, const char *filename, int lineno) +{ + // Should we queue the object for the owning thread to merge? + int should_queue; + + Py_ssize_t new_shared; + Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&o->ob_ref_shared); + do { + should_queue = (shared == 0 || shared == _Py_REF_MAYBE_WEAKREF); + + if (should_queue) { + // If the object had refcount zero, not queued, and not merged, + // then we enqueue the object to be merged by the owning thread. + // In this case, we don't subtract one from the reference count + // because the queue holds a reference. + new_shared = _Py_REF_QUEUED; + } + else { + // Otherwise, subtract one from the reference count. This might + // be negative! + new_shared = shared - (1 << _Py_REF_SHARED_SHIFT); + } + +#ifdef Py_REF_DEBUG + if ((_Py_REF_IS_MERGED(new_shared) && new_shared < 0) || + is_shared_refcnt_dead(shared)) + { + _Py_NegativeRefcount(filename, lineno, o); + } +#endif + } while (!_Py_atomic_compare_exchange_ssize(&o->ob_ref_shared, + &shared, new_shared)); + + if (should_queue) { + // TODO: the inter-thread queue is not yet implemented. For now, + // we just merge the refcount here. + Py_ssize_t refcount = _Py_ExplicitMergeRefcount(o, -1); + if (refcount == 0) { + _Py_Dealloc(o); + } + } + else if (new_shared == _Py_REF_MERGED) { + // refcount is zero AND merged + _Py_Dealloc(o); + } +} + +void +_Py_DecRefShared(PyObject *o) +{ + _Py_DecRefSharedDebug(o, NULL, 0); +} + +void +_Py_MergeZeroLocalRefcount(PyObject *op) +{ + assert(op->ob_ref_local == 0); + + _Py_atomic_store_uintptr_relaxed(&op->ob_tid, 0); + Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&op->ob_ref_shared); + if (shared == 0) { + // Fast-path: shared refcount is zero (including flags) + _Py_Dealloc(op); + return; + } + + // Slow-path: atomically set the flags (low two bits) to _Py_REF_MERGED. + Py_ssize_t new_shared; + do { + new_shared = (shared & ~_Py_REF_SHARED_FLAG_MASK) | _Py_REF_MERGED; + } while (!_Py_atomic_compare_exchange_ssize(&op->ob_ref_shared, + &shared, new_shared)); + + if (new_shared == _Py_REF_MERGED) { + // i.e., the shared refcount is zero (only the flags are set) so we + // deallocate the object. + _Py_Dealloc(op); + } +} + +Py_ssize_t +_Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra) +{ + assert(!_Py_IsImmortal(op)); + Py_ssize_t refcnt; + Py_ssize_t new_shared; + Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&op->ob_ref_shared); + do { + refcnt = Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT); + if (_Py_REF_IS_MERGED(shared)) { + return refcnt; + } + + refcnt += (Py_ssize_t)op->ob_ref_local; + refcnt += extra; + + new_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED); + } while (!_Py_atomic_compare_exchange_ssize(&op->ob_ref_shared, + &shared, new_shared)); + + _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, 0); + _Py_atomic_store_uintptr_relaxed(&op->ob_tid, 0); + return refcnt; +} +#endif /* Py_GIL_DISABLED */ + /**************************************/ @@ -921,7 +1042,10 @@ PyObject_HasAttrString(PyObject *obj, const char *name) { int rc = PyObject_HasAttrStringWithError(obj, name); if (rc < 0) { - PyErr_Clear(); + PyErr_FormatUnraisable( + "Exception ignored in PyObject_HasAttrString(); consider using " + "PyObject_HasAttrStringWithError(), " + "PyObject_GetOptionalAttrString() or PyObject_GetAttrString()"); return 0; } return rc; @@ -1156,7 +1280,10 @@ PyObject_HasAttr(PyObject *obj, PyObject *name) { int rc = PyObject_HasAttrWithError(obj, name); if (rc < 0) { - PyErr_Clear(); + PyErr_FormatUnraisable( + "Exception ignored in PyObject_HasAttr(); consider using " + "PyObject_HasAttrWithError(), " + "PyObject_GetOptionalAttr() or PyObject_GetAttr()"); return 0; } return rc; @@ -1363,19 +1490,14 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } if (dict != NULL) { Py_INCREF(dict); - PyObject *attr = PyDict_GetItemWithError(dict, name); - if (attr != NULL) { - *method = Py_NewRef(attr); + if (PyDict_GetItemRef(dict, name, method) != 0) { + // found or error Py_DECREF(dict); Py_XDECREF(descr); return 0; } + // not found Py_DECREF(dict); - - if (PyErr_Occurred()) { - Py_XDECREF(descr); - return 0; - } } if (meth_found) { @@ -1480,21 +1602,17 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } if (dict != NULL) { Py_INCREF(dict); - res = PyDict_GetItemWithError(dict, name); + int rc = PyDict_GetItemRef(dict, name, &res); + Py_DECREF(dict); if (res != NULL) { - Py_INCREF(res); - Py_DECREF(dict); goto done; } - else { - Py_DECREF(dict); - if (PyErr_Occurred()) { - if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } - else { - goto done; - } + else if (rc < 0) { + if (suppress && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + else { + goto done; } } } @@ -1908,7 +2026,7 @@ PyTypeObject _PyNone_Type = { 0, /*tp_doc */ 0, /*tp_traverse */ 0, /*tp_clear */ - 0, /*tp_richcompare */ + _Py_BaseObject_RichCompare, /*tp_richcompare */ 0, /*tp_weaklistoffset */ 0, /*tp_iter */ 0, /*tp_iternext */ @@ -1925,10 +2043,7 @@ PyTypeObject _PyNone_Type = { none_new, /*tp_new */ }; -PyObject _Py_NoneStruct = { - { _Py_IMMORTAL_REFCNT }, - &_PyNone_Type -}; +PyObject _Py_NoneStruct = _PyObject_HEAD_INIT(&_PyNone_Type); /* NotImplemented is an object that can be used to signal that an operation is not implemented for the given type combination. */ @@ -2027,10 +2142,7 @@ PyTypeObject _PyNotImplemented_Type = { notimplemented_new, /*tp_new */ }; -PyObject _Py_NotImplementedStruct = { - { _Py_IMMORTAL_REFCNT }, - &_PyNotImplemented_Type -}; +PyObject _Py_NotImplementedStruct = _PyObject_HEAD_INIT(&_PyNotImplemented_Type); PyStatus @@ -2157,6 +2269,9 @@ static PyTypeObject* static_types[] = { &_PyBufferWrapper_Type, &_PyContextTokenMissing_Type, &_PyCoroWrapper_Type, + &_PyCounterExecutor_Type, + &_PyCounterOptimizer_Type, + &_PyDefaultOptimizer_Type, &_Py_GenericAliasIterType, &_PyHamtItems_Type, &_PyHamtKeys_Type, @@ -2176,6 +2291,8 @@ static PyTypeObject* static_types[] = { &_PyPositionsIterator, &_PyUnicodeASCIIIter_Type, &_PyUnion_Type, + &_PyUOpExecutor_Type, + &_PyUOpOptimizer_Type, &_PyWeakref_CallableProxyType, &_PyWeakref_ProxyType, &_PyWeakref_RefType, @@ -2242,7 +2359,16 @@ new_reference(PyObject *op) _PyTraceMalloc_NewReference(op); } // Skip the immortal object check in Py_SET_REFCNT; always set refcnt to 1 +#if !defined(Py_GIL_DISABLED) op->ob_refcnt = 1; +#else + op->ob_tid = _Py_ThreadId(); + op->_padding = 0; + op->ob_mutex = (struct _PyMutex){ 0 }; + op->ob_gc_bits = 0; + op->ob_ref_local = 1; + op->ob_ref_shared = 0; +#endif #ifdef Py_TRACE_REFS _Py_AddToAllObjects(op); #endif @@ -2804,3 +2930,11 @@ int Py_IsFalse(PyObject *x) { return Py_Is(x, Py_False); } + + +// Py_SET_REFCNT() implementation for stable ABI +void +_Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt) +{ + Py_SET_REFCNT(ob, refcnt); +} diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 7d552ff57c8f1e..99c95d90658b08 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -10,6 +10,15 @@ #include // malloc() #include +#ifdef WITH_MIMALLOC +# include "pycore_mimalloc.h" +# include "mimalloc/static.c" +# include "mimalloc/internal.h" // for stats +#endif + +#if defined(Py_GIL_DISABLED) && !defined(WITH_MIMALLOC) +# error "Py_GIL_DISABLED requires WITH_MIMALLOC" +#endif #undef uint #define uint pymem_uint @@ -74,25 +83,95 @@ _PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr) free(ptr); } +#ifdef WITH_MIMALLOC + +void * +_PyMem_MiMalloc(void *ctx, size_t size) +{ + return mi_malloc(size); +} + +void * +_PyMem_MiCalloc(void *ctx, size_t nelem, size_t elsize) +{ + return mi_calloc(nelem, elsize); +} + +void * +_PyMem_MiRealloc(void *ctx, void *ptr, size_t size) +{ + return mi_realloc(ptr, size); +} + +void +_PyMem_MiFree(void *ctx, void *ptr) +{ + mi_free(ptr); +} + +void * +_PyObject_MiMalloc(void *ctx, size_t nbytes) +{ + return mi_malloc(nbytes); +} + +void * +_PyObject_MiCalloc(void *ctx, size_t nelem, size_t elsize) +{ + return mi_calloc(nelem, elsize); +} + + +void * +_PyObject_MiRealloc(void *ctx, void *ptr, size_t nbytes) +{ + return mi_realloc(ptr, nbytes); +} + +void +_PyObject_MiFree(void *ctx, void *ptr) +{ + mi_free(ptr); +} + +#endif // WITH_MIMALLOC + + #define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} -#define PYRAW_ALLOC MALLOC_ALLOC -/* the default object allocator */ + +#ifdef WITH_MIMALLOC +# define MIMALLOC_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree} +# define MIMALLOC_OBJALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree} +#endif + +/* the pymalloc allocator */ // The actual implementation is further down. -#ifdef WITH_PYMALLOC +#if defined(WITH_PYMALLOC) void* _PyObject_Malloc(void *ctx, size_t size); void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); void _PyObject_Free(void *ctx, void *p); void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); # define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +#endif // WITH_PYMALLOC + +#if defined(Py_GIL_DISABLED) +// Py_GIL_DISABLED requires using mimalloc for "mem" and "obj" domains. +# define PYRAW_ALLOC MALLOC_ALLOC +# define PYMEM_ALLOC MIMALLOC_ALLOC +# define PYOBJ_ALLOC MIMALLOC_OBJALLOC +#elif defined(WITH_PYMALLOC) +# define PYRAW_ALLOC MALLOC_ALLOC +# define PYMEM_ALLOC PYMALLOC_ALLOC # define PYOBJ_ALLOC PYMALLOC_ALLOC #else +# define PYRAW_ALLOC MALLOC_ALLOC +# define PYMEM_ALLOC MALLOC_ALLOC # define PYOBJ_ALLOC MALLOC_ALLOC -#endif // WITH_PYMALLOC +#endif -#define PYMEM_ALLOC PYOBJ_ALLOC /* the default debug allocators */ @@ -259,13 +338,9 @@ int _PyMem_SetDefaultAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *old_alloc) { - if (ALLOCATORS_MUTEX == NULL) { - /* The runtime must be initializing. */ - return set_default_allocator_unlocked(domain, pydebug, old_alloc); - } - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); int res = set_default_allocator_unlocked(domain, pydebug, old_alloc); - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); return res; } @@ -284,7 +359,7 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator) else if (strcmp(name, "debug") == 0) { *allocator = PYMEM_ALLOCATOR_DEBUG; } -#ifdef WITH_PYMALLOC +#if defined(WITH_PYMALLOC) && !defined(Py_GIL_DISABLED) else if (strcmp(name, "pymalloc") == 0) { *allocator = PYMEM_ALLOCATOR_PYMALLOC; } @@ -292,12 +367,22 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator) *allocator = PYMEM_ALLOCATOR_PYMALLOC_DEBUG; } #endif +#ifdef WITH_MIMALLOC + else if (strcmp(name, "mimalloc") == 0) { + *allocator = PYMEM_ALLOCATOR_MIMALLOC; + } + else if (strcmp(name, "mimalloc_debug") == 0) { + *allocator = PYMEM_ALLOCATOR_MIMALLOC_DEBUG; + } +#endif +#ifndef Py_GIL_DISABLED else if (strcmp(name, "malloc") == 0) { *allocator = PYMEM_ALLOCATOR_MALLOC; } else if (strcmp(name, "malloc_debug") == 0) { *allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG; } +#endif else { /* unknown allocator */ return -1; @@ -343,6 +428,26 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator) break; } #endif +#ifdef WITH_MIMALLOC + case PYMEM_ALLOCATOR_MIMALLOC: + case PYMEM_ALLOCATOR_MIMALLOC_DEBUG: + { + PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; + set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc); + + PyMemAllocatorEx pymalloc = MIMALLOC_ALLOC; + set_allocator_unlocked(PYMEM_DOMAIN_MEM, &pymalloc); + + PyMemAllocatorEx objmalloc = MIMALLOC_OBJALLOC; + set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &objmalloc); + + if (allocator == PYMEM_ALLOCATOR_MIMALLOC_DEBUG) { + set_up_debug_hooks_unlocked(); + } + + break; + } +#endif case PYMEM_ALLOCATOR_MALLOC: case PYMEM_ALLOCATOR_MALLOC_DEBUG: @@ -369,9 +474,9 @@ set_up_allocators_unlocked(PyMemAllocatorName allocator) int _PyMem_SetupAllocators(PyMemAllocatorName allocator) { - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); int res = set_up_allocators_unlocked(allocator); - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); return res; } @@ -390,6 +495,10 @@ get_current_allocator_name_unlocked(void) #ifdef WITH_PYMALLOC PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC; #endif +#ifdef WITH_MIMALLOC + PyMemAllocatorEx mimalloc = MIMALLOC_ALLOC; + PyMemAllocatorEx mimalloc_obj = MIMALLOC_OBJALLOC; +#endif if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) && pymemallocator_eq(&_PyMem, &malloc_alloc) && @@ -405,6 +514,14 @@ get_current_allocator_name_unlocked(void) return "pymalloc"; } #endif +#ifdef WITH_MIMALLOC + if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc) && + pymemallocator_eq(&_PyMem, &mimalloc) && + pymemallocator_eq(&_PyObject, &mimalloc_obj)) + { + return "mimalloc"; + } +#endif PyMemAllocatorEx dbg_raw = PYDBGRAW_ALLOC; PyMemAllocatorEx dbg_mem = PYDBGMEM_ALLOC; @@ -428,6 +545,14 @@ get_current_allocator_name_unlocked(void) { return "pymalloc_debug"; } +#endif +#ifdef WITH_MIMALLOC + if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) && + pymemallocator_eq(&_PyMem_Debug.mem.alloc, &mimalloc) && + pymemallocator_eq(&_PyMem_Debug.obj.alloc, &mimalloc_obj)) + { + return "mimalloc_debug"; + } #endif } return NULL; @@ -436,9 +561,9 @@ get_current_allocator_name_unlocked(void) const char* _PyMem_GetCurrentAllocatorName(void) { - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); const char *name = get_current_allocator_name_unlocked(); - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); return name; } @@ -460,7 +585,21 @@ _PyMem_PymallocEnabled(void) return (_PyObject.malloc == _PyObject_Malloc); } } -#endif + +#ifdef WITH_MIMALLOC +static int +_PyMem_MimallocEnabled(void) +{ + if (_PyMem_DebugEnabled()) { + return (_PyMem_Debug.obj.alloc.malloc == _PyObject_MiMalloc); + } + else { + return (_PyObject.malloc == _PyObject_MiMalloc); + } +} +#endif // WITH_MIMALLOC + +#endif // WITH_PYMALLOC static void @@ -521,14 +660,9 @@ set_up_debug_hooks_unlocked(void) void PyMem_SetupDebugHooks(void) { - if (ALLOCATORS_MUTEX == NULL) { - /* The runtime must not be completely initialized yet. */ - set_up_debug_hooks_unlocked(); - return; - } - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); set_up_debug_hooks_unlocked(); - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); } static void @@ -564,53 +698,33 @@ set_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { - if (ALLOCATORS_MUTEX == NULL) { - /* The runtime must not be completely initialized yet. */ - get_allocator_unlocked(domain, allocator); - return; - } - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); get_allocator_unlocked(domain, allocator); - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); } void PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { - if (ALLOCATORS_MUTEX == NULL) { - /* The runtime must not be completely initialized yet. */ - set_allocator_unlocked(domain, allocator); - return; - } - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); set_allocator_unlocked(domain, allocator); - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); } void PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator) { - if (ALLOCATORS_MUTEX == NULL) { - /* The runtime must not be completely initialized yet. */ - *allocator = _PyObject_Arena; - return; - } - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); *allocator = _PyObject_Arena; - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); } void PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) { - if (ALLOCATORS_MUTEX == NULL) { - /* The runtime must not be completely initialized yet. */ - _PyObject_Arena = *allocator; - return; - } - PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + PyMutex_Lock(&ALLOCATORS_MUTEX); _PyObject_Arena = *allocator; - PyThread_release_lock(ALLOCATORS_MUTEX); + PyMutex_Unlock(&ALLOCATORS_MUTEX); } @@ -883,9 +997,31 @@ get_state(void) #define narenas_highwater (state->mgmt.narenas_highwater) #define raw_allocated_blocks (state->mgmt.raw_allocated_blocks) +#ifdef WITH_MIMALLOC +static bool count_blocks( + const mi_heap_t* heap, const mi_heap_area_t* area, + void* block, size_t block_size, void* allocated_blocks) +{ + *(size_t *)allocated_blocks += area->used; + return 1; +} +#endif + Py_ssize_t _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp) { +#ifdef WITH_MIMALLOC + // TODO(sgross): this only counts the current thread's blocks. + if (_PyMem_MimallocEnabled()) { + size_t allocated_blocks = 0; + + mi_heap_t *heap = mi_heap_get_default(); + mi_heap_visit_blocks(heap, false, &count_blocks, &allocated_blocks); + + return allocated_blocks; + } +#endif + #ifdef Py_DEBUG assert(has_own_state(interp)); #else @@ -919,6 +1055,11 @@ _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp) void _PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *interp) { +#ifdef WITH_MIMALLOC + if (_PyMem_MimallocEnabled()) { + return; + } +#endif if (has_own_state(interp)) { Py_ssize_t leaked = _PyInterpreterState_GetAllocatedBlocks(interp); assert(has_own_state(interp) || leaked == 0); @@ -944,6 +1085,16 @@ _Py_FinalizeAllocatedBlocks(_PyRuntimeState *runtime) static Py_ssize_t get_num_global_allocated_blocks(_PyRuntimeState *runtime) { +#ifdef WITH_MIMALLOC + if (_PyMem_MimallocEnabled()) { + size_t allocated_blocks = 0; + + mi_heap_t *heap = mi_heap_get_default(); + mi_heap_visit_blocks(heap, false, &count_blocks, &allocated_blocks); + + return allocated_blocks; + } +#endif Py_ssize_t total = 0; if (_PyRuntimeState_GetFinalizing(runtime) != NULL) { PyInterpreterState *interp = _PyInterpreterState_Main(); @@ -2536,19 +2687,55 @@ pool_is_in_list(const poolp target, poolp list) } #endif -/* Print summary info to "out" about the state of pymalloc's structures. - * In Py_DEBUG mode, also perform some expensive internal consistency - * checks. - * - * Return 0 if the memory debug hooks are not installed or no statistics was - * written into out, return 1 otherwise. - */ -int -_PyObject_DebugMallocStats(FILE *out) +#ifdef WITH_MIMALLOC +struct _alloc_stats { + size_t allocated_blocks; + size_t allocated_bytes; + size_t allocated_with_overhead; + size_t bytes_reserved; + size_t bytes_committed; +}; + +static bool _collect_alloc_stats( + const mi_heap_t* heap, const mi_heap_area_t* area, + void* block, size_t block_size, void* arg) +{ + struct _alloc_stats *stats = (struct _alloc_stats *)arg; + stats->allocated_blocks += area->used; + stats->allocated_bytes += area->used * area->block_size; + stats->allocated_with_overhead += area->used * area->full_block_size; + stats->bytes_reserved += area->reserved; + stats->bytes_committed += area->committed; + return 1; +} + +static void +py_mimalloc_print_stats(FILE *out) +{ + fprintf(out, "Small block threshold = %zd, in %u size classes.\n", + MI_SMALL_OBJ_SIZE_MAX, MI_BIN_HUGE); + fprintf(out, "Medium block threshold = %zd\n", + MI_MEDIUM_OBJ_SIZE_MAX); + fprintf(out, "Large object max size = %zd\n", + MI_LARGE_OBJ_SIZE_MAX); + + mi_heap_t *heap = mi_heap_get_default(); + struct _alloc_stats stats; + memset(&stats, 0, sizeof(stats)); + mi_heap_visit_blocks(heap, false, &_collect_alloc_stats, &stats); + + fprintf(out, " Allocated Blocks: %zd\n", stats.allocated_blocks); + fprintf(out, " Allocated Bytes: %zd\n", stats.allocated_bytes); + fprintf(out, " Allocated Bytes w/ Overhead: %zd\n", stats.allocated_with_overhead); + fprintf(out, " Bytes Reserved: %zd\n", stats.bytes_reserved); + fprintf(out, " Bytes Committed: %zd\n", stats.bytes_committed); +} +#endif + + +static void +pymalloc_print_stats(FILE *out) { - if (!_PyMem_PymallocEnabled()) { - return 0; - } OMState *state = get_state(); uint i; @@ -2701,7 +2888,32 @@ _PyObject_DebugMallocStats(FILE *out) #endif #endif - return 1; +} + +/* Print summary info to "out" about the state of pymalloc's structures. + * In Py_DEBUG mode, also perform some expensive internal consistency + * checks. + * + * Return 0 if the memory debug hooks are not installed or no statistics was + * written into out, return 1 otherwise. + */ +int +_PyObject_DebugMallocStats(FILE *out) +{ +#ifdef WITH_MIMALLOC + if (_PyMem_MimallocEnabled()) { + py_mimalloc_print_stats(out); + return 1; + } + else +#endif + if (_PyMem_PymallocEnabled()) { + pymalloc_print_stats(out); + return 1; + } + else { + return 0; + } } #endif /* #ifdef WITH_PYMALLOC */ diff --git a/Objects/odictobject.c b/Objects/odictobject.c index b99896319e0136..b5280c39e1be54 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1049,7 +1049,10 @@ _odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, return NULL; } /* Now delete the value from the dict. */ - value = _PyDict_Pop_KnownHash(od, key, hash, failobj); + if (_PyDict_Pop_KnownHash((PyDictObject *)od, key, hash, + &value) == 0) { + value = Py_NewRef(failobj); + } } else if (value == NULL && !PyErr_Occurred()) { /* Apply the fallback value, if necessary. */ diff --git a/Objects/setobject.c b/Objects/setobject.c index ae3f0b8d5e55d8..88d20019bfb4a7 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -942,7 +942,10 @@ set_update(PySetObject *so, PyObject *args) } PyDoc_STRVAR(update_doc, -"Update a set with the union of itself and others."); +"update($self, /, *others)\n\ +--\n\ +\n\ +Update the set, adding elements from all others."); /* XXX Todo: If aligned memory allocations become available, make the @@ -1141,9 +1144,10 @@ set_union(PySetObject *so, PyObject *args) } PyDoc_STRVAR(union_doc, - "Return the union of sets as a new set.\n\ +"union($self, /, *others)\n\ +--\n\ \n\ -(i.e. all elements that are in either set.)"); +Return a new set with elements from the set and all others."); static PyObject * set_or(PySetObject *so, PyObject *other) @@ -1281,9 +1285,10 @@ set_intersection_multi(PySetObject *so, PyObject *args) } PyDoc_STRVAR(intersection_doc, -"Return the intersection of two sets as a new set.\n\ +"intersection($self, /, *others)\n\ +--\n\ \n\ -(i.e. all elements that are in both sets.)"); +Return a new set with elements common to the set and all others."); static PyObject * set_intersection_update(PySetObject *so, PyObject *other) @@ -1312,7 +1317,10 @@ set_intersection_update_multi(PySetObject *so, PyObject *args) } PyDoc_STRVAR(intersection_update_doc, -"Update a set with the intersection of itself and another."); +"intersection_update($self, /, *others)\n\ +--\n\ +\n\ +Update the set, keeping only elements found in it and all others."); static PyObject * set_and(PySetObject *so, PyObject *other) @@ -1470,7 +1478,10 @@ set_difference_update(PySetObject *so, PyObject *args) } PyDoc_STRVAR(difference_update_doc, -"Remove all elements of another set from this set."); +"difference_update($self, /, *others)\n\ +--\n\ +\n\ +Update the set, removing elements found in others."); static PyObject * set_copy_and_difference(PySetObject *so, PyObject *other) @@ -1587,9 +1598,10 @@ set_difference_multi(PySetObject *so, PyObject *args) } PyDoc_STRVAR(difference_doc, -"Return the difference of two or more sets as a new set.\n\ +"difference($self, /, *others)\n\ +--\n\ \n\ -(i.e. all elements that are in this set but not the others.)"); +Return a new set with elements in the set that are not in the others."); static PyObject * set_sub(PySetObject *so, PyObject *other) { @@ -1673,7 +1685,10 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) } PyDoc_STRVAR(symmetric_difference_update_doc, -"Update a set with the symmetric difference of itself and another."); +"symmetric_difference_update($self, other, /)\n\ +--\n\ +\n\ +Update the set, keeping only elements found in either set, but not in both."); static PyObject * set_symmetric_difference(PySetObject *so, PyObject *other) @@ -1694,9 +1709,10 @@ set_symmetric_difference(PySetObject *so, PyObject *other) } PyDoc_STRVAR(symmetric_difference_doc, -"Return the symmetric difference of two sets as a new set.\n\ +"symmetric_difference($self, other, /)\n\ +--\n\ \n\ -(i.e. all elements that are in exactly one of the sets.)"); +Return a new set with elements in either the set or other but not both."); static PyObject * set_xor(PySetObject *so, PyObject *other) @@ -2022,13 +2038,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}, @@ -2066,10 +2075,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, @@ -2111,8 +2116,8 @@ static PyNumberMethods set_as_number = { }; PyDoc_STRVAR(set_doc, -"set() -> new empty set object\n\ -set(iterable) -> new set object\n\ +"set(iterable=(), /)\n\ +--\n\ \n\ Build an unordered collection of unique elements."); @@ -2212,8 +2217,8 @@ static PyNumberMethods frozenset_as_number = { }; PyDoc_STRVAR(frozenset_doc, -"frozenset() -> empty frozenset object\n\ -frozenset(iterable) -> frozenset object\n\ +"frozenset(iterable=(), /)\n\ +--\n\ \n\ Build an immutable unordered collection of unique elements."); @@ -2368,148 +2373,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 * @@ -2547,7 +2410,4 @@ static PyTypeObject _PySetDummy_Type = { Py_TPFLAGS_DEFAULT, /*tp_flags */ }; -static PyObject _dummy_struct = { - { _Py_IMMORTAL_REFCNT }, - &_PySetDummy_Type -}; +static PyObject _dummy_struct = _PyObject_HEAD_INIT(&_PySetDummy_Type); diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 5ffc52ae674c82..a3ed0c096d84ed 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -16,6 +16,7 @@ this type and there is exactly one in existence. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_modsupport.h" // _PyArg_NoKeywords() #include "pycore_object.h" // _PyObject_GC_TRACK() @@ -97,10 +98,7 @@ PyTypeObject PyEllipsis_Type = { ellipsis_new, /* tp_new */ }; -PyObject _Py_EllipsisObject = { - { _Py_IMMORTAL_REFCNT }, - &PyEllipsis_Type -}; +PyObject _Py_EllipsisObject = _PyObject_HEAD_INIT(&PyEllipsis_Type); /* Slice object implementation */ diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index e81c5916e6f196..3a985ab5c7a9f5 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(stringlib_expandtabs__doc__, "expandtabs($self, /, tabsize=8)\n" @@ -278,4 +279,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=39cd1ee983137188 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b409bdf9ab68d5a6 input=a9049054013a1b77]*/ diff --git a/Objects/structseq.c b/Objects/structseq.c index 0ca622edc2ba37..581d6ad240885a 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -8,11 +8,11 @@ */ #include "Python.h" -#include "pycore_tuple.h" // _PyTuple_FromArray() +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_modsupport.h" // _PyArg_NoPositional() #include "pycore_object.h" // _PyObject_GC_TRACK() - #include "pycore_structseq.h" // PyStructSequence_InitType() -#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_tuple.h" // _PyTuple_FromArray() static const char visible_length_key[] = "n_sequence_fields"; static const char real_length_key[] = "n_fields"; @@ -216,19 +216,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) { - PyObject *ob = NULL; - if (dict != NULL) { - const char *name = 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) { + ob = Py_NewRef(Py_None); + } + else { + ++n_found_keys; + } + res->ob_item[i] = ob; } - if (ob == NULL) { - ob = Py_NewRef(Py_None); + 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] = ob; } _PyObject_GC_TRACK(res); @@ -365,9 +380,81 @@ 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 *ob; + if (PyDict_PopString(kwargs, Py_TYPE(self)->tp_members[i].name, + &ob) < 0) { + goto error; + } + if (ob == NULL) { + ob = Py_NewRef(self->ob_item[i]); + } + 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 diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 893d8420bba4c4..08f5f47d586729 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -828,7 +828,9 @@ PyType_Modified(PyTypeObject *type) if (bits & 1) { PyType_WatchCallback cb = interp->type_watchers[i]; if (cb && (cb(type) < 0)) { - PyErr_WriteUnraisable((PyObject *)type); + PyErr_FormatUnraisable( + "Exception ignored in type watcher callback #%d for %R", + i, type); } } i++; @@ -1090,14 +1092,9 @@ type_module(PyTypeObject *type, void *context) if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyObject *dict = lookup_tp_dict(type); - mod = PyDict_GetItemWithError(dict, &_Py_ID(__module__)); - if (mod == NULL) { - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_AttributeError, "__module__"); - } - return NULL; + if (PyDict_GetItemRef(dict, &_Py_ID(__module__), &mod) == 0) { + PyErr_Format(PyExc_AttributeError, "__module__"); } - Py_INCREF(mod); } else { const char *s = strrchr(type->tp_name, '.'); @@ -1132,17 +1129,16 @@ type_abstractmethods(PyTypeObject *type, void *context) PyObject *mod = NULL; /* type itself has an __abstractmethods__ descriptor (this). Don't return that. */ - if (type != &PyType_Type) { - PyObject *dict = lookup_tp_dict(type); - mod = PyDict_GetItemWithError(dict, &_Py_ID(__abstractmethods__)); + if (type == &PyType_Type) { + PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); } - if (!mod) { - if (!PyErr_Occurred()) { + else { + PyObject *dict = lookup_tp_dict(type); + if (PyDict_GetItemRef(dict, &_Py_ID(__abstractmethods__), &mod) == 0) { PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); } - return NULL; } - return Py_NewRef(mod); + return mod; } static int @@ -1433,18 +1429,14 @@ type_get_doc(PyTypeObject *type, void *context) return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); } PyObject *dict = lookup_tp_dict(type); - result = PyDict_GetItemWithError(dict, &_Py_ID(__doc__)); - if (result == NULL) { - if (!PyErr_Occurred()) { - result = Py_NewRef(Py_None); - } + if (PyDict_GetItemRef(dict, &_Py_ID(__doc__), &result) == 0) { + result = Py_NewRef(Py_None); } - else if (Py_TYPE(result)->tp_descr_get) { - result = Py_TYPE(result)->tp_descr_get(result, NULL, - (PyObject *)type); - } - else { - Py_INCREF(result); + else if (result) { + descrgetfunc descr_get = Py_TYPE(result)->tp_descr_get; + if (descr_get) { + Py_SETREF(result, descr_get(result, NULL, (PyObject *)type)); + } } return result; } @@ -1475,16 +1467,16 @@ type_get_annotations(PyTypeObject *type, void *context) PyObject *annotations; PyObject *dict = lookup_tp_dict(type); - annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); + if (PyDict_GetItemRef(dict, &_Py_ID(__annotations__), &annotations) < 0) { + return NULL; + } if (annotations) { - if (Py_TYPE(annotations)->tp_descr_get) { - annotations = Py_TYPE(annotations)->tp_descr_get( - annotations, NULL, (PyObject *)type); - } else { - Py_INCREF(annotations); + descrgetfunc get = Py_TYPE(annotations)->tp_descr_get; + if (get) { + Py_SETREF(annotations, get(annotations, NULL, (PyObject *)type)); } } - else if (!PyErr_Occurred()) { + else { annotations = PyDict_New(); if (annotations) { int result = PyDict_SetItem( @@ -1531,16 +1523,11 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context) static PyObject * type_get_type_params(PyTypeObject *type, void *context) { - PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__)); - - if (params) { - return Py_NewRef(params); + PyObject *params; + if (PyDict_GetItemRef(lookup_tp_dict(type), &_Py_ID(__type_params__), ¶ms) == 0) { + return PyTuple_New(0); } - if (PyErr_Occurred()) { - return NULL; - } - - return PyTuple_New(0); + return params; } static int @@ -1835,7 +1822,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; } @@ -1905,7 +1892,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) { @@ -3019,21 +3006,21 @@ subtype_getweakref(PyObject *obj, void *context) static PyGetSetDef subtype_getsets_full[] = { {"__dict__", subtype_dict, subtype_setdict, - PyDoc_STR("dictionary for instance variables (if defined)")}, + PyDoc_STR("dictionary for instance variables")}, {"__weakref__", subtype_getweakref, NULL, - PyDoc_STR("list of weak references to the object (if defined)")}, + PyDoc_STR("list of weak references to the object")}, {0} }; static PyGetSetDef subtype_getsets_dict_only[] = { {"__dict__", subtype_dict, subtype_setdict, - PyDoc_STR("dictionary for instance variables (if defined)")}, + PyDoc_STR("dictionary for instance variables")}, {0} }; static PyGetSetDef subtype_getsets_weakref_only[] = { {"__weakref__", subtype_getweakref, NULL, - PyDoc_STR("list of weak references to the object (if defined)")}, + PyDoc_STR("list of weak references to the object")}, {0} }; @@ -3434,18 +3421,13 @@ type_new_set_module(PyTypeObject *type) return 0; } - PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); - if (module == NULL) { - if (PyErr_Occurred()) { - return -1; - } - return 0; - } - - if (PyDict_SetItem(dict, &_Py_ID(__module__), module) < 0) { - return -1; + PyObject *module; + r = PyDict_GetItemRef(globals, &_Py_ID(__name__), &module); + if (module) { + r = PyDict_SetItem(dict, &_Py_ID(__module__), module); + Py_DECREF(module); } - return 0; + return r; } @@ -3456,23 +3438,24 @@ type_new_set_ht_name(PyTypeObject *type) { PyHeapTypeObject *et = (PyHeapTypeObject *)type; PyObject *dict = lookup_tp_dict(type); - PyObject *qualname = PyDict_GetItemWithError(dict, &_Py_ID(__qualname__)); + PyObject *qualname; + if (PyDict_GetItemRef(dict, &_Py_ID(__qualname__), &qualname) < 0) { + return -1; + } if (qualname != NULL) { if (!PyUnicode_Check(qualname)) { PyErr_Format(PyExc_TypeError, "type __qualname__ must be a str, not %s", Py_TYPE(qualname)->tp_name); + Py_DECREF(qualname); return -1; } - et->ht_qualname = Py_NewRef(qualname); + et->ht_qualname = qualname; if (PyDict_DelItem(dict, &_Py_ID(__qualname__)) < 0) { return -1; } } else { - if (PyErr_Occurred()) { - return -1; - } et->ht_qualname = Py_NewRef(et->ht_name); } return 0; @@ -4557,6 +4540,12 @@ PyType_GetQualName(PyTypeObject *type) return type_qualname(type, NULL); } +PyObject * +_PyType_GetModuleName(PyTypeObject *type) +{ + return type_module(type, NULL); +} + void * PyType_GetSlot(PyTypeObject *type, int slot) { @@ -5252,8 +5241,10 @@ static PyMethodDef type_methods[] = { TYPE___SUBCLASSES___METHODDEF {"__prepare__", _PyCFunction_CAST(type_prepare), METH_FASTCALL | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("__prepare__() -> dict\n" - "used to create the namespace for the class statement")}, + PyDoc_STR("__prepare__($cls, name, bases, /, **kwds)\n" + "--\n" + "\n" + "Create the namespace for the class statement")}, TYPE___INSTANCECHECK___METHODDEF TYPE___SUBCLASSCHECK___METHODDEF TYPE___DIR___METHODDEF @@ -5634,6 +5625,12 @@ object_richcompare(PyObject *self, PyObject *other, int op) return res; } +PyObject* +_Py_BaseObject_RichCompare(PyObject* self, PyObject* other, int op) +{ + return object_richcompare(self, other, op); +} + static PyObject * object_get_class(PyObject *self, void *closure) { @@ -5884,24 +5881,22 @@ _PyType_GetSlotNames(PyTypeObject *cls) /* Get the slot names from the cache in the class if possible. */ PyObject *dict = lookup_tp_dict(cls); - slotnames = PyDict_GetItemWithError(dict, &_Py_ID(__slotnames__)); + if (PyDict_GetItemRef(dict, &_Py_ID(__slotnames__), &slotnames) < 0) { + return NULL; + } if (slotnames != NULL) { if (slotnames != Py_None && !PyList_Check(slotnames)) { PyErr_Format(PyExc_TypeError, "%.200s.__slotnames__ should be a list or None, " "not %.200s", cls->tp_name, Py_TYPE(slotnames)->tp_name); + Py_DECREF(slotnames); return NULL; } - return Py_NewRef(slotnames); - } - else { - if (PyErr_Occurred()) { - return NULL; - } - /* The class does not have the slot names cached yet. */ + return slotnames; } + /* The class does not have the slot names cached yet. */ copyreg = import_copyreg(); if (copyreg == NULL) return NULL; @@ -9290,7 +9285,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer) // from a Python __buffer__ function. mv = PyMemoryView_FromBuffer(buffer); if (mv == NULL) { - PyErr_WriteUnraisable(self); + PyErr_FormatUnraisable("Exception ignored in bf_releasebuffer of %s", Py_TYPE(self)->tp_name); goto end; } // Set the memoryview to restricted mode, which forbids @@ -9303,7 +9298,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer) PyObject *stack[2] = {self, mv}; PyObject *ret = vectorcall_method(&_Py_ID(__release_buffer__), stack, 2); if (ret == NULL) { - PyErr_WriteUnraisable(self); + PyErr_FormatUnraisable("Exception ignored in __release_buffer__ of %s", Py_TYPE(self)->tp_name); } else { Py_DECREF(ret); @@ -9311,7 +9306,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer) if (!is_buffer_wrapper) { PyObject *res = PyObject_CallMethodNoArgs(mv, &_Py_ID(release)); if (res == NULL) { - PyErr_WriteUnraisable(self); + PyErr_FormatUnraisable("Exception ignored in bf_releasebuffer of %s", Py_TYPE(self)->tp_name); } else { Py_DECREF(res); @@ -10260,23 +10255,18 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * return NULL; /* keep a strong reference to mro because su_obj_type->tp_mro can be - replaced during PyDict_GetItemWithError(dict, name) */ + replaced during PyDict_GetItemRef(dict, name, &res) */ Py_INCREF(mro); do { PyObject *obj = PyTuple_GET_ITEM(mro, i); PyObject *dict = lookup_tp_dict(_PyType_CAST(obj)); assert(dict != NULL && PyDict_Check(dict)); - res = PyDict_GetItemWithError(dict, name); - if (res != NULL) { - Py_INCREF(res); + if (PyDict_GetItemRef(dict, name, &res) != 0) { + // found or error Py_DECREF(mro); return res; } - else if (PyErr_Occurred()) { - Py_DECREF(mro); - return NULL; - } i++; } while (i < n); diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 0f04523b0032ed..7f80c9c61b8abc 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -200,7 +200,7 @@ 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); @@ -216,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; } @@ -227,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; } @@ -327,7 +327,6 @@ typevar.__new__ as typevar_new name: object(subclass_of="&PyUnicode_Type") *constraints: object - * bound: object = None covariant: bool = False contravariant: bool = False @@ -340,7 +339,7 @@ static PyObject * typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, PyObject *bound, int covariant, int contravariant, int infer_variance) -/*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/ +/*[clinic end generated code: output=1d200450ee99226d input=41ae33a916bfe76f]*/ { if (covariant && contravariant) { PyErr_SetString(PyExc_ValueError, @@ -364,11 +363,7 @@ typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, } } - if (!PyTuple_CheckExact(constraints)) { - PyErr_SetString(PyExc_TypeError, - "constraints must be a tuple"); - return NULL; - } + assert(PyTuple_CheckExact(constraints)); Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints); if (n_constraints == 1) { PyErr_SetString(PyExc_TypeError, @@ -744,7 +739,7 @@ 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); @@ -757,7 +752,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; } @@ -765,7 +760,7 @@ static int paramspec_clear(paramspecobject *self) { Py_CLEAR(self->bound); - _PyObject_ClearManagedDict((PyObject *)self); + PyObject_ClearManagedDict((PyObject *)self); return 0; } @@ -1026,7 +1021,7 @@ 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); @@ -1165,14 +1160,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; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 49981a1f881c21..836e14fd5d5dea 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1904,7 +1904,7 @@ _PyUnicode_FromId(_Py_Identifier *id) if (index < 0) { struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; - PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); + PyMutex_Lock(&rt_ids->mutex); // Check again to detect concurrent access. Another thread can have // initialized the index while this thread waited for the lock. index = _Py_atomic_load_ssize(&id->index); @@ -1914,7 +1914,7 @@ _PyUnicode_FromId(_Py_Identifier *id) rt_ids->next_index++; _Py_atomic_store_ssize(&id->index, index); } - PyThread_release_lock(rt_ids->lock); + PyMutex_Unlock(&rt_ids->mutex); } assert(index >= 0); @@ -3820,17 +3820,24 @@ PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) { if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); + if (psize) { + *psize = -1; + } return NULL; } if (PyUnicode_UTF8(unicode) == NULL) { if (unicode_fill_utf8(unicode) == -1) { + if (psize) { + *psize = -1; + } return NULL; } } - if (psize) + if (psize) { *psize = PyUnicode_UTF8_LENGTH(unicode); + } return PyUnicode_UTF8(unicode); } @@ -3840,6 +3847,18 @@ PyUnicode_AsUTF8(PyObject *unicode) return PyUnicode_AsUTF8AndSize(unicode, NULL); } +const char * +_PyUnicode_AsUTF8NoNUL(PyObject *unicode) +{ + Py_ssize_t size; + const char *s = PyUnicode_AsUTF8AndSize(unicode, &size); + if (s && strlen(s) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + return NULL; + } + return s; +} + /* PyUnicode_GetSize() has been deprecated since Python 3.3 because it returned length of Py_UNICODE. @@ -5850,6 +5869,23 @@ PyUnicode_AsUTF16String(PyObject *unicode) return _PyUnicode_EncodeUTF16(unicode, NULL, 0); } +_PyUnicode_Name_CAPI * +_PyUnicode_GetNameCAPI(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + _PyUnicode_Name_CAPI *ucnhash_capi; + + ucnhash_capi = _Py_atomic_load_ptr(&interp->unicode.ucnhash_capi); + if (ucnhash_capi == NULL) { + ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( + PyUnicodeData_CAPSULE_NAME, 1); + + // It's fine if we overwite the value here. It's always the same value. + _Py_atomic_store_ptr(&interp->unicode.ucnhash_capi, ucnhash_capi); + } + return ucnhash_capi; +} + /* --- Unicode Escape Codec ----------------------------------------------- */ PyObject * @@ -5865,7 +5901,6 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, PyObject *errorHandler = NULL; PyObject *exc = NULL; _PyUnicode_Name_CAPI *ucnhash_capi; - PyInterpreterState *interp = _PyInterpreterState_GET(); // so we can remember if we've seen an invalid escape char or not *first_invalid_escape = NULL; @@ -6013,19 +6048,13 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, /* \N{name} */ case 'N': - ucnhash_capi = interp->unicode.ucnhash_capi; + ucnhash_capi = _PyUnicode_GetNameCAPI(); if (ucnhash_capi == NULL) { - /* load the unicode data module */ - ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( - PyUnicodeData_CAPSULE_NAME, 1); - if (ucnhash_capi == NULL) { - PyErr_SetString( + PyErr_SetString( PyExc_UnicodeError, "\\N escapes not supported (can't load unicodedata module)" - ); - goto onError; - } - interp->unicode.ucnhash_capi = ucnhash_capi; + ); + goto onError; } message = "malformed \\N character escape"; @@ -10673,6 +10702,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) { @@ -13295,15 +13400,17 @@ _PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer) #include "stringlib/unicode_format.h" PyDoc_STRVAR(format__doc__, - "S.format(*args, **kwargs) -> str\n\ + "format($self, /, *args, **kwargs)\n\ +--\n\ \n\ -Return a formatted version of S, using substitutions from args and kwargs.\n\ +Return a formatted version of the string, using substitutions from args and kwargs.\n\ The substitutions are identified by braces ('{' and '}')."); PyDoc_STRVAR(format_map__doc__, - "S.format_map(mapping) -> str\n\ + "format_map($self, /, mapping)\n\ +--\n\ \n\ -Return a formatted version of S, using substitutions from mapping.\n\ +Return a formatted version of the string, using substitutions from mapping.\n\ The substitutions are identified by braces ('{' and '}')."); /*[clinic input] @@ -14601,7 +14708,7 @@ errors is specified, then the object must expose a data buffer\n\ that will be decoded using the given encoding and error handler.\n\ Otherwise, returns the result of object.__str__() (if defined)\n\ or repr(object).\n\ -encoding defaults to sys.getdefaultencoding().\n\ +encoding defaults to 'utf-8'.\n\ errors defaults to 'strict'."); static PyObject *unicode_iter(PyObject *seq); @@ -14878,7 +14985,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) // Skip the Immortal Instance check and restore // the two references (key and value) ignored // by PyUnicode_InternInPlace(). - s->ob_refcnt = 2; + _Py_SetMortal(s, 2); #ifdef INTERNED_STATS total_length += PyUnicode_GET_LENGTH(s); #endif diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 39a567dc46e89a..e6dbeffbe2aa3e 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -1,4 +1,4 @@ -/* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ +/* this file was generated by ./Tools/unicode/makeunicodedata.py 3.3 */ /* a list of unique character type descriptors */ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { diff --git a/PC/_testconsole.c b/PC/_testconsole.c index 5e5a771b96bfec..1dc0d230c4d7c3 100644 --- a/PC/_testconsole.c +++ b/PC/_testconsole.c @@ -133,31 +133,12 @@ _testconsole_read_output_impl(PyObject *module, PyObject *file) Py_RETURN_NONE; } -/*[clinic input] -_testconsole.flush_console_input_buffer - handle: HANDLE - -Flushes the console input buffer. - -All input records currently in the input buffer are discarded. -[clinic start generated code]*/ - -static PyObject * -_testconsole_flush_console_input_buffer_impl(PyObject *module, void *handle) -/*[clinic end generated code: output=1f923a81331465ce input=be8203ae84a288f5]*/ -/*[clinic end generated code:]*/ -{ - FlushConsoleInputBuffer(handle); - - Py_RETURN_NONE; -} #include "clinic\_testconsole.c.h" PyMethodDef testconsole_methods[] = { _TESTCONSOLE_WRITE_INPUT_METHODDEF _TESTCONSOLE_READ_OUTPUT_METHODDEF - _TESTCONSOLE_FLUSH_CONSOLE_INPUT_BUFFER_METHODDEF {NULL, NULL} }; diff --git a/PC/_wmimodule.cpp b/PC/_wmimodule.cpp index 310aa86d94d9b6..5ab6dcb032550b 100644 --- a/PC/_wmimodule.cpp +++ b/PC/_wmimodule.cpp @@ -8,6 +8,11 @@ // Version history // 2022-08: Initial contribution (Steve Dower) +// clinic/_wmimodule.cpp.h uses internal pycore_modsupport.h API +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #define _WIN32_DCOM #include #include @@ -39,6 +44,8 @@ struct _query_data { LPCWSTR query; HANDLE writePipe; HANDLE readPipe; + HANDLE initEvent; + HANDLE connectEvent; }; @@ -75,12 +82,18 @@ _query_thread(LPVOID param) IID_IWbemLocator, (LPVOID *)&locator ); } + if (SUCCEEDED(hr) && !SetEvent(data->initEvent)) { + hr = HRESULT_FROM_WIN32(GetLastError()); + } if (SUCCEEDED(hr)) { hr = locator->ConnectServer( bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &services ); } + if (SUCCEEDED(hr) && !SetEvent(data->connectEvent)) { + hr = HRESULT_FROM_WIN32(GetLastError()); + } if (SUCCEEDED(hr)) { hr = CoSetProxyBlanket( services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, @@ -184,6 +197,24 @@ _query_thread(LPVOID param) } +static DWORD +wait_event(HANDLE event, DWORD timeout) +{ + DWORD err = 0; + switch (WaitForSingleObject(event, timeout)) { + case WAIT_OBJECT_0: + break; + case WAIT_TIMEOUT: + err = WAIT_TIMEOUT; + break; + default: + err = GetLastError(); + break; + } + return err; +} + + /*[clinic input] _wmi.exec_query @@ -226,7 +257,11 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query) Py_BEGIN_ALLOW_THREADS - if (!CreatePipe(&data.readPipe, &data.writePipe, NULL, 0)) { + data.initEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + data.connectEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!data.initEvent || !data.connectEvent || + !CreatePipe(&data.readPipe, &data.writePipe, NULL, 0)) + { err = GetLastError(); } else { hThread = CreateThread(NULL, 0, _query_thread, (LPVOID*)&data, 0, NULL); @@ -238,6 +273,17 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query) } } + // gh-112278: If current user doesn't have permission to query the WMI, the + // function IWbemLocator::ConnectServer will hang for 5 seconds, and there + // is no way to specify the timeout. So we use an Event object to simulate + // a timeout. The initEvent will be set after COM initialization, it will + // take a longer time when first initialized. The connectEvent will be set + // after connected to WMI. + err = wait_event(data.initEvent, 1000); + if (!err) { + err = wait_event(data.connectEvent, 100); + } + while (!err) { if (ReadFile( data.readPipe, @@ -260,7 +306,7 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query) } // Allow the thread some time to clean up - switch (WaitForSingleObject(hThread, 1000)) { + switch (WaitForSingleObject(hThread, 100)) { case WAIT_OBJECT_0: // Thread ended cleanly if (!GetExitCodeThread(hThread, (LPDWORD)&err)) { @@ -281,6 +327,8 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query) } CloseHandle(hThread); + CloseHandle(data.initEvent); + CloseHandle(data.connectEvent); hThread = NULL; Py_END_ALLOW_THREADS diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index b76588909782ea..2c71c11c438b5b 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() #if defined(MS_WINDOWS) @@ -132,70 +133,6 @@ _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nar #endif /* defined(MS_WINDOWS) */ -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(_testconsole_flush_console_input_buffer__doc__, -"flush_console_input_buffer($module, /, handle)\n" -"--\n" -"\n" -"Flushes the console input buffer.\n" -"\n" -"All input records currently in the input buffer are discarded."); - -#define _TESTCONSOLE_FLUSH_CONSOLE_INPUT_BUFFER_METHODDEF \ - {"flush_console_input_buffer", _PyCFunction_CAST(_testconsole_flush_console_input_buffer), METH_FASTCALL|METH_KEYWORDS, _testconsole_flush_console_input_buffer__doc__}, - -static PyObject * -_testconsole_flush_console_input_buffer_impl(PyObject *module, void *handle); - -static PyObject * -_testconsole_flush_console_input_buffer(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 1 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(handle), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"handle", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "flush_console_input_buffer", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - void *handle; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - handle = PyLong_AsVoidPtr(args[0]); - if (!handle && PyErr_Occurred()) { - goto exit; - } - return_value = _testconsole_flush_console_input_buffer_impl(module, handle); - -exit: - return return_value; -} - -#endif /* defined(MS_WINDOWS) */ - #ifndef _TESTCONSOLE_WRITE_INPUT_METHODDEF #define _TESTCONSOLE_WRITE_INPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_WRITE_INPUT_METHODDEF) */ @@ -203,8 +140,4 @@ _testconsole_flush_console_input_buffer(PyObject *module, PyObject *const *args, #ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF #define _TESTCONSOLE_READ_OUTPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ - -#ifndef _TESTCONSOLE_FLUSH_CONSOLE_INPUT_BUFFER_METHODDEF - #define _TESTCONSOLE_FLUSH_CONSOLE_INPUT_BUFFER_METHODDEF -#endif /* !defined(_TESTCONSOLE_FLUSH_CONSOLE_INPUT_BUFFER_METHODDEF) */ -/*[clinic end generated code: output=5d488564f2500dd9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=08a1c844b3657272 input=a9049054013a1b77]*/ diff --git a/PC/clinic/_wmimodule.cpp.h b/PC/clinic/_wmimodule.cpp.h index 3ece5e6823b462..fccf3d795d5340 100644 --- a/PC/clinic/_wmimodule.cpp.h +++ b/PC/clinic/_wmimodule.cpp.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_wmi_exec_query__doc__, "exec_query($module, /, query)\n" @@ -68,4 +69,4 @@ _wmi_exec_query(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj exit: return return_value; } -/*[clinic end generated code: output=53821e597fc2aca4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ba04920d127f3ceb input=a9049054013a1b77]*/ diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h index 54ae61bd4f10a9..e3f7ea43f38211 100644 --- a/PC/clinic/msvcrtmodule.c.h +++ b/PC/clinic/msvcrtmodule.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(msvcrt_heapmin__doc__, "heapmin($module, /)\n" "--\n" @@ -695,4 +697,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=525ec6ac4e3cb4f2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=de9687b46212c2ed input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 7507c1151a9840..7e5545e113e718 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_long.h" // _PyLong_UnsignedLong_Converter() +#include "pycore_modsupport.h" // _PyArg_CheckPositional() #if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) @@ -1761,4 +1762,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=d7ae41899af53d7c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1ee4098b2f143b6a input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index b8c8e7d04a699f..6cc989565b638e 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -2,11 +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(winsound_PlaySound__doc__, "PlaySound($module, /, sound, flags)\n" "--\n" @@ -19,53 +14,22 @@ PyDoc_STRVAR(winsound_PlaySound__doc__, " Flag values, ored together. See module documentation."); #define WINSOUND_PLAYSOUND_METHODDEF \ - {"PlaySound", _PyCFunction_CAST(winsound_PlaySound), METH_FASTCALL|METH_KEYWORDS, winsound_PlaySound__doc__}, + {"PlaySound", (PyCFunction)(void(*)(void))winsound_PlaySound, METH_VARARGS|METH_KEYWORDS, winsound_PlaySound__doc__}, static PyObject * winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags); static PyObject * -winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winsound_PlaySound(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(sound), &_Py_ID(flags), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"sound", "flags", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "PlaySound", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; + static char *_keywords[] = {"sound", "flags", NULL}; PyObject *sound; int flags; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { - goto exit; - } - sound = args[0]; - flags = PyLong_AsInt(args[1]); - if (flags == -1 && PyErr_Occurred()) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi:PlaySound", _keywords, + &sound, &flags)) goto exit; - } return_value = winsound_PlaySound_impl(module, sound, flags); exit: @@ -85,56 +49,22 @@ PyDoc_STRVAR(winsound_Beep__doc__, " How long the sound should play, in milliseconds."); #define WINSOUND_BEEP_METHODDEF \ - {"Beep", _PyCFunction_CAST(winsound_Beep), METH_FASTCALL|METH_KEYWORDS, winsound_Beep__doc__}, + {"Beep", (PyCFunction)(void(*)(void))winsound_Beep, METH_VARARGS|METH_KEYWORDS, winsound_Beep__doc__}, static PyObject * winsound_Beep_impl(PyObject *module, int frequency, int duration); static PyObject * -winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winsound_Beep(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(frequency), &_Py_ID(duration), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"frequency", "duration", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "Beep", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; + static char *_keywords[] = {"frequency", "duration", NULL}; int frequency; int duration; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { - goto exit; - } - frequency = PyLong_AsInt(args[0]); - if (frequency == -1 && PyErr_Occurred()) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:Beep", _keywords, + &frequency, &duration)) goto exit; - } - duration = PyLong_AsInt(args[1]); - if (duration == -1 && PyErr_Occurred()) { - goto exit; - } return_value = winsound_Beep_impl(module, frequency, duration); exit: @@ -150,59 +80,24 @@ PyDoc_STRVAR(winsound_MessageBeep__doc__, "x defaults to MB_OK."); #define WINSOUND_MESSAGEBEEP_METHODDEF \ - {"MessageBeep", _PyCFunction_CAST(winsound_MessageBeep), METH_FASTCALL|METH_KEYWORDS, winsound_MessageBeep__doc__}, + {"MessageBeep", (PyCFunction)(void(*)(void))winsound_MessageBeep, METH_VARARGS|METH_KEYWORDS, winsound_MessageBeep__doc__}, static PyObject * winsound_MessageBeep_impl(PyObject *module, int type); static PyObject * -winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +winsound_MessageBeep(PyObject *module, 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(type), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"type", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "MessageBeep", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + static char *_keywords[] = {"type", NULL}; int type = MB_OK; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - type = PyLong_AsInt(args[0]); - if (type == -1 && PyErr_Occurred()) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:MessageBeep", _keywords, + &type)) goto exit; - } -skip_optional_pos: return_value = winsound_MessageBeep_impl(module, type); exit: return return_value; } -/*[clinic end generated code: output=21584101f656198f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=18a3771b34cdf97d input=a9049054013a1b77]*/ diff --git a/PC/config.c b/PC/config.c index 88f69758aac764..f754ce6d3b057b 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); @@ -36,6 +37,7 @@ extern PyObject* PyInit__weakref(void); extern PyObject* PyInit_xxsubtype(void); extern PyObject* PyInit__xxsubinterpreters(void); extern PyObject* PyInit__xxinterpchannels(void); +extern PyObject* PyInit__xxinterpqueues(void); extern PyObject* PyInit__random(void); extern PyObject* PyInit_itertools(void); extern PyObject* PyInit__collections(void); @@ -102,6 +104,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}, @@ -140,6 +143,7 @@ struct _inittab _PyImport_Inittab[] = { {"xxsubtype", PyInit_xxsubtype}, {"_xxsubinterpreters", PyInit__xxsubinterpreters}, {"_xxinterpchannels", PyInit__xxinterpchannels}, + {"_xxinterpqueues", PyInit__xxinterpqueues}, #ifdef _Py_HAVE_ZLIB {"zlib", PyInit_zlib}, #endif diff --git a/PC/launcher2.c b/PC/launcher2.c index bb500d4b6bfb07..2a8f8a101fc8a6 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; @@ -431,7 +438,7 @@ typedef struct { bool list; // if true, only list detected runtimes with paths without launching bool listPaths; - // if true, display help message before contiuning + // if true, display help message before continuing bool help; // if set, limits search to registry keys with the specified Company // This is intended for debugging and testing only @@ -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/layout/main.py b/PC/layout/main.py index cb2e4878da26b1..accfd51dd978fb 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -73,7 +73,10 @@ def copy_if_modified(src, dest): ) if do_copy: - shutil.copy2(src, dest) + try: + shutil.copy2(src, dest) + except FileNotFoundError: + raise FileNotFoundError(src) from None def get_lib_layout(ns): @@ -208,8 +211,7 @@ def _c(d): for dest, src in rglob(ns.source / "Include", "**/*.h"): yield "include/{}".format(dest), src - src = ns.source / "PC" / "pyconfig.h" - yield "include/pyconfig.h", src + yield "include/pyconfig.h", ns.build / "pyconfig.h" for dest, src in get_tcltk_lib(ns): yield dest, src diff --git a/PC/pyconfig.h b/PC/pyconfig.h deleted file mode 100644 index ac20129cd30fcc..00000000000000 --- a/PC/pyconfig.h +++ /dev/null @@ -1,739 +0,0 @@ -#ifndef Py_CONFIG_H -#define Py_CONFIG_H - -/* pyconfig.h. NOT Generated automatically by configure. - -This is a manually maintained version used for the Watcom, -Borland and Microsoft Visual C++ compilers. It is a -standard part of the Python distribution. - -WINDOWS DEFINES: -The code specific to Windows should be wrapped around one of -the following #defines - -MS_WIN64 - Code specific to the MS Win64 API -MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) -MS_WINDOWS - Code specific to Windows, but all versions. -Py_ENABLE_SHARED - Code if the Python core is built as a DLL. - -Also note that neither "_M_IX86" or "_MSC_VER" should be used for -any purpose other than "Windows Intel x86 specific" and "Microsoft -compiler specific". Therefore, these should be very rare. - - -NOTE: The following symbols are deprecated: -NT, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT -MS_CORE_DLL. - -WIN32 is still required for the locale module. - -*/ - -/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ -#ifdef USE_DL_EXPORT -# define Py_BUILD_CORE -#endif /* USE_DL_EXPORT */ - -/* Visual Studio 2005 introduces deprecation warnings for - "insecure" and POSIX functions. The insecure functions should - be replaced by *_s versions (according to Microsoft); the - POSIX functions by _* versions (which, according to Microsoft, - would be ISO C conforming). Neither renaming is feasible, so - we just silence the warnings. */ - -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif - -#define HAVE_IO_H -#define HAVE_SYS_UTIME_H -#define HAVE_TEMPNAM -#define HAVE_TMPFILE -#define HAVE_TMPNAM -#define HAVE_CLOCK -#define HAVE_STRERROR - -#include - -#define HAVE_STRFTIME -#define DONT_HAVE_SIG_ALARM -#define DONT_HAVE_SIG_PAUSE -#define LONG_BIT 32 -#define WORD_BIT 32 - -#define MS_WIN32 /* only support win32 and greater. */ -#define MS_WINDOWS -#define NT_THREADS -#define WITH_THREAD -#ifndef NETSCAPE_PI -#define USE_SOCKET -#endif - -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) -#include - -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#define MS_WINDOWS_DESKTOP -#endif -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) -#define MS_WINDOWS_APP -#endif -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM) -#define MS_WINDOWS_SYSTEM -#endif -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES) -#define MS_WINDOWS_GAMES -#endif - -/* Define to 1 if you support windows console io */ -#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) -#define HAVE_WINDOWS_CONSOLE_IO 1 -#endif -#endif /* Py_BUILD_CORE || Py_BUILD_CORE_BUILTIN || Py_BUILD_CORE_MODULE */ - -/* Compiler specific defines */ - -/* ------------------------------------------------------------------------*/ -/* Microsoft C defines _MSC_VER, as does clang-cl.exe */ -#ifdef _MSC_VER - -/* We want COMPILER to expand to a string containing _MSC_VER's *value*. - * This is horridly tricky, because the stringization operator only works - * on macro arguments, and doesn't evaluate macros passed *as* arguments. - */ -#define _Py_PASTE_VERSION(SUFFIX) \ - ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") -/* e.g., this produces, after compile-time string catenation, - * ("[MSC v.1900 64 bit (Intel)]") - * - * _Py_STRINGIZE(_MSC_VER) expands to - * _Py_STRINGIZE1(_MSC_VER) and this second macro call is scanned - * again for macros and so further expands to - * _Py_STRINGIZE1(1900) which then expands to - * "1900" - */ -#define _Py_STRINGIZE(X) _Py_STRINGIZE1(X) -#define _Py_STRINGIZE1(X) #X - -/* MSVC defines _WINxx to differentiate the windows platform types - - Note that for compatibility reasons _WIN32 is defined on Win32 - *and* on Win64. For the same reasons, in Python, MS_WIN32 is - defined on Win32 *and* Win64. Win32 only code must therefore be - guarded as follows: - #if defined(MS_WIN32) && !defined(MS_WIN64) -*/ -#ifdef _WIN64 -#define MS_WIN64 -#endif - -/* set the COMPILER and support tier - * - * win_amd64 MSVC (x86_64-pc-windows-msvc): 1 - * win32 MSVC (i686-pc-windows-msvc): 1 - * win_arm64 MSVC (aarch64-pc-windows-msvc): 3 - * other archs and ICC: 0 - */ -#ifdef MS_WIN64 -#if defined(_M_X64) || defined(_M_AMD64) -#if defined(__clang__) -#define COMPILER ("[Clang " __clang_version__ "] 64 bit (AMD64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#define PY_SUPPORT_TIER 0 -#elif defined(__INTEL_COMPILER) -#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#define PY_SUPPORT_TIER 0 -#else -#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") -#define PY_SUPPORT_TIER 1 -#endif /* __clang__ */ -#define PYD_PLATFORM_TAG "win_amd64" -#elif defined(_M_ARM64) -#define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") -#define PY_SUPPORT_TIER 3 -#define PYD_PLATFORM_TAG "win_arm64" -#else -#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") -#define PY_SUPPORT_TIER 0 -#endif -#endif /* MS_WIN64 */ - -/* set the version macros for the windows headers */ -/* Python 3.9+ requires Windows 8 or greater */ -#define Py_WINVER 0x0602 /* _WIN32_WINNT_WIN8 */ -#define Py_NTDDI NTDDI_WIN8 - -/* We only set these values when building Python - we don't want to force - these values on extensions, as that will affect the prototypes and - structures exposed in the Windows headers. Even when building Python, we - allow a single source file to override this - they may need access to - structures etc so it can optionally use new Windows features if it - determines at runtime they are available. -*/ -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) -#ifndef NTDDI_VERSION -#define NTDDI_VERSION Py_NTDDI -#endif -#ifndef WINVER -#define WINVER Py_WINVER -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT Py_WINVER -#endif -#endif - -/* _W64 is not defined for VC6 or eVC4 */ -#ifndef _W64 -#define _W64 -#endif - -/* Define like size_t, omitting the "unsigned" */ -#ifdef MS_WIN64 -typedef __int64 Py_ssize_t; -# define PY_SSIZE_T_MAX LLONG_MAX -#else -typedef _W64 int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -#endif -#define HAVE_PY_SSIZE_T 1 - -#if defined(MS_WIN32) && !defined(MS_WIN64) -#if defined(_M_IX86) -#if defined(__clang__) -#define COMPILER ("[Clang " __clang_version__ "] 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#define PY_SUPPORT_TIER 0 -#elif defined(__INTEL_COMPILER) -#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#define PY_SUPPORT_TIER 0 -#else -#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") -#define PY_SUPPORT_TIER 1 -#endif /* __clang__ */ -#define PYD_PLATFORM_TAG "win32" -#elif defined(_M_ARM) -#define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") -#define PYD_PLATFORM_TAG "win_arm32" -#define PY_SUPPORT_TIER 0 -#else -#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") -#define PY_SUPPORT_TIER 0 -#endif -#endif /* MS_WIN32 && !MS_WIN64 */ - -typedef int pid_t; - -/* define some ANSI types that are not defined in earlier Win headers */ -#if _MSC_VER >= 1200 -/* This file only exists in VC 6.0 or higher */ -#include -#endif - -#endif /* _MSC_VER */ - -/* ------------------------------------------------------------------------*/ -/* mingw and mingw-w64 define __MINGW32__ */ -#ifdef __MINGW32__ - -#ifdef _WIN64 -#define MS_WIN64 -#endif - -#endif /* __MINGW32__*/ - -/* ------------------------------------------------------------------------*/ -/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ -#if defined(__GNUC__) && defined(_WIN32) -/* XXX These defines are likely incomplete, but should be easy to fix. - They should be complete enough to build extension modules. */ -/* Suggested by Rene Liebscher to avoid a GCC 2.91.* - bug that requires structure imports. More recent versions of the - compiler don't exhibit this bug. -*/ -#if (__GNUC__==2) && (__GNUC_MINOR__<=91) -#warning "Please use an up-to-date version of gcc! (>2.91 recommended)" -#endif - -#define COMPILER "[gcc]" -#define PY_LONG_LONG long long -#define PY_LLONG_MIN LLONG_MIN -#define PY_LLONG_MAX LLONG_MAX -#define PY_ULLONG_MAX ULLONG_MAX -#endif /* GNUC */ - -/* ------------------------------------------------------------------------*/ -/* lcc-win32 defines __LCC__ */ -#if defined(__LCC__) -/* XXX These defines are likely incomplete, but should be easy to fix. - They should be complete enough to build extension modules. */ - -#define COMPILER "[lcc-win32]" -typedef int pid_t; -/* __declspec() is supported here too - do nothing to get the defaults */ - -#endif /* LCC */ - -/* ------------------------------------------------------------------------*/ -/* End of compilers - finish up */ - -#ifndef NO_STDIO_H -# include -#endif - -/* 64 bit ints are usually spelt __int64 unless compiler has overridden */ -#ifndef PY_LONG_LONG -# define PY_LONG_LONG __int64 -# define PY_LLONG_MAX _I64_MAX -# define PY_LLONG_MIN _I64_MIN -# define PY_ULLONG_MAX _UI64_MAX -#endif - -/* For Windows the Python core is in a DLL by default. Test -Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ -#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED) -# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */ -# define MS_COREDLL /* deprecated old symbol */ -#endif /* !MS_NO_COREDLL && ... */ - -/* All windows compilers that use this header support __declspec */ -#define HAVE_DECLSPEC_DLL - -/* For an MSVC DLL, we can nominate the .lib files used by extensions */ -#ifdef MS_COREDLL -# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) - /* not building the core - must be an ext */ -# if defined(_MSC_VER) - /* So MSVC users need not specify the .lib - file in their Makefile (other compilers are - generally taken care of by distutils.) */ -# if defined(_DEBUG) -# pragma comment(lib,"python313_d.lib") -# elif defined(Py_LIMITED_API) -# pragma comment(lib,"python3.lib") -# else -# pragma comment(lib,"python313.lib") -# endif /* _DEBUG */ -# endif /* _MSC_VER */ -# endif /* Py_BUILD_CORE */ -#endif /* MS_COREDLL */ - -#ifdef MS_WIN64 -/* maintain "win32" sys.platform for backward compatibility of Python code, - the Win64 API should be close enough to the Win32 API to make this - preferable */ -# define PLATFORM "win32" -# define SIZEOF_VOID_P 8 -# define SIZEOF_TIME_T 8 -# define SIZEOF_OFF_T 4 -# define SIZEOF_FPOS_T 8 -# define SIZEOF_HKEY 8 -# define SIZEOF_SIZE_T 8 -# define ALIGNOF_SIZE_T 8 -# define ALIGNOF_MAX_ALIGN_T 8 -/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff - sizeof(off_t) > sizeof(long), and sizeof(long long) >= sizeof(off_t). - On Win64 the second condition is not true, but if fpos_t replaces off_t - then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 - should define this. */ -# define HAVE_LARGEFILE_SUPPORT -#elif defined(MS_WIN32) -# define PLATFORM "win32" -# define HAVE_LARGEFILE_SUPPORT -# define SIZEOF_VOID_P 4 -# define SIZEOF_OFF_T 4 -# define SIZEOF_FPOS_T 8 -# define SIZEOF_HKEY 4 -# define SIZEOF_SIZE_T 4 -# define ALIGNOF_SIZE_T 4 - /* MS VS2005 changes time_t to a 64-bit type on all platforms */ -# if defined(_MSC_VER) && _MSC_VER >= 1400 -# define SIZEOF_TIME_T 8 -# else -# define SIZEOF_TIME_T 4 -# endif -# define ALIGNOF_MAX_ALIGN_T 8 -#endif - -#ifdef _DEBUG -# define Py_DEBUG -#endif - - -#ifdef MS_WIN32 - -#define SIZEOF_SHORT 2 -#define SIZEOF_INT 4 -#define SIZEOF_LONG 4 -#define ALIGNOF_LONG 4 -#define SIZEOF_LONG_LONG 8 -#define SIZEOF_DOUBLE 8 -#define SIZEOF_FLOAT 4 - -/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. - Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't - define these. - If some compiler does not provide them, modify the #if appropriately. */ -#if defined(_MSC_VER) -#if _MSC_VER > 1300 -#define HAVE_UINTPTR_T 1 -#define HAVE_INTPTR_T 1 -#else -/* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ -#define Py_LL(x) x##I64 -#endif /* _MSC_VER > 1300 */ -#endif /* _MSC_VER */ - -#endif - -/* define signed and unsigned exact-width 32-bit and 64-bit types, used in the - implementation of Python integers. */ -#define PY_UINT32_T uint32_t -#define PY_UINT64_T uint64_t -#define PY_INT32_T int32_t -#define PY_INT64_T int64_t - -/* Fairly standard from here! */ - -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* #undef _ALL_SOURCE */ -#endif - -/* Define to empty if the keyword does not work. */ -/* #define const */ - -/* Define to 1 if you have the header file. */ -#define HAVE_CONIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DIRECT_H 1 - -/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. - */ -#define HAVE_DECL_TZNAME 1 - -/* Define if you have dirent.h. */ -/* #define DIRENT 1 */ - -/* Define to the type of elements in the array set by `getgroups'. - Usually this is either `int' or `gid_t'. */ -/* #undef GETGROUPS_T */ - -/* Define to `int' if doesn't define. */ -/* #undef gid_t */ - -/* Define if your struct tm has tm_zone. */ -/* #undef HAVE_TM_ZONE */ - -/* Define if you don't have tm_zone but do have the external array - tzname. */ -#define HAVE_TZNAME - -/* Define to `int' if doesn't define. */ -/* #undef mode_t */ - -/* Define if you don't have dirent.h, but have ndir.h. */ -/* #undef NDIR */ - -/* Define to `long' if doesn't define. */ -/* #undef off_t */ - -/* Define to `int' if doesn't define. */ -/* #undef pid_t */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define as the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define to `unsigned' if doesn't define. */ -/* #undef size_t */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you don't have dirent.h, but have sys/dir.h. */ -/* #undef SYSDIR */ - -/* Define if you don't have dirent.h, but have sys/ndir.h. */ -/* #undef SYSNDIR */ - -/* Define if you can safely include both and . */ -/* #undef TIME_WITH_SYS_TIME */ - -/* Define if your declares struct tm. */ -/* #define TM_IN_SYS_TIME 1 */ - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define if the closedir function returns void instead of int. */ -/* #undef VOID_CLOSEDIR */ - -/* Define if getpgrp() must be called as getpgrp(0) - and (consequently) setpgrp() as setpgrp(0, 0). */ -/* #undef GETPGRP_HAVE_ARGS */ - -/* Define this if your time.h defines altzone */ -/* #define HAVE_ALTZONE */ - -/* Define if you have the putenv function. */ -#define HAVE_PUTENV - -/* Define if your compiler supports function prototypes */ -#define HAVE_PROTOTYPES - -/* Define if you can safely include both and - (which you can't on SCO ODT 3.0). */ -/* #undef SYS_SELECT_WITH_SYS_TIME */ - -/* Define if you want build the _decimal module using a coroutine-local rather - than a thread-local context */ -#define WITH_DECIMAL_CONTEXTVAR 1 - -/* Define if you want documentation strings in extension modules */ -#define WITH_DOC_STRINGS 1 - -/* Define if you want to compile in rudimentary thread support */ -/* #undef WITH_THREAD */ - -/* Define if you want to use the GNU readline library */ -/* #define WITH_READLINE 1 */ - -/* Use Python's own small-block memory-allocator. */ -#define WITH_PYMALLOC 1 - -/* Define if you want to compile in object freelists optimization */ -#define WITH_FREELISTS 1 - -/* Define if you have clock. */ -/* #define HAVE_CLOCK */ - -/* Define when any dynamic module loading is enabled */ -#define HAVE_DYNAMIC_LOADING - -/* Define if you have ftime. */ -#define HAVE_FTIME - -/* Define if you have getpeername. */ -#define HAVE_GETPEERNAME - -/* Define if you have getpgrp. */ -/* #undef HAVE_GETPGRP */ - -/* Define if you have getpid. */ -#define HAVE_GETPID - -/* Define if you have gettimeofday. */ -/* #undef HAVE_GETTIMEOFDAY */ - -/* Define if you have getwd. */ -/* #undef HAVE_GETWD */ - -/* Define if you have lstat. */ -/* #undef HAVE_LSTAT */ - -/* Define if you have the mktime function. */ -#define HAVE_MKTIME - -/* Define if you have nice. */ -/* #undef HAVE_NICE */ - -/* Define if you have readlink. */ -/* #undef HAVE_READLINK */ - -/* Define if you have setpgid. */ -/* #undef HAVE_SETPGID */ - -/* Define if you have setpgrp. */ -/* #undef HAVE_SETPGRP */ - -/* Define if you have setsid. */ -/* #undef HAVE_SETSID */ - -/* Define if you have setvbuf. */ -#define HAVE_SETVBUF - -/* Define if you have siginterrupt. */ -/* #undef HAVE_SIGINTERRUPT */ - -/* Define to 1 if you have the `shutdown' function. */ -#define HAVE_SHUTDOWN 1 - -/* Define if you have symlink. */ -/* #undef HAVE_SYMLINK */ - -/* Define if you have tcgetpgrp. */ -/* #undef HAVE_TCGETPGRP */ - -/* Define if you have tcsetpgrp. */ -/* #undef HAVE_TCSETPGRP */ - -/* Define if you have times. */ -/* #undef HAVE_TIMES */ - -/* Define to 1 if you have the `umask' function. */ -#define HAVE_UMASK 1 - -/* Define if you have uname. */ -/* #undef HAVE_UNAME */ - -/* Define if you have waitpid. */ -/* #undef HAVE_WAITPID */ - -/* Define to 1 if you have the `wcsftime' function. */ -#if defined(_MSC_VER) && _MSC_VER >= 1310 -#define HAVE_WCSFTIME 1 -#endif - -/* Define to 1 if you have the `wcscoll' function. */ -#define HAVE_WCSCOLL 1 - -/* Define to 1 if you have the `wcsxfrm' function. */ -#define HAVE_WCSXFRM 1 - -/* Define if the zlib library has inflateCopy */ -#define HAVE_ZLIB_COPY 1 - -/* Define if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_PROCESS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDDEF_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_AUDIOIO_H */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_PARAM_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SELECT_H 1 */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SYS_TIME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_TIMES_H 1 */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SYS_UN_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_UTIME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_UTSNAME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_UNISTD_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_UTIME_H 1 */ - -/* Define if the compiler provides a wchar.h header file. */ -#define HAVE_WCHAR_H 1 - -/* The size of `wchar_t', as computed by sizeof. */ -#define SIZEOF_WCHAR_T 2 - -/* The size of `_Bool', as computed by sizeof. */ -#define SIZEOF__BOOL 1 - -/* The size of `pid_t', as computed by sizeof. */ -#define SIZEOF_PID_T SIZEOF_INT - -/* Define if you have the dl library (-ldl). */ -/* #undef HAVE_LIBDL */ - -/* Define if you have the mpc library (-lmpc). */ -/* #undef HAVE_LIBMPC */ - -/* Define if you have the seq library (-lseq). */ -/* #undef HAVE_LIBSEQ */ - -/* Define if you have the socket library (-lsocket). */ -#define HAVE_LIBSOCKET 1 - -/* Define if you have the sun library (-lsun). */ -/* #undef HAVE_LIBSUN */ - -/* Define if you have the termcap library (-ltermcap). */ -/* #undef HAVE_LIBTERMCAP */ - -/* Define if you have the termlib library (-ltermlib). */ -/* #undef HAVE_LIBTERMLIB */ - -/* Define if you have the thread library (-lthread). */ -/* #undef HAVE_LIBTHREAD */ - -/* WinSock does not use a bitmask in select, and uses - socket handles greater than FD_SETSIZE */ -#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE - -/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the - least significant byte first */ -#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 - -/* Define to 1 if you have the `erf' function. */ -#define HAVE_ERF 1 - -/* Define to 1 if you have the `erfc' function. */ -#define HAVE_ERFC 1 - -// netdb.h functions (provided by winsock.h) -#define HAVE_GETHOSTNAME 1 -#define HAVE_GETHOSTBYADDR 1 -#define HAVE_GETHOSTBYNAME 1 -#define HAVE_GETPROTOBYNAME 1 -#define HAVE_GETSERVBYNAME 1 -#define HAVE_GETSERVBYPORT 1 -// sys/socket.h functions (provided by winsock.h) -#define HAVE_INET_PTON 1 -#define HAVE_INET_NTOA 1 -#define HAVE_ACCEPT 1 -#define HAVE_BIND 1 -#define HAVE_CONNECT 1 -#define HAVE_GETSOCKNAME 1 -#define HAVE_LISTEN 1 -#define HAVE_RECVFROM 1 -#define HAVE_SENDTO 1 -#define HAVE_SETSOCKOPT 1 -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the `dup' function. */ -#define HAVE_DUP 1 - -/* framework name */ -#define _PYTHONFRAMEWORK "" - -/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ -#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 - -#endif /* !Py_CONFIG_H */ diff --git a/PC/pyconfig.h.in b/PC/pyconfig.h.in new file mode 100644 index 00000000000000..d8f0a6be69c21a --- /dev/null +++ b/PC/pyconfig.h.in @@ -0,0 +1,745 @@ +#ifndef Py_CONFIG_H +#define Py_CONFIG_H + +/* pyconfig.h. NOT Generated automatically by configure. + +This is a manually maintained version used for the Watcom, +Borland and Microsoft Visual C++ compilers. It is a +standard part of the Python distribution. + +WINDOWS DEFINES: +The code specific to Windows should be wrapped around one of +the following #defines + +MS_WIN64 - Code specific to the MS Win64 API +MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) +MS_WINDOWS - Code specific to Windows, but all versions. +Py_ENABLE_SHARED - Code if the Python core is built as a DLL. + +Also note that neither "_M_IX86" or "_MSC_VER" should be used for +any purpose other than "Windows Intel x86 specific" and "Microsoft +compiler specific". Therefore, these should be very rare. + + +NOTE: The following symbols are deprecated: +NT, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT +MS_CORE_DLL. + +WIN32 is still required for the locale module. + +*/ + +/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ +#ifdef USE_DL_EXPORT +# define Py_BUILD_CORE +#endif /* USE_DL_EXPORT */ + +/* Visual Studio 2005 introduces deprecation warnings for + "insecure" and POSIX functions. The insecure functions should + be replaced by *_s versions (according to Microsoft); the + POSIX functions by _* versions (which, according to Microsoft, + would be ISO C conforming). Neither renaming is feasible, so + we just silence the warnings. */ + +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +#define HAVE_IO_H +#define HAVE_SYS_UTIME_H +#define HAVE_TEMPNAM +#define HAVE_TMPFILE +#define HAVE_TMPNAM +#define HAVE_CLOCK +#define HAVE_STRERROR + +#include + +#define HAVE_STRFTIME +#define DONT_HAVE_SIG_ALARM +#define DONT_HAVE_SIG_PAUSE +#define LONG_BIT 32 +#define WORD_BIT 32 + +#define MS_WIN32 /* only support win32 and greater. */ +#define MS_WINDOWS +#define NT_THREADS +#define WITH_THREAD +#ifndef NETSCAPE_PI +#define USE_SOCKET +#endif + +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) +#include + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define MS_WINDOWS_DESKTOP +#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define MS_WINDOWS_APP +#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM) +#define MS_WINDOWS_SYSTEM +#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES) +#define MS_WINDOWS_GAMES +#endif + +/* Define to 1 if you support windows console io */ +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) +#define HAVE_WINDOWS_CONSOLE_IO 1 +#endif +#endif /* Py_BUILD_CORE || Py_BUILD_CORE_BUILTIN || Py_BUILD_CORE_MODULE */ + +/* Compiler specific defines */ + +/* ------------------------------------------------------------------------*/ +/* Microsoft C defines _MSC_VER, as does clang-cl.exe */ +#ifdef _MSC_VER + +/* We want COMPILER to expand to a string containing _MSC_VER's *value*. + * This is horridly tricky, because the stringization operator only works + * on macro arguments, and doesn't evaluate macros passed *as* arguments. + */ +#define _Py_PASTE_VERSION(SUFFIX) \ + ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") +/* e.g., this produces, after compile-time string catenation, + * ("[MSC v.1900 64 bit (Intel)]") + * + * _Py_STRINGIZE(_MSC_VER) expands to + * _Py_STRINGIZE1(_MSC_VER) and this second macro call is scanned + * again for macros and so further expands to + * _Py_STRINGIZE1(1900) which then expands to + * "1900" + */ +#define _Py_STRINGIZE(X) _Py_STRINGIZE1(X) +#define _Py_STRINGIZE1(X) #X + +/* MSVC defines _WINxx to differentiate the windows platform types + + Note that for compatibility reasons _WIN32 is defined on Win32 + *and* on Win64. For the same reasons, in Python, MS_WIN32 is + defined on Win32 *and* Win64. Win32 only code must therefore be + guarded as follows: + #if defined(MS_WIN32) && !defined(MS_WIN64) +*/ +#ifdef _WIN64 +#define MS_WIN64 +#endif + +/* set the COMPILER and support tier + * + * win_amd64 MSVC (x86_64-pc-windows-msvc): 1 + * win32 MSVC (i686-pc-windows-msvc): 1 + * win_arm64 MSVC (aarch64-pc-windows-msvc): 3 + * other archs and ICC: 0 + */ +#ifdef MS_WIN64 +#if defined(_M_X64) || defined(_M_AMD64) +#if defined(__clang__) +#define COMPILER ("[Clang " __clang_version__ "] 64 bit (AMD64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#elif defined(__INTEL_COMPILER) +#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#else +#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") +#define PY_SUPPORT_TIER 1 +#endif /* __clang__ */ +#define PYD_PLATFORM_TAG "win_amd64" +#elif defined(_M_ARM64) +#define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") +#define PY_SUPPORT_TIER 3 +#define PYD_PLATFORM_TAG "win_arm64" +#else +#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") +#define PY_SUPPORT_TIER 0 +#endif +#endif /* MS_WIN64 */ + +/* set the version macros for the windows headers */ +/* Python 3.9+ requires Windows 8 or greater */ +#define Py_WINVER 0x0602 /* _WIN32_WINNT_WIN8 */ +#define Py_NTDDI NTDDI_WIN8 + +/* We only set these values when building Python - we don't want to force + these values on extensions, as that will affect the prototypes and + structures exposed in the Windows headers. Even when building Python, we + allow a single source file to override this - they may need access to + structures etc so it can optionally use new Windows features if it + determines at runtime they are available. +*/ +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) +#ifndef NTDDI_VERSION +#define NTDDI_VERSION Py_NTDDI +#endif +#ifndef WINVER +#define WINVER Py_WINVER +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT Py_WINVER +#endif +#endif + +/* _W64 is not defined for VC6 or eVC4 */ +#ifndef _W64 +#define _W64 +#endif + +/* Define like size_t, omitting the "unsigned" */ +#ifdef MS_WIN64 +typedef __int64 Py_ssize_t; +# define PY_SSIZE_T_MAX LLONG_MAX +#else +typedef _W64 int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +#endif +#define HAVE_PY_SSIZE_T 1 + +#if defined(MS_WIN32) && !defined(MS_WIN64) +#if defined(_M_IX86) +#if defined(__clang__) +#define COMPILER ("[Clang " __clang_version__ "] 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#elif defined(__INTEL_COMPILER) +#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#else +#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#define PY_SUPPORT_TIER 1 +#endif /* __clang__ */ +#define PYD_PLATFORM_TAG "win32" +#elif defined(_M_ARM) +#define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") +#define PYD_PLATFORM_TAG "win_arm32" +#define PY_SUPPORT_TIER 0 +#else +#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") +#define PY_SUPPORT_TIER 0 +#endif +#endif /* MS_WIN32 && !MS_WIN64 */ + +typedef int pid_t; + +/* define some ANSI types that are not defined in earlier Win headers */ +#if _MSC_VER >= 1200 +/* This file only exists in VC 6.0 or higher */ +#include +#endif + +#endif /* _MSC_VER */ + +/* ------------------------------------------------------------------------*/ +/* mingw and mingw-w64 define __MINGW32__ */ +#ifdef __MINGW32__ + +#ifdef _WIN64 +#define MS_WIN64 +#endif + +#endif /* __MINGW32__*/ + +/* ------------------------------------------------------------------------*/ +/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ +#if defined(__GNUC__) && defined(_WIN32) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ +/* Suggested by Rene Liebscher to avoid a GCC 2.91.* + bug that requires structure imports. More recent versions of the + compiler don't exhibit this bug. +*/ +#if (__GNUC__==2) && (__GNUC_MINOR__<=91) +#warning "Please use an up-to-date version of gcc! (>2.91 recommended)" +#endif + +#define COMPILER "[gcc]" +#define PY_LONG_LONG long long +#define PY_LLONG_MIN LLONG_MIN +#define PY_LLONG_MAX LLONG_MAX +#define PY_ULLONG_MAX ULLONG_MAX +#endif /* GNUC */ + +/* ------------------------------------------------------------------------*/ +/* lcc-win32 defines __LCC__ */ +#if defined(__LCC__) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ + +#define COMPILER "[lcc-win32]" +typedef int pid_t; +/* __declspec() is supported here too - do nothing to get the defaults */ + +#endif /* LCC */ + +/* ------------------------------------------------------------------------*/ +/* End of compilers - finish up */ + +#ifndef NO_STDIO_H +# include +#endif + +/* 64 bit ints are usually spelt __int64 unless compiler has overridden */ +#ifndef PY_LONG_LONG +# define PY_LONG_LONG __int64 +# define PY_LLONG_MAX _I64_MAX +# define PY_LLONG_MIN _I64_MIN +# define PY_ULLONG_MAX _UI64_MAX +#endif + +/* For Windows the Python core is in a DLL by default. Test +Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ +#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED) +# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */ +# define MS_COREDLL /* deprecated old symbol */ +#endif /* !MS_NO_COREDLL && ... */ + +/* All windows compilers that use this header support __declspec */ +#define HAVE_DECLSPEC_DLL + +/* For an MSVC DLL, we can nominate the .lib files used by extensions */ +#ifdef MS_COREDLL +# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) + /* not building the core - must be an ext */ +# if defined(_MSC_VER) + /* So MSVC users need not specify the .lib + file in their Makefile (other compilers are + generally taken care of by distutils.) */ +# if defined(_DEBUG) +# pragma comment(lib,"python313_d.lib") +# elif defined(Py_LIMITED_API) +# pragma comment(lib,"python3.lib") +# else +# pragma comment(lib,"python313.lib") +# endif /* _DEBUG */ +# endif /* _MSC_VER */ +# endif /* Py_BUILD_CORE */ +#endif /* MS_COREDLL */ + +#ifdef MS_WIN64 +/* maintain "win32" sys.platform for backward compatibility of Python code, + the Win64 API should be close enough to the Win32 API to make this + preferable */ +# define PLATFORM "win32" +# define SIZEOF_VOID_P 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 8 +# define SIZEOF_SIZE_T 8 +# define ALIGNOF_SIZE_T 8 +# define ALIGNOF_MAX_ALIGN_T 8 +/* configure.ac defines HAVE_LARGEFILE_SUPPORT iff + sizeof(off_t) > sizeof(long), and sizeof(long long) >= sizeof(off_t). + On Win64 the second condition is not true, but if fpos_t replaces off_t + then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 + should define this. */ +# define HAVE_LARGEFILE_SUPPORT +#elif defined(MS_WIN32) +# define PLATFORM "win32" +# define HAVE_LARGEFILE_SUPPORT +# define SIZEOF_VOID_P 4 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 4 +# define SIZEOF_SIZE_T 4 +# define ALIGNOF_SIZE_T 4 + /* MS VS2005 changes time_t to a 64-bit type on all platforms */ +# if defined(_MSC_VER) && _MSC_VER >= 1400 +# define SIZEOF_TIME_T 8 +# else +# define SIZEOF_TIME_T 4 +# endif +# define ALIGNOF_MAX_ALIGN_T 8 +#endif + +#ifdef _DEBUG +# define Py_DEBUG +#endif + + +#ifdef MS_WIN32 + +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define ALIGNOF_LONG 4 +#define SIZEOF_LONG_LONG 8 +#define SIZEOF_DOUBLE 8 +#define SIZEOF_FLOAT 4 + +/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. + Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't + define these. + If some compiler does not provide them, modify the #if appropriately. */ +#if defined(_MSC_VER) +#if _MSC_VER > 1300 +#define HAVE_UINTPTR_T 1 +#define HAVE_INTPTR_T 1 +#else +/* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ +#define Py_LL(x) x##I64 +#endif /* _MSC_VER > 1300 */ +#endif /* _MSC_VER */ + +#endif + +/* define signed and unsigned exact-width 32-bit and 64-bit types, used in the + implementation of Python integers. */ +#define PY_UINT32_T uint32_t +#define PY_UINT64_T uint64_t +#define PY_INT32_T int32_t +#define PY_INT64_T int64_t + +/* Fairly standard from here! */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define to empty if the keyword does not work. */ +/* #define const */ + +/* Define to 1 if you have the header file. */ +#define HAVE_CONIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRECT_H 1 + +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +#define HAVE_DECL_TZNAME 1 + +/* Define if you have dirent.h. */ +/* #define DIRENT 1 */ + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +/* #undef GETGROUPS_T */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#define HAVE_TZNAME + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define if you don't have dirent.h, but have ndir.h. */ +/* #undef NDIR */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you don't have dirent.h, but have sys/dir.h. */ +/* #undef SYSDIR */ + +/* Define if you don't have dirent.h, but have sys/ndir.h. */ +/* #undef SYSNDIR */ + +/* Define if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define if your declares struct tm. */ +/* #define TM_IN_SYS_TIME 1 */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef VOID_CLOSEDIR */ + +/* Define if getpgrp() must be called as getpgrp(0) + and (consequently) setpgrp() as setpgrp(0, 0). */ +/* #undef GETPGRP_HAVE_ARGS */ + +/* Define this if your time.h defines altzone */ +/* #define HAVE_ALTZONE */ + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV + +/* Define if your compiler supports function prototypes */ +#define HAVE_PROTOTYPES + +/* Define if you can safely include both and + (which you can't on SCO ODT 3.0). */ +/* #undef SYS_SELECT_WITH_SYS_TIME */ + +/* Define if you want build the _decimal module using a coroutine-local rather + than a thread-local context */ +#define WITH_DECIMAL_CONTEXTVAR 1 + +/* Define if you want documentation strings in extension modules */ +#define WITH_DOC_STRINGS 1 + +/* Define if you want to compile in rudimentary thread support */ +/* #undef WITH_THREAD */ + +/* Define if you want to use the GNU readline library */ +/* #define WITH_READLINE 1 */ + +/* Use Python's own small-block memory-allocator. */ +#define WITH_PYMALLOC 1 + +/* Define if you want to compile in mimalloc memory allocator. */ +#define WITH_MIMALLOC 1 + +/* Define if you want to compile in object freelists optimization */ +#define WITH_FREELISTS 1 + +/* Define if you have clock. */ +/* #define HAVE_CLOCK */ + +/* Define when any dynamic module loading is enabled */ +#define HAVE_DYNAMIC_LOADING + +/* Define if you have ftime. */ +#define HAVE_FTIME + +/* Define if you have getpeername. */ +#define HAVE_GETPEERNAME + +/* Define if you have getpgrp. */ +/* #undef HAVE_GETPGRP */ + +/* Define if you have getpid. */ +#define HAVE_GETPID + +/* Define if you have gettimeofday. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define if you have getwd. */ +/* #undef HAVE_GETWD */ + +/* Define if you have lstat. */ +/* #undef HAVE_LSTAT */ + +/* Define if you have the mktime function. */ +#define HAVE_MKTIME + +/* Define if you have nice. */ +/* #undef HAVE_NICE */ + +/* Define if you have readlink. */ +/* #undef HAVE_READLINK */ + +/* Define if you have setpgid. */ +/* #undef HAVE_SETPGID */ + +/* Define if you have setpgrp. */ +/* #undef HAVE_SETPGRP */ + +/* Define if you have setsid. */ +/* #undef HAVE_SETSID */ + +/* Define if you have setvbuf. */ +#define HAVE_SETVBUF + +/* Define if you have siginterrupt. */ +/* #undef HAVE_SIGINTERRUPT */ + +/* Define to 1 if you have the `shutdown' function. */ +#define HAVE_SHUTDOWN 1 + +/* Define if you have symlink. */ +/* #undef HAVE_SYMLINK */ + +/* Define if you have tcgetpgrp. */ +/* #undef HAVE_TCGETPGRP */ + +/* Define if you have tcsetpgrp. */ +/* #undef HAVE_TCSETPGRP */ + +/* Define if you have times. */ +/* #undef HAVE_TIMES */ + +/* Define to 1 if you have the `umask' function. */ +#define HAVE_UMASK 1 + +/* Define if you have uname. */ +/* #undef HAVE_UNAME */ + +/* Define if you have waitpid. */ +/* #undef HAVE_WAITPID */ + +/* Define to 1 if you have the `wcsftime' function. */ +#if defined(_MSC_VER) && _MSC_VER >= 1310 +#define HAVE_WCSFTIME 1 +#endif + +/* Define to 1 if you have the `wcscoll' function. */ +#define HAVE_WCSCOLL 1 + +/* Define to 1 if you have the `wcsxfrm' function. */ +#define HAVE_WCSXFRM 1 + +/* Define if the zlib library has inflateCopy */ +#define HAVE_ZLIB_COPY 1 + +/* Define if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PROCESS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_AUDIOIO_H */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SELECT_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIMES_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UN_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTSNAME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_UNISTD_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_UTIME_H 1 */ + +/* Define if the compiler provides a wchar.h header file. */ +#define HAVE_WCHAR_H 1 + +/* The size of `wchar_t', as computed by sizeof. */ +#define SIZEOF_WCHAR_T 2 + +/* The size of `_Bool', as computed by sizeof. */ +#define SIZEOF__BOOL 1 + +/* The size of `pid_t', as computed by sizeof. */ +#define SIZEOF_PID_T SIZEOF_INT + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define if you have the mpc library (-lmpc). */ +/* #undef HAVE_LIBMPC */ + +/* Define if you have the seq library (-lseq). */ +/* #undef HAVE_LIBSEQ */ + +/* Define if you have the socket library (-lsocket). */ +#define HAVE_LIBSOCKET 1 + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Define if you have the termcap library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define if you have the termlib library (-ltermlib). */ +/* #undef HAVE_LIBTERMLIB */ + +/* Define if you have the thread library (-lthread). */ +/* #undef HAVE_LIBTHREAD */ + +/* WinSock does not use a bitmask in select, and uses + socket handles greater than FD_SETSIZE */ +#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 + +/* Define to 1 if you have the `erf' function. */ +#define HAVE_ERF 1 + +/* Define to 1 if you have the `erfc' function. */ +#define HAVE_ERFC 1 + +// netdb.h functions (provided by winsock.h) +#define HAVE_GETHOSTNAME 1 +#define HAVE_GETHOSTBYADDR 1 +#define HAVE_GETHOSTBYNAME 1 +#define HAVE_GETPROTOBYNAME 1 +#define HAVE_GETSERVBYNAME 1 +#define HAVE_GETSERVBYPORT 1 +// sys/socket.h functions (provided by winsock.h) +#define HAVE_INET_PTON 1 +#define HAVE_INET_NTOA 1 +#define HAVE_ACCEPT 1 +#define HAVE_BIND 1 +#define HAVE_CONNECT 1 +#define HAVE_GETSOCKNAME 1 +#define HAVE_LISTEN 1 +#define HAVE_RECVFROM 1 +#define HAVE_SENDTO 1 +#define HAVE_SETSOCKOPT 1 +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the `dup' function. */ +#define HAVE_DUP 1 + +/* framework name */ +#define _PYTHONFRAMEWORK "" + +/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ +#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 + +/* Define if you want to disable the GIL */ +#undef Py_GIL_DISABLED + +#endif /* !Py_CONFIG_H */ diff --git a/PC/python3dll.c b/PC/python3dll.c index 2c1cc8098ce856..07aa84c91f9fc7 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -19,6 +19,7 @@ EXPORT_FUNC(_Py_Dealloc) EXPORT_FUNC(_Py_DecRef) EXPORT_FUNC(_Py_IncRef) EXPORT_FUNC(_Py_NegativeRefcount) +EXPORT_FUNC(_Py_SetRefcnt) EXPORT_FUNC(_Py_VaBuildValue_SizeT) EXPORT_FUNC(_PyArg_Parse_SizeT) EXPORT_FUNC(_PyArg_ParseTuple_SizeT) @@ -69,6 +70,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) @@ -372,6 +374,10 @@ EXPORT_FUNC(PyMarshal_WriteObjectToString) EXPORT_FUNC(PyMem_Calloc) EXPORT_FUNC(PyMem_Free) EXPORT_FUNC(PyMem_Malloc) +EXPORT_FUNC(PyMem_RawCalloc) +EXPORT_FUNC(PyMem_RawFree) +EXPORT_FUNC(PyMem_RawMalloc) +EXPORT_FUNC(PyMem_RawRealloc) EXPORT_FUNC(PyMem_Realloc) EXPORT_FUNC(PyMember_GetOne) EXPORT_FUNC(PyMember_SetOne) @@ -563,6 +569,8 @@ EXPORT_FUNC(PyStructSequence_SetItem) EXPORT_FUNC(PySys_AddWarnOption) EXPORT_FUNC(PySys_AddWarnOptionUnicode) EXPORT_FUNC(PySys_AddXOption) +EXPORT_FUNC(PySys_Audit) +EXPORT_FUNC(PySys_AuditTuple) EXPORT_FUNC(PySys_FormatStderr) EXPORT_FUNC(PySys_FormatStdout) EXPORT_FUNC(PySys_GetObject) @@ -688,6 +696,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/winsound.c b/PC/winsound.c index 68a917810f884d..7e4ebd90f50c2e 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -35,6 +35,13 @@ winsound.PlaySound(None, 0) */ +#include "pyconfig.h" // Py_GIL_DISABLED + +#ifndef Py_GIL_DISABLED +// Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030c0000 +#endif + #include #include #include @@ -95,9 +102,13 @@ winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags) } wsound = (wchar_t *)view.buf; } else if (PyBytes_Check(sound)) { - PyErr_Format(PyExc_TypeError, - "'sound' must be str, os.PathLike, or None, not '%s'", - Py_TYPE(sound)->tp_name); + PyObject *type_name = PyType_GetQualName(Py_TYPE(sound)); + if (type_name != NULL) { + PyErr_Format(PyExc_TypeError, + "'sound' must be str, os.PathLike, or None, not %S", + type_name); + Py_DECREF(type_name); + } return NULL; } else { PyObject *obj = PyOS_FSPath(sound); diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index bdcf29ba44dab5..f8c5fafa561efa 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -89,6 +89,7 @@ Py_NO_ENABLE_SHARED;Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions) + $(IntDir);%(AdditionalIncludeDirectories) Disabled false @@ -172,7 +173,14 @@ - + + + + + + + + @@ -188,11 +196,12 @@ + + - @@ -213,12 +222,14 @@ + + @@ -247,6 +258,9 @@ + + + @@ -374,9 +388,62 @@ $(PySourcePath)Python\frozen_modules\getpath.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @(PyConfigH->'%(FullPath)', ';') + $([System.IO.File]::ReadAllText($(PyConfigH))) + $([System.IO.File]::ReadAllText('$(IntDir)pyconfig.h')) + + + $(PyConfigHText.Replace('#undef Py_GIL_DISABLED', '#define Py_GIL_DISABLED 1')) + + + + + @@ -405,32 +472,19 @@ AfterTargets="_RebuildFrozen" DependsOnTargets="FindPythonForBuild" Condition="$(Configuration) != 'PGUpdate'"> + + + +$(IntDir)\deepfreeze_mappings.txt + + + + - + diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 45333fa97f1c64..1c5a6d623f4dad 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -103,6 +103,12 @@ Source Files + + Source Files + + + Source Files + Source Files @@ -124,9 +130,6 @@ Source Files - - Source Files - Source Files @@ -223,6 +226,9 @@ Source Files + + Source Files + Source Files @@ -289,6 +295,9 @@ Source Files + + Source Files + Source Files @@ -397,7 +406,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 0a02929db438b8..1c15541d3ec735 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -100,20 +100,31 @@ + + + + + + + + + + + diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index 4ba6011d8af5b9..6059959bb9a040 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -30,12 +30,27 @@ Source Files + + Source Files + + + Source Files + Source Files Source Files + + Source Files + + + Source Files + + + Source Files + Source Files @@ -54,6 +69,12 @@ Source Files + + Source Files + + + Source Files + Source Files @@ -72,6 +93,18 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + Source Files diff --git a/PCbuild/_testinternalcapi.vcxproj b/PCbuild/_testinternalcapi.vcxproj index fb474f06f38fe8..558f66ca95cd33 100644 --- a/PCbuild/_testinternalcapi.vcxproj +++ b/PCbuild/_testinternalcapi.vcxproj @@ -95,7 +95,9 @@ + + diff --git a/PCbuild/_testinternalcapi.vcxproj.filters b/PCbuild/_testinternalcapi.vcxproj.filters index 9c8a5d793ee0f4..abfeeb39630daf 100644 --- a/PCbuild/_testinternalcapi.vcxproj.filters +++ b/PCbuild/_testinternalcapi.vcxproj.filters @@ -15,6 +15,9 @@ Source Files + + Source Files + Source Files diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index fc43ce2b1835d0..6151990096e0be 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,9 +54,9 @@ 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.11 -set libraries=%libraries% sqlite-3.42.0.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% sqlite-3.43.1.0 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.1 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.1 set libraries=%libraries% xz-5.2.5 set libraries=%libraries% zlib-1.2.13 @@ -77,7 +77,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.11 -if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.13.0 +if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.13.1 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 for %%b in (%binaries%) do ( diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 9db400eebae388..68c0550f7603b7 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -10,6 +10,8 @@ $(MSBuildThisFileDirectory)obj\ $(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\$(ProjectName)\ $(IntDir.Replace(`\\`, `\`)) + + $(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\pythoncore\ $(ProjectName) $(TargetName)$(PyDebugExt) false @@ -38,9 +40,9 @@ - $(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories) + $(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)Include\internal\mimalloc;$(GeneratedPyConfigDir);$(PySourcePath)PC;%(AdditionalIncludeDirectories) WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) - Py_NOGIL=1;%(PreprocessorDefinitions) + _Py_USING_PGO=1;%(PreprocessorDefinitions) MaxSpeed true @@ -59,6 +61,7 @@ -Wno-deprecated-non-prototype -Wno-unused-label -Wno-pointer-sign -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-function %(AdditionalOptions) -flto %(AdditionalOptions) -d2pattern-opt-disable:-932189325 %(AdditionalOptions) + /sourceDependencies "$(IntDir.Trim(`\`))" %(AdditionalOptions) OnlyExplicitInline @@ -233,7 +236,10 @@ public override bool Execute() { - + + + + diff --git a/PCbuild/python.props b/PCbuild/python.props index 35c6e92be45dc9..496bc3dd4cf794 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -68,7 +68,7 @@ - $(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\ diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index f4640454a73070..8b733865962373 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -95,7 +95,7 @@ Console 2000000 - 8000000 + 12000000 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 1ec106777db56d..90aa8cf28f8c5d 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -158,7 +158,6 @@ - @@ -173,6 +172,7 @@ + @@ -203,7 +203,6 @@ - @@ -218,6 +217,8 @@ + + @@ -240,6 +241,7 @@ + @@ -283,6 +285,7 @@ + @@ -301,6 +304,12 @@ + + + + + + @@ -361,13 +370,16 @@ - + + + + + - + - @@ -438,6 +450,7 @@ + @@ -445,6 +458,7 @@ + @@ -506,7 +520,14 @@ - + + + + + + + + @@ -531,10 +552,11 @@ + + - @@ -624,6 +646,35 @@ + + + + + + + + + + @(PyConfigH->'%(FullPath)', ';') + $([System.IO.File]::ReadAllText($(PyConfigH))) + $([System.IO.File]::ReadAllText('$(IntDir)pyconfig.h')) + + + $(PyConfigHText.Replace('#undef Py_GIL_DISABLED', '#define Py_GIL_DISABLED 1')) + + + + + + + + + + + git diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index f381120c9b035a..a96ca24cf08b66 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -4,6 +4,9 @@ {086b0afb-270c-4603-a02a-63d46f0b2b92} + + {1dc8d8bd-d493-478e-9b7a-7eb108bb8bd5} + {8e81609f-13ca-4eae-9fdb-f8af20c710c7} @@ -19,6 +22,9 @@ {ab29a558-143d-4fe7-a039-b431fb429856} + + {ad449c55-23cb-44f8-ada4-04b23c9ec388} + {97349fee-0abf-48b0-a8f5-771bf39b8aee} @@ -291,7 +297,19 @@ Objects - + + Parser + + + Parser + + + Parser + + + Parser + + Parser @@ -300,9 +318,6 @@ PC - - Python - Python @@ -408,9 +423,6 @@ Include\cpython - - Include\cpython - Include\cpython @@ -456,6 +468,9 @@ Include\cpython + + Include\cpython + Include\cpython @@ -528,9 +543,6 @@ Include\internal - - Include\internal - Include\internal @@ -570,6 +582,12 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -633,6 +651,9 @@ Include\internal + + Include\internal + Include\internal @@ -759,6 +780,9 @@ Include\internal + + Include\internal + Include\internal @@ -777,6 +801,24 @@ Include\internal + + Include\internal\mimalloc + + + Include\internal\mimalloc + + + Include\internal\mimalloc + + + Include\internal\mimalloc + + + Include\internal\mimalloc + + + Include\internal\mimalloc + Modules\zlib @@ -959,6 +1001,9 @@ Modules + + Modules + Modules @@ -1136,7 +1181,28 @@ Parser - + + Parser + + + Parser + + + Parser + + + Parser + + + Parser + + + Parser + + + Parser + + Parser @@ -1184,6 +1250,12 @@ Python + + Python + + + Source Files + Python @@ -1193,9 +1265,6 @@ Python - - Python - Python @@ -1436,6 +1505,9 @@ Modules + + Modules + Parser diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 199aacdf7687ed..175ce918ac20f6 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -189,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 @@ -293,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/rt.bat b/PCbuild/rt.bat index 7ae7141bfc4eaa..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=--fail-env-changed --fail-rerun +set regrtestargs=--fast-ci set exe= :CheckOpts diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props index 96dd289face6a5..8ddf01d5dd1dca 100644 --- a/PCbuild/tcltk.props +++ b/PCbuild/tcltk.props @@ -2,7 +2,7 @@ - 8.6.13.0 + 8.6.13.1 $(TclVersion) $([System.Version]::Parse($(TclVersion)).Major) $([System.Version]::Parse($(TclVersion)).Minor) diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index 36e0750220a30d..3f6c282ffa7a68 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 @@ -119,38 +118,8 @@ expr_ty _PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name) { assert(first_name != NULL && second_name != NULL); - PyObject *first_identifier = first_name->v.Name.id; - PyObject *second_identifier = second_name->v.Name.id; - - const char *first_str = PyUnicode_AsUTF8(first_identifier); - if (!first_str) { - return NULL; - } - const char *second_str = PyUnicode_AsUTF8(second_identifier); - if (!second_str) { - return NULL; - } - Py_ssize_t len = strlen(first_str) + strlen(second_str) + 1; // +1 for the dot - - PyObject *str = PyBytes_FromStringAndSize(NULL, len); - if (!str) { - return NULL; - } - - char *s = PyBytes_AS_STRING(str); - if (!s) { - return NULL; - } - - strcpy(s, first_str); - s += strlen(first_str); - *s++ = '.'; - strcpy(s, second_str); - s += strlen(second_str); - *s = '\0'; - - PyObject *uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), PyBytes_GET_SIZE(str), NULL); - Py_DECREF(str); + PyObject *uni = PyUnicode_FromFormat("%U.%U", + first_name->v.Name.id, second_name->v.Name.id); if (!uni) { return NULL; } @@ -998,18 +967,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 f61099b97055ad..c9bf08ed2e0f6d 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -518,7 +518,7 @@ def sumTrailer(self, name, add_label=False): if add_label: self.emit("failed:", 1) self.emit("Py_XDECREF(tmp);", 1) - self.emit("return 1;", 1) + self.emit("return -1;", 1) self.emit("}", 0) self.emit("", 0) @@ -529,7 +529,7 @@ def simpleSum(self, sum, name): "state->%s_type);") self.emit(line % (t.name,), 1) self.emit("if (isinstance == -1) {", 1) - self.emit("return 1;", 2) + self.emit("return -1;", 2) self.emit("}", 1) self.emit("if (isinstance) {", 1) self.emit("*out = %s;" % t.name, 2) @@ -558,7 +558,7 @@ def complexSum(self, sum, name): self.emit("tp = state->%s_type;" % (t.name,), 1) self.emit("isinstance = PyObject_IsInstance(obj, tp);", 1) self.emit("if (isinstance == -1) {", 1) - self.emit("return 1;", 2) + self.emit("return -1;", 2) self.emit("}", 1) self.emit("if (isinstance) {", 1) for f in t.fields: @@ -605,7 +605,7 @@ def visitProduct(self, prod, name): self.emit("return 0;", 1) self.emit("failed:", 0) self.emit("Py_XDECREF(tmp);", 1) - self.emit("return 1;", 1) + self.emit("return -1;", 1) self.emit("}", 0) self.emit("", 0) @@ -631,13 +631,13 @@ def visitField(self, field, name, sum=None, prod=None, depth=0): ctype = get_c_type(field.type) line = "if (PyObject_GetOptionalAttr(obj, state->%s, &tmp) < 0) {" self.emit(line % field.name, depth) - self.emit("return 1;", depth+1) + self.emit("return -1;", depth+1) self.emit("}", depth) if field.seq: self.emit("if (tmp == NULL) {", depth) self.emit("tmp = PyList_New(0);", depth+1) self.emit("if (tmp == NULL) {", depth+1) - self.emit("return 1;", depth+2) + self.emit("return -1;", depth+2) self.emit("}", depth+1) self.emit("}", depth) self.emit("{", depth) @@ -647,7 +647,7 @@ def visitField(self, field, name, sum=None, prod=None, depth=0): message = "required field \\\"%s\\\" missing from %s" % (field.name, name) format = "PyErr_SetString(PyExc_TypeError, \"%s\");" self.emit(format % message, depth+1, reflow=False) - self.emit("return 1;", depth+1) + self.emit("return -1;", depth+1) else: self.emit("if (tmp == NULL || tmp == Py_None) {", depth) self.emit("Py_CLEAR(tmp);", depth+1) @@ -968,16 +968,16 @@ def visitModule(self, mod): int i, result; PyObject *s, *l = PyTuple_New(num_fields); if (!l) - return 0; + return -1; for (i = 0; i < num_fields; i++) { s = PyUnicode_InternFromString(attrs[i]); if (!s) { Py_DECREF(l); - return 0; + return -1; } PyTuple_SET_ITEM(l, i, s); } - result = PyObject_SetAttr(type, state->_attributes, l) >= 0; + result = PyObject_SetAttr(type, state->_attributes, l); Py_DECREF(l); return result; } @@ -1052,7 +1052,7 @@ def visitModule(self, mod): { if (!PyUnicode_CheckExact(obj) && obj != Py_None) { PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str"); - return 1; + return -1; } return obj2ast_object(state, obj, out, arena); } @@ -1061,7 +1061,7 @@ def visitModule(self, mod): { if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) { PyErr_SetString(PyExc_TypeError, "AST string must be of type str"); - return 1; + return -1; } return obj2ast_object(state, obj, out, arena); } @@ -1071,12 +1071,12 @@ def visitModule(self, mod): int i; if (!PyLong_Check(obj)) { PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj); - return 1; + return -1; } i = PyLong_AsInt(obj); if (i == -1 && PyErr_Occurred()) - return 1; + return -1; *out = i; return 0; } @@ -1102,22 +1102,15 @@ def visitModule(self, mod): static int init_types(struct ast_state *state) { - // init_types() must not be called after _PyAST_Fini() - // has been called - assert(state->initialized >= 0); - - if (state->initialized) { - return 1; - } if (init_identifiers(state) < 0) { - return 0; + return -1; } state->AST_type = PyType_FromSpec(&AST_type_spec); if (!state->AST_type) { - return 0; + return -1; } if (add_ast_fields(state) < 0) { - return 0; + return -1; } ''')) for dfn in mod.dfns: @@ -1125,8 +1118,7 @@ def visitModule(self, mod): self.file.write(textwrap.dedent(''' state->recursion_depth = 0; state->recursion_limit = 0; - state->initialized = 1; - return 1; + return 0; } ''')) @@ -1138,12 +1130,12 @@ def visitProduct(self, prod, name): self.emit('state->%s_type = make_type(state, "%s", state->AST_type, %s, %d,' % (name, name, fields, len(prod.fields)), 1) self.emit('%s);' % reflow_c_string(asdl_of(name, prod), 2), 2, reflow=False) - self.emit("if (!state->%s_type) return 0;" % name, 1) + self.emit("if (!state->%s_type) return -1;" % name, 1) if prod.attributes: - self.emit("if (!add_attributes(state, state->%s_type, %s_attributes, %d)) return 0;" % + self.emit("if (add_attributes(state, state->%s_type, %s_attributes, %d) < 0) return -1;" % (name, name, len(prod.attributes)), 1) else: - self.emit("if (!add_attributes(state, state->%s_type, NULL, 0)) return 0;" % name, 1) + self.emit("if (add_attributes(state, state->%s_type, NULL, 0) < 0) return -1;" % name, 1) self.emit_defaults(name, prod.fields, 1) self.emit_defaults(name, prod.attributes, 1) @@ -1151,12 +1143,12 @@ def visitSum(self, sum, name): self.emit('state->%s_type = make_type(state, "%s", state->AST_type, NULL, 0,' % (name, name), 1) self.emit('%s);' % reflow_c_string(asdl_of(name, sum), 2), 2, reflow=False) - self.emit("if (!state->%s_type) return 0;" % name, 1) + self.emit("if (!state->%s_type) return -1;" % name, 1) if sum.attributes: - self.emit("if (!add_attributes(state, state->%s_type, %s_attributes, %d)) return 0;" % + self.emit("if (add_attributes(state, state->%s_type, %s_attributes, %d) < 0) return -1;" % (name, name, len(sum.attributes)), 1) else: - self.emit("if (!add_attributes(state, state->%s_type, NULL, 0)) return 0;" % name, 1) + self.emit("if (add_attributes(state, state->%s_type, NULL, 0) < 0) return -1;" % name, 1) self.emit_defaults(name, sum.attributes, 1) simple = is_simple(sum) for t in sum.types: @@ -1170,20 +1162,20 @@ def visitConstructor(self, cons, name, simple): self.emit('state->%s_type = make_type(state, "%s", state->%s_type, %s, %d,' % (cons.name, cons.name, name, fields, len(cons.fields)), 1) self.emit('%s);' % reflow_c_string(asdl_of(cons.name, cons), 2), 2, reflow=False) - self.emit("if (!state->%s_type) return 0;" % cons.name, 1) + self.emit("if (!state->%s_type) return -1;" % cons.name, 1) self.emit_defaults(cons.name, cons.fields, 1) if simple: self.emit("state->%s_singleton = PyType_GenericNew((PyTypeObject *)" "state->%s_type, NULL, NULL);" % (cons.name, cons.name), 1) - self.emit("if (!state->%s_singleton) return 0;" % cons.name, 1) + self.emit("if (!state->%s_singleton) return -1;" % cons.name, 1) def emit_defaults(self, name, fields, depth): for field in fields: if field.opt: self.emit('if (PyObject_SetAttr(state->%s_type, state->%s, Py_None) == -1)' % (name, field.name), depth) - self.emit("return 0;", depth+1) + self.emit("return -1;", depth+1) class ASTModuleVisitor(PickleVisitor): @@ -1279,13 +1271,14 @@ def func_begin(self, name): self.emit("if (++state->recursion_depth > state->recursion_limit) {", 1) self.emit("PyErr_SetString(PyExc_RecursionError,", 2) self.emit('"maximum recursion depth exceeded during ast construction");', 3) - self.emit("return 0;", 2) + self.emit("return NULL;", 2) self.emit("}", 1) def func_end(self): self.emit("state->recursion_depth--;", 1) self.emit("return result;", 1) self.emit("failed:", 0) + self.emit("state->recursion_depth--;", 1) self.emit("Py_XDECREF(value);", 1) self.emit("Py_XDECREF(result);", 1) self.emit("return NULL;", 1) @@ -1399,7 +1392,7 @@ class PartingShots(StaticVisitor): int COMPILER_STACK_FRAME_SCALE = 2; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { - return 0; + return NULL; } state->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; @@ -1413,7 +1406,7 @@ class PartingShots(StaticVisitor): PyErr_Format(PyExc_SystemError, "AST constructor recursion depth mismatch (before=%d, after=%d)", starting_recursion_depth, state->recursion_depth); - return 0; + return NULL; } return result; } @@ -1480,7 +1473,8 @@ def visit(self, object): def generate_ast_state(module_state, f): f.write('struct ast_state {\n') - f.write(' int initialized;\n') + f.write(' _PyOnceFlag once;\n') + f.write(' int finalized;\n') f.write(' int recursion_depth;\n') f.write(' int recursion_limit;\n') for s in module_state: @@ -1500,11 +1494,8 @@ def generate_ast_fini(module_state, f): f.write(textwrap.dedent(""" Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)); - #if !defined(NDEBUG) - state->initialized = -1; - #else - state->initialized = 0; - #endif + state->finalized = 1; + state->once = (_PyOnceFlag){0}; } """)) @@ -1543,6 +1534,7 @@ def generate_module_def(mod, metadata, f, internal_h): #include "pycore_ast.h" #include "pycore_ast_state.h" // struct ast_state #include "pycore_ceval.h" // _Py_EnterRecursiveCall + #include "pycore_lock.h" // _PyOnceFlag #include "pycore_interp.h" // _PyInterpreterState.ast #include "pycore_pystate.h" // _PyInterpreterState_GET() #include @@ -1555,7 +1547,8 @@ def generate_module_def(mod, metadata, f, internal_h): { PyInterpreterState *interp = _PyInterpreterState_GET(); struct ast_state *state = &interp->ast; - if (!init_types(state)) { + assert(!state->finalized); + if (_PyOnceFlag_CallOnce(&state->once, (_Py_once_fn_t *)&init_types, state) < 0) { return NULL; } return state; @@ -1569,8 +1562,8 @@ def generate_module_def(mod, metadata, f, internal_h): for identifier in state_strings: f.write(' if ((state->' + identifier) f.write(' = PyUnicode_InternFromString("') - f.write(identifier + '")) == NULL) return 0;\n') - f.write(' return 1;\n') + f.write(identifier + '")) == NULL) return -1;\n') + f.write(' return 0;\n') f.write('};\n\n') def write_header(mod, metadata, f): @@ -1628,6 +1621,9 @@ def write_internal_h_header(mod, f): print(textwrap.dedent(""" #ifndef Py_INTERNAL_AST_STATE_H #define Py_INTERNAL_AST_STATE_H + + #include "pycore_lock.h" // _PyOnceFlag + #ifdef __cplusplus extern "C" { #endif 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..ea4bdf7ce4a24c --- /dev/null +++ b/Parser/lexer/lexer.c @@ -0,0 +1,1480 @@ +#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) { + if ((unsigned int) tok->col_offset >= (unsigned int) INT_MAX) { + tok->done = E_COLUMNOVERFLOW; + return EOF; + } + 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 = NULL; + + // Check if there is a # character in the expression + int hash_detected = 0; + for (Py_ssize_t i = 0; i < tok_mode->last_expr_size - tok_mode->last_expr_end; i++) { + if (tok_mode->last_expr_buffer[i] == '#') { + hash_detected = 1; + break; + } + } + + if (hash_detected) { + Py_ssize_t input_length = tok_mode->last_expr_size - tok_mode->last_expr_end; + char *result = (char *)PyObject_Malloc((input_length + 1) * sizeof(char)); + if (!result) { + return -1; + } + + Py_ssize_t i = 0; + Py_ssize_t j = 0; + + for (i = 0, j = 0; i < input_length; i++) { + if (tok_mode->last_expr_buffer[i] == '#') { + // Skip characters until newline or end of string + while (tok_mode->last_expr_buffer[i] != '\0' && i < input_length) { + if (tok_mode->last_expr_buffer[i] == '\n') { + result[j++] = tok_mode->last_expr_buffer[i]; + break; + } + i++; + } + } else { + result[j++] = tok_mode->last_expr_buffer[i]; + } + } + + result[j] = '\0'; // Null-terminate the result string + res = PyUnicode_DecodeUTF8(result, j, NULL); + PyObject_Free(result); + } else { + 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; + int has_escaped_quote = 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 { + if (has_escaped_quote) { + _PyTokenizer_syntaxerror( + tok, + "unterminated string literal (detected at line %d); " + "perhaps you escaped the end quote?", + start + ); + } 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 == quote) { /* but record whether the escaped char was a quote */ + has_escaped_quote = 1; + } + 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/lexer/state.h b/Parser/lexer/state.h new file mode 100644 index 00000000000000..61d090d6d2fe21 --- /dev/null +++ b/Parser/lexer/state.h @@ -0,0 +1,141 @@ +#ifndef _PY_LEXER_H_ +#define _PY_LEXER_H_ + +#include "object.h" + +#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, + STATE_NORMAL +}; + +enum interactive_underflow_t { + /* Normal mode of operation: return a new token when asked in interactive mode */ + IUNDERFLOW_NORMAL, + /* Forcefully return ENDMARKER when asked for a new token in interactive mode. This + * can be used to prevent the tokenizer to prompt the user for new tokens */ + IUNDERFLOW_STOP, +}; + +struct token { + int level; + int lineno, col_offset, end_lineno, end_col_offset; + const char *start, *end; + PyObject *metadata; +}; + +enum tokenizer_mode_kind_t { + TOK_REGULAR_MODE, + TOK_FSTRING_MODE, +}; + +#define MAX_EXPR_NESTING 3 + +typedef struct _tokenizer_mode { + enum tokenizer_mode_kind_t kind; + + int curly_bracket_depth; + int curly_bracket_expr_start_depth; + + char f_string_quote; + int f_string_quote_size; + int f_string_raw; + const char* f_string_start; + const char* f_string_multi_line_start; + int f_string_line_start; + + Py_ssize_t f_string_start_offset; + Py_ssize_t f_string_multi_line_start_offset; + + Py_ssize_t last_expr_size; + Py_ssize_t last_expr_end; + char* last_expr_buffer; + int f_string_debug; +} tokenizer_mode; + +/* Tokenizer state */ +struct tok_state { + /* Input state; buf <= cur <= inp <= end */ + /* NB an entire line is held in the buffer */ + char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL or readline != NULL */ + char *cur; /* Next character in buffer */ + char *inp; /* End of data in buffer */ + int fp_interactive; /* If the file descriptor is interactive */ + char *interactive_src_start; /* The start of the source parsed so far in interactive mode */ + char *interactive_src_end; /* The end of the source parsed so far in interactive mode */ + const char *end; /* End of input buffer if buf != NULL */ + const char *start; /* Start of current token if not NULL */ + int done; /* E_OK normally, E_EOF at EOF, otherwise error code */ + /* NB If done != E_OK, cur must be == inp!!! */ + FILE *fp; /* Rest of input; NULL if tokenizing a string */ + int tabsize; /* Tab spacing */ + int indent; /* Current indentation index */ + int indstack[MAXINDENT]; /* Stack of indents */ + int atbol; /* Nonzero if at begin of new line */ + int pendin; /* Pending indents (if > 0) or dedents (if < 0) */ + const char *prompt, *nextprompt; /* For interactive prompting */ + int lineno; /* Current line number */ + int first_lineno; /* First line of a single line or multi line string + expression (cf. issue 16806) */ + int starting_col_offset; /* The column offset at the beginning of a token */ + int col_offset; /* Current col offset */ + int level; /* () [] {} Parentheses nesting level */ + /* Used to allow free continuations inside them */ + char parenstack[MAXLEVEL]; + int parenlinenostack[MAXLEVEL]; + int parencolstack[MAXLEVEL]; + PyObject *filename; + /* Stuff for checking on different tab sizes */ + int altindstack[MAXINDENT]; /* Stack of alternate indents */ + /* Stuff for PEP 0263 */ + enum decoding_state decoding_state; + int decoding_erred; /* whether erred in decoding */ + char *encoding; /* Source encoding. */ + int cont_line; /* whether we are in a continuation line. */ + const char* line_start; /* pointer to start of current line */ + const char* multi_line_start; /* pointer to start of first line of + a single line or multi line string + expression (cf. issue 16806) */ + PyObject *decoding_readline; /* open(...).readline */ + PyObject *decoding_buffer; + PyObject *readline; /* readline() function */ + const char* enc; /* Encoding for the current str. */ + char* str; /* Source string being tokenized (if tokenizing from a string)*/ + char* input; /* Tokenizer's newline translated copy of the string. */ + + int type_comments; /* Whether to look for type comments */ + + /* 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_extra_tokens; + int comment_newline; + int implicit_newline; +#ifdef Py_DEBUG + int debug; +#endif +}; + +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 *); + + +#endif diff --git a/Parser/myreadline.c b/Parser/myreadline.c index 815387388218c6..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,11 +14,15 @@ #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 + // Export the symbol since it's used by the readline shared extension PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; @@ -360,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 24f67f4dedfb1f..9006efb09a59fa 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -8,7 +8,11 @@ #endif #ifdef __wasi__ -# define MAXSTACK 4000 +# ifdef Py_DEBUG +# define MAXSTACK 1000 +# else +# define MAXSTACK 4000 +# endif #else # define MAXSTACK 6000 #endif @@ -17,18 +21,18 @@ static KeywordToken *reserved_keywords[] = { (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) { - {"if", 656}, - {"as", 654}, - {"in", 667}, + {"if", 658}, + {"as", 656}, + {"in", 669}, {"or", 581}, {"is", 589}, {NULL, -1}, }, (KeywordToken[]) { {"del", 613}, - {"def", 669}, - {"for", 666}, - {"try", 638}, + {"def", 671}, + {"for", 668}, + {"try", 640}, {"and", 582}, {"not", 588}, {NULL, -1}, @@ -36,9 +40,9 @@ static KeywordToken *reserved_keywords[] = { (KeywordToken[]) { {"from", 618}, {"pass", 504}, - {"with", 629}, - {"elif", 658}, - {"else", 659}, + {"with", 631}, + {"elif", 660}, + {"else", 661}, {"None", 611}, {"True", 610}, {NULL, -1}, @@ -47,9 +51,9 @@ static KeywordToken *reserved_keywords[] = { {"raise", 525}, {"yield", 580}, {"break", 508}, - {"async", 668}, - {"class", 671}, - {"while", 661}, + {"async", 670}, + {"class", 673}, + {"while", 663}, {"False", 612}, {"await", 590}, {NULL, -1}, @@ -59,12 +63,12 @@ static KeywordToken *reserved_keywords[] = { {"import", 617}, {"assert", 529}, {"global", 526}, - {"except", 651}, + {"except", 653}, {"lambda", 609}, {NULL, -1}, }, (KeywordToken[]) { - {"finally", 647}, + {"finally", 649}, {NULL, -1}, }, (KeywordToken[]) { @@ -300,305 +304,312 @@ static char *soft_keywords[] = { #define invalid_group_type 1217 #define invalid_import_type 1218 #define invalid_import_from_targets_type 1219 -#define invalid_with_stmt_type 1220 -#define invalid_with_stmt_indent_type 1221 -#define invalid_try_stmt_type 1222 -#define invalid_except_stmt_type 1223 -#define invalid_finally_stmt_type 1224 -#define invalid_except_stmt_indent_type 1225 -#define invalid_except_star_stmt_indent_type 1226 -#define invalid_match_stmt_type 1227 -#define invalid_case_block_type 1228 -#define invalid_as_pattern_type 1229 -#define invalid_class_pattern_type 1230 -#define invalid_class_argument_pattern_type 1231 -#define invalid_if_stmt_type 1232 -#define invalid_elif_stmt_type 1233 -#define invalid_else_stmt_type 1234 -#define invalid_while_stmt_type 1235 -#define invalid_for_stmt_type 1236 -#define invalid_def_raw_type 1237 -#define invalid_class_def_raw_type 1238 -#define invalid_double_starred_kvpairs_type 1239 -#define invalid_kvpair_type 1240 -#define invalid_starred_expression_type 1241 -#define invalid_replacement_field_type 1242 -#define invalid_conversion_character_type 1243 -#define _loop0_1_type 1244 -#define _loop0_2_type 1245 -#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 -#define _tmp_10_type 1253 -#define _tmp_11_type 1254 -#define _tmp_12_type 1255 -#define _tmp_13_type 1256 -#define _loop1_14_type 1257 -#define _tmp_15_type 1258 -#define _tmp_16_type 1259 -#define _tmp_17_type 1260 -#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 _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 _loop0_36_type 1279 -#define _loop0_37_type 1280 -#define _loop0_38_type 1281 -#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 _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 _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 _tmp_62_type 1305 -#define _tmp_63_type 1306 -#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 _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 _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 _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 _loop0_98_type 1341 -#define _loop0_99_type 1342 -#define _loop0_100_type 1343 -#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 _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 -#define _loop0_118_type 1360 -#define _gather_117_type 1361 -#define _loop1_119_type 1362 -#define _loop0_120_type 1363 -#define _loop0_121_type 1364 -#define _tmp_122_type 1365 -#define _loop0_124_type 1366 -#define _gather_123_type 1367 -#define _tmp_125_type 1368 -#define _loop0_127_type 1369 -#define _gather_126_type 1370 -#define _loop0_129_type 1371 -#define _gather_128_type 1372 -#define _loop0_131_type 1373 -#define _gather_130_type 1374 -#define _loop0_133_type 1375 -#define _gather_132_type 1376 -#define _loop0_134_type 1377 -#define _loop0_136_type 1378 -#define _gather_135_type 1379 -#define _loop1_137_type 1380 -#define _tmp_138_type 1381 -#define _loop0_140_type 1382 -#define _gather_139_type 1383 -#define _loop0_142_type 1384 -#define _gather_141_type 1385 -#define _loop0_144_type 1386 -#define _gather_143_type 1387 -#define _loop0_146_type 1388 -#define _gather_145_type 1389 -#define _loop0_148_type 1390 -#define _gather_147_type 1391 -#define _tmp_149_type 1392 -#define _tmp_150_type 1393 -#define _tmp_151_type 1394 -#define _tmp_152_type 1395 -#define _tmp_153_type 1396 -#define _tmp_154_type 1397 -#define _tmp_155_type 1398 -#define _tmp_156_type 1399 -#define _tmp_157_type 1400 -#define _tmp_158_type 1401 -#define _tmp_159_type 1402 -#define _loop0_160_type 1403 -#define _loop0_161_type 1404 -#define _loop0_162_type 1405 -#define _tmp_163_type 1406 -#define _tmp_164_type 1407 -#define _tmp_165_type 1408 -#define _tmp_166_type 1409 -#define _tmp_167_type 1410 -#define _loop0_168_type 1411 -#define _loop0_169_type 1412 -#define _loop0_170_type 1413 -#define _loop1_171_type 1414 -#define _tmp_172_type 1415 -#define _loop0_173_type 1416 -#define _tmp_174_type 1417 -#define _loop0_175_type 1418 -#define _loop1_176_type 1419 -#define _tmp_177_type 1420 -#define _tmp_178_type 1421 -#define _tmp_179_type 1422 -#define _loop0_180_type 1423 -#define _tmp_181_type 1424 -#define _tmp_182_type 1425 -#define _loop1_183_type 1426 -#define _tmp_184_type 1427 -#define _loop0_185_type 1428 -#define _loop0_186_type 1429 -#define _loop0_187_type 1430 -#define _loop0_189_type 1431 -#define _gather_188_type 1432 -#define _tmp_190_type 1433 -#define _loop0_191_type 1434 -#define _tmp_192_type 1435 -#define _loop0_193_type 1436 -#define _loop1_194_type 1437 -#define _loop1_195_type 1438 -#define _tmp_196_type 1439 -#define _tmp_197_type 1440 -#define _loop0_198_type 1441 -#define _tmp_199_type 1442 -#define _tmp_200_type 1443 -#define _tmp_201_type 1444 -#define _loop0_203_type 1445 -#define _gather_202_type 1446 -#define _loop0_205_type 1447 -#define _gather_204_type 1448 -#define _loop0_207_type 1449 -#define _gather_206_type 1450 -#define _loop0_209_type 1451 -#define _gather_208_type 1452 -#define _loop0_211_type 1453 -#define _gather_210_type 1454 -#define _tmp_212_type 1455 -#define _loop0_213_type 1456 -#define _loop1_214_type 1457 -#define _tmp_215_type 1458 -#define _loop0_216_type 1459 -#define _loop1_217_type 1460 -#define _tmp_218_type 1461 -#define _tmp_219_type 1462 -#define _tmp_220_type 1463 -#define _tmp_221_type 1464 -#define _tmp_222_type 1465 -#define _tmp_223_type 1466 -#define _tmp_224_type 1467 -#define _tmp_225_type 1468 -#define _tmp_226_type 1469 -#define _tmp_227_type 1470 -#define _loop0_229_type 1471 -#define _gather_228_type 1472 -#define _tmp_230_type 1473 -#define _tmp_231_type 1474 -#define _tmp_232_type 1475 -#define _tmp_233_type 1476 -#define _tmp_234_type 1477 -#define _tmp_235_type 1478 -#define _tmp_236_type 1479 -#define _tmp_237_type 1480 -#define _tmp_238_type 1481 -#define _tmp_239_type 1482 -#define _tmp_240_type 1483 -#define _tmp_241_type 1484 -#define _tmp_242_type 1485 -#define _loop0_243_type 1486 -#define _tmp_244_type 1487 -#define _tmp_245_type 1488 -#define _tmp_246_type 1489 -#define _tmp_247_type 1490 -#define _tmp_248_type 1491 -#define _tmp_249_type 1492 -#define _tmp_250_type 1493 -#define _tmp_251_type 1494 -#define _tmp_252_type 1495 -#define _tmp_253_type 1496 -#define _tmp_254_type 1497 -#define _tmp_255_type 1498 -#define _tmp_256_type 1499 -#define _tmp_257_type 1500 -#define _tmp_258_type 1501 -#define _tmp_259_type 1502 -#define _tmp_260_type 1503 -#define _tmp_261_type 1504 -#define _tmp_262_type 1505 -#define _tmp_263_type 1506 -#define _tmp_264_type 1507 -#define _tmp_265_type 1508 -#define _tmp_266_type 1509 -#define _tmp_267_type 1510 -#define _tmp_268_type 1511 -#define _tmp_269_type 1512 -#define _tmp_270_type 1513 -#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 invalid_compound_stmt_type 1220 +#define invalid_with_stmt_type 1221 +#define invalid_with_stmt_indent_type 1222 +#define invalid_try_stmt_type 1223 +#define invalid_except_stmt_type 1224 +#define invalid_finally_stmt_type 1225 +#define invalid_except_stmt_indent_type 1226 +#define invalid_except_star_stmt_indent_type 1227 +#define invalid_match_stmt_type 1228 +#define invalid_case_block_type 1229 +#define invalid_as_pattern_type 1230 +#define invalid_class_pattern_type 1231 +#define invalid_class_argument_pattern_type 1232 +#define invalid_if_stmt_type 1233 +#define invalid_elif_stmt_type 1234 +#define invalid_else_stmt_type 1235 +#define invalid_while_stmt_type 1236 +#define invalid_for_stmt_type 1237 +#define invalid_def_raw_type 1238 +#define invalid_class_def_raw_type 1239 +#define invalid_double_starred_kvpairs_type 1240 +#define invalid_kvpair_type 1241 +#define invalid_starred_expression_type 1242 +#define invalid_replacement_field_type 1243 +#define invalid_conversion_character_type 1244 +#define _loop0_1_type 1245 +#define _loop0_2_type 1246 +#define _loop1_3_type 1247 +#define _loop0_5_type 1248 +#define _gather_4_type 1249 +#define _tmp_6_type 1250 +#define _tmp_7_type 1251 +#define _tmp_8_type 1252 +#define _tmp_9_type 1253 +#define _tmp_10_type 1254 +#define _tmp_11_type 1255 +#define _tmp_12_type 1256 +#define _tmp_13_type 1257 +#define _loop1_14_type 1258 +#define _tmp_15_type 1259 +#define _tmp_16_type 1260 +#define _tmp_17_type 1261 +#define _loop0_19_type 1262 +#define _gather_18_type 1263 +#define _loop0_21_type 1264 +#define _gather_20_type 1265 +#define _tmp_22_type 1266 +#define _tmp_23_type 1267 +#define _loop0_24_type 1268 +#define _loop1_25_type 1269 +#define _loop0_27_type 1270 +#define _gather_26_type 1271 +#define _tmp_28_type 1272 +#define _loop0_30_type 1273 +#define _gather_29_type 1274 +#define _tmp_31_type 1275 +#define _loop1_32_type 1276 +#define _tmp_33_type 1277 +#define _tmp_34_type 1278 +#define _tmp_35_type 1279 +#define _loop0_36_type 1280 +#define _loop0_37_type 1281 +#define _loop0_38_type 1282 +#define _loop1_39_type 1283 +#define _loop0_40_type 1284 +#define _loop1_41_type 1285 +#define _loop1_42_type 1286 +#define _loop1_43_type 1287 +#define _loop0_44_type 1288 +#define _loop1_45_type 1289 +#define _loop0_46_type 1290 +#define _loop1_47_type 1291 +#define _loop0_48_type 1292 +#define _loop0_49_type 1293 +#define _loop1_50_type 1294 +#define _loop0_52_type 1295 +#define _gather_51_type 1296 +#define _loop0_54_type 1297 +#define _gather_53_type 1298 +#define _loop0_56_type 1299 +#define _gather_55_type 1300 +#define _loop0_58_type 1301 +#define _gather_57_type 1302 +#define _tmp_59_type 1303 +#define _loop1_60_type 1304 +#define _loop1_61_type 1305 +#define _tmp_62_type 1306 +#define _tmp_63_type 1307 +#define _loop1_64_type 1308 +#define _loop0_66_type 1309 +#define _gather_65_type 1310 +#define _tmp_67_type 1311 +#define _tmp_68_type 1312 +#define _tmp_69_type 1313 +#define _tmp_70_type 1314 +#define _loop0_72_type 1315 +#define _gather_71_type 1316 +#define _loop0_74_type 1317 +#define _gather_73_type 1318 +#define _tmp_75_type 1319 +#define _loop0_77_type 1320 +#define _gather_76_type 1321 +#define _loop0_79_type 1322 +#define _gather_78_type 1323 +#define _loop0_81_type 1324 +#define _gather_80_type 1325 +#define _loop1_82_type 1326 +#define _loop1_83_type 1327 +#define _loop0_85_type 1328 +#define _gather_84_type 1329 +#define _loop1_86_type 1330 +#define _loop1_87_type 1331 +#define _loop1_88_type 1332 +#define _tmp_89_type 1333 +#define _loop0_91_type 1334 +#define _gather_90_type 1335 +#define _tmp_92_type 1336 +#define _tmp_93_type 1337 +#define _tmp_94_type 1338 +#define _tmp_95_type 1339 +#define _tmp_96_type 1340 +#define _tmp_97_type 1341 +#define _loop0_98_type 1342 +#define _loop0_99_type 1343 +#define _loop0_100_type 1344 +#define _loop1_101_type 1345 +#define _loop0_102_type 1346 +#define _loop1_103_type 1347 +#define _loop1_104_type 1348 +#define _loop1_105_type 1349 +#define _loop0_106_type 1350 +#define _loop1_107_type 1351 +#define _loop0_108_type 1352 +#define _loop1_109_type 1353 +#define _loop0_110_type 1354 +#define _loop1_111_type 1355 +#define _tmp_112_type 1356 +#define _loop0_113_type 1357 +#define _loop0_114_type 1358 +#define _loop1_115_type 1359 +#define _tmp_116_type 1360 +#define _loop0_118_type 1361 +#define _gather_117_type 1362 +#define _loop1_119_type 1363 +#define _loop0_120_type 1364 +#define _loop0_121_type 1365 +#define _tmp_122_type 1366 +#define _loop0_124_type 1367 +#define _gather_123_type 1368 +#define _tmp_125_type 1369 +#define _loop0_127_type 1370 +#define _gather_126_type 1371 +#define _loop0_129_type 1372 +#define _gather_128_type 1373 +#define _loop0_131_type 1374 +#define _gather_130_type 1375 +#define _loop0_133_type 1376 +#define _gather_132_type 1377 +#define _loop0_134_type 1378 +#define _loop0_136_type 1379 +#define _gather_135_type 1380 +#define _loop1_137_type 1381 +#define _tmp_138_type 1382 +#define _loop0_140_type 1383 +#define _gather_139_type 1384 +#define _loop0_142_type 1385 +#define _gather_141_type 1386 +#define _loop0_144_type 1387 +#define _gather_143_type 1388 +#define _loop0_146_type 1389 +#define _gather_145_type 1390 +#define _loop0_148_type 1391 +#define _gather_147_type 1392 +#define _tmp_149_type 1393 +#define _tmp_150_type 1394 +#define _tmp_151_type 1395 +#define _tmp_152_type 1396 +#define _tmp_153_type 1397 +#define _tmp_154_type 1398 +#define _tmp_155_type 1399 +#define _tmp_156_type 1400 +#define _tmp_157_type 1401 +#define _tmp_158_type 1402 +#define _tmp_159_type 1403 +#define _tmp_160_type 1404 +#define _loop0_161_type 1405 +#define _loop0_162_type 1406 +#define _loop0_163_type 1407 +#define _tmp_164_type 1408 +#define _tmp_165_type 1409 +#define _tmp_166_type 1410 +#define _tmp_167_type 1411 +#define _tmp_168_type 1412 +#define _loop0_169_type 1413 +#define _loop0_170_type 1414 +#define _loop0_171_type 1415 +#define _loop1_172_type 1416 +#define _tmp_173_type 1417 +#define _loop0_174_type 1418 +#define _tmp_175_type 1419 +#define _loop0_176_type 1420 +#define _loop1_177_type 1421 +#define _tmp_178_type 1422 +#define _tmp_179_type 1423 +#define _tmp_180_type 1424 +#define _loop0_181_type 1425 +#define _tmp_182_type 1426 +#define _tmp_183_type 1427 +#define _loop1_184_type 1428 +#define _tmp_185_type 1429 +#define _loop0_186_type 1430 +#define _loop0_187_type 1431 +#define _loop0_188_type 1432 +#define _loop0_190_type 1433 +#define _gather_189_type 1434 +#define _tmp_191_type 1435 +#define _loop0_192_type 1436 +#define _tmp_193_type 1437 +#define _loop0_194_type 1438 +#define _loop1_195_type 1439 +#define _loop1_196_type 1440 +#define _tmp_197_type 1441 +#define _tmp_198_type 1442 +#define _loop0_199_type 1443 +#define _tmp_200_type 1444 +#define _tmp_201_type 1445 +#define _tmp_202_type 1446 +#define _loop0_204_type 1447 +#define _gather_203_type 1448 +#define _loop0_206_type 1449 +#define _gather_205_type 1450 +#define _loop0_208_type 1451 +#define _gather_207_type 1452 +#define _loop0_210_type 1453 +#define _gather_209_type 1454 +#define _loop0_212_type 1455 +#define _gather_211_type 1456 +#define _tmp_213_type 1457 +#define _loop0_214_type 1458 +#define _loop1_215_type 1459 +#define _tmp_216_type 1460 +#define _loop0_217_type 1461 +#define _loop1_218_type 1462 +#define _tmp_219_type 1463 +#define _tmp_220_type 1464 +#define _tmp_221_type 1465 +#define _tmp_222_type 1466 +#define _tmp_223_type 1467 +#define _tmp_224_type 1468 +#define _tmp_225_type 1469 +#define _tmp_226_type 1470 +#define _tmp_227_type 1471 +#define _tmp_228_type 1472 +#define _loop0_230_type 1473 +#define _gather_229_type 1474 +#define _tmp_231_type 1475 +#define _tmp_232_type 1476 +#define _tmp_233_type 1477 +#define _tmp_234_type 1478 +#define _tmp_235_type 1479 +#define _tmp_236_type 1480 +#define _tmp_237_type 1481 +#define _tmp_238_type 1482 +#define _tmp_239_type 1483 +#define _tmp_240_type 1484 +#define _tmp_241_type 1485 +#define _tmp_242_type 1486 +#define _tmp_243_type 1487 +#define _loop0_244_type 1488 +#define _tmp_245_type 1489 +#define _tmp_246_type 1490 +#define _tmp_247_type 1491 +#define _tmp_248_type 1492 +#define _tmp_249_type 1493 +#define _tmp_250_type 1494 +#define _tmp_251_type 1495 +#define _tmp_252_type 1496 +#define _tmp_253_type 1497 +#define _tmp_254_type 1498 +#define _tmp_255_type 1499 +#define _tmp_256_type 1500 +#define _tmp_257_type 1501 +#define _tmp_258_type 1502 +#define _tmp_259_type 1503 +#define _tmp_260_type 1504 +#define _tmp_261_type 1505 +#define _tmp_262_type 1506 +#define _tmp_263_type 1507 +#define _tmp_264_type 1508 +#define _tmp_265_type 1509 +#define _tmp_266_type 1510 +#define _tmp_267_type 1511 +#define _tmp_268_type 1512 +#define _tmp_269_type 1513 +#define _tmp_270_type 1514 +#define _tmp_271_type 1515 +#define _tmp_272_type 1516 +#define _tmp_273_type 1517 +#define _loop0_275_type 1518 +#define _gather_274_type 1519 +#define _tmp_276_type 1520 +#define _tmp_277_type 1521 +#define _tmp_278_type 1522 +#define _tmp_279_type 1523 +#define _tmp_280_type 1524 +#define _tmp_281_type 1525 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -820,6 +831,7 @@ static void *invalid_for_target_rule(Parser *p); static void *invalid_group_rule(Parser *p); static void *invalid_import_rule(Parser *p); static void *invalid_import_from_targets_rule(Parser *p); +static void *invalid_compound_stmt_rule(Parser *p); static void *invalid_with_stmt_rule(Parser *p); static void *invalid_with_stmt_indent_rule(Parser *p); static void *invalid_try_stmt_rule(Parser *p); @@ -1003,65 +1015,65 @@ static void *_tmp_156_rule(Parser *p); static void *_tmp_157_rule(Parser *p); static void *_tmp_158_rule(Parser *p); static void *_tmp_159_rule(Parser *p); -static asdl_seq *_loop0_160_rule(Parser *p); +static void *_tmp_160_rule(Parser *p); static asdl_seq *_loop0_161_rule(Parser *p); static asdl_seq *_loop0_162_rule(Parser *p); -static void *_tmp_163_rule(Parser *p); +static asdl_seq *_loop0_163_rule(Parser *p); static void *_tmp_164_rule(Parser *p); static void *_tmp_165_rule(Parser *p); static void *_tmp_166_rule(Parser *p); static void *_tmp_167_rule(Parser *p); -static asdl_seq *_loop0_168_rule(Parser *p); +static void *_tmp_168_rule(Parser *p); static asdl_seq *_loop0_169_rule(Parser *p); static asdl_seq *_loop0_170_rule(Parser *p); -static asdl_seq *_loop1_171_rule(Parser *p); -static void *_tmp_172_rule(Parser *p); -static asdl_seq *_loop0_173_rule(Parser *p); -static void *_tmp_174_rule(Parser *p); -static asdl_seq *_loop0_175_rule(Parser *p); -static asdl_seq *_loop1_176_rule(Parser *p); -static void *_tmp_177_rule(Parser *p); +static asdl_seq *_loop0_171_rule(Parser *p); +static asdl_seq *_loop1_172_rule(Parser *p); +static void *_tmp_173_rule(Parser *p); +static asdl_seq *_loop0_174_rule(Parser *p); +static void *_tmp_175_rule(Parser *p); +static asdl_seq *_loop0_176_rule(Parser *p); +static asdl_seq *_loop1_177_rule(Parser *p); static void *_tmp_178_rule(Parser *p); static void *_tmp_179_rule(Parser *p); -static asdl_seq *_loop0_180_rule(Parser *p); -static void *_tmp_181_rule(Parser *p); +static void *_tmp_180_rule(Parser *p); +static asdl_seq *_loop0_181_rule(Parser *p); static void *_tmp_182_rule(Parser *p); -static asdl_seq *_loop1_183_rule(Parser *p); -static void *_tmp_184_rule(Parser *p); -static asdl_seq *_loop0_185_rule(Parser *p); +static void *_tmp_183_rule(Parser *p); +static asdl_seq *_loop1_184_rule(Parser *p); +static void *_tmp_185_rule(Parser *p); static asdl_seq *_loop0_186_rule(Parser *p); static asdl_seq *_loop0_187_rule(Parser *p); -static asdl_seq *_loop0_189_rule(Parser *p); -static asdl_seq *_gather_188_rule(Parser *p); -static void *_tmp_190_rule(Parser *p); -static asdl_seq *_loop0_191_rule(Parser *p); -static void *_tmp_192_rule(Parser *p); -static asdl_seq *_loop0_193_rule(Parser *p); -static asdl_seq *_loop1_194_rule(Parser *p); +static asdl_seq *_loop0_188_rule(Parser *p); +static asdl_seq *_loop0_190_rule(Parser *p); +static asdl_seq *_gather_189_rule(Parser *p); +static void *_tmp_191_rule(Parser *p); +static asdl_seq *_loop0_192_rule(Parser *p); +static void *_tmp_193_rule(Parser *p); +static asdl_seq *_loop0_194_rule(Parser *p); static asdl_seq *_loop1_195_rule(Parser *p); -static void *_tmp_196_rule(Parser *p); +static asdl_seq *_loop1_196_rule(Parser *p); static void *_tmp_197_rule(Parser *p); -static asdl_seq *_loop0_198_rule(Parser *p); -static void *_tmp_199_rule(Parser *p); +static void *_tmp_198_rule(Parser *p); +static asdl_seq *_loop0_199_rule(Parser *p); static void *_tmp_200_rule(Parser *p); static void *_tmp_201_rule(Parser *p); -static asdl_seq *_loop0_203_rule(Parser *p); -static asdl_seq *_gather_202_rule(Parser *p); -static asdl_seq *_loop0_205_rule(Parser *p); -static asdl_seq *_gather_204_rule(Parser *p); -static asdl_seq *_loop0_207_rule(Parser *p); -static asdl_seq *_gather_206_rule(Parser *p); -static asdl_seq *_loop0_209_rule(Parser *p); -static asdl_seq *_gather_208_rule(Parser *p); -static asdl_seq *_loop0_211_rule(Parser *p); -static asdl_seq *_gather_210_rule(Parser *p); -static void *_tmp_212_rule(Parser *p); -static asdl_seq *_loop0_213_rule(Parser *p); -static asdl_seq *_loop1_214_rule(Parser *p); -static void *_tmp_215_rule(Parser *p); -static asdl_seq *_loop0_216_rule(Parser *p); -static asdl_seq *_loop1_217_rule(Parser *p); -static void *_tmp_218_rule(Parser *p); +static void *_tmp_202_rule(Parser *p); +static asdl_seq *_loop0_204_rule(Parser *p); +static asdl_seq *_gather_203_rule(Parser *p); +static asdl_seq *_loop0_206_rule(Parser *p); +static asdl_seq *_gather_205_rule(Parser *p); +static asdl_seq *_loop0_208_rule(Parser *p); +static asdl_seq *_gather_207_rule(Parser *p); +static asdl_seq *_loop0_210_rule(Parser *p); +static asdl_seq *_gather_209_rule(Parser *p); +static asdl_seq *_loop0_212_rule(Parser *p); +static asdl_seq *_gather_211_rule(Parser *p); +static void *_tmp_213_rule(Parser *p); +static asdl_seq *_loop0_214_rule(Parser *p); +static asdl_seq *_loop1_215_rule(Parser *p); +static void *_tmp_216_rule(Parser *p); +static asdl_seq *_loop0_217_rule(Parser *p); +static asdl_seq *_loop1_218_rule(Parser *p); static void *_tmp_219_rule(Parser *p); static void *_tmp_220_rule(Parser *p); static void *_tmp_221_rule(Parser *p); @@ -1071,9 +1083,9 @@ static void *_tmp_224_rule(Parser *p); static void *_tmp_225_rule(Parser *p); static void *_tmp_226_rule(Parser *p); static void *_tmp_227_rule(Parser *p); -static asdl_seq *_loop0_229_rule(Parser *p); -static asdl_seq *_gather_228_rule(Parser *p); -static void *_tmp_230_rule(Parser *p); +static void *_tmp_228_rule(Parser *p); +static asdl_seq *_loop0_230_rule(Parser *p); +static asdl_seq *_gather_229_rule(Parser *p); static void *_tmp_231_rule(Parser *p); static void *_tmp_232_rule(Parser *p); static void *_tmp_233_rule(Parser *p); @@ -1086,8 +1098,8 @@ static void *_tmp_239_rule(Parser *p); static void *_tmp_240_rule(Parser *p); static void *_tmp_241_rule(Parser *p); static void *_tmp_242_rule(Parser *p); -static asdl_seq *_loop0_243_rule(Parser *p); -static void *_tmp_244_rule(Parser *p); +static void *_tmp_243_rule(Parser *p); +static asdl_seq *_loop0_244_rule(Parser *p); static void *_tmp_245_rule(Parser *p); static void *_tmp_246_rule(Parser *p); static void *_tmp_247_rule(Parser *p); @@ -1117,8 +1129,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? $ @@ -2028,6 +2046,7 @@ simple_stmt_rule(Parser *p) } // compound_stmt: +// | invalid_compound_stmt // | &('def' | '@' | 'async') function_def // | &'if' if_stmt // | &('class' | '@') class_def @@ -2048,6 +2067,25 @@ compound_stmt_rule(Parser *p) } stmt_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_compound_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_compound_stmt")); + void *invalid_compound_stmt_var; + if ( + (invalid_compound_stmt_var = invalid_compound_stmt_rule(p)) // invalid_compound_stmt + ) + { + D(fprintf(stderr, "%*c+ compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_compound_stmt")); + _res = invalid_compound_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, "invalid_compound_stmt")); + } { // &('def' | '@' | 'async') function_def if (p->error_indicator) { p->level--; @@ -2077,7 +2115,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, 656) // token='if' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 658) // token='if' && (if_stmt_var = if_stmt_rule(p)) // if_stmt ) @@ -2161,7 +2199,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, 638) // token='try' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 640) // token='try' && (try_stmt_var = try_stmt_rule(p)) // try_stmt ) @@ -2182,7 +2220,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, 661) // token='while' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 663) // token='while' && (while_stmt_var = while_stmt_rule(p)) // while_stmt ) @@ -4322,7 +4360,7 @@ class_def_raw_rule(Parser *p) asdl_stmt_seq* c; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 671)) // token='class' + (_keyword = _PyPegen_expect_token(p, 673)) // token='class' && (a = _PyPegen_name_token(p)) // NAME && @@ -4489,7 +4527,7 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='def' + (_keyword = _PyPegen_expect_token(p, 671)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4550,9 +4588,9 @@ function_def_raw_rule(Parser *p) void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 669)) // token='def' + (_keyword_1 = _PyPegen_expect_token(p, 671)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -5890,7 +5928,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -5935,7 +5973,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -6030,7 +6068,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 658)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 660)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6075,7 +6113,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 658)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 660)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6156,7 +6194,7 @@ else_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 659)) // token='else' + (_keyword = _PyPegen_expect_token(p, 661)) // token='else' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6235,7 +6273,7 @@ while_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 661)) // token='while' + (_keyword = _PyPegen_expect_token(p, 663)) // token='while' && (a = named_expression_rule(p)) // named_expression && @@ -6335,11 +6373,11 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword = _PyPegen_expect_token(p, 668)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 669)) // token='in' && (_cut_var = 1) && @@ -6397,13 +6435,13 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 668)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_2 = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 669)) // token='in' && (_cut_var = 1) && @@ -6471,7 +6509,7 @@ for_stmt_rule(Parser *p) // with_stmt: // | invalid_with_stmt_indent -// | 'with' '(' ','.with_item+ ','? ')' ':' block +// | 'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block // | 'with' ','.with_item+ ':' TYPE_COMMENT? block // | 'async' 'with' '(' ','.with_item+ ','? ')' ':' block // | 'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block @@ -6516,12 +6554,12 @@ 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, "invalid_with_stmt_indent")); } - { // 'with' '(' ','.with_item+ ','? ')' ':' block + { // '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, "'with' '(' ','.with_item+ ','? ')' ':' block")); + D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block")); Token * _keyword; Token * _literal; Token * _literal_1; @@ -6530,8 +6568,9 @@ with_stmt_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_withitem_seq* a; asdl_stmt_seq* b; + void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword = _PyPegen_expect_token(p, 631)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -6543,10 +6582,12 @@ with_stmt_rule(Parser *p) && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && (b = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); + D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -6556,7 +6597,7 @@ with_stmt_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = CHECK_VERSION ( stmt_ty , 9 , "Parenthesized context managers are" , _PyAST_With ( a , b , NULL , EXTRA ) ); + _res = CHECK_VERSION ( stmt_ty , 9 , "Parenthesized context managers are" , _PyAST_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -6566,7 +6607,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, "'with' '(' ','.with_item+ ','? ')' ':' block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block")); } { // 'with' ','.with_item+ ':' TYPE_COMMENT? block if (p->error_indicator) { @@ -6580,7 +6621,7 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword = _PyPegen_expect_token(p, 631)) // token='with' && (a = (asdl_withitem_seq*)_gather_53_rule(p)) // ','.with_item+ && @@ -6629,9 +6670,9 @@ with_stmt_rule(Parser *p) asdl_withitem_seq* a; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 631)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && @@ -6681,9 +6722,9 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword_1 = _PyPegen_expect_token(p, 631)) // token='with' && (a = (asdl_withitem_seq*)_gather_57_rule(p)) // ','.with_item+ && @@ -6769,7 +6810,7 @@ with_item_rule(Parser *p) if ( (e = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (t = star_target_rule(p)) // star_target && @@ -6894,7 +6935,7 @@ try_stmt_rule(Parser *p) asdl_stmt_seq* b; asdl_stmt_seq* f; if ( - (_keyword = _PyPegen_expect_token(p, 638)) // token='try' + (_keyword = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6938,7 +6979,7 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 638)) // token='try' + (_keyword = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6986,7 +7027,7 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 638)) // token='try' + (_keyword = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7084,7 +7125,7 @@ except_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='except' + (_keyword = _PyPegen_expect_token(p, 653)) // token='except' && (e = expression_rule(p)) // expression && @@ -7127,7 +7168,7 @@ except_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='except' + (_keyword = _PyPegen_expect_token(p, 653)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7238,7 +7279,7 @@ except_star_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='except' + (_keyword = _PyPegen_expect_token(p, 653)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && @@ -7340,7 +7381,7 @@ finally_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 649)) // token='finally' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7648,7 +7689,7 @@ guard_rule(Parser *p) Token * _keyword; expr_ty guard; if ( - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (guard = named_expression_rule(p)) // named_expression ) @@ -7843,7 +7884,7 @@ as_pattern_rule(Parser *p) if ( (pattern = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (target = pattern_capture_target_rule(p)) // pattern_capture_target ) @@ -11066,11 +11107,11 @@ expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 659)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 661)) // token='else' && (c = expression_rule(p)) // expression ) @@ -12608,7 +12649,7 @@ notin_bitwise_or_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 588)) // token='not' && - (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 669)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12654,7 +12695,7 @@ in_bitwise_or_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword = _PyPegen_expect_token(p, 669)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -16834,13 +16875,13 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' && - (_keyword_1 = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword_1 = _PyPegen_expect_token(p, 668)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_2 = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword_2 = _PyPegen_expect_token(p, 669)) // token='in' && (_cut_var = 1) && @@ -16879,11 +16920,11 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword = _PyPegen_expect_token(p, 668)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 669)) // token='in' && (_cut_var = 1) && @@ -19709,7 +19750,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 '=' &(',' | ')') @@ -19728,25 +19769,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--; @@ -19756,7 +19797,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) { @@ -19776,7 +19817,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]")); @@ -19836,13 +19877,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 '=' &(',' | ')')")); @@ -19980,7 +20021,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='=' ) @@ -20040,7 +20081,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 && @@ -20143,11 +20184,11 @@ expression_without_invalid_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 659)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 661)) // token='else' && (c = expression_rule(p)) // expression ) @@ -20296,7 +20337,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 && @@ -20328,11 +20369,11 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // 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' | ':')")); @@ -20453,7 +20494,7 @@ invalid_named_expression_rule(Parser *p) && (b = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_157_rule, p) + _PyPegen_lookahead(0, _tmp_158_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); @@ -20479,7 +20520,7 @@ invalid_named_expression_rule(Parser *p) Token * b; expr_ty bitwise_or_var; if ( - _PyPegen_lookahead(0, _tmp_158_rule, p) + _PyPegen_lookahead(0, _tmp_159_rule, p) && (a = bitwise_or_rule(p)) // bitwise_or && @@ -20487,7 +20528,7 @@ invalid_named_expression_rule(Parser *p) && (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_159_rule, p) + _PyPegen_lookahead(0, _tmp_160_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); @@ -20567,7 +20608,7 @@ invalid_assignment_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_160_var; + asdl_seq * _loop0_161_var; expr_ty a; expr_ty expression_var; if ( @@ -20575,7 +20616,7 @@ invalid_assignment_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_160_var = _loop0_160_rule(p)) // star_named_expressions* + (_loop0_161_var = _loop0_161_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20632,10 +20673,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - asdl_seq * _loop0_161_var; + asdl_seq * _loop0_162_var; expr_ty a; if ( - (_loop0_161_var = _loop0_161_rule(p)) // ((star_targets '='))* + (_loop0_162_var = _loop0_162_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -20662,10 +20703,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); Token * _literal; - asdl_seq * _loop0_162_var; + asdl_seq * _loop0_163_var; expr_ty a; if ( - (_loop0_162_var = _loop0_162_rule(p)) // ((star_targets '='))* + (_loop0_163_var = _loop0_163_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -20691,7 +20732,7 @@ invalid_assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_163_var; + void *_tmp_164_var; expr_ty a; AugOperator* augassign_var; if ( @@ -20699,7 +20740,7 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_163_var = _tmp_163_rule(p)) // yield_expr | star_expressions + (_tmp_164_var = _tmp_164_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); @@ -20921,11 +20962,11 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_164_var; + void *_tmp_165_var; expr_ty a; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_164_var = _tmp_164_rule(p)) // '[' | '(' | '{' + (_tmp_165_var = _tmp_165_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -20952,12 +20993,12 @@ invalid_comprehension_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); Token * _literal; - void *_tmp_165_var; + void *_tmp_166_var; expr_ty a; asdl_expr_seq* b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_165_var = _tmp_165_rule(p)) // '[' | '{' + (_tmp_166_var = _tmp_166_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -20987,12 +21028,12 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); - void *_tmp_166_var; + void *_tmp_167_var; expr_ty a; Token * b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_166_var = _tmp_166_rule(p)) // '[' | '{' + (_tmp_167_var = _tmp_167_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -21127,13 +21168,13 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); - asdl_seq * _loop0_168_var; - void *_tmp_167_var; + asdl_seq * _loop0_169_var; + void *_tmp_168_var; Token * a; if ( - (_tmp_167_var = _tmp_167_rule(p)) // slash_no_default | slash_with_default + (_tmp_168_var = _tmp_168_rule(p)) // slash_no_default | slash_with_default && - (_loop0_168_var = _loop0_168_rule(p)) // param_maybe_default* + (_loop0_169_var = _loop0_169_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21157,7 +21198,7 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); - asdl_seq * _loop0_169_var; + asdl_seq * _loop0_170_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings arg_ty a; @@ -21165,7 +21206,7 @@ invalid_parameters_rule(Parser *p) if ( (_opt_var = slash_no_default_rule(p), !p->error_indicator) // slash_no_default? && - (_loop0_169_var = _loop0_169_rule(p)) // param_no_default* + (_loop0_170_var = _loop0_170_rule(p)) // param_no_default* && (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper && @@ -21191,18 +21232,18 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); - asdl_seq * _loop0_170_var; - asdl_seq * _loop1_171_var; + asdl_seq * _loop0_171_var; + asdl_seq * _loop1_172_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_170_var = _loop0_170_rule(p)) // param_no_default* + (_loop0_171_var = _loop0_171_rule(p)) // param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_loop1_171_var = _loop1_171_rule(p)) // param_no_default+ + (_loop1_172_var = _loop1_172_rule(p)) // param_no_default+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21229,22 +21270,22 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_173_var; - asdl_seq * _loop0_175_var; + asdl_seq * _loop0_174_var; + asdl_seq * _loop0_176_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_174_var; + void *_tmp_175_var; Token * a; if ( - (_opt_var = _tmp_172_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + (_opt_var = _tmp_173_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] && - (_loop0_173_var = _loop0_173_rule(p)) // param_maybe_default* + (_loop0_174_var = _loop0_174_rule(p)) // param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_174_var = _tmp_174_rule(p)) // ',' | param_no_default + (_tmp_175_var = _tmp_175_rule(p)) // ',' | param_no_default && - (_loop0_175_var = _loop0_175_rule(p)) // param_maybe_default* + (_loop0_176_var = _loop0_176_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21269,10 +21310,10 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_176_var; + asdl_seq * _loop1_177_var; Token * a; if ( - (_loop1_176_var = _loop1_176_rule(p)) // param_maybe_default+ + (_loop1_177_var = _loop1_177_rule(p)) // param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -21321,7 +21362,7 @@ invalid_default_rule(Parser *p) if ( (a = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_177_rule, p) + _PyPegen_lookahead(1, _tmp_178_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); @@ -21366,12 +21407,12 @@ invalid_star_etc_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_178_var; + void *_tmp_179_var; Token * a; if ( (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_178_var = _tmp_178_rule(p)) // ')' | ',' (')' | '**') + (_tmp_179_var = _tmp_179_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -21454,20 +21495,20 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_180_var; - void *_tmp_179_var; - void *_tmp_181_var; + asdl_seq * _loop0_181_var; + void *_tmp_180_var; + void *_tmp_182_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_179_var = _tmp_179_rule(p)) // param_no_default | ',' + (_tmp_180_var = _tmp_180_rule(p)) // param_no_default | ',' && - (_loop0_180_var = _loop0_180_rule(p)) // param_maybe_default* + (_loop0_181_var = _loop0_181_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_181_var = _tmp_181_rule(p)) // param_no_default | ',' + (_tmp_182_var = _tmp_182_rule(p)) // param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); @@ -21582,7 +21623,7 @@ invalid_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_182_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_183_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); @@ -21647,13 +21688,13 @@ invalid_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_183_var; + asdl_seq * _loop1_184_var; if ( - (_loop1_183_var = _loop1_183_rule(p)) // param_with_default+ + (_loop1_184_var = _loop1_184_rule(p)) // param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_183_var; + _res = _loop1_184_var; goto done; } p->mark = _mark; @@ -21718,13 +21759,13 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); - asdl_seq * _loop0_185_var; - void *_tmp_184_var; + asdl_seq * _loop0_186_var; + void *_tmp_185_var; Token * a; if ( - (_tmp_184_var = _tmp_184_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + (_tmp_185_var = _tmp_185_rule(p)) // lambda_slash_no_default | lambda_slash_with_default && - (_loop0_185_var = _loop0_185_rule(p)) // lambda_param_maybe_default* + (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21748,7 +21789,7 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_186_var; + asdl_seq * _loop0_187_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings arg_ty a; @@ -21756,7 +21797,7 @@ invalid_lambda_parameters_rule(Parser *p) if ( (_opt_var = lambda_slash_no_default_rule(p), !p->error_indicator) // lambda_slash_no_default? && - (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_no_default* + (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_no_default* && (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper && @@ -21782,18 +21823,18 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - asdl_seq * _gather_188_var; - asdl_seq * _loop0_187_var; + asdl_seq * _gather_189_var; + asdl_seq * _loop0_188_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_no_default* + (_loop0_188_var = _loop0_188_rule(p)) // lambda_param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_188_var = _gather_188_rule(p)) // ','.lambda_param+ + (_gather_189_var = _gather_189_rule(p)) // ','.lambda_param+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21820,22 +21861,22 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_191_var; - asdl_seq * _loop0_193_var; + asdl_seq * _loop0_192_var; + asdl_seq * _loop0_194_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_192_var; + void *_tmp_193_var; Token * a; if ( - (_opt_var = _tmp_190_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + (_opt_var = _tmp_191_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] && - (_loop0_191_var = _loop0_191_rule(p)) // lambda_param_maybe_default* + (_loop0_192_var = _loop0_192_rule(p)) // lambda_param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_192_var = _tmp_192_rule(p)) // ',' | lambda_param_no_default + (_tmp_193_var = _tmp_193_rule(p)) // ',' | lambda_param_no_default && - (_loop0_193_var = _loop0_193_rule(p)) // lambda_param_maybe_default* + (_loop0_194_var = _loop0_194_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -21860,10 +21901,10 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_194_var; + asdl_seq * _loop1_195_var; Token * a; if ( - (_loop1_194_var = _loop1_194_rule(p)) // lambda_param_maybe_default+ + (_loop1_195_var = _loop1_195_rule(p)) // lambda_param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -21934,13 +21975,13 @@ invalid_lambda_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_195_var; + asdl_seq * _loop1_196_var; if ( - (_loop1_195_var = _loop1_195_rule(p)) // lambda_param_with_default+ + (_loop1_196_var = _loop1_196_rule(p)) // lambda_param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_195_var; + _res = _loop1_196_var; goto done; } p->mark = _mark; @@ -21976,11 +22017,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_196_var; + void *_tmp_197_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_196_var = _tmp_196_rule(p)) // ':' | ',' (':' | '**') + (_tmp_197_var = _tmp_197_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -22033,20 +22074,20 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_198_var; - void *_tmp_197_var; - void *_tmp_199_var; + asdl_seq * _loop0_199_var; + void *_tmp_198_var; + void *_tmp_200_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_197_var = _tmp_197_rule(p)) // lambda_param_no_default | ',' + (_tmp_198_var = _tmp_198_rule(p)) // lambda_param_no_default | ',' && - (_loop0_198_var = _loop0_198_rule(p)) // lambda_param_maybe_default* + (_loop0_199_var = _loop0_199_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_199_var = _tmp_199_rule(p)) // lambda_param_no_default | ',' + (_tmp_200_var = _tmp_200_rule(p)) // lambda_param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); @@ -22164,7 +22205,7 @@ invalid_lambda_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_200_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_201_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); @@ -22266,11 +22307,11 @@ invalid_with_item_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_201_rule, p) + _PyPegen_lookahead(1, _tmp_202_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -22316,9 +22357,9 @@ invalid_for_target_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings expr_ty a; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword = _PyPegen_expect_token(p, 668)) // token='for' && (a = star_expressions_rule(p)) // star_expressions ) @@ -22443,14 +22484,14 @@ invalid_import_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_import[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); - asdl_seq * _gather_202_var; + asdl_seq * _gather_203_var; Token * _keyword; Token * a; expr_ty dotted_name_var; if ( (a = _PyPegen_expect_token(p, 617)) // token='import' && - (_gather_202_var = _gather_202_rule(p)) // ','.dotted_name+ + (_gather_203_var = _gather_203_rule(p)) // ','.dotted_name+ && (_keyword = _PyPegen_expect_token(p, 618)) // token='from' && @@ -22525,6 +22566,82 @@ invalid_import_from_targets_rule(Parser *p) return _res; } +// invalid_compound_stmt: 'elif' named_expression ':' | 'else' ':' +static void * +invalid_compound_stmt_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; + { // 'elif' named_expression ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':'")); + Token * _literal; + Token * a; + expr_ty named_expression_var; + if ( + (a = _PyPegen_expect_token(p, 660)) // token='elif' + && + (named_expression_var = named_expression_rule(p)) // named_expression + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':'")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "'elif' must match an if-statement here" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'elif' named_expression ':'")); + } + { // 'else' ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' ':'")); + Token * _literal; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 661)) // token='else' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_compound_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else' ':'")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "'else' must match a valid statement here" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_compound_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else' ':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // invalid_with_stmt: // | 'async'? 'with' ','.(expression ['as' star_target])+ NEWLINE // | 'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE @@ -22546,17 +22663,17 @@ invalid_with_stmt_rule(Parser *p) 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")); - asdl_seq * _gather_204_var; + 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, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword = _PyPegen_expect_token(p, 631)) // token='with' && - (_gather_204_var = _gather_204_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_205_var = _gather_205_rule(p)) // ','.(expression ['as' star_target])+ && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -22580,7 +22697,7 @@ invalid_with_stmt_rule(Parser *p) 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")); - asdl_seq * _gather_206_var; + asdl_seq * _gather_207_var; Token * _keyword; Token * _literal; Token * _literal_1; @@ -22590,13 +22707,13 @@ invalid_with_stmt_rule(Parser *p) UNUSED(_opt_var_1); // Silence compiler warnings Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword = _PyPegen_expect_token(p, 631)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_206_var = _gather_206_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_207_var = _gather_207_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -22645,18 +22762,18 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); - asdl_seq * _gather_208_var; + asdl_seq * _gather_209_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 629)) // token='with' + (a = _PyPegen_expect_token(p, 631)) // token='with' && - (_gather_208_var = _gather_208_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_209_var = _gather_209_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22684,7 +22801,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); - asdl_seq * _gather_210_var; + asdl_seq * _gather_211_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -22695,13 +22812,13 @@ invalid_with_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 629)) // token='with' + (a = _PyPegen_expect_token(p, 631)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_210_var = _gather_210_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_211_var = _gather_211_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -22760,7 +22877,7 @@ invalid_try_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 638)) // token='try' + (a = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22792,13 +22909,13 @@ invalid_try_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 638)) // token='try' + (_keyword = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_212_rule, p) + _PyPegen_lookahead(0, _tmp_213_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -22823,29 +22940,29 @@ invalid_try_stmt_rule(Parser *p) Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_213_var; - asdl_seq * _loop1_214_var; + asdl_seq * _loop0_214_var; + asdl_seq * _loop1_215_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 638)) // token='try' + (_keyword = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_213_var = _loop0_213_rule(p)) // block* + (_loop0_214_var = _loop0_214_rule(p)) // block* && - (_loop1_214_var = _loop1_214_rule(p)) // except_block+ + (_loop1_215_var = _loop1_215_rule(p)) // except_block+ && - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (b = _PyPegen_expect_token(p, 16)) // token='*' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_215_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_216_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22872,23 +22989,23 @@ invalid_try_stmt_rule(Parser *p) Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_216_var; - asdl_seq * _loop1_217_var; + asdl_seq * _loop0_217_var; + asdl_seq * _loop1_218_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; if ( - (_keyword = _PyPegen_expect_token(p, 638)) // token='try' + (_keyword = _PyPegen_expect_token(p, 640)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_216_var = _loop0_216_rule(p)) // block* + (_loop0_217_var = _loop0_217_rule(p)) // block* && - (_loop1_217_var = _loop1_217_rule(p)) // except_star_block+ + (_loop1_218_var = _loop1_218_rule(p)) // except_star_block+ && - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && - (_opt_var = _tmp_218_rule(p), !p->error_indicator) // [expression ['as' NAME]] + (_opt_var = _tmp_219_rule(p), !p->error_indicator) // [expression ['as' NAME]] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22945,7 +23062,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty a; expr_ty expressions_var; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='except' + (_keyword = _PyPegen_expect_token(p, 653)) // token='except' && (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && @@ -22955,7 +23072,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var_1 = _tmp_219_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_220_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22987,13 +23104,13 @@ invalid_except_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && (expression_var = expression_rule(p)) // expression && - (_opt_var_1 = _tmp_220_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_221_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -23020,7 +23137,7 @@ invalid_except_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -23045,14 +23162,14 @@ invalid_except_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); Token * _literal; - void *_tmp_221_var; + void *_tmp_222_var; Token * a; if ( - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_221_var = _tmp_221_rule(p)) // NEWLINE | ':' + (_tmp_222_var = _tmp_222_rule(p)) // NEWLINE | ':' ) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); @@ -23097,7 +23214,7 @@ invalid_finally_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 647)) // token='finally' + (a = _PyPegen_expect_token(p, 649)) // token='finally' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23153,11 +23270,11 @@ invalid_except_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_222_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_223_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23189,7 +23306,7 @@ invalid_except_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23245,13 +23362,13 @@ invalid_except_star_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 651)) // token='except' + (a = _PyPegen_expect_token(p, 653)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_223_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_224_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23484,7 +23601,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' ) @@ -23514,7 +23631,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p) && @@ -23615,7 +23732,7 @@ invalid_class_argument_pattern_rule(Parser *p) asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_224_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_225_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -23668,7 +23785,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23699,7 +23816,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty a_1; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 656)) // token='if' + (a = _PyPegen_expect_token(p, 658)) // token='if' && (a_1 = named_expression_rule(p)) // named_expression && @@ -23754,7 +23871,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 658)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 660)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23785,7 +23902,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 658)) // token='elif' + (a = _PyPegen_expect_token(p, 660)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23838,7 +23955,7 @@ invalid_else_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 659)) // token='else' + (a = _PyPegen_expect_token(p, 661)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23891,7 +24008,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 661)) // token='while' + (_keyword = _PyPegen_expect_token(p, 663)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23922,7 +24039,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 661)) // token='while' + (a = _PyPegen_expect_token(p, 663)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23981,13 +24098,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (_keyword = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword = _PyPegen_expect_token(p, 668)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 669)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -24022,13 +24139,13 @@ invalid_for_stmt_rule(Parser *p) expr_ty star_expressions_var; expr_ty star_targets_var; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 666)) // token='for' + (a = _PyPegen_expect_token(p, 668)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword = _PyPegen_expect_token(p, 667)) // token='in' + (_keyword = _PyPegen_expect_token(p, 669)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -24059,7 +24176,7 @@ invalid_for_stmt_rule(Parser *p) } // invalid_def_raw: -// | 'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT +// | 'async'? 'def' NAME type_params? '(' params? ')' ['->' expression] ':' NEWLINE !INDENT static void * invalid_def_raw_rule(Parser *p) { @@ -24072,12 +24189,12 @@ invalid_def_raw_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'async'? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT + { // 'async'? 'def' NAME type_params? '(' 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 type_params? '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); Token * _literal; Token * _literal_1; Token * _literal_2; @@ -24087,23 +24204,27 @@ invalid_def_raw_rule(Parser *p) UNUSED(_opt_var_1); // Silence compiler warnings void *_opt_var_2; UNUSED(_opt_var_2); // Silence compiler warnings + void *_opt_var_3; + UNUSED(_opt_var_3); // Silence compiler warnings Token * a; expr_ty name_var; Token * newline_var; if ( - (_opt_var = _PyPegen_expect_token(p, 668), !p->error_indicator) // 'async'? + (_opt_var = _PyPegen_expect_token(p, 670), !p->error_indicator) // 'async'? && - (a = _PyPegen_expect_token(p, 669)) // token='def' + (a = _PyPegen_expect_token(p, 671)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && + (_opt_var_1 = type_params_rule(p), !p->error_indicator) // type_params? + && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_opt_var_1 = params_rule(p), !p->error_indicator) // params? + (_opt_var_2 = params_rule(p), !p->error_indicator) // params? && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_2 = _tmp_225_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_3 = _tmp_226_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24112,7 +24233,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 type_params? '(' 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; @@ -24123,7 +24244,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 type_params? '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); } _res = NULL; done: @@ -24132,8 +24253,8 @@ invalid_def_raw_rule(Parser *p) } // invalid_class_def_raw: -// | 'class' NAME ['(' arguments? ')'] NEWLINE -// | 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT +// | 'class' NAME type_params? ['(' arguments? ')'] NEWLINE +// | 'class' NAME type_params? ['(' arguments? ')'] ':' NEWLINE !INDENT static void * invalid_class_def_raw_rule(Parser *p) { @@ -24146,28 +24267,32 @@ invalid_class_def_raw_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'class' NAME ['(' arguments? ')'] NEWLINE + { // 'class' NAME type_params? ['(' arguments? ')'] NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] NEWLINE")); + D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] NEWLINE")); Token * _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings expr_ty name_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 671)) // token='class' + (_keyword = _PyPegen_expect_token(p, 673)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_226_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = type_params_rule(p), !p->error_indicator) // type_params? + && + (_opt_var_1 = _tmp_227_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] NEWLINE")); + D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24178,26 +24303,30 @@ invalid_class_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] NEWLINE")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] NEWLINE")); } - { // 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT + { // 'class' NAME type_params? ['(' arguments? ')'] ':' NEWLINE !INDENT if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' NEWLINE !INDENT")); Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings Token * a; expr_ty name_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 671)) // token='class' + (a = _PyPegen_expect_token(p, 673)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_227_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = type_params_rule(p), !p->error_indicator) // type_params? + && + (_opt_var_1 = _tmp_228_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -24206,7 +24335,7 @@ invalid_class_def_raw_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT ) { - D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); + D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' NEWLINE !INDENT")); _res = RAISE_INDENTATION_ERROR ( "expected an indented block after class definition on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24217,7 +24346,7 @@ invalid_class_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' NEWLINE !INDENT")); } _res = NULL; done: @@ -24247,11 +24376,11 @@ invalid_double_starred_kvpairs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - asdl_seq * _gather_228_var; + asdl_seq * _gather_229_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_228_var = _gather_228_rule(p)) // ','.double_starred_kvpair+ + (_gather_229_var = _gather_229_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -24259,7 +24388,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - _res = _PyPegen_dummy_name(p, _gather_228_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_229_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -24312,7 +24441,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_230_rule, p) + _PyPegen_lookahead(1, _tmp_231_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -24422,7 +24551,7 @@ invalid_kvpair_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_231_rule, p) + _PyPegen_lookahead(1, _tmp_232_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -24638,7 +24767,7 @@ invalid_replacement_field_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - _PyPegen_lookahead(0, _tmp_232_rule, p) + _PyPegen_lookahead(0, _tmp_233_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !(yield_expr | star_expressions)")); @@ -24661,13 +24790,13 @@ invalid_replacement_field_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); Token * _literal; - void *_tmp_233_var; + void *_tmp_234_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_233_var = _tmp_233_rule(p)) // yield_expr | star_expressions + (_tmp_234_var = _tmp_234_rule(p)) // yield_expr | star_expressions && - _PyPegen_lookahead(0, _tmp_234_rule, p) + _PyPegen_lookahead(0, _tmp_235_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); @@ -24691,15 +24820,15 @@ invalid_replacement_field_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); Token * _literal; Token * _literal_1; - void *_tmp_235_var; + void *_tmp_236_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_235_var = _tmp_235_rule(p)) // yield_expr | star_expressions + (_tmp_236_var = _tmp_236_rule(p)) // yield_expr | star_expressions && (_literal_1 = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(0, _tmp_236_rule, p) + _PyPegen_lookahead(0, _tmp_237_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); @@ -24724,12 +24853,12 @@ invalid_replacement_field_rule(Parser *p) Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_237_var; + void *_tmp_238_var; void *invalid_conversion_character_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_237_var = _tmp_237_rule(p)) // yield_expr | star_expressions + (_tmp_238_var = _tmp_238_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && @@ -24737,7 +24866,7 @@ invalid_replacement_field_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_237_var, _opt_var, invalid_conversion_character_var); + _res = _PyPegen_dummy_name(p, _literal, _tmp_238_var, _opt_var, invalid_conversion_character_var); goto done; } p->mark = _mark; @@ -24755,17 +24884,17 @@ invalid_replacement_field_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_238_var; + void *_tmp_239_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_238_var = _tmp_238_rule(p)) // yield_expr | star_expressions + (_tmp_239_var = _tmp_239_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_239_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_240_rule(p), !p->error_indicator) // ['!' NAME] && - _PyPegen_lookahead(0, _tmp_240_rule, p) + _PyPegen_lookahead(0, _tmp_241_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')")); @@ -24789,24 +24918,24 @@ invalid_replacement_field_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_243_var; + asdl_seq * _loop0_244_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_241_var; + void *_tmp_242_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_241_var = _tmp_241_rule(p)) // yield_expr | star_expressions + (_tmp_242_var = _tmp_242_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_242_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_243_rule(p), !p->error_indicator) // ['!' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_243_var = _loop0_243_rule(p)) // fstring_format_spec* + (_loop0_244_var = _loop0_244_rule(p)) // fstring_format_spec* && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) @@ -24835,15 +24964,15 @@ invalid_replacement_field_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings - void *_tmp_244_var; + void *_tmp_245_var; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (_tmp_244_var = _tmp_244_rule(p)) // yield_expr | star_expressions + (_tmp_245_var = _tmp_245_rule(p)) // yield_expr | star_expressions && (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? && - (_opt_var_1 = _tmp_245_rule(p), !p->error_indicator) // ['!' NAME] + (_opt_var_1 = _tmp_246_rule(p), !p->error_indicator) // ['!' NAME] && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) @@ -24890,7 +25019,7 @@ invalid_conversion_character_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' && - _PyPegen_lookahead(1, _tmp_246_rule, p) + _PyPegen_lookahead(1, _tmp_247_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); @@ -25339,7 +25468,7 @@ _tmp_7_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 669)) // token='def' + (_keyword = _PyPegen_expect_token(p, 671)) // token='def' ) { D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); @@ -25377,7 +25506,7 @@ _tmp_7_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -25415,7 +25544,7 @@ _tmp_8_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 671)) // token='class' + (_keyword = _PyPegen_expect_token(p, 673)) // token='class' ) { D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); @@ -25472,7 +25601,7 @@ _tmp_9_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 629)) // token='with' + (_keyword = _PyPegen_expect_token(p, 631)) // token='with' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); @@ -25491,7 +25620,7 @@ _tmp_9_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -25529,7 +25658,7 @@ _tmp_10_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 666)) // token='for' + (_keyword = _PyPegen_expect_token(p, 668)) // token='for' ) { D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); @@ -25548,7 +25677,7 @@ _tmp_10_rule(Parser *p) D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'async'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 668)) // token='async' + (_keyword = _PyPegen_expect_token(p, 670)) // token='async' ) { D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'async'")); @@ -25753,12 +25882,12 @@ _loop1_14_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_247_var; + void *_tmp_248_var; while ( - (_tmp_247_var = _tmp_247_rule(p)) // star_targets '=' + (_tmp_248_var = _tmp_248_rule(p)) // star_targets '=' ) { - _res = _tmp_247_var; + _res = _tmp_248_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26322,12 +26451,12 @@ _loop0_24_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_248_var; + void *_tmp_249_var; while ( - (_tmp_248_var = _tmp_248_rule(p)) // '.' | '...' + (_tmp_249_var = _tmp_249_rule(p)) // '.' | '...' ) { - _res = _tmp_248_var; + _res = _tmp_249_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26389,12 +26518,12 @@ _loop1_25_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_249_var; + void *_tmp_250_var; while ( - (_tmp_249_var = _tmp_249_rule(p)) // '.' | '...' + (_tmp_250_var = _tmp_250_rule(p)) // '.' | '...' ) { - _res = _tmp_249_var; + _res = _tmp_250_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26572,7 +26701,7 @@ _tmp_28_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -26735,7 +26864,7 @@ _tmp_31_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -26787,12 +26916,12 @@ _loop1_32_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_250_var; + void *_tmp_251_var; while ( - (_tmp_250_var = _tmp_250_rule(p)) // '@' named_expression NEWLINE + (_tmp_251_var = _tmp_251_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_250_var; + _res = _tmp_251_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28722,7 +28851,7 @@ _tmp_62_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -28768,7 +28897,7 @@ _tmp_63_rule(Parser *p) Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -29917,12 +30046,12 @@ _loop1_82_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_251_var; + void *_tmp_252_var; while ( - (_tmp_251_var = _tmp_251_rule(p)) // ',' expression + (_tmp_252_var = _tmp_252_rule(p)) // ',' expression ) { - _res = _tmp_251_var; + _res = _tmp_252_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -29989,12 +30118,12 @@ _loop1_83_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_252_var; + void *_tmp_253_var; while ( - (_tmp_252_var = _tmp_252_rule(p)) // ',' star_expression + (_tmp_253_var = _tmp_253_rule(p)) // ',' star_expression ) { - _res = _tmp_252_var; + _res = _tmp_253_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30178,12 +30307,12 @@ _loop1_86_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_253_var; + void *_tmp_254_var; while ( - (_tmp_253_var = _tmp_253_rule(p)) // 'or' conjunction + (_tmp_254_var = _tmp_254_rule(p)) // 'or' conjunction ) { - _res = _tmp_253_var; + _res = _tmp_254_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30250,12 +30379,12 @@ _loop1_87_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_254_var; + void *_tmp_255_var; while ( - (_tmp_254_var = _tmp_254_rule(p)) // 'and' inversion + (_tmp_255_var = _tmp_255_rule(p)) // 'and' inversion ) { - _res = _tmp_254_var; + _res = _tmp_255_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30442,7 +30571,7 @@ _loop0_91_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_255_rule(p)) // slice | starred_expression + (elem = _tmp_256_rule(p)) // slice | starred_expression ) { _res = elem; @@ -30507,7 +30636,7 @@ _gather_90_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_255_rule(p)) // slice | starred_expression + (elem = _tmp_256_rule(p)) // slice | starred_expression && (seq = _loop0_91_rule(p)) // _loop0_91 ) @@ -32106,12 +32235,12 @@ _loop1_115_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(fstring | string)")); - void *_tmp_256_var; + void *_tmp_257_var; while ( - (_tmp_256_var = _tmp_256_rule(p)) // fstring | string + (_tmp_257_var = _tmp_257_rule(p)) // fstring | string ) { - _res = _tmp_256_var; + _res = _tmp_257_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32416,12 +32545,12 @@ _loop0_120_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_257_var; + void *_tmp_258_var; while ( - (_tmp_257_var = _tmp_257_rule(p)) // 'if' disjunction + (_tmp_258_var = _tmp_258_rule(p)) // 'if' disjunction ) { - _res = _tmp_257_var; + _res = _tmp_258_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32483,12 +32612,12 @@ _loop0_121_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_258_var; + void *_tmp_259_var; while ( - (_tmp_258_var = _tmp_258_rule(p)) // 'if' disjunction + (_tmp_259_var = _tmp_259_rule(p)) // 'if' disjunction ) { - _res = _tmp_258_var; + _res = _tmp_259_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32614,7 +32743,7 @@ _loop0_124_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_259_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_260_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -32680,7 +32809,7 @@ _gather_123_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_259_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_260_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && (seq = _loop0_124_rule(p)) // _loop0_124 ) @@ -33241,12 +33370,12 @@ _loop0_134_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_260_var; + void *_tmp_261_var; while ( - (_tmp_260_var = _tmp_260_rule(p)) // ',' star_target + (_tmp_261_var = _tmp_261_rule(p)) // ',' star_target ) { - _res = _tmp_260_var; + _res = _tmp_261_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33425,12 +33554,12 @@ _loop1_137_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_261_var; + void *_tmp_262_var; while ( - (_tmp_261_var = _tmp_261_rule(p)) // ',' star_target + (_tmp_262_var = _tmp_262_rule(p)) // ',' star_target ) { - _res = _tmp_261_var; + _res = _tmp_262_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34135,9 +34264,68 @@ _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) { + _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); @@ -34153,18 +34341,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 @@ -34172,7 +34360,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 ( @@ -34181,12 +34369,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; @@ -34195,9 +34383,9 @@ _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) { _Pypegen_stack_overflow(p); @@ -34213,7 +34401,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 ( @@ -34222,12 +34410,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; @@ -34236,9 +34424,9 @@ _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) { _Pypegen_stack_overflow(p); @@ -34254,18 +34442,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, "','")); } { // ')' @@ -34273,18 +34461,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; @@ -34293,9 +34481,9 @@ _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) { _Pypegen_stack_overflow(p); @@ -34311,18 +34499,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, 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' @@ -34330,18 +34518,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, 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' @@ -34349,18 +34537,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, 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; @@ -34369,9 +34557,9 @@ _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) { _Pypegen_stack_overflow(p); @@ -34387,7 +34575,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 ( @@ -34396,12 +34584,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; @@ -34410,9 +34598,9 @@ _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) { _Pypegen_stack_overflow(p); @@ -34428,7 +34616,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 ( @@ -34437,12 +34625,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 @@ -34450,18 +34638,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; @@ -34470,9 +34658,9 @@ _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) { _Pypegen_stack_overflow(p); @@ -34488,18 +34676,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, 659)) // token='else' + (_keyword = _PyPegen_expect_token(p, 661)) // 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'")); } { // ':' @@ -34507,18 +34695,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, "':'")); + 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, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -34527,9 +34715,9 @@ _tmp_156_rule(Parser *p) return _res; } -// _tmp_157: '=' | ':=' +// _tmp_158: '=' | ':=' static void * -_tmp_157_rule(Parser *p) +_tmp_158_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34545,18 +34733,18 @@ _tmp_157_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -34564,18 +34752,18 @@ _tmp_157_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -34584,9 +34772,9 @@ _tmp_157_rule(Parser *p) return _res; } -// _tmp_158: list | tuple | genexp | 'True' | 'None' | 'False' +// _tmp_159: list | tuple | genexp | 'True' | 'None' | 'False' static void * -_tmp_158_rule(Parser *p) +_tmp_159_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34602,18 +34790,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_159[%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_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_159[%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_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // tuple @@ -34621,18 +34809,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_159[%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_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_159[%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_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // genexp @@ -34640,18 +34828,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_159[%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_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_159[%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_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } { // 'True' @@ -34659,18 +34847,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 610)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'None' @@ -34678,18 +34866,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 611)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } { // 'False' @@ -34697,18 +34885,18 @@ _tmp_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 612)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } _res = NULL; @@ -34717,9 +34905,9 @@ _tmp_158_rule(Parser *p) return _res; } -// _tmp_159: '=' | ':=' +// _tmp_160: '=' | ':=' static void * -_tmp_159_rule(Parser *p) +_tmp_160_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34735,18 +34923,18 @@ _tmp_159_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -34754,18 +34942,18 @@ _tmp_159_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -34774,9 +34962,9 @@ _tmp_159_rule(Parser *p) return _res; } -// _loop0_160: star_named_expressions +// _loop0_161: star_named_expressions static asdl_seq * -_loop0_160_rule(Parser *p) +_loop0_161_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34801,7 +34989,7 @@ _loop0_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); asdl_expr_seq* star_named_expressions_var; while ( (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions @@ -34824,7 +35012,7 @@ _loop0_160_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34841,9 +35029,9 @@ _loop0_160_rule(Parser *p) return _seq; } -// _loop0_161: (star_targets '=') +// _loop0_162: (star_targets '=') static asdl_seq * -_loop0_161_rule(Parser *p) +_loop0_162_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34868,13 +35056,13 @@ _loop0_161_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_262_var; + D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_264_var; while ( - (_tmp_262_var = _tmp_262_rule(p)) // star_targets '=' + (_tmp_264_var = _tmp_264_rule(p)) // star_targets '=' ) { - _res = _tmp_262_var; + _res = _tmp_264_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34891,7 +35079,7 @@ _loop0_161_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34908,9 +35096,9 @@ _loop0_161_rule(Parser *p) return _seq; } -// _loop0_162: (star_targets '=') +// _loop0_163: (star_targets '=') static asdl_seq * -_loop0_162_rule(Parser *p) +_loop0_163_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34935,13 +35123,13 @@ _loop0_162_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_263_var; + D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_265_var; while ( - (_tmp_263_var = _tmp_263_rule(p)) // star_targets '=' + (_tmp_265_var = _tmp_265_rule(p)) // star_targets '=' ) { - _res = _tmp_263_var; + _res = _tmp_265_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34958,7 +35146,7 @@ _loop0_162_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34975,9 +35163,9 @@ _loop0_162_rule(Parser *p) return _seq; } -// _tmp_163: yield_expr | star_expressions +// _tmp_164: yield_expr | star_expressions static void * -_tmp_163_rule(Parser *p) +_tmp_164_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -34993,18 +35181,18 @@ _tmp_163_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_164[%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_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_164[%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_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -35012,18 +35200,18 @@ _tmp_163_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_164[%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_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_164[%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_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -35032,9 +35220,9 @@ _tmp_163_rule(Parser *p) return _res; } -// _tmp_164: '[' | '(' | '{' +// _tmp_165: '[' | '(' | '{' static void * -_tmp_164_rule(Parser *p) +_tmp_165_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35050,18 +35238,18 @@ _tmp_164_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '(' @@ -35069,18 +35257,18 @@ _tmp_164_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '{' @@ -35088,18 +35276,18 @@ _tmp_164_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35108,9 +35296,9 @@ _tmp_164_rule(Parser *p) return _res; } -// _tmp_165: '[' | '{' +// _tmp_166: '[' | '{' static void * -_tmp_165_rule(Parser *p) +_tmp_166_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35126,18 +35314,18 @@ _tmp_165_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -35145,18 +35333,18 @@ _tmp_165_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35165,9 +35353,9 @@ _tmp_165_rule(Parser *p) return _res; } -// _tmp_166: '[' | '{' +// _tmp_167: '[' | '{' static void * -_tmp_166_rule(Parser *p) +_tmp_167_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35183,18 +35371,18 @@ _tmp_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -35202,18 +35390,18 @@ _tmp_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -35222,9 +35410,9 @@ _tmp_166_rule(Parser *p) return _res; } -// _tmp_167: slash_no_default | slash_with_default +// _tmp_168: slash_no_default | slash_with_default static void * -_tmp_167_rule(Parser *p) +_tmp_168_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35240,18 +35428,18 @@ _tmp_167_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); asdl_arg_seq* slash_no_default_var; if ( (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } { // slash_with_default @@ -35259,18 +35447,18 @@ _tmp_167_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; @@ -35279,9 +35467,9 @@ _tmp_167_rule(Parser *p) return _res; } -// _loop0_168: param_maybe_default +// _loop0_169: param_maybe_default static asdl_seq * -_loop0_168_rule(Parser *p) +_loop0_169_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35306,7 +35494,7 @@ _loop0_168_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -35329,75 +35517,8 @@ _loop0_168_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_168[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - p->level--; - return _seq; -} - -// _loop0_169: param_no_default -static asdl_seq * -_loop0_169_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> _loop0_169[%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_169[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -35480,9 +35601,9 @@ _loop0_170_rule(Parser *p) return _seq; } -// _loop1_171: param_no_default +// _loop0_171: param_no_default static asdl_seq * -_loop1_171_rule(Parser *p) +_loop0_171_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35507,7 +35628,7 @@ _loop1_171_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_171[%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 @@ -35530,7 +35651,74 @@ _loop1_171_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_171[%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_172: param_no_default +static asdl_seq * +_loop1_172_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_172[%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_172[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -35552,9 +35740,9 @@ _loop1_171_rule(Parser *p) return _seq; } -// _tmp_172: slash_no_default | slash_with_default +// _tmp_173: slash_no_default | slash_with_default static void * -_tmp_172_rule(Parser *p) +_tmp_173_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35570,18 +35758,18 @@ _tmp_172_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); asdl_arg_seq* slash_no_default_var; if ( (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } { // slash_with_default @@ -35589,18 +35777,18 @@ _tmp_172_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; @@ -35609,9 +35797,9 @@ _tmp_172_rule(Parser *p) return _res; } -// _loop0_173: param_maybe_default +// _loop0_174: param_maybe_default static asdl_seq * -_loop0_173_rule(Parser *p) +_loop0_174_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35636,7 +35824,7 @@ _loop0_173_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -35659,7 +35847,7 @@ _loop0_173_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_174[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35676,9 +35864,9 @@ _loop0_173_rule(Parser *p) return _seq; } -// _tmp_174: ',' | param_no_default +// _tmp_175: ',' | param_no_default static void * -_tmp_174_rule(Parser *p) +_tmp_175_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35694,18 +35882,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // param_no_default @@ -35713,18 +35901,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } _res = NULL; @@ -35733,9 +35921,9 @@ _tmp_174_rule(Parser *p) return _res; } -// _loop0_175: param_maybe_default +// _loop0_176: param_maybe_default static asdl_seq * -_loop0_175_rule(Parser *p) +_loop0_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35760,7 +35948,7 @@ _loop0_175_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_176[%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 @@ -35783,7 +35971,7 @@ _loop0_175_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_176[%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); @@ -35800,9 +35988,9 @@ _loop0_175_rule(Parser *p) return _seq; } -// _loop1_176: param_maybe_default +// _loop1_177: param_maybe_default static asdl_seq * -_loop1_176_rule(Parser *p) +_loop1_177_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35827,7 +36015,7 @@ _loop1_176_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_177[%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 @@ -35850,7 +36038,7 @@ _loop1_176_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_176[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_177[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -35872,9 +36060,9 @@ _loop1_176_rule(Parser *p) return _seq; } -// _tmp_177: ')' | ',' +// _tmp_178: ')' | ',' static void * -_tmp_177_rule(Parser *p) +_tmp_178_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35890,18 +36078,18 @@ _tmp_177_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' @@ -35909,18 +36097,18 @@ _tmp_177_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -35929,9 +36117,9 @@ _tmp_177_rule(Parser *p) return _res; } -// _tmp_178: ')' | ',' (')' | '**') +// _tmp_179: ')' | ',' (')' | '**') static void * -_tmp_178_rule(Parser *p) +_tmp_179_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -35947,18 +36135,18 @@ _tmp_178_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -35966,21 +36154,21 @@ _tmp_178_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_264_var; + void *_tmp_266_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_264_var = _tmp_264_rule(p)) // ')' | '**' + (_tmp_266_var = _tmp_266_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_264_var); + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_266_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -35989,9 +36177,9 @@ _tmp_178_rule(Parser *p) return _res; } -// _tmp_179: param_no_default | ',' +// _tmp_180: param_no_default | ',' static void * -_tmp_179_rule(Parser *p) +_tmp_180_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36007,18 +36195,18 @@ _tmp_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -36026,18 +36214,18 @@ _tmp_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36046,9 +36234,9 @@ _tmp_179_rule(Parser *p) return _res; } -// _loop0_180: param_maybe_default +// _loop0_181: param_maybe_default static asdl_seq * -_loop0_180_rule(Parser *p) +_loop0_181_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36073,7 +36261,7 @@ _loop0_180_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_181[%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 @@ -36096,7 +36284,7 @@ _loop0_180_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36113,9 +36301,9 @@ _loop0_180_rule(Parser *p) return _seq; } -// _tmp_181: param_no_default | ',' +// _tmp_182: param_no_default | ',' static void * -_tmp_181_rule(Parser *p) +_tmp_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36131,18 +36319,18 @@ _tmp_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -36150,18 +36338,18 @@ _tmp_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36170,9 +36358,9 @@ _tmp_181_rule(Parser *p) return _res; } -// _tmp_182: '*' | '**' | '/' +// _tmp_183: '*' | '**' | '/' static void * -_tmp_182_rule(Parser *p) +_tmp_183_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36188,18 +36376,18 @@ _tmp_182_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -36207,18 +36395,18 @@ _tmp_182_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -36226,18 +36414,18 @@ _tmp_182_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -36246,9 +36434,9 @@ _tmp_182_rule(Parser *p) return _res; } -// _loop1_183: param_with_default +// _loop1_184: param_with_default static asdl_seq * -_loop1_183_rule(Parser *p) +_loop1_184_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36273,7 +36461,7 @@ _loop1_183_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_184[%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 @@ -36296,7 +36484,7 @@ _loop1_183_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_184[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -36318,9 +36506,9 @@ _loop1_183_rule(Parser *p) return _seq; } -// _tmp_184: lambda_slash_no_default | lambda_slash_with_default +// _tmp_185: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_184_rule(Parser *p) +_tmp_185_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36336,18 +36524,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); asdl_arg_seq* lambda_slash_no_default_var; if ( (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -36355,18 +36543,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -36375,9 +36563,9 @@ _tmp_184_rule(Parser *p) return _res; } -// _loop0_185: lambda_param_maybe_default +// _loop0_186: lambda_param_maybe_default static asdl_seq * -_loop0_185_rule(Parser *p) +_loop0_186_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36402,7 +36590,7 @@ _loop0_185_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_186[%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 @@ -36425,7 +36613,7 @@ _loop0_185_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_186[%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); @@ -36442,9 +36630,9 @@ _loop0_185_rule(Parser *p) return _seq; } -// _loop0_186: lambda_param_no_default +// _loop0_187: lambda_param_no_default static asdl_seq * -_loop0_186_rule(Parser *p) +_loop0_187_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36469,7 +36657,7 @@ _loop0_186_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_187[%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 @@ -36492,7 +36680,7 @@ _loop0_186_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_186[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_187[%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); @@ -36509,9 +36697,9 @@ _loop0_186_rule(Parser *p) return _seq; } -// _loop0_187: lambda_param_no_default +// _loop0_188: lambda_param_no_default static asdl_seq * -_loop0_187_rule(Parser *p) +_loop0_188_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36536,7 +36724,7 @@ _loop0_187_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_188[%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 @@ -36559,7 +36747,7 @@ _loop0_187_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_188[%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); @@ -36576,9 +36764,9 @@ _loop0_187_rule(Parser *p) return _seq; } -// _loop0_189: ',' lambda_param +// _loop0_190: ',' lambda_param static asdl_seq * -_loop0_189_rule(Parser *p) +_loop0_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36603,7 +36791,7 @@ _loop0_189_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); Token * _literal; arg_ty elem; while ( @@ -36635,7 +36823,7 @@ _loop0_189_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36652,9 +36840,9 @@ _loop0_189_rule(Parser *p) return _seq; } -// _gather_188: lambda_param _loop0_189 +// _gather_189: lambda_param _loop0_190 static asdl_seq * -_gather_188_rule(Parser *p) +_gather_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36665,27 +36853,27 @@ _gather_188_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_189 + { // lambda_param _loop0_190 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_189")); + D(fprintf(stderr, "%*c> _gather_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_190")); arg_ty elem; asdl_seq * seq; if ( (elem = lambda_param_rule(p)) // lambda_param && - (seq = _loop0_189_rule(p)) // _loop0_189 + (seq = _loop0_190_rule(p)) // _loop0_190 ) { - D(fprintf(stderr, "%*c+ _gather_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_189")); + D(fprintf(stderr, "%*c+ _gather_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_190")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_188[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_189")); + D(fprintf(stderr, "%*c%s _gather_189[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_190")); } _res = NULL; done: @@ -36693,9 +36881,9 @@ _gather_188_rule(Parser *p) return _res; } -// _tmp_190: lambda_slash_no_default | lambda_slash_with_default +// _tmp_191: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_190_rule(Parser *p) +_tmp_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36711,18 +36899,18 @@ _tmp_190_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); asdl_arg_seq* lambda_slash_no_default_var; if ( (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -36730,18 +36918,18 @@ _tmp_190_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -36750,9 +36938,9 @@ _tmp_190_rule(Parser *p) return _res; } -// _loop0_191: lambda_param_maybe_default +// _loop0_192: lambda_param_maybe_default static asdl_seq * -_loop0_191_rule(Parser *p) +_loop0_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36777,7 +36965,7 @@ _loop0_191_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -36800,7 +36988,7 @@ _loop0_191_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36817,9 +37005,9 @@ _loop0_191_rule(Parser *p) return _seq; } -// _tmp_192: ',' | lambda_param_no_default +// _tmp_193: ',' | lambda_param_no_default static void * -_tmp_192_rule(Parser *p) +_tmp_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36835,18 +37023,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // lambda_param_no_default @@ -36854,18 +37042,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } _res = NULL; @@ -36874,9 +37062,9 @@ _tmp_192_rule(Parser *p) return _res; } -// _loop0_193: lambda_param_maybe_default +// _loop0_194: lambda_param_maybe_default static asdl_seq * -_loop0_193_rule(Parser *p) +_loop0_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36901,7 +37089,7 @@ _loop0_193_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_194[%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 @@ -36924,7 +37112,7 @@ _loop0_193_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_193[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_194[%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); @@ -36941,9 +37129,9 @@ _loop0_193_rule(Parser *p) return _seq; } -// _loop1_194: lambda_param_maybe_default +// _loop1_195: lambda_param_maybe_default static asdl_seq * -_loop1_194_rule(Parser *p) +_loop1_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -36968,7 +37156,7 @@ _loop1_194_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_195[%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 @@ -36991,7 +37179,7 @@ _loop1_194_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -37013,9 +37201,9 @@ _loop1_194_rule(Parser *p) return _seq; } -// _loop1_195: lambda_param_with_default +// _loop1_196: lambda_param_with_default static asdl_seq * -_loop1_195_rule(Parser *p) +_loop1_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37040,7 +37228,7 @@ _loop1_195_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_196[%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 @@ -37063,7 +37251,7 @@ _loop1_195_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_195[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_196[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -37085,9 +37273,9 @@ _loop1_195_rule(Parser *p) return _seq; } -// _tmp_196: ':' | ',' (':' | '**') +// _tmp_197: ':' | ',' (':' | '**') static void * -_tmp_196_rule(Parser *p) +_tmp_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37103,18 +37291,18 @@ _tmp_196_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') @@ -37122,21 +37310,21 @@ _tmp_196_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_265_var; + void *_tmp_267_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_265_var = _tmp_265_rule(p)) // ':' | '**' + (_tmp_267_var = _tmp_267_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_265_var); + D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_267_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; @@ -37145,9 +37333,9 @@ _tmp_196_rule(Parser *p) return _res; } -// _tmp_197: lambda_param_no_default | ',' +// _tmp_198: lambda_param_no_default | ',' static void * -_tmp_197_rule(Parser *p) +_tmp_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37163,18 +37351,18 @@ _tmp_197_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -37182,18 +37370,18 @@ _tmp_197_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -37202,9 +37390,9 @@ _tmp_197_rule(Parser *p) return _res; } -// _loop0_198: lambda_param_maybe_default +// _loop0_199: lambda_param_maybe_default static asdl_seq * -_loop0_198_rule(Parser *p) +_loop0_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37229,7 +37417,7 @@ _loop0_198_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_199[%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 @@ -37252,7 +37440,7 @@ _loop0_198_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37269,9 +37457,9 @@ _loop0_198_rule(Parser *p) return _seq; } -// _tmp_199: lambda_param_no_default | ',' +// _tmp_200: lambda_param_no_default | ',' static void * -_tmp_199_rule(Parser *p) +_tmp_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37287,18 +37475,18 @@ _tmp_199_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -37306,18 +37494,18 @@ _tmp_199_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -37326,9 +37514,9 @@ _tmp_199_rule(Parser *p) return _res; } -// _tmp_200: '*' | '**' | '/' +// _tmp_201: '*' | '**' | '/' static void * -_tmp_200_rule(Parser *p) +_tmp_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37344,18 +37532,18 @@ _tmp_200_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -37363,18 +37551,18 @@ _tmp_200_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -37382,18 +37570,18 @@ _tmp_200_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -37402,9 +37590,9 @@ _tmp_200_rule(Parser *p) return _res; } -// _tmp_201: ',' | ')' | ':' +// _tmp_202: ',' | ')' | ':' static void * -_tmp_201_rule(Parser *p) +_tmp_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37420,18 +37608,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -37439,18 +37627,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -37458,18 +37646,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -37478,9 +37666,9 @@ _tmp_201_rule(Parser *p) return _res; } -// _loop0_203: ',' dotted_name +// _loop0_204: ',' dotted_name static asdl_seq * -_loop0_203_rule(Parser *p) +_loop0_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37505,7 +37693,7 @@ _loop0_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); + D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); Token * _literal; expr_ty elem; while ( @@ -37537,7 +37725,7 @@ _loop0_203_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37554,9 +37742,9 @@ _loop0_203_rule(Parser *p) return _seq; } -// _gather_202: dotted_name _loop0_203 +// _gather_203: dotted_name _loop0_204 static asdl_seq * -_gather_202_rule(Parser *p) +_gather_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37567,27 +37755,27 @@ _gather_202_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // dotted_name _loop0_203 + { // dotted_name _loop0_204 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_203")); + D(fprintf(stderr, "%*c> _gather_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_204")); expr_ty elem; asdl_seq * seq; if ( (elem = dotted_name_rule(p)) // dotted_name && - (seq = _loop0_203_rule(p)) // _loop0_203 + (seq = _loop0_204_rule(p)) // _loop0_204 ) { - D(fprintf(stderr, "%*c+ _gather_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_203")); + D(fprintf(stderr, "%*c+ _gather_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_204")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_202[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_203")); + D(fprintf(stderr, "%*c%s _gather_203[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_204")); } _res = NULL; done: @@ -37595,9 +37783,9 @@ _gather_202_rule(Parser *p) return _res; } -// _loop0_205: ',' (expression ['as' star_target]) +// _loop0_206: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_205_rule(Parser *p) +_loop0_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37622,13 +37810,13 @@ _loop0_205_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_266_rule(p)) // expression ['as' star_target] + (elem = _tmp_268_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -37654,7 +37842,7 @@ _loop0_205_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_205[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_206[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37671,9 +37859,9 @@ _loop0_205_rule(Parser *p) return _seq; } -// _gather_204: (expression ['as' star_target]) _loop0_205 +// _gather_205: (expression ['as' star_target]) _loop0_206 static asdl_seq * -_gather_204_rule(Parser *p) +_gather_205_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37684,27 +37872,27 @@ _gather_204_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_205 + { // (expression ['as' star_target]) _loop0_206 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); + D(fprintf(stderr, "%*c> _gather_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_206")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_266_rule(p)) // expression ['as' star_target] + (elem = _tmp_268_rule(p)) // expression ['as' star_target] && - (seq = _loop0_205_rule(p)) // _loop0_205 + (seq = _loop0_206_rule(p)) // _loop0_206 ) { - D(fprintf(stderr, "%*c+ _gather_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); + D(fprintf(stderr, "%*c+ _gather_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_206")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_204[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); + D(fprintf(stderr, "%*c%s _gather_205[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_206")); } _res = NULL; done: @@ -37712,9 +37900,9 @@ _gather_204_rule(Parser *p) return _res; } -// _loop0_207: ',' (expressions ['as' star_target]) +// _loop0_208: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_207_rule(Parser *p) +_loop0_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37739,13 +37927,13 @@ _loop0_207_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_267_rule(p)) // expressions ['as' star_target] + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -37771,7 +37959,7 @@ _loop0_207_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_208[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37788,9 +37976,9 @@ _loop0_207_rule(Parser *p) return _seq; } -// _gather_206: (expressions ['as' star_target]) _loop0_207 +// _gather_207: (expressions ['as' star_target]) _loop0_208 static asdl_seq * -_gather_206_rule(Parser *p) +_gather_207_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37801,27 +37989,27 @@ _gather_206_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_207 + { // (expressions ['as' star_target]) _loop0_208 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); + D(fprintf(stderr, "%*c> _gather_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_208")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_267_rule(p)) // expressions ['as' star_target] + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_207_rule(p)) // _loop0_207 + (seq = _loop0_208_rule(p)) // _loop0_208 ) { - D(fprintf(stderr, "%*c+ _gather_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); + D(fprintf(stderr, "%*c+ _gather_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_208")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_206[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); + D(fprintf(stderr, "%*c%s _gather_207[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_208")); } _res = NULL; done: @@ -37829,9 +38017,9 @@ _gather_206_rule(Parser *p) return _res; } -// _loop0_209: ',' (expression ['as' star_target]) +// _loop0_210: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_209_rule(Parser *p) +_loop0_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37856,13 +38044,13 @@ _loop0_209_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_268_rule(p)) // expression ['as' star_target] + (elem = _tmp_270_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -37888,7 +38076,7 @@ _loop0_209_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_209[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_210[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -37905,9 +38093,9 @@ _loop0_209_rule(Parser *p) return _seq; } -// _gather_208: (expression ['as' star_target]) _loop0_209 +// _gather_209: (expression ['as' star_target]) _loop0_210 static asdl_seq * -_gather_208_rule(Parser *p) +_gather_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37918,27 +38106,27 @@ _gather_208_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_209 + { // (expression ['as' star_target]) _loop0_210 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); + D(fprintf(stderr, "%*c> _gather_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_210")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_268_rule(p)) // expression ['as' star_target] + (elem = _tmp_270_rule(p)) // expression ['as' star_target] && - (seq = _loop0_209_rule(p)) // _loop0_209 + (seq = _loop0_210_rule(p)) // _loop0_210 ) { - D(fprintf(stderr, "%*c+ _gather_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); + D(fprintf(stderr, "%*c+ _gather_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_210")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_208[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); + D(fprintf(stderr, "%*c%s _gather_209[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_210")); } _res = NULL; done: @@ -37946,9 +38134,9 @@ _gather_208_rule(Parser *p) return _res; } -// _loop0_211: ',' (expressions ['as' star_target]) +// _loop0_212: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_211_rule(Parser *p) +_loop0_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -37973,13 +38161,13 @@ _loop0_211_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_269_rule(p)) // expressions ['as' star_target] + (elem = _tmp_271_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -38005,7 +38193,7 @@ _loop0_211_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_211[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_212[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38022,9 +38210,9 @@ _loop0_211_rule(Parser *p) return _seq; } -// _gather_210: (expressions ['as' star_target]) _loop0_211 +// _gather_211: (expressions ['as' star_target]) _loop0_212 static asdl_seq * -_gather_210_rule(Parser *p) +_gather_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38035,27 +38223,27 @@ _gather_210_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_211 + { // (expressions ['as' star_target]) _loop0_212 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); + D(fprintf(stderr, "%*c> _gather_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_212")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_269_rule(p)) // expressions ['as' star_target] + (elem = _tmp_271_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_211_rule(p)) // _loop0_211 + (seq = _loop0_212_rule(p)) // _loop0_212 ) { - D(fprintf(stderr, "%*c+ _gather_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); + D(fprintf(stderr, "%*c+ _gather_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_212")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_210[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); + D(fprintf(stderr, "%*c%s _gather_211[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_212")); } _res = NULL; done: @@ -38063,9 +38251,9 @@ _gather_210_rule(Parser *p) return _res; } -// _tmp_212: 'except' | 'finally' +// _tmp_213: 'except' | 'finally' static void * -_tmp_212_rule(Parser *p) +_tmp_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38081,18 +38269,18 @@ _tmp_212_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='except' + (_keyword = _PyPegen_expect_token(p, 653)) // token='except' ) { - D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } { // 'finally' @@ -38100,18 +38288,18 @@ _tmp_212_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 649)) // token='finally' ) { - D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } _res = NULL; @@ -38120,9 +38308,9 @@ _tmp_212_rule(Parser *p) return _res; } -// _loop0_213: block +// _loop0_214: block static asdl_seq * -_loop0_213_rule(Parser *p) +_loop0_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38147,7 +38335,7 @@ _loop0_213_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -38170,7 +38358,7 @@ _loop0_213_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_213[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_214[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38187,9 +38375,9 @@ _loop0_213_rule(Parser *p) return _seq; } -// _loop1_214: except_block +// _loop1_215: except_block static asdl_seq * -_loop1_214_rule(Parser *p) +_loop1_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38214,7 +38402,7 @@ _loop1_214_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_215[%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 @@ -38237,7 +38425,7 @@ _loop1_214_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_214[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_215[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -38259,9 +38447,9 @@ _loop1_214_rule(Parser *p) return _seq; } -// _tmp_215: 'as' NAME +// _tmp_216: 'as' NAME static void * -_tmp_215_rule(Parser *p) +_tmp_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38277,21 +38465,21 @@ _tmp_215_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38300,9 +38488,9 @@ _tmp_215_rule(Parser *p) return _res; } -// _loop0_216: block +// _loop0_217: block static asdl_seq * -_loop0_216_rule(Parser *p) +_loop0_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38327,7 +38515,7 @@ _loop0_216_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -38350,7 +38538,7 @@ _loop0_216_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_216[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38367,9 +38555,9 @@ _loop0_216_rule(Parser *p) return _seq; } -// _loop1_217: except_star_block +// _loop1_218: except_star_block static asdl_seq * -_loop1_217_rule(Parser *p) +_loop1_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38394,7 +38582,7 @@ _loop1_217_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_218[%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 @@ -38417,7 +38605,7 @@ _loop1_217_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_217[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -38439,9 +38627,9 @@ _loop1_217_rule(Parser *p) return _seq; } -// _tmp_218: expression ['as' NAME] +// _tmp_219: expression ['as' NAME] static void * -_tmp_218_rule(Parser *p) +_tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38457,22 +38645,22 @@ _tmp_218_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_270_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_272_rule(p), !p->error_indicator) // ['as' NAME] ) { - D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]")); } _res = NULL; @@ -38481,9 +38669,9 @@ _tmp_218_rule(Parser *p) return _res; } -// _tmp_219: 'as' NAME +// _tmp_220: 'as' NAME static void * -_tmp_219_rule(Parser *p) +_tmp_220_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38499,21 +38687,21 @@ _tmp_219_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_220[%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_219[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38522,9 +38710,9 @@ _tmp_219_rule(Parser *p) return _res; } -// _tmp_220: 'as' NAME +// _tmp_221: 'as' NAME static void * -_tmp_220_rule(Parser *p) +_tmp_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38540,21 +38728,21 @@ _tmp_220_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_221[%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_220[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38563,9 +38751,9 @@ _tmp_220_rule(Parser *p) return _res; } -// _tmp_221: NEWLINE | ':' +// _tmp_222: NEWLINE | ':' static void * -_tmp_221_rule(Parser *p) +_tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38581,18 +38769,18 @@ _tmp_221_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_222[%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_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_222[%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_221[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } { // ':' @@ -38600,18 +38788,18 @@ _tmp_221_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -38620,9 +38808,9 @@ _tmp_221_rule(Parser *p) return _res; } -// _tmp_222: 'as' NAME +// _tmp_223: 'as' NAME static void * -_tmp_222_rule(Parser *p) +_tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38638,21 +38826,21 @@ _tmp_222_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_223[%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_222[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38661,9 +38849,9 @@ _tmp_222_rule(Parser *p) return _res; } -// _tmp_223: 'as' NAME +// _tmp_224: 'as' NAME static void * -_tmp_223_rule(Parser *p) +_tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38679,21 +38867,21 @@ _tmp_223_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_224[%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_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38702,9 +38890,9 @@ _tmp_223_rule(Parser *p) return _res; } -// _tmp_224: positional_patterns ',' +// _tmp_225: positional_patterns ',' static void * -_tmp_224_rule(Parser *p) +_tmp_225_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38720,7 +38908,7 @@ _tmp_224_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; asdl_pattern_seq* positional_patterns_var; if ( @@ -38729,12 +38917,12 @@ _tmp_224_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); } _res = NULL; @@ -38743,9 +38931,9 @@ _tmp_224_rule(Parser *p) return _res; } -// _tmp_225: '->' expression +// _tmp_226: '->' expression static void * -_tmp_225_rule(Parser *p) +_tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38761,7 +38949,7 @@ _tmp_225_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty expression_var; if ( @@ -38770,12 +38958,12 @@ _tmp_225_rule(Parser *p) (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = _PyPegen_dummy_name(p, _literal, expression_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -38784,9 +38972,9 @@ _tmp_225_rule(Parser *p) return _res; } -// _tmp_226: '(' arguments? ')' +// _tmp_227: '(' arguments? ')' static void * -_tmp_226_rule(Parser *p) +_tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38802,7 +38990,7 @@ _tmp_226_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -38815,12 +39003,12 @@ _tmp_226_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -38829,9 +39017,9 @@ _tmp_226_rule(Parser *p) return _res; } -// _tmp_227: '(' arguments? ')' +// _tmp_228: '(' arguments? ')' static void * -_tmp_227_rule(Parser *p) +_tmp_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38847,7 +39035,7 @@ _tmp_227_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -38860,12 +39048,12 @@ _tmp_227_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -38874,9 +39062,9 @@ _tmp_227_rule(Parser *p) return _res; } -// _loop0_229: ',' double_starred_kvpair +// _loop0_230: ',' double_starred_kvpair static asdl_seq * -_loop0_229_rule(Parser *p) +_loop0_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38901,7 +39089,7 @@ _loop0_229_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -38933,7 +39121,7 @@ _loop0_229_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_229[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -38950,9 +39138,9 @@ _loop0_229_rule(Parser *p) return _seq; } -// _gather_228: double_starred_kvpair _loop0_229 +// _gather_229: double_starred_kvpair _loop0_230 static asdl_seq * -_gather_228_rule(Parser *p) +_gather_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -38963,84 +39151,27 @@ _gather_228_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_229 + { // double_starred_kvpair _loop0_230 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_229")); + D(fprintf(stderr, "%*c> _gather_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_230")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_229_rule(p)) // _loop0_229 + (seq = _loop0_230_rule(p)) // _loop0_230 ) { - D(fprintf(stderr, "%*c+ _gather_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_229")); + D(fprintf(stderr, "%*c+ _gather_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_230")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_228[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_229")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_230: '}' | ',' -static void * -_tmp_230_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; - { // '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); - } - { // ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + D(fprintf(stderr, "%*c%s _gather_229[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_230")); } _res = NULL; done: @@ -39105,7 +39236,7 @@ _tmp_231_rule(Parser *p) return _res; } -// _tmp_232: yield_expr | star_expressions +// _tmp_232: '}' | ',' static void * _tmp_232_rule(Parser *p) { @@ -39118,43 +39249,43 @@ _tmp_232_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // yield_expr + { // '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty yield_expr_var; + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr + (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - _res = yield_expr_var; + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } - { // star_expressions + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; done: @@ -39219,9 +39350,66 @@ _tmp_233_rule(Parser *p) return _res; } -// _tmp_234: '=' | '!' | ':' | '}' +// _tmp_234: yield_expr | star_expressions static void * _tmp_234_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; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_234[%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_234[%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_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_234[%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_234[%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_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_235: '=' | '!' | ':' | '}' +static void * +_tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39237,18 +39425,18 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // '!' @@ -39256,18 +39444,18 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } { // ':' @@ -39275,18 +39463,18 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39294,18 +39482,18 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39314,9 +39502,9 @@ _tmp_234_rule(Parser *p) return _res; } -// _tmp_235: yield_expr | star_expressions +// _tmp_236: yield_expr | star_expressions static void * -_tmp_235_rule(Parser *p) +_tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39332,18 +39520,18 @@ _tmp_235_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_236[%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_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_236[%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_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39351,18 +39539,18 @@ _tmp_235_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_236[%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_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_236[%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_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39371,9 +39559,9 @@ _tmp_235_rule(Parser *p) return _res; } -// _tmp_236: '!' | ':' | '}' +// _tmp_237: '!' | ':' | '}' static void * -_tmp_236_rule(Parser *p) +_tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39389,18 +39577,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } { // ':' @@ -39408,18 +39596,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39427,18 +39615,18 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39447,9 +39635,9 @@ _tmp_236_rule(Parser *p) return _res; } -// _tmp_237: yield_expr | star_expressions +// _tmp_238: yield_expr | star_expressions static void * -_tmp_237_rule(Parser *p) +_tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39465,18 +39653,18 @@ _tmp_237_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_238[%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_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_238[%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_237[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39484,18 +39672,18 @@ _tmp_237_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_238[%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_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_238[%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_237[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39504,9 +39692,9 @@ _tmp_237_rule(Parser *p) return _res; } -// _tmp_238: yield_expr | star_expressions +// _tmp_239: yield_expr | star_expressions static void * -_tmp_238_rule(Parser *p) +_tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39522,18 +39710,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_239[%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_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_239[%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_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39541,18 +39729,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_239[%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_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_239[%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_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39561,9 +39749,9 @@ _tmp_238_rule(Parser *p) return _res; } -// _tmp_239: '!' NAME +// _tmp_240: '!' NAME static void * -_tmp_239_rule(Parser *p) +_tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39579,7 +39767,7 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -39588,12 +39776,12 @@ _tmp_239_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; @@ -39602,9 +39790,9 @@ _tmp_239_rule(Parser *p) return _res; } -// _tmp_240: ':' | '}' +// _tmp_241: ':' | '}' static void * -_tmp_240_rule(Parser *p) +_tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39620,18 +39808,18 @@ _tmp_240_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39639,18 +39827,18 @@ _tmp_240_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39659,9 +39847,9 @@ _tmp_240_rule(Parser *p) return _res; } -// _tmp_241: yield_expr | star_expressions +// _tmp_242: yield_expr | star_expressions static void * -_tmp_241_rule(Parser *p) +_tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39677,18 +39865,18 @@ _tmp_241_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_242[%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_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_242[%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_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39696,18 +39884,18 @@ _tmp_241_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_242[%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_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_242[%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_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39716,9 +39904,9 @@ _tmp_241_rule(Parser *p) return _res; } -// _tmp_242: '!' NAME +// _tmp_243: '!' NAME static void * -_tmp_242_rule(Parser *p) +_tmp_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39734,7 +39922,7 @@ _tmp_242_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -39743,12 +39931,12 @@ _tmp_242_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; @@ -39757,9 +39945,9 @@ _tmp_242_rule(Parser *p) return _res; } -// _loop0_243: fstring_format_spec +// _loop0_244: fstring_format_spec static asdl_seq * -_loop0_243_rule(Parser *p) +_loop0_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39784,7 +39972,7 @@ _loop0_243_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); + D(fprintf(stderr, "%*c> _loop0_244[%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 @@ -39807,7 +39995,7 @@ _loop0_243_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_243[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_244[%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); @@ -39824,9 +40012,9 @@ _loop0_243_rule(Parser *p) return _seq; } -// _tmp_244: yield_expr | star_expressions +// _tmp_245: yield_expr | star_expressions static void * -_tmp_244_rule(Parser *p) +_tmp_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39842,18 +40030,18 @@ _tmp_244_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_245[%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_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_245[%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_244[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -39861,18 +40049,18 @@ _tmp_244_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_245[%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_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_245[%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_244[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -39881,9 +40069,9 @@ _tmp_244_rule(Parser *p) return _res; } -// _tmp_245: '!' NAME +// _tmp_246: '!' NAME static void * -_tmp_245_rule(Parser *p) +_tmp_246_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39899,7 +40087,7 @@ _tmp_245_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; expr_ty name_var; if ( @@ -39908,12 +40096,12 @@ _tmp_245_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; @@ -39922,9 +40110,9 @@ _tmp_245_rule(Parser *p) return _res; } -// _tmp_246: ':' | '}' +// _tmp_247: ':' | '}' static void * -_tmp_246_rule(Parser *p) +_tmp_247_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39940,18 +40128,18 @@ _tmp_246_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '}' @@ -39959,18 +40147,18 @@ _tmp_246_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; @@ -39979,9 +40167,9 @@ _tmp_246_rule(Parser *p) return _res; } -// _tmp_247: star_targets '=' +// _tmp_248: star_targets '=' static void * -_tmp_247_rule(Parser *p) +_tmp_248_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -39997,7 +40185,7 @@ _tmp_247_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -40006,7 +40194,7 @@ _tmp_247_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40016,7 +40204,7 @@ _tmp_247_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -40025,9 +40213,9 @@ _tmp_247_rule(Parser *p) return _res; } -// _tmp_248: '.' | '...' +// _tmp_249: '.' | '...' static void * -_tmp_248_rule(Parser *p) +_tmp_249_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40043,18 +40231,18 @@ _tmp_248_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -40062,18 +40250,18 @@ _tmp_248_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -40082,9 +40270,9 @@ _tmp_248_rule(Parser *p) return _res; } -// _tmp_249: '.' | '...' +// _tmp_250: '.' | '...' static void * -_tmp_249_rule(Parser *p) +_tmp_250_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40100,18 +40288,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -40119,18 +40307,18 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -40139,9 +40327,9 @@ _tmp_249_rule(Parser *p) return _res; } -// _tmp_250: '@' named_expression NEWLINE +// _tmp_251: '@' named_expression NEWLINE static void * -_tmp_250_rule(Parser *p) +_tmp_251_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40157,7 +40345,7 @@ _tmp_250_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -40169,7 +40357,7 @@ _tmp_250_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40179,7 +40367,7 @@ _tmp_250_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -40188,9 +40376,9 @@ _tmp_250_rule(Parser *p) return _res; } -// _tmp_251: ',' expression +// _tmp_252: ',' expression static void * -_tmp_251_rule(Parser *p) +_tmp_252_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40206,7 +40394,7 @@ _tmp_251_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -40215,7 +40403,7 @@ _tmp_251_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40225,7 +40413,7 @@ _tmp_251_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -40234,9 +40422,9 @@ _tmp_251_rule(Parser *p) return _res; } -// _tmp_252: ',' star_expression +// _tmp_253: ',' star_expression static void * -_tmp_252_rule(Parser *p) +_tmp_253_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40252,7 +40440,7 @@ _tmp_252_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -40261,7 +40449,7 @@ _tmp_252_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40271,7 +40459,7 @@ _tmp_252_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -40280,9 +40468,9 @@ _tmp_252_rule(Parser *p) return _res; } -// _tmp_253: 'or' conjunction +// _tmp_254: 'or' conjunction static void * -_tmp_253_rule(Parser *p) +_tmp_254_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40298,7 +40486,7 @@ _tmp_253_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -40307,7 +40495,7 @@ _tmp_253_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40317,7 +40505,7 @@ _tmp_253_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -40326,9 +40514,9 @@ _tmp_253_rule(Parser *p) return _res; } -// _tmp_254: 'and' inversion +// _tmp_255: 'and' inversion static void * -_tmp_254_rule(Parser *p) +_tmp_255_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40344,7 +40532,7 @@ _tmp_254_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -40353,7 +40541,7 @@ _tmp_254_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40363,7 +40551,7 @@ _tmp_254_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -40372,9 +40560,9 @@ _tmp_254_rule(Parser *p) return _res; } -// _tmp_255: slice | starred_expression +// _tmp_256: slice | starred_expression static void * -_tmp_255_rule(Parser *p) +_tmp_256_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40390,18 +40578,18 @@ _tmp_255_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); expr_ty slice_var; if ( (slice_var = slice_rule(p)) // slice ) { - D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); _res = slice_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice")); } { // starred_expression @@ -40409,18 +40597,18 @@ _tmp_255_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_256[%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_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_256[%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_255[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } _res = NULL; @@ -40429,9 +40617,9 @@ _tmp_255_rule(Parser *p) return _res; } -// _tmp_256: fstring | string +// _tmp_257: fstring | string static void * -_tmp_256_rule(Parser *p) +_tmp_257_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40447,18 +40635,18 @@ _tmp_256_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); + D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); expr_ty fstring_var; if ( (fstring_var = fstring_rule(p)) // fstring ) { - D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); + D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); _res = fstring_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring")); } { // string @@ -40466,18 +40654,18 @@ _tmp_256_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); + D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); expr_ty string_var; if ( (string_var = string_rule(p)) // string ) { - D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string")); + D(fprintf(stderr, "%*c+ _tmp_257[%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_256[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "string")); } _res = NULL; @@ -40486,9 +40674,9 @@ _tmp_256_rule(Parser *p) return _res; } -// _tmp_257: 'if' disjunction +// _tmp_258: 'if' disjunction static void * -_tmp_257_rule(Parser *p) +_tmp_258_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40504,16 +40692,16 @@ _tmp_257_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40523,7 +40711,7 @@ _tmp_257_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -40532,9 +40720,9 @@ _tmp_257_rule(Parser *p) return _res; } -// _tmp_258: 'if' disjunction +// _tmp_259: 'if' disjunction static void * -_tmp_258_rule(Parser *p) +_tmp_259_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40550,16 +40738,16 @@ _tmp_258_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 656)) // token='if' + (_keyword = _PyPegen_expect_token(p, 658)) // token='if' && (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40569,7 +40757,7 @@ _tmp_258_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -40578,9 +40766,9 @@ _tmp_258_rule(Parser *p) return _res; } -// _tmp_259: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_260: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_259_rule(Parser *p) +_tmp_260_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40596,18 +40784,18 @@ _tmp_259_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_260[%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_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_260[%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_259[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -40615,20 +40803,20 @@ _tmp_259_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_271_var; + D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_273_var; if ( - (_tmp_271_var = _tmp_271_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_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_271_var; + D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_273_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -40637,9 +40825,9 @@ _tmp_259_rule(Parser *p) return _res; } -// _tmp_260: ',' star_target +// _tmp_261: ',' star_target static void * -_tmp_260_rule(Parser *p) +_tmp_261_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40655,7 +40843,7 @@ _tmp_260_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -40664,7 +40852,7 @@ _tmp_260_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40674,7 +40862,7 @@ _tmp_260_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -40683,9 +40871,9 @@ _tmp_260_rule(Parser *p) return _res; } -// _tmp_261: ',' star_target +// _tmp_262: ',' star_target static void * -_tmp_261_rule(Parser *p) +_tmp_262_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40701,7 +40889,7 @@ _tmp_261_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -40710,7 +40898,7 @@ _tmp_261_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -40720,7 +40908,7 @@ _tmp_261_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -40729,9 +40917,54 @@ _tmp_261_rule(Parser *p) return _res; } -// _tmp_262: star_targets '=' +// _tmp_263: +// | ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs static void * -_tmp_262_rule(Parser *p) +_tmp_263_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 | (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, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + asdl_seq * _gather_274_var; + Token * _literal; + asdl_seq* kwargs_var; + if ( + (_gather_274_var = _gather_274_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + && + (_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, "','.(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, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ ',' kwargs")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_264: star_targets '=' +static void * +_tmp_264_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40747,7 +40980,7 @@ _tmp_262_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -40756,12 +40989,12 @@ _tmp_262_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_264[%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_262[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -40770,9 +41003,9 @@ _tmp_262_rule(Parser *p) return _res; } -// _tmp_263: star_targets '=' +// _tmp_265: star_targets '=' static void * -_tmp_263_rule(Parser *p) +_tmp_265_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40788,7 +41021,7 @@ _tmp_263_rule(Parser *p) 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_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -40797,12 +41030,12 @@ _tmp_263_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + 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_263[%d-%d]: %s failed!\n", p->level, ' ', + 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; @@ -40811,9 +41044,9 @@ _tmp_263_rule(Parser *p) return _res; } -// _tmp_264: ')' | '**' +// _tmp_266: ')' | '**' static void * -_tmp_264_rule(Parser *p) +_tmp_266_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40829,18 +41062,18 @@ _tmp_264_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_264[%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_264[%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_264[%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, "')'")); } { // '**' @@ -40848,18 +41081,18 @@ _tmp_264_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_264[%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_264[%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_264[%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; @@ -40868,9 +41101,9 @@ _tmp_264_rule(Parser *p) return _res; } -// _tmp_265: ':' | '**' +// _tmp_267: ':' | '**' static void * -_tmp_265_rule(Parser *p) +_tmp_267_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40886,18 +41119,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_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_265[%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_265[%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, "':'")); } { // '**' @@ -40905,18 +41138,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_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_265[%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_265[%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; @@ -40925,9 +41158,9 @@ _tmp_265_rule(Parser *p) return _res; } -// _tmp_266: expression ['as' star_target] +// _tmp_268: expression ['as' star_target] static void * -_tmp_266_rule(Parser *p) +_tmp_268_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40943,22 +41176,22 @@ _tmp_266_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_266[%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_272_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_266[%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_266[%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; @@ -40967,9 +41200,9 @@ _tmp_266_rule(Parser *p) return _res; } -// _tmp_267: expressions ['as' star_target] +// _tmp_269: expressions ['as' star_target] static void * -_tmp_267_rule(Parser *p) +_tmp_269_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -40985,22 +41218,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, "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_273_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_267[%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_267[%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; @@ -41009,9 +41242,9 @@ _tmp_267_rule(Parser *p) return _res; } -// _tmp_268: expression ['as' star_target] +// _tmp_270: expression ['as' star_target] static void * -_tmp_268_rule(Parser *p) +_tmp_270_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41027,22 +41260,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, "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_274_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_268[%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_268[%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; @@ -41051,9 +41284,9 @@ _tmp_268_rule(Parser *p) return _res; } -// _tmp_269: expressions ['as' star_target] +// _tmp_271: expressions ['as' star_target] static void * -_tmp_269_rule(Parser *p) +_tmp_271_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41069,22 +41302,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, "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_275_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_269[%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_269[%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; @@ -41093,9 +41326,9 @@ _tmp_269_rule(Parser *p) return _res; } -// _tmp_270: 'as' NAME +// _tmp_272: 'as' NAME static void * -_tmp_270_rule(Parser *p) +_tmp_272_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41111,21 +41344,21 @@ _tmp_270_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_270[%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, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_270[%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_270[%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; @@ -41134,9 +41367,9 @@ _tmp_270_rule(Parser *p) return _res; } -// _tmp_271: assignment_expression | expression !':=' +// _tmp_273: assignment_expression | expression !':=' static void * -_tmp_271_rule(Parser *p) +_tmp_273_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41152,18 +41385,18 @@ _tmp_271_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_271[%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_271[%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_271[%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 !':=' @@ -41171,7 +41404,7 @@ _tmp_271_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_271[%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 @@ -41179,12 +41412,12 @@ _tmp_271_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_271[%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_271[%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; @@ -41193,9 +41426,127 @@ _tmp_271_rule(Parser *p) return _res; } -// _tmp_272: 'as' star_target +// _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_272_rule(Parser *p) +_tmp_276_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41211,21 +41562,21 @@ _tmp_272_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_272[%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, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_272[%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_272[%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; @@ -41234,9 +41585,9 @@ _tmp_272_rule(Parser *p) return _res; } -// _tmp_273: 'as' star_target +// _tmp_277: 'as' star_target static void * -_tmp_273_rule(Parser *p) +_tmp_277_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41252,21 +41603,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_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, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // 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_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_273[%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; @@ -41275,9 +41626,9 @@ _tmp_273_rule(Parser *p) return _res; } -// _tmp_274: 'as' star_target +// _tmp_278: 'as' star_target static void * -_tmp_274_rule(Parser *p) +_tmp_278_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41293,21 +41644,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_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, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // 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_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_274[%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; @@ -41316,9 +41667,9 @@ _tmp_274_rule(Parser *p) return _res; } -// _tmp_275: 'as' star_target +// _tmp_279: 'as' star_target static void * -_tmp_275_rule(Parser *p) +_tmp_279_rule(Parser *p) { if (p->level++ == MAXSTACK) { _Pypegen_stack_overflow(p); @@ -41334,21 +41685,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_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, 654)) // token='as' + (_keyword = _PyPegen_expect_token(p, 656)) // 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_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_275[%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; @@ -41357,6 +41708,124 @@ _tmp_275_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) { 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 bfade3446a57f7..7766253a76066f 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 @@ -18,12 +19,8 @@ _PyPegen_interactive_exit(Parser *p) } Py_ssize_t -_PyPegen_byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) +_PyPegen_byte_offset_to_character_offset_raw(const char* str, Py_ssize_t col_offset) { - const char *str = PyUnicode_AsUTF8(line); - if (!str) { - return -1; - } Py_ssize_t len = strlen(str); if (col_offset > len + 1) { col_offset = len + 1; @@ -38,6 +35,16 @@ _PyPegen_byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) return size; } +Py_ssize_t +_PyPegen_byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) +{ + const char *str = PyUnicode_AsUTF8(line); + if (!str) { + return -1; + } + return _PyPegen_byte_offset_to_character_offset_raw(str, col_offset); +} + // Here, mark is the start of the node, while p->mark is the end. // If node==NULL, they should be the same. int @@ -877,7 +884,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) { @@ -907,6 +915,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 266d5219d45a9d..57b45a54c36c57 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -149,6 +149,7 @@ expr_ty _PyPegen_name_token(Parser *p); expr_ty _PyPegen_number_token(Parser *p); void *_PyPegen_string_token(Parser *p); Py_ssize_t _PyPegen_byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset); +Py_ssize_t _PyPegen_byte_offset_to_character_offset_raw(const char*, Py_ssize_t col_offset); // Error handling functions and APIs typedef enum { @@ -350,7 +351,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 b11b0442fe96ff..8a02aab1f4e504 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 @@ -67,6 +68,7 @@ _Pypegen_tokenizer_error(Parser *p) const char *msg = NULL; PyObject* errtype = PyExc_SyntaxError; Py_ssize_t col_offset = -1; + p->error_indicator = 1; switch (p->tok->done) { case E_TOKEN: msg = "invalid token"; @@ -102,6 +104,10 @@ _Pypegen_tokenizer_error(Parser *p) msg = "unexpected character after line continuation character"; break; } + case E_COLUMNOVERFLOW: + PyErr_SetString(PyExc_OverflowError, + "Parser column offset overflow - source line is too big"); + return -1; default: msg = "unknown parsing error"; } @@ -213,6 +219,10 @@ _PyPegen_tokenize_full_source_to_check_for_errors(Parser *p) { void * _PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *errmsg, ...) { + // Bail out if we already have an error set. + if (p->error_indicator && PyErr_Occurred()) { + return NULL; + } if (p->fill == 0) { va_list va; va_start(va, errmsg); @@ -272,6 +282,10 @@ get_error_line_from_tokenizer_buffers(Parser *p, Py_ssize_t lineno) Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp; + if (buf_end < cur_line) { + buf_end = cur_line + strlen(cur_line); + } + for (int i = 0; i < relative_lineno - 1; i++) { char *new_line = strchr(cur_line, '\n'); // The assert is here for debug builds but the conditional that @@ -388,7 +402,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, void _Pypegen_set_syntax_error(Parser* p, Token* last_token) { - // Existing sintax error + // Existing syntax error if (PyErr_Occurred()) { // Prioritize tokenizer errors to custom syntax errors raised // on the second phase only if the errors come from the parser. diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 72898c38b79bde..bacfd815441110 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -4,7 +4,7 @@ #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,9 +13,15 @@ static int warn_invalid_escape_sequence(Parser *p, const char *first_invalid_escape, Token *t) { + if (p->call_invalid_rules) { + // Do not report warnings if we are in the second pass of the parser + // to avoid showing the warning twice. + return 0; + } 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/tokenizer.c b/Parser/tokenizer.c deleted file mode 100644 index 46b7159ff0516b..00000000000000 --- a/Parser/tokenizer.c +++ /dev/null @@ -1,2937 +0,0 @@ - -/* Tokenizer implementation */ - -#include "Python.h" -#include "pycore_call.h" // _PyObject_CallNoArgs() - -#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->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; -#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] = 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 = 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->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 (c < 128 && 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 (Py_ISDIGIT(c)); - if (c != '_') { - break; - } - c = tok_nextc(tok); - if (!Py_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); - - 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(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(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 (Py_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 (Py_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 (Py_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 (!Py_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 (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(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(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(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(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.h b/Parser/tokenizer.h deleted file mode 100644 index 11d69fc5b2e15c..00000000000000 --- a/Parser/tokenizer.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef Py_TOKENIZER_H -#define Py_TOKENIZER_H -#ifdef __cplusplus -extern "C" { -#endif - -#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 */ - -enum decoding_state { - STATE_INIT, - STATE_SEEK_CODING, - STATE_NORMAL -}; - -enum interactive_underflow_t { - /* Normal mode of operation: return a new token when asked in interactive mode */ - IUNDERFLOW_NORMAL, - /* Forcefully return ENDMARKER when asked for a new token in interactive mode. This - * can be used to prevent the tokenizer to prompt the user for new tokens */ - IUNDERFLOW_STOP, -}; - -struct token { - int level; - int lineno, col_offset, end_lineno, end_col_offset; - const char *start, *end; - PyObject *metadata; -}; - -enum tokenizer_mode_kind_t { - TOK_REGULAR_MODE, - TOK_FSTRING_MODE, -}; - -#define MAX_EXPR_NESTING 3 - -typedef struct _tokenizer_mode { - enum tokenizer_mode_kind_t kind; - - int curly_bracket_depth; - int curly_bracket_expr_start_depth; - - char f_string_quote; - int f_string_quote_size; - int f_string_raw; - const char* f_string_start; - const char* f_string_multi_line_start; - int f_string_line_start; - - Py_ssize_t f_string_start_offset; - Py_ssize_t f_string_multi_line_start_offset; - - Py_ssize_t last_expr_size; - Py_ssize_t last_expr_end; - char* last_expr_buffer; - int f_string_debug; -} tokenizer_mode; - -/* Tokenizer state */ -struct tok_state { - /* Input state; buf <= cur <= inp <= end */ - /* NB an entire line is held in the buffer */ - char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL or readline != NULL */ - char *cur; /* Next character in buffer */ - char *inp; /* End of data in buffer */ - int fp_interactive; /* If the file descriptor is interactive */ - char *interactive_src_start; /* The start of the source parsed so far in interactive mode */ - char *interactive_src_end; /* The end of the source parsed so far in interactive mode */ - const char *end; /* End of input buffer if buf != NULL */ - const char *start; /* Start of current token if not NULL */ - int done; /* E_OK normally, E_EOF at EOF, otherwise error code */ - /* NB If done != E_OK, cur must be == inp!!! */ - FILE *fp; /* Rest of input; NULL if tokenizing a string */ - int tabsize; /* Tab spacing */ - int indent; /* Current indentation index */ - int indstack[MAXINDENT]; /* Stack of indents */ - int atbol; /* Nonzero if at begin of new line */ - int pendin; /* Pending indents (if > 0) or dedents (if < 0) */ - const char *prompt, *nextprompt; /* For interactive prompting */ - int lineno; /* Current line number */ - int first_lineno; /* First line of a single line or multi line string - expression (cf. issue 16806) */ - int starting_col_offset; /* The column offset at the beginning of a token */ - int col_offset; /* Current col offset */ - int level; /* () [] {} Parentheses nesting level */ - /* Used to allow free continuations inside them */ - char parenstack[MAXLEVEL]; - int parenlinenostack[MAXLEVEL]; - int parencolstack[MAXLEVEL]; - PyObject *filename; - /* Stuff for checking on different tab sizes */ - int altindstack[MAXINDENT]; /* Stack of alternate indents */ - /* Stuff for PEP 0263 */ - enum decoding_state decoding_state; - int decoding_erred; /* whether erred in decoding */ - char *encoding; /* Source encoding. */ - int cont_line; /* whether we are in a continuation line. */ - const char* line_start; /* pointer to start of current line */ - const char* multi_line_start; /* pointer to start of first line of - a single line or multi line string - expression (cf. issue 16806) */ - PyObject *decoding_readline; /* open(...).readline */ - PyObject *decoding_buffer; - PyObject *readline; /* readline() function */ - const char* enc; /* Encoding for the current str. */ - char* str; /* Source string being tokenized (if tokenizing from a string)*/ - char* input; /* Tokenizer's newline translated copy of the string. */ - - int type_comments; /* Whether to look for type comments */ - - /* How to proceed when asked for a new token in interactive mode */ - enum interactive_underflow_t interactive_underflow; - int report_warnings; - // TODO: Factor this into its own thing - tokenizer_mode tok_mode_stack[MAXFSTRINGLEVEL]; - int tok_mode_stack_index; - int tok_extra_tokens; - int comment_newline; - int implicit_newline; -#ifdef Py_DEBUG - int debug; -#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 *); - -#define tok_dump _Py_tok_dump - -#ifdef __cplusplus -} -#endif -#endif /* !Py_TOKENIZER_H */ 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/_testembed.c b/Programs/_testembed.c index bc991020d0fa77..30998bf80f9ce4 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -576,7 +576,11 @@ static int test_init_from_config(void) _PyPreConfig_InitCompatConfig(&preconfig); putenv("PYTHONMALLOC=malloc_debug"); +#ifndef Py_GIL_DISABLED preconfig.allocator = PYMEM_ALLOCATOR_MALLOC; +#else + preconfig.allocator = PYMEM_ALLOCATOR_MIMALLOC; +#endif putenv("PYTHONUTF8=0"); Py_UTF8Mode = 0; @@ -715,6 +719,7 @@ static int test_init_from_config(void) putenv("PYTHONINTMAXSTRDIGITS=6666"); config.int_max_str_digits = 31337; + config.cpu_count = 4321; init_from_config_clear(&config); @@ -764,7 +769,11 @@ static int test_init_dont_parse_argv(void) static void set_most_env_vars(void) { putenv("PYTHONHASHSEED=42"); +#ifndef Py_GIL_DISABLED putenv("PYTHONMALLOC=malloc"); +#else + putenv("PYTHONMALLOC=mimalloc"); +#endif putenv("PYTHONTRACEMALLOC=2"); putenv("PYTHONPROFILEIMPORTTIME=1"); putenv("PYTHONNODEBUGRANGES=1"); @@ -850,7 +859,11 @@ static int test_init_env_dev_mode_alloc(void) /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; set_all_env_vars_dev_mode(); +#ifndef Py_GIL_DISABLED putenv("PYTHONMALLOC=malloc"); +#else + putenv("PYTHONMALLOC=mimalloc"); +#endif _testembed_Py_InitializeFromConfig(); dump_config(); Py_Finalize(); @@ -1278,11 +1291,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; } @@ -1296,6 +1314,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) @@ -2140,6 +2209,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/Python/Python-ast.c b/Python/Python-ast.c index a197d44868b5aa..75dc3e156aa945 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -4,6 +4,7 @@ #include "pycore_ast.h" #include "pycore_ast_state.h" // struct ast_state #include "pycore_ceval.h" // _Py_EnterRecursiveCall +#include "pycore_lock.h" // _PyOnceFlag #include "pycore_interp.h" // _PyInterpreterState.ast #include "pycore_pystate.h" // _PyInterpreterState_GET() #include @@ -16,7 +17,8 @@ get_ast_state(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); struct ast_state *state = &interp->ast; - if (!init_types(state)) { + assert(!state->finalized); + if (_PyOnceFlag_CallOnce(&state->once, (_Py_once_fn_t *)&init_types, state) < 0) { return NULL; } return state; @@ -271,102 +273,99 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)); -#if !defined(NDEBUG) - state->initialized = -1; -#else - state->initialized = 0; -#endif + state->finalized = 1; + state->once = (_PyOnceFlag){0}; } static int init_identifiers(struct ast_state *state) { - if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0; - if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0; - if ((state->__match_args__ = PyUnicode_InternFromString("__match_args__")) == NULL) return 0; - if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0; - if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0; - if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0; - if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0; - if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return 0; - if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0; - if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0; - if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0; - if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return 0; - if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0; - if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0; - if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0; - if ((state->bound = PyUnicode_InternFromString("bound")) == NULL) return 0; - if ((state->cases = PyUnicode_InternFromString("cases")) == NULL) return 0; - if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0; - if ((state->cls = PyUnicode_InternFromString("cls")) == NULL) return 0; - if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return 0; - if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return 0; - if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return 0; - if ((state->conversion = PyUnicode_InternFromString("conversion")) == NULL) return 0; - if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0; - if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0; - if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0; - if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0; - if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0; - if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0; - if ((state->end_lineno = PyUnicode_InternFromString("end_lineno")) == NULL) return 0; - if ((state->exc = PyUnicode_InternFromString("exc")) == NULL) return 0; - if ((state->finalbody = PyUnicode_InternFromString("finalbody")) == NULL) return 0; - if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return 0; - if ((state->func = PyUnicode_InternFromString("func")) == NULL) return 0; - if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return 0; - if ((state->guard = PyUnicode_InternFromString("guard")) == NULL) return 0; - if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return 0; - if ((state->id = PyUnicode_InternFromString("id")) == NULL) return 0; - if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return 0; - if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return 0; - if ((state->items = PyUnicode_InternFromString("items")) == NULL) return 0; - if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return 0; - if ((state->key = PyUnicode_InternFromString("key")) == NULL) return 0; - if ((state->keys = PyUnicode_InternFromString("keys")) == NULL) return 0; - if ((state->keywords = PyUnicode_InternFromString("keywords")) == NULL) return 0; - if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return 0; - if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return 0; - if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return 0; - if ((state->kwd_attrs = PyUnicode_InternFromString("kwd_attrs")) == NULL) return 0; - if ((state->kwd_patterns = PyUnicode_InternFromString("kwd_patterns")) == NULL) return 0; - if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return 0; - if ((state->left = PyUnicode_InternFromString("left")) == NULL) return 0; - if ((state->level = PyUnicode_InternFromString("level")) == NULL) return 0; - if ((state->lineno = PyUnicode_InternFromString("lineno")) == NULL) return 0; - if ((state->lower = PyUnicode_InternFromString("lower")) == NULL) return 0; - if ((state->module = PyUnicode_InternFromString("module")) == NULL) return 0; - if ((state->msg = PyUnicode_InternFromString("msg")) == NULL) return 0; - if ((state->name = PyUnicode_InternFromString("name")) == NULL) return 0; - if ((state->names = PyUnicode_InternFromString("names")) == NULL) return 0; - if ((state->op = PyUnicode_InternFromString("op")) == NULL) return 0; - if ((state->operand = PyUnicode_InternFromString("operand")) == NULL) return 0; - if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return 0; - if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return 0; - if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return 0; - if ((state->pattern = PyUnicode_InternFromString("pattern")) == NULL) return 0; - if ((state->patterns = PyUnicode_InternFromString("patterns")) == NULL) return 0; - if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return 0; - if ((state->rest = PyUnicode_InternFromString("rest")) == NULL) return 0; - if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return 0; - if ((state->right = PyUnicode_InternFromString("right")) == NULL) return 0; - if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return 0; - if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return 0; - if ((state->step = PyUnicode_InternFromString("step")) == NULL) return 0; - if ((state->subject = PyUnicode_InternFromString("subject")) == NULL) return 0; - if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return 0; - if ((state->target = PyUnicode_InternFromString("target")) == NULL) return 0; - if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return 0; - if ((state->test = PyUnicode_InternFromString("test")) == NULL) return 0; - if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0; - if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0; - if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0; - if ((state->type_params = PyUnicode_InternFromString("type_params")) == NULL) return 0; - if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0; - if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0; - if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0; - if ((state->vararg = PyUnicode_InternFromString("vararg")) == NULL) return 0; - return 1; + if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return -1; + if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return -1; + if ((state->__match_args__ = PyUnicode_InternFromString("__match_args__")) == NULL) return -1; + if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return -1; + if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return -1; + if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return -1; + if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return -1; + if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return -1; + if ((state->args = PyUnicode_InternFromString("args")) == NULL) return -1; + if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return -1; + if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return -1; + if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return -1; + if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return -1; + if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return -1; + if ((state->body = PyUnicode_InternFromString("body")) == NULL) return -1; + if ((state->bound = PyUnicode_InternFromString("bound")) == NULL) return -1; + if ((state->cases = PyUnicode_InternFromString("cases")) == NULL) return -1; + if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return -1; + if ((state->cls = PyUnicode_InternFromString("cls")) == NULL) return -1; + if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return -1; + if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return -1; + if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return -1; + if ((state->conversion = PyUnicode_InternFromString("conversion")) == NULL) return -1; + if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return -1; + if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return -1; + if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return -1; + if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return -1; + if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return -1; + if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return -1; + if ((state->end_lineno = PyUnicode_InternFromString("end_lineno")) == NULL) return -1; + if ((state->exc = PyUnicode_InternFromString("exc")) == NULL) return -1; + if ((state->finalbody = PyUnicode_InternFromString("finalbody")) == NULL) return -1; + if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return -1; + if ((state->func = PyUnicode_InternFromString("func")) == NULL) return -1; + if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return -1; + if ((state->guard = PyUnicode_InternFromString("guard")) == NULL) return -1; + if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return -1; + if ((state->id = PyUnicode_InternFromString("id")) == NULL) return -1; + if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return -1; + if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return -1; + if ((state->items = PyUnicode_InternFromString("items")) == NULL) return -1; + if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return -1; + if ((state->key = PyUnicode_InternFromString("key")) == NULL) return -1; + if ((state->keys = PyUnicode_InternFromString("keys")) == NULL) return -1; + if ((state->keywords = PyUnicode_InternFromString("keywords")) == NULL) return -1; + if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return -1; + if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return -1; + if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return -1; + if ((state->kwd_attrs = PyUnicode_InternFromString("kwd_attrs")) == NULL) return -1; + if ((state->kwd_patterns = PyUnicode_InternFromString("kwd_patterns")) == NULL) return -1; + if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return -1; + if ((state->left = PyUnicode_InternFromString("left")) == NULL) return -1; + if ((state->level = PyUnicode_InternFromString("level")) == NULL) return -1; + if ((state->lineno = PyUnicode_InternFromString("lineno")) == NULL) return -1; + if ((state->lower = PyUnicode_InternFromString("lower")) == NULL) return -1; + if ((state->module = PyUnicode_InternFromString("module")) == NULL) return -1; + if ((state->msg = PyUnicode_InternFromString("msg")) == NULL) return -1; + if ((state->name = PyUnicode_InternFromString("name")) == NULL) return -1; + if ((state->names = PyUnicode_InternFromString("names")) == NULL) return -1; + if ((state->op = PyUnicode_InternFromString("op")) == NULL) return -1; + if ((state->operand = PyUnicode_InternFromString("operand")) == NULL) return -1; + if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return -1; + if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return -1; + if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return -1; + if ((state->pattern = PyUnicode_InternFromString("pattern")) == NULL) return -1; + if ((state->patterns = PyUnicode_InternFromString("patterns")) == NULL) return -1; + if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return -1; + if ((state->rest = PyUnicode_InternFromString("rest")) == NULL) return -1; + if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return -1; + if ((state->right = PyUnicode_InternFromString("right")) == NULL) return -1; + if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return -1; + if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return -1; + if ((state->step = PyUnicode_InternFromString("step")) == NULL) return -1; + if ((state->subject = PyUnicode_InternFromString("subject")) == NULL) return -1; + if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return -1; + if ((state->target = PyUnicode_InternFromString("target")) == NULL) return -1; + if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return -1; + if ((state->test = PyUnicode_InternFromString("test")) == NULL) return -1; + if ((state->type = PyUnicode_InternFromString("type")) == NULL) return -1; + if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return -1; + if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return -1; + if ((state->type_params = PyUnicode_InternFromString("type_params")) == NULL) return -1; + if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return -1; + if ((state->value = PyUnicode_InternFromString("value")) == NULL) return -1; + if ((state->values = PyUnicode_InternFromString("values")) == NULL) return -1; + if ((state->vararg = PyUnicode_InternFromString("vararg")) == NULL) return -1; + return 0; }; GENERATE_ASDL_SEQ_CONSTRUCTOR(mod, mod_ty) @@ -993,16 +992,16 @@ add_attributes(struct ast_state *state, PyObject *type, const char * const *attr int i, result; PyObject *s, *l = PyTuple_New(num_fields); if (!l) - return 0; + return -1; for (i = 0; i < num_fields; i++) { s = PyUnicode_InternFromString(attrs[i]); if (!s) { Py_DECREF(l); - return 0; + return -1; } PyTuple_SET_ITEM(l, i, s); } - result = PyObject_SetAttr(type, state->_attributes, l) >= 0; + result = PyObject_SetAttr(type, state->_attributes, l); Py_DECREF(l); return result; } @@ -1077,7 +1076,7 @@ static int obj2ast_identifier(struct ast_state *state, PyObject* obj, PyObject** { if (!PyUnicode_CheckExact(obj) && obj != Py_None) { PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str"); - return 1; + return -1; } return obj2ast_object(state, obj, out, arena); } @@ -1086,7 +1085,7 @@ static int obj2ast_string(struct ast_state *state, PyObject* obj, PyObject** out { if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) { PyErr_SetString(PyExc_TypeError, "AST string must be of type str"); - return 1; + return -1; } return obj2ast_object(state, obj, out, arena); } @@ -1096,12 +1095,12 @@ static int obj2ast_int(struct ast_state* Py_UNUSED(state), PyObject* obj, int* o int i; if (!PyLong_Check(obj)) { PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj); - return 1; + return -1; } i = PyLong_AsInt(obj); if (i == -1 && PyErr_Occurred()) - return 1; + return -1; *out = i; return 0; } @@ -1126,47 +1125,40 @@ static int add_ast_fields(struct ast_state *state) static int init_types(struct ast_state *state) { - // init_types() must not be called after _PyAST_Fini() - // has been called - assert(state->initialized >= 0); - - if (state->initialized) { - return 1; - } if (init_identifiers(state) < 0) { - return 0; + return -1; } state->AST_type = PyType_FromSpec(&AST_type_spec); if (!state->AST_type) { - return 0; + return -1; } if (add_ast_fields(state) < 0) { - return 0; + return -1; } state->mod_type = make_type(state, "mod", state->AST_type, NULL, 0, "mod = Module(stmt* body, type_ignore* type_ignores)\n" " | Interactive(stmt* body)\n" " | Expression(expr body)\n" " | FunctionType(expr* argtypes, expr returns)"); - if (!state->mod_type) return 0; - if (!add_attributes(state, state->mod_type, NULL, 0)) return 0; + if (!state->mod_type) return -1; + if (add_attributes(state, state->mod_type, NULL, 0) < 0) return -1; state->Module_type = make_type(state, "Module", state->mod_type, Module_fields, 2, "Module(stmt* body, type_ignore* type_ignores)"); - if (!state->Module_type) return 0; + if (!state->Module_type) return -1; state->Interactive_type = make_type(state, "Interactive", state->mod_type, Interactive_fields, 1, "Interactive(stmt* body)"); - if (!state->Interactive_type) return 0; + if (!state->Interactive_type) return -1; state->Expression_type = make_type(state, "Expression", state->mod_type, Expression_fields, 1, "Expression(expr body)"); - if (!state->Expression_type) return 0; + if (!state->Expression_type) return -1; state->FunctionType_type = make_type(state, "FunctionType", state->mod_type, FunctionType_fields, 2, "FunctionType(expr* argtypes, expr returns)"); - if (!state->FunctionType_type) return 0; + if (!state->FunctionType_type) return -1; state->stmt_type = make_type(state, "stmt", state->AST_type, NULL, 0, "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)\n" " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)\n" @@ -1196,160 +1188,161 @@ init_types(struct ast_state *state) " | Pass\n" " | Break\n" " | Continue"); - if (!state->stmt_type) return 0; - if (!add_attributes(state, state->stmt_type, stmt_attributes, 4)) return 0; + if (!state->stmt_type) return -1; + if (add_attributes(state, state->stmt_type, stmt_attributes, 4) < 0) return + -1; if (PyObject_SetAttr(state->stmt_type, state->end_lineno, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->stmt_type, state->end_col_offset, Py_None) == -1) - return 0; + return -1; state->FunctionDef_type = make_type(state, "FunctionDef", state->stmt_type, FunctionDef_fields, 7, "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)"); - if (!state->FunctionDef_type) return 0; + if (!state->FunctionDef_type) return -1; if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->FunctionDef_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->AsyncFunctionDef_type = make_type(state, "AsyncFunctionDef", state->stmt_type, AsyncFunctionDef_fields, 7, "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)"); - if (!state->AsyncFunctionDef_type) return 0; + if (!state->AsyncFunctionDef_type) return -1; if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->ClassDef_type = make_type(state, "ClassDef", state->stmt_type, ClassDef_fields, 6, "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list, type_param* type_params)"); - if (!state->ClassDef_type) return 0; + if (!state->ClassDef_type) return -1; state->Return_type = make_type(state, "Return", state->stmt_type, Return_fields, 1, "Return(expr? value)"); - if (!state->Return_type) return 0; + if (!state->Return_type) return -1; if (PyObject_SetAttr(state->Return_type, state->value, Py_None) == -1) - return 0; + return -1; state->Delete_type = make_type(state, "Delete", state->stmt_type, Delete_fields, 1, "Delete(expr* targets)"); - if (!state->Delete_type) return 0; + if (!state->Delete_type) return -1; state->Assign_type = make_type(state, "Assign", state->stmt_type, Assign_fields, 3, "Assign(expr* targets, expr value, string? type_comment)"); - if (!state->Assign_type) return 0; + if (!state->Assign_type) return -1; if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->TypeAlias_type = make_type(state, "TypeAlias", state->stmt_type, TypeAlias_fields, 3, "TypeAlias(expr name, type_param* type_params, expr value)"); - if (!state->TypeAlias_type) return 0; + if (!state->TypeAlias_type) return -1; state->AugAssign_type = make_type(state, "AugAssign", state->stmt_type, AugAssign_fields, 3, "AugAssign(expr target, operator op, expr value)"); - if (!state->AugAssign_type) return 0; + if (!state->AugAssign_type) return -1; state->AnnAssign_type = make_type(state, "AnnAssign", state->stmt_type, AnnAssign_fields, 4, "AnnAssign(expr target, expr annotation, expr? value, int simple)"); - if (!state->AnnAssign_type) return 0; + if (!state->AnnAssign_type) return -1; if (PyObject_SetAttr(state->AnnAssign_type, state->value, Py_None) == -1) - return 0; + return -1; state->For_type = make_type(state, "For", state->stmt_type, For_fields, 5, "For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)"); - if (!state->For_type) return 0; + if (!state->For_type) return -1; if (PyObject_SetAttr(state->For_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->AsyncFor_type = make_type(state, "AsyncFor", state->stmt_type, AsyncFor_fields, 5, "AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)"); - if (!state->AsyncFor_type) return 0; + if (!state->AsyncFor_type) return -1; if (PyObject_SetAttr(state->AsyncFor_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->While_type = make_type(state, "While", state->stmt_type, While_fields, 3, "While(expr test, stmt* body, stmt* orelse)"); - if (!state->While_type) return 0; + if (!state->While_type) return -1; state->If_type = make_type(state, "If", state->stmt_type, If_fields, 3, "If(expr test, stmt* body, stmt* orelse)"); - if (!state->If_type) return 0; + if (!state->If_type) return -1; state->With_type = make_type(state, "With", state->stmt_type, With_fields, 3, "With(withitem* items, stmt* body, string? type_comment)"); - if (!state->With_type) return 0; + if (!state->With_type) return -1; if (PyObject_SetAttr(state->With_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->AsyncWith_type = make_type(state, "AsyncWith", state->stmt_type, AsyncWith_fields, 3, "AsyncWith(withitem* items, stmt* body, string? type_comment)"); - if (!state->AsyncWith_type) return 0; + if (!state->AsyncWith_type) return -1; if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None) == -1) - return 0; + return -1; state->Match_type = make_type(state, "Match", state->stmt_type, Match_fields, 2, "Match(expr subject, match_case* cases)"); - if (!state->Match_type) return 0; + if (!state->Match_type) return -1; state->Raise_type = make_type(state, "Raise", state->stmt_type, Raise_fields, 2, "Raise(expr? exc, expr? cause)"); - if (!state->Raise_type) return 0; + if (!state->Raise_type) return -1; if (PyObject_SetAttr(state->Raise_type, state->exc, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->Raise_type, state->cause, Py_None) == -1) - return 0; + return -1; state->Try_type = make_type(state, "Try", state->stmt_type, Try_fields, 4, "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); - if (!state->Try_type) return 0; + if (!state->Try_type) return -1; state->TryStar_type = make_type(state, "TryStar", state->stmt_type, TryStar_fields, 4, "TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); - if (!state->TryStar_type) return 0; + if (!state->TryStar_type) return -1; state->Assert_type = make_type(state, "Assert", state->stmt_type, Assert_fields, 2, "Assert(expr test, expr? msg)"); - if (!state->Assert_type) return 0; + if (!state->Assert_type) return -1; if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1) - return 0; + return -1; state->Import_type = make_type(state, "Import", state->stmt_type, Import_fields, 1, "Import(alias* names)"); - if (!state->Import_type) return 0; + if (!state->Import_type) return -1; state->ImportFrom_type = make_type(state, "ImportFrom", state->stmt_type, ImportFrom_fields, 3, "ImportFrom(identifier? module, alias* names, int? level)"); - if (!state->ImportFrom_type) return 0; + if (!state->ImportFrom_type) return -1; if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1) - return 0; + return -1; state->Global_type = make_type(state, "Global", state->stmt_type, Global_fields, 1, "Global(identifier* names)"); - if (!state->Global_type) return 0; + if (!state->Global_type) return -1; state->Nonlocal_type = make_type(state, "Nonlocal", state->stmt_type, Nonlocal_fields, 1, "Nonlocal(identifier* names)"); - if (!state->Nonlocal_type) return 0; + if (!state->Nonlocal_type) return -1; state->Expr_type = make_type(state, "Expr", state->stmt_type, Expr_fields, 1, "Expr(expr value)"); - if (!state->Expr_type) return 0; + if (!state->Expr_type) return -1; state->Pass_type = make_type(state, "Pass", state->stmt_type, NULL, 0, "Pass"); - if (!state->Pass_type) return 0; + if (!state->Pass_type) return -1; state->Break_type = make_type(state, "Break", state->stmt_type, NULL, 0, "Break"); - if (!state->Break_type) return 0; + if (!state->Break_type) return -1; state->Continue_type = make_type(state, "Continue", state->stmt_type, NULL, 0, "Continue"); - if (!state->Continue_type) return 0; + if (!state->Continue_type) return -1; state->expr_type = make_type(state, "expr", state->AST_type, NULL, 0, "expr = BoolOp(boolop op, expr* values)\n" " | NamedExpr(expr target, expr value)\n" @@ -1378,454 +1371,457 @@ init_types(struct ast_state *state) " | List(expr* elts, expr_context ctx)\n" " | Tuple(expr* elts, expr_context ctx)\n" " | Slice(expr? lower, expr? upper, expr? step)"); - if (!state->expr_type) return 0; - if (!add_attributes(state, state->expr_type, expr_attributes, 4)) return 0; + if (!state->expr_type) return -1; + if (add_attributes(state, state->expr_type, expr_attributes, 4) < 0) return + -1; if (PyObject_SetAttr(state->expr_type, state->end_lineno, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) == -1) - return 0; + return -1; state->BoolOp_type = make_type(state, "BoolOp", state->expr_type, BoolOp_fields, 2, "BoolOp(boolop op, expr* values)"); - if (!state->BoolOp_type) return 0; + if (!state->BoolOp_type) return -1; state->NamedExpr_type = make_type(state, "NamedExpr", state->expr_type, NamedExpr_fields, 2, "NamedExpr(expr target, expr value)"); - if (!state->NamedExpr_type) return 0; + if (!state->NamedExpr_type) return -1; state->BinOp_type = make_type(state, "BinOp", state->expr_type, BinOp_fields, 3, "BinOp(expr left, operator op, expr right)"); - if (!state->BinOp_type) return 0; + if (!state->BinOp_type) return -1; state->UnaryOp_type = make_type(state, "UnaryOp", state->expr_type, UnaryOp_fields, 2, "UnaryOp(unaryop op, expr operand)"); - if (!state->UnaryOp_type) return 0; + if (!state->UnaryOp_type) return -1; state->Lambda_type = make_type(state, "Lambda", state->expr_type, Lambda_fields, 2, "Lambda(arguments args, expr body)"); - if (!state->Lambda_type) return 0; + if (!state->Lambda_type) return -1; state->IfExp_type = make_type(state, "IfExp", state->expr_type, IfExp_fields, 3, "IfExp(expr test, expr body, expr orelse)"); - if (!state->IfExp_type) return 0; + if (!state->IfExp_type) return -1; state->Dict_type = make_type(state, "Dict", state->expr_type, Dict_fields, 2, "Dict(expr* keys, expr* values)"); - if (!state->Dict_type) return 0; + if (!state->Dict_type) return -1; state->Set_type = make_type(state, "Set", state->expr_type, Set_fields, 1, "Set(expr* elts)"); - if (!state->Set_type) return 0; + if (!state->Set_type) return -1; state->ListComp_type = make_type(state, "ListComp", state->expr_type, ListComp_fields, 2, "ListComp(expr elt, comprehension* generators)"); - if (!state->ListComp_type) return 0; + if (!state->ListComp_type) return -1; state->SetComp_type = make_type(state, "SetComp", state->expr_type, SetComp_fields, 2, "SetComp(expr elt, comprehension* generators)"); - if (!state->SetComp_type) return 0; + if (!state->SetComp_type) return -1; state->DictComp_type = make_type(state, "DictComp", state->expr_type, DictComp_fields, 3, "DictComp(expr key, expr value, comprehension* generators)"); - if (!state->DictComp_type) return 0; + if (!state->DictComp_type) return -1; state->GeneratorExp_type = make_type(state, "GeneratorExp", state->expr_type, GeneratorExp_fields, 2, "GeneratorExp(expr elt, comprehension* generators)"); - if (!state->GeneratorExp_type) return 0; + if (!state->GeneratorExp_type) return -1; state->Await_type = make_type(state, "Await", state->expr_type, Await_fields, 1, "Await(expr value)"); - if (!state->Await_type) return 0; + if (!state->Await_type) return -1; state->Yield_type = make_type(state, "Yield", state->expr_type, Yield_fields, 1, "Yield(expr? value)"); - if (!state->Yield_type) return 0; + if (!state->Yield_type) return -1; if (PyObject_SetAttr(state->Yield_type, state->value, Py_None) == -1) - return 0; + return -1; state->YieldFrom_type = make_type(state, "YieldFrom", state->expr_type, YieldFrom_fields, 1, "YieldFrom(expr value)"); - if (!state->YieldFrom_type) return 0; + if (!state->YieldFrom_type) return -1; state->Compare_type = make_type(state, "Compare", state->expr_type, Compare_fields, 3, "Compare(expr left, cmpop* ops, expr* comparators)"); - if (!state->Compare_type) return 0; + if (!state->Compare_type) return -1; state->Call_type = make_type(state, "Call", state->expr_type, Call_fields, 3, "Call(expr func, expr* args, keyword* keywords)"); - if (!state->Call_type) return 0; + if (!state->Call_type) return -1; state->FormattedValue_type = make_type(state, "FormattedValue", state->expr_type, FormattedValue_fields, 3, "FormattedValue(expr value, int conversion, expr? format_spec)"); - if (!state->FormattedValue_type) return 0; + if (!state->FormattedValue_type) return -1; if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec, Py_None) == -1) - return 0; + return -1; state->JoinedStr_type = make_type(state, "JoinedStr", state->expr_type, JoinedStr_fields, 1, "JoinedStr(expr* values)"); - if (!state->JoinedStr_type) return 0; + if (!state->JoinedStr_type) return -1; state->Constant_type = make_type(state, "Constant", state->expr_type, Constant_fields, 2, "Constant(constant value, string? kind)"); - if (!state->Constant_type) return 0; + if (!state->Constant_type) return -1; if (PyObject_SetAttr(state->Constant_type, state->kind, Py_None) == -1) - return 0; + return -1; state->Attribute_type = make_type(state, "Attribute", state->expr_type, Attribute_fields, 3, "Attribute(expr value, identifier attr, expr_context ctx)"); - if (!state->Attribute_type) return 0; + if (!state->Attribute_type) return -1; state->Subscript_type = make_type(state, "Subscript", state->expr_type, Subscript_fields, 3, "Subscript(expr value, expr slice, expr_context ctx)"); - if (!state->Subscript_type) return 0; + if (!state->Subscript_type) return -1; state->Starred_type = make_type(state, "Starred", state->expr_type, Starred_fields, 2, "Starred(expr value, expr_context ctx)"); - if (!state->Starred_type) return 0; + if (!state->Starred_type) return -1; state->Name_type = make_type(state, "Name", state->expr_type, Name_fields, 2, "Name(identifier id, expr_context ctx)"); - if (!state->Name_type) return 0; + if (!state->Name_type) return -1; state->List_type = make_type(state, "List", state->expr_type, List_fields, 2, "List(expr* elts, expr_context ctx)"); - if (!state->List_type) return 0; + if (!state->List_type) return -1; state->Tuple_type = make_type(state, "Tuple", state->expr_type, Tuple_fields, 2, "Tuple(expr* elts, expr_context ctx)"); - if (!state->Tuple_type) return 0; + if (!state->Tuple_type) return -1; state->Slice_type = make_type(state, "Slice", state->expr_type, Slice_fields, 3, "Slice(expr? lower, expr? upper, expr? step)"); - if (!state->Slice_type) return 0; + if (!state->Slice_type) return -1; if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1) - return 0; + return -1; state->expr_context_type = make_type(state, "expr_context", state->AST_type, NULL, 0, "expr_context = Load | Store | Del"); - if (!state->expr_context_type) return 0; - if (!add_attributes(state, state->expr_context_type, NULL, 0)) return 0; + if (!state->expr_context_type) return -1; + if (add_attributes(state, state->expr_context_type, NULL, 0) < 0) return -1; state->Load_type = make_type(state, "Load", state->expr_context_type, NULL, 0, "Load"); - if (!state->Load_type) return 0; + if (!state->Load_type) return -1; state->Load_singleton = PyType_GenericNew((PyTypeObject *)state->Load_type, NULL, NULL); - if (!state->Load_singleton) return 0; + if (!state->Load_singleton) return -1; state->Store_type = make_type(state, "Store", state->expr_context_type, NULL, 0, "Store"); - if (!state->Store_type) return 0; + if (!state->Store_type) return -1; state->Store_singleton = PyType_GenericNew((PyTypeObject *)state->Store_type, NULL, NULL); - if (!state->Store_singleton) return 0; + if (!state->Store_singleton) return -1; state->Del_type = make_type(state, "Del", state->expr_context_type, NULL, 0, "Del"); - if (!state->Del_type) return 0; + if (!state->Del_type) return -1; state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type, NULL, NULL); - if (!state->Del_singleton) return 0; + if (!state->Del_singleton) return -1; state->boolop_type = make_type(state, "boolop", state->AST_type, NULL, 0, "boolop = And | Or"); - if (!state->boolop_type) return 0; - if (!add_attributes(state, state->boolop_type, NULL, 0)) return 0; + if (!state->boolop_type) return -1; + if (add_attributes(state, state->boolop_type, NULL, 0) < 0) return -1; state->And_type = make_type(state, "And", state->boolop_type, NULL, 0, "And"); - if (!state->And_type) return 0; + if (!state->And_type) return -1; state->And_singleton = PyType_GenericNew((PyTypeObject *)state->And_type, NULL, NULL); - if (!state->And_singleton) return 0; + if (!state->And_singleton) return -1; state->Or_type = make_type(state, "Or", state->boolop_type, NULL, 0, "Or"); - if (!state->Or_type) return 0; + if (!state->Or_type) return -1; state->Or_singleton = PyType_GenericNew((PyTypeObject *)state->Or_type, NULL, NULL); - if (!state->Or_singleton) return 0; + if (!state->Or_singleton) return -1; state->operator_type = make_type(state, "operator", state->AST_type, NULL, 0, "operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv"); - if (!state->operator_type) return 0; - if (!add_attributes(state, state->operator_type, NULL, 0)) return 0; + if (!state->operator_type) return -1; + if (add_attributes(state, state->operator_type, NULL, 0) < 0) return -1; state->Add_type = make_type(state, "Add", state->operator_type, NULL, 0, "Add"); - if (!state->Add_type) return 0; + if (!state->Add_type) return -1; state->Add_singleton = PyType_GenericNew((PyTypeObject *)state->Add_type, NULL, NULL); - if (!state->Add_singleton) return 0; + if (!state->Add_singleton) return -1; state->Sub_type = make_type(state, "Sub", state->operator_type, NULL, 0, "Sub"); - if (!state->Sub_type) return 0; + if (!state->Sub_type) return -1; state->Sub_singleton = PyType_GenericNew((PyTypeObject *)state->Sub_type, NULL, NULL); - if (!state->Sub_singleton) return 0; + if (!state->Sub_singleton) return -1; state->Mult_type = make_type(state, "Mult", state->operator_type, NULL, 0, "Mult"); - if (!state->Mult_type) return 0; + if (!state->Mult_type) return -1; state->Mult_singleton = PyType_GenericNew((PyTypeObject *)state->Mult_type, NULL, NULL); - if (!state->Mult_singleton) return 0; + if (!state->Mult_singleton) return -1; state->MatMult_type = make_type(state, "MatMult", state->operator_type, NULL, 0, "MatMult"); - if (!state->MatMult_type) return 0; + if (!state->MatMult_type) return -1; state->MatMult_singleton = PyType_GenericNew((PyTypeObject *)state->MatMult_type, NULL, NULL); - if (!state->MatMult_singleton) return 0; + if (!state->MatMult_singleton) return -1; state->Div_type = make_type(state, "Div", state->operator_type, NULL, 0, "Div"); - if (!state->Div_type) return 0; + if (!state->Div_type) return -1; state->Div_singleton = PyType_GenericNew((PyTypeObject *)state->Div_type, NULL, NULL); - if (!state->Div_singleton) return 0; + if (!state->Div_singleton) return -1; state->Mod_type = make_type(state, "Mod", state->operator_type, NULL, 0, "Mod"); - if (!state->Mod_type) return 0; + if (!state->Mod_type) return -1; state->Mod_singleton = PyType_GenericNew((PyTypeObject *)state->Mod_type, NULL, NULL); - if (!state->Mod_singleton) return 0; + if (!state->Mod_singleton) return -1; state->Pow_type = make_type(state, "Pow", state->operator_type, NULL, 0, "Pow"); - if (!state->Pow_type) return 0; + if (!state->Pow_type) return -1; state->Pow_singleton = PyType_GenericNew((PyTypeObject *)state->Pow_type, NULL, NULL); - if (!state->Pow_singleton) return 0; + if (!state->Pow_singleton) return -1; state->LShift_type = make_type(state, "LShift", state->operator_type, NULL, 0, "LShift"); - if (!state->LShift_type) return 0; + if (!state->LShift_type) return -1; state->LShift_singleton = PyType_GenericNew((PyTypeObject *)state->LShift_type, NULL, NULL); - if (!state->LShift_singleton) return 0; + if (!state->LShift_singleton) return -1; state->RShift_type = make_type(state, "RShift", state->operator_type, NULL, 0, "RShift"); - if (!state->RShift_type) return 0; + if (!state->RShift_type) return -1; state->RShift_singleton = PyType_GenericNew((PyTypeObject *)state->RShift_type, NULL, NULL); - if (!state->RShift_singleton) return 0; + if (!state->RShift_singleton) return -1; state->BitOr_type = make_type(state, "BitOr", state->operator_type, NULL, 0, "BitOr"); - if (!state->BitOr_type) return 0; + if (!state->BitOr_type) return -1; state->BitOr_singleton = PyType_GenericNew((PyTypeObject *)state->BitOr_type, NULL, NULL); - if (!state->BitOr_singleton) return 0; + if (!state->BitOr_singleton) return -1; state->BitXor_type = make_type(state, "BitXor", state->operator_type, NULL, 0, "BitXor"); - if (!state->BitXor_type) return 0; + if (!state->BitXor_type) return -1; state->BitXor_singleton = PyType_GenericNew((PyTypeObject *)state->BitXor_type, NULL, NULL); - if (!state->BitXor_singleton) return 0; + if (!state->BitXor_singleton) return -1; state->BitAnd_type = make_type(state, "BitAnd", state->operator_type, NULL, 0, "BitAnd"); - if (!state->BitAnd_type) return 0; + if (!state->BitAnd_type) return -1; state->BitAnd_singleton = PyType_GenericNew((PyTypeObject *)state->BitAnd_type, NULL, NULL); - if (!state->BitAnd_singleton) return 0; + if (!state->BitAnd_singleton) return -1; state->FloorDiv_type = make_type(state, "FloorDiv", state->operator_type, NULL, 0, "FloorDiv"); - if (!state->FloorDiv_type) return 0; + if (!state->FloorDiv_type) return -1; state->FloorDiv_singleton = PyType_GenericNew((PyTypeObject *)state->FloorDiv_type, NULL, NULL); - if (!state->FloorDiv_singleton) return 0; + if (!state->FloorDiv_singleton) return -1; state->unaryop_type = make_type(state, "unaryop", state->AST_type, NULL, 0, "unaryop = Invert | Not | UAdd | USub"); - if (!state->unaryop_type) return 0; - if (!add_attributes(state, state->unaryop_type, NULL, 0)) return 0; + if (!state->unaryop_type) return -1; + if (add_attributes(state, state->unaryop_type, NULL, 0) < 0) return -1; state->Invert_type = make_type(state, "Invert", state->unaryop_type, NULL, 0, "Invert"); - if (!state->Invert_type) return 0; + if (!state->Invert_type) return -1; state->Invert_singleton = PyType_GenericNew((PyTypeObject *)state->Invert_type, NULL, NULL); - if (!state->Invert_singleton) return 0; + if (!state->Invert_singleton) return -1; state->Not_type = make_type(state, "Not", state->unaryop_type, NULL, 0, "Not"); - if (!state->Not_type) return 0; + if (!state->Not_type) return -1; state->Not_singleton = PyType_GenericNew((PyTypeObject *)state->Not_type, NULL, NULL); - if (!state->Not_singleton) return 0; + if (!state->Not_singleton) return -1; state->UAdd_type = make_type(state, "UAdd", state->unaryop_type, NULL, 0, "UAdd"); - if (!state->UAdd_type) return 0; + if (!state->UAdd_type) return -1; state->UAdd_singleton = PyType_GenericNew((PyTypeObject *)state->UAdd_type, NULL, NULL); - if (!state->UAdd_singleton) return 0; + if (!state->UAdd_singleton) return -1; state->USub_type = make_type(state, "USub", state->unaryop_type, NULL, 0, "USub"); - if (!state->USub_type) return 0; + if (!state->USub_type) return -1; state->USub_singleton = PyType_GenericNew((PyTypeObject *)state->USub_type, NULL, NULL); - if (!state->USub_singleton) return 0; + if (!state->USub_singleton) return -1; state->cmpop_type = make_type(state, "cmpop", state->AST_type, NULL, 0, "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn"); - if (!state->cmpop_type) return 0; - if (!add_attributes(state, state->cmpop_type, NULL, 0)) return 0; + if (!state->cmpop_type) return -1; + if (add_attributes(state, state->cmpop_type, NULL, 0) < 0) return -1; state->Eq_type = make_type(state, "Eq", state->cmpop_type, NULL, 0, "Eq"); - if (!state->Eq_type) return 0; + if (!state->Eq_type) return -1; state->Eq_singleton = PyType_GenericNew((PyTypeObject *)state->Eq_type, NULL, NULL); - if (!state->Eq_singleton) return 0; + if (!state->Eq_singleton) return -1; state->NotEq_type = make_type(state, "NotEq", state->cmpop_type, NULL, 0, "NotEq"); - if (!state->NotEq_type) return 0; + if (!state->NotEq_type) return -1; state->NotEq_singleton = PyType_GenericNew((PyTypeObject *)state->NotEq_type, NULL, NULL); - if (!state->NotEq_singleton) return 0; + if (!state->NotEq_singleton) return -1; state->Lt_type = make_type(state, "Lt", state->cmpop_type, NULL, 0, "Lt"); - if (!state->Lt_type) return 0; + if (!state->Lt_type) return -1; state->Lt_singleton = PyType_GenericNew((PyTypeObject *)state->Lt_type, NULL, NULL); - if (!state->Lt_singleton) return 0; + if (!state->Lt_singleton) return -1; state->LtE_type = make_type(state, "LtE", state->cmpop_type, NULL, 0, "LtE"); - if (!state->LtE_type) return 0; + if (!state->LtE_type) return -1; state->LtE_singleton = PyType_GenericNew((PyTypeObject *)state->LtE_type, NULL, NULL); - if (!state->LtE_singleton) return 0; + if (!state->LtE_singleton) return -1; state->Gt_type = make_type(state, "Gt", state->cmpop_type, NULL, 0, "Gt"); - if (!state->Gt_type) return 0; + if (!state->Gt_type) return -1; state->Gt_singleton = PyType_GenericNew((PyTypeObject *)state->Gt_type, NULL, NULL); - if (!state->Gt_singleton) return 0; + if (!state->Gt_singleton) return -1; state->GtE_type = make_type(state, "GtE", state->cmpop_type, NULL, 0, "GtE"); - if (!state->GtE_type) return 0; + if (!state->GtE_type) return -1; state->GtE_singleton = PyType_GenericNew((PyTypeObject *)state->GtE_type, NULL, NULL); - if (!state->GtE_singleton) return 0; + if (!state->GtE_singleton) return -1; state->Is_type = make_type(state, "Is", state->cmpop_type, NULL, 0, "Is"); - if (!state->Is_type) return 0; + if (!state->Is_type) return -1; state->Is_singleton = PyType_GenericNew((PyTypeObject *)state->Is_type, NULL, NULL); - if (!state->Is_singleton) return 0; + if (!state->Is_singleton) return -1; state->IsNot_type = make_type(state, "IsNot", state->cmpop_type, NULL, 0, "IsNot"); - if (!state->IsNot_type) return 0; + if (!state->IsNot_type) return -1; state->IsNot_singleton = PyType_GenericNew((PyTypeObject *)state->IsNot_type, NULL, NULL); - if (!state->IsNot_singleton) return 0; + if (!state->IsNot_singleton) return -1; state->In_type = make_type(state, "In", state->cmpop_type, NULL, 0, "In"); - if (!state->In_type) return 0; + if (!state->In_type) return -1; state->In_singleton = PyType_GenericNew((PyTypeObject *)state->In_type, NULL, NULL); - if (!state->In_singleton) return 0; + if (!state->In_singleton) return -1; state->NotIn_type = make_type(state, "NotIn", state->cmpop_type, NULL, 0, "NotIn"); - if (!state->NotIn_type) return 0; + if (!state->NotIn_type) return -1; state->NotIn_singleton = PyType_GenericNew((PyTypeObject *)state->NotIn_type, NULL, NULL); - if (!state->NotIn_singleton) return 0; + if (!state->NotIn_singleton) return -1; state->comprehension_type = make_type(state, "comprehension", state->AST_type, comprehension_fields, 4, "comprehension(expr target, expr iter, expr* ifs, int is_async)"); - if (!state->comprehension_type) return 0; - if (!add_attributes(state, state->comprehension_type, NULL, 0)) return 0; + if (!state->comprehension_type) return -1; + if (add_attributes(state, state->comprehension_type, NULL, 0) < 0) return + -1; state->excepthandler_type = make_type(state, "excepthandler", state->AST_type, NULL, 0, "excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)"); - if (!state->excepthandler_type) return 0; - if (!add_attributes(state, state->excepthandler_type, - excepthandler_attributes, 4)) return 0; + if (!state->excepthandler_type) return -1; + if (add_attributes(state, state->excepthandler_type, + excepthandler_attributes, 4) < 0) return -1; if (PyObject_SetAttr(state->excepthandler_type, state->end_lineno, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->excepthandler_type, state->end_col_offset, Py_None) == -1) - return 0; + return -1; state->ExceptHandler_type = make_type(state, "ExceptHandler", state->excepthandler_type, ExceptHandler_fields, 3, "ExceptHandler(expr? type, identifier? name, stmt* body)"); - if (!state->ExceptHandler_type) return 0; + if (!state->ExceptHandler_type) return -1; if (PyObject_SetAttr(state->ExceptHandler_type, state->type, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->ExceptHandler_type, state->name, Py_None) == -1) - return 0; + return -1; state->arguments_type = make_type(state, "arguments", state->AST_type, arguments_fields, 7, "arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults)"); - if (!state->arguments_type) return 0; - if (!add_attributes(state, state->arguments_type, NULL, 0)) return 0; + if (!state->arguments_type) return -1; + if (add_attributes(state, state->arguments_type, NULL, 0) < 0) return -1; if (PyObject_SetAttr(state->arguments_type, state->vararg, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->arguments_type, state->kwarg, Py_None) == -1) - return 0; + return -1; state->arg_type = make_type(state, "arg", state->AST_type, arg_fields, 3, "arg(identifier arg, expr? annotation, string? type_comment)"); - if (!state->arg_type) return 0; - if (!add_attributes(state, state->arg_type, arg_attributes, 4)) return 0; + if (!state->arg_type) return -1; + if (add_attributes(state, state->arg_type, arg_attributes, 4) < 0) return + -1; if (PyObject_SetAttr(state->arg_type, state->annotation, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->arg_type, state->type_comment, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->arg_type, state->end_lineno, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->arg_type, state->end_col_offset, Py_None) == -1) - return 0; + return -1; state->keyword_type = make_type(state, "keyword", state->AST_type, keyword_fields, 2, "keyword(identifier? arg, expr value)"); - if (!state->keyword_type) return 0; - if (!add_attributes(state, state->keyword_type, keyword_attributes, 4)) - return 0; + if (!state->keyword_type) return -1; + if (add_attributes(state, state->keyword_type, keyword_attributes, 4) < 0) + return -1; if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->keyword_type, state->end_lineno, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->keyword_type, state->end_col_offset, Py_None) == -1) - return 0; + return -1; state->alias_type = make_type(state, "alias", state->AST_type, alias_fields, 2, "alias(identifier name, identifier? asname)"); - if (!state->alias_type) return 0; - if (!add_attributes(state, state->alias_type, alias_attributes, 4)) return - 0; + if (!state->alias_type) return -1; + if (add_attributes(state, state->alias_type, alias_attributes, 4) < 0) + return -1; if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->alias_type, state->end_lineno, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->alias_type, state->end_col_offset, Py_None) == -1) - return 0; + return -1; state->withitem_type = make_type(state, "withitem", state->AST_type, withitem_fields, 2, "withitem(expr context_expr, expr? optional_vars)"); - if (!state->withitem_type) return 0; - if (!add_attributes(state, state->withitem_type, NULL, 0)) return 0; + if (!state->withitem_type) return -1; + if (add_attributes(state, state->withitem_type, NULL, 0) < 0) return -1; if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None) == -1) - return 0; + return -1; state->match_case_type = make_type(state, "match_case", state->AST_type, match_case_fields, 3, "match_case(pattern pattern, expr? guard, stmt* body)"); - if (!state->match_case_type) return 0; - if (!add_attributes(state, state->match_case_type, NULL, 0)) return 0; + if (!state->match_case_type) return -1; + if (add_attributes(state, state->match_case_type, NULL, 0) < 0) return -1; if (PyObject_SetAttr(state->match_case_type, state->guard, Py_None) == -1) - return 0; + return -1; state->pattern_type = make_type(state, "pattern", state->AST_type, NULL, 0, "pattern = MatchValue(expr value)\n" " | MatchSingleton(constant value)\n" @@ -1835,93 +1831,92 @@ init_types(struct ast_state *state) " | MatchStar(identifier? name)\n" " | MatchAs(pattern? pattern, identifier? name)\n" " | MatchOr(pattern* patterns)"); - if (!state->pattern_type) return 0; - if (!add_attributes(state, state->pattern_type, pattern_attributes, 4)) - return 0; + if (!state->pattern_type) return -1; + if (add_attributes(state, state->pattern_type, pattern_attributes, 4) < 0) + return -1; state->MatchValue_type = make_type(state, "MatchValue", state->pattern_type, MatchValue_fields, 1, "MatchValue(expr value)"); - if (!state->MatchValue_type) return 0; + if (!state->MatchValue_type) return -1; state->MatchSingleton_type = make_type(state, "MatchSingleton", state->pattern_type, MatchSingleton_fields, 1, "MatchSingleton(constant value)"); - if (!state->MatchSingleton_type) return 0; + if (!state->MatchSingleton_type) return -1; state->MatchSequence_type = make_type(state, "MatchSequence", state->pattern_type, MatchSequence_fields, 1, "MatchSequence(pattern* patterns)"); - if (!state->MatchSequence_type) return 0; + if (!state->MatchSequence_type) return -1; state->MatchMapping_type = make_type(state, "MatchMapping", state->pattern_type, MatchMapping_fields, 3, "MatchMapping(expr* keys, pattern* patterns, identifier? rest)"); - if (!state->MatchMapping_type) return 0; + if (!state->MatchMapping_type) return -1; if (PyObject_SetAttr(state->MatchMapping_type, state->rest, Py_None) == -1) - return 0; + return -1; state->MatchClass_type = make_type(state, "MatchClass", state->pattern_type, MatchClass_fields, 4, "MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)"); - if (!state->MatchClass_type) return 0; + if (!state->MatchClass_type) return -1; state->MatchStar_type = make_type(state, "MatchStar", state->pattern_type, MatchStar_fields, 1, "MatchStar(identifier? name)"); - if (!state->MatchStar_type) return 0; + if (!state->MatchStar_type) return -1; if (PyObject_SetAttr(state->MatchStar_type, state->name, Py_None) == -1) - return 0; + return -1; state->MatchAs_type = make_type(state, "MatchAs", state->pattern_type, MatchAs_fields, 2, "MatchAs(pattern? pattern, identifier? name)"); - if (!state->MatchAs_type) return 0; + if (!state->MatchAs_type) return -1; if (PyObject_SetAttr(state->MatchAs_type, state->pattern, Py_None) == -1) - return 0; + return -1; if (PyObject_SetAttr(state->MatchAs_type, state->name, Py_None) == -1) - return 0; + return -1; state->MatchOr_type = make_type(state, "MatchOr", state->pattern_type, MatchOr_fields, 1, "MatchOr(pattern* patterns)"); - if (!state->MatchOr_type) return 0; + if (!state->MatchOr_type) return -1; state->type_ignore_type = make_type(state, "type_ignore", state->AST_type, NULL, 0, "type_ignore = TypeIgnore(int lineno, string tag)"); - if (!state->type_ignore_type) return 0; - if (!add_attributes(state, state->type_ignore_type, NULL, 0)) return 0; + if (!state->type_ignore_type) return -1; + if (add_attributes(state, state->type_ignore_type, NULL, 0) < 0) return -1; state->TypeIgnore_type = make_type(state, "TypeIgnore", state->type_ignore_type, TypeIgnore_fields, 2, "TypeIgnore(int lineno, string tag)"); - if (!state->TypeIgnore_type) return 0; + if (!state->TypeIgnore_type) return -1; state->type_param_type = make_type(state, "type_param", state->AST_type, NULL, 0, "type_param = TypeVar(identifier name, expr? bound)\n" " | ParamSpec(identifier name)\n" " | TypeVarTuple(identifier name)"); - if (!state->type_param_type) return 0; - if (!add_attributes(state, state->type_param_type, type_param_attributes, - 4)) return 0; + if (!state->type_param_type) return -1; + if (add_attributes(state, state->type_param_type, type_param_attributes, 4) + < 0) return -1; state->TypeVar_type = make_type(state, "TypeVar", state->type_param_type, TypeVar_fields, 2, "TypeVar(identifier name, expr? bound)"); - if (!state->TypeVar_type) return 0; + if (!state->TypeVar_type) return -1; if (PyObject_SetAttr(state->TypeVar_type, state->bound, Py_None) == -1) - return 0; + return -1; state->ParamSpec_type = make_type(state, "ParamSpec", state->type_param_type, ParamSpec_fields, 1, "ParamSpec(identifier name)"); - if (!state->ParamSpec_type) return 0; + if (!state->ParamSpec_type) return -1; state->TypeVarTuple_type = make_type(state, "TypeVarTuple", state->type_param_type, TypeVarTuple_fields, 1, "TypeVarTuple(identifier name)"); - if (!state->TypeVarTuple_type) return 0; + if (!state->TypeVarTuple_type) return -1; state->recursion_depth = 0; state->recursion_limit = 0; - state->initialized = 1; - return 1; + return 0; } static int obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, @@ -3786,7 +3781,7 @@ ast2obj_mod(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case Module_kind: @@ -3846,6 +3841,7 @@ ast2obj_mod(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -3863,7 +3859,7 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case FunctionDef_kind: @@ -4451,6 +4447,7 @@ ast2obj_stmt(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -4468,7 +4465,7 @@ ast2obj_expr(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case BoolOp_kind: @@ -4934,6 +4931,7 @@ ast2obj_expr(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5045,7 +5043,7 @@ ast2obj_comprehension(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->comprehension_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5073,6 +5071,7 @@ ast2obj_comprehension(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5090,7 +5089,7 @@ ast2obj_excepthandler(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case ExceptHandler_kind: @@ -5138,6 +5137,7 @@ ast2obj_excepthandler(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5155,7 +5155,7 @@ ast2obj_arguments(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->arguments_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5198,6 +5198,7 @@ ast2obj_arguments(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5215,7 +5216,7 @@ ast2obj_arg(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->arg_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5258,6 +5259,7 @@ ast2obj_arg(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5275,7 +5277,7 @@ ast2obj_keyword(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->keyword_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5313,6 +5315,7 @@ ast2obj_keyword(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5330,7 +5333,7 @@ ast2obj_alias(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->alias_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5368,6 +5371,7 @@ ast2obj_alias(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5385,7 +5389,7 @@ ast2obj_withitem(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->withitem_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5403,6 +5407,7 @@ ast2obj_withitem(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5420,7 +5425,7 @@ ast2obj_match_case(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } tp = (PyTypeObject *)state->match_case_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -5443,6 +5448,7 @@ ast2obj_match_case(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5460,7 +5466,7 @@ ast2obj_pattern(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case MatchValue_kind: @@ -5604,6 +5610,7 @@ ast2obj_pattern(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5621,7 +5628,7 @@ ast2obj_type_ignore(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case TypeIgnore_kind: @@ -5643,6 +5650,7 @@ ast2obj_type_ignore(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5660,7 +5668,7 @@ ast2obj_type_param(struct ast_state *state, void* _o) if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during ast construction"); - return 0; + return NULL; } switch (o->kind) { case TypeVar_kind: @@ -5722,6 +5730,7 @@ ast2obj_type_param(struct ast_state *state, void* _o) state->recursion_depth--; return result; failed: + state->recursion_depth--; Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -5743,19 +5752,19 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) tp = state->Module_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_stmt_seq* body; asdl_type_ignore_seq* type_ignores; if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -5788,12 +5797,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_ignores, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -5832,18 +5841,18 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) tp = state->Interactive_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_stmt_seq* body; if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -5882,17 +5891,17 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) tp = state->Expression_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty body; if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Expression"); - return 1; + return -1; } else { int res; @@ -5911,19 +5920,19 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) tp = state->FunctionType_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* argtypes; expr_ty returns; if (PyObject_GetOptionalAttr(obj, state->argtypes, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -5956,11 +5965,11 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->returns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType"); - return 1; + return -1; } else { int res; @@ -5980,7 +5989,7 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -6001,11 +6010,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 0; } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt"); - return 1; + return -1; } else { int res; @@ -6018,11 +6027,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt"); - return 1; + return -1; } else { int res; @@ -6035,7 +6044,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6052,7 +6061,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6071,7 +6080,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->FunctionDef_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; @@ -6083,11 +6092,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_type_param_seq* type_params; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef"); - return 1; + return -1; } else { int res; @@ -6100,11 +6109,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->args, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef"); - return 1; + return -1; } else { int res; @@ -6117,12 +6126,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6155,12 +6164,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->decorator_list, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6193,7 +6202,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->returns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6210,7 +6219,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6227,12 +6236,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_params, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6274,7 +6283,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->AsyncFunctionDef_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; @@ -6286,11 +6295,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_type_param_seq* type_params; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef"); - return 1; + return -1; } else { int res; @@ -6303,11 +6312,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->args, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef"); - return 1; + return -1; } else { int res; @@ -6320,12 +6329,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6358,12 +6367,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->decorator_list, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6396,7 +6405,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->returns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6413,7 +6422,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6430,12 +6439,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_params, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6477,7 +6486,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->ClassDef_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; @@ -6488,11 +6497,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_type_param_seq* type_params; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); - return 1; + return -1; } else { int res; @@ -6505,12 +6514,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->bases, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6543,12 +6552,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->keywords, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6581,12 +6590,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6619,12 +6628,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->decorator_list, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6657,12 +6666,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_params, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6703,13 +6712,13 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Return_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6733,18 +6742,18 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Delete_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* targets; if (PyObject_GetOptionalAttr(obj, state->targets, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6784,7 +6793,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Assign_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* targets; @@ -6792,12 +6801,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* string type_comment; if (PyObject_GetOptionalAttr(obj, state->targets, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6830,11 +6839,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign"); - return 1; + return -1; } else { int res; @@ -6847,7 +6856,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -6871,7 +6880,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->TypeAlias_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty name; @@ -6879,11 +6888,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* expr_ty value; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeAlias"); - return 1; + return -1; } else { int res; @@ -6896,12 +6905,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_params, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -6934,11 +6943,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from TypeAlias"); - return 1; + return -1; } else { int res; @@ -6958,7 +6967,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->AugAssign_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty target; @@ -6966,11 +6975,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* expr_ty value; if (PyObject_GetOptionalAttr(obj, state->target, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign"); - return 1; + return -1; } else { int res; @@ -6983,11 +6992,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->op, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign"); - return 1; + return -1; } else { int res; @@ -7000,11 +7009,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from AugAssign"); - return 1; + return -1; } else { int res; @@ -7024,7 +7033,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->AnnAssign_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty target; @@ -7033,11 +7042,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* int simple; if (PyObject_GetOptionalAttr(obj, state->target, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign"); - return 1; + return -1; } else { int res; @@ -7050,11 +7059,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->annotation, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign"); - return 1; + return -1; } else { int res; @@ -7067,7 +7076,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7084,11 +7093,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->simple, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign"); - return 1; + return -1; } else { int res; @@ -7108,7 +7117,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->For_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty target; @@ -7118,11 +7127,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* string type_comment; if (PyObject_GetOptionalAttr(obj, state->target, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For"); - return 1; + return -1; } else { int res; @@ -7135,11 +7144,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->iter, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For"); - return 1; + return -1; } else { int res; @@ -7152,12 +7161,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7190,12 +7199,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7228,7 +7237,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7252,7 +7261,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->AsyncFor_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty target; @@ -7262,11 +7271,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* string type_comment; if (PyObject_GetOptionalAttr(obj, state->target, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor"); - return 1; + return -1; } else { int res; @@ -7279,11 +7288,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->iter, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor"); - return 1; + return -1; } else { int res; @@ -7296,12 +7305,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7334,12 +7343,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7372,7 +7381,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7397,7 +7406,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->While_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty test; @@ -7405,11 +7414,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_stmt_seq* orelse; if (PyObject_GetOptionalAttr(obj, state->test, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While"); - return 1; + return -1; } else { int res; @@ -7422,12 +7431,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7460,12 +7469,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7505,7 +7514,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->If_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty test; @@ -7513,11 +7522,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_stmt_seq* orelse; if (PyObject_GetOptionalAttr(obj, state->test, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If"); - return 1; + return -1; } else { int res; @@ -7530,12 +7539,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7568,12 +7577,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7613,7 +7622,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->With_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_withitem_seq* items; @@ -7621,12 +7630,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* string type_comment; if (PyObject_GetOptionalAttr(obj, state->items, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7659,12 +7668,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7697,7 +7706,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7721,7 +7730,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->AsyncWith_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_withitem_seq* items; @@ -7729,12 +7738,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* string type_comment; if (PyObject_GetOptionalAttr(obj, state->items, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7767,12 +7776,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7805,7 +7814,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7829,18 +7838,18 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Match_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty subject; asdl_match_case_seq* cases; if (PyObject_GetOptionalAttr(obj, state->subject, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"subject\" missing from Match"); - return 1; + return -1; } else { int res; @@ -7853,12 +7862,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->cases, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7898,14 +7907,14 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Raise_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty exc; expr_ty cause; if (PyObject_GetOptionalAttr(obj, state->exc, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7922,7 +7931,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->cause, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -7946,7 +7955,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Try_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_stmt_seq* body; @@ -7955,12 +7964,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_stmt_seq* finalbody; if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -7993,12 +8002,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->handlers, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8031,12 +8040,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8069,12 +8078,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->finalbody, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8114,7 +8123,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->TryStar_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_stmt_seq* body; @@ -8123,12 +8132,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_stmt_seq* finalbody; if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8161,12 +8170,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->handlers, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8199,12 +8208,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8237,12 +8246,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->finalbody, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8282,18 +8291,18 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Assert_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty test; expr_ty msg; if (PyObject_GetOptionalAttr(obj, state->test, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert"); - return 1; + return -1; } else { int res; @@ -8306,7 +8315,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->msg, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -8330,18 +8339,18 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Import_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_alias_seq* names; if (PyObject_GetOptionalAttr(obj, state->names, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8381,7 +8390,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->ImportFrom_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier module; @@ -8389,7 +8398,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* int level; if (PyObject_GetOptionalAttr(obj, state->module, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -8406,12 +8415,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->names, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8444,7 +8453,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->level, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -8468,18 +8477,18 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Global_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_identifier_seq* names; if (PyObject_GetOptionalAttr(obj, state->names, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8519,18 +8528,18 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Nonlocal_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_identifier_seq* names; if (PyObject_GetOptionalAttr(obj, state->names, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8570,17 +8579,17 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Expr_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Expr"); - return 1; + return -1; } else { int res; @@ -8600,7 +8609,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Pass_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { @@ -8612,7 +8621,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Break_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { @@ -8624,7 +8633,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* tp = state->Continue_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { @@ -8637,7 +8646,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -8658,11 +8667,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 0; } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr"); - return 1; + return -1; } else { int res; @@ -8675,11 +8684,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr"); - return 1; + return -1; } else { int res; @@ -8692,7 +8701,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -8709,7 +8718,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -8728,18 +8737,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->BoolOp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { boolop_ty op; asdl_expr_seq* values; if (PyObject_GetOptionalAttr(obj, state->op, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp"); - return 1; + return -1; } else { int res; @@ -8752,12 +8761,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->values, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -8797,18 +8806,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->NamedExpr_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty target; expr_ty value; if (PyObject_GetOptionalAttr(obj, state->target, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr"); - return 1; + return -1; } else { int res; @@ -8821,11 +8830,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr"); - return 1; + return -1; } else { int res; @@ -8845,7 +8854,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->BinOp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty left; @@ -8853,11 +8862,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* expr_ty right; if (PyObject_GetOptionalAttr(obj, state->left, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp"); - return 1; + return -1; } else { int res; @@ -8870,11 +8879,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->op, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp"); - return 1; + return -1; } else { int res; @@ -8887,11 +8896,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->right, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"right\" missing from BinOp"); - return 1; + return -1; } else { int res; @@ -8911,18 +8920,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->UnaryOp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { unaryop_ty op; expr_ty operand; if (PyObject_GetOptionalAttr(obj, state->op, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp"); - return 1; + return -1; } else { int res; @@ -8935,11 +8944,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->operand, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"operand\" missing from UnaryOp"); - return 1; + return -1; } else { int res; @@ -8959,18 +8968,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Lambda_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { arguments_ty args; expr_ty body; if (PyObject_GetOptionalAttr(obj, state->args, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda"); - return 1; + return -1; } else { int res; @@ -8983,11 +8992,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Lambda"); - return 1; + return -1; } else { int res; @@ -9007,7 +9016,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->IfExp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty test; @@ -9015,11 +9024,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* expr_ty orelse; if (PyObject_GetOptionalAttr(obj, state->test, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp"); - return 1; + return -1; } else { int res; @@ -9032,11 +9041,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp"); - return 1; + return -1; } else { int res; @@ -9049,11 +9058,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->orelse, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from IfExp"); - return 1; + return -1; } else { int res; @@ -9073,19 +9082,19 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Dict_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* keys; asdl_expr_seq* values; if (PyObject_GetOptionalAttr(obj, state->keys, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9118,12 +9127,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->values, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9163,18 +9172,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Set_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* elts; if (PyObject_GetOptionalAttr(obj, state->elts, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9214,18 +9223,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->ListComp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty elt; asdl_comprehension_seq* generators; if (PyObject_GetOptionalAttr(obj, state->elt, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp"); - return 1; + return -1; } else { int res; @@ -9238,12 +9247,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->generators, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9283,18 +9292,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->SetComp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty elt; asdl_comprehension_seq* generators; if (PyObject_GetOptionalAttr(obj, state->elt, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp"); - return 1; + return -1; } else { int res; @@ -9307,12 +9316,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->generators, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9352,7 +9361,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->DictComp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty key; @@ -9360,11 +9369,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* asdl_comprehension_seq* generators; if (PyObject_GetOptionalAttr(obj, state->key, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp"); - return 1; + return -1; } else { int res; @@ -9377,11 +9386,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp"); - return 1; + return -1; } else { int res; @@ -9394,12 +9403,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->generators, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9439,18 +9448,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->GeneratorExp_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty elt; asdl_comprehension_seq* generators; if (PyObject_GetOptionalAttr(obj, state->elt, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp"); - return 1; + return -1; } else { int res; @@ -9463,12 +9472,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->generators, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9508,17 +9517,17 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Await_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await"); - return 1; + return -1; } else { int res; @@ -9538,13 +9547,13 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Yield_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -9568,17 +9577,17 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->YieldFrom_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom"); - return 1; + return -1; } else { int res; @@ -9598,7 +9607,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Compare_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty left; @@ -9606,11 +9615,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* asdl_expr_seq* comparators; if (PyObject_GetOptionalAttr(obj, state->left, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare"); - return 1; + return -1; } else { int res; @@ -9623,12 +9632,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ops, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9661,12 +9670,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->comparators, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9706,7 +9715,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Call_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty func; @@ -9714,11 +9723,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* asdl_keyword_seq* keywords; if (PyObject_GetOptionalAttr(obj, state->func, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call"); - return 1; + return -1; } else { int res; @@ -9731,12 +9740,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->args, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9769,12 +9778,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->keywords, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9814,7 +9823,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->FormattedValue_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; @@ -9822,11 +9831,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* expr_ty format_spec; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue"); - return 1; + return -1; } else { int res; @@ -9839,11 +9848,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->conversion, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"conversion\" missing from FormattedValue"); - return 1; + return -1; } else { int res; @@ -9856,7 +9865,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->format_spec, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -9881,18 +9890,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->JoinedStr_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* values; if (PyObject_GetOptionalAttr(obj, state->values, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -9932,18 +9941,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Constant_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { constant value; string kind; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Constant"); - return 1; + return -1; } else { int res; @@ -9956,7 +9965,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->kind, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -9980,7 +9989,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Attribute_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; @@ -9988,11 +9997,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* expr_context_ty ctx; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute"); - return 1; + return -1; } else { int res; @@ -10005,11 +10014,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->attr, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute"); - return 1; + return -1; } else { int res; @@ -10022,11 +10031,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ctx, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Attribute"); - return 1; + return -1; } else { int res; @@ -10046,7 +10055,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Subscript_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; @@ -10054,11 +10063,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* expr_context_ty ctx; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript"); - return 1; + return -1; } else { int res; @@ -10071,11 +10080,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->slice, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript"); - return 1; + return -1; } else { int res; @@ -10088,11 +10097,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ctx, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Subscript"); - return 1; + return -1; } else { int res; @@ -10112,18 +10121,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Starred_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; expr_context_ty ctx; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred"); - return 1; + return -1; } else { int res; @@ -10136,11 +10145,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ctx, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred"); - return 1; + return -1; } else { int res; @@ -10160,18 +10169,18 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Name_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier id; expr_context_ty ctx; if (PyObject_GetOptionalAttr(obj, state->id, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name"); - return 1; + return -1; } else { int res; @@ -10184,11 +10193,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ctx, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Name"); - return 1; + return -1; } else { int res; @@ -10208,19 +10217,19 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->List_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* elts; expr_context_ty ctx; if (PyObject_GetOptionalAttr(obj, state->elts, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -10253,11 +10262,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ctx, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from List"); - return 1; + return -1; } else { int res; @@ -10277,19 +10286,19 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Tuple_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* elts; expr_context_ty ctx; if (PyObject_GetOptionalAttr(obj, state->elts, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -10322,11 +10331,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ctx, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Tuple"); - return 1; + return -1; } else { int res; @@ -10346,7 +10355,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* tp = state->Slice_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty lower; @@ -10354,7 +10363,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* expr_ty step; if (PyObject_GetOptionalAttr(obj, state->lower, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10371,7 +10380,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->upper, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10388,7 +10397,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->step, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10413,7 +10422,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -10424,7 +10433,7 @@ obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* isinstance = PyObject_IsInstance(obj, state->Load_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Load; @@ -10432,7 +10441,7 @@ obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* } isinstance = PyObject_IsInstance(obj, state->Store_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Store; @@ -10440,7 +10449,7 @@ obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* } isinstance = PyObject_IsInstance(obj, state->Del_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Del; @@ -10448,7 +10457,7 @@ obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty* } PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj); - return 1; + return -1; } int @@ -10459,7 +10468,7 @@ obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* out, PyArena* isinstance = PyObject_IsInstance(obj, state->And_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = And; @@ -10467,7 +10476,7 @@ obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->Or_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Or; @@ -10475,7 +10484,7 @@ obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* out, PyArena* } PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %R", obj); - return 1; + return -1; } int @@ -10486,7 +10495,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, isinstance = PyObject_IsInstance(obj, state->Add_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Add; @@ -10494,7 +10503,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->Sub_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Sub; @@ -10502,7 +10511,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->Mult_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Mult; @@ -10510,7 +10519,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->MatMult_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = MatMult; @@ -10518,7 +10527,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->Div_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Div; @@ -10526,7 +10535,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->Mod_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Mod; @@ -10534,7 +10543,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->Pow_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Pow; @@ -10542,7 +10551,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->LShift_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = LShift; @@ -10550,7 +10559,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->RShift_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = RShift; @@ -10558,7 +10567,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->BitOr_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = BitOr; @@ -10566,7 +10575,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->BitXor_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = BitXor; @@ -10574,7 +10583,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->BitAnd_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = BitAnd; @@ -10582,7 +10591,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } isinstance = PyObject_IsInstance(obj, state->FloorDiv_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = FloorDiv; @@ -10590,7 +10599,7 @@ obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out, } PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %R", obj); - return 1; + return -1; } int @@ -10601,7 +10610,7 @@ obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, isinstance = PyObject_IsInstance(obj, state->Invert_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Invert; @@ -10609,7 +10618,7 @@ obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, } isinstance = PyObject_IsInstance(obj, state->Not_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Not; @@ -10617,7 +10626,7 @@ obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, } isinstance = PyObject_IsInstance(obj, state->UAdd_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = UAdd; @@ -10625,7 +10634,7 @@ obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, } isinstance = PyObject_IsInstance(obj, state->USub_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = USub; @@ -10633,7 +10642,7 @@ obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out, } PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %R", obj); - return 1; + return -1; } int @@ -10644,7 +10653,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* isinstance = PyObject_IsInstance(obj, state->Eq_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Eq; @@ -10652,7 +10661,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->NotEq_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = NotEq; @@ -10660,7 +10669,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->Lt_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Lt; @@ -10668,7 +10677,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->LtE_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = LtE; @@ -10676,7 +10685,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->Gt_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Gt; @@ -10684,7 +10693,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->GtE_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = GtE; @@ -10692,7 +10701,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->Is_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = Is; @@ -10700,7 +10709,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->IsNot_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = IsNot; @@ -10708,7 +10717,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->In_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = In; @@ -10716,7 +10725,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } isinstance = PyObject_IsInstance(obj, state->NotIn_type); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { *out = NotIn; @@ -10724,7 +10733,7 @@ obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena* } PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %R", obj); - return 1; + return -1; } int @@ -10738,11 +10747,11 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* int is_async; if (PyObject_GetOptionalAttr(obj, state->target, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension"); - return 1; + return -1; } else { int res; @@ -10755,11 +10764,11 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->iter, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension"); - return 1; + return -1; } else { int res; @@ -10772,12 +10781,12 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->ifs, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -10810,11 +10819,11 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->is_async, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"is_async\" missing from comprehension"); - return 1; + return -1; } else { int res; @@ -10831,7 +10840,7 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -10852,11 +10861,11 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* return 0; } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler"); - return 1; + return -1; } else { int res; @@ -10869,11 +10878,11 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler"); - return 1; + return -1; } else { int res; @@ -10886,7 +10895,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10903,7 +10912,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10922,7 +10931,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* tp = state->ExceptHandler_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty type; @@ -10930,7 +10939,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* asdl_stmt_seq* body; if (PyObject_GetOptionalAttr(obj, state->type, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10947,7 +10956,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -10964,12 +10973,12 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11010,7 +11019,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11027,12 +11036,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, asdl_expr_seq* defaults; if (PyObject_GetOptionalAttr(obj, state->posonlyargs, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11065,12 +11074,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->args, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11103,7 +11112,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->vararg, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11120,12 +11129,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->kwonlyargs, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11158,12 +11167,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->kw_defaults, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11196,7 +11205,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->kwarg, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11213,12 +11222,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->defaults, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11256,7 +11265,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11272,11 +11281,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) int end_col_offset; if (PyObject_GetOptionalAttr(obj, state->arg, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg"); - return 1; + return -1; } else { int res; @@ -11289,7 +11298,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->annotation, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11306,7 +11315,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->type_comment, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11323,11 +11332,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg"); - return 1; + return -1; } else { int res; @@ -11340,11 +11349,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg"); - return 1; + return -1; } else { int res; @@ -11357,7 +11366,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11374,7 +11383,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11396,7 +11405,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11412,7 +11421,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, int end_col_offset; if (PyObject_GetOptionalAttr(obj, state->arg, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11429,11 +11438,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from keyword"); - return 1; + return -1; } else { int res; @@ -11446,11 +11455,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from keyword"); - return 1; + return -1; } else { int res; @@ -11463,11 +11472,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from keyword"); - return 1; + return -1; } else { int res; @@ -11480,7 +11489,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11497,7 +11506,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11519,7 +11528,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11535,11 +11544,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* int end_col_offset; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias"); - return 1; + return -1; } else { int res; @@ -11552,7 +11561,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->asname, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11569,11 +11578,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from alias"); - return 1; + return -1; } else { int res; @@ -11586,11 +11595,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from alias"); - return 1; + return -1; } else { int res; @@ -11603,7 +11612,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11620,7 +11629,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11642,7 +11651,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11654,11 +11663,11 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, expr_ty optional_vars; if (PyObject_GetOptionalAttr(obj, state->context_expr, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem"); - return 1; + return -1; } else { int res; @@ -11671,7 +11680,7 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->optional_vars, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11692,7 +11701,7 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11705,11 +11714,11 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, asdl_stmt_seq* body; if (PyObject_GetOptionalAttr(obj, state->pattern, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"pattern\" missing from match_case"); - return 1; + return -1; } else { int res; @@ -11722,7 +11731,7 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->guard, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -11739,12 +11748,12 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->body, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11781,7 +11790,7 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, return 0; failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -11802,11 +11811,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 0; } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from pattern"); - return 1; + return -1; } else { int res; @@ -11819,11 +11828,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from pattern"); - return 1; + return -1; } else { int res; @@ -11836,11 +11845,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"end_lineno\" missing from pattern"); - return 1; + return -1; } else { int res; @@ -11853,11 +11862,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"end_col_offset\" missing from pattern"); - return 1; + return -1; } else { int res; @@ -11872,17 +11881,17 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchValue_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchValue"); - return 1; + return -1; } else { int res; @@ -11902,17 +11911,17 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchSingleton_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { constant value; if (PyObject_GetOptionalAttr(obj, state->value, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchSingleton"); - return 1; + return -1; } else { int res; @@ -11932,18 +11941,18 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchSequence_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_pattern_seq* patterns; if (PyObject_GetOptionalAttr(obj, state->patterns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -11983,7 +11992,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchMapping_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_expr_seq* keys; @@ -11991,12 +12000,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, identifier rest; if (PyObject_GetOptionalAttr(obj, state->keys, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -12029,12 +12038,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->patterns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -12067,7 +12076,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->rest, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -12091,7 +12100,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchClass_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { expr_ty cls; @@ -12100,11 +12109,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, asdl_pattern_seq* kwd_patterns; if (PyObject_GetOptionalAttr(obj, state->cls, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"cls\" missing from MatchClass"); - return 1; + return -1; } else { int res; @@ -12117,12 +12126,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->patterns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -12155,12 +12164,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->kwd_attrs, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -12193,12 +12202,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->kwd_patterns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -12239,13 +12248,13 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchStar_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -12269,14 +12278,14 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchAs_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { pattern_ty pattern; identifier name; if (PyObject_GetOptionalAttr(obj, state->pattern, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -12293,7 +12302,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -12317,18 +12326,18 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, tp = state->MatchOr_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { asdl_pattern_seq* patterns; if (PyObject_GetOptionalAttr(obj, state->patterns, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { tmp = PyList_New(0); if (tmp == NULL) { - return 1; + return -1; } } { @@ -12369,7 +12378,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, PyErr_Format(PyExc_TypeError, "expected some sort of pattern, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -12388,18 +12397,18 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* tp = state->TypeIgnore_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { int lineno; string tag; if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore"); - return 1; + return -1; } else { int res; @@ -12412,11 +12421,11 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->tag, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore"); - return 1; + return -1; } else { int res; @@ -12436,7 +12445,7 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } int @@ -12457,11 +12466,11 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, return 0; } if (PyObject_GetOptionalAttr(obj, state->lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from type_param"); - return 1; + return -1; } else { int res; @@ -12474,11 +12483,11 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from type_param"); - return 1; + return -1; } else { int res; @@ -12491,11 +12500,11 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_lineno, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"end_lineno\" missing from type_param"); - return 1; + return -1; } else { int res; @@ -12508,11 +12517,11 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->end_col_offset, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"end_col_offset\" missing from type_param"); - return 1; + return -1; } else { int res; @@ -12527,18 +12536,18 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, tp = state->TypeVar_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; expr_ty bound; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVar"); - return 1; + return -1; } else { int res; @@ -12551,7 +12560,7 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, Py_CLEAR(tmp); } if (PyObject_GetOptionalAttr(obj, state->bound, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); @@ -12575,17 +12584,17 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, tp = state->ParamSpec_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ParamSpec"); - return 1; + return -1; } else { int res; @@ -12605,17 +12614,17 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, tp = state->TypeVarTuple_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { - return 1; + return -1; } if (isinstance) { identifier name; if (PyObject_GetOptionalAttr(obj, state->name, &tmp) < 0) { - return 1; + return -1; } if (tmp == NULL) { PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVarTuple"); - return 1; + return -1; } else { int res; @@ -12636,7 +12645,7 @@ obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, PyErr_Format(PyExc_TypeError, "expected some sort of type_param, but got %R", obj); failed: Py_XDECREF(tmp); - return 1; + return -1; } @@ -13079,7 +13088,7 @@ PyObject* PyAST_mod2obj(mod_ty t) int COMPILER_STACK_FRAME_SCALE = 2; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { - return 0; + return NULL; } state->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; @@ -13093,7 +13102,7 @@ PyObject* PyAST_mod2obj(mod_ty t) PyErr_Format(PyExc_SystemError, "AST constructor recursion depth mismatch (before=%d, after=%d)", starting_recursion_depth, state->recursion_depth); - return 0; + return NULL; } return result; } diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c index 1b021069c5e10b..a7891709b3b44a 100644 --- a/Python/Python-tokenize.c +++ b/Python/Python-tokenize.c @@ -1,7 +1,8 @@ #include "Python.h" #include "errcode.h" -#include "../Parser/tokenizer.h" -#include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() +#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() static struct PyModuleDef _tokenizemodule; @@ -224,7 +225,7 @@ tokenizeriter_next(tokenizeriterobject *it) col_offset = _PyPegen_byte_offset_to_character_offset(line, token.start - line_start); } if (token.end != NULL && token.end >= it->tok->line_start) { - end_col_offset = _PyPegen_byte_offset_to_character_offset(line, token.end - it->tok->line_start); + end_col_offset = _PyPegen_byte_offset_to_character_offset_raw(it->tok->line_start, token.end - it->tok->line_start); } if (it->tok->tok_extra_tokens) { diff --git a/Python/_warnings.c b/Python/_warnings.c index 4b7fb888247145..d4765032824e56 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -425,15 +425,15 @@ already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key, Py_DECREF(version_obj); } else { - already_warned = PyDict_GetItemWithError(registry, key); + if (PyDict_GetItemRef(registry, key, &already_warned) < 0) { + return -1; + } if (already_warned != NULL) { int rc = PyObject_IsTrue(already_warned); + Py_DECREF(already_warned); if (rc != 0) return rc; } - else if (PyErr_Occurred()) { - return -1; - } } /* This warning wasn't found in the registry, set it. */ diff --git a/Python/abstract_interp_cases.c.h b/Python/abstract_interp_cases.c.h index 61b1db9e5a1543..96ac0aabd1b59f 100644 --- a/Python/abstract_interp_cases.c.h +++ b/Python/abstract_interp_cases.c.h @@ -38,7 +38,7 @@ break; } - case TO_BOOL: { + case _TO_BOOL: { PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); break; } @@ -113,7 +113,7 @@ break; } - case BINARY_SUBSCR: { + case _BINARY_SUBSCR: { STACK_SHRINK(1); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); break; @@ -164,7 +164,7 @@ break; } - case STORE_SUBSCR: { + case _STORE_SUBSCR: { STACK_SHRINK(3); break; } @@ -242,7 +242,7 @@ break; } - case UNPACK_SEQUENCE: { + case _UNPACK_SEQUENCE: { STACK_SHRINK(1); STACK_GROW(oparg); break; @@ -272,7 +272,7 @@ break; } - case STORE_ATTR: { + case _STORE_ATTR: { STACK_SHRINK(2); break; } @@ -308,7 +308,7 @@ break; } - case LOAD_GLOBAL: { + 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); @@ -344,6 +344,10 @@ break; } + case MAKE_CELL: { + break; + } + case DELETE_DEREF: { break; } @@ -452,7 +456,7 @@ break; } - case LOAD_ATTR: { + 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); @@ -474,6 +478,28 @@ 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); @@ -481,16 +507,23 @@ break; } - case _GUARD_DORV_VALUES: { + case _CHECK_ATTR_CLASS: { break; } - case _STORE_ATTR_INSTANCE_VALUE: { - STACK_SHRINK(2); + 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_TYPE_VERSION_STORE: { + case _GUARD_DORV_VALUES: { + break; + } + + case _STORE_ATTR_INSTANCE_VALUE: { + STACK_SHRINK(2); break; } @@ -499,7 +532,7 @@ break; } - case COMPARE_OP: { + case _COMPARE_OP: { STACK_SHRINK(1); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); break; @@ -591,13 +624,17 @@ break; } + case _FOR_ITER_TIER_TWO: { + STACK_GROW(1); + 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); + case _GUARD_NOT_EXHAUSTED_LIST: { break; } @@ -611,9 +648,7 @@ break; } - case _IS_ITER_EXHAUSTED_TUPLE: { - STACK_GROW(1); - PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + case _GUARD_NOT_EXHAUSTED_TUPLE: { break; } @@ -627,14 +662,26 @@ break; } - case _IS_ITER_EXHAUSTED_RANGE: { + case _GUARD_NOT_EXHAUSTED_RANGE: { + break; + } + + case _ITER_NEXT_RANGE: { STACK_GROW(1); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); break; } - case _ITER_NEXT_RANGE: { + case BEFORE_ASYNC_WITH: { 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 BEFORE_WITH: { + STACK_GROW(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-2)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); break; } @@ -674,6 +721,29 @@ 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; } @@ -704,7 +774,8 @@ } case _PUSH_FRAME: { - PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); + STACK_SHRINK(1); + PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(0)), true); break; } @@ -838,7 +909,7 @@ break; } - case BINARY_OP: { + case _BINARY_OP: { STACK_SHRINK(1); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); break; @@ -850,12 +921,22 @@ break; } - case _POP_JUMP_IF_FALSE: { + case _GUARD_IS_TRUE_POP: { STACK_SHRINK(1); break; } - case _POP_JUMP_IF_TRUE: { + case _GUARD_IS_FALSE_POP: { + STACK_SHRINK(1); + break; + } + + case _GUARD_IS_NONE_POP: { + STACK_SHRINK(1); + break; + } + + case _GUARD_IS_NOT_NONE_POP: { STACK_SHRINK(1); break; } @@ -868,7 +949,7 @@ break; } - case _SAVE_CURRENT_IP: { + case _SAVE_RETURN_OFFSET: { break; } @@ -880,3 +961,7 @@ PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1 - oparg)), true); break; } + + case _CHECK_VALIDITY: { + break; + } diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 41f48eba08afc4..04d7ae6eaafbc0 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -142,15 +142,6 @@ check_complexity(PyObject *obj, Py_ssize_t limit) } return limit; } - else if (PyFrozenSet_Check(obj)) { - Py_ssize_t i = 0; - PyObject *item; - Py_hash_t hash; - limit -= PySet_GET_SIZE(obj); - while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) { - limit = check_complexity(item, limit); - } - } return limit; } @@ -174,9 +165,8 @@ safe_multiply(PyObject *v, PyObject *w) return NULL; } } - else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) { - Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) : - PySet_GET_SIZE(w); + else if (PyLong_Check(v) && PyTuple_Check(w)) { + Py_ssize_t size = PyTuple_GET_SIZE(w); if (size) { long n = PyLong_AsLong(v); if (n < 0 || n > MAX_COLLECTION_SIZE / size) { @@ -198,8 +188,7 @@ safe_multiply(PyObject *v, PyObject *w) } } else if (PyLong_Check(w) && - (PyTuple_Check(v) || PyFrozenSet_Check(v) || - PyUnicode_Check(v) || PyBytes_Check(v))) + (PyTuple_Check(v) || PyUnicode_Check(v) || PyBytes_Check(v))) { return safe_multiply(w, v); } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 69056bf23f4058..e54d5cbacdc96f 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -5,7 +5,6 @@ #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() @@ -17,6 +16,11 @@ #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) { @@ -136,18 +140,16 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, goto error; } - meta = _PyDict_GetItemWithError(mkw, &_Py_ID(metaclass)); + if (PyDict_GetItemRef(mkw, &_Py_ID(metaclass), &meta) < 0) { + goto error; + } if (meta != NULL) { - Py_INCREF(meta); if (PyDict_DelItem(mkw, &_Py_ID(metaclass)) < 0) { goto error; } /* metaclass is explicitly given, check if it's indeed a class */ isclass = PyType_Check(meta); } - else if (PyErr_Occurred()) { - goto error; - } } if (meta == NULL) { /* if there are no bases, use type: */ @@ -477,6 +479,7 @@ builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb PyDoc_STRVAR(breakpoint_doc, "breakpoint(*args, **kws)\n\ +--\n\ \n\ Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\ whatever arguments are passed.\n\ @@ -621,7 +624,8 @@ static PyMethodDef filter_methods[] = { }; PyDoc_STRVAR(filter_doc, -"filter(function or None, iterable) --> filter object\n\ +"filter(function, iterable, /)\n\ +--\n\ \n\ Return an iterator yielding those items of iterable for which function(item)\n\ is true. If function is None, return the items that are true."); @@ -1444,7 +1448,8 @@ static PyMethodDef map_methods[] = { PyDoc_STRVAR(map_doc, -"map(func, *iterables) --> map object\n\ +"map(function, /, *iterables)\n\ +--\n\ \n\ Make an iterator that computes the function using arguments from\n\ each of the iterables. Stops when the shortest iterable is exhausted."); @@ -1761,35 +1766,27 @@ builtin_locals_impl(PyObject *module) static PyObject * -min_max(PyObject *args, PyObject *kwds, int op) +min_max(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, int op) { - PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL; - PyObject *emptytuple, *defaultval = NULL; - static char *kwlist[] = {"key", "default", NULL}; - const char *name = op == Py_LT ? "min" : "max"; - const int positional = PyTuple_Size(args) > 1; - int ret; + PyObject *it = NULL, *item, *val, *maxitem, *maxval, *keyfunc=NULL; + PyObject *defaultval = NULL; + static const char * const keywords[] = {"key", "default", NULL}; + static _PyArg_Parser _parser_min = {"|$OO:min", keywords, 0}; + static _PyArg_Parser _parser_max = {"|$OO:max", keywords, 0}; + const char *name = (op == Py_LT) ? "min" : "max"; + _PyArg_Parser *_parser = (op == Py_LT) ? &_parser_min : &_parser_max; - if (positional) { - v = args; - } - else if (!PyArg_UnpackTuple(args, name, 1, 1, &v)) { - if (PyExceptionClass_Check(PyExc_TypeError)) { - PyErr_Format(PyExc_TypeError, "%s expected at least 1 argument, got 0", name); - } + if (nargs == 0) { + PyErr_Format(PyExc_TypeError, "%s expected at least 1 argument, got 0", name); return NULL; } - emptytuple = PyTuple_New(0); - if (emptytuple == NULL) - return NULL; - ret = PyArg_ParseTupleAndKeywords(emptytuple, kwds, - (op == Py_LT) ? "|$OO:min" : "|$OO:max", - kwlist, &keyfunc, &defaultval); - Py_DECREF(emptytuple); - if (!ret) + if (kwnames != NULL && !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, _parser, + &keyfunc, &defaultval)) { return NULL; + } + const int positional = nargs > 1; // False iff nargs == 1 if (positional && defaultval != NULL) { PyErr_Format(PyExc_TypeError, "Cannot specify a default for %s() with multiple " @@ -1797,9 +1794,11 @@ min_max(PyObject *args, PyObject *kwds, int op) return NULL; } - it = PyObject_GetIter(v); - if (it == NULL) { - return NULL; + if (!positional) { + it = PyObject_GetIter(args[0]); + if (it == NULL) { + return NULL; + } } if (keyfunc == Py_None) { @@ -1808,7 +1807,24 @@ min_max(PyObject *args, PyObject *kwds, int op) maxitem = NULL; /* the result */ maxval = NULL; /* the value associated with the result */ - while (( item = PyIter_Next(it) )) { + while (1) { + if (it == NULL) { + if (nargs-- <= 0) { + break; + } + item = *args++; + Py_INCREF(item); + } + else { + item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) { + goto Fail_it; + } + break; + } + } + /* get the value from the key function */ if (keyfunc != NULL) { val = PyObject_CallOneArg(keyfunc, item); @@ -1842,8 +1858,6 @@ min_max(PyObject *args, PyObject *kwds, int op) } } } - if (PyErr_Occurred()) - goto Fail_it; if (maxval == NULL) { assert(maxitem == NULL); if (defaultval != NULL) { @@ -1855,7 +1869,7 @@ min_max(PyObject *args, PyObject *kwds, int op) } else Py_DECREF(maxval); - Py_DECREF(it); + Py_XDECREF(it); return maxitem; Fail_it_item_and_val: @@ -1865,15 +1879,15 @@ min_max(PyObject *args, PyObject *kwds, int op) Fail_it: Py_XDECREF(maxval); Py_XDECREF(maxitem); - Py_DECREF(it); + Py_XDECREF(it); return NULL; } /* AC: cannot convert yet, waiting for *args support */ static PyObject * -builtin_min(PyObject *self, PyObject *args, PyObject *kwds) +builtin_min(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return min_max(args, kwds, Py_LT); + return min_max(args, nargs, kwnames, Py_LT); } PyDoc_STRVAR(min_doc, @@ -1883,14 +1897,14 @@ min(arg1, arg2, *args, *[, key=func]) -> value\n\ With a single iterable argument, return its smallest item. The\n\ default keyword-only argument specifies an object to return if\n\ the provided iterable is empty.\n\ -With two or more arguments, return the smallest argument."); +With two or more positional arguments, return the smallest argument."); /* AC: cannot convert yet, waiting for *args support */ static PyObject * -builtin_max(PyObject *self, PyObject *args, PyObject *kwds) +builtin_max(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return min_max(args, kwds, Py_GT); + return min_max(args, nargs, kwnames, Py_GT); } PyDoc_STRVAR(max_doc, @@ -1900,7 +1914,7 @@ max(arg1, arg2, *args, *[, key=func]) -> value\n\ With a single iterable argument, return its biggest item. The\n\ default keyword-only argument specifies an object to return if\n\ the provided iterable is empty.\n\ -With two or more arguments, return the largest argument."); +With two or more positional arguments, return the largest argument."); /*[clinic input] @@ -2257,6 +2271,11 @@ builtin_input_impl(PyObject *module, PyObject *prompt) goto _readline_errors; assert(PyBytes_Check(po)); promptstr = PyBytes_AS_STRING(po); + if ((Py_ssize_t)strlen(promptstr) != PyBytes_GET_SIZE(po)) { + PyErr_SetString(PyExc_ValueError, + "input: prompt string cannot contain null characters"); + goto _readline_errors; + } } else { po = NULL; @@ -2606,7 +2625,10 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) } if (PyFloat_CheckExact(item)) { // Improved Kahan–Babuška algorithm by Arnold Neumaier - // https://www.mat.univie.ac.at/~neum/scan/01.pdf + // Neumaier, A. (1974), Rundungsfehleranalyse einiger Verfahren + // zur Summation endlicher Summen. Z. angew. Math. Mech., + // 54: 39-51. https://doi.org/10.1002/zamm.19740540106 + // https://en.wikipedia.org/wiki/Kahan_summation_algorithm#Further_enhancements double x = PyFloat_AS_DOUBLE(item); double t = f_result + x; if (fabs(f_result) >= fabs(x)) { @@ -2950,10 +2972,8 @@ static PyMethodDef zip_methods[] = { }; PyDoc_STRVAR(zip_doc, -"zip(*iterables, strict=False) --> Yield tuples until an input is exhausted.\n\ -\n\ - >>> list(zip('abcdefg', range(3), range(4)))\n\ - [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\ +"zip(*iterables, strict=False)\n\ +--\n\ \n\ The zip object yields n-length tuples, where n is the number of iterables\n\ passed as positional arguments to zip(). The i-th element in every tuple\n\ @@ -2961,7 +2981,10 @@ comes from the i-th iterable argument to zip(). This continues until the\n\ shortest argument is exhausted.\n\ \n\ If strict is true and one of the arguments is exhausted before the others,\n\ -raise a ValueError."); +raise a ValueError.\n\ +\n\ + >>> list(zip('abcdefg', range(3), range(4)))\n\ + [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]"); PyTypeObject PyZip_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -3040,8 +3063,8 @@ static PyMethodDef builtin_methods[] = { 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}, + {"max", _PyCFunction_CAST(builtin_max), METH_FASTCALL | METH_KEYWORDS, max_doc}, + {"min", _PyCFunction_CAST(builtin_min), METH_FASTCALL | METH_KEYWORDS, min_doc}, {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc}, BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF 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 f7681bd234a43f..1ae83422730f8f 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -41,8 +41,6 @@ #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: @@ -52,6 +50,11 @@ #define family(name, ...) static int family_##name #define pseudo(name) static int pseudo_##name +/* Annotations */ +#define guard +#define override +#define specializing + // Dummy variables for stack effects. static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub; static PyObject *container, *start, *stop, *v, *lhs, *rhs, *res2; @@ -65,6 +68,7 @@ static size_t jump; static uint16_t invert, counter, index, hint; #define unused 0 // Used in a macro def, can't be static static uint32_t type_version; +static _PyUOpExecutorObject *current_executor; static PyObject * dummy_func( @@ -82,6 +86,7 @@ dummy_func( pop_1_error: // Dummy locals. PyObject *dummy; + _Py_CODEUNIT *this_instr; PyObject *attr; PyObject *attrs; PyObject *bottom; @@ -138,53 +143,56 @@ dummy_func( inst(RESUME, (--)) { TIER_ONE_ONLY assert(frame == tstate->current_frame); - 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; + 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--; + next_instr = this_instr; } else { - if (oparg < 2) { + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { CHECK_EVAL_BREAKER(); } - next_instr[-1].op.code = RESUME_CHECK; + this_instr->op.code = RESUME_CHECK; } } inst(RESUME_CHECK, (--)) { #if defined(__EMSCRIPTEN__) - DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME); + DEOPT_IF(_Py_emscripten_signal_clock == 0); _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif - /* Possibly combine these two checks */ - DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version - != tstate->interp->monitoring_version, RESUME); - DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), RESUME); + 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; + GOTO_ERROR(error); } - next_instr--; + next_instr = this_instr; } else { - if (oparg < 2) { + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { CHECK_EVAL_BREAKER(); } _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_call_instrumentation( - tstate, oparg > 0, frame, next_instr-1); + tstate, oparg > 0, frame, this_instr); stack_pointer = _PyFrame_GetStackPointer(frame); ERROR_IF(err, error); - if (frame->prev_instr != next_instr-1) { + if (frame->instr_ptr != this_instr) { /* Instrumentation has jumped */ - next_instr = frame->prev_instr; + next_instr = this_instr; DISPATCH(); } } @@ -260,12 +268,13 @@ dummy_func( macro(END_FOR) = POP_TOP + POP_TOP; inst(INSTRUMENTED_END_FOR, (receiver, value --)) { + TIER_ONE_ONLY /* Need to create a fake StopIteration error here, * to conform to PEP 380 */ if (PyGen_Check(receiver)) { PyErr_SetObject(PyExc_StopIteration, value); - if (monitor_stop_iteration(tstate, frame, next_instr-1)) { - goto error; + if (monitor_stop_iteration(tstate, frame, this_instr)) { + GOTO_ERROR(error); } PyErr_SetRaisedException(NULL); } @@ -277,10 +286,11 @@ dummy_func( } inst(INSTRUMENTED_END_SEND, (receiver, value -- value)) { + TIER_ONE_ONLY if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) { PyErr_SetObject(PyExc_StopIteration, value); - if (monitor_stop_iteration(tstate, frame, next_instr-1)) { - goto error; + if (monitor_stop_iteration(tstate, frame, this_instr)) { + GOTO_ERROR(error); } PyErr_SetRaisedException(NULL); } @@ -307,30 +317,35 @@ dummy_func( TO_BOOL_STR, }; - inst(TO_BOOL, (unused/1, unused/2, value -- res)) { + specializing op(_SPECIALIZE_TO_BOOL, (counter/1, value -- value)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyToBoolCache *cache = (_PyToBoolCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_ToBool(value, next_instr); DISPATCH_SAME_OPARG(); } STAT_INC(TO_BOOL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_TO_BOOL, (unused/2, value -- res)) { int err = PyObject_IsTrue(value); DECREF_INPUTS(); ERROR_IF(err < 0, error); res = err ? Py_True : Py_False; } + macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + _TO_BOOL; + 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)); @@ -343,7 +358,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(); @@ -351,13 +366,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)); @@ -373,7 +388,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; @@ -397,8 +412,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)) { @@ -433,8 +448,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)) { @@ -469,8 +484,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)) { @@ -490,11 +505,10 @@ dummy_func( // So the inputs are the same as for all BINARY_OP // specializations, but there is no output. // At the end we just skip over the STORE_FAST. - op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) { - _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); + op(_BINARY_OP_INPLACE_ADD_UNICODE, (unused/1, left, right --)) { + assert(next_instr->op.code == STORE_FAST); + PyObject **target_local = &GETLOCAL(next_instr->op.arg); + DEOPT_IF(*target_local != left); STAT_INC(BINARY_OP, hit); /* Handle `left = left + right` or `left += right` for str. * @@ -513,7 +527,8 @@ dummy_func( _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); ERROR_IF(*target_local == NULL, error); // The STORE_FAST is already done. - SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + assert(next_instr->op.code == STORE_FAST); + SKIP_OVER(1); } macro(BINARY_OP_INPLACE_ADD_UNICODE) = @@ -527,22 +542,27 @@ dummy_func( BINARY_SUBSCR_TUPLE_INT, }; - inst(BINARY_SUBSCR, (unused/1, container, sub -- res)) { + specializing op(_SPECIALIZE_BINARY_SUBSCR, (counter/1, container, sub -- container, sub)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_BinarySubscr(container, sub, next_instr); DISPATCH_SAME_OPARG(); } STAT_INC(BINARY_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_BINARY_SUBSCR, (container, sub -- res)) { res = PyObject_GetItem(container, sub); DECREF_INPUTS(); ERROR_IF(res == NULL, error); } + macro(BINARY_SUBSCR) = _SPECIALIZE_BINARY_SUBSCR + _BINARY_SUBSCR; + inst(BINARY_SLICE, (container, start, stop -- res)) { PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); // Can't use ERROR_IF() here, because we haven't @@ -574,13 +594,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); @@ -590,14 +610,14 @@ dummy_func( } inst(BINARY_SUBSCR_STR_INT, (unused/1, str, sub -- res)) { - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyUnicode_CheckExact(str), BINARY_SUBSCR); - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + 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, BINARY_SUBSCR); + 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, BINARY_SUBSCR); + 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); @@ -605,13 +625,13 @@ dummy_func( } 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); @@ -621,42 +641,37 @@ 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) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetKeyError(sub); - } - DECREF_INPUTS(); - ERROR_IF(true, error); + int rc = PyDict_GetItemRef(dict, sub, &res); + if (rc == 0) { + _PyErr_SetKeyError(sub); } - Py_INCREF(res); // Do this before DECREF'ing dict, sub DECREF_INPUTS(); + ERROR_IF(rc <= 0, error); // not found or error } 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); STACK_SHRINK(2); new_frame->localsplus[0] = container; new_frame->localsplus[1] = sub; - SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - frame->return_offset = 0; + frame->return_offset = (uint16_t)(next_instr - this_instr); DISPATCH_INLINED(new_frame); } @@ -675,32 +690,37 @@ dummy_func( STORE_SUBSCR_LIST_INT, }; - inst(STORE_SUBSCR, (unused/1, v, container, sub -- )) { + specializing op(_SPECIALIZE_STORE_SUBSCR, (counter/1, container, sub -- container, sub)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_StoreSubscr(container, sub, next_instr); DISPATCH_SAME_OPARG(); } STAT_INC(STORE_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_STORE_SUBSCR, (v, container, sub -- )) { /* container[sub] = v */ int err = PyObject_SetItem(container, sub, v); DECREF_INPUTS(); ERROR_IF(err, error); } + macro(STORE_SUBSCR) = _SPECIALIZE_STORE_SUBSCR + _STORE_SUBSCR; + 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); @@ -712,7 +732,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); @@ -741,6 +761,7 @@ dummy_func( } inst(RAISE_VARARGS, (args[oparg] -- )) { + TIER_ONE_ONLY PyObject *cause = NULL, *exc = NULL; switch (oparg) { case 2: @@ -752,7 +773,7 @@ dummy_func( case 0: if (do_raise(tstate, exc, cause)) { assert(oparg == 0); - monitor_reraise(tstate, frame, next_instr-1); + monitor_reraise(tstate, frame, this_instr); goto exception_unwind; } break; @@ -779,20 +800,19 @@ dummy_func( // 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()); #if TIER_ONE assert(frame != &entry_frame); #endif STORE_SP(); + assert(EMPTY()); _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(); + LOAD_IP(frame->return_offset); #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -802,15 +822,13 @@ dummy_func( } macro(RETURN_VALUE) = - _SET_IP + // Tier 2 only; special-cased oparg - _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, - frame, next_instr-1, retval); - if (err) goto error; + frame, this_instr, retval); + if (err) GOTO_ERROR(error); STACK_SHRINK(1); assert(EMPTY()); _PyFrame_SetStackPointer(frame, stack_pointer); @@ -820,23 +838,21 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); + LOAD_IP(frame->return_offset); goto resume_frame; } macro(RETURN_CONST) = LOAD_CONST + - _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr _POP_FRAME; inst(INSTRUMENTED_RETURN_CONST, (--)) { PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg); int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_RETURN, - frame, next_instr-1, retval); - if (err) goto error; + frame, this_instr, retval); + if (err) GOTO_ERROR(error); Py_INCREF(retval); assert(EMPTY()); _PyFrame_SetStackPointer(frame, stack_pointer); @@ -846,8 +862,8 @@ dummy_func( _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; _PyFrame_StackPush(frame, retval); + LOAD_IP(frame->return_offset); goto resume_frame; } @@ -892,7 +908,7 @@ dummy_func( if (PyAsyncGen_CheckExact(aiter)) { awaitable = type->tp_as_async->am_anext(aiter); if (awaitable == NULL) { - goto error; + GOTO_ERROR(error); } } else { if (type->tp_as_async != NULL){ @@ -902,7 +918,7 @@ dummy_func( if (getter != NULL) { next_iter = (*getter)(aiter); if (next_iter == NULL) { - goto error; + GOTO_ERROR(error); } } else { @@ -910,7 +926,7 @@ dummy_func( "'async for' requires an iterator with " "__anext__ method, got %.100s", type->tp_name); - goto error; + GOTO_ERROR(error); } awaitable = _PyCoro_GetAwaitableIter(next_iter); @@ -922,7 +938,7 @@ dummy_func( Py_TYPE(next_iter)->tp_name); Py_DECREF(next_iter); - goto error; + GOTO_ERROR(error); } else { Py_DECREF(next_iter); } @@ -959,17 +975,20 @@ dummy_func( SEND_GEN, }; - inst(SEND, (unused/1, receiver, v -- receiver, retval)) { + specializing op(_SPECIALIZE_SEND, (counter/1, receiver, unused -- receiver, unused)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PySendCache *cache = (_PySendCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_Send(receiver, next_instr); DISPATCH_SAME_OPARG(); } STAT_INC(SEND, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_SEND, (receiver, v -- receiver, retval)) { assert(frame != &entry_frame); if ((tstate->interp->eval_frame == NULL) && (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && @@ -982,8 +1001,8 @@ dummy_func( 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; + assert(next_instr - this_instr + oparg <= UINT16_MAX); + frame->return_offset = (uint16_t)(next_instr - this_instr + oparg); DISPATCH_INLINED(gen_frame); } if (Py_IsNone(v) && PyIter_Check(receiver)) { @@ -995,25 +1014,26 @@ dummy_func( if (retval == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) ) { - monitor_raise(tstate, frame, next_instr-1); + monitor_raise(tstate, frame, this_instr); } if (_PyGen_FetchStopIterationValue(&retval) == 0) { assert(retval != NULL); JUMPBY(oparg); } else { - goto error; + GOTO_ERROR(error); } } Py_DECREF(v); } + macro(SEND) = _SPECIALIZE_SEND + _SEND; + 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; STACK_SHRINK(1); @@ -1021,21 +1041,23 @@ dummy_func( 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; + assert(next_instr - this_instr + oparg <= UINT16_MAX); + frame->return_offset = (uint16_t)(next_instr - this_instr + oparg); DISPATCH_INLINED(gen_frame); } inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) { assert(frame != &entry_frame); - assert(oparg >= 0); /* make the generator identify this as HAS_ARG */ + frame->instr_ptr = next_instr; PyGenObject *gen = _PyFrame_GetGenerator(frame); - gen->gi_frame_state = FRAME_SUSPENDED; + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + gen->gi_frame_state = FRAME_SUSPENDED + oparg; _PyFrame_SetStackPointer(frame, stack_pointer - 1); int err = _Py_call_instrumentation_arg( tstate, PY_MONITORING_EVENT_PY_YIELD, - frame, next_instr-1, retval); - if (err) goto error; + frame, this_instr, retval); + if (err) GOTO_ERROR(error); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; _Py_LeaveRecursiveCallPy(tstate); @@ -1043,6 +1065,9 @@ dummy_func( frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); + /* We don't know which of these is relevant here, so keep them equal */ + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); goto resume_frame; } @@ -1050,10 +1075,12 @@ dummy_func( // NOTE: It's important that YIELD_VALUE never raises an exception! // The compiler treats any exception raised here as a failed close() // or throw() call. - assert(oparg >= 0); /* make the generator identify this as HAS_ARG */ assert(frame != &entry_frame); + frame->instr_ptr = next_instr; PyGenObject *gen = _PyFrame_GetGenerator(frame); - gen->gi_frame_state = FRAME_SUSPENDED; + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + gen->gi_frame_state = FRAME_SUSPENDED + oparg; _PyFrame_SetStackPointer(frame, stack_pointer - 1); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; @@ -1062,6 +1089,9 @@ dummy_func( frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); + /* We don't know which of these is relevant here, so keep them equal */ + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); goto resume_frame; } @@ -1071,27 +1101,29 @@ dummy_func( } inst(RERAISE, (values[oparg], exc -- values[oparg])) { + TIER_ONE_ONLY assert(oparg >= 0 && oparg <= 2); if (oparg) { PyObject *lasti = values[0]; if (PyLong_Check(lasti)) { - frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); + frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); assert(!_PyErr_Occurred(tstate)); } else { assert(PyLong_Check(lasti)); _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); - goto error; + GOTO_ERROR(error); } } assert(exc && PyExceptionInstance_Check(exc)); Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); - monitor_reraise(tstate, frame, next_instr-1); + monitor_reraise(tstate, frame, this_instr); goto exception_unwind; } inst(END_ASYNC_FOR, (awaitable, exc -- )) { + TIER_ONE_ONLY assert(exc && PyExceptionInstance_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { DECREF_INPUTS(); @@ -1099,12 +1131,13 @@ dummy_func( else { Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); - monitor_reraise(tstate, frame, next_instr-1); + monitor_reraise(tstate, frame, this_instr); goto exception_unwind; } } inst(CLEANUP_THROW, (sub_iter, last_sent_val, exc_value -- none, value)) { + TIER_ONE_ONLY assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { @@ -1114,7 +1147,7 @@ dummy_func( } else { _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); - monitor_reraise(tstate, frame, next_instr-1); + monitor_reraise(tstate, frame, this_instr); goto exception_unwind; } } @@ -1132,7 +1165,6 @@ dummy_func( } } - inst(STORE_NAME, (v -- )) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *ns = LOCALS(); @@ -1158,7 +1190,7 @@ dummy_func( if (ns == NULL) { _PyErr_Format(tstate, PyExc_SystemError, "no locals when deleting %R", name); - goto error; + GOTO_ERROR(error); } err = PyObject_DelItem(ns, name); // Can't use ERROR_IF here. @@ -1166,7 +1198,7 @@ dummy_func( _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); - goto error; + GOTO_ERROR(error); } } @@ -1176,26 +1208,33 @@ dummy_func( UNPACK_SEQUENCE_LIST, }; - inst(UNPACK_SEQUENCE, (unused/1, seq -- unused[oparg])) { + specializing op(_SPECIALIZE_UNPACK_SEQUENCE, (counter/1, seq -- seq)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_UnpackSequence(seq, next_instr, oparg); DISPATCH_SAME_OPARG(); } STAT_INC(UNPACK_SEQUENCE, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + (void)seq; + (void)counter; + } + + op(_UNPACK_SEQUENCE, (seq -- unused[oparg])) { PyObject **top = stack_pointer + oparg - 1; int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); DECREF_INPUTS(); ERROR_IF(res == 0, error); } + macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE; + 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)); @@ -1204,8 +1243,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; ) { @@ -1215,8 +1254,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; ) { @@ -1239,24 +1278,29 @@ dummy_func( STORE_ATTR_WITH_HINT, }; - inst(STORE_ATTR, (unused/1, unused/3, v, owner --)) { + specializing op(_SPECIALIZE_STORE_ATTR, (counter/1, owner -- owner)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - next_instr--; + next_instr = this_instr; _Py_Specialize_StoreAttr(owner, next_instr, name); DISPATCH_SAME_OPARG(); } STAT_INC(STORE_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_STORE_ATTR, (unused/3, v, owner --)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyObject_SetAttr(owner, name, v); DECREF_INPUTS(); ERROR_IF(err, error); } + macro(STORE_ATTR) = _SPECIALIZE_STORE_ATTR + _STORE_ATTR; + inst(DELETE_ATTR, (owner --)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyObject_DelAttr(owner, name); @@ -1281,7 +1325,7 @@ dummy_func( _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); } - goto error; + GOTO_ERROR(error); } } @@ -1298,25 +1342,21 @@ dummy_func( 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) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; + if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) { + GOTO_ERROR(error); } - else { + if (v == NULL) { if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); - goto error; + GOTO_ERROR(error); } } } @@ -1332,25 +1372,21 @@ dummy_func( } PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; + if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) { + GOTO_ERROR(error); } - else { + if (v == NULL) { if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, NAME_ERROR_MSG, name); - goto error; + GOTO_ERROR(error); } } } @@ -1361,18 +1397,21 @@ dummy_func( LOAD_GLOBAL_BUILTIN, }; - inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) { + specializing op(_SPECIALIZE_LOAD_GLOBAL, (counter/1 -- )) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - next_instr--; + next_instr = this_instr; _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); DISPATCH_SAME_OPARG(); } STAT_INC(LOAD_GLOBAL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_LOAD_GLOBAL, (unused/1, unused/1, unused/1 -- res, null if (oparg & 1))) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) @@ -1393,7 +1432,6 @@ dummy_func( } else { /* Slow-path if globals or builtins is not a dict */ - /* namespace 1: globals */ ERROR_IF(PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0, error); if (res == NULL) { @@ -1410,17 +1448,19 @@ dummy_func( null = NULL; } + macro(LOAD_GLOBAL) = _SPECIALIZE_LOAD_GLOBAL + _LOAD_GLOBAL; + 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)); } @@ -1428,7 +1468,7 @@ dummy_func( 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; @@ -1438,7 +1478,7 @@ dummy_func( 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; @@ -1468,7 +1508,7 @@ dummy_func( PyObject *initial = GETLOCAL(oparg); PyObject *cell = PyCell_New(initial); if (cell == NULL) { - goto resume_with_error; + GOTO_ERROR(error); } SETLOCAL(oparg, cell); } @@ -1480,7 +1520,7 @@ dummy_func( // Fortunately we don't need its superpower. if (oldobj == NULL) { _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - goto error; + GOTO_ERROR(error); } PyCell_SET(cell, NULL); Py_DECREF(oldobj); @@ -1492,19 +1532,18 @@ dummy_func( assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); if (PyMapping_GetOptionalItem(class_dict, name, &value) < 0) { - Py_DECREF(class_dict); - goto error; + GOTO_ERROR(error); } - Py_DECREF(class_dict); if (!value) { PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - goto error; + GOTO_ERROR(error); } Py_INCREF(value); } + Py_DECREF(class_dict); } inst(LOAD_DEREF, ( -- value)) { @@ -1580,7 +1619,7 @@ dummy_func( inst(BUILD_SET, (values[oparg] -- set)) { set = PySet_New(NULL); if (set == NULL) - goto error; + GOTO_ERROR(error); int err = 0; for (int i = 0; i < oparg; i++) { PyObject *item = values[i]; @@ -1612,34 +1651,17 @@ dummy_func( ERROR_IF(true, error); } /* check if __annotations__ in locals()... */ - if (PyDict_CheckExact(LOCALS())) { - ann_dict = _PyDict_GetItemWithError(LOCALS(), - &_Py_ID(__annotations__)); - if (ann_dict == NULL) { - ERROR_IF(_PyErr_Occurred(tstate), error); - /* ...if not, create a new one */ - ann_dict = PyDict_New(); - ERROR_IF(ann_dict == NULL, error); - err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - ERROR_IF(err, error); - } + ERROR_IF(PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict) < 0, error); + if (ann_dict == NULL) { + ann_dict = PyDict_New(); + ERROR_IF(ann_dict == NULL, error); + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + ERROR_IF(err, error); } else { - /* do the same if locals() is not a dict */ - ERROR_IF(PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict) < 0, error); - if (ann_dict == NULL) { - ann_dict = PyDict_New(); - ERROR_IF(ann_dict == NULL, error); - err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - ERROR_IF(err, error); - } - else { - Py_DECREF(ann_dict); - } + Py_DECREF(ann_dict); } } @@ -1648,7 +1670,7 @@ dummy_func( PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, "bad BUILD_CONST_KEY_MAP keys argument"); - goto error; // Pop the keys and values. + GOTO_ERROR(error); // Pop the keys and values. } map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, @@ -1686,11 +1708,10 @@ dummy_func( ERROR_IF(_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0, error); } - inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/9, unused, unused, unused -- unused, unused if (oparg & 1))) { - _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; + inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/1, unused, unused, unused -- unused, unused if (oparg & 1))) { // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we // don't want to specialize instrumented instructions - INCREMENT_ADAPTIVE_COUNTER(cache->counter); + INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); } @@ -1699,28 +1720,29 @@ dummy_func( LOAD_SUPER_ATTR_METHOD, }; - 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; + specializing op(_SPECIALIZE_LOAD_SUPER_ATTR, (counter/1, global_super, class, unused -- global_super, class, unused)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + int load_method = oparg & 1; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method); DISPATCH_SAME_OPARG(); } STAT_INC(LOAD_SUPER_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + op(_LOAD_SUPER_ATTR, (global_super, class, self -- attr, null if (oparg & 1))) { + TIER_ONE_ONLY if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr-1, global_super, arg); + frame, this_instr, global_super, arg); ERROR_IF(err, error); } - // we make no attempt to optimize here; specializations should // handle any case whose performance we care about PyObject *stack[] = {class, self}; @@ -1730,12 +1752,12 @@ dummy_func( if (super == NULL) { _Py_call_instrumentation_exc2( tstate, PY_MONITORING_EVENT_C_RAISE, - frame, next_instr-1, global_super, arg); + frame, this_instr, global_super, arg); } else { int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, global_super, arg); + frame, this_instr, global_super, arg); if (err < 0) { Py_CLEAR(super); } @@ -1743,12 +1765,15 @@ dummy_func( } DECREF_INPUTS(); ERROR_IF(super == NULL, error); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); attr = PyObject_GetAttr(super, name); Py_DECREF(super); ERROR_IF(attr == NULL, error); null = NULL; } + macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR; + pseudo(LOAD_SUPER_METHOD) = { LOAD_SUPER_ATTR, }; @@ -1763,8 +1788,8 @@ dummy_func( 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); attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); @@ -1774,8 +1799,8 @@ dummy_func( 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; @@ -1811,18 +1836,21 @@ dummy_func( LOAD_ATTR_NONDESCRIPTOR_NO_DICT, }; - inst(LOAD_ATTR, (unused/9, owner -- attr, self_or_null if (oparg & 1))) { + specializing op(_SPECIALIZE_LOAD_ATTR, (counter/1, owner -- owner)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - next_instr--; + next_instr = this_instr; _Py_Specialize_LoadAttr(owner, next_instr, name); DISPATCH_SAME_OPARG(); } STAT_INC(LOAD_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_LOAD_ATTR, (unused/8, owner -- attr, self_or_null if (oparg & 1))) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ @@ -1830,7 +1858,6 @@ dummy_func( 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(attr != NULL); // No errors on this branch @@ -1841,7 +1868,6 @@ dummy_func( something was returned by a descriptor protocol). Set the second element of the stack to NULL, to signal CALL that it's not a method call. - NULL | meth | arg1 | ... | argN */ DECREF_INPUTS(); @@ -1857,6 +1883,8 @@ dummy_func( } } + macro(LOAD_ATTR) = _SPECIALIZE_LOAD_ATTR + _LOAD_ATTR; + pseudo(LOAD_METHOD) = { LOAD_ATTR, }; @@ -1864,22 +1892,20 @@ 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) && - !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), - LOAD_ATTR); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)); } op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, owner -- attr, null if (oparg & 1))) { PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); attr = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(attr == NULL, LOAD_ATTR); + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); null = NULL; @@ -1893,56 +1919,74 @@ dummy_func( _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 -- attr, null if (oparg & 1))) { - 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; attr = ep->me_value; - DEOPT_IF(attr == NULL, LOAD_ATTR); + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); null = NULL; DECREF_INPUTS(); } - inst(LOAD_ATTR_WITH_HINT, (unused/1, type_version/2, index/1, unused/5, owner -- attr, null if (oparg & 1))) { - 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); + 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); + DEOPT_IF(ep->me_key != name); attr = ep->me_value; } - DEOPT_IF(attr == NULL, LOAD_ATTR); + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); null = NULL; DECREF_INPUTS(); } + 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; attr = *(PyObject **)addr; - DEOPT_IF(attr == NULL, LOAD_ATTR); + DEOPT_IF(attr == NULL); STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr); null = NULL; @@ -1955,59 +1999,64 @@ dummy_func( _LOAD_ATTR_SLOT + // NOTE: This action may also deopt unused/5; - inst(LOAD_ATTR_CLASS, (unused/1, type_version/2, unused/2, descr/4, owner -- attr, null if (oparg & 1))) { - - DEOPT_IF(!PyType_Check(owner), LOAD_ATTR); - DEOPT_IF(((PyTypeObject *)owner)->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); + assert(descr != NULL); + attr = Py_NewRef(descr); null = NULL; - attr = descr; - assert(attr != NULL); - Py_INCREF(attr); DECREF_INPUTS(); } + 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, LOAD_ATTR); + DEOPT_IF(tstate->interp->eval_frame); PyTypeObject *cls = Py_TYPE(owner); - DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); assert(type_version != 0); + DEOPT_IF(cls->tp_version_tag != type_version); 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(). STACK_SHRINK(1); new_frame->localsplus[0] = owner; - SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; + frame->return_offset = (uint16_t)(next_instr - this_instr); DISPATCH_INLINED(new_frame); } 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, LOAD_ATTR); + DEOPT_IF(tstate->interp->eval_frame); PyTypeObject *cls = Py_TYPE(owner); - DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); assert(type_version != 0); + DEOPT_IF(cls->tp_version_tag != type_version); 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); @@ -2017,15 +2066,14 @@ dummy_func( STACK_SHRINK(1); new_frame->localsplus[0] = owner; new_frame->localsplus[1] = Py_NewRef(name); - SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; + frame->return_offset = (uint16_t)(next_instr - this_instr); DISPATCH_INLINED(new_frame); } 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), STORE_ATTR); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv)); } op(_STORE_ATTR_INSTANCE_VALUE, (index/1, value, owner --)) { @@ -2045,37 +2093,37 @@ dummy_func( macro(STORE_ATTR_INSTANCE_VALUE) = unused/1 + - _GUARD_TYPE_VERSION_STORE + + _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; } @@ -2090,12 +2138,6 @@ dummy_func( Py_DECREF(owner); } - op(_GUARD_TYPE_VERSION_STORE, (type_version/2, owner -- 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); @@ -2107,7 +2149,7 @@ dummy_func( macro(STORE_ATTR_SLOT) = unused/1 + - _GUARD_TYPE_VERSION_STORE + + _GUARD_TYPE_VERSION + _STORE_ATTR_SLOT; family(COMPARE_OP, INLINE_CACHE_ENTRIES_COMPARE_OP) = { @@ -2116,17 +2158,20 @@ dummy_func( COMPARE_OP_STR, }; - inst(COMPARE_OP, (unused/1, left, right -- res)) { + specializing op(_SPECIALIZE_COMPARE_OP, (counter/1, left, right -- left, right)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_CompareOp(left, right, next_instr, oparg); DISPATCH_SAME_OPARG(); } STAT_INC(COMPARE_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + op(_COMPARE_OP, (left, right -- res)) { assert((oparg >> 5) <= Py_GE); res = PyObject_RichCompare(left, right, oparg >> 5); DECREF_INPUTS(); @@ -2139,9 +2184,11 @@ dummy_func( } } + macro(COMPARE_OP) = _SPECIALIZE_COMPARE_OP + _COMPARE_OP; + 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); @@ -2155,10 +2202,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); @@ -2174,8 +2221,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); @@ -2235,6 +2282,7 @@ dummy_func( } inst(IMPORT_NAME, (level, fromlist -- res)) { + TIER_ONE_ONLY PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); res = import_name(tstate, frame, name, fromlist, level); DECREF_INPUTS(); @@ -2242,6 +2290,7 @@ dummy_func( } inst(IMPORT_FROM, (from -- from, res)) { + TIER_ONE_ONLY PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); res = import_from(tstate, from, name); ERROR_IF(res == NULL, error); @@ -2251,26 +2300,38 @@ dummy_func( JUMPBY(oparg); } - inst(JUMP_BACKWARD, (--)) { + inst(JUMP_BACKWARD, (unused/1 --)) { CHECK_EVAL_BREAKER(); - _Py_CODEUNIT *here = next_instr - 1; assert(oparg <= INSTR_OFFSET()); - JUMPBY(1-oparg); + JUMPBY(-oparg); #if ENABLE_SPECIALIZATION - here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); - if (here[1].cache > tstate->interp->optimizer_backedge_threshold && - // Double-check that the opcode isn't instrumented or something: - here->op.code == JUMP_BACKWARD) - { - OBJECT_STAT_INC(optimization_attempts); - int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer); + this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); + /* We are using unsigned values, but we really want signed values, so + * do the 2s complement comparison manually */ + uint16_t ucounter = this_instr[1].cache + (1 << 15); + uint16_t threshold = tstate->interp->optimizer_backedge_threshold + (1 << 15); + // Double-check that the opcode isn't instrumented or something: + if (ucounter > threshold && this_instr->op.code == JUMP_BACKWARD) { + OPT_STAT_INC(attempts); + int optimized = _PyOptimizer_BackEdge(frame, this_instr, 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(this_instr->op.code == ENTER_EXECUTOR); + next_instr = this_instr; + this_instr[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); + } + else { + int backoff = this_instr[1].cache & ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); + if (backoff < MINIMUM_TIER2_BACKOFF) { + backoff = MINIMUM_TIER2_BACKOFF; + } + else if (backoff < 15 - OPTIMIZER_BITS_IN_COUNTER) { + backoff++; + } + assert(backoff <= 15 - OPTIMIZER_BITS_IN_COUNTER); + this_instr[1].cache = ((1 << 16) - ((1 << OPTIMIZER_BITS_IN_COUNTER) << backoff)) | backoff; } - here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); } #endif /* ENABLE_SPECIALIZATION */ } @@ -2286,36 +2347,38 @@ dummy_func( }; inst(ENTER_EXECUTOR, (--)) { + TIER_ONE_ONLY CHECK_EVAL_BREAKER(); PyCodeObject *code = _PyFrame_GetCode(frame); _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; - int original_oparg = executor->vm_data.oparg | (oparg & 0xfffff00); - JUMPBY(1-original_oparg); - frame->prev_instr = next_instr - 1; Py_INCREF(executor); - frame = executor->execute(executor, frame, stack_pointer); - if (frame == NULL) { - frame = tstate->current_frame; + if (executor->execute == _PyUOpExecute) { + current_executor = (_PyUOpExecutorObject *)executor; + GOTO_TIER_TWO(); + } + next_instr = executor->execute(executor, frame, stack_pointer); + frame = tstate->current_frame; + if (next_instr == NULL) { goto resume_with_error; } - goto resume_frame; + stack_pointer = _PyFrame_GetStackPointer(frame); } - inst(POP_JUMP_IF_FALSE, (unused/1, cond -- )) { + replaced op(_POP_JUMP_IF_FALSE, (unused/1, cond -- )) { assert(PyBool_Check(cond)); int flag = Py_IsFalse(cond); #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | flag; #endif JUMPBY(oparg * flag); } - inst(POP_JUMP_IF_TRUE, (unused/1, cond -- )) { + replaced op(_POP_JUMP_IF_TRUE, (unused/1, cond -- )) { assert(PyBool_Check(cond)); int flag = Py_IsTrue(cond); #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | flag; #endif JUMPBY(oparg * flag); } @@ -2330,9 +2393,13 @@ dummy_func( } } - macro(POP_JUMP_IF_NONE) = _IS_NONE + POP_JUMP_IF_TRUE; + macro(POP_JUMP_IF_TRUE) = _POP_JUMP_IF_TRUE; + + macro(POP_JUMP_IF_FALSE) = _POP_JUMP_IF_FALSE; - macro(POP_JUMP_IF_NOT_NONE) = _IS_NONE + POP_JUMP_IF_FALSE; + macro(POP_JUMP_IF_NONE) = _IS_NONE + _POP_JUMP_IF_TRUE; + + 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. @@ -2399,7 +2466,7 @@ dummy_func( _PyErr_SetString(tstate, PyExc_TypeError, "cannot 'yield from' a coroutine object " "in a non-coroutine generator"); - goto error; + GOTO_ERROR(error); } iter = iterable; } @@ -2410,7 +2477,7 @@ dummy_func( /* `iterable` is not a generator. */ iter = PyObject_GetIter(iterable); if (iter == NULL) { - goto error; + GOTO_ERROR(error); } DECREF_INPUTS(); } @@ -2429,33 +2496,35 @@ dummy_func( FOR_ITER_GEN, }; - inst(FOR_ITER, (unused/1, iter -- iter, next)) { + specializing op(_SPECIALIZE_FOR_ITER, (counter/1, iter -- iter)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyForIterCache *cache = (_PyForIterCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_ForIter(iter, next_instr, oparg); DISPATCH_SAME_OPARG(); } STAT_INC(FOR_ITER, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ + } + + replaced op(_FOR_ITER, (iter -- iter, next)) { /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ next = (*Py_TYPE(iter)->tp_iternext)(iter); if (next == NULL) { if (_PyErr_Occurred(tstate)) { if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; + GOTO_ERROR(error); } - monitor_raise(tstate, frame, next_instr-1); + monitor_raise(tstate, frame, this_instr); _PyErr_Clear(tstate); } /* iterator ended normally */ - assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || - next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); Py_DECREF(iter); STACK_SHRINK(1); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(oparg + 1); DISPATCH(); @@ -2463,39 +2532,59 @@ dummy_func( // Common case: no jump, leave it to the code generator } - inst(INSTRUMENTED_FOR_ITER, ( -- )) { - _Py_CODEUNIT *here = next_instr-1; + op(_FOR_ITER_TIER_TWO, (iter -- iter, next)) { + /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ + next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next == NULL) { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + GOTO_ERROR(error); + } + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + Py_DECREF(iter); + STACK_SHRINK(1); + /* The translator sets the deopt target just past END_FOR */ + DEOPT_IF(true); + } + // Common case: no jump, leave it to the code generator + } + + macro(FOR_ITER) = _SPECIALIZE_FOR_ITER + _FOR_ITER; + + inst(INSTRUMENTED_FOR_ITER, (unused/1 -- )) { _Py_CODEUNIT *target; PyObject *iter = TOP(); PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); if (next != NULL) { PUSH(next); - target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER; + target = next_instr; } else { if (_PyErr_Occurred(tstate)) { if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; + GOTO_ERROR(error); } - monitor_raise(tstate, frame, here); + monitor_raise(tstate, frame, this_instr); _PyErr_Clear(tstate); } /* iterator ended normally */ - assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || - next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); STACK_SHRINK(1); Py_DECREF(iter); /* Skip END_FOR */ - target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; + target = next_instr + oparg + 1; } - INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); + INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH); } 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)) { + replaced op(_ITER_JUMP_LIST, (iter -- iter)) { _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); STAT_INC(FOR_ITER, hit); @@ -2507,7 +2596,6 @@ dummy_func( } Py_DECREF(iter); STACK_SHRINK(1); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(oparg + 1); DISPATCH(); @@ -2515,21 +2603,12 @@ dummy_func( } // Only used by Tier 2 - op(_IS_ITER_EXHAUSTED_LIST, (iter -- iter, exhausted)) { + op(_GUARD_NOT_EXHAUSTED_LIST, (iter -- iter)) { _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); PyListObject *seq = it->it_seq; - if (seq == NULL) { - exhausted = Py_True; - } - else if (it->it_index >= PyList_GET_SIZE(seq)) { - Py_DECREF(seq); - it->it_seq = NULL; - exhausted = Py_True; - } - else { - exhausted = Py_False; - } + DEOPT_IF(seq == NULL); + DEOPT_IF(it->it_index >= PyList_GET_SIZE(seq)); } op(_ITER_NEXT_LIST, (iter -- iter, next)) { @@ -2548,10 +2627,10 @@ 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)) { + replaced op(_ITER_JUMP_TUPLE, (iter -- iter)) { _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); STAT_INC(FOR_ITER, hit); @@ -2563,7 +2642,6 @@ dummy_func( } Py_DECREF(iter); STACK_SHRINK(1); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); /* Jump forward oparg, then skip following END_FOR instruction */ JUMPBY(oparg + 1); DISPATCH(); @@ -2571,21 +2649,12 @@ dummy_func( } // Only used by Tier 2 - op(_IS_ITER_EXHAUSTED_TUPLE, (iter -- iter, exhausted)) { + op(_GUARD_NOT_EXHAUSTED_TUPLE, (iter -- iter)) { _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); PyTupleObject *seq = it->it_seq; - if (seq == NULL) { - exhausted = Py_True; - } - else if (it->it_index >= PyTuple_GET_SIZE(seq)) { - Py_DECREF(seq); - it->it_seq = NULL; - exhausted = Py_True; - } - else { - exhausted = Py_False; - } + DEOPT_IF(seq == NULL); + DEOPT_IF(it->it_index >= PyTuple_GET_SIZE(seq)); } op(_ITER_NEXT_TUPLE, (iter -- iter, next)) { @@ -2605,17 +2674,16 @@ 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)) { + replaced op(_ITER_JUMP_RANGE, (iter -- iter)) { _PyRangeIterObject *r = (_PyRangeIterObject *)iter; assert(Py_TYPE(r) == &PyRangeIter_Type); STAT_INC(FOR_ITER, hit); if (r->len <= 0) { STACK_SHRINK(1); Py_DECREF(r); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); // Jump over END_FOR instruction. JUMPBY(oparg + 1); DISPATCH(); @@ -2623,10 +2691,10 @@ dummy_func( } // Only used by Tier 2 - op(_IS_ITER_EXHAUSTED_RANGE, (iter -- iter, exhausted)) { + op(_GUARD_NOT_EXHAUSTED_RANGE, (iter -- iter)) { _PyRangeIterObject *r = (_PyRangeIterObject *)iter; assert(Py_TYPE(r) == &PyRangeIter_Type); - exhausted = r->len <= 0 ? Py_True : Py_False; + DEOPT_IF(r->len <= 0); } op(_ITER_NEXT_RANGE, (iter -- iter, next)) { @@ -2647,20 +2715,20 @@ 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; _PyFrame_StackPush(gen_frame, Py_None); 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_FOR_ITER); assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); - frame->return_offset = oparg; + assert(next_instr - this_instr + oparg <= UINT16_MAX); + frame->return_offset = (uint16_t)(next_instr - this_instr + oparg); DISPATCH_INLINED(gen_frame); } @@ -2673,7 +2741,7 @@ dummy_func( "asynchronous context manager protocol", Py_TYPE(mgr)->tp_name); } - goto error; + GOTO_ERROR(error); } exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); if (exit == NULL) { @@ -2685,10 +2753,10 @@ dummy_func( Py_TYPE(mgr)->tp_name); } Py_DECREF(enter); - goto error; + GOTO_ERROR(error); } DECREF_INPUTS(); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); @@ -2708,7 +2776,7 @@ dummy_func( "context manager protocol", Py_TYPE(mgr)->tp_name); } - goto error; + GOTO_ERROR(error); } exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); if (exit == NULL) { @@ -2720,10 +2788,10 @@ dummy_func( Py_TYPE(mgr)->tp_name); } Py_DECREF(enter); - goto error; + GOTO_ERROR(error); } DECREF_INPUTS(); - res = _PyObject_CallNoArgs(enter); + res = _PyObject_CallNoArgsTstate(tstate, enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); @@ -2759,15 +2827,15 @@ dummy_func( ERROR_IF(res == NULL, error); } - pseudo(SETUP_FINALLY) = { + pseudo(SETUP_FINALLY, (HAS_ARG)) = { NOP, }; - pseudo(SETUP_CLEANUP) = { + pseudo(SETUP_CLEANUP, (HAS_ARG)) = { NOP, }; - pseudo(SETUP_WITH) = { + pseudo(SETUP_WITH, (HAS_ARG)) = { NOP, }; @@ -2790,16 +2858,13 @@ dummy_func( 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), - LOAD_ATTR); + 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, LOAD_ATTR); + 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))) { @@ -2835,46 +2900,46 @@ dummy_func( unused/2 + _LOAD_ATTR_METHOD_NO_DICT; - inst(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, owner -- attr, unused if (0))) { + op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr, unused if (0))) { assert((oparg & 1) == 0); - PyTypeObject *owner_cls = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && - !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), - LOAD_ATTR); - PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; - DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != - keys_version, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); DECREF_INPUTS(); attr = Py_NewRef(descr); } - inst(LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, owner -- attr, unused if (0))) { + 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 *owner_cls = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(owner_cls->tp_dictoffset == 0); + assert(Py_TYPE(owner)->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); DECREF_INPUTS(); attr = Py_NewRef(descr); } - inst(LOAD_ATTR_METHOD_LAZY_DICT, (unused/1, type_version/2, unused/2, descr/4, owner -- attr, self if (1))) { - assert(oparg & 1); - PyTypeObject *owner_cls = Py_TYPE(owner); - DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR); - Py_ssize_t dictoffset = owner_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 *)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)); @@ -2882,7 +2947,14 @@ dummy_func( self = owner; } - inst(INSTRUMENTED_CALL, ( -- )) { + 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, (unused/3 -- )) { int is_meth = PEEK(oparg + 1) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(oparg + 2); @@ -2890,10 +2962,9 @@ dummy_func( &_PyInstrumentation_MISSING : PEEK(total_args); int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr-1, function, arg); + frame, this_instr, function, arg); ERROR_IF(err, error); - _PyCallCache *cache = (_PyCallCache *)next_instr; - INCREMENT_ADAPTIVE_COUNTER(cache->counter); + INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); GO_TO_INSTRUCTION(CALL); } @@ -2920,25 +2991,28 @@ dummy_func( CALL_ALLOC_AND_ENTER_INIT, }; + specializing op(_SPECIALIZE_CALL, (counter/1, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) { + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_Call(callable, next_instr, oparg + (self_or_null != NULL)); + DISPATCH_SAME_OPARG(); + } + STAT_INC(CALL, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ + } + // When calling Python, inline the call using DISPATCH_INLINED(). - inst(CALL, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { + op(_CALL, (unused/2, callable, self_or_null, args[oparg] -- res)) { // oparg counts all of the args, but *not* self: int total_args = oparg; if (self_or_null != NULL) { args--; total_args++; } - #if ENABLE_SPECIALIZATION - _PyCallCache *cache = (_PyCallCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_Call(callable, next_instr, total_args); - DISPATCH_SAME_OPARG(); - } - STAT_INC(CALL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) { + else if (Py_TYPE(callable) == &PyMethod_Type) { args--; total_args++; PyObject *self = ((PyMethodObject *)callable)->im_self; @@ -2964,10 +3038,9 @@ dummy_func( // 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; + GOTO_ERROR(error); } - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; + frame->return_offset = (uint16_t)(next_instr - this_instr); DISPATCH_INLINED(new_frame); } /* Callable is not a normal Python function */ @@ -2981,12 +3054,12 @@ dummy_func( if (res == NULL) { _Py_call_instrumentation_exc2( tstate, PY_MONITORING_EVENT_C_RAISE, - frame, next_instr-1, callable, arg); + frame, this_instr, callable, arg); } else { int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, callable, arg); + frame, this_instr, callable, arg); if (err < 0) { Py_CLEAR(res); } @@ -3001,9 +3074,11 @@ dummy_func( CHECK_EVAL_BREAKER(); } + macro(CALL) = _SPECIALIZE_CALL + _CALL; + op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) { - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); + 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])) { @@ -3016,22 +3091,22 @@ dummy_func( } op(_CHECK_PEP_523, (--)) { - DEOPT_IF(tstate->interp->eval_frame, CALL); + 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), 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; - DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL); + 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), CALL); - DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL); + 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*)) { @@ -3051,10 +3126,9 @@ dummy_func( // 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)) { + op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- unused if (0))) { // 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; @@ -3062,7 +3136,7 @@ dummy_func( frame = tstate->current_frame = new_frame; tstate->py_recursion_remaining--; LOAD_SP(); - LOAD_IP(); + LOAD_IP(0); #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -3079,8 +3153,7 @@ dummy_func( _CHECK_FUNCTION_EXACT_ARGS + _CHECK_STACK_SPACE + _INIT_CALL_PY_EXACT_ARGS + - _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr + _SAVE_RETURN_OFFSET + _PUSH_FRAME; macro(CALL_PY_EXACT_ARGS) = @@ -3089,29 +3162,28 @@ dummy_func( _CHECK_FUNCTION_EXACT_ARGS + _CHECK_STACK_SPACE + _INIT_CALL_PY_EXACT_ARGS + - _SET_IP + // Tier 2 only; special-cased oparg - _SAVE_CURRENT_IP + // Sets frame->prev_instr + _SAVE_RETURN_OFFSET + _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, CALL); + DEOPT_IF(tstate->interp->eval_frame); int argcount = oparg; 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++) { @@ -3123,16 +3195,15 @@ dummy_func( } // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). STACK_SHRINK(oparg + 2); - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; + frame->return_offset = (uint16_t)(next_instr - this_instr); DISPATCH_INLINED(new_frame); } 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); @@ -3141,8 +3212,8 @@ dummy_func( 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); @@ -3154,8 +3225,8 @@ dummy_func( 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); @@ -3171,25 +3242,25 @@ dummy_func( * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) * 3. Pushes the frame for ``__init__`` to the frame stack * */ - _PyCallCache *cache = (_PyCallCache *)next_instr; - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(!PyType_Check(callable), CALL); + _PyCallCache *cache = (_PyCallCache *)&this_instr[1]; + 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) { - goto error; + GOTO_ERROR(error); } Py_DECREF(tp); _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( - tstate, (PyCodeObject *)&_Py_InitCleanup, 1, 0); - assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK); + tstate, (PyCodeObject *)&_Py_InitCleanup, 1); + assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[0].op.code == EXIT_INIT_CHECK); /* Push self onto stack of shim */ Py_INCREF(self); shim->localsplus[0] = self; @@ -3200,9 +3271,7 @@ dummy_func( for (int i = 0; i < oparg; i++) { init_frame->localsplus[i+1] = args[i]; } - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - frame->return_offset = 0; + frame->return_offset = (uint16_t)(next_instr - this_instr); STACK_SHRINK(oparg+2); _PyFrame_SetStackPointer(frame, stack_pointer); /* Link frames */ @@ -3223,7 +3292,7 @@ dummy_func( PyErr_Format(PyExc_TypeError, "__init__() should return None, not '%.200s'", Py_TYPE(should_be_none)->tp_name); - goto error; + GOTO_ERROR(error); } } @@ -3233,9 +3302,9 @@ dummy_func( args--; total_args++; } - 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, NULL); /* Free the arguments. */ @@ -3254,15 +3323,15 @@ dummy_func( 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 // function calls. if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + GOTO_ERROR(error); } PyObject *arg = args[0]; res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); @@ -3282,8 +3351,8 @@ dummy_func( 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) */ @@ -3314,9 +3383,8 @@ dummy_func( 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 = @@ -3341,14 +3409,14 @@ dummy_func( args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); + DEOPT_IF(total_args != 1); PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.len, CALL); + DEOPT_IF(callable != interp->callable_cache.len); STAT_INC(CALL, hit); PyObject *arg = args[0]; Py_ssize_t len_i = PyObject_Length(arg); if (len_i < 0) { - goto error; + GOTO_ERROR(error); } res = PyLong_FromSsize_t(len_i); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -3365,15 +3433,15 @@ dummy_func( args--; total_args++; } - DEOPT_IF(total_args != 2, CALL); + DEOPT_IF(total_args != 2); PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + DEOPT_IF(callable != interp->callable_cache.isinstance); STAT_INC(CALL, hit); PyObject *cls = args[1]; PyObject *inst = args[0]; int retval = PyObject_IsInstance(inst, cls); if (retval < 0) { - goto error; + GOTO_ERROR(error); } res = PyBool_FromLong(retval); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -3388,9 +3456,9 @@ dummy_func( inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) { assert(oparg == 1); PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.list_append, CALL); + DEOPT_IF(callable != interp->callable_cache.list_append); assert(self != NULL); - DEOPT_IF(!PyList_Check(self), CALL); + 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 @@ -3398,9 +3466,9 @@ dummy_func( Py_DECREF(self); Py_DECREF(callable); STACK_SHRINK(3); - // CALL + POP_TOP - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); - assert(next_instr[-1].op.code == POP_TOP); + // Skip POP_TOP + assert(next_instr->op.code == POP_TOP); + SKIP_OVER(1); DISPATCH(); } @@ -3411,19 +3479,19 @@ dummy_func( total_args++; } PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(total_args != 2, CALL); - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + 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, CALL); + DEOPT_IF(meth->ml_flags != METH_O); PyObject *arg = args[1]; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, method->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 // function calls. if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + GOTO_ERROR(error); } res = _PyCFunction_TrampolineCall(cfunc, self, arg); _Py_LeaveRecursiveCallTstate(tstate); @@ -3442,12 +3510,12 @@ dummy_func( total_args++; } PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); PyMethodDef *meth = method->d_method; - DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + 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 = @@ -3471,19 +3539,19 @@ dummy_func( args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); + DEOPT_IF(total_args != 1); PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); PyMethodDef *meth = method->d_method; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, method->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 // function calls. if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + GOTO_ERROR(error); } res = _PyCFunction_TrampolineCall(cfunc, self, NULL); _Py_LeaveRecursiveCallTstate(tstate); @@ -3502,11 +3570,11 @@ dummy_func( } PyMethodDescrObject *method = (PyMethodDescrObject *)callable; /* Builtin METH_FASTCALL methods, without keywords */ - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); PyMethodDef *meth = method->d_method; - DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + DEOPT_IF(meth->ml_flags != METH_FASTCALL); PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, method->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; @@ -3530,7 +3598,7 @@ dummy_func( : PEEK(total_args + 1); int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr - 1, function, arg); + frame, this_instr, function, arg); ERROR_IF(err, error); GO_TO_INSTRUCTION(CALL_KW); } @@ -3570,9 +3638,10 @@ dummy_func( // 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; + GOTO_ERROR(error); } - frame->return_offset = 0; + assert(next_instr - this_instr == 1); + frame->return_offset = 1; DISPATCH_INLINED(new_frame); } /* Callable is not a normal Python function */ @@ -3586,12 +3655,12 @@ dummy_func( if (res == NULL) { _Py_call_instrumentation_exc2( tstate, PY_MONITORING_EVENT_C_RAISE, - frame, next_instr-1, callable, arg); + frame, this_instr, callable, arg); } else { int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, callable, arg); + frame, this_instr, callable, arg); if (err < 0) { Py_CLEAR(res); } @@ -3617,11 +3686,11 @@ dummy_func( assert(kwargs == NULL || PyDict_CheckExact(kwargs)); if (!PyTuple_CheckExact(callargs)) { if (check_args_iterable(tstate, func, callargs) < 0) { - goto error; + GOTO_ERROR(error); } PyObject *tuple = PySequence_Tuple(callargs); if (tuple == NULL) { - goto error; + GOTO_ERROR(error); } Py_SETREF(callargs, tuple); } @@ -3634,18 +3703,18 @@ dummy_func( PyTuple_GET_ITEM(callargs, 0) : Py_None; int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr-1, func, arg); - if (err) goto error; + frame, this_instr, func, arg); + if (err) GOTO_ERROR(error); result = PyObject_Call(func, callargs, kwargs); if (result == NULL) { _Py_call_instrumentation_exc2( tstate, PY_MONITORING_EVENT_C_RAISE, - frame, next_instr-1, func, arg); + frame, this_instr, func, arg); } else { int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, func, arg); + frame, this_instr, func, arg); if (err < 0) { Py_CLEAR(result); } @@ -3666,9 +3735,10 @@ dummy_func( // Need to manually shrink the stack since we exit with DISPATCH_INLINED. STACK_SHRINK(oparg + 3); if (new_frame == NULL) { - goto error; + GOTO_ERROR(error); } - frame->return_offset = 0; + assert(next_instr - this_instr == 1); + frame->return_offset = 1; DISPATCH_INLINED(new_frame); } result = PyObject_Call(func, callargs, kwargs); @@ -3686,7 +3756,7 @@ dummy_func( Py_DECREF(codeobj); if (func_obj == NULL) { - goto error; + GOTO_ERROR(error); } _PyFunction_SetVersion( @@ -3726,11 +3796,12 @@ dummy_func( PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); if (gen == NULL) { - goto error; + GOTO_ERROR(error); } assert(EMPTY()); _PyFrame_SetStackPointer(frame, stack_pointer); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->instr_ptr = next_instr; _PyFrame_Copy(frame, gen_frame); assert(frame->frame_obj == NULL); gen->gi_frame_state = FRAME_CREATED; @@ -3741,6 +3812,7 @@ dummy_func( _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); + LOAD_IP(frame->return_offset); goto resume_frame; } @@ -3784,25 +3856,30 @@ dummy_func( top = Py_NewRef(bottom); } - inst(BINARY_OP, (unused/1, lhs, rhs -- res)) { + specializing op(_SPECIALIZE_BINARY_OP, (counter/1, lhs, rhs -- lhs, rhs)) { + TIER_ONE_ONLY #if ENABLE_SPECIALIZATION - _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY); DISPATCH_SAME_OPARG(); } STAT_INC(BINARY_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); #endif /* ENABLE_SPECIALIZATION */ assert(NB_ADD <= oparg); assert(oparg <= NB_INPLACE_XOR); + } + + op(_BINARY_OP, (lhs, rhs -- res)) { assert(_PyEval_BinaryOps[oparg]); res = _PyEval_BinaryOps[oparg](lhs, rhs); DECREF_INPUTS(); ERROR_IF(res == NULL, error); } + macro(BINARY_OP) = _SPECIALIZE_BINARY_OP + _BINARY_OP; + inst(SWAP, (bottom, unused[oparg-2], top -- top, unused[oparg-2], bottom)) { assert(oparg >= 2); @@ -3810,12 +3887,11 @@ dummy_func( inst(INSTRUMENTED_INSTRUCTION, ( -- )) { int next_opcode = _Py_call_instrumentation_instruction( - tstate, frame, next_instr-1); + tstate, frame, this_instr); ERROR_IF(next_opcode < 0, error); - next_instr--; + next_instr = this_instr; if (_PyOpcode_Caches[next_opcode]) { - _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1); - INCREMENT_ADAPTIVE_COUNTER(cache->counter); + INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); } assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; @@ -3823,41 +3899,38 @@ dummy_func( } inst(INSTRUMENTED_JUMP_FORWARD, ( -- )) { - INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); + INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP); } - inst(INSTRUMENTED_JUMP_BACKWARD, ( -- )) { + inst(INSTRUMENTED_JUMP_BACKWARD, (unused/1 -- )) { CHECK_EVAL_BREAKER(); - INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); + INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP); } inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) { PyObject *cond = POP(); assert(PyBool_Check(cond)); - _Py_CODEUNIT *here = next_instr - 1; int flag = Py_IsTrue(cond); int offset = flag * oparg; #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | flag; #endif - INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) { PyObject *cond = POP(); assert(PyBool_Check(cond)); - _Py_CODEUNIT *here = next_instr - 1; int flag = Py_IsFalse(cond); int offset = flag * oparg; #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | flag; #endif - INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) { PyObject *value = POP(); - _Py_CODEUNIT *here = next_instr - 1; int flag = Py_IsNone(value); int offset; if (flag) { @@ -3868,14 +3941,13 @@ dummy_func( offset = 0; } #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | flag; #endif - INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) { PyObject *value = POP(); - _Py_CODEUNIT *here = next_instr-1; int offset; int nflag = Py_IsNone(value); if (nflag) { @@ -3886,12 +3958,13 @@ dummy_func( offset = oparg; } #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | !nflag; + this_instr[1].cache = (this_instr[1].cache << 1) | !nflag; #endif - INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); } inst(EXTENDED_ARG, ( -- )) { + TIER_ONE_ONLY assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; @@ -3900,53 +3973,61 @@ dummy_func( } inst(CACHE, (--)) { + TIER_ONE_ONLY assert(0 && "Executing a cache."); Py_UNREACHABLE(); } inst(RESERVED, (--)) { + TIER_ONE_ONLY assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); } ///////// Tier-2 only opcodes ///////// - op(_POP_JUMP_IF_FALSE, (flag -- )) { - if (Py_IsFalse(flag)) { - pc = oparg; - } + op (_GUARD_IS_TRUE_POP, (flag -- )) { + DEOPT_IF(Py_IsFalse(flag)); + assert(Py_IsTrue(flag)); } - op(_POP_JUMP_IF_TRUE, (flag -- )) { - if (Py_IsTrue(flag)) { - pc = oparg; - } + op (_GUARD_IS_FALSE_POP, (flag -- )) { + DEOPT_IF(Py_IsTrue(flag)); + assert(Py_IsFalse(flag)); + } + + op (_GUARD_IS_NONE_POP, (val -- )) { + DEOPT_IF(!Py_IsNone(val)); + } + + op (_GUARD_IS_NOT_NONE_POP, (val -- )) { + DEOPT_IF(Py_IsNone(val)); + Py_DECREF(val); } op(_JUMP_TO_TOP, (--)) { - pc = 0; + next_uop = current_executor->trace; CHECK_EVAL_BREAKER(); } op(_SET_IP, (--)) { - frame->prev_instr = ip_offset + oparg; + TIER_TWO_ONLY + // TODO: Put the code pointer in `operand` to avoid indirection via `frame` + frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + oparg; } - op(_SAVE_CURRENT_IP, (--)) { + op(_SAVE_RETURN_OFFSET, (--)) { #if TIER_ONE - frame->prev_instr = next_instr - 1; + frame->return_offset = (uint16_t)(next_instr - this_instr); #endif #if TIER_TWO - // Relies on a preceding _SET_IP - frame->prev_instr--; + frame->return_offset = oparg; #endif } op(_EXIT_TRACE, (--)) { - frame->prev_instr--; // Back up to just before destination - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(self); - return frame; + TIER_TWO_ONLY + GOTO_TIER_ONE(); } op(_INSERT, (unused[oparg], top -- top, unused[oparg])) { @@ -3954,6 +4035,11 @@ dummy_func( memmove(&stack_pointer[-1 - oparg], &stack_pointer[-oparg], oparg * sizeof(stack_pointer[0])); } + op(_CHECK_VALIDITY, (--)) { + TIER_TWO_ONLY + DEOPT_IF(!current_executor->base.vm_data.valid); + } + // END BYTECODES // diff --git a/Python/ceval.c b/Python/ceval.c index cae29e061ce5d3..d92ab926f84963 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -46,12 +46,13 @@ # error "ceval.c must be build with Py_BUILD_CORE define for best performance" #endif -#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) +#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_GIL_DISABLED) // GH-89279: The MSVC compiler does not inline these static inline functions // in PGO build in _PyEval_EvalFrameDefault(), because this function is over // the limit of PGO, and that limit cannot be configured. // Define them as macros to make sure that they are always inlined by the // preprocessor. +// TODO: implement Py_DECREF macro for Py_GIL_DISABLED #undef Py_DECREF #define Py_DECREF(arg) \ @@ -134,14 +135,14 @@ dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer) static void lltrace_instruction(_PyInterpreterFrame *frame, PyObject **stack_pointer, - _Py_CODEUNIT *next_instr) + _Py_CODEUNIT *next_instr, + int opcode, + int oparg) { if (frame->owner == FRAME_OWNED_BY_CSTACK) { return; } dump_stack(frame, stack_pointer); - int oparg = next_instr->op.arg; - int opcode = next_instr->op.code; const char *opname = _PyOpcode_OpName[opcode]; assert(opname != NULL); int offset = (int)(next_instr - _PyCode_CODE(_PyFrame_GetCode(frame))); @@ -201,15 +202,15 @@ maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, _PyInterpreterFrame *skip if (r < 0) { return -1; } - int lltrace = r; + int lltrace = r * 5; // Levels 1-4 only trace uops 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 + // Can also be controlled by environment variable + char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); + if (python_lltrace != NULL && *python_lltrace >= '0') { + lltrace = *python_lltrace - '0'; // TODO: Parse an int and all that } } - if (lltrace) { + if (lltrace >= 5) { lltrace_resume_frame(frame); } return lltrace; @@ -506,7 +507,9 @@ _PyEval_MatchClass(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++) { @@ -522,7 +525,10 @@ _PyEval_MatchClass(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); } } @@ -535,7 +541,10 @@ _PyEval_MatchClass(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)); @@ -602,10 +611,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) return _PyEval_EvalFrame(tstate, f->f_frame, throwflag); } -#define TIER_ONE 1 #include "ceval_macros.h" - int _Py_CheckRecursiveCallPy( PyThreadState *tstate) { @@ -632,12 +639,16 @@ static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = { /* Put a NOP at the start, so that the IP points into * the code, rather than before it */ { .op.code = NOP, .op.arg = 0 }, - { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, - { .op.code = RESUME, .op.arg = 0 } + { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on return */ + { .op.code = NOP, .op.arg = 0 }, + { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on yield */ + { .op.code = RESUME, .op.arg = RESUME_OPARG_DEPTH1_MASK | RESUME_AT_FUNC_START } }; extern const struct _PyCode_DEF(8) _Py_InitCleanup; +extern const char *_PyUOpName(int index); + /* Disable unused label warnings. They are handy for debugging, even if computed gotos aren't used. */ @@ -655,6 +666,15 @@ extern const struct _PyCode_DEF(8) _Py_InitCleanup; * so consume 3 units of C stack */ #define PY_EVAL_C_STACK_UNITS 2 +#if defined(_MSC_VER) && defined(_Py_USING_PGO) +/* gh-111786: _PyEval_EvalFrameDefault is too large to optimize for speed with + PGO on MSVC. Disable that optimization temporarily. If this is fixed + upstream, we should gate this on the version of MSVC. + */ +# pragma optimize("t", off) +/* This setting is reversed below following _PyEval_EvalFrameDefault */ +#endif + PyObject* _Py_HOT_FUNCTION _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) { @@ -669,9 +689,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #ifdef Py_STATS int lastopcode = 0; #endif - // opcode is an 8-bit value to improve the code generated by MSVC - // for the big switch below (in combination with the EXTRA_CASES macro). - uint8_t opcode; /* Current opcode */ + uint8_t opcode; /* Current opcode */ int oparg; /* Current opcode argument, if any */ #ifdef LLTRACE int lltrace = 0; @@ -690,7 +708,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int entry_frame.f_builtins = (PyObject*)0xaaa4; #endif entry_frame.f_executable = Py_None; - entry_frame.prev_instr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS; + entry_frame.instr_ptr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1; entry_frame.stacktop = 0; entry_frame.owner = FRAME_OWNED_BY_CSTACK; entry_frame.return_offset = 0; @@ -714,30 +732,29 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Because this avoids the RESUME, * we need to update instrumentation */ _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - monitor_throw(tstate, frame, frame->prev_instr); + monitor_throw(tstate, frame, frame->instr_ptr); /* TO DO -- Monitor throw entry. */ goto resume_with_error; } + /* State shared between Tier 1 and Tier 2 interpreter */ + _PyUOpExecutorObject *current_executor = NULL; + /* Local "register" variables. * These are cached values from the frame and code object. */ _Py_CODEUNIT *next_instr; PyObject **stack_pointer; -/* Sets the above local variables from the frame */ -#define SET_LOCALS_FROM_FRAME() \ - /* Jump back to the last instruction executed... */ \ - next_instr = frame->prev_instr + 1; \ - stack_pointer = _PyFrame_GetStackPointer(frame); start_frame: if (_Py_EnterRecursivePy(tstate)) { goto exit_unwind; } + next_instr = frame->instr_ptr; resume_frame: - SET_LOCALS_FROM_FRAME(); + stack_pointer = _PyFrame_GetStackPointer(frame); #ifdef LLTRACE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); @@ -766,7 +783,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #include "generated_cases.c.h" /* INSTRUMENTED_LINE has to be here, rather than in bytecodes.c, - * because it needs to capture frame->prev_instr before it is updated, + * because it needs to capture frame->instr_ptr before it is updated, * as happens in the standard instruction prologue. */ #if USE_COMPUTED_GOTOS @@ -775,8 +792,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int case INSTRUMENTED_LINE: #endif { - _Py_CODEUNIT *prev = frame->prev_instr; - _Py_CODEUNIT *here = frame->prev_instr = next_instr; + _Py_CODEUNIT *prev = frame->instr_ptr; + _Py_CODEUNIT *here = frame->instr_ptr = next_instr; _PyFrame_SetStackPointer(frame, stack_pointer); int original_opcode = _Py_call_instrumentation_line( tstate, frame, here, prev); @@ -785,7 +802,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr = here+1; goto error; } - next_instr = frame->prev_instr; + next_instr = frame->instr_ptr; if (next_instr != here) { DISPATCH(); } @@ -803,7 +820,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #if USE_COMPUTED_GOTOS _unknown_opcode: #else - EXTRA_CASES // From pycore_opcode.h, a 'case' for each unused opcode + EXTRA_CASES // From pycore_opcode_metadata.h, a 'case' for each unused opcode #endif /* Tell C compilers not to hold the opcode variable in the loop. next_instr points the current instruction without TARGET(). */ @@ -860,7 +877,7 @@ _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 */ + /* We can't use frame->instr_ptr here, as RERAISE may have set it */ int offset = INSTR_OFFSET()-1; int level, handler, lasti; if (get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti) == 0) { @@ -900,13 +917,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Python main loop. */ PyObject *exc = _PyErr_GetRaisedException(tstate); PUSH(exc); - JUMPTO(handler); + next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + handler; + if (monitor_handled(tstate, frame, next_instr, exc) < 0) { goto exception_unwind; } /* Resume normal execution */ #ifdef LLTRACE - if (lltrace) { + if (lltrace >= 5) { lltrace_resume_frame(frame); } #endif @@ -931,14 +949,151 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } resume_with_error: - SET_LOCALS_FROM_FRAME(); + next_instr = frame->instr_ptr; + stack_pointer = _PyFrame_GetStackPointer(frame); goto error; + + +// The Tier 2 interpreter is also here! +enter_tier_two: + +#undef LOAD_IP +#define LOAD_IP(UNUSED) (void)0 + +#undef GOTO_ERROR +#define GOTO_ERROR(LABEL) goto LABEL ## _tier_two + +#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 + +#ifdef Py_DEBUG + #define DPRINTF(level, ...) \ + if (lltrace >= (level)) { printf(__VA_ARGS__); } +#else + #define DPRINTF(level, ...) +#endif + + OPT_STAT_INC(traces_executed); + _PyUOpInstruction *next_uop = current_executor->trace; + uint16_t uopcode; +#ifdef Py_STATS + uint64_t trace_uop_execution_counter = 0; +#endif + + for (;;) { + uopcode = next_uop->opcode; + DPRINTF(3, + "%4d: uop %s, oparg %d, operand %" PRIu64 ", target %d, stack_level %d\n", + (int)(next_uop - current_executor->trace), + _PyUOpName(uopcode), + next_uop->oparg, + next_uop->operand, + next_uop->target, + (int)(stack_pointer - _PyFrame_Stackbase(frame))); + next_uop++; + OPT_STAT_INC(uops_executed); + UOP_STAT_INC(uopcode, execution_count); +#ifdef Py_STATS + trace_uop_execution_counter++; +#endif + + switch (uopcode) { + +#include "executor_cases.c.h" + + default: +#ifdef Py_DEBUG + { + fprintf(stderr, "Unknown uop %d, oparg %d, operand %" PRIu64 " @ %d\n", + opcode, next_uop[-1].oparg, next_uop[-1].operand, + (int)(next_uop - current_executor->trace - 1)); + Py_FatalError("Unknown uop"); + } +#else + Py_UNREACHABLE(); +#endif + + } + } + +// Jump here from ERROR_IF(..., unbound_local_error) +unbound_local_error_tier_two: + _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) + ); + goto error_tier_two; + +// JUMP to any of these from ERROR_IF(..., error) +pop_4_error_tier_two: + STACK_SHRINK(1); +pop_3_error_tier_two: + STACK_SHRINK(1); +pop_2_error_tier_two: + STACK_SHRINK(1); +pop_1_error_tier_two: + STACK_SHRINK(1); +error_tier_two: + DPRINTF(2, "Error: [UOp %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d -> %s]\n", + uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target, + (int)(next_uop - current_executor->trace - 1), + _PyOpcode_OpName[frame->instr_ptr->op.code]); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); + frame->return_offset = 0; // Don't leave this random + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(current_executor); + goto resume_with_error; + +// Jump here from DEOPT_IF() +deoptimize: + // On DEOPT_IF we just repeat the last instruction. + // This presumes nothing was popped from the stack (nor pushed). + frame->instr_ptr = next_uop[-1].target + _PyCode_CODE(_PyFrame_GetCode(frame)); + DPRINTF(2, "DEOPT: [UOp %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d -> %s]\n", + uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target, + (int)(next_uop - current_executor->trace - 1), + _PyOpcode_OpName[frame->instr_ptr->op.code]); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); + UOP_STAT_INC(uopcode, miss); + frame->return_offset = 0; // Dispatch to frame->instr_ptr + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_DECREF(current_executor); + // Fall through +// Jump here from ENTER_EXECUTOR +enter_tier_one: + next_instr = frame->instr_ptr; + goto resume_frame; + +// Jump here from _EXIT_TRACE +exit_trace: + _PyFrame_SetStackPointer(frame, stack_pointer); + frame->instr_ptr = next_uop[-1].target + _PyCode_CODE(_PyFrame_GetCode(frame)); + Py_DECREF(current_executor); + OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); + goto enter_tier_one; } #if defined(__GNUC__) # pragma GCC diagnostic pop #elif defined(_MSC_VER) /* MS_WINDOWS */ # pragma warning(pop) +# pragma optimize("", on) #endif static void @@ -1445,14 +1600,14 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, continue; PyObject *varname = PyTuple_GET_ITEM(co->co_localsplusnames, i); if (func->func_kwdefaults != NULL) { - PyObject *def = PyDict_GetItemWithError(func->func_kwdefaults, varname); + PyObject *def; + if (PyDict_GetItemRef(func->func_kwdefaults, varname, &def) < 0) { + goto fail_post_args; + } if (def) { - localsplus[i] = Py_NewRef(def); + localsplus[i] = def; continue; } - else if (_PyErr_Occurred(tstate)) { - goto fail_post_args; - } } missing++; } @@ -1767,6 +1922,13 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) fixed_cause = _PyObject_CallNoArgs(cause); if (fixed_cause == NULL) goto raise_error; + if (!PyExceptionInstance_Check(fixed_cause)) { + _PyErr_Format(tstate, PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + cause, Py_TYPE(fixed_cause)); + goto raise_error; + } Py_DECREF(cause); } else if (PyExceptionInstance_Check(cause)) { @@ -2096,7 +2258,7 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) PyThreadState *tstate = _PyThreadState_GET(); if (_PyEval_SetProfile(tstate, func, arg) < 0) { /* Log _PySys_Audit() error */ - _PyErr_WriteUnraisableMsg("in PyEval_SetProfile", NULL); + PyErr_FormatUnraisable("Exception ignored in PyEval_SetProfile"); } } @@ -2113,7 +2275,7 @@ PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg) while (ts) { if (_PyEval_SetProfile(ts, func, arg) < 0) { - _PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL); + PyErr_FormatUnraisable("Exception ignored in PyEval_SetProfileAllThreads"); } HEAD_LOCK(runtime); ts = PyThreadState_Next(ts); @@ -2127,7 +2289,7 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) PyThreadState *tstate = _PyThreadState_GET(); if (_PyEval_SetTrace(tstate, func, arg) < 0) { /* Log _PySys_Audit() error */ - _PyErr_WriteUnraisableMsg("in PyEval_SetTrace", NULL); + PyErr_FormatUnraisable("Exception ignored in PyEval_SetTrace"); } } @@ -2144,7 +2306,7 @@ PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg) while (ts) { if (_PyEval_SetTrace(ts, func, arg) < 0) { - _PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL); + PyErr_FormatUnraisable("Exception ignored in PyEval_SetTraceAllThreads"); } HEAD_LOCK(runtime); ts = PyThreadState_Next(ts); @@ -2254,13 +2416,9 @@ PyEval_GetBuiltins(void) PyObject * _PyEval_GetBuiltin(PyObject *name) { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *attr = PyDict_GetItemWithError(PyEval_GetBuiltins(), name); - if (attr) { - Py_INCREF(attr); - } - else if (!_PyErr_Occurred(tstate)) { - _PyErr_SetObject(tstate, PyExc_AttributeError, name); + PyObject *attr; + if (PyDict_GetItemRef(PyEval_GetBuiltins(), name, &attr) == 0) { + PyErr_SetObject(PyExc_AttributeError, name); } return attr; } @@ -2411,12 +2569,12 @@ static PyObject * import_name(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *name, PyObject *fromlist, PyObject *level) { - PyObject *import_func = _PyDict_GetItemWithError(frame->f_builtins, - &_Py_ID(__import__)); + PyObject *import_func; + if (PyDict_GetItemRef(frame->f_builtins, &_Py_ID(__import__), &import_func) < 0) { + return NULL; + } if (import_func == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); - } + _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); return NULL; } @@ -2427,6 +2585,7 @@ import_name(PyThreadState *tstate, _PyInterpreterFrame *frame, /* Fast path for not overloaded __import__. */ if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) { + Py_DECREF(import_func); int ilevel = PyLong_AsInt(level); if (ilevel == -1 && _PyErr_Occurred(tstate)) { return NULL; @@ -2440,7 +2599,6 @@ import_name(PyThreadState *tstate, _PyInterpreterFrame *frame, } PyObject* args[5] = {name, frame->f_globals, locals, fromlist, level}; - Py_INCREF(import_func); PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL); Py_DECREF(import_func); return res; @@ -2458,11 +2616,10 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) /* Issue #17636: in case this failed because of a circular relative import, try to fallback on reading the module directly from sys.modules. */ - pkgname = PyObject_GetAttr(v, &_Py_ID(__name__)); - if (pkgname == NULL) { - goto error; + if (PyObject_GetOptionalAttr(v, &_Py_ID(__name__), &pkgname) < 0) { + return NULL; } - if (!PyUnicode_Check(pkgname)) { + if (pkgname == NULL || !PyUnicode_Check(pkgname)) { Py_CLEAR(pkgname); goto error; } @@ -2479,42 +2636,59 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) Py_DECREF(pkgname); return x; error: - pkgpath = PyModule_GetFilenameObject(v); if (pkgname == NULL) { pkgname_or_unknown = PyUnicode_FromString(""); if (pkgname_or_unknown == NULL) { - Py_XDECREF(pkgpath); return NULL; } } else { pkgname_or_unknown = pkgname; } + pkgpath = NULL; + if (PyModule_Check(v)) { + pkgpath = PyModule_GetFilenameObject(v); + if (pkgpath == NULL) { + if (!PyErr_ExceptionMatches(PyExc_SystemError)) { + Py_DECREF(pkgname_or_unknown); + return NULL; + } + // module filename missing + _PyErr_Clear(tstate); + } + } if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) { - _PyErr_Clear(tstate); + Py_CLEAR(pkgpath); errmsg = PyUnicode_FromFormat( "cannot import name %R from %R (unknown location)", name, pkgname_or_unknown ); - /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, NULL, name); } else { - PyObject *spec = PyObject_GetAttr(v, &_Py_ID(__spec__)); + PyObject *spec; + int rc = PyObject_GetOptionalAttr(v, &_Py_ID(__spec__), &spec); + if (rc > 0) { + rc = _PyModuleSpec_IsInitializing(spec); + Py_DECREF(spec); + } + if (rc < 0) { + Py_DECREF(pkgname_or_unknown); + Py_DECREF(pkgpath); + return NULL; + } const char *fmt = - _PyModuleSpec_IsInitializing(spec) ? + rc ? "cannot import name %R from partially initialized module %R " "(most likely due to a circular import) (%S)" : "cannot import name %R from %R (%S)"; - Py_XDECREF(spec); errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath); - /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, pkgpath, name); } + /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ + _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, pkgpath, name); Py_XDECREF(errmsg); - Py_XDECREF(pkgname_or_unknown); + Py_DECREF(pkgname_or_unknown); Py_XDECREF(pkgpath); return NULL; } diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index ba16f5eb9bfe74..d70abbc27606b4 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -1,6 +1,5 @@ #include "Python.h" -#include "pycore_atomic.h" // _Py_atomic_int #include "pycore_ceval.h" // _PyEval_SignalReceived() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // _Py_RunGC() @@ -57,113 +56,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); -} - - -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); + _Py_set_eval_breaker_bit(interp, _PY_CALLS_TO_DO_BIT, 0); } - -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); -} - - /* * Implementation of the Global Interpreter Lock (GIL). */ @@ -171,9 +119,6 @@ UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) #include #include -#include "pycore_atomic.h" - - #include "condvar.h" #define MUTEX_INIT(mut) \ @@ -217,8 +162,7 @@ UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) static void _gil_initialize(struct _gil_runtime_state *gil) { - _Py_atomic_int uninitialized = {-1}; - gil->locked = uninitialized; + gil->locked = -1; gil->interval = DEFAULT_INTERVAL; } @@ -227,7 +171,7 @@ static int gil_created(struct _gil_runtime_state *gil) if (gil == NULL) { return 0; } - return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); + return (_Py_atomic_load_int_acquire(&gil->locked) >= 0); } static void create_gil(struct _gil_runtime_state *gil) @@ -240,9 +184,9 @@ 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); + _Py_atomic_store_int_release(&gil->locked, 0); } static void destroy_gil(struct _gil_runtime_state *gil) @@ -256,8 +200,7 @@ static void destroy_gil(struct _gil_runtime_state *gil) COND_FINI(gil->switch_cond); MUTEX_FINI(gil->switch_mutex); #endif - _Py_atomic_store_explicit(&gil->locked, -1, - _Py_memory_order_release); + _Py_atomic_store_int_release(&gil->locked, -1); _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); } @@ -271,8 +214,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 @@ -283,7 +227,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"); } @@ -292,12 +236,12 @@ 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); _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); - _Py_atomic_store_relaxed(&gil->locked, 0); + _Py_atomic_store_int_relaxed(&gil->locked, 0); COND_SIGNAL(gil->cond); MUTEX_UNLOCK(gil->mutex); @@ -310,10 +254,10 @@ 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(_PyThreadState_CheckConsistency(tstate)); RESET_GIL_DROP_REQUEST(tstate->interp); @@ -356,20 +300,15 @@ take_gil(PyThreadState *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)); MUTEX_LOCK(gil->mutex); - if (!_Py_atomic_load_relaxed(&gil->locked)) { - goto _ready; - } - int drop_requested = 0; - while (_Py_atomic_load_relaxed(&gil->locked)) { + while (_Py_atomic_load_int_relaxed(&gil->locked)) { unsigned long saved_switchnum = gil->switch_number; unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); @@ -379,7 +318,7 @@ take_gil(PyThreadState *tstate) /* If we timed out and no switch occurred in the meantime, it is time to ask the GIL-holding thread to drop it. */ if (timed_out && - _Py_atomic_load_relaxed(&gil->locked) && + _Py_atomic_load_int_relaxed(&gil->locked) && gil->switch_number == saved_switchnum) { if (_PyThreadState_MustExit(tstate)) { @@ -402,18 +341,17 @@ take_gil(PyThreadState *tstate) } } -_ready: #ifdef FORCE_SWITCHING /* This mutex must be taken before modifying gil->last_holder: see drop_gil(). */ MUTEX_LOCK(gil->switch_mutex); #endif /* We now hold the GIL */ - _Py_atomic_store_relaxed(&gil->locked, 1); + _Py_atomic_store_int_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; } @@ -431,27 +369,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(_PyThreadState_CheckConsistency(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. - - 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); @@ -499,10 +423,10 @@ 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); + return _Py_atomic_load_int_relaxed(&gil->locked); } static void @@ -523,29 +447,25 @@ init_own_gil(PyInterpreterState *interp, struct _gil_runtime_state *gil) interp->ceval.own_gil = 1; } -PyStatus +void _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); } - return _PyStatus_OK(); + // Lock the GIL and mark the current thread as attached. + _PyThreadState_Attach(tstate); } void @@ -611,8 +531,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 @@ -628,33 +547,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(_PyThreadState_CheckConsistency(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); + _PyThreadState_Detach(tstate); } #ifdef HAVE_FORK @@ -675,9 +582,7 @@ _PyEval_ReInitThreads(PyThreadState *tstate) take_gil(tstate); struct _pending_calls *pending = &tstate->interp->ceval.pending; - if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - return _PyStatus_ERR("Can't reinitialize pending calls lock"); - } + _PyMutex_at_fork_reinit(&pending->mutex); /* Destroy all threads except the current one */ _PyThreadState_DeleteExcept(tstate); @@ -691,18 +596,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; } @@ -710,10 +611,7 @@ void PyEval_RestoreThread(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - _PyThreadState_SwapNoGIL(tstate); + _PyThreadState_Attach(tstate); } @@ -742,28 +640,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, - _Py_pending_call_func func, void *arg) + _Py_pending_call_func func, void *arg, int flags) { int i = pending->last; int j = (i + 1) % NPENDINGCALLS; @@ -772,13 +657,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) { @@ -788,18 +676,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--; } } @@ -810,26 +701,23 @@ _pop_pending_call(struct _pending_calls *pending, int _PyEval_AddPendingCall(PyInterpreterState *interp, - _Py_pending_call_func func, 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; } - /* Ensure that _PyEval_InitState() was called - and that _PyEval_FiniState() is not called yet. */ - assert(pending->lock != NULL); - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); - PyThread_release_lock(pending->lock); + PyMutex_Lock(&pending->mutex); + int result = _push_pending_call(pending, func, arg, flags); + PyMutex_Unlock(&pending->mutex); /* signal main loop */ - SIGNAL_PENDING_CALLS(pending, interp); + SIGNAL_PENDING_CALLS(interp); return result; } @@ -839,40 +727,25 @@ 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(_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) { @@ -880,17 +753,22 @@ _make_pending_calls(struct _pending_calls *pending) for (int i=0; ilock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); - PyThread_release_lock(pending->lock); + PyMutex_Lock(&pending->mutex); + _pop_pending_call(pending, &func, &arg, &flags); + PyMutex_Unlock(&pending->mutex); /* 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; } } @@ -905,7 +783,7 @@ make_pending_calls(PyInterpreterState *interp) /* Only one thread (per interpreter) may run the pending calls at once. In the same way, we don't do recursive pending calls. */ - PyThread_acquire_lock(pending->lock, WAIT_LOCK); + PyMutex_Lock(&pending->mutex); if (pending->busy) { /* A pending call was added after another thread was already handling the pending calls (and had already "unsignaled"). @@ -917,11 +795,11 @@ make_pending_calls(PyInterpreterState *interp) care of any remaining pending calls. Until then, though, all the interpreter's threads will be tripping the eval breaker every time it's checked. */ - PyThread_release_lock(pending->lock); + PyMutex_Unlock(&pending->mutex); return 0; } pending->busy = 1; - PyThread_release_lock(pending->lock); + PyMutex_Unlock(&pending->mutex); /* unsignal before starting to call callbacks, so that any callback added in-between re-signals */ @@ -930,7 +808,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; } @@ -938,7 +816,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; } } @@ -1002,23 +880,9 @@ Py_MakePendingCalls(void) } void -_PyEval_InitState(PyInterpreterState *interp, PyThread_type_lock pending_lock) +_PyEval_InitState(PyInterpreterState *interp) { _gil_initialize(&interp->_gil); - - struct _pending_calls *pending = &interp->ceval.pending; - assert(pending->lock == NULL); - pending->lock = pending_lock; -} - -void -_PyEval_FiniState(struct _ceval_state *ceval) -{ - struct _pending_calls *pending = &ceval->pending; - if (pending->lock != NULL) { - PyThread_free_lock(pending->lock); - pending->lock = NULL; - } } @@ -1083,70 +947,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 012750df387c1c..ac44aecae046d8 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -1,4 +1,4 @@ -// Macros and other things needed by ceval.c, executor.c, and bytecodes.c +// Macros and other things needed by ceval.c, and bytecodes.c /* Computed GOTOs, or the-optimization-commonly-but-improperly-known-as-"threaded code" @@ -60,29 +60,28 @@ #endif #ifdef Py_STATS -#define INSTRUCTION_START(op) \ +#define INSTRUCTION_STATS(op) \ do { \ - frame->prev_instr = next_instr++; \ OPCODE_EXE_INC(op); \ if (_Py_stats) _Py_stats->opcode_stats[lastopcode].pair_count[op]++; \ lastopcode = op; \ } while (0) #else -#define INSTRUCTION_START(op) (frame->prev_instr = next_instr++) +#define INSTRUCTION_STATS(op) ((void)0) #endif #if USE_COMPUTED_GOTOS -# define TARGET(op) TARGET_##op: INSTRUCTION_START(op); +# define TARGET(op) TARGET_##op: # define DISPATCH_GOTO() goto *opcode_targets[opcode] #else -# define TARGET(op) case op: TARGET_##op: INSTRUCTION_START(op); +# define TARGET(op) case op: TARGET_##op: # define DISPATCH_GOTO() goto dispatch_opcode #endif /* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ #ifdef LLTRACE -#define PRE_DISPATCH_GOTO() if (lltrace) { \ - lltrace_instruction(frame, stack_pointer, next_instr); } +#define PRE_DISPATCH_GOTO() if (lltrace >= 5) { \ + lltrace_instruction(frame, stack_pointer, next_instr, opcode, oparg); } #else #define PRE_DISPATCH_GOTO() ((void)0) #endif @@ -107,18 +106,20 @@ do { \ assert(tstate->interp->eval_frame == NULL); \ _PyFrame_SetStackPointer(frame, stack_pointer); \ - frame->prev_instr = next_instr - 1; \ (NEW_FRAME)->previous = frame; \ frame = tstate->current_frame = (NEW_FRAME); \ CALL_STAT_INC(inlined_py_calls); \ goto start_frame; \ } while (0) +// Use this instead of 'goto error' so Tier 2 can go to a different label +#define GOTO_ERROR(LABEL) goto LABEL + #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; \ + GOTO_ERROR(error); \ } \ } @@ -146,7 +147,6 @@ GETITEM(PyObject *v, Py_ssize_t i) { opcode = word.op.code; \ oparg = word.op.arg; \ } while (0) -#define JUMPTO(x) (next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + (x)) /* JUMPBY makes the generator identify the instruction as a jump. SKIP_OVER is * for advancing to the next instruction, taking into account cache entries @@ -258,10 +258,6 @@ GETITEM(PyObject *v, Py_ssize_t i) { if (ADAPTIVE_COUNTER_IS_ZERO(next_instr->cache)) { \ STAT_INC((INSTNAME), deopt); \ } \ - else { \ - /* This is about to be (incorrectly) incremented: */ \ - STAT_DEC((INSTNAME), deferred); \ - } \ } while (0) #else #define UPDATE_MISS_STATS(INSTNAME) ((void)0) @@ -325,7 +321,7 @@ do { \ }\ else { \ result = PyFloat_FromDouble(dval); \ - if ((result) == NULL) goto error; \ + if ((result) == NULL) GOTO_ERROR(error); \ _Py_DECREF_NO_DEALLOC(left); \ _Py_DECREF_NO_DEALLOC(right); \ } \ @@ -372,28 +368,19 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { /* 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) + * These need to treated differently by tier 1 and 2. + * The Tier 1 version is here; Tier 2 is inlined in ceval.c. */ -#define LOAD_SP() \ -stack_pointer = _PyFrame_GetStackPointer(frame); - -#endif - - -#if TIER_TWO +#define LOAD_IP(OFFSET) do { \ + next_instr = frame->instr_ptr + (OFFSET); \ + } while (0) -#define LOAD_IP() \ -do { ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; } while (0) +/* There's no STORE_IP(), it's inlined by the code generator. */ #define STORE_SP() \ _PyFrame_SetStackPointer(frame, stack_pointer) @@ -401,8 +388,12 @@ _PyFrame_SetStackPointer(frame, stack_pointer) #define LOAD_SP() \ stack_pointer = _PyFrame_GetStackPointer(frame); -#endif +/* Tier-switching macros. */ +#define GOTO_TIER_TWO() goto enter_tier_two; +#define GOTO_TIER_ONE() goto exit_trace; +#define CURRENT_OPARG() (next_uop[-1].oparg) +#define CURRENT_OPERAND() (next_uop[-1].operand) diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h index a8453e25807b0d..730fa8ef2a2154 100644 --- a/Python/clinic/Python-tokenize.c.h +++ b/Python/clinic/Python-tokenize.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() static PyObject * tokenizeriter_new_impl(PyTypeObject *type, PyObject *readline, @@ -79,4 +80,4 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=406b5a433a59069c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dcd6ec48f06a092e input=a9049054013a1b77]*/ diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h index cf3c73b1cf0e6e..98dc49db3059b1 100644 --- a/Python/clinic/_warnings.c.h +++ b/Python/clinic/_warnings.c.h @@ -7,6 +7,7 @@ preserve # include "pycore_runtime.h" // _Py_ID() #endif #include "pycore_abstract.h" // _PyNumber_Index() +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(warnings_warn__doc__, "warn($module, /, message, category=None, stacklevel=1, source=None, *,\n" @@ -243,4 +244,4 @@ warnings_filters_mutated(PyObject *module, PyObject *Py_UNUSED(ignored)) { return warnings_filters_mutated_impl(module); } -/*[clinic end generated code: output=8c396a721ef75739 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f2d4214c382717a6 input=a9049054013a1b77]*/ diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index b4dcc6bf1d2978..8d40e659b54a57 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(builtin___import____doc__, "__import__($module, /, name, globals=None, locals=None, fromlist=(),\n" @@ -1211,4 +1212,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=607c62f2341ebfc0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31bded5d08647a57 input=a9049054013a1b77]*/ diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h index 292d3f7f4ff49c..997ac6f63384a9 100644 --- a/Python/clinic/context.c.h +++ b/Python/clinic/context.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(_contextvars_Context_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -177,4 +179,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=2436b16a92452869 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b667826178444c3f input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 890c3026fc9996..5edeaef656ef62 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_imp_lock_held__doc__, "lock_held($module, /)\n" @@ -604,10 +605,6 @@ _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb if (PyObject_GetBuffer(args[1], &source, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&source, 'C')) { - _PyArg_BadArgument("source_hash", "argument 'source'", "contiguous buffer", args[1]); - goto exit; - } return_value = _imp_source_hash_impl(module, key, &source); exit: @@ -626,4 +623,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=058f6aa1c9f4ebe4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dbd63707bd40b07c input=a9049054013a1b77]*/ diff --git a/Python/clinic/instrumentation.c.h b/Python/clinic/instrumentation.c.h index 1b1b6d048b0dd0..8dae747c44a543 100644 --- a/Python/clinic/instrumentation.c.h +++ b/Python/clinic/instrumentation.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(monitoring_use_tool_id__doc__, "use_tool_id($module, tool_id, name, /)\n" "--\n" @@ -302,4 +304,4 @@ monitoring__all_events(PyObject *module, PyObject *Py_UNUSED(ignored)) { return monitoring__all_events_impl(module); } -/*[clinic end generated code: output=46f449b18195f976 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=14ffc0884a6de50a input=a9049054013a1b77]*/ diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h index 16e48f77c87fdb..e6b0f1999a41c5 100644 --- a/Python/clinic/marshal.c.h +++ b/Python/clinic/marshal.c.h @@ -2,6 +2,8 @@ preserve [clinic start generated code]*/ +#include "pycore_modsupport.h" // _PyArg_CheckPositional() + PyDoc_STRVAR(marshal_dump__doc__, "dump($module, value, file, version=version, /)\n" "--\n" @@ -141,10 +143,6 @@ marshal_loads(PyObject *module, PyObject *arg) if (PyObject_GetBuffer(arg, &bytes, PyBUF_SIMPLE) != 0) { goto exit; } - if (!PyBuffer_IsContiguous(&bytes, 'C')) { - _PyArg_BadArgument("loads", "argument", "contiguous buffer", arg); - goto exit; - } return_value = marshal_loads_impl(module, &bytes); exit: @@ -155,4 +153,4 @@ marshal_loads(PyObject *module, PyObject *arg) return return_value; } -/*[clinic end generated code: output=23091e077319f596 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=92d2d47aac9128ee input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 30691c3d08ae67..93b8385a5b4097 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(sys_addaudithook__doc__, "addaudithook($module, /, hook)\n" @@ -288,6 +289,40 @@ sys_intern(PyObject *module, PyObject *arg) return return_value; } +PyDoc_STRVAR(sys__is_interned__doc__, +"_is_interned($module, string, /)\n" +"--\n" +"\n" +"Return True if the given string is \"interned\"."); + +#define SYS__IS_INTERNED_METHODDEF \ + {"_is_interned", (PyCFunction)sys__is_interned, METH_O, sys__is_interned__doc__}, + +static int +sys__is_interned_impl(PyObject *module, PyObject *string); + +static PyObject * +sys__is_interned(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *string; + int _return_value; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("_is_interned", "argument", "str", arg); + goto exit; + } + string = arg; + _return_value = sys__is_interned_impl(module, string); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(sys__settraceallthreads__doc__, "_settraceallthreads($module, arg, /)\n" "--\n" @@ -1380,6 +1415,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) */ @@ -1423,4 +1486,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=549bb1f92a15f916 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3dc3b2cb0ce38ebb input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index c5687e30748782..aee08d6ad97047 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(tb_new__doc__, "TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" @@ -77,4 +78,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=57e27eb68d04d842 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4e2f6b935841b09c input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index b79bf555f2f22a..d8fe7b22063a80 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -146,15 +146,14 @@ PyObject *_PyCodec_Lookup(const char *encoding) PyUnicode_InternInPlace(&v); /* First, try to lookup the name in the registry dictionary */ - PyObject *result = PyDict_GetItemWithError(interp->codec_search_cache, v); + PyObject *result; + if (PyDict_GetItemRef(interp->codec_search_cache, v, &result) < 0) { + goto onError; + } if (result != NULL) { - Py_INCREF(result); Py_DECREF(v); return result; } - else if (PyErr_Occurred()) { - goto onError; - } /* Next, scan the search functions in order of registration */ const Py_ssize_t len = PyList_Size(interp->codec_search_path); @@ -932,8 +931,6 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) return Py_BuildValue("(Nn)", res, end); } -static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; - PyObject *PyCodec_NameReplaceErrors(PyObject *exc) { if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { @@ -954,13 +951,9 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; - if (!ucnhash_capi) { - /* load the unicode data module */ - ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( - PyUnicodeData_CAPSULE_NAME, 1); - if (!ucnhash_capi) { - return NULL; - } + _PyUnicode_Name_CAPI *ucnhash_capi = _PyUnicode_GetNameCAPI(); + if (ucnhash_capi == NULL) { + return NULL; } for (i = start, ressize = 0; i < end; ++i) { /* object is guaranteed to be "ready" */ diff --git a/Python/compile.c b/Python/compile.c index 1d9ae626677310..8b9e2f02048f11 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -34,7 +34,6 @@ #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() @@ -884,49 +883,49 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) } int -PyUnstable_OpcodeIsValid(int opcode) +_PyCompile_OpcodeIsValid(int opcode) { return IS_VALID_OPCODE(opcode); } int -PyUnstable_OpcodeHasArg(int opcode) +_PyCompile_OpcodeHasArg(int opcode) { return OPCODE_HAS_ARG(opcode); } int -PyUnstable_OpcodeHasConst(int opcode) +_PyCompile_OpcodeHasConst(int opcode) { return OPCODE_HAS_CONST(opcode); } int -PyUnstable_OpcodeHasName(int opcode) +_PyCompile_OpcodeHasName(int opcode) { return OPCODE_HAS_NAME(opcode); } int -PyUnstable_OpcodeHasJump(int opcode) +_PyCompile_OpcodeHasJump(int opcode) { return OPCODE_HAS_JUMP(opcode); } int -PyUnstable_OpcodeHasFree(int opcode) +_PyCompile_OpcodeHasFree(int opcode) { return OPCODE_HAS_FREE(opcode); } int -PyUnstable_OpcodeHasLocal(int opcode) +_PyCompile_OpcodeHasLocal(int opcode) { return OPCODE_HAS_LOCAL(opcode); } int -PyUnstable_OpcodeHasExc(int opcode) +_PyCompile_OpcodeHasExc(int opcode) { return IS_BLOCK_PUSH_OPCODE(opcode); } @@ -1383,7 +1382,7 @@ compiler_enter_scope(struct compiler *c, identifier name, else { RETURN_IF_ERROR(compiler_set_qualname(c)); } - ADDOP_I(c, loc, RESUME, 0); + ADDOP_I(c, loc, RESUME, RESUME_AT_FUNC_START); if (u->u_scope_type == COMPILER_SCOPE_MODULE) { loc.lineno = -1; @@ -1407,8 +1406,8 @@ compiler_exit_scope(struct compiler *c) assert(c->u); /* we are deleting from a list so this really shouldn't fail */ if (PySequence_DelItem(c->c_stack, n) < 0) { - _PyErr_WriteUnraisableMsg("on removing the last compiler " - "stack item", NULL); + PyErr_FormatUnraisable("Exception ignored on removing " + "the last compiler stack item"); } } else { @@ -1550,9 +1549,9 @@ compiler_add_yield_from(struct compiler *c, location loc, int await) // Set up a virtual try/except to handle when StopIteration is raised during // a close or throw call. The only way YIELD_VALUE raises if they do! ADDOP_JUMP(c, loc, SETUP_FINALLY, fail); - ADDOP_I(c, loc, YIELD_VALUE, 0); + ADDOP_I(c, loc, YIELD_VALUE, 1); ADDOP(c, NO_LOCATION, POP_BLOCK); - ADDOP_I(c, loc, RESUME, await ? 3 : 2); + ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM); ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send); USE_LABEL(c, fail); @@ -4161,7 +4160,7 @@ addop_yield(struct compiler *c, location loc) { ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP); } ADDOP_I(c, loc, YIELD_VALUE, 0); - ADDOP_I(c, loc, RESUME, 1); + ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD); return SUCCESS; } @@ -5043,8 +5042,12 @@ compiler_joined_str(struct compiler *c, expr_ty e) } else { VISIT_SEQ(c, expr, e->v.JoinedStr.values); - if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) { - ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); + if (value_count > 1) { + ADDOP_I(c, loc, BUILD_STRING, value_count); + } + else if (value_count == 0) { + _Py_DECLARE_STR(empty, ""); + ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty))); } } return SUCCESS; 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/critical_section.c b/Python/critical_section.c new file mode 100644 index 00000000000000..2214d80eeb297b --- /dev/null +++ b/Python/critical_section.c @@ -0,0 +1,100 @@ +#include "Python.h" + +#include "pycore_lock.h" +#include "pycore_critical_section.h" + +static_assert(_Alignof(_PyCriticalSection) >= 4, + "critical section must be aligned to at least 4 bytes"); + +void +_PyCriticalSection_BeginSlow(_PyCriticalSection *c, PyMutex *m) +{ + PyThreadState *tstate = _PyThreadState_GET(); + c->mutex = NULL; + c->prev = (uintptr_t)tstate->critical_section; + tstate->critical_section = (uintptr_t)c; + + _PyMutex_LockSlow(m); + c->mutex = m; +} + +void +_PyCriticalSection2_BeginSlow(_PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2, + int is_m1_locked) +{ + PyThreadState *tstate = _PyThreadState_GET(); + c->base.mutex = NULL; + c->mutex2 = NULL; + c->base.prev = tstate->critical_section; + tstate->critical_section = (uintptr_t)c | _Py_CRITICAL_SECTION_TWO_MUTEXES; + + if (!is_m1_locked) { + PyMutex_Lock(m1); + } + PyMutex_Lock(m2); + c->base.mutex = m1; + c->mutex2 = m2; +} + +static _PyCriticalSection * +untag_critical_section(uintptr_t tag) +{ + return (_PyCriticalSection *)(tag & ~_Py_CRITICAL_SECTION_MASK); +} + +// Release all locks held by critical sections. This is called by +// _PyThreadState_Detach. +void +_PyCriticalSection_SuspendAll(PyThreadState *tstate) +{ + uintptr_t *tagptr = &tstate->critical_section; + while (_PyCriticalSection_IsActive(*tagptr)) { + _PyCriticalSection *c = untag_critical_section(*tagptr); + + if (c->mutex) { + PyMutex_Unlock(c->mutex); + if ((*tagptr & _Py_CRITICAL_SECTION_TWO_MUTEXES)) { + _PyCriticalSection2 *c2 = (_PyCriticalSection2 *)c; + if (c2->mutex2) { + PyMutex_Unlock(c2->mutex2); + } + } + } + + *tagptr |= _Py_CRITICAL_SECTION_INACTIVE; + tagptr = &c->prev; + } +} + +void +_PyCriticalSection_Resume(PyThreadState *tstate) +{ + uintptr_t p = tstate->critical_section; + _PyCriticalSection *c = untag_critical_section(p); + assert(!_PyCriticalSection_IsActive(p)); + + PyMutex *m1 = c->mutex; + c->mutex = NULL; + + PyMutex *m2 = NULL; + _PyCriticalSection2 *c2 = NULL; + if ((p & _Py_CRITICAL_SECTION_TWO_MUTEXES)) { + c2 = (_PyCriticalSection2 *)c; + m2 = c2->mutex2; + c2->mutex2 = NULL; + } + + if (m1) { + PyMutex_Lock(m1); + } + if (m2) { + PyMutex_Lock(m2); + } + + c->mutex = m1; + if (m2) { + c2->mutex2 = m2; + } + + tstate->critical_section &= ~_Py_CRITICAL_SECTION_INACTIVE; +} diff --git a/Python/crossinterp.c b/Python/crossinterp.c new file mode 100644 index 00000000000000..c6ed7daeb1074a --- /dev/null +++ b/Python/crossinterp.c @@ -0,0 +1,2294 @@ + +/* API for managing interactions between isolated interpreters */ + +#include "Python.h" +#include "pycore_ceval.h" // _Py_simple_func +#include "pycore_crossinterp.h" // struct _xid +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_namespace.h" //_PyNamespace_New() +#include "pycore_pyerrors.h" // _PyErr_Clear() +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_typeobject.h" // _PyType_GetModuleName() +#include "pycore_weakref.h" // _PyWeakref_GET_REF() + + +/**************/ +/* exceptions */ +/**************/ + +/* InterpreterError extends Exception */ + +static PyTypeObject _PyExc_InterpreterError = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "InterpreterError", + .tp_doc = PyDoc_STR("An interpreter was not found."), + //.tp_base = (PyTypeObject *)PyExc_BaseException, +}; +PyObject *PyExc_InterpreterError = (PyObject *)&_PyExc_InterpreterError; + +/* InterpreterNotFoundError extends InterpreterError */ + +static PyTypeObject _PyExc_InterpreterNotFoundError = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "InterpreterNotFoundError", + .tp_doc = PyDoc_STR("An interpreter was not found."), + .tp_base = &_PyExc_InterpreterError, +}; +PyObject *PyExc_InterpreterNotFoundError = (PyObject *)&_PyExc_InterpreterNotFoundError; + +/* lifecycle */ + +static int +init_exceptions(PyInterpreterState *interp) +{ + _PyExc_InterpreterError.tp_base = (PyTypeObject *)PyExc_BaseException; + if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterError) < 0) { + return -1; + } + if (_PyStaticType_InitBuiltin(interp, &_PyExc_InterpreterNotFoundError) < 0) { + return -1; + } + return 0; +} + +static void +fini_exceptions(PyInterpreterState *interp) +{ + _PyStaticType_Dealloc(interp, &_PyExc_InterpreterNotFoundError); + _PyStaticType_Dealloc(interp, &_PyExc_InterpreterError); +} + + +/***************************/ +/* cross-interpreter calls */ +/***************************/ + +int +_Py_CallInInterpreter(PyInterpreterState *interp, + _Py_simple_func func, void *arg) +{ + if (interp == _PyThreadState_GetCurrent()->interp) { + return func(arg); + } + // XXX Emit a warning if this fails? + _PyEval_AddPendingCall(interp, (_Py_pending_call_func)func, arg, 0); + return 0; +} + +int +_Py_CallInInterpreterAndRawFree(PyInterpreterState *interp, + _Py_simple_func func, void *arg) +{ + if (interp == _PyThreadState_GetCurrent()->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; +} + + +/**************************/ +/* cross-interpreter data */ +/**************************/ + +_PyCrossInterpreterData * +_PyCrossInterpreterData_New(void) +{ + _PyCrossInterpreterData *xid = PyMem_RawMalloc( + sizeof(_PyCrossInterpreterData)); + if (xid == NULL) { + PyErr_NoMemory(); + } + return xid; +} + +void +_PyCrossInterpreterData_Free(_PyCrossInterpreterData *xid) +{ + PyInterpreterState *interp = PyInterpreterState_Get(); + _PyCrossInterpreterData_Clear(interp, xid); + PyMem_RawFree(xid); +} + + +/* exceptions */ + +static PyStatus +_init_not_shareable_error_type(PyInterpreterState *interp) +{ + const char *name = "_interpreters.NotShareableError"; + PyObject *base = PyExc_ValueError; + PyObject *ns = NULL; + PyObject *exctype = PyErr_NewException(name, base, ns); + if (exctype == NULL) { + PyErr_Clear(); + return _PyStatus_ERR("could not initialize NotShareableError"); + } + + interp->xi.PyExc_NotShareableError = exctype; + return _PyStatus_OK(); +} + +static void +_fini_not_shareable_error_type(PyInterpreterState *interp) +{ + Py_CLEAR(interp->xi.PyExc_NotShareableError); +} + +static PyObject * +_get_not_shareable_error_type(PyInterpreterState *interp) +{ + assert(interp->xi.PyExc_NotShareableError != NULL); + return interp->xi.PyExc_NotShareableError; +} + + +/* defining cross-interpreter data */ + +static inline void +_xidata_init(_PyCrossInterpreterData *data) +{ + // If the value is being reused + // then _xidata_clear() should have been called already. + assert(data->data == NULL); + assert(data->obj == NULL); + *data = (_PyCrossInterpreterData){0}; + data->interpid = -1; +} + +static inline void +_xidata_clear(_PyCrossInterpreterData *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; + } + Py_CLEAR(data->obj); +} + +void +_PyCrossInterpreterData_Init(_PyCrossInterpreterData *data, + PyInterpreterState *interp, + void *shared, PyObject *obj, + xid_newobjectfunc new_object) +{ + assert(data != NULL); + assert(new_object != NULL); + _xidata_init(data); + data->data = shared; + if (obj != NULL) { + assert(interp != NULL); + // released in _PyCrossInterpreterData_Clear() + data->obj = Py_NewRef(obj); + } + // Ideally every object would know its owning interpreter. + // Until then, we have to rely on the caller to identify it + // (but we don't need it in all cases). + data->interpid = (interp != NULL) ? interp->id : -1; + data->new_object = new_object; +} + +int +_PyCrossInterpreterData_InitWithSize(_PyCrossInterpreterData *data, + PyInterpreterState *interp, + const size_t size, PyObject *obj, + xid_newobjectfunc new_object) +{ + assert(size > 0); + // For now we always free the shared data in the same interpreter + // where it was allocated, so the interpreter is required. + assert(interp != NULL); + _PyCrossInterpreterData_Init(data, interp, NULL, obj, new_object); + data->data = PyMem_RawMalloc(size); + if (data->data == NULL) { + return -1; + } + data->free = PyMem_RawFree; + return 0; +} + +void +_PyCrossInterpreterData_Clear(PyInterpreterState *interp, + _PyCrossInterpreterData *data) +{ + assert(data != NULL); + // This must be called in the owning interpreter. + assert(interp == NULL + || data->interpid == -1 + || data->interpid == interp->id); + _xidata_clear(data); +} + + +/* using cross-interpreter data */ + +static int +_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) +{ + // data->data can be anything, including NULL, so we don't check it. + + // data->obj may be NULL, so we don't check it. + + if (data->interpid < 0) { + _PyErr_SetString(tstate, PyExc_SystemError, "missing interp"); + return -1; + } + + if (data->new_object == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func"); + return -1; + } + + // data->free may be NULL, so we don't check it. + + return 0; +} + +static crossinterpdatafunc _lookup_getdata_from_registry( + PyInterpreterState *, PyObject *); + +static crossinterpdatafunc +_lookup_getdata(PyInterpreterState *interp, PyObject *obj) +{ + /* Cross-interpreter objects are looked up by exact match on the class. + We can reassess this policy when we move from a global registry to a + tp_* slot. */ + return _lookup_getdata_from_registry(interp, obj); +} + +crossinterpdatafunc +_PyCrossInterpreterData_Lookup(PyObject *obj) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return _lookup_getdata(interp, obj); +} + +static inline void +_set_xid_lookup_failure(PyInterpreterState *interp, + PyObject *obj, const char *msg) +{ + PyObject *exctype = _get_not_shareable_error_type(interp); + assert(exctype != NULL); + if (msg != NULL) { + assert(obj == NULL); + PyErr_SetString(exctype, msg); + } + else if (obj == NULL) { + PyErr_SetString(exctype, + "object does not support cross-interpreter data"); + } + else { + PyErr_Format(exctype, + "%S does not support cross-interpreter data", obj); + } +} + +int +_PyObject_CheckCrossInterpreterData(PyObject *obj) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + crossinterpdatafunc getdata = _lookup_getdata(interp, obj); + if (getdata == NULL) { + if (!PyErr_Occurred()) { + _set_xid_lookup_failure(interp, obj, NULL); + } + return -1; + } + return 0; +} + +int +_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) +{ + PyThreadState *tstate = _PyThreadState_GetCurrent(); +#ifdef Py_DEBUG + // The caller must hold the GIL + _Py_EnsureTstateNotNULL(tstate); +#endif + PyInterpreterState *interp = tstate->interp; + + // Reset data before re-populating. + *data = (_PyCrossInterpreterData){0}; + data->interpid = -1; + + // Call the "getdata" func for the object. + Py_INCREF(obj); + crossinterpdatafunc getdata = _lookup_getdata(interp, obj); + if (getdata == NULL) { + Py_DECREF(obj); + if (!PyErr_Occurred()) { + _set_xid_lookup_failure(interp, obj, NULL); + } + return -1; + } + int res = getdata(tstate, obj, data); + Py_DECREF(obj); + if (res != 0) { + return -1; + } + + // Fill in the blanks and validate the result. + data->interpid = interp->id; + if (_check_xidata(tstate, data) != 0) { + (void)_PyCrossInterpreterData_Release(data); + return -1; + } + + return 0; +} + +PyObject * +_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) +{ + return data->new_object(data); +} + +static int +_call_clear_xidata(void *data) +{ + _xidata_clear((_PyCrossInterpreterData *)data); + return 0; +} + +static int +_xidata_release(_PyCrossInterpreterData *data, int rawfree) +{ + if ((data->data == NULL || data->free == NULL) && data->obj == NULL) { + // Nothing to release! + if (rawfree) { + PyMem_RawFree(data); + } + else { + data->data = NULL; + } + return 0; + } + + // Switch to the original interpreter. + PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interpid); + if (interp == NULL) { + // The interpreter was already destroyed. + // 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. + 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} */ + +/* 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. */ + +static inline struct _xidregistry * +_get_global_xidregistry(_PyRuntimeState *runtime) +{ + return &runtime->xi.registry; +} + +static inline struct _xidregistry * +_get_xidregistry(PyInterpreterState *interp) +{ + return &interp->xi.registry; +} + +static inline struct _xidregistry * +_get_xidregistry_for_type(PyInterpreterState *interp, PyTypeObject *cls) +{ + struct _xidregistry *registry = _get_global_xidregistry(interp->runtime); + if (cls->tp_flags & Py_TPFLAGS_HEAPTYPE) { + registry = _get_xidregistry(interp); + } + return registry; +} + +static int +_xidregistry_add_type(struct _xidregistry *xidregistry, + PyTypeObject *cls, crossinterpdatafunc getdata) +{ + struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); + if (newhead == NULL) { + 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->next = xidregistry->head; + if (newhead->next != NULL) { + newhead->next->prev = newhead; + } + xidregistry->head = newhead; + return 0; +} + +static struct _xidregitem * +_xidregistry_remove_entry(struct _xidregistry *xidregistry, + struct _xidregitem *entry) +{ + struct _xidregitem *next = entry->next; + if (entry->prev != NULL) { + assert(entry->prev->next == entry); + entry->prev->next = next; + } + else { + assert(xidregistry->head == entry); + xidregistry->head = next; + } + if (next != NULL) { + next->prev = entry->prev; + } + Py_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 void +_xidregistry_lock(struct _xidregistry *registry) +{ + if (registry->global) { + PyMutex_Lock(®istry->mutex); + } + // else: Within an interpreter we rely on the GIL instead of a separate lock. +} + +static void +_xidregistry_unlock(struct _xidregistry *registry) +{ + if (registry->global) { + PyMutex_Unlock(®istry->mutex); + } +} + +static struct _xidregitem * +_xidregistry_find_type(struct _xidregistry *xidregistry, PyTypeObject *cls) +{ + struct _xidregitem *cur = xidregistry->head; + while (cur != NULL) { + 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); + } + if (cur->cls == cls) { + return cur; + } + cur = cur->next; + } + return NULL; +} + +int +_PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, + crossinterpdatafunc getdata) +{ + if (!PyType_Check(cls)) { + PyErr_Format(PyExc_ValueError, "only classes may be registered"); + return -1; + } + if (getdata == NULL) { + PyErr_Format(PyExc_ValueError, "missing 'getdata' func"); + return -1; + } + + int res = 0; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _xidregistry *xidregistry = _get_xidregistry_for_type(interp, cls); + _xidregistry_lock(xidregistry); + + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + if (matched != NULL) { + assert(matched->getdata == getdata); + matched->refcount += 1; + goto finally; + } + + res = _xidregistry_add_type(xidregistry, cls, getdata); + +finally: + _xidregistry_unlock(xidregistry); + return res; +} + +int +_PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) +{ + int res = 0; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _xidregistry *xidregistry = _get_xidregistry_for_type(interp, cls); + _xidregistry_lock(xidregistry); + + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + if (matched != NULL) { + assert(matched->refcount > 0); + matched->refcount -= 1; + if (matched->refcount == 0) { + (void)_xidregistry_remove_entry(xidregistry, matched); + } + res = 1; + } + + _xidregistry_unlock(xidregistry); + return res; +} + +static crossinterpdatafunc +_lookup_getdata_from_registry(PyInterpreterState *interp, PyObject *obj) +{ + PyTypeObject *cls = Py_TYPE(obj); + + struct _xidregistry *xidregistry = _get_xidregistry_for_type(interp, cls); + _xidregistry_lock(xidregistry); + + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + crossinterpdatafunc func = matched != NULL ? matched->getdata : NULL; + + _xidregistry_unlock(xidregistry); + return func; +} + +/* cross-interpreter data for builtin types */ + +// bytes + +struct _shared_bytes_data { + char *bytes; + Py_ssize_t len; +}; + +static PyObject * +_new_bytes_object(_PyCrossInterpreterData *data) +{ + struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data); + return PyBytes_FromStringAndSize(shared->bytes, shared->len); +} + +static int +_bytes_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _shared_bytes_data), obj, + _new_bytes_object + ) < 0) + { + return -1; + } + struct _shared_bytes_data *shared = (struct _shared_bytes_data *)data->data; + if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { + _PyCrossInterpreterData_Clear(tstate->interp, data); + return -1; + } + return 0; +} + +// str + +struct _shared_str_data { + int kind; + const void *buffer; + Py_ssize_t len; +}; + +static PyObject * +_new_str_object(_PyCrossInterpreterData *data) +{ + struct _shared_str_data *shared = (struct _shared_str_data *)(data->data); + return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len); +} + +static int +_str_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _shared_str_data), obj, + _new_str_object + ) < 0) + { + return -1; + } + struct _shared_str_data *shared = (struct _shared_str_data *)data->data; + shared->kind = PyUnicode_KIND(obj); + shared->buffer = PyUnicode_DATA(obj); + shared->len = PyUnicode_GET_LENGTH(obj); + return 0; +} + +// int + +static PyObject * +_new_long_object(_PyCrossInterpreterData *data) +{ + return PyLong_FromSsize_t((Py_ssize_t)(data->data)); +} + +static int +_long_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + /* Note that this means the size of shareable ints is bounded by + * sys.maxsize. Hence on 32-bit architectures that is half the + * size of maximum shareable ints on 64-bit. + */ + Py_ssize_t value = PyLong_AsSsize_t(obj); + if (value == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, "try sending as bytes"); + } + return -1; + } + _PyCrossInterpreterData_Init(data, tstate->interp, (void *)value, NULL, + _new_long_object); + // data->obj and data->free remain NULL + return 0; +} + +// float + +static PyObject * +_new_float_object(_PyCrossInterpreterData *data) +{ + double * value_ptr = data->data; + return PyFloat_FromDouble(*value_ptr); +} + +static int +_float_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(double), NULL, + _new_float_object + ) < 0) + { + return -1; + } + double *shared = (double *)data->data; + *shared = PyFloat_AsDouble(obj); + return 0; +} + +// None + +static PyObject * +_new_none_object(_PyCrossInterpreterData *data) +{ + // XXX Singleton refcounts are problematic across interpreters... + return Py_NewRef(Py_None); +} + +static int +_none_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + _PyCrossInterpreterData_Init(data, tstate->interp, NULL, NULL, + _new_none_object); + // data->data, data->obj and data->free remain NULL + return 0; +} + +// bool + +static PyObject * +_new_bool_object(_PyCrossInterpreterData *data) +{ + if (data->data){ + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static int +_bool_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + _PyCrossInterpreterData_Init(data, tstate->interp, + (void *) (Py_IsTrue(obj) ? (uintptr_t) 1 : (uintptr_t) 0), NULL, + _new_bool_object); + // data->obj and data->free remain NULL + return 0; +} + +// tuple + +struct _shared_tuple_data { + Py_ssize_t len; + _PyCrossInterpreterData **data; +}; + +static PyObject * +_new_tuple_object(_PyCrossInterpreterData *data) +{ + struct _shared_tuple_data *shared = (struct _shared_tuple_data *)(data->data); + PyObject *tuple = PyTuple_New(shared->len); + if (tuple == NULL) { + return NULL; + } + + for (Py_ssize_t i = 0; i < shared->len; i++) { + PyObject *item = _PyCrossInterpreterData_NewObject(shared->data[i]); + if (item == NULL){ + Py_DECREF(tuple); + return NULL; + } + PyTuple_SET_ITEM(tuple, i, item); + } + return tuple; +} + +static void +_tuple_shared_free(void* data) +{ + struct _shared_tuple_data *shared = (struct _shared_tuple_data *)(data); +#ifndef NDEBUG + int64_t interpid = PyInterpreterState_GetID(_PyInterpreterState_GET()); +#endif + for (Py_ssize_t i = 0; i < shared->len; i++) { + if (shared->data[i] != NULL) { + assert(shared->data[i]->interpid == interpid); + _PyCrossInterpreterData_Release(shared->data[i]); + PyMem_RawFree(shared->data[i]); + shared->data[i] = NULL; + } + } + PyMem_Free(shared->data); + PyMem_RawFree(shared); +} + +static int +_tuple_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + Py_ssize_t len = PyTuple_GET_SIZE(obj); + if (len < 0) { + return -1; + } + struct _shared_tuple_data *shared = PyMem_RawMalloc(sizeof(struct _shared_tuple_data)); + if (shared == NULL){ + PyErr_NoMemory(); + return -1; + } + + shared->len = len; + shared->data = (_PyCrossInterpreterData **) PyMem_Calloc(shared->len, sizeof(_PyCrossInterpreterData *)); + if (shared->data == NULL) { + PyErr_NoMemory(); + return -1; + } + + for (Py_ssize_t i = 0; i < shared->len; i++) { + _PyCrossInterpreterData *data = _PyCrossInterpreterData_New(); + if (data == NULL) { + goto error; // PyErr_NoMemory already set + } + PyObject *item = PyTuple_GET_ITEM(obj, i); + + int res = -1; + if (!_Py_EnterRecursiveCallTstate(tstate, " while sharing a tuple")) { + res = _PyObject_GetCrossInterpreterData(item, data); + _Py_LeaveRecursiveCallTstate(tstate); + } + if (res < 0) { + PyMem_RawFree(data); + goto error; + } + shared->data[i] = data; + } + _PyCrossInterpreterData_Init( + data, tstate->interp, shared, obj, _new_tuple_object); + data->free = _tuple_shared_free; + return 0; + +error: + _tuple_shared_free(shared); + return -1; +} + +// registration + +static void +_register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) +{ + // None + if (_xidregistry_add_type(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { + Py_FatalError("could not register None for cross-interpreter sharing"); + } + + // int + if (_xidregistry_add_type(xidregistry, &PyLong_Type, _long_shared) != 0) { + Py_FatalError("could not register int for cross-interpreter sharing"); + } + + // bytes + if (_xidregistry_add_type(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { + Py_FatalError("could not register bytes for cross-interpreter sharing"); + } + + // str + if (_xidregistry_add_type(xidregistry, &PyUnicode_Type, _str_shared) != 0) { + Py_FatalError("could not register str for cross-interpreter sharing"); + } + + // bool + if (_xidregistry_add_type(xidregistry, &PyBool_Type, _bool_shared) != 0) { + Py_FatalError("could not register bool for cross-interpreter sharing"); + } + + // float + if (_xidregistry_add_type(xidregistry, &PyFloat_Type, _float_shared) != 0) { + Py_FatalError("could not register float for cross-interpreter sharing"); + } + + // tuple + if (_xidregistry_add_type(xidregistry, &PyTuple_Type, _tuple_shared) != 0) { + Py_FatalError("could not register tuple for cross-interpreter sharing"); + } +} + +/* registry lifecycle */ + +static void +_xidregistry_init(struct _xidregistry *registry) +{ + if (registry->initialized) { + return; + } + registry->initialized = 1; + + if (registry->global) { + // Registering the builtins is cheap so we don't bother doing it lazily. + assert(registry->head == NULL); + _register_builtins_for_crossinterpreter_data(registry); + } +} + +static void +_xidregistry_fini(struct _xidregistry *registry) +{ + if (!registry->initialized) { + return; + } + registry->initialized = 0; + + _xidregistry_clear(registry); +} + + +/*************************/ +/* convenience utilities */ +/*************************/ + +static const char * +_copy_string_obj_raw(PyObject *strobj, Py_ssize_t *p_size) +{ + Py_ssize_t size = -1; + const char *str = PyUnicode_AsUTF8AndSize(strobj, &size); + if (str == NULL) { + return NULL; + } + + char *copied = PyMem_RawMalloc(size+1); + if (copied == NULL) { + PyErr_NoMemory(); + return NULL; + } + strcpy(copied, str); + if (p_size != NULL) { + *p_size = size; + } + return copied; +} + + +static int +_convert_exc_to_TracebackException(PyObject *exc, PyObject **p_tbexc) +{ + PyObject *args = NULL; + PyObject *kwargs = NULL; + PyObject *create = NULL; + + // This is inspired by _PyErr_Display(). + PyObject *tbmod = PyImport_ImportModule("traceback"); + if (tbmod == NULL) { + return -1; + } + PyObject *tbexc_type = PyObject_GetAttrString(tbmod, "TracebackException"); + Py_DECREF(tbmod); + if (tbexc_type == NULL) { + return -1; + } + create = PyObject_GetAttrString(tbexc_type, "from_exception"); + Py_DECREF(tbexc_type); + if (create == NULL) { + return -1; + } + + args = PyTuple_Pack(1, exc); + if (args == NULL) { + goto error; + } + + kwargs = PyDict_New(); + if (kwargs == NULL) { + goto error; + } + if (PyDict_SetItemString(kwargs, "save_exc_type", Py_False) < 0) { + goto error; + } + if (PyDict_SetItemString(kwargs, "lookup_lines", Py_False) < 0) { + goto error; + } + + PyObject *tbexc = PyObject_Call(create, args, kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(create); + if (tbexc == NULL) { + goto error; + } + + *p_tbexc = tbexc; + return 0; + +error: + Py_XDECREF(args); + Py_XDECREF(kwargs); + Py_XDECREF(create); + return -1; +} + + +static const char * +_format_TracebackException(PyObject *tbexc) +{ + PyObject *lines = PyObject_CallMethod(tbexc, "format", NULL); + if (lines == NULL) { + return NULL; + } + PyObject *formatted_obj = PyUnicode_Join(&_Py_STR(empty), lines); + Py_DECREF(lines); + if (formatted_obj == NULL) { + return NULL; + } + + Py_ssize_t size = -1; + const char *formatted = _copy_string_obj_raw(formatted_obj, &size); + Py_DECREF(formatted_obj); + // We remove trailing the newline added by TracebackException.format(). + assert(formatted[size-1] == '\n'); + ((char *)formatted)[size-1] = '\0'; + return formatted; +} + + +static int +_release_xid_data(_PyCrossInterpreterData *data, int rawfree) +{ + PyObject *exc = PyErr_GetRaisedException(); + int res = rawfree + ? _PyCrossInterpreterData_Release(data) + : _PyCrossInterpreterData_ReleaseAndRawFree(data); + if (res < 0) { + /* The owning interpreter is already destroyed. */ + _PyCrossInterpreterData_Clear(NULL, data); + // XXX Emit a warning? + PyErr_Clear(); + } + PyErr_SetRaisedException(exc); + return res; +} + + +/***********************/ +/* exception snapshots */ +/***********************/ + +static int +_excinfo_init_type(struct _excinfo_type *info, PyObject *exc) +{ + /* Note that this copies directly rather than into an intermediate + struct and does not clear on error. If we need that then we + should have a separate function to wrap this one + and do all that there. */ + PyObject *strobj = NULL; + + PyTypeObject *type = Py_TYPE(exc); + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + assert(_Py_IsImmortal((PyObject *)type)); + info->builtin = type; + } + else { + // Only builtin types are preserved. + info->builtin = NULL; + } + + // __name__ + strobj = PyType_GetName(type); + if (strobj == NULL) { + return -1; + } + info->name = _copy_string_obj_raw(strobj, NULL); + Py_DECREF(strobj); + if (info->name == NULL) { + return -1; + } + + // __qualname__ + strobj = PyType_GetQualName(type); + if (strobj == NULL) { + return -1; + } + info->qualname = _copy_string_obj_raw(strobj, NULL); + Py_DECREF(strobj); + if (info->name == NULL) { + return -1; + } + + // __module__ + strobj = _PyType_GetModuleName(type); + if (strobj == NULL) { + return -1; + } + info->module = _copy_string_obj_raw(strobj, NULL); + Py_DECREF(strobj); + if (info->name == NULL) { + return -1; + } + + return 0; +} + +static void +_excinfo_clear_type(struct _excinfo_type *info) +{ + if (info->builtin != NULL) { + assert(info->builtin->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_Py_IsImmortal((PyObject *)info->builtin)); + } + if (info->name != NULL) { + PyMem_RawFree((void *)info->name); + } + if (info->qualname != NULL) { + PyMem_RawFree((void *)info->qualname); + } + if (info->module != NULL) { + PyMem_RawFree((void *)info->module); + } + *info = (struct _excinfo_type){NULL}; +} + +static void +_excinfo_normalize_type(struct _excinfo_type *info, + const char **p_module, const char **p_qualname) +{ + if (info->name == NULL) { + assert(info->builtin == NULL); + assert(info->qualname == NULL); + assert(info->module == NULL); + // This is inspired by TracebackException.format_exception_only(). + *p_module = NULL; + *p_qualname = NULL; + return; + } + + const char *module = info->module; + const char *qualname = info->qualname; + if (qualname == NULL) { + qualname = info->name; + } + assert(module != NULL); + if (strcmp(module, "builtins") == 0) { + module = NULL; + } + else if (strcmp(module, "__main__") == 0) { + module = NULL; + } + *p_qualname = qualname; + *p_module = module; +} + +static void +_PyXI_excinfo_Clear(_PyXI_excinfo *info) +{ + _excinfo_clear_type(&info->type); + if (info->msg != NULL) { + PyMem_RawFree((void *)info->msg); + } + if (info->errdisplay != NULL) { + PyMem_RawFree((void *)info->errdisplay); + } + *info = (_PyXI_excinfo){{NULL}}; +} + +static PyObject * +_PyXI_excinfo_format(_PyXI_excinfo *info) +{ + const char *module, *qualname; + _excinfo_normalize_type(&info->type, &module, &qualname); + if (qualname != NULL) { + if (module != NULL) { + if (info->msg != NULL) { + return PyUnicode_FromFormat("%s.%s: %s", + module, qualname, info->msg); + } + else { + return PyUnicode_FromFormat("%s.%s", module, qualname); + } + } + else { + if (info->msg != NULL) { + return PyUnicode_FromFormat("%s: %s", qualname, info->msg); + } + else { + return PyUnicode_FromString(qualname); + } + } + } + else if (info->msg != NULL) { + return PyUnicode_FromString(info->msg); + } + else { + Py_RETURN_NONE; + } +} + +static const char * +_PyXI_excinfo_InitFromException(_PyXI_excinfo *info, PyObject *exc) +{ + assert(exc != NULL); + + if (PyErr_GivenExceptionMatches(exc, PyExc_MemoryError)) { + _PyXI_excinfo_Clear(info); + return NULL; + } + const char *failure = NULL; + + if (_excinfo_init_type(&info->type, exc) < 0) { + failure = "error while initializing exception type snapshot"; + goto error; + } + + // Extract the exception message. + PyObject *msgobj = PyObject_Str(exc); + if (msgobj == NULL) { + failure = "error while formatting exception"; + goto error; + } + info->msg = _copy_string_obj_raw(msgobj, NULL); + Py_DECREF(msgobj); + if (info->msg == NULL) { + failure = "error while copying exception message"; + goto error; + } + + // Pickle a traceback.TracebackException. + PyObject *tbexc = NULL; + if (_convert_exc_to_TracebackException(exc, &tbexc) < 0) { +#ifdef Py_DEBUG + PyErr_FormatUnraisable("Exception ignored while creating TracebackException"); +#endif + PyErr_Clear(); + } + else { + info->errdisplay = _format_TracebackException(tbexc); + Py_DECREF(tbexc); + if (info->errdisplay == NULL) { +#ifdef Py_DEBUG + PyErr_FormatUnraisable("Exception ignored while formating TracebackException"); +#endif + PyErr_Clear(); + } + } + + return NULL; + +error: + assert(failure != NULL); + _PyXI_excinfo_Clear(info); + return failure; +} + +static void +_PyXI_excinfo_Apply(_PyXI_excinfo *info, PyObject *exctype) +{ + PyObject *tbexc = NULL; + if (info->errdisplay != NULL) { + tbexc = PyUnicode_FromString(info->errdisplay); + if (tbexc == NULL) { + PyErr_Clear(); + } + } + + PyObject *formatted = _PyXI_excinfo_format(info); + PyErr_SetObject(exctype, formatted); + Py_DECREF(formatted); + + if (tbexc != NULL) { + PyObject *exc = PyErr_GetRaisedException(); + if (PyObject_SetAttrString(exc, "_errdisplay", tbexc) < 0) { +#ifdef Py_DEBUG + PyErr_FormatUnraisable("Exception ignored when setting _errdisplay"); +#endif + PyErr_Clear(); + } + Py_DECREF(tbexc); + PyErr_SetRaisedException(exc); + } +} + +static PyObject * +_PyXI_excinfo_TypeAsObject(_PyXI_excinfo *info) +{ + PyObject *ns = _PyNamespace_New(NULL); + if (ns == NULL) { + return NULL; + } + int empty = 1; + + if (info->type.name != NULL) { + PyObject *name = PyUnicode_FromString(info->type.name); + if (name == NULL) { + goto error; + } + int res = PyObject_SetAttrString(ns, "__name__", name); + Py_DECREF(name); + if (res < 0) { + goto error; + } + empty = 0; + } + + if (info->type.qualname != NULL) { + PyObject *qualname = PyUnicode_FromString(info->type.qualname); + if (qualname == NULL) { + goto error; + } + int res = PyObject_SetAttrString(ns, "__qualname__", qualname); + Py_DECREF(qualname); + if (res < 0) { + goto error; + } + empty = 0; + } + + if (info->type.module != NULL) { + PyObject *module = PyUnicode_FromString(info->type.module); + if (module == NULL) { + goto error; + } + int res = PyObject_SetAttrString(ns, "__module__", module); + Py_DECREF(module); + if (res < 0) { + goto error; + } + empty = 0; + } + + if (empty) { + Py_CLEAR(ns); + } + + return ns; + +error: + Py_DECREF(ns); + return NULL; +} + +static PyObject * +_PyXI_excinfo_AsObject(_PyXI_excinfo *info) +{ + PyObject *ns = _PyNamespace_New(NULL); + if (ns == NULL) { + return NULL; + } + int res; + + PyObject *type = _PyXI_excinfo_TypeAsObject(info); + if (type == NULL) { + if (PyErr_Occurred()) { + goto error; + } + type = Py_NewRef(Py_None); + } + res = PyObject_SetAttrString(ns, "type", type); + Py_DECREF(type); + if (res < 0) { + goto error; + } + + PyObject *msg = info->msg != NULL + ? PyUnicode_FromString(info->msg) + : Py_NewRef(Py_None); + if (msg == NULL) { + goto error; + } + res = PyObject_SetAttrString(ns, "msg", msg); + Py_DECREF(msg); + if (res < 0) { + goto error; + } + + PyObject *formatted = _PyXI_excinfo_format(info); + if (formatted == NULL) { + goto error; + } + res = PyObject_SetAttrString(ns, "formatted", formatted); + Py_DECREF(formatted); + if (res < 0) { + goto error; + } + + if (info->errdisplay != NULL) { + PyObject *tbexc = PyUnicode_FromString(info->errdisplay); + if (tbexc == NULL) { + PyErr_Clear(); + } + else { + res = PyObject_SetAttrString(ns, "errdisplay", tbexc); + Py_DECREF(tbexc); + if (res < 0) { + goto error; + } + } + } + + return ns; + +error: + Py_DECREF(ns); + return NULL; +} + + +/***************************/ +/* short-term data sharing */ +/***************************/ + +/* error codes */ + +static int +_PyXI_ApplyErrorCode(_PyXI_errcode code, PyInterpreterState *interp) +{ + assert(!PyErr_Occurred()); + switch (code) { + case _PyXI_ERR_NO_ERROR: // fall through + case _PyXI_ERR_UNCAUGHT_EXCEPTION: + // There is nothing to apply. +#ifdef Py_DEBUG + Py_UNREACHABLE(); +#endif + return 0; + case _PyXI_ERR_OTHER: + // XXX msg? + PyErr_SetNone(PyExc_RuntimeError); + break; + case _PyXI_ERR_NO_MEMORY: + PyErr_NoMemory(); + break; + case _PyXI_ERR_ALREADY_RUNNING: + assert(interp != NULL); + assert(_PyInterpreterState_IsRunningMain(interp)); + _PyInterpreterState_FailIfRunningMain(interp); + break; + case _PyXI_ERR_MAIN_NS_FAILURE: + PyErr_SetString(PyExc_RuntimeError, + "failed to get __main__ namespace"); + break; + case _PyXI_ERR_APPLY_NS_FAILURE: + PyErr_SetString(PyExc_RuntimeError, + "failed to apply namespace to __main__"); + break; + case _PyXI_ERR_NOT_SHAREABLE: + _set_xid_lookup_failure(interp, NULL, NULL); + break; + default: +#ifdef Py_DEBUG + Py_UNREACHABLE(); +#else + PyErr_Format(PyExc_RuntimeError, "unsupported error code %d", code); +#endif + } + assert(PyErr_Occurred()); + return -1; +} + +/* shared exceptions */ + +static const char * +_PyXI_InitError(_PyXI_error *error, PyObject *excobj, _PyXI_errcode code) +{ + if (error->interp == NULL) { + error->interp = PyInterpreterState_Get(); + } + + const char *failure = NULL; + if (code == _PyXI_ERR_UNCAUGHT_EXCEPTION) { + // There is an unhandled exception we need to propagate. + failure = _PyXI_excinfo_InitFromException(&error->uncaught, excobj); + if (failure != NULL) { + // We failed to initialize error->uncaught. + // XXX Print the excobj/traceback? Emit a warning? + // XXX Print the current exception/traceback? + if (PyErr_ExceptionMatches(PyExc_MemoryError)) { + error->code = _PyXI_ERR_NO_MEMORY; + } + else { + error->code = _PyXI_ERR_OTHER; + } + PyErr_Clear(); + } + else { + error->code = code; + } + assert(error->code != _PyXI_ERR_NO_ERROR); + } + else { + // There is an error code we need to propagate. + assert(excobj == NULL); + assert(code != _PyXI_ERR_NO_ERROR); + error->code = code; + _PyXI_excinfo_Clear(&error->uncaught); + } + return failure; +} + +PyObject * +_PyXI_ApplyError(_PyXI_error *error) +{ + if (error->code == _PyXI_ERR_UNCAUGHT_EXCEPTION) { + // Raise an exception that proxies the propagated exception. + return _PyXI_excinfo_AsObject(&error->uncaught); + } + else if (error->code == _PyXI_ERR_NOT_SHAREABLE) { + // Propagate the exception directly. + _set_xid_lookup_failure(error->interp, NULL, error->uncaught.msg); + } + else { + // Raise an exception corresponding to the code. + assert(error->code != _PyXI_ERR_NO_ERROR); + (void)_PyXI_ApplyErrorCode(error->code, error->interp); + if (error->uncaught.type.name != NULL || error->uncaught.msg != NULL) { + // __context__ will be set to a proxy of the propagated exception. + PyObject *exc = PyErr_GetRaisedException(); + _PyXI_excinfo_Apply(&error->uncaught, PyExc_RuntimeError); + PyObject *exc2 = PyErr_GetRaisedException(); + PyException_SetContext(exc, exc2); + PyErr_SetRaisedException(exc); + } + } + assert(PyErr_Occurred()); + return NULL; +} + +/* shared namespaces */ + +/* Shared namespaces are expected to have relatively short lifetimes. + This means dealloc of a shared namespace will normally happen "soon". + Namespace items hold cross-interpreter data, which must get released. + If the namespace/items are cleared in a different interpreter than + where the items' cross-interpreter data was set then that will cause + pending calls to be used to release the cross-interpreter data. + The tricky bit is that the pending calls can happen sufficiently + later that the namespace/items might already be deallocated. This is + a problem if the cross-interpreter data is allocated as part of a + namespace item. If that's the case then we must ensure the shared + namespace is only cleared/freed *after* that data has been released. */ + +typedef struct _sharednsitem { + const char *name; + _PyCrossInterpreterData *data; + // We could have a "PyCrossInterpreterData _data" field, so it would + // be allocated as part of the item and avoid an extra allocation. + // However, doing so adds a bunch of complexity because we must + // ensure the item isn't freed before a pending call might happen + // in a different interpreter to release the XI data. +} _PyXI_namespace_item; + +static int +_sharednsitem_is_initialized(_PyXI_namespace_item *item) +{ + if (item->name != NULL) { + return 1; + } + return 0; +} + +static int +_sharednsitem_init(_PyXI_namespace_item *item, PyObject *key) +{ + item->name = _copy_string_obj_raw(key, NULL); + if (item->name == NULL) { + assert(!_sharednsitem_is_initialized(item)); + return -1; + } + item->data = NULL; + assert(_sharednsitem_is_initialized(item)); + return 0; +} + +static int +_sharednsitem_has_value(_PyXI_namespace_item *item, int64_t *p_interpid) +{ + if (item->data == NULL) { + return 0; + } + if (p_interpid != NULL) { + *p_interpid = item->data->interpid; + } + return 1; +} + +static int +_sharednsitem_set_value(_PyXI_namespace_item *item, PyObject *value) +{ + assert(_sharednsitem_is_initialized(item)); + assert(item->data == NULL); + item->data = PyMem_RawMalloc(sizeof(_PyCrossInterpreterData)); + if (item->data == NULL) { + PyErr_NoMemory(); + return -1; + } + if (_PyObject_GetCrossInterpreterData(value, item->data) != 0) { + PyMem_RawFree(item->data); + item->data = NULL; + // The caller may want to propagate PyExc_NotShareableError + // if currently switched between interpreters. + return -1; + } + return 0; +} + +static void +_sharednsitem_clear_value(_PyXI_namespace_item *item) +{ + _PyCrossInterpreterData *data = item->data; + if (data != NULL) { + item->data = NULL; + int rawfree = 1; + (void)_release_xid_data(data, rawfree); + } +} + +static void +_sharednsitem_clear(_PyXI_namespace_item *item) +{ + if (item->name != NULL) { + PyMem_RawFree((void *)item->name); + item->name = NULL; + } + _sharednsitem_clear_value(item); +} + +static int +_sharednsitem_copy_from_ns(struct _sharednsitem *item, PyObject *ns) +{ + assert(item->name != NULL); + assert(item->data == NULL); + PyObject *value = PyDict_GetItemString(ns, item->name); // borrowed + if (value == NULL) { + if (PyErr_Occurred()) { + return -1; + } + // When applied, this item will be set to the default (or fail). + return 0; + } + if (_sharednsitem_set_value(item, value) < 0) { + return -1; + } + return 0; +} + +static int +_sharednsitem_apply(_PyXI_namespace_item *item, PyObject *ns, PyObject *dflt) +{ + PyObject *name = PyUnicode_FromString(item->name); + if (name == NULL) { + return -1; + } + PyObject *value; + if (item->data != NULL) { + value = _PyCrossInterpreterData_NewObject(item->data); + if (value == NULL) { + Py_DECREF(name); + return -1; + } + } + else { + value = Py_NewRef(dflt); + } + int res = PyDict_SetItem(ns, name, value); + Py_DECREF(name); + Py_DECREF(value); + return res; +} + +struct _sharedns { + Py_ssize_t len; + _PyXI_namespace_item *items; +}; + +static _PyXI_namespace * +_sharedns_new(void) +{ + _PyXI_namespace *ns = PyMem_RawCalloc(sizeof(_PyXI_namespace), 1); + if (ns == NULL) { + PyErr_NoMemory(); + return NULL; + } + *ns = (_PyXI_namespace){ 0 }; + return ns; +} + +static int +_sharedns_is_initialized(_PyXI_namespace *ns) +{ + if (ns->len == 0) { + assert(ns->items == NULL); + return 0; + } + + assert(ns->len > 0); + assert(ns->items != NULL); + assert(_sharednsitem_is_initialized(&ns->items[0])); + assert(ns->len == 1 + || _sharednsitem_is_initialized(&ns->items[ns->len - 1])); + return 1; +} + +#define HAS_COMPLETE_DATA 1 +#define HAS_PARTIAL_DATA 2 + +static int +_sharedns_has_xidata(_PyXI_namespace *ns, int64_t *p_interpid) +{ + // We expect _PyXI_namespace to always be initialized. + assert(_sharedns_is_initialized(ns)); + int res = 0; + _PyXI_namespace_item *item0 = &ns->items[0]; + if (!_sharednsitem_is_initialized(item0)) { + return 0; + } + int64_t interpid0 = -1; + if (!_sharednsitem_has_value(item0, &interpid0)) { + return 0; + } + if (ns->len > 1) { + // At this point we know it is has at least partial data. + _PyXI_namespace_item *itemN = &ns->items[ns->len-1]; + if (!_sharednsitem_is_initialized(itemN)) { + res = HAS_PARTIAL_DATA; + goto finally; + } + int64_t interpidN = -1; + if (!_sharednsitem_has_value(itemN, &interpidN)) { + res = HAS_PARTIAL_DATA; + goto finally; + } + assert(interpidN == interpid0); + } + res = HAS_COMPLETE_DATA; + *p_interpid = interpid0; + +finally: + return res; +} + +static void +_sharedns_clear(_PyXI_namespace *ns) +{ + if (!_sharedns_is_initialized(ns)) { + return; + } + + // If the cross-interpreter data were allocated as part of + // _PyXI_namespace_item (instead of dynamically), this is where + // we would need verify that we are clearing the items in the + // correct interpreter, to avoid a race with releasing the XI data + // via a pending call. See _sharedns_has_xidata(). + for (Py_ssize_t i=0; i < ns->len; i++) { + _sharednsitem_clear(&ns->items[i]); + } + PyMem_RawFree(ns->items); + ns->items = NULL; + ns->len = 0; +} + +static void +_sharedns_free(_PyXI_namespace *ns) +{ + _sharedns_clear(ns); + PyMem_RawFree(ns); +} + +static int +_sharedns_init(_PyXI_namespace *ns, PyObject *names) +{ + assert(!_sharedns_is_initialized(ns)); + assert(names != NULL); + Py_ssize_t len = PyDict_CheckExact(names) + ? PyDict_Size(names) + : PySequence_Size(names); + if (len < 0) { + return -1; + } + if (len == 0) { + PyErr_SetString(PyExc_ValueError, "empty namespaces not allowed"); + return -1; + } + assert(len > 0); + + // Allocate the items. + _PyXI_namespace_item *items = + PyMem_RawCalloc(sizeof(struct _sharednsitem), len); + if (items == NULL) { + PyErr_NoMemory(); + return -1; + } + + // Fill in the names. + Py_ssize_t i = -1; + if (PyDict_CheckExact(names)) { + Py_ssize_t pos = 0; + for (i=0; i < len; i++) { + PyObject *key; + if (!PyDict_Next(names, &pos, &key, NULL)) { + // This should not be possible. + assert(0); + goto error; + } + if (_sharednsitem_init(&items[i], key) < 0) { + goto error; + } + } + } + else if (PySequence_Check(names)) { + for (i=0; i < len; i++) { + PyObject *key = PySequence_GetItem(names, i); + if (key == NULL) { + goto error; + } + int res = _sharednsitem_init(&items[i], key); + Py_DECREF(key); + if (res < 0) { + goto error; + } + } + } + else { + PyErr_SetString(PyExc_NotImplementedError, + "non-sequence namespace not supported"); + goto error; + } + + ns->items = items; + ns->len = len; + assert(_sharedns_is_initialized(ns)); + return 0; + +error: + for (Py_ssize_t j=0; j < i; j++) { + _sharednsitem_clear(&items[j]); + } + PyMem_RawFree(items); + assert(!_sharedns_is_initialized(ns)); + return -1; +} + +void +_PyXI_FreeNamespace(_PyXI_namespace *ns) +{ + if (!_sharedns_is_initialized(ns)) { + return; + } + + int64_t interpid = -1; + if (!_sharedns_has_xidata(ns, &interpid)) { + _sharedns_free(ns); + return; + } + + if (interpid == PyInterpreterState_GetID(_PyInterpreterState_GET())) { + _sharedns_free(ns); + } + else { + // If we weren't always dynamically allocating the cross-interpreter + // data in each item then we would need to using a pending call + // to call _sharedns_free(), to avoid the race between freeing + // the shared namespace and releasing the XI data. + _sharedns_free(ns); + } +} + +_PyXI_namespace * +_PyXI_NamespaceFromNames(PyObject *names) +{ + if (names == NULL || names == Py_None) { + return NULL; + } + + _PyXI_namespace *ns = _sharedns_new(); + if (ns == NULL) { + return NULL; + } + + if (_sharedns_init(ns, names) < 0) { + PyMem_RawFree(ns); + if (PySequence_Size(names) == 0) { + PyErr_Clear(); + } + return NULL; + } + + return ns; +} + +#ifndef NDEBUG +static int _session_is_active(_PyXI_session *); +#endif +static void _propagate_not_shareable_error(_PyXI_session *); + +int +_PyXI_FillNamespaceFromDict(_PyXI_namespace *ns, PyObject *nsobj, + _PyXI_session *session) +{ + // session must be entered already, if provided. + assert(session == NULL || _session_is_active(session)); + assert(_sharedns_is_initialized(ns)); + for (Py_ssize_t i=0; i < ns->len; i++) { + _PyXI_namespace_item *item = &ns->items[i]; + if (_sharednsitem_copy_from_ns(item, nsobj) < 0) { + _propagate_not_shareable_error(session); + // Clear out the ones we set so far. + for (Py_ssize_t j=0; j < i; j++) { + _sharednsitem_clear_value(&ns->items[j]); + } + return -1; + } + } + return 0; +} + +// All items are expected to be shareable. +static _PyXI_namespace * +_PyXI_NamespaceFromDict(PyObject *nsobj, _PyXI_session *session) +{ + // session must be entered already, if provided. + assert(session == NULL || _session_is_active(session)); + if (nsobj == NULL || nsobj == Py_None) { + return NULL; + } + if (!PyDict_CheckExact(nsobj)) { + PyErr_SetString(PyExc_TypeError, "expected a dict"); + return NULL; + } + + _PyXI_namespace *ns = _sharedns_new(); + if (ns == NULL) { + return NULL; + } + + if (_sharedns_init(ns, nsobj) < 0) { + if (PyDict_Size(nsobj) == 0) { + PyMem_RawFree(ns); + PyErr_Clear(); + return NULL; + } + goto error; + } + + if (_PyXI_FillNamespaceFromDict(ns, nsobj, session) < 0) { + goto error; + } + + return ns; + +error: + assert(PyErr_Occurred() + || (session != NULL && session->error_override != NULL)); + _sharedns_free(ns); + return NULL; +} + +int +_PyXI_ApplyNamespace(_PyXI_namespace *ns, PyObject *nsobj, PyObject *dflt) +{ + for (Py_ssize_t i=0; i < ns->len; i++) { + if (_sharednsitem_apply(&ns->items[i], nsobj, dflt) != 0) { + return -1; + } + } + return 0; +} + + +/**********************/ +/* high-level helpers */ +/**********************/ + +/* enter/exit a cross-interpreter session */ + +static void +_enter_session(_PyXI_session *session, PyInterpreterState *interp) +{ + // Set here and cleared in _exit_session(). + assert(!session->own_init_tstate); + assert(session->init_tstate == NULL); + assert(session->prev_tstate == NULL); + // Set elsewhere and cleared in _exit_session(). + assert(!session->running); + assert(session->main_ns == NULL); + // Set elsewhere and cleared in _capture_current_exception(). + assert(session->error_override == NULL); + // Set elsewhere and cleared in _PyXI_ApplyCapturedException(). + assert(session->error == NULL); + + // Switch to interpreter. + PyThreadState *tstate = PyThreadState_Get(); + PyThreadState *prev = tstate; + if (interp != tstate->interp) { + tstate = PyThreadState_New(interp); + tstate->_whence = _PyThreadState_WHENCE_EXEC; + // XXX Possible GILState issues? + session->prev_tstate = PyThreadState_Swap(tstate); + assert(session->prev_tstate == prev); + session->own_init_tstate = 1; + } + session->init_tstate = tstate; + session->prev_tstate = prev; +} + +static void +_exit_session(_PyXI_session *session) +{ + PyThreadState *tstate = session->init_tstate; + assert(tstate != NULL); + assert(PyThreadState_Get() == tstate); + + // Release any of the entered interpreters resources. + if (session->main_ns != NULL) { + Py_CLEAR(session->main_ns); + } + + // Ensure this thread no longer owns __main__. + if (session->running) { + _PyInterpreterState_SetNotRunningMain(tstate->interp); + assert(!PyErr_Occurred()); + session->running = 0; + } + + // Switch back. + assert(session->prev_tstate != NULL); + if (session->prev_tstate != session->init_tstate) { + assert(session->own_init_tstate); + session->own_init_tstate = 0; + PyThreadState_Clear(tstate); + PyThreadState_Swap(session->prev_tstate); + PyThreadState_Delete(tstate); + } + else { + assert(!session->own_init_tstate); + } + session->prev_tstate = NULL; + session->init_tstate = NULL; +} + +#ifndef NDEBUG +static int +_session_is_active(_PyXI_session *session) +{ + return (session->init_tstate != NULL); +} +#endif + +static void +_propagate_not_shareable_error(_PyXI_session *session) +{ + if (session == NULL) { + return; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (PyErr_ExceptionMatches(_get_not_shareable_error_type(interp))) { + // We want to propagate the exception directly. + session->_error_override = _PyXI_ERR_NOT_SHAREABLE; + session->error_override = &session->_error_override; + } +} + +static void +_capture_current_exception(_PyXI_session *session) +{ + assert(session->error == NULL); + if (!PyErr_Occurred()) { + assert(session->error_override == NULL); + return; + } + + // Handle the exception override. + _PyXI_errcode *override = session->error_override; + session->error_override = NULL; + _PyXI_errcode errcode = override != NULL + ? *override + : _PyXI_ERR_UNCAUGHT_EXCEPTION; + + // Pop the exception object. + PyObject *excval = NULL; + if (errcode == _PyXI_ERR_UNCAUGHT_EXCEPTION) { + // We want to actually capture the current exception. + excval = PyErr_GetRaisedException(); + } + else if (errcode == _PyXI_ERR_ALREADY_RUNNING) { + // We don't need the exception info. + PyErr_Clear(); + } + else { + // We could do a variety of things here, depending on errcode. + // However, for now we simply capture the exception and save + // the errcode. + excval = PyErr_GetRaisedException(); + } + + // Capture the exception. + _PyXI_error *err = &session->_error; + *err = (_PyXI_error){ + .interp = session->init_tstate->interp, + }; + const char *failure; + if (excval == NULL) { + failure = _PyXI_InitError(err, NULL, errcode); + } + else { + failure = _PyXI_InitError(err, excval, _PyXI_ERR_UNCAUGHT_EXCEPTION); + Py_DECREF(excval); + if (failure == NULL && override != NULL) { + err->code = errcode; + } + } + + // Handle capture failure. + if (failure != NULL) { + // XXX Make this error message more generic. + fprintf(stderr, + "RunFailedError: script raised an uncaught exception (%s)", + failure); + err = NULL; + } + + // Finished! + assert(!PyErr_Occurred()); + session->error = err; +} + +PyObject * +_PyXI_ApplyCapturedException(_PyXI_session *session) +{ + assert(!PyErr_Occurred()); + assert(session->error != NULL); + PyObject *res = _PyXI_ApplyError(session->error); + assert((res == NULL) != (PyErr_Occurred() == NULL)); + session->error = NULL; + return res; +} + +int +_PyXI_HasCapturedException(_PyXI_session *session) +{ + return session->error != NULL; +} + +int +_PyXI_Enter(_PyXI_session *session, + PyInterpreterState *interp, PyObject *nsupdates) +{ + // Convert the attrs for cross-interpreter use. + _PyXI_namespace *sharedns = NULL; + if (nsupdates != NULL) { + sharedns = _PyXI_NamespaceFromDict(nsupdates, NULL); + if (sharedns == NULL && PyErr_Occurred()) { + assert(session->error == NULL); + return -1; + } + } + + // Switch to the requested interpreter (if necessary). + _enter_session(session, interp); + _PyXI_errcode errcode = _PyXI_ERR_UNCAUGHT_EXCEPTION; + + // Ensure this thread owns __main__. + if (_PyInterpreterState_SetRunningMain(interp) < 0) { + // 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. + errcode = _PyXI_ERR_ALREADY_RUNNING; + goto error; + } + session->running = 1; + + // Cache __main__.__dict__. + PyObject *main_mod = PyUnstable_InterpreterState_GetMainModule(interp); + if (main_mod == NULL) { + errcode = _PyXI_ERR_MAIN_NS_FAILURE; + goto error; + } + PyObject *ns = PyModule_GetDict(main_mod); // borrowed + Py_DECREF(main_mod); + if (ns == NULL) { + errcode = _PyXI_ERR_MAIN_NS_FAILURE; + goto error; + } + session->main_ns = Py_NewRef(ns); + + // Apply the cross-interpreter data. + if (sharedns != NULL) { + if (_PyXI_ApplyNamespace(sharedns, ns, NULL) < 0) { + errcode = _PyXI_ERR_APPLY_NS_FAILURE; + goto error; + } + _PyXI_FreeNamespace(sharedns); + } + + errcode = _PyXI_ERR_NO_ERROR; + assert(!PyErr_Occurred()); + return 0; + +error: + assert(PyErr_Occurred()); + // We want to propagate all exceptions here directly (best effort). + assert(errcode != _PyXI_ERR_UNCAUGHT_EXCEPTION); + session->error_override = &errcode; + _capture_current_exception(session); + _exit_session(session); + if (sharedns != NULL) { + _PyXI_FreeNamespace(sharedns); + } + return -1; +} + +void +_PyXI_Exit(_PyXI_session *session) +{ + _capture_current_exception(session); + _exit_session(session); +} + + +/*********************/ +/* runtime lifecycle */ +/*********************/ + +PyStatus +_PyXI_Init(PyInterpreterState *interp) +{ + PyStatus status; + + // Initialize the XID registry. + if (_Py_IsMainInterpreter(interp)) { + _xidregistry_init(_get_global_xidregistry(interp->runtime)); + } + _xidregistry_init(_get_xidregistry(interp)); + + // Initialize exceptions (heap types). + status = _init_not_shareable_error_type(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + return _PyStatus_OK(); +} + +// _PyXI_Fini() must be called before the interpreter is cleared, +// since we must clear some heap objects. + +void +_PyXI_Fini(PyInterpreterState *interp) +{ + // Finalize exceptions (heap types). + _fini_not_shareable_error_type(interp); + + // Finalize the XID registry. + _xidregistry_fini(_get_xidregistry(interp)); + if (_Py_IsMainInterpreter(interp)) { + _xidregistry_fini(_get_global_xidregistry(interp->runtime)); + } +} + +PyStatus +_PyXI_InitTypes(PyInterpreterState *interp) +{ + if (init_exceptions(interp) < 0) { + return _PyStatus_ERR("failed to initialize an exception type"); + } + return _PyStatus_OK(); +} + +void +_PyXI_FiniTypes(PyInterpreterState *interp) +{ + fini_exceptions(interp); +} diff --git a/Python/dtoa.c b/Python/dtoa.c index 5dfc0e179cbc34..6e3162f80bdae1 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -309,7 +309,7 @@ BCinfo { // struct Bigint is defined in pycore_dtoa.h. typedef struct Bigint Bigint; -#ifndef Py_USING_MEMORY_DEBUGGER +#if !defined(Py_GIL_DISABLED) && !defined(Py_USING_MEMORY_DEBUGGER) /* Memory management: memory is allocated from, and returned to, Kmax+1 pools of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds == @@ -428,7 +428,7 @@ Bfree(Bigint *v) } } -#endif /* Py_USING_MEMORY_DEBUGGER */ +#endif /* !defined(Py_GIL_DISABLED) && !defined(Py_USING_MEMORY_DEBUGGER) */ #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ y->wds*sizeof(Long) + 2*sizeof(int)) @@ -673,10 +673,17 @@ mult(Bigint *a, Bigint *b) static Bigint * pow5mult(Bigint *b, int k) { - Bigint *b1, *p5, *p51; + Bigint *b1, *p5, **p5s; int i; static const int p05[3] = { 5, 25, 125 }; + // For double-to-string conversion, the maximum value of k is limited by + // DBL_MAX_10_EXP (308), the maximum decimal base-10 exponent for binary64. + // For string-to-double conversion, the extreme case is constrained by our + // hardcoded exponent limit before we underflow of -512, adjusted by + // STRTOD_DIGLIM-DBL_DIG-1, giving a maximum of k=535. + assert(0 <= k && k < 1024); + if ((i = k & 3)) { b = multadd(b, p05[i-1], 0); if (b == NULL) @@ -686,18 +693,11 @@ pow5mult(Bigint *b, int k) if (!(k >>= 2)) return b; PyInterpreterState *interp = _PyInterpreterState_GET(); - p5 = interp->dtoa.p5s; - if (!p5) { - /* first time */ - p5 = i2b(625); - if (p5 == NULL) { - Bfree(b); - return NULL; - } - interp->dtoa.p5s = p5; - p5->next = 0; - } + p5s = interp->dtoa.p5s; for(;;) { + assert(p5s != interp->dtoa.p5s + Bigint_Pow5size); + p5 = *p5s; + p5s++; if (k & 1) { b1 = mult(b, p5); Bfree(b); @@ -707,17 +707,6 @@ pow5mult(Bigint *b, int k) } if (!(k >>= 1)) break; - p51 = p5->next; - if (!p51) { - p51 = mult(p5,p5); - if (p51 == NULL) { - Bfree(b); - return NULL; - } - p51->next = 0; - p5->next = p51; - } - p5 = p51; } return b; } @@ -2811,3 +2800,42 @@ _Py_dg_dtoa(double dd, int mode, int ndigits, } #endif // _PY_SHORT_FLOAT_REPR == 1 + +PyStatus +_PyDtoa_Init(PyInterpreterState *interp) +{ +#if _PY_SHORT_FLOAT_REPR == 1 && !defined(Py_USING_MEMORY_DEBUGGER) + Bigint **p5s = interp->dtoa.p5s; + + // 5**4 = 625 + Bigint *p5 = i2b(625); + if (p5 == NULL) { + return PyStatus_NoMemory(); + } + p5s[0] = p5; + + // compute 5**8, 5**16, 5**32, ..., 5**512 + for (Py_ssize_t i = 1; i < Bigint_Pow5size; i++) { + p5 = mult(p5, p5); + if (p5 == NULL) { + return PyStatus_NoMemory(); + } + p5s[i] = p5; + } + +#endif + return PyStatus_Ok(); +} + +void +_PyDtoa_Fini(PyInterpreterState *interp) +{ +#if _PY_SHORT_FLOAT_REPR == 1 && !defined(Py_USING_MEMORY_DEBUGGER) + Bigint **p5s = interp->dtoa.p5s; + for (Py_ssize_t i = 0; i < Bigint_Pow5size; i++) { + Bigint *p5 = p5s[i]; + p5s[i] = NULL; + Bfree(p5); + } +#endif +} 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 fcb3cb744047ce..a0ac31c80a5f6e 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -5,30 +5,10 @@ #include "pycore_fileutils.h" // _Py_add_relfile() #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "importdl.h" // dl_funcptr +#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 Py_NOGIL -# define PYD_THREADING_TAG "t" -#else -# define PYD_THREADING_TAG "" -#endif - -#ifdef PYD_PLATFORM_TAG -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG "-" PYD_PLATFORM_TAG ".pyd" -#else -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG ".pyd" -#endif - -#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" - const char *_PyImport_DynLoadFiletab[] = { PYD_TAGGED_SUFFIX, PYD_UNTAGGED_SUFFIX, diff --git a/Python/errors.c b/Python/errors.c index 15af39b10dc07e..ed5eec5c261970 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1569,14 +1569,16 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args) for Python to handle it. For example, when a destructor raises an exception or during garbage collection (gc.collect()). - If err_msg_str is non-NULL, the error message is formatted as: - "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in" - error message. + If format is non-NULL, the error message is formatted using format and + variable arguments as in PyUnicode_FromFormat(). + Otherwise, use "Exception ignored in" error message. An exception must be set when calling this function. */ -void -_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) + +static void +format_unraisable_v(const char *format, va_list va, PyObject *obj) { + const char *err_msg_str; PyThreadState *tstate = _PyThreadState_GET(); _Py_EnsureTstateNotNULL(tstate); @@ -1610,8 +1612,8 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) } } - if (err_msg_str != NULL) { - err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str); + if (format != NULL) { + err_msg = PyUnicode_FromFormatV(format, va); if (err_msg == NULL) { PyErr_Clear(); } @@ -1676,11 +1678,30 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) _PyErr_Clear(tstate); /* Just in case */ } +void +PyErr_FormatUnraisable(const char *format, ...) +{ + va_list va; + + va_start(va, format); + format_unraisable_v(format, va, NULL); + va_end(va); +} + +static void +format_unraisable(PyObject *obj, const char *format, ...) +{ + va_list va; + + va_start(va, format); + format_unraisable_v(format, va, obj); + va_end(va); +} void PyErr_WriteUnraisable(PyObject *obj) { - _PyErr_WriteUnraisableMsg(NULL, obj); + format_unraisable(obj, NULL); } diff --git a/Python/executor.c b/Python/executor.c deleted file mode 100644 index ac9104223da8ff..00000000000000 --- a/Python/executor.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "Python.h" - -#include "opcode.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 ASSERT_KWNAMES_IS_NULL -#define ASSERT_KWNAMES_IS_NULL() (void)0 - -#undef DEOPT_IF -#define DEOPT_IF(COND, INSTNAME) \ - if ((COND)) { \ - goto deoptimize; \ - } - -#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(); - - 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) { - -#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); - _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/executor_cases.c.h b/Python/executor_cases.c.h index 55a03c9a23a572..14d9dd6e95e533 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1,110 +1,122 @@ -// This file is generated by Tools/cases_generator/generate_cases.py +// This file is generated by Tools/cases_generator/tier2_generator.py // from: // Python/bytecodes.c // Do not edit! - case NOP: { +#ifdef TIER_ONE + #error "This file is for Tier 2 only" +#endif +#define TIER_TWO 2 + + case _NOP: { break; } - case RESUME_CHECK: { -#if defined(__EMSCRIPTEN__) - DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME); + case _RESUME_CHECK: { + #if defined(__EMSCRIPTEN__) + if (_Py_emscripten_signal_clock == 0) goto deoptimize; _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; -#endif - /* Possibly combine these two checks */ - DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version - != tstate->interp->monitoring_version, RESUME); - DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), RESUME); + #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); + if (eval_breaker != version) goto deoptimize; break; } - case LOAD_FAST_CHECK: { + /* _INSTRUMENTED_RESUME is not a viable micro-op for tier 2 */ + + case _LOAD_FAST_CHECK: { PyObject *value; + oparg = CURRENT_OPARG(); value = GETLOCAL(oparg); - if (value == NULL) goto unbound_local_error; + if (value == NULL) goto unbound_local_error_tier_two; Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + stack_pointer[0] = value; + stack_pointer += 1; break; } - case LOAD_FAST: { + case _LOAD_FAST: { PyObject *value; + oparg = CURRENT_OPARG(); value = GETLOCAL(oparg); assert(value != NULL); Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + stack_pointer[0] = value; + stack_pointer += 1; break; } - case LOAD_FAST_AND_CLEAR: { + case _LOAD_FAST_AND_CLEAR: { PyObject *value; + oparg = CURRENT_OPARG(); value = GETLOCAL(oparg); // do not use SETLOCAL here, it decrefs the old value GETLOCAL(oparg) = NULL; - STACK_GROW(1); - stack_pointer[-1] = value; + stack_pointer[0] = value; + stack_pointer += 1; break; } - case LOAD_CONST: { + case _LOAD_CONST: { PyObject *value; + oparg = CURRENT_OPARG(); value = GETITEM(FRAME_CO_CONSTS, oparg); Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + stack_pointer[0] = value; + stack_pointer += 1; break; } - case STORE_FAST: { + case _STORE_FAST: { PyObject *value; + oparg = CURRENT_OPARG(); value = stack_pointer[-1]; SETLOCAL(oparg, value); - STACK_SHRINK(1); + stack_pointer += -1; break; } - case POP_TOP: { + case _POP_TOP: { PyObject *value; value = stack_pointer[-1]; Py_DECREF(value); - STACK_SHRINK(1); + stack_pointer += -1; break; } - case PUSH_NULL: { + case _PUSH_NULL: { PyObject *res; res = NULL; - STACK_GROW(1); - stack_pointer[-1] = res; + stack_pointer[0] = res; + stack_pointer += 1; break; } - case END_SEND: { + case _END_SEND: { PyObject *value; PyObject *receiver; value = stack_pointer[-1]; receiver = stack_pointer[-2]; Py_DECREF(receiver); - STACK_SHRINK(1); - stack_pointer[-1] = value; + stack_pointer[-2] = value; + stack_pointer += -1; break; } - case UNARY_NEGATIVE: { + case _UNARY_NEGATIVE: { PyObject *value; PyObject *res; value = stack_pointer[-1]; res = PyNumber_Negative(value); Py_DECREF(value); - if (res == NULL) goto pop_1_error; + if (res == NULL) goto pop_1_error_tier_two; stack_pointer[-1] = res; break; } - case UNARY_NOT: { + case _UNARY_NOT: { PyObject *value; PyObject *res; value = stack_pointer[-1]; @@ -114,41 +126,31 @@ break; } - case TO_BOOL: { + case _TO_BOOL: { PyObject *value; PyObject *res; value = stack_pointer[-1]; - #if ENABLE_SPECIALIZATION - _PyToBoolCache *cache = (_PyToBoolCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_ToBool(value, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(TO_BOOL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ int err = PyObject_IsTrue(value); Py_DECREF(value); - if (err < 0) goto pop_1_error; + if (err < 0) goto pop_1_error_tier_two; res = err ? Py_True : Py_False; stack_pointer[-1] = res; break; } - case TO_BOOL_BOOL: { + case _TO_BOOL_BOOL: { PyObject *value; value = stack_pointer[-1]; - DEOPT_IF(!PyBool_Check(value), TO_BOOL); + if (!PyBool_Check(value)) goto deoptimize; STAT_INC(TO_BOOL, hit); break; } - case TO_BOOL_INT: { + case _TO_BOOL_INT: { PyObject *value; PyObject *res; value = stack_pointer[-1]; - DEOPT_IF(!PyLong_CheckExact(value), TO_BOOL); + if (!PyLong_CheckExact(value)) goto deoptimize; STAT_INC(TO_BOOL, hit); if (_PyLong_IsZero((PyLongObject *)value)) { assert(_Py_IsImmortal(value)); @@ -162,11 +164,11 @@ break; } - case TO_BOOL_LIST: { + case _TO_BOOL_LIST: { PyObject *value; PyObject *res; value = stack_pointer[-1]; - DEOPT_IF(!PyList_CheckExact(value), TO_BOOL); + if (!PyList_CheckExact(value)) goto deoptimize; STAT_INC(TO_BOOL, hit); res = Py_SIZE(value) ? Py_True : Py_False; Py_DECREF(value); @@ -174,23 +176,23 @@ break; } - case TO_BOOL_NONE: { + case _TO_BOOL_NONE: { 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); + if (!Py_IsNone(value)) goto deoptimize; STAT_INC(TO_BOOL, hit); res = Py_False; stack_pointer[-1] = res; break; } - case TO_BOOL_STR: { + case _TO_BOOL_STR: { PyObject *value; PyObject *res; value = stack_pointer[-1]; - DEOPT_IF(!PyUnicode_CheckExact(value), TO_BOOL); + if (!PyUnicode_CheckExact(value)) goto deoptimize; STAT_INC(TO_BOOL, hit); if (value == &_Py_STR(empty)) { assert(_Py_IsImmortal(value)); @@ -205,14 +207,14 @@ break; } - case TO_BOOL_ALWAYS_TRUE: { + case _TO_BOOL_ALWAYS_TRUE: { PyObject *value; PyObject *res; value = stack_pointer[-1]; - uint32_t version = (uint32_t)operand; + uint32_t version = (uint32_t)CURRENT_OPERAND(); // This one is a bit weird, because we expect *some* failures: assert(version); - DEOPT_IF(Py_TYPE(value)->tp_version_tag != version, TO_BOOL); + if (Py_TYPE(value)->tp_version_tag != version) goto deoptimize; STAT_INC(TO_BOOL, hit); Py_DECREF(value); res = Py_True; @@ -220,13 +222,13 @@ break; } - case UNARY_INVERT: { + case _UNARY_INVERT: { PyObject *value; PyObject *res; value = stack_pointer[-1]; res = PyNumber_Invert(value); Py_DECREF(value); - if (res == NULL) goto pop_1_error; + if (res == NULL) goto pop_1_error_tier_two; stack_pointer[-1] = res; break; } @@ -236,8 +238,8 @@ PyObject *left; right = stack_pointer[-1]; left = stack_pointer[-2]; - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + if (!PyLong_CheckExact(left)) goto deoptimize; + if (!PyLong_CheckExact(right)) goto deoptimize; break; } @@ -251,9 +253,9 @@ 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; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } @@ -267,9 +269,9 @@ 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; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } @@ -283,9 +285,9 @@ 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; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } @@ -294,8 +296,8 @@ PyObject *left; right = stack_pointer[-1]; left = stack_pointer[-2]; - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + if (!PyFloat_CheckExact(left)) goto deoptimize; + if (!PyFloat_CheckExact(right)) goto deoptimize; break; } @@ -307,11 +309,11 @@ left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); double dres = - ((PyFloatObject *)left)->ob_fval * - ((PyFloatObject *)right)->ob_fval; + ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } @@ -323,11 +325,11 @@ left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); double dres = - ((PyFloatObject *)left)->ob_fval + - ((PyFloatObject *)right)->ob_fval; + ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } @@ -339,11 +341,11 @@ left = stack_pointer[-2]; STAT_INC(BINARY_OP, hit); double dres = - ((PyFloatObject *)left)->ob_fval - - ((PyFloatObject *)right)->ob_fval; + ((PyFloatObject *)left)->ob_fval - + ((PyFloatObject *)right)->ob_fval; DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } @@ -352,8 +354,8 @@ PyObject *left; right = stack_pointer[-1]; left = stack_pointer[-2]; - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); + if (!PyUnicode_CheckExact(left)) goto deoptimize; + if (!PyUnicode_CheckExact(right)) goto deoptimize; break; } @@ -367,38 +369,60 @@ res = PyUnicode_Concat(left, right); _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; + break; + } + + case _BINARY_OP_INPLACE_ADD_UNICODE: { + PyObject *right; + PyObject *left; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + assert(next_instr->op.code == STORE_FAST); + PyObject **target_local = &GETLOCAL(next_instr->op.arg); + if (*target_local != left) goto deoptimize; + STAT_INC(BINARY_OP, hit); + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ + assert(Py_REFCNT(left) >= 2); + _Py_DECREF_NO_DEALLOC(left); + PyUnicode_Append(target_local, right); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (*target_local == NULL) goto pop_2_error_tier_two; + // The STORE_FAST is already done. + assert(next_instr->op.code == STORE_FAST); + SKIP_OVER(1); + stack_pointer += -2; break; } - case BINARY_SUBSCR: { + case _BINARY_SUBSCR: { 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)) { - next_instr--; - _Py_Specialize_BinarySubscr(container, sub, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(BINARY_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ res = PyObject_GetItem(container, sub); Py_DECREF(container); Py_DECREF(sub); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case BINARY_SLICE: { + case _BINARY_SLICE: { PyObject *stop; PyObject *start; PyObject *container; @@ -417,13 +441,13 @@ Py_DECREF(slice); } Py_DECREF(container); - if (res == NULL) goto pop_3_error; - STACK_SHRINK(2); - stack_pointer[-1] = res; + if (res == NULL) goto pop_3_error_tier_two; + stack_pointer[-3] = res; + stack_pointer += -2; break; } - case STORE_SLICE: { + case _STORE_SLICE: { PyObject *stop; PyObject *start; PyObject *container; @@ -443,200 +467,186 @@ } Py_DECREF(v); Py_DECREF(container); - if (err) goto pop_4_error; - STACK_SHRINK(4); + if (err) goto pop_4_error_tier_two; + stack_pointer += -4; break; } - case BINARY_SUBSCR_LIST_INT: { + case _BINARY_SUBSCR_LIST_INT: { 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); - + if (!PyLong_CheckExact(sub)) goto deoptimize; + if (!PyList_CheckExact(list)) goto deoptimize; // Deopt unless 0 <= sub < PyList_Size(list) - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) goto deoptimize; Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + if (index >= PyList_GET_SIZE(list)) goto deoptimize; STAT_INC(BINARY_SUBSCR, hit); res = PyList_GET_ITEM(list, index); assert(res != NULL); Py_INCREF(res); _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(list); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case BINARY_SUBSCR_STR_INT: { + 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); + if (!PyLong_CheckExact(sub)) goto deoptimize; + if (!PyUnicode_CheckExact(str)) goto deoptimize; + if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) goto deoptimize; Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index, BINARY_SUBSCR); + if (PyUnicode_GET_LENGTH(str) <= index) goto deoptimize; // 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); + if (Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c) goto deoptimize; 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; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case BINARY_SUBSCR_TUPLE_INT: { + case _BINARY_SUBSCR_TUPLE_INT: { 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); - + if (!PyLong_CheckExact(sub)) goto deoptimize; + if (!PyTuple_CheckExact(tuple)) goto deoptimize; // Deopt unless 0 <= sub < PyTuple_Size(list) - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) goto deoptimize; Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); + if (index >= PyTuple_GET_SIZE(tuple)) goto deoptimize; STAT_INC(BINARY_SUBSCR, hit); res = PyTuple_GET_ITEM(tuple, index); assert(res != NULL); Py_INCREF(res); _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(tuple); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case BINARY_SUBSCR_DICT: { + case _BINARY_SUBSCR_DICT: { PyObject *sub; PyObject *dict; PyObject *res; sub = stack_pointer[-1]; dict = stack_pointer[-2]; - DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); + if (!PyDict_CheckExact(dict)) goto deoptimize; STAT_INC(BINARY_SUBSCR, hit); - res = PyDict_GetItemWithError(dict, sub); - if (res == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetKeyError(sub); - } - Py_DECREF(dict); - Py_DECREF(sub); - if (true) goto pop_2_error; + int rc = PyDict_GetItemRef(dict, sub, &res); + if (rc == 0) { + _PyErr_SetKeyError(sub); } - Py_INCREF(res); // Do this before DECREF'ing dict, sub Py_DECREF(dict); Py_DECREF(sub); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (rc <= 0) goto pop_2_error_tier_two; + // not found or error + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case LIST_APPEND: { + /* _BINARY_SUBSCR_GETITEM is not a viable micro-op for tier 2 */ + + case _LIST_APPEND: { PyObject *v; PyObject *list; + oparg = CURRENT_OPARG(); v = stack_pointer[-1]; list = stack_pointer[-2 - (oparg-1)]; - if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error; - STACK_SHRINK(1); + if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error_tier_two; + stack_pointer += -1; break; } - case SET_ADD: { + case _SET_ADD: { PyObject *v; PyObject *set; + oparg = CURRENT_OPARG(); 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; - STACK_SHRINK(1); + if (err) goto pop_1_error_tier_two; + stack_pointer += -1; break; } - case STORE_SUBSCR: { + case _STORE_SUBSCR: { 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)) { - next_instr--; - _Py_Specialize_StoreSubscr(container, sub, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(STORE_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ /* container[sub] = v */ int err = PyObject_SetItem(container, sub, v); Py_DECREF(v); Py_DECREF(container); Py_DECREF(sub); - if (err) goto pop_3_error; - STACK_SHRINK(3); + if (err) goto pop_3_error_tier_two; + stack_pointer += -3; break; } - case STORE_SUBSCR_LIST_INT: { + case _STORE_SUBSCR_LIST_INT: { 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); - + if (!PyLong_CheckExact(sub)) goto deoptimize; + if (!PyList_CheckExact(list)) goto deoptimize; // Ensure nonnegative, zero-or-one-digit ints. - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), STORE_SUBSCR); + if (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) goto deoptimize; Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; // Ensure index < len(list) - DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + if (index >= PyList_GET_SIZE(list)) goto deoptimize; STAT_INC(STORE_SUBSCR, hit); - PyObject *old_value = PyList_GET_ITEM(list, index); PyList_SET_ITEM(list, index, value); assert(old_value != NULL); Py_DECREF(old_value); _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(list); - STACK_SHRINK(3); + stack_pointer += -3; break; } - case STORE_SUBSCR_DICT: { + case _STORE_SUBSCR_DICT: { 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); + if (!PyDict_CheckExact(dict)) goto deoptimize; STAT_INC(STORE_SUBSCR, hit); int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); Py_DECREF(dict); - if (err) goto pop_3_error; - STACK_SHRINK(3); + if (err) goto pop_3_error_tier_two; + stack_pointer += -3; break; } - case DELETE_SUBSCR: { + case _DELETE_SUBSCR: { PyObject *sub; PyObject *container; sub = stack_pointer[-1]; @@ -645,126 +655,136 @@ int err = PyObject_DelItem(container, sub); Py_DECREF(container); Py_DECREF(sub); - if (err) goto pop_2_error; - STACK_SHRINK(2); + if (err) goto pop_2_error_tier_two; + stack_pointer += -2; break; } - case CALL_INTRINSIC_1: { + case _CALL_INTRINSIC_1: { PyObject *value; PyObject *res; + oparg = CURRENT_OPARG(); value = stack_pointer[-1]; assert(oparg <= MAX_INTRINSIC_1); res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value); Py_DECREF(value); - if (res == NULL) goto pop_1_error; + if (res == NULL) goto pop_1_error_tier_two; stack_pointer[-1] = res; break; } - case CALL_INTRINSIC_2: { + case _CALL_INTRINSIC_2: { PyObject *value1; PyObject *value2; PyObject *res; + oparg = CURRENT_OPARG(); value1 = stack_pointer[-1]; value2 = stack_pointer[-2]; assert(oparg <= MAX_INTRINSIC_2); res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); Py_DECREF(value2); Py_DECREF(value1); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } + case _INTERPRETER_EXIT: { + PyObject *retval; + retval = stack_pointer[-1]; + assert(frame == &entry_frame); + assert(_PyFrame_IsIncomplete(frame)); + /* Restore previous frame and return. */ + tstate->current_frame = frame->previous; + assert(!_PyErr_Occurred(tstate)); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + return retval; + } + case _POP_FRAME: { PyObject *retval; retval = stack_pointer[-1]; - STACK_SHRINK(1); - assert(EMPTY()); #if TIER_ONE assert(frame != &entry_frame); #endif - STORE_SP(); + stack_pointer += -1; + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(EMPTY()); _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 + LOAD_IP(frame->return_offset); + #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { goto exit_unwind; } -#endif + #endif break; } - case GET_AITER: { + /* _INSTRUMENTED_RETURN_VALUE is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_RETURN_CONST is not a viable micro-op for tier 2 */ + + case _GET_AITER: { PyObject *obj; PyObject *iter; obj = stack_pointer[-1]; unaryfunc getter = NULL; PyTypeObject *type = Py_TYPE(obj); - if (type->tp_as_async != NULL) { getter = type->tp_as_async->am_aiter; } - if (getter == NULL) { _PyErr_Format(tstate, PyExc_TypeError, "'async for' requires an object with " "__aiter__ method, got %.100s", type->tp_name); Py_DECREF(obj); - if (true) goto pop_1_error; + if (true) goto pop_1_error_tier_two; } - iter = (*getter)(obj); Py_DECREF(obj); - if (iter == NULL) goto pop_1_error; - + if (iter == NULL) goto pop_1_error_tier_two; if (Py_TYPE(iter)->tp_as_async == NULL || - Py_TYPE(iter)->tp_as_async->am_anext == NULL) { - + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { _PyErr_Format(tstate, PyExc_TypeError, "'async for' received an object from __aiter__ " "that does not implement __anext__: %.100s", Py_TYPE(iter)->tp_name); Py_DECREF(iter); - if (true) goto pop_1_error; + if (true) goto pop_1_error_tier_two; } stack_pointer[-1] = iter; break; } - case GET_ANEXT: { + case _GET_ANEXT: { PyObject *aiter; PyObject *awaitable; aiter = stack_pointer[-1]; unaryfunc getter = NULL; PyObject *next_iter = NULL; PyTypeObject *type = Py_TYPE(aiter); - if (PyAsyncGen_CheckExact(aiter)) { awaitable = type->tp_as_async->am_anext(aiter); if (awaitable == NULL) { - goto error; + GOTO_ERROR(error); } } else { if (type->tp_as_async != NULL){ getter = type->tp_as_async->am_anext; } - if (getter != NULL) { next_iter = (*getter)(aiter); if (next_iter == NULL) { - goto error; + GOTO_ERROR(error); } } else { @@ -772,9 +792,8 @@ "'async for' requires an iterator with " "__anext__ method, got %.100s", type->tp_name); - goto error; + GOTO_ERROR(error); } - awaitable = _PyCoro_GetAwaitableIter(next_iter); if (awaitable == NULL) { _PyErr_FormatFromCause( @@ -782,30 +801,27 @@ "'async for' received an invalid object " "from __anext__: %.100s", Py_TYPE(next_iter)->tp_name); - Py_DECREF(next_iter); - goto error; + GOTO_ERROR(error); } else { Py_DECREF(next_iter); } } - STACK_GROW(1); - stack_pointer[-1] = awaitable; + stack_pointer[0] = awaitable; + stack_pointer += 1; break; } - case GET_AWAITABLE: { + case _GET_AWAITABLE: { PyObject *iterable; PyObject *iter; + oparg = CURRENT_OPARG(); iterable = stack_pointer[-1]; iter = _PyCoro_GetAwaitableIter(iterable); - if (iter == NULL) { _PyEval_FormatAwaitableError(tstate, Py_TYPE(iterable), oparg); } - Py_DECREF(iterable); - if (iter != NULL && PyCoro_CheckExact(iter)) { PyObject *yf = _PyGen_yf((PyGenObject*)iter); if (yf != NULL) { @@ -819,44 +835,77 @@ /* The code below jumps to `error` if `iter` is NULL. */ } } - - if (iter == NULL) goto pop_1_error; + if (iter == NULL) goto pop_1_error_tier_two; stack_pointer[-1] = iter; break; } - case POP_EXCEPT: { + /* _SEND is not a viable micro-op for tier 2 */ + + /* _SEND_GEN is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_YIELD_VALUE is not a viable micro-op for tier 2 */ + + case _YIELD_VALUE: { + PyObject *retval; + oparg = CURRENT_OPARG(); + 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. + assert(frame != &entry_frame); + frame->instr_ptr = next_instr; + PyGenObject *gen = _PyFrame_GetGenerator(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + gen->gi_frame_state = FRAME_SUSPENDED + oparg; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + /* We don't know which of these is relevant here, so keep them equal */ + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + goto resume_frame; + } + + case _POP_EXCEPT: { 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); + stack_pointer += -1; break; } - case LOAD_ASSERTION_ERROR: { + case _LOAD_ASSERTION_ERROR: { PyObject *value; value = Py_NewRef(PyExc_AssertionError); - STACK_GROW(1); - stack_pointer[-1] = value; + stack_pointer[0] = value; + stack_pointer += 1; break; } - case LOAD_BUILD_CLASS: { + case _LOAD_BUILD_CLASS: { PyObject *bc; - if (PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc) < 0) goto error; + if (PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc) < 0) goto error_tier_two; if (bc == NULL) { _PyErr_SetString(tstate, PyExc_NameError, "__build_class__ not found"); - if (true) goto error; + if (true) goto error_tier_two; } - STACK_GROW(1); - stack_pointer[-1] = bc; + stack_pointer[0] = bc; + stack_pointer += 1; break; } - case STORE_NAME: { + case _STORE_NAME: { PyObject *v; + oparg = CURRENT_OPARG(); v = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *ns = LOCALS(); @@ -865,173 +914,158 @@ _PyErr_Format(tstate, PyExc_SystemError, "no locals found when storing %R", name); Py_DECREF(v); - if (true) goto pop_1_error; + if (true) goto pop_1_error_tier_two; } if (PyDict_CheckExact(ns)) - err = PyDict_SetItem(ns, name, v); + err = PyDict_SetItem(ns, name, v); else - err = PyObject_SetItem(ns, name, v); + err = PyObject_SetItem(ns, name, v); Py_DECREF(v); - if (err) goto pop_1_error; - STACK_SHRINK(1); + if (err) goto pop_1_error_tier_two; + stack_pointer += -1; break; } - case DELETE_NAME: { + case _DELETE_NAME: { + oparg = CURRENT_OPARG(); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *ns = LOCALS(); int err; if (ns == NULL) { _PyErr_Format(tstate, PyExc_SystemError, "no locals when deleting %R", name); - goto error; + GOTO_ERROR(error); } err = PyObject_DelItem(ns, name); // Can't use ERROR_IF here. if (err != 0) { _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); - goto error; + NAME_ERROR_MSG, + name); + GOTO_ERROR(error); } break; } - case UNPACK_SEQUENCE: { + case _UNPACK_SEQUENCE: { PyObject *seq; + oparg = CURRENT_OPARG(); seq = stack_pointer[-1]; - #if ENABLE_SPECIALIZATION - _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_UnpackSequence(seq, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - STAT_INC(UNPACK_SEQUENCE, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); Py_DECREF(seq); - if (res == 0) goto pop_1_error; - STACK_SHRINK(1); - STACK_GROW(oparg); + if (res == 0) goto pop_1_error_tier_two; + stack_pointer += -1 + oparg; break; } - case UNPACK_SEQUENCE_TWO_TUPLE: { + case _UNPACK_SEQUENCE_TWO_TUPLE: { PyObject *seq; PyObject **values; + oparg = CURRENT_OPARG(); seq = stack_pointer[-1]; - values = stack_pointer - 1; - DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + values = &stack_pointer[-1]; + if (!PyTuple_CheckExact(seq)) goto deoptimize; + if (PyTuple_GET_SIZE(seq) != 2) goto deoptimize; assert(oparg == 2); STAT_INC(UNPACK_SEQUENCE, hit); values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); Py_DECREF(seq); - STACK_SHRINK(1); - STACK_GROW(oparg); + stack_pointer += -1 + oparg; break; } - case UNPACK_SEQUENCE_TUPLE: { + case _UNPACK_SEQUENCE_TUPLE: { PyObject *seq; PyObject **values; + oparg = CURRENT_OPARG(); seq = stack_pointer[-1]; - values = stack_pointer - 1; - DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + values = &stack_pointer[-1]; + if (!PyTuple_CheckExact(seq)) goto deoptimize; + if (PyTuple_GET_SIZE(seq) != oparg) goto deoptimize; STAT_INC(UNPACK_SEQUENCE, hit); PyObject **items = _PyTuple_ITEMS(seq); for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } Py_DECREF(seq); - STACK_SHRINK(1); - STACK_GROW(oparg); + stack_pointer += -1 + oparg; break; } - case UNPACK_SEQUENCE_LIST: { + case _UNPACK_SEQUENCE_LIST: { PyObject *seq; PyObject **values; + oparg = CURRENT_OPARG(); seq = stack_pointer[-1]; - values = stack_pointer - 1; - DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + values = &stack_pointer[-1]; + if (!PyList_CheckExact(seq)) goto deoptimize; + if (PyList_GET_SIZE(seq) != oparg) goto deoptimize; STAT_INC(UNPACK_SEQUENCE, hit); PyObject **items = _PyList_ITEMS(seq); for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } Py_DECREF(seq); - STACK_SHRINK(1); - STACK_GROW(oparg); + stack_pointer += -1 + oparg; break; } - case UNPACK_EX: { + case _UNPACK_EX: { PyObject *seq; + oparg = CURRENT_OPARG(); seq = stack_pointer[-1]; int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; 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)); + if (res == 0) goto pop_1_error_tier_two; + stack_pointer += (oparg >> 8) + (oparg & 0xFF); break; } - case STORE_ATTR: { + case _STORE_ATTR: { PyObject *owner; PyObject *v; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; v = stack_pointer[-2]; - #if ENABLE_SPECIALIZATION - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - next_instr--; - _Py_Specialize_StoreAttr(owner, next_instr, name); - DISPATCH_SAME_OPARG(); - } - STAT_INC(STORE_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyObject_SetAttr(owner, name, v); Py_DECREF(v); Py_DECREF(owner); - if (err) goto pop_2_error; - STACK_SHRINK(2); + if (err) goto pop_2_error_tier_two; + stack_pointer += -2; break; } - case DELETE_ATTR: { + case _DELETE_ATTR: { PyObject *owner; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyObject_DelAttr(owner, name); Py_DECREF(owner); - if (err) goto pop_1_error; - STACK_SHRINK(1); + if (err) goto pop_1_error_tier_two; + stack_pointer += -1; break; } - case STORE_GLOBAL: { + case _STORE_GLOBAL: { PyObject *v; + oparg = CURRENT_OPARG(); v = stack_pointer[-1]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); Py_DECREF(v); - if (err) goto pop_1_error; - STACK_SHRINK(1); + if (err) goto pop_1_error_tier_two; + stack_pointer += -1; break; } - case DELETE_GLOBAL: { + case _DELETE_GLOBAL: { + oparg = CURRENT_OPARG(); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err; err = PyDict_DelItem(GLOBALS(), name); @@ -1039,52 +1073,49 @@ if (err != 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name); } - goto error; + GOTO_ERROR(error); } break; } - case LOAD_LOCALS: { + case _LOAD_LOCALS: { PyObject *locals; locals = LOCALS(); if (locals == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "no locals found"); - if (true) goto error; + if (true) goto error_tier_two; } Py_INCREF(locals); - STACK_GROW(1); - stack_pointer[-1] = locals; + stack_pointer[0] = locals; + stack_pointer += 1; break; } - case LOAD_FROM_DICT_OR_GLOBALS: { + case _LOAD_FROM_DICT_OR_GLOBALS: { PyObject *mod_or_class_dict; PyObject *v; + oparg = CURRENT_OPARG(); 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; + GOTO_ERROR(error); } if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); + if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) { + GOTO_ERROR(error); } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - else { + if (v == NULL) { if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { _PyEval_FormatExcCheckArg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + GOTO_ERROR(error); } } } @@ -1093,113 +1124,98 @@ break; } - case LOAD_NAME: { + case _LOAD_NAME: { PyObject *v; + oparg = CURRENT_OPARG(); PyObject *mod_or_class_dict = LOCALS(); if (mod_or_class_dict == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "no locals found"); - if (true) goto error; + if (true) goto error_tier_two; } PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; + if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) { + GOTO_ERROR(error); } - else { + if (v == NULL) { if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; + GOTO_ERROR(error); } if (v == NULL) { _PyEval_FormatExcCheckArg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + GOTO_ERROR(error); } } } - STACK_GROW(1); - stack_pointer[-1] = v; + stack_pointer[0] = v; + stack_pointer += 1; break; } - case LOAD_GLOBAL: { + case _LOAD_GLOBAL: { PyObject *res; PyObject *null = NULL; - #if ENABLE_SPECIALIZATION - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - next_instr--; - _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); - DISPATCH_SAME_OPARG(); - } - STAT_INC(LOAD_GLOBAL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ + oparg = CURRENT_OPARG(); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { res = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); + (PyDictObject *)BUILTINS(), + name); if (res == NULL) { if (!_PyErr_Occurred(tstate)) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name); } - if (true) goto error; + if (true) goto error_tier_two; } Py_INCREF(res); } else { /* Slow-path if globals or builtins is not a dict */ - /* namespace 1: globals */ - if (PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0) goto error; + if (PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0) goto error_tier_two; if (res == NULL) { /* namespace 2: builtins */ - if (PyMapping_GetOptionalItem(BUILTINS(), name, &res) < 0) goto error; + if (PyMapping_GetOptionalItem(BUILTINS(), name, &res) < 0) goto error_tier_two; if (res == NULL) { _PyEval_FormatExcCheckArg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - if (true) goto error; + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + if (true) goto error_tier_two; } } } null = NULL; - STACK_GROW(1); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + stack_pointer[0] = res; + if (oparg & 1) stack_pointer[1] = null; + stack_pointer += 1 + ((oparg & 1)); break; } case _GUARD_GLOBALS_VERSION: { - uint16_t version = (uint16_t)operand; + uint16_t version = (uint16_t)CURRENT_OPERAND(); PyDictObject *dict = (PyDictObject *)GLOBALS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + if (!PyDict_CheckExact(dict)) goto deoptimize; + if (dict->ma_keys->dk_version != version) goto deoptimize; assert(DK_IS_UNICODE(dict->ma_keys)); break; } case _GUARD_BUILTINS_VERSION: { - uint16_t version = (uint16_t)operand; + uint16_t version = (uint16_t)CURRENT_OPERAND(); PyDictObject *dict = (PyDictObject *)BUILTINS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + if (!PyDict_CheckExact(dict)) goto deoptimize; + if (dict->ma_keys->dk_version != version) goto deoptimize; assert(DK_IS_UNICODE(dict->ma_keys)); break; } @@ -1207,112 +1223,130 @@ case _LOAD_GLOBAL_MODULE: { PyObject *res; PyObject *null = NULL; - uint16_t index = (uint16_t)operand; + oparg = CURRENT_OPARG(); + uint16_t index = (uint16_t)CURRENT_OPERAND(); PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); + if (res == NULL) goto deoptimize; Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - STACK_GROW(1); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + stack_pointer[0] = res; + if (oparg & 1) stack_pointer[1] = null; + stack_pointer += 1 + ((oparg & 1)); break; } case _LOAD_GLOBAL_BUILTINS: { PyObject *res; PyObject *null = NULL; - uint16_t index = (uint16_t)operand; + oparg = CURRENT_OPARG(); + uint16_t index = (uint16_t)CURRENT_OPERAND(); PyDictObject *bdict = (PyDictObject *)BUILTINS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); + if (res == NULL) goto deoptimize; Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - STACK_GROW(1); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + stack_pointer[0] = res; + if (oparg & 1) stack_pointer[1] = null; + stack_pointer += 1 + ((oparg & 1)); break; } - case DELETE_FAST: { + case _DELETE_FAST: { + oparg = CURRENT_OPARG(); PyObject *v = GETLOCAL(oparg); - if (v == NULL) goto unbound_local_error; + if (v == NULL) goto unbound_local_error_tier_two; SETLOCAL(oparg, NULL); break; } - case DELETE_DEREF: { + case _MAKE_CELL: { + oparg = CURRENT_OPARG(); + // "initial" is probably NULL but not if it's an arg (or set + // via PyFrame_LocalsToFast() before MAKE_CELL has run). + PyObject *initial = GETLOCAL(oparg); + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + GOTO_ERROR(error); + } + SETLOCAL(oparg, cell); + break; + } + + case _DELETE_DEREF: { + oparg = CURRENT_OPARG(); PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); // Can't use ERROR_IF here. // Fortunately we don't need its superpower. if (oldobj == NULL) { _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - goto error; + GOTO_ERROR(error); } PyCell_SET(cell, NULL); Py_DECREF(oldobj); break; } - case LOAD_FROM_DICT_OR_DEREF: { + case _LOAD_FROM_DICT_OR_DEREF: { PyObject *class_dict; PyObject *value; + oparg = CURRENT_OPARG(); class_dict = stack_pointer[-1]; PyObject *name; assert(class_dict); assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); if (PyMapping_GetOptionalItem(class_dict, name, &value) < 0) { - Py_DECREF(class_dict); - goto error; + GOTO_ERROR(error); } - Py_DECREF(class_dict); if (!value) { PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - goto error; + GOTO_ERROR(error); } Py_INCREF(value); } + Py_DECREF(class_dict); stack_pointer[-1] = value; break; } - case LOAD_DEREF: { + case _LOAD_DEREF: { PyObject *value; + oparg = CURRENT_OPARG(); PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - if (true) goto error; + if (true) goto error_tier_two; } Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + stack_pointer[0] = value; + stack_pointer += 1; break; } - case STORE_DEREF: { + case _STORE_DEREF: { PyObject *v; + oparg = CURRENT_OPARG(); v = stack_pointer[-1]; PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); Py_XDECREF(oldobj); - STACK_SHRINK(1); + stack_pointer += -1; break; } - case COPY_FREE_VARS: { + case _COPY_FREE_VARS: { + oparg = CURRENT_OPARG(); /* Copy closure variables to free variables */ PyCodeObject *co = _PyFrame_GetCode(frame); assert(PyFunction_Check(frame->f_funcobj)); @@ -1326,275 +1360,268 @@ break; } - case BUILD_STRING: { + case _BUILD_STRING: { PyObject **pieces; PyObject *str; - pieces = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + pieces = &stack_pointer[-oparg]; str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); } - if (str == NULL) { STACK_SHRINK(oparg); goto error; } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = str; + if (str == NULL) { stack_pointer += -oparg; goto error_tier_two; } + stack_pointer[-oparg] = str; + stack_pointer += 1 - oparg; break; } - case BUILD_TUPLE: { + case _BUILD_TUPLE: { PyObject **values; PyObject *tup; - values = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + values = &stack_pointer[-oparg]; tup = _PyTuple_FromArraySteal(values, oparg); - if (tup == NULL) { STACK_SHRINK(oparg); goto error; } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = tup; + if (tup == NULL) { stack_pointer += -oparg; goto error_tier_two; } + stack_pointer[-oparg] = tup; + stack_pointer += 1 - oparg; break; } - case BUILD_LIST: { + case _BUILD_LIST: { PyObject **values; PyObject *list; - values = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + values = &stack_pointer[-oparg]; list = _PyList_FromArraySteal(values, oparg); - if (list == NULL) { STACK_SHRINK(oparg); goto error; } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = list; + if (list == NULL) { stack_pointer += -oparg; goto error_tier_two; } + stack_pointer[-oparg] = list; + stack_pointer += 1 - oparg; break; } - case LIST_EXTEND: { + case _LIST_EXTEND: { PyObject *iterable; PyObject *list; + oparg = CURRENT_OPARG(); 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) && - (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) { _PyErr_Clear(tstate); _PyErr_Format(tstate, PyExc_TypeError, - "Value after * must be an iterable, not %.200s", - Py_TYPE(iterable)->tp_name); + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); } Py_DECREF(iterable); - if (true) goto pop_1_error; + if (true) goto pop_1_error_tier_two; } assert(Py_IsNone(none_val)); Py_DECREF(iterable); - STACK_SHRINK(1); + stack_pointer += -1; break; } - case SET_UPDATE: { + case _SET_UPDATE: { PyObject *iterable; PyObject *set; + oparg = CURRENT_OPARG(); 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; - STACK_SHRINK(1); + if (err < 0) goto pop_1_error_tier_two; + stack_pointer += -1; break; } - case BUILD_SET: { + case _BUILD_SET: { PyObject **values; PyObject *set; - values = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + values = &stack_pointer[-oparg]; set = PySet_New(NULL); if (set == NULL) - goto error; + GOTO_ERROR(error); int err = 0; for (int i = 0; i < oparg; i++) { PyObject *item = values[i]; if (err == 0) - err = PySet_Add(set, item); + err = PySet_Add(set, item); Py_DECREF(item); } if (err != 0) { Py_DECREF(set); - if (true) { STACK_SHRINK(oparg); goto error; } + if (true) { stack_pointer += -oparg; goto error_tier_two; } } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = set; + stack_pointer[-oparg] = set; + stack_pointer += 1 - oparg; break; } - case BUILD_MAP: { + case _BUILD_MAP: { PyObject **values; PyObject *map; - values = stack_pointer - oparg*2; + oparg = CURRENT_OPARG(); + values = &stack_pointer[-oparg*2]; map = _PyDict_FromItems( - values, 2, - values+1, 2, - oparg); + values, 2, + values+1, 2, + oparg); for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } - if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } - STACK_SHRINK(oparg*2); - STACK_GROW(1); - stack_pointer[-1] = map; + if (map == NULL) { stack_pointer += -oparg*2; goto error_tier_two; } + stack_pointer[-oparg*2] = map; + stack_pointer += 1 - oparg*2; break; } - case SETUP_ANNOTATIONS: { + case _SETUP_ANNOTATIONS: { int err; PyObject *ann_dict; if (LOCALS() == NULL) { _PyErr_Format(tstate, PyExc_SystemError, "no locals found when setting up annotations"); - if (true) goto error; + if (true) goto error_tier_two; } /* check if __annotations__ in locals()... */ - if (PyDict_CheckExact(LOCALS())) { - ann_dict = _PyDict_GetItemWithError(LOCALS(), - &_Py_ID(__annotations__)); - if (ann_dict == NULL) { - if (_PyErr_Occurred(tstate)) goto error; - /* ...if not, create a new one */ - ann_dict = PyDict_New(); - if (ann_dict == NULL) goto error; - err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - if (err) goto error; - } + if (PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict) < 0) goto error_tier_two; + if (ann_dict == NULL) { + ann_dict = PyDict_New(); + if (ann_dict == NULL) goto error_tier_two; + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + if (err) goto error_tier_two; } else { - /* do the same if locals() is not a dict */ - if (PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict) < 0) goto error; - if (ann_dict == NULL) { - ann_dict = PyDict_New(); - if (ann_dict == NULL) goto error; - err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - if (err) goto error; - } - else { - Py_DECREF(ann_dict); - } + Py_DECREF(ann_dict); } break; } - case BUILD_CONST_KEY_MAP: { + case _BUILD_CONST_KEY_MAP: { PyObject *keys; PyObject **values; PyObject *map; + oparg = CURRENT_OPARG(); keys = stack_pointer[-1]; - values = stack_pointer - 1 - oparg; + values = &stack_pointer[-1 - oparg]; if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, "bad BUILD_CONST_KEY_MAP keys argument"); - goto error; // Pop the keys and values. + GOTO_ERROR(error); // Pop the keys and values. } map = _PyDict_FromItems( - &PyTuple_GET_ITEM(keys, 0), 1, - values, 1, oparg); + &PyTuple_GET_ITEM(keys, 0), 1, + values, 1, oparg); for (int _i = oparg; --_i >= 0;) { Py_DECREF(values[_i]); } Py_DECREF(keys); - if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } - STACK_SHRINK(oparg); - stack_pointer[-1] = map; + if (map == NULL) { stack_pointer += -1 - oparg; goto error_tier_two; } + stack_pointer[-1 - oparg] = map; + stack_pointer += -oparg; break; } - case DICT_UPDATE: { + case _DICT_UPDATE: { PyObject *update; PyObject *dict; + oparg = CURRENT_OPARG(); 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, - "'%.200s' object is not a mapping", - Py_TYPE(update)->tp_name); + "'%.200s' object is not a mapping", + Py_TYPE(update)->tp_name); } Py_DECREF(update); - if (true) goto pop_1_error; + if (true) goto pop_1_error_tier_two; } Py_DECREF(update); - STACK_SHRINK(1); + stack_pointer += -1; break; } - case DICT_MERGE: { + case _DICT_MERGE: { PyObject *update; PyObject *dict; PyObject *callable; + oparg = CURRENT_OPARG(); update = stack_pointer[-1]; dict = stack_pointer[-2 - (oparg - 1)]; callable = stack_pointer[-5 - (oparg - 1)]; if (_PyDict_MergeEx(dict, update, 2) < 0) { _PyEval_FormatKwargsError(tstate, callable, update); Py_DECREF(update); - if (true) goto pop_1_error; + if (true) goto pop_1_error_tier_two; } Py_DECREF(update); - STACK_SHRINK(1); + stack_pointer += -1; break; } - case MAP_ADD: { + case _MAP_ADD: { PyObject *value; PyObject *key; PyObject *dict; + oparg = CURRENT_OPARG(); 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 - if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; - STACK_SHRINK(2); + if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error_tier_two; + stack_pointer += -2; break; } - case LOAD_SUPER_ATTR_ATTR: { + /* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 */ + + case _LOAD_SUPER_ATTR_ATTR: { PyObject *self; PyObject *class; PyObject *global_super; PyObject *attr; + oparg = CURRENT_OPARG(); 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); + if (global_super != (PyObject *)&PySuper_Type) goto deoptimize; + if (!PyType_Check(class)) goto deoptimize; STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - if (attr == NULL) goto pop_3_error; - STACK_SHRINK(2); - stack_pointer[-1] = attr; + if (attr == NULL) goto pop_3_error_tier_two; + stack_pointer[-3] = attr; + stack_pointer += -2 + (((0) ? 1 : 0)); break; } - case LOAD_SUPER_ATTR_METHOD: { + case _LOAD_SUPER_ATTR_METHOD: { PyObject *self; PyObject *class; PyObject *global_super; PyObject *attr; PyObject *self_or_null; + oparg = CURRENT_OPARG(); 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); + if (global_super != (PyObject *)&PySuper_Type) goto deoptimize; + if (!PyType_Check(class)) goto deoptimize; STAT_INC(LOAD_SUPER_ATTR, hit); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); PyTypeObject *cls = (PyTypeObject *)class; @@ -1605,7 +1632,7 @@ Py_DECREF(class); if (attr == NULL) { Py_DECREF(self); - if (true) goto pop_3_error; + if (true) goto pop_3_error_tier_two; } if (method_found) { self_or_null = self; // transfer ownership @@ -1613,28 +1640,18 @@ Py_DECREF(self); self_or_null = NULL; } - STACK_SHRINK(1); - stack_pointer[-2] = attr; - stack_pointer[-1] = self_or_null; + stack_pointer[-3] = attr; + stack_pointer[-2] = self_or_null; + stack_pointer += -1; break; } - case LOAD_ATTR: { + case _LOAD_ATTR: { PyObject *owner; PyObject *attr; PyObject *self_or_null = NULL; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; - #if ENABLE_SPECIALIZATION - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - next_instr--; - _Py_Specialize_LoadAttr(owner, next_instr, name); - DISPATCH_SAME_OPARG(); - } - STAT_INC(LOAD_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); if (oparg & 1) { /* Designed to work in tandem with CALL, pushes two values. */ @@ -1642,7 +1659,6 @@ 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(attr != NULL); // No errors on this branch @@ -1653,11 +1669,10 @@ something was returned by a descriptor protocol). Set the second element of the stack to NULL, to signal CALL that it's not a method call. - NULL | meth | arg1 | ... | argN - */ + */ Py_DECREF(owner); - if (attr == NULL) goto pop_1_error; + if (attr == NULL) goto pop_1_error_tier_two; self_or_null = NULL; } } @@ -1665,21 +1680,21 @@ /* Classic, pushes one value. */ attr = PyObject_GetAttr(owner, name); Py_DECREF(owner); - if (attr == NULL) goto pop_1_error; + if (attr == NULL) goto pop_1_error_tier_two; } - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = self_or_null; } + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = self_or_null; + stack_pointer += ((oparg & 1)); break; } case _GUARD_TYPE_VERSION: { PyObject *owner; owner = stack_pointer[-1]; - uint32_t type_version = (uint32_t)operand; + uint32_t type_version = (uint32_t)CURRENT_OPERAND(); PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + if (tp->tp_version_tag != type_version) goto deoptimize; break; } @@ -1689,9 +1704,7 @@ 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) && - !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), - LOAD_ATTR); + if (!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)) goto deoptimize; break; } @@ -1699,18 +1712,97 @@ PyObject *owner; PyObject *attr; PyObject *null = NULL; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; - uint16_t index = (uint16_t)operand; + uint16_t index = (uint16_t)CURRENT_OPERAND(); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); attr = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(attr == NULL, LOAD_ATTR); + if (attr == NULL) goto deoptimize; + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); + break; + } + + case _CHECK_ATTR_MODULE: { + PyObject *owner; + owner = stack_pointer[-1]; + uint32_t type_version = (uint32_t)CURRENT_OPERAND(); + if (!PyModule_CheckExact(owner)) goto deoptimize; + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + if (dict->ma_keys->dk_version != type_version) goto deoptimize; + break; + } + + case _LOAD_ATTR_MODULE: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + uint16_t index = (uint16_t)CURRENT_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; + if (attr == NULL) goto deoptimize; + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); + 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); + if (_PyDictOrValues_IsValues(dorv)) goto deoptimize; + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + if (dict == NULL) goto deoptimize; + assert(PyDict_CheckExact((PyObject *)dict)); + break; + } + + case _LOAD_ATTR_WITH_HINT: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + uint16_t hint = (uint16_t)CURRENT_OPERAND(); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + if (hint >= (size_t)dict->ma_keys->dk_nentries) goto deoptimize; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + if (ep->me_key != name) goto deoptimize; + attr = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + if (ep->me_key != name) goto deoptimize; + attr = ep->me_value; + } + if (attr == NULL) goto deoptimize; 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; } + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); break; } @@ -1718,27 +1810,60 @@ PyObject *owner; PyObject *attr; PyObject *null = NULL; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; - uint16_t index = (uint16_t)operand; + uint16_t index = (uint16_t)CURRENT_OPERAND(); char *addr = (char *)owner + index; attr = *(PyObject **)addr; - DEOPT_IF(attr == NULL, LOAD_ATTR); + if (attr == NULL) goto deoptimize; 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; } + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); + break; + } + + case _CHECK_ATTR_CLASS: { + PyObject *owner; + owner = stack_pointer[-1]; + uint32_t type_version = (uint32_t)CURRENT_OPERAND(); + if (!PyType_Check(owner)) goto deoptimize; + assert(type_version != 0); + if (((PyTypeObject *)owner)->tp_version_tag != type_version) goto deoptimize; + break; + } + + case _LOAD_ATTR_CLASS: { + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)CURRENT_OPERAND(); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + attr = Py_NewRef(descr); + null = NULL; + Py_DECREF(owner); + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); break; } + /* _LOAD_ATTR_PROPERTY is not a viable micro-op for tier 2 */ + + /* _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN is not a viable micro-op for tier 2 */ + 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), STORE_ATTR); + if (!_PyDictOrValues_IsValues(dorv)) goto deoptimize; break; } @@ -1747,7 +1872,7 @@ PyObject *value; owner = stack_pointer[-1]; value = stack_pointer[-2]; - uint16_t index = (uint16_t)operand; + uint16_t index = (uint16_t)CURRENT_OPERAND(); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); STAT_INC(STORE_ATTR, hit); PyDictValues *values = _PyDictOrValues_GetValues(dorv); @@ -1760,76 +1885,60 @@ Py_DECREF(old_value); } Py_DECREF(owner); - STACK_SHRINK(2); + stack_pointer += -2; break; } - case _GUARD_TYPE_VERSION_STORE: { - 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, STORE_ATTR); - break; - } + /* _STORE_ATTR_WITH_HINT is not a viable micro-op for tier 2 */ case _STORE_ATTR_SLOT: { PyObject *owner; PyObject *value; owner = stack_pointer[-1]; value = stack_pointer[-2]; - uint16_t index = (uint16_t)operand; + uint16_t index = (uint16_t)CURRENT_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); + stack_pointer += -2; break; } - case COMPARE_OP: { + case _COMPARE_OP: { PyObject *right; PyObject *left; PyObject *res; + oparg = CURRENT_OPARG(); right = stack_pointer[-1]; left = stack_pointer[-2]; - #if ENABLE_SPECIALIZATION - _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_CompareOp(left, right, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - STAT_INC(COMPARE_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ assert((oparg >> 5) <= Py_GE); res = PyObject_RichCompare(left, right, oparg >> 5); Py_DECREF(left); Py_DECREF(right); - if (res == NULL) goto pop_2_error; + if (res == NULL) goto pop_2_error_tier_two; if (oparg & 16) { int res_bool = PyObject_IsTrue(res); Py_DECREF(res); - if (res_bool < 0) goto pop_2_error; + if (res_bool < 0) goto pop_2_error_tier_two; res = res_bool ? Py_True : Py_False; } - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case COMPARE_OP_FLOAT: { + case _COMPARE_OP_FLOAT: { PyObject *right; PyObject *left; PyObject *res; + oparg = CURRENT_OPARG(); right = stack_pointer[-1]; left = stack_pointer[-2]; - DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); + if (!PyFloat_CheckExact(left)) goto deoptimize; + if (!PyFloat_CheckExact(right)) goto deoptimize; STAT_INC(COMPARE_OP, hit); double dleft = PyFloat_AS_DOUBLE(left); double dright = PyFloat_AS_DOUBLE(right); @@ -1839,21 +1948,22 @@ _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? Py_True : Py_False; // It's always a bool, so we don't care about oparg & 16. - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case COMPARE_OP_INT: { + case _COMPARE_OP_INT: { PyObject *right; PyObject *left; PyObject *res; + oparg = CURRENT_OPARG(); 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); - DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP); + if (!PyLong_CheckExact(left)) goto deoptimize; + if (!PyLong_CheckExact(right)) goto deoptimize; + if (!_PyLong_IsCompact((PyLongObject *)left)) goto deoptimize; + if (!_PyLong_IsCompact((PyLongObject *)right)) goto deoptimize; STAT_INC(COMPARE_OP, hit); assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 && _PyLong_DigitCount((PyLongObject *)right) <= 1); @@ -1865,19 +1975,20 @@ _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? Py_True : Py_False; // It's always a bool, so we don't care about oparg & 16. - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case COMPARE_OP_STR: { + case _COMPARE_OP_STR: { PyObject *right; PyObject *left; PyObject *res; + oparg = CURRENT_OPARG(); right = stack_pointer[-1]; left = stack_pointer[-2]; - DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); + if (!PyUnicode_CheckExact(left)) goto deoptimize; + if (!PyUnicode_CheckExact(right)) goto deoptimize; STAT_INC(COMPARE_OP, hit); int eq = _PyUnicode_Equal(left, right); assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); @@ -1888,43 +1999,45 @@ assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; // It's always a bool, so we don't care about oparg & 16. - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case IS_OP: { + case _IS_OP: { PyObject *right; PyObject *left; PyObject *b; + oparg = CURRENT_OPARG(); right = stack_pointer[-1]; left = stack_pointer[-2]; int res = Py_Is(left, right) ^ oparg; Py_DECREF(left); Py_DECREF(right); b = res ? Py_True : Py_False; - STACK_SHRINK(1); - stack_pointer[-1] = b; + stack_pointer[-2] = b; + stack_pointer += -1; break; } - case CONTAINS_OP: { + case _CONTAINS_OP: { PyObject *right; PyObject *left; PyObject *b; + oparg = CURRENT_OPARG(); right = stack_pointer[-1]; left = stack_pointer[-2]; int res = PySequence_Contains(right, left); Py_DECREF(left); Py_DECREF(right); - if (res < 0) goto pop_2_error; + if (res < 0) goto pop_2_error_tier_two; b = (res ^ oparg) ? Py_True : Py_False; - STACK_SHRINK(1); - stack_pointer[-1] = b; + stack_pointer[-2] = b; + stack_pointer += -1; break; } - case CHECK_EG_MATCH: { + case _CHECK_EG_MATCH: { PyObject *match_type; PyObject *exc_value; PyObject *rest; @@ -1934,20 +2047,17 @@ if (_PyEval_CheckExceptStarTypeValid(tstate, match_type) < 0) { Py_DECREF(exc_value); Py_DECREF(match_type); - if (true) goto pop_2_error; + if (true) goto pop_2_error_tier_two; } - match = NULL; rest = NULL; int res = _PyEval_ExceptionGroupMatch(exc_value, match_type, - &match, &rest); + &match, &rest); Py_DECREF(exc_value); Py_DECREF(match_type); - if (res < 0) goto pop_2_error; - + if (res < 0) goto pop_2_error_tier_two; assert((match == NULL) == (rest == NULL)); - if (match == NULL) goto pop_2_error; - + if (match == NULL) goto pop_2_error_tier_two; if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } @@ -1956,7 +2066,7 @@ break; } - case CHECK_EXC_MATCH: { + case _CHECK_EXC_MATCH: { PyObject *right; PyObject *left; PyObject *b; @@ -1964,10 +2074,9 @@ left = stack_pointer[-2]; assert(PyExceptionInstance_Check(left)); if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { - Py_DECREF(right); - if (true) goto pop_1_error; + Py_DECREF(right); + if (true) goto pop_1_error_tier_two; } - int res = PyErr_GivenExceptionMatches(left, right); Py_DECREF(right); b = res ? Py_True : Py_False; @@ -1975,6 +2084,18 @@ break; } + case _JUMP_FORWARD: { + oparg = CURRENT_OPARG(); + JUMPBY(oparg); + break; + } + + /* _JUMP_BACKWARD is not a viable micro-op for tier 2 */ + + /* _POP_JUMP_IF_FALSE is not a viable micro-op for tier 2 */ + + /* _POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */ + case _IS_NONE: { PyObject *value; PyObject *b; @@ -1990,25 +2111,37 @@ break; } - case GET_LEN: { + case _JUMP_BACKWARD_NO_INTERRUPT: { + oparg = CURRENT_OPARG(); + /* This bytecode is used in the `yield from` or `await` loop. + * If there is an interrupt, we want it handled in the innermost + * generator or coroutine, so we deliberately do not check it here. + * (see bpo-30039). + */ + JUMPBY(-oparg); + break; + } + + case _GET_LEN: { 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; + if (len_i < 0) goto error_tier_two; len_o = PyLong_FromSsize_t(len_i); - if (len_o == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = len_o; + if (len_o == NULL) goto error_tier_two; + stack_pointer[0] = len_o; + stack_pointer += 1; break; } - case MATCH_CLASS: { + case _MATCH_CLASS: { PyObject *names; PyObject *type; PyObject *subject; PyObject *attrs; + oparg = CURRENT_OPARG(); names = stack_pointer[-1]; type = stack_pointer[-2]; subject = stack_pointer[-3]; @@ -2023,37 +2156,38 @@ assert(PyTuple_CheckExact(attrs)); // Success! } else { - if (_PyErr_Occurred(tstate)) goto pop_3_error; + if (_PyErr_Occurred(tstate)) goto pop_3_error_tier_two; + // Error! attrs = Py_None; // Failure! } - STACK_SHRINK(2); - stack_pointer[-1] = attrs; + stack_pointer[-3] = attrs; + stack_pointer += -2; break; } - case MATCH_MAPPING: { + case _MATCH_MAPPING: { 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); - stack_pointer[-1] = res; + stack_pointer[0] = res; + stack_pointer += 1; break; } - case MATCH_SEQUENCE: { + case _MATCH_SEQUENCE: { 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); - stack_pointer[-1] = res; + stack_pointer[0] = res; + stack_pointer += 1; break; } - case MATCH_KEYS: { + case _MATCH_KEYS: { PyObject *keys; PyObject *subject; PyObject *values_or_none; @@ -2061,25 +2195,25 @@ subject = stack_pointer[-2]; // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = _PyEval_MatchKeys(tstate, subject, keys); - if (values_or_none == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = values_or_none; + if (values_or_none == NULL) goto error_tier_two; + stack_pointer[0] = values_or_none; + stack_pointer += 1; break; } - case GET_ITER: { + case _GET_ITER: { PyObject *iterable; PyObject *iter; iterable = stack_pointer[-1]; /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); Py_DECREF(iterable); - if (iter == NULL) goto pop_1_error; + if (iter == NULL) goto pop_1_error_tier_two; stack_pointer[-1] = iter; break; } - case GET_YIELD_FROM_ITER: { + case _GET_YIELD_FROM_ITER: { PyObject *iterable; PyObject *iter; iterable = stack_pointer[-1]; @@ -2092,7 +2226,7 @@ _PyErr_SetString(tstate, PyExc_TypeError, "cannot 'yield from' a coroutine object " "in a non-coroutine generator"); - goto error; + GOTO_ERROR(error); } iter = iterable; } @@ -2103,7 +2237,7 @@ /* `iterable` is not a generator. */ iter = PyObject_GetIter(iterable); if (iter == NULL) { - goto error; + GOTO_ERROR(error); } Py_DECREF(iterable); } @@ -2111,33 +2245,52 @@ break; } + /* _FOR_ITER is not a viable micro-op for tier 2 */ + + case _FOR_ITER_TIER_TWO: { + PyObject *iter; + PyObject *next; + iter = stack_pointer[-1]; + /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ + next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next == NULL) { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + GOTO_ERROR(error); + } + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + Py_DECREF(iter); + STACK_SHRINK(1); + /* The translator sets the deopt target just past END_FOR */ + if (true) goto deoptimize; + } + // Common case: no jump, leave it to the code generator + stack_pointer[0] = next; + stack_pointer += 1; + break; + } + + /* _INSTRUMENTED_FOR_ITER is not a viable micro-op for tier 2 */ + case _ITER_CHECK_LIST: { PyObject *iter; iter = stack_pointer[-1]; - DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); + if (Py_TYPE(iter) != &PyListIter_Type) goto deoptimize; break; } - case _IS_ITER_EXHAUSTED_LIST: { + /* _ITER_JUMP_LIST is not a viable micro-op for tier 2 */ + + case _GUARD_NOT_EXHAUSTED_LIST: { PyObject *iter; - PyObject *exhausted; iter = stack_pointer[-1]; _PyListIterObject *it = (_PyListIterObject *)iter; assert(Py_TYPE(iter) == &PyListIter_Type); PyListObject *seq = it->it_seq; - if (seq == NULL) { - exhausted = Py_True; - } - else if (it->it_index >= PyList_GET_SIZE(seq)) { - Py_DECREF(seq); - it->it_seq = NULL; - exhausted = Py_True; - } - else { - exhausted = Py_False; - } - STACK_GROW(1); - stack_pointer[-1] = exhausted; + if (seq == NULL) goto deoptimize; + if (it->it_index >= PyList_GET_SIZE(seq)) goto deoptimize; break; } @@ -2151,38 +2304,28 @@ assert(seq); assert(it->it_index < PyList_GET_SIZE(seq)); next = Py_NewRef(PyList_GET_ITEM(seq, it->it_index++)); - STACK_GROW(1); - stack_pointer[-1] = next; + stack_pointer[0] = next; + stack_pointer += 1; break; } case _ITER_CHECK_TUPLE: { PyObject *iter; iter = stack_pointer[-1]; - DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER); + if (Py_TYPE(iter) != &PyTupleIter_Type) goto deoptimize; break; } - case _IS_ITER_EXHAUSTED_TUPLE: { + /* _ITER_JUMP_TUPLE is not a viable micro-op for tier 2 */ + + case _GUARD_NOT_EXHAUSTED_TUPLE: { PyObject *iter; - PyObject *exhausted; iter = stack_pointer[-1]; _PyTupleIterObject *it = (_PyTupleIterObject *)iter; assert(Py_TYPE(iter) == &PyTupleIter_Type); PyTupleObject *seq = it->it_seq; - if (seq == NULL) { - exhausted = Py_True; - } - else if (it->it_index >= PyTuple_GET_SIZE(seq)) { - Py_DECREF(seq); - it->it_seq = NULL; - exhausted = Py_True; - } - else { - exhausted = Py_False; - } - STACK_GROW(1); - stack_pointer[-1] = exhausted; + if (seq == NULL) goto deoptimize; + if (it->it_index >= PyTuple_GET_SIZE(seq)) goto deoptimize; break; } @@ -2196,8 +2339,8 @@ assert(seq); assert(it->it_index < PyTuple_GET_SIZE(seq)); next = Py_NewRef(PyTuple_GET_ITEM(seq, it->it_index++)); - STACK_GROW(1); - stack_pointer[-1] = next; + stack_pointer[0] = next; + stack_pointer += 1; break; } @@ -2205,19 +2348,18 @@ PyObject *iter; iter = stack_pointer[-1]; _PyRangeIterObject *r = (_PyRangeIterObject *)iter; - DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + if (Py_TYPE(r) != &PyRangeIter_Type) goto deoptimize; break; } - case _IS_ITER_EXHAUSTED_RANGE: { + /* _ITER_JUMP_RANGE is not a viable micro-op for tier 2 */ + + case _GUARD_NOT_EXHAUSTED_RANGE: { 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; - STACK_GROW(1); - stack_pointer[-1] = exhausted; + if (r->len <= 0) goto deoptimize; break; } @@ -2232,13 +2374,98 @@ r->start = value + r->step; r->len--; next = PyLong_FromLong(value); - if (next == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = next; + if (next == NULL) goto error_tier_two; + stack_pointer[0] = next; + stack_pointer += 1; + break; + } + + /* _FOR_ITER_GEN is not a viable micro-op for tier 2 */ + + case _BEFORE_ASYNC_WITH: { + 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)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol", + Py_TYPE(mgr)->tp_name); + } + GOTO_ERROR(error); + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol " + "(missed __aexit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + GOTO_ERROR(error); + } + Py_DECREF(mgr); + res = _PyObject_CallNoArgsTstate(tstate, enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error_tier_two; + } + stack_pointer[-1] = exit; + stack_pointer[0] = res; + stack_pointer += 1; + break; + } + + case _BEFORE_WITH: { + 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__ + */ + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + GOTO_ERROR(error); + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + GOTO_ERROR(error); + } + Py_DECREF(mgr); + res = _PyObject_CallNoArgsTstate(tstate, enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error_tier_two; + } + stack_pointer[-1] = exit; + stack_pointer[0] = res; + stack_pointer += 1; break; } - case WITH_EXCEPT_START: { + case _WITH_EXCEPT_START: { PyObject *val; PyObject *lasti; PyObject *exit_func; @@ -2253,9 +2480,8 @@ - exit_func: FOURTH = the context.__exit__ bound method We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). Then we push the __exit__ return value. - */ + */ PyObject *exc, *tb; - assert(val && PyExceptionInstance_Check(val)); exc = PyExceptionInstance_Class(val); tb = PyException_GetTraceback(val); @@ -2269,14 +2495,14 @@ (void)lasti; // Shut up compiler warning if asserts are off PyObject *stack[4] = {NULL, exc, val, tb}; res = PyObject_Vectorcall(exit_func, stack + 1, - 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); - if (res == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = res; + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + if (res == NULL) goto error_tier_two; + stack_pointer[0] = res; + stack_pointer += 1; break; } - case PUSH_EXC_INFO: { + case _PUSH_EXC_INFO: { PyObject *new_exc; PyObject *prev_exc; new_exc = stack_pointer[-1]; @@ -2289,9 +2515,9 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - STACK_GROW(1); - stack_pointer[-2] = prev_exc; - stack_pointer[-1] = new_exc; + stack_pointer[-1] = prev_exc; + stack_pointer[0] = new_exc; + stack_pointer += 1; break; } @@ -2300,29 +2526,27 @@ 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), - LOAD_ATTR); + if (!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv)) goto deoptimize; break; } case _GUARD_KEYS_VERSION: { PyObject *owner; owner = stack_pointer[-1]; - uint32_t keys_version = (uint32_t)operand; + uint32_t keys_version = (uint32_t)CURRENT_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, LOAD_ATTR); + if (owner_heap_type->ht_cached_keys->dk_version != keys_version) goto deoptimize; break; } case _LOAD_ATTR_METHOD_WITH_VALUES: { PyObject *owner; PyObject *attr; - PyObject *self; + PyObject *self = NULL; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; - PyObject *descr = (PyObject *)operand; + PyObject *descr = (PyObject *)CURRENT_OPERAND(); assert(oparg & 1); /* Cached method object */ STAT_INC(LOAD_ATTR, hit); @@ -2330,18 +2554,19 @@ 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; + stack_pointer[-1] = attr; + if (1) stack_pointer[0] = self; + stack_pointer += (((1) ? 1 : 0)); break; } case _LOAD_ATTR_METHOD_NO_DICT: { PyObject *owner; PyObject *attr; - PyObject *self; + PyObject *self = NULL; + oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; - PyObject *descr = (PyObject *)operand; + PyObject *descr = (PyObject *)CURRENT_OPERAND(); assert(oparg & 1); assert(Py_TYPE(owner)->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); @@ -2349,19 +2574,87 @@ 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; + stack_pointer[-1] = attr; + if (1) stack_pointer[0] = self; + stack_pointer += (((1) ? 1 : 0)); + break; + } + + case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: { + PyObject *owner; + PyObject *attr; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)CURRENT_OPERAND(); + assert((oparg & 1) == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + Py_DECREF(owner); + attr = Py_NewRef(descr); + stack_pointer[-1] = attr; + stack_pointer += (((0) ? 1 : 0)); + break; + } + + case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { + PyObject *owner; + PyObject *attr; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)CURRENT_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; + stack_pointer += (((0) ? 1 : 0)); + 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 */ + if (dict != NULL) goto deoptimize; + break; + } + + case _LOAD_ATTR_METHOD_LAZY_DICT: { + PyObject *owner; + PyObject *attr; + PyObject *self = NULL; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)CURRENT_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_pointer[-1] = attr; + if (1) stack_pointer[0] = self; + stack_pointer += (((1) ? 1 : 0)); break; } + /* _INSTRUMENTED_CALL is not a viable micro-op for tier 2 */ + + /* _CALL is not a viable micro-op for tier 2 */ + case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: { PyObject *null; PyObject *callable; + oparg = CURRENT_OPARG(); null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); + if (null != NULL) goto deoptimize; + if (Py_TYPE(callable) != &PyMethod_Type) goto deoptimize; break; } @@ -2369,6 +2662,7 @@ PyObject *callable; PyObject *func; PyObject *self; + oparg = CURRENT_OPARG(); callable = stack_pointer[-2 - oparg]; STAT_INC(CALL, hit); self = Py_NewRef(((PyMethodObject *)callable)->im_self); @@ -2382,31 +2676,33 @@ } case _CHECK_PEP_523: { - DEOPT_IF(tstate->interp->eval_frame, CALL); + if (tstate->interp->eval_frame) goto deoptimize; break; } case _CHECK_FUNCTION_EXACT_ARGS: { PyObject *self_or_null; PyObject *callable; + oparg = CURRENT_OPARG(); self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; - uint32_t func_version = (uint32_t)operand; - DEOPT_IF(!PyFunction_Check(callable), CALL); + uint32_t func_version = (uint32_t)CURRENT_OPERAND(); + if (!PyFunction_Check(callable)) goto deoptimize; PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != func_version, CALL); + if (func->func_version != func_version) goto deoptimize; PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL); + if (code->co_argcount != oparg + (self_or_null != NULL)) goto deoptimize; break; } case _CHECK_STACK_SPACE: { PyObject *callable; + oparg = CURRENT_OPARG(); callable = stack_pointer[-2 - oparg]; 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); + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) goto deoptimize; + if (tstate->py_recursion_remaining <= 1) goto deoptimize; break; } @@ -2415,7 +2711,8 @@ PyObject *self_or_null; PyObject *callable; _PyInterpreterFrame *new_frame; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; int argcount = oparg; @@ -2429,126 +2726,130 @@ 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; + stack_pointer[-2 - oparg] = (PyObject *)new_frame; + stack_pointer += -1 - oparg; 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(); + stack_pointer += -1; + _PyFrame_SetStackPointer(frame, stack_pointer); 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 + LOAD_IP(0); + #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { goto exit_unwind; } -#endif + #endif + stack_pointer += (((0) ? 1 : 0)); break; } - case CALL_TYPE_1: { + /* _CALL_PY_WITH_DEFAULTS is not a viable micro-op for tier 2 */ + + case _CALL_TYPE_1: { PyObject **args; PyObject *null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; assert(oparg == 1); - DEOPT_IF(null != NULL, CALL); + if (null != NULL) goto deoptimize; PyObject *obj = args[0]; - DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + if (callable != (PyObject *)&PyType_Type) goto deoptimize; STAT_INC(CALL, hit); res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; break; } - case CALL_STR_1: { + case _CALL_STR_1: { PyObject **args; PyObject *null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + 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); + if (null != NULL) goto deoptimize; + if (callable != (PyObject *)&PyUnicode_Type) goto deoptimize; STAT_INC(CALL, hit); PyObject *arg = args[0]; res = PyObject_Str(arg); Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_TUPLE_1: { + case _CALL_TUPLE_1: { PyObject **args; PyObject *null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + 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); + if (null != NULL) goto deoptimize; + if (callable != (PyObject *)&PyTuple_Type) goto deoptimize; STAT_INC(CALL, hit); PyObject *arg = args[0]; res = PySequence_Tuple(arg); Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case EXIT_INIT_CHECK: { + /* _CALL_ALLOC_AND_ENTER_INIT is not a viable micro-op for tier 2 */ + + case _EXIT_INIT_CHECK: { PyObject *should_be_none; should_be_none = stack_pointer[-1]; assert(STACK_LEVEL() == 2); if (should_be_none != Py_None) { PyErr_Format(PyExc_TypeError, - "__init__() should return None, not '%.200s'", - Py_TYPE(should_be_none)->tp_name); - goto error; + "__init__() should return None, not '%.200s'", + Py_TYPE(should_be_none)->tp_name); + GOTO_ERROR(error); } - STACK_SHRINK(1); + stack_pointer += -1; break; } - case CALL_BUILTIN_CLASS: { + case _CALL_BUILTIN_CLASS: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; int total_args = oparg; @@ -2556,9 +2857,9 @@ args--; total_args++; } - DEOPT_IF(!PyType_Check(callable), CALL); + if (!PyType_Check(callable)) goto deoptimize; PyTypeObject *tp = (PyTypeObject *)callable; - DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + if (tp->tp_vectorcall == NULL) goto deoptimize; STAT_INC(CALL, hit); res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL); /* Free the arguments. */ @@ -2566,20 +2867,20 @@ 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; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_BUILTIN_O: { + case _CALL_BUILTIN_O: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* Builtin METH_O functions */ @@ -2588,37 +2889,36 @@ args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + if (total_args != 1) goto deoptimize; + if (!PyCFunction_CheckExact(callable)) goto deoptimize; + if (PyCFunction_GET_FLAGS(callable) != METH_O) goto deoptimize; STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); // This is slower but CPython promises to check all non-vectorcall // function calls. if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + GOTO_ERROR(error); } PyObject *arg = args[0]; res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); _Py_LeaveRecursiveCallTstate(tstate); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(arg); Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_BUILTIN_FAST: { + case _CALL_BUILTIN_FAST: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL functions, without keywords */ @@ -2627,8 +2927,8 @@ args--; total_args++; } - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, CALL); + if (!PyCFunction_CheckExact(callable)) goto deoptimize; + if (PyCFunction_GET_FLAGS(callable) != METH_FASTCALL) goto deoptimize; STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); /* res = func(self, args, nargs) */ @@ -2637,31 +2937,30 @@ args, total_args); 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; } - /* Not deopting because this doesn't mean our optimization was - wrong. `res` can be NULL for valid reasons. Eg. getattr(x, - 'invalid'). In those cases an exception is set, so we must - handle it. - */ - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + /* Not deopting because this doesn't mean our optimization was + wrong. `res` can be NULL for valid reasons. Eg. getattr(x, + 'invalid'). In those cases an exception is set, so we must + handle it. + */ + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_BUILTIN_FAST_WITH_KEYWORDS: { + case _CALL_BUILTIN_FAST_WITH_KEYWORDS: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ @@ -2670,36 +2969,34 @@ args--; total_args++; } - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != - (METH_FASTCALL | METH_KEYWORDS), CALL); + if (!PyCFunction_CheckExact(callable)) goto deoptimize; + if (PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS)) goto deoptimize; STAT_INC(CALL, hit); /* res = func(self, args, nargs, kwnames) */ _PyCFunctionFastWithKeywords cfunc = - (_PyCFunctionFastWithKeywords)(void(*)(void)) - PyCFunction_GET_FUNCTION(callable); + (_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; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_LEN: { + case _CALL_LEN: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* len(o) */ @@ -2708,33 +3005,32 @@ args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); + if (total_args != 1) goto deoptimize; PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.len, CALL); + if (callable != interp->callable_cache.len) goto deoptimize; STAT_INC(CALL, hit); PyObject *arg = args[0]; Py_ssize_t len_i = PyObject_Length(arg); if (len_i < 0) { - goto error; + GOTO_ERROR(error); } res = PyLong_FromSsize_t(len_i); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(callable); Py_DECREF(arg); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; break; } - case CALL_ISINSTANCE: { + case _CALL_ISINSTANCE: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* isinstance(o, o2) */ @@ -2743,35 +3039,60 @@ args--; total_args++; } - DEOPT_IF(total_args != 2, CALL); + if (total_args != 2) goto deoptimize; PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + if (callable != interp->callable_cache.isinstance) goto deoptimize; STAT_INC(CALL, hit); PyObject *cls = args[1]; PyObject *inst = args[0]; int retval = PyObject_IsInstance(inst, cls); if (retval < 0) { - goto error; + GOTO_ERROR(error); } res = PyBool_FromLong(retval); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(inst); Py_DECREF(cls); Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; break; } - case CALL_METHOD_DESCRIPTOR_O: { + case _CALL_LIST_APPEND: { + PyObject **args; + PyObject *self; + PyObject *callable; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; + self = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + assert(oparg == 1); + PyInterpreterState *interp = tstate->interp; + if (callable != interp->callable_cache.list_append) goto deoptimize; + assert(self != NULL); + if (!PyList_Check(self)) goto deoptimize; + 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(callable); + STACK_SHRINK(3); + // Skip POP_TOP + assert(next_instr->op.code == POP_TOP); + SKIP_OVER(1); + DISPATCH(); + } + + case _CALL_METHOD_DESCRIPTOR_O: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; int total_args = oparg; @@ -2780,19 +3101,19 @@ total_args++; } PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(total_args != 2, CALL); - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + if (total_args != 2) goto deoptimize; + if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) goto deoptimize; PyMethodDef *meth = method->d_method; - DEOPT_IF(meth->ml_flags != METH_O, CALL); + if (meth->ml_flags != METH_O) goto deoptimize; PyObject *arg = args[1]; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); + if (!Py_IS_TYPE(self, method->d_common.d_type)) goto deoptimize; STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall // function calls. if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + GOTO_ERROR(error); } res = _PyCFunction_TrampolineCall(cfunc, self, arg); _Py_LeaveRecursiveCallTstate(tstate); @@ -2800,20 +3121,20 @@ Py_DECREF(self); Py_DECREF(arg); Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { + case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; int total_args = oparg; @@ -2822,38 +3143,37 @@ total_args++; } PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) goto deoptimize; PyMethodDef *meth = method->d_method; - DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + if (meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS)) goto deoptimize; PyTypeObject *d_type = method->d_common.d_type; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + if (!Py_IS_TYPE(self, d_type)) goto deoptimize; STAT_INC(CALL, hit); int nargs = total_args - 1; _PyCFunctionFastWithKeywords cfunc = - (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + (_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; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_METHOD_DESCRIPTOR_NOARGS: { + case _CALL_METHOD_DESCRIPTOR_NOARGS: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; assert(oparg == 0 || oparg == 1); @@ -2862,39 +3182,39 @@ args--; total_args++; } - DEOPT_IF(total_args != 1, CALL); + if (total_args != 1) goto deoptimize; PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) goto deoptimize; PyMethodDef *meth = method->d_method; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); - DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + if (!Py_IS_TYPE(self, method->d_common.d_type)) goto deoptimize; + if (meth->ml_flags != METH_NOARGS) goto deoptimize; STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall // function calls. if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + GOTO_ERROR(error); } res = _PyCFunction_TrampolineCall(cfunc, self, NULL); _Py_LeaveRecursiveCallTstate(tstate); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); Py_DECREF(self); Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case CALL_METHOD_DESCRIPTOR_FAST: { + case _CALL_METHOD_DESCRIPTOR_FAST: { PyObject **args; PyObject *self_or_null; PyObject *callable; PyObject *res; - args = stack_pointer - oparg; + oparg = CURRENT_OPARG(); + args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; int total_args = oparg; @@ -2904,14 +3224,14 @@ } PyMethodDescrObject *method = (PyMethodDescrObject *)callable; /* Builtin METH_FASTCALL methods, without keywords */ - DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL); + if (!Py_IS_TYPE(method, &PyMethodDescr_Type)) goto deoptimize; PyMethodDef *meth = method->d_method; - DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + if (meth->ml_flags != METH_FASTCALL) goto deoptimize; PyObject *self = args[0]; - DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type), CALL); + if (!Py_IS_TYPE(self, method->d_common.d_type)) goto deoptimize; STAT_INC(CALL, hit); _PyCFunctionFast cfunc = - (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; int nargs = total_args - 1; res = cfunc(self, args + 1, nargs); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -2920,102 +3240,133 @@ 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; + if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; CHECK_EVAL_BREAKER(); break; } - case MAKE_FUNCTION: { + /* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 */ + + /* _CALL_KW is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */ + + /* _CALL_FUNCTION_EX is not a viable micro-op for tier 2 */ + + case _MAKE_FUNCTION: { PyObject *codeobj; PyObject *func; codeobj = stack_pointer[-1]; - PyFunctionObject *func_obj = (PyFunctionObject *) - PyFunction_New(codeobj, GLOBALS()); - + PyFunction_New(codeobj, GLOBALS()); Py_DECREF(codeobj); if (func_obj == NULL) { - goto error; + GOTO_ERROR(error); } - _PyFunction_SetVersion( - func_obj, ((PyCodeObject *)codeobj)->co_version); + func_obj, ((PyCodeObject *)codeobj)->co_version); func = (PyObject *)func_obj; stack_pointer[-1] = func; break; } - case SET_FUNCTION_ATTRIBUTE: { + case _SET_FUNCTION_ATTRIBUTE: { PyObject *func; PyObject *attr; + oparg = CURRENT_OPARG(); func = stack_pointer[-1]; attr = stack_pointer[-2]; assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { case MAKE_FUNCTION_CLOSURE: - assert(func_obj->func_closure == NULL); - func_obj->func_closure = attr; - break; + assert(func_obj->func_closure == NULL); + func_obj->func_closure = attr; + break; case MAKE_FUNCTION_ANNOTATIONS: - assert(func_obj->func_annotations == NULL); - func_obj->func_annotations = attr; - break; + assert(func_obj->func_annotations == NULL); + func_obj->func_annotations = attr; + break; case MAKE_FUNCTION_KWDEFAULTS: - assert(PyDict_CheckExact(attr)); - assert(func_obj->func_kwdefaults == NULL); - func_obj->func_kwdefaults = attr; - break; + assert(PyDict_CheckExact(attr)); + assert(func_obj->func_kwdefaults == NULL); + func_obj->func_kwdefaults = attr; + break; case MAKE_FUNCTION_DEFAULTS: - assert(PyTuple_CheckExact(attr)); - assert(func_obj->func_defaults == NULL); - func_obj->func_defaults = attr; - break; + assert(PyTuple_CheckExact(attr)); + assert(func_obj->func_defaults == NULL); + func_obj->func_defaults = attr; + break; default: - Py_UNREACHABLE(); + Py_UNREACHABLE(); } - STACK_SHRINK(1); - stack_pointer[-1] = func; + stack_pointer[-2] = func; + stack_pointer += -1; break; } - case BUILD_SLICE: { + case _RETURN_GENERATOR: { + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + if (gen == NULL) { + GOTO_ERROR(error); + } + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->instr_ptr = next_instr; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = tstate->current_frame = prev; + _PyFrame_StackPush(frame, (PyObject *)gen); + LOAD_IP(frame->return_offset); + goto resume_frame; + } + + case _BUILD_SLICE: { 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)]; + oparg = CURRENT_OPARG(); + 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); Py_XDECREF(step); - if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - STACK_SHRINK(((oparg == 3) ? 1 : 0)); - STACK_SHRINK(1); - stack_pointer[-1] = slice; + if (slice == NULL) { stack_pointer += -2 - (((oparg == 3) ? 1 : 0)); goto error_tier_two; } + stack_pointer[-2 - (((oparg == 3) ? 1 : 0))] = slice; + stack_pointer += -1 - (((oparg == 3) ? 1 : 0)); break; } - case CONVERT_VALUE: { + case _CONVERT_VALUE: { PyObject *value; PyObject *result; + oparg = CURRENT_OPARG(); value = stack_pointer[-1]; convertion_func_ptr conv_fn; assert(oparg >= FVC_STR && oparg <= FVC_ASCII); conv_fn = CONVERSION_FUNCTIONS[oparg]; result = conv_fn(value); Py_DECREF(value); - if (result == NULL) goto pop_1_error; + if (result == NULL) goto pop_1_error_tier_two; stack_pointer[-1] = result; break; } - case FORMAT_SIMPLE: { + case _FORMAT_SIMPLE: { PyObject *value; PyObject *res; value = stack_pointer[-1]; @@ -3024,7 +3375,7 @@ if (!PyUnicode_CheckExact(value)) { res = PyObject_Format(value, NULL); Py_DECREF(value); - if (res == NULL) goto pop_1_error; + if (res == NULL) goto pop_1_error_tier_two; } else { res = value; @@ -3033,7 +3384,7 @@ break; } - case FORMAT_WITH_SPEC: { + case _FORMAT_WITH_SPEC: { PyObject *fmt_spec; PyObject *value; PyObject *res; @@ -3042,54 +3393,45 @@ res = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_DECREF(fmt_spec); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case COPY: { + case _COPY: { PyObject *bottom; PyObject *top; + oparg = CURRENT_OPARG(); bottom = stack_pointer[-1 - (oparg-1)]; assert(oparg > 0); top = Py_NewRef(bottom); - STACK_GROW(1); - stack_pointer[-1] = top; + stack_pointer[0] = top; + stack_pointer += 1; break; } - case BINARY_OP: { + case _BINARY_OP: { PyObject *rhs; PyObject *lhs; PyObject *res; + oparg = CURRENT_OPARG(); rhs = stack_pointer[-1]; lhs = stack_pointer[-2]; - #if ENABLE_SPECIALIZATION - _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY); - DISPATCH_SAME_OPARG(); - } - STAT_INC(BINARY_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - 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; - STACK_SHRINK(1); - stack_pointer[-1] = res; + if (res == NULL) goto pop_2_error_tier_two; + stack_pointer[-2] = res; + stack_pointer += -1; break; } - case SWAP: { + case _SWAP: { PyObject *top; PyObject *bottom; + oparg = CURRENT_OPARG(); top = stack_pointer[-1]; bottom = stack_pointer[-2 - (oparg-2)]; assert(oparg >= 2); @@ -3098,61 +3440,100 @@ break; } - case _POP_JUMP_IF_FALSE: { + /* _INSTRUMENTED_INSTRUCTION is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_JUMP_FORWARD is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_JUMP_BACKWARD is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_POP_JUMP_IF_FALSE is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_POP_JUMP_IF_NONE is not a viable micro-op for tier 2 */ + + /* _INSTRUMENTED_POP_JUMP_IF_NOT_NONE is not a viable micro-op for tier 2 */ + + case _GUARD_IS_TRUE_POP: { PyObject *flag; flag = stack_pointer[-1]; - if (Py_IsFalse(flag)) { - pc = oparg; - } - STACK_SHRINK(1); + if (Py_IsFalse(flag)) goto deoptimize; + assert(Py_IsTrue(flag)); + stack_pointer += -1; break; } - case _POP_JUMP_IF_TRUE: { + case _GUARD_IS_FALSE_POP: { PyObject *flag; flag = stack_pointer[-1]; - if (Py_IsTrue(flag)) { - pc = oparg; - } - STACK_SHRINK(1); + if (Py_IsTrue(flag)) goto deoptimize; + assert(Py_IsFalse(flag)); + stack_pointer += -1; + break; + } + + case _GUARD_IS_NONE_POP: { + PyObject *val; + val = stack_pointer[-1]; + if (!Py_IsNone(val)) goto deoptimize; + stack_pointer += -1; + break; + } + + case _GUARD_IS_NOT_NONE_POP: { + PyObject *val; + val = stack_pointer[-1]; + if (Py_IsNone(val)) goto deoptimize; + Py_DECREF(val); + stack_pointer += -1; break; } case _JUMP_TO_TOP: { - pc = 0; + next_uop = current_executor->trace; CHECK_EVAL_BREAKER(); break; } case _SET_IP: { - frame->prev_instr = ip_offset + oparg; + oparg = CURRENT_OPARG(); + TIER_TWO_ONLY + // TODO: Put the code pointer in `operand` to avoid indirection via `frame` + frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + oparg; break; } - case _SAVE_CURRENT_IP: { + case _SAVE_RETURN_OFFSET: { + oparg = CURRENT_OPARG(); #if TIER_ONE - frame->prev_instr = next_instr - 1; + frame->return_offset = (uint16_t)(next_instr - this_instr); #endif #if TIER_TWO - // Relies on a preceding _SET_IP - frame->prev_instr--; + frame->return_offset = oparg; #endif break; } case _EXIT_TRACE: { - frame->prev_instr--; // Back up to just before destination - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(self); - return frame; + TIER_TWO_ONLY + GOTO_TIER_ONE(); break; } case _INSERT: { PyObject *top; + oparg = CURRENT_OPARG(); 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; } + + case _CHECK_VALIDITY: { + TIER_TWO_ONLY + if (!current_executor->base.vm_data.valid) goto deoptimize; + break; + } + +#undef TIER_TWO diff --git a/Python/fileutils.c b/Python/fileutils.c index 9bc1de2db84006..882d3299575cf3 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: @@ -1236,6 +1239,7 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) BY_HANDLE_FILE_INFORMATION info; FILE_BASIC_INFO basicInfo; FILE_ID_INFO idInfo; + FILE_ID_INFO *pIdInfo = &idInfo; HANDLE h; int type; @@ -1268,15 +1272,19 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) } if (!GetFileInformationByHandle(h, &info) || - !GetFileInformationByHandleEx(h, FileBasicInfo, &basicInfo, sizeof(basicInfo)) || - !GetFileInformationByHandleEx(h, FileIdInfo, &idInfo, sizeof(idInfo))) { + !GetFileInformationByHandleEx(h, FileBasicInfo, &basicInfo, sizeof(basicInfo))) { /* The Win32 error is already set, but we also set errno for callers who expect it */ errno = winerror_to_errno(GetLastError()); return -1; } - _Py_attribute_data_to_stat(&info, 0, &basicInfo, &idInfo, status); + if (!GetFileInformationByHandleEx(h, FileIdInfo, &idInfo, sizeof(idInfo))) { + /* Failed to get FileIdInfo, so do not pass it along */ + pIdInfo = NULL; + } + + _Py_attribute_data_to_stat(&info, 0, &basicInfo, pIdInfo, status); return 0; #else return fstat(fd, status); @@ -2870,9 +2878,9 @@ _Py_GetLocaleconvNumeric(struct lconv *lc, * non-opened fd in the middle. * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. */ -#ifdef __FreeBSD__ +#ifdef HAVE_CLOSEFROM # define USE_CLOSEFROM -#endif /* __FreeBSD__ */ +#endif /* HAVE_CLOSEFROM */ #ifdef HAVE_FDWALK # define USE_FDWALK @@ -2914,7 +2922,7 @@ _Py_closerange(int first, int last) #ifdef USE_CLOSEFROM if (last >= sysconf(_SC_OPEN_MAX)) { /* Any errors encountered while closing file descriptors are ignored */ - closefrom(first); + (void)closefrom(first); } else #endif /* USE_CLOSEFROM */ @@ -2935,3 +2943,27 @@ _Py_closerange(int first, int last) #endif /* USE_FDWALK */ _Py_END_SUPPRESS_IPH } + + +#ifndef MS_WINDOWS +// Ticks per second used by clock() and times() functions. +// See os.times() and time.process_time() implementations. +int +_Py_GetTicksPerSecond(long *ticks_per_second) +{ +#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) + long value = sysconf(_SC_CLK_TCK); + if (value < 1) { + return -1; + } + *ticks_per_second = value; +#elif defined(HZ) + assert(HZ >= 1); + *ticks_per_second = HZ; +#else + // Magic fallback value; may be bogus + *ticks_per_second = 60; +#endif + return 0; +} +#endif diff --git a/Python/flowgraph.c b/Python/flowgraph.c index e89ad39b35719b..fe632082d5a66c 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -97,6 +97,7 @@ static const jump_target_label NO_LABEL = {-1}; static inline int is_block_push(cfg_instr *i) { + assert(OPCODE_HAS_ARG(i->i_opcode) || !IS_BLOCK_PUSH_OPCODE(i->i_opcode)); return IS_BLOCK_PUSH_OPCODE(i->i_opcode); } @@ -840,6 +841,7 @@ label_exception_targets(basicblock *entryblock) { assert(except_stack != NULL); b->b_exceptstack = NULL; handler = except_stack_top(except_stack); + int last_yield_except_depth = -1; for (int i = 0; i < b->b_iused; i++) { cfg_instr *instr = &b->b_instr[i]; if (is_block_push(instr)) { @@ -878,10 +880,21 @@ label_exception_targets(basicblock *entryblock) { todo++; } } - else { - if (instr->i_opcode == YIELD_VALUE) { - instr->i_oparg = except_stack->depth; + else if (instr->i_opcode == YIELD_VALUE) { + instr->i_except = handler; + last_yield_except_depth = except_stack->depth; + } + else if (instr->i_opcode == RESUME) { + instr->i_except = handler; + if (instr->i_oparg != RESUME_AT_FUNC_START) { + assert(last_yield_except_depth >= 0); + if (last_yield_except_depth == 1) { + instr->i_oparg |= RESUME_OPARG_DEPTH1_MASK; + } + last_yield_except_depth = -1; } + } + else { instr->i_except = handler; } } @@ -2227,7 +2240,6 @@ convert_pseudo_ops(basicblock *entryblock) for (int i = 0; i < b->b_iused; i++) { cfg_instr *instr = &b->b_instr[i]; if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) { - assert(SAME_OPCODE_METADATA(instr->i_opcode, NOP)); INSTR_SET_OP0(instr, NOP); } else if (instr->i_opcode == LOAD_CLOSURE) { diff --git a/Python/frame.c b/Python/frame.c index b483903fdf3018..2865b2eab603c2 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -90,7 +90,7 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) // This may be a newly-created generator or coroutine frame. Since it's // dead anyways, just pretend that the first RESUME ran: PyCodeObject *code = _PyFrame_GetCode(frame); - frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; + frame->instr_ptr = _PyCode_CODE(code) + code->_co_firsttraceable + 1; } assert(!_PyFrame_IsIncomplete(frame)); assert(f->f_back == NULL); diff --git a/Python/frozen.c b/Python/frozen.c index 0fb38a11902f35..77f51a7f750965 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -80,7 +80,6 @@ extern PyObject *_Py_get__sitebuiltins_toplevel(void); extern PyObject *_Py_get_genericpath_toplevel(void); extern PyObject *_Py_get_ntpath_toplevel(void); extern PyObject *_Py_get_posixpath_toplevel(void); -extern PyObject *_Py_get_posixpath_toplevel(void); extern PyObject *_Py_get_os_toplevel(void); extern PyObject *_Py_get_site_toplevel(void); extern PyObject *_Py_get_stat_toplevel(void); @@ -88,13 +87,8 @@ extern PyObject *_Py_get_importlib_util_toplevel(void); extern PyObject *_Py_get_importlib_machinery_toplevel(void); extern PyObject *_Py_get_runpy_toplevel(void); extern PyObject *_Py_get___hello___toplevel(void); -extern PyObject *_Py_get___hello___toplevel(void); -extern PyObject *_Py_get___hello___toplevel(void); -extern PyObject *_Py_get___hello___toplevel(void); -extern PyObject *_Py_get___phello___toplevel(void); extern PyObject *_Py_get___phello___toplevel(void); extern PyObject *_Py_get___phello___ham_toplevel(void); -extern PyObject *_Py_get___phello___ham_toplevel(void); extern PyObject *_Py_get___phello___ham_eggs_toplevel(void); extern PyObject *_Py_get___phello___spam_toplevel(void); extern PyObject *_Py_get_frozen_only_toplevel(void); 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 2701d416648a20..65e6f11f68b38c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1,389 +1,304 @@ -// This file is generated by Tools/cases_generator/generate_cases.py +// This file is generated by Tools/cases_generator/tier1_generator.py // from: // Python/bytecodes.c // Do not edit! - TARGET(NOP) { - DISPATCH(); - } +#ifdef TIER_TWO + #error "This file is for Tier 1 only" +#endif +#define TIER_ONE 1 - TARGET(RESUME) { - PREDICTED(RESUME); - static_assert(0 == 0, "incorrect cache size"); - TIER_ONE_ONLY - assert(frame == tstate->current_frame); - if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) { - int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp); - if (err) goto error; - next_instr--; + + TARGET(BEFORE_ASYNC_WITH) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(BEFORE_ASYNC_WITH); + 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)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol", + Py_TYPE(mgr)->tp_name); + } + GOTO_ERROR(error); } - else { - if (oparg < 2) { - CHECK_EVAL_BREAKER(); + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol " + "(missed __aexit__ method)", + Py_TYPE(mgr)->tp_name); } - next_instr[-1].op.code = RESUME_CHECK; + Py_DECREF(enter); + GOTO_ERROR(error); } + Py_DECREF(mgr); + res = _PyObject_CallNoArgsTstate(tstate, enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error; + } + stack_pointer[-1] = exit; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } - TARGET(RESUME_CHECK) { -#if defined(__EMSCRIPTEN__) - DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME); - _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; -#endif - /* Possibly combine these two checks */ - DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version - != tstate->interp->monitoring_version, RESUME); - DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), 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? + TARGET(BEFORE_WITH) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(BEFORE_WITH); + 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__ */ - if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) { - if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) { - goto error; + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); } - next_instr--; + GOTO_ERROR(error); } - else { - if (oparg < 2) { - CHECK_EVAL_BREAKER(); - } - _PyFrame_SetStackPointer(frame, stack_pointer); - int err = _Py_call_instrumentation( - tstate, oparg > 0, frame, next_instr-1); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (err) goto error; - if (frame->prev_instr != next_instr-1) { - /* Instrumentation has jumped */ - next_instr = frame->prev_instr; - DISPATCH(); + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); } + Py_DECREF(enter); + GOTO_ERROR(error); + } + Py_DECREF(mgr); + res = _PyObject_CallNoArgsTstate(tstate, enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error; } + stack_pointer[-1] = exit; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } - TARGET(LOAD_FAST_CHECK) { - PyObject *value; - value = GETLOCAL(oparg); - if (value == NULL) goto unbound_local_error; - Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + TARGET(BINARY_OP) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP); + PREDICTED(BINARY_OP); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *rhs; + PyObject *lhs; + PyObject *res; + // _SPECIALIZE_BINARY_OP + rhs = stack_pointer[-1]; + lhs = stack_pointer[-2]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ + assert(NB_ADD <= oparg); + assert(oparg <= NB_INPLACE_XOR); + } + // _BINARY_OP + { + assert(_PyEval_BinaryOps[oparg]); + res = _PyEval_BinaryOps[oparg](lhs, rhs); + Py_DECREF(lhs); + Py_DECREF(rhs); + if (res == NULL) goto pop_2_error; + } + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_FAST) { - PyObject *value; - value = GETLOCAL(oparg); - assert(value != NULL); - Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + TARGET(BINARY_OP_ADD_FLOAT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_ADD_FLOAT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_FLOAT + right = stack_pointer[-1]; + left = stack_pointer[-2]; + { + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + } + // _BINARY_OP_ADD_FLOAT + { + STAT_INC(BINARY_OP, hit); + double dres = + ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); + } + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_FAST_AND_CLEAR) { - PyObject *value; - value = GETLOCAL(oparg); - // do not use SETLOCAL here, it decrefs the old value - GETLOCAL(oparg) = NULL; - STACK_GROW(1); - stack_pointer[-1] = value; + TARGET(BINARY_OP_ADD_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_ADD_INT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_INT + right = stack_pointer[-1]; + left = stack_pointer[-2]; + { + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + } + // _BINARY_OP_ADD_INT + { + 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; + } + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_FAST_LOAD_FAST) { - PyObject *value1; - PyObject *value2; - uint32_t oparg1 = oparg >> 4; - uint32_t oparg2 = oparg & 15; - value1 = GETLOCAL(oparg1); - value2 = GETLOCAL(oparg2); - Py_INCREF(value1); - Py_INCREF(value2); - STACK_GROW(2); - stack_pointer[-2] = value1; - stack_pointer[-1] = value2; + TARGET(BINARY_OP_ADD_UNICODE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_ADD_UNICODE); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_UNICODE + right = stack_pointer[-1]; + left = stack_pointer[-2]; + { + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); + } + // _BINARY_OP_ADD_UNICODE + { + STAT_INC(BINARY_OP, hit); + res = PyUnicode_Concat(left, right); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (res == NULL) goto pop_2_error; + } + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_CONST) { - PyObject *value; - value = GETITEM(FRAME_CO_CONSTS, oparg); - Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_INPLACE_ADD_UNICODE); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *right; + PyObject *left; + // _GUARD_BOTH_UNICODE + right = stack_pointer[-1]; + left = stack_pointer[-2]; + { + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); + } + // _BINARY_OP_INPLACE_ADD_UNICODE + { + assert(next_instr->op.code == STORE_FAST); + PyObject **target_local = &GETLOCAL(next_instr->op.arg); + DEOPT_IF(*target_local != left, BINARY_OP); + STAT_INC(BINARY_OP, hit); + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ + assert(Py_REFCNT(left) >= 2); + _Py_DECREF_NO_DEALLOC(left); + PyUnicode_Append(target_local, right); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (*target_local == NULL) goto pop_2_error; + // The STORE_FAST is already done. + assert(next_instr->op.code == STORE_FAST); + SKIP_OVER(1); + } + stack_pointer += -2; DISPATCH(); } - TARGET(STORE_FAST) { - PyObject *value; - value = stack_pointer[-1]; - SETLOCAL(oparg, value); - STACK_SHRINK(1); - DISPATCH(); - } - - TARGET(STORE_FAST_LOAD_FAST) { - PyObject *value1; - PyObject *value2; - value1 = stack_pointer[-1]; - uint32_t oparg1 = oparg >> 4; - uint32_t oparg2 = oparg & 15; - SETLOCAL(oparg1, value1); - value2 = GETLOCAL(oparg2); - Py_INCREF(value2); - stack_pointer[-1] = value2; - DISPATCH(); - } - - TARGET(STORE_FAST_STORE_FAST) { - 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); - SETLOCAL(oparg2, value2); - STACK_SHRINK(2); - DISPATCH(); - } - - TARGET(POP_TOP) { - PyObject *value; - value = stack_pointer[-1]; - Py_DECREF(value); - STACK_SHRINK(1); - DISPATCH(); - } - - TARGET(PUSH_NULL) { - PyObject *res; - res = NULL; - STACK_GROW(1); - stack_pointer[-1] = res; - DISPATCH(); - } - - TARGET(END_FOR) { - PyObject *value; - // POP_TOP - value = stack_pointer[-1]; - { - Py_DECREF(value); - } - // POP_TOP - value = stack_pointer[-2]; - { - Py_DECREF(value); - } - STACK_SHRINK(2); - DISPATCH(); - } - - TARGET(INSTRUMENTED_END_FOR) { - 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)) { - PyErr_SetObject(PyExc_StopIteration, value); - if (monitor_stop_iteration(tstate, frame, next_instr-1)) { - goto error; - } - PyErr_SetRaisedException(NULL); - } - Py_DECREF(receiver); - Py_DECREF(value); - STACK_SHRINK(2); - DISPATCH(); - } - - TARGET(END_SEND) { - PyObject *value; - PyObject *receiver; - value = stack_pointer[-1]; - receiver = stack_pointer[-2]; - Py_DECREF(receiver); - STACK_SHRINK(1); - stack_pointer[-1] = value; - DISPATCH(); - } - - TARGET(INSTRUMENTED_END_SEND) { - 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)) { - goto error; - } - PyErr_SetRaisedException(NULL); - } - Py_DECREF(receiver); - STACK_SHRINK(1); - stack_pointer[-1] = value; - DISPATCH(); - } - - TARGET(UNARY_NEGATIVE) { - PyObject *value; - PyObject *res; - value = stack_pointer[-1]; - res = PyNumber_Negative(value); - Py_DECREF(value); - if (res == NULL) goto pop_1_error; - stack_pointer[-1] = res; - DISPATCH(); - } - - TARGET(UNARY_NOT) { - PyObject *value; - PyObject *res; - value = stack_pointer[-1]; - assert(PyBool_Check(value)); - res = Py_IsFalse(value) ? Py_True : Py_False; - stack_pointer[-1] = res; - DISPATCH(); - } - - TARGET(TO_BOOL) { - PREDICTED(TO_BOOL); - static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); - PyObject *value; - PyObject *res; - value = stack_pointer[-1]; - #if ENABLE_SPECIALIZATION - _PyToBoolCache *cache = (_PyToBoolCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_ToBool(value, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(TO_BOOL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - int err = PyObject_IsTrue(value); - Py_DECREF(value); - if (err < 0) goto pop_1_error; - res = err ? Py_True : Py_False; - stack_pointer[-1] = res; - next_instr += 3; - DISPATCH(); - } - - TARGET(TO_BOOL_BOOL) { - PyObject *value; - value = stack_pointer[-1]; - DEOPT_IF(!PyBool_Check(value), TO_BOOL); - STAT_INC(TO_BOOL, hit); - next_instr += 3; - DISPATCH(); - } - - TARGET(TO_BOOL_INT) { - 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)) { - assert(_Py_IsImmortal(value)); - res = Py_False; - } - else { - Py_DECREF(value); - res = Py_True; - } - stack_pointer[-1] = res; - next_instr += 3; - DISPATCH(); - } - - TARGET(TO_BOOL_LIST) { - 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; - Py_DECREF(value); - stack_pointer[-1] = res; - next_instr += 3; - DISPATCH(); - } - - TARGET(TO_BOOL_NONE) { - 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); - res = Py_False; - stack_pointer[-1] = res; - next_instr += 3; - DISPATCH(); - } - - TARGET(TO_BOOL_STR) { - 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)) { - assert(_Py_IsImmortal(value)); - res = Py_False; - } - else { - assert(Py_SIZE(value)); - Py_DECREF(value); - res = Py_True; - } - stack_pointer[-1] = res; - next_instr += 3; - DISPATCH(); - } - - TARGET(TO_BOOL_ALWAYS_TRUE) { - 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); - DEOPT_IF(Py_TYPE(value)->tp_version_tag != version, TO_BOOL); - STAT_INC(TO_BOOL, hit); - Py_DECREF(value); - res = Py_True; - stack_pointer[-1] = res; - next_instr += 3; - DISPATCH(); - } - - TARGET(UNARY_INVERT) { - PyObject *value; - PyObject *res; - value = stack_pointer[-1]; - res = PyNumber_Invert(value); - Py_DECREF(value); - if (res == NULL) goto pop_1_error; - stack_pointer[-1] = res; + TARGET(BINARY_OP_MULTIPLY_FLOAT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_MULTIPLY_FLOAT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *right; + PyObject *left; + PyObject *res; + // _GUARD_BOTH_FLOAT + right = stack_pointer[-1]; + left = stack_pointer[-2]; + { + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + } + // _BINARY_OP_MULTIPLY_FLOAT + { + STAT_INC(BINARY_OP, hit); + double dres = + ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); + } + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } TARGET(BINARY_OP_MULTIPLY_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_MULTIPLY_INT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *res; @@ -402,38 +317,44 @@ _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); if (res == NULL) goto pop_2_error; } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(BINARY_OP_ADD_INT) { + TARGET(BINARY_OP_SUBTRACT_FLOAT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_SUBTRACT_FLOAT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *res; - // _GUARD_BOTH_INT + // _GUARD_BOTH_FLOAT right = stack_pointer[-1]; left = stack_pointer[-2]; { - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); } - // _BINARY_OP_ADD_INT + // _BINARY_OP_SUBTRACT_FLOAT { 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; + double dres = + ((PyFloatObject *)left)->ob_fval - + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_OP_SUBTRACT_INT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *res; @@ -452,181 +373,15 @@ _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); if (res == NULL) goto pop_2_error; } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; - DISPATCH(); - } - - TARGET(BINARY_OP_MULTIPLY_FLOAT) { - PyObject *right; - PyObject *left; - PyObject *res; - // _GUARD_BOTH_FLOAT - right = stack_pointer[-1]; - left = stack_pointer[-2]; - { - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - } - // _BINARY_OP_MULTIPLY_FLOAT - { - STAT_INC(BINARY_OP, hit); - double dres = - ((PyFloatObject *)left)->ob_fval * - ((PyFloatObject *)right)->ob_fval; - DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_FLOAT) { - PyObject *right; - PyObject *left; - PyObject *res; - // _GUARD_BOTH_FLOAT - right = stack_pointer[-1]; - left = stack_pointer[-2]; - { - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - } - // _BINARY_OP_ADD_FLOAT - { - STAT_INC(BINARY_OP, hit); - double dres = - ((PyFloatObject *)left)->ob_fval + - ((PyFloatObject *)right)->ob_fval; - DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; - DISPATCH(); - } - - TARGET(BINARY_OP_SUBTRACT_FLOAT) { - PyObject *right; - PyObject *left; - PyObject *res; - // _GUARD_BOTH_FLOAT - right = stack_pointer[-1]; - left = stack_pointer[-2]; - { - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - } - // _BINARY_OP_SUBTRACT_FLOAT - { - STAT_INC(BINARY_OP, hit); - double dres = - ((PyFloatObject *)left)->ob_fval - - ((PyFloatObject *)right)->ob_fval; - DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dres, res); - } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_UNICODE) { - PyObject *right; - PyObject *left; - PyObject *res; - // _GUARD_BOTH_UNICODE - right = stack_pointer[-1]; - left = stack_pointer[-2]; - { - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); - } - // _BINARY_OP_ADD_UNICODE - { - STAT_INC(BINARY_OP, hit); - res = PyUnicode_Concat(left, right); - _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - if (res == NULL) goto pop_2_error; - } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; - DISPATCH(); - } - - TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { - PyObject *right; - PyObject *left; - // _GUARD_BOTH_UNICODE - right = stack_pointer[-1]; - left = stack_pointer[-2]; - { - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP); - } - // _BINARY_OP_INPLACE_ADD_UNICODE - { - _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); - STAT_INC(BINARY_OP, hit); - /* Handle `left = left + right` or `left += right` for str. - * - * When possible, extend `left` in place rather than - * allocating a new PyUnicodeObject. This attempts to avoid - * quadratic behavior when one neglects to use str.join(). - * - * If `left` has only two references remaining (one from - * the stack, one in the locals), DECREFing `left` leaves - * only the locals reference, so PyUnicode_Append knows - * that the string is safe to mutate. - */ - assert(Py_REFCNT(left) >= 2); - _Py_DECREF_NO_DEALLOC(left); - PyUnicode_Append(target_local, right); - _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - if (*target_local == NULL) goto pop_2_error; - // The STORE_FAST is already done. - SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_OP + 1); - } - STACK_SHRINK(2); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR) { - PREDICTED(BINARY_SUBSCR); - static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); - 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)) { - next_instr--; - _Py_Specialize_BinarySubscr(container, sub, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(BINARY_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - res = PyObject_GetItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } TARGET(BINARY_SLICE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(BINARY_SLICE); PyObject *stop; PyObject *start; PyObject *container; @@ -646,37 +401,110 @@ } Py_DECREF(container); if (res == NULL) goto pop_3_error; - STACK_SHRINK(2); - stack_pointer[-1] = res; + stack_pointer[-3] = res; + stack_pointer += -2; DISPATCH(); } - TARGET(STORE_SLICE) { - PyObject *stop; - PyObject *start; + TARGET(BINARY_SUBSCR) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_SUBSCR); + PREDICTED(BINARY_SUBSCR); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *sub; 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) { - err = 1; + PyObject *res; + // _SPECIALIZE_BINARY_SUBSCR + sub = stack_pointer[-1]; + container = stack_pointer[-2]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_BinarySubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_SUBSCR, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - else { - err = PyObject_SetItem(container, slice, v); - Py_DECREF(slice); + // _BINARY_SUBSCR + { + res = PyObject_GetItem(container, sub); + Py_DECREF(container); + Py_DECREF(sub); + if (res == NULL) goto pop_2_error; } - Py_DECREF(v); - Py_DECREF(container); - if (err) goto pop_4_error; - STACK_SHRINK(4); + stack_pointer[-2] = res; + stack_pointer += -1; + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_DICT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_SUBSCR_DICT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); + 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); + int rc = PyDict_GetItemRef(dict, sub, &res); + if (rc == 0) { + _PyErr_SetKeyError(sub); + } + Py_DECREF(dict); + Py_DECREF(sub); + if (rc <= 0) goto pop_2_error; + // not found or error + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } + TARGET(BINARY_SUBSCR_GETITEM) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_SUBSCR_GETITEM); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); + 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); + PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; + PyObject *cached = ht->_spec_cache.getitem; + DEOPT_IF(cached == NULL, BINARY_SUBSCR); + 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); + PyCodeObject *code = (PyCodeObject *)getitem->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + Py_INCREF(getitem); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); + STACK_SHRINK(2); + new_frame->localsplus[0] = container; + new_frame->localsplus[1] = sub; + frame->return_offset = (uint16_t)(next_instr - this_instr); + DISPATCH_INLINED(new_frame); + } + TARGET(BINARY_SUBSCR_LIST_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_SUBSCR_LIST_INT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); PyObject *sub; PyObject *list; PyObject *res; @@ -684,7 +512,6 @@ list = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); - // Deopt unless 0 <= sub < PyList_Size(list) DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; @@ -695,13 +522,16 @@ Py_INCREF(res); _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(list); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } TARGET(BINARY_SUBSCR_STR_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_SUBSCR_STR_INT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); PyObject *sub; PyObject *str; PyObject *res; @@ -719,13 +549,16 @@ 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; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } TARGET(BINARY_SUBSCR_TUPLE_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(BINARY_SUBSCR_TUPLE_INT); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); PyObject *sub; PyObject *tuple; PyObject *res; @@ -733,7 +566,6 @@ tuple = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); - // Deopt unless 0 <= sub < PyTuple_Size(list) DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; @@ -744,2845 +576,3014 @@ Py_INCREF(res); _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(tuple); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(BINARY_SUBSCR_DICT) { - 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); - if (res == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetKeyError(sub); - } - Py_DECREF(dict); - Py_DECREF(sub); - if (true) goto pop_2_error; - } - Py_INCREF(res); // Do this before DECREF'ing dict, sub - Py_DECREF(dict); - Py_DECREF(sub); - STACK_SHRINK(1); - stack_pointer[-1] = res; + TARGET(BUILD_CONST_KEY_MAP) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(BUILD_CONST_KEY_MAP); + 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, + "bad BUILD_CONST_KEY_MAP keys argument"); + GOTO_ERROR(error); // Pop the keys and values. + } + map = _PyDict_FromItems( + &PyTuple_GET_ITEM(keys, 0), 1, + values, 1, oparg); + for (int _i = oparg; --_i >= 0;) { + Py_DECREF(values[_i]); + } + Py_DECREF(keys); + if (map == NULL) { stack_pointer += -1 - oparg; goto error; } + stack_pointer[-1 - oparg] = map; + stack_pointer += -oparg; DISPATCH(); } - TARGET(BINARY_SUBSCR_GETITEM) { - 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); - PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; - PyObject *cached = ht->_spec_cache.getitem; - DEOPT_IF(cached == NULL, BINARY_SUBSCR); - 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); - PyCodeObject *code = (PyCodeObject *)getitem->func_code; - assert(code->co_argcount == 2); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - Py_INCREF(getitem); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); - STACK_SHRINK(2); - new_frame->localsplus[0] = container; - new_frame->localsplus[1] = sub; - SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); - } - - TARGET(LIST_APPEND) { - 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; - 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; - STACK_SHRINK(1); + TARGET(BUILD_LIST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(BUILD_LIST); + PyObject **values; + PyObject *list; + values = &stack_pointer[-oparg]; + list = _PyList_FromArraySteal(values, oparg); + if (list == NULL) { stack_pointer += -oparg; goto error; } + stack_pointer[-oparg] = list; + stack_pointer += 1 - oparg; DISPATCH(); } - TARGET(STORE_SUBSCR) { - PREDICTED(STORE_SUBSCR); - static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size"); - 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)) { - next_instr--; - _Py_Specialize_StoreSubscr(container, sub, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(STORE_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - /* container[sub] = v */ - int err = PyObject_SetItem(container, sub, v); - Py_DECREF(v); - Py_DECREF(container); - Py_DECREF(sub); - if (err) goto pop_3_error; - STACK_SHRINK(3); + TARGET(BUILD_MAP) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(BUILD_MAP); + PyObject **values; + PyObject *map; + values = &stack_pointer[-oparg*2]; + map = _PyDict_FromItems( + values, 2, + values+1, 2, + oparg); + for (int _i = oparg*2; --_i >= 0;) { + Py_DECREF(values[_i]); + } + if (map == NULL) { stack_pointer += -oparg*2; goto error; } + stack_pointer[-oparg*2] = map; + stack_pointer += 1 - oparg*2; DISPATCH(); } - TARGET(STORE_SUBSCR_LIST_INT) { - 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); - - // Ensure nonnegative, zero-or-one-digit ints. - DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), STORE_SUBSCR); - Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; - // Ensure index < len(list) - DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); - STAT_INC(STORE_SUBSCR, hit); - - PyObject *old_value = PyList_GET_ITEM(list, index); - PyList_SET_ITEM(list, index, value); - assert(old_value != NULL); - Py_DECREF(old_value); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); - Py_DECREF(list); - STACK_SHRINK(3); + TARGET(BUILD_SET) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(BUILD_SET); + PyObject **values; + PyObject *set; + values = &stack_pointer[-oparg]; + set = PySet_New(NULL); + if (set == NULL) + GOTO_ERROR(error); + int err = 0; + for (int i = 0; i < oparg; i++) { + PyObject *item = values[i]; + if (err == 0) + err = PySet_Add(set, item); + Py_DECREF(item); + } + if (err != 0) { + Py_DECREF(set); + if (true) { stack_pointer += -oparg; goto error; } + } + stack_pointer[-oparg] = set; + stack_pointer += 1 - oparg; DISPATCH(); } - TARGET(STORE_SUBSCR_DICT) { - 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); - Py_DECREF(dict); - if (err) goto pop_3_error; - STACK_SHRINK(3); + TARGET(BUILD_SLICE) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(BUILD_SLICE); + 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); + Py_XDECREF(step); + if (slice == NULL) { stack_pointer += -2 - (((oparg == 3) ? 1 : 0)); goto error; } + stack_pointer[-2 - (((oparg == 3) ? 1 : 0))] = slice; + stack_pointer += -1 - (((oparg == 3) ? 1 : 0)); DISPATCH(); } - TARGET(DELETE_SUBSCR) { - PyObject *sub; - PyObject *container; - sub = stack_pointer[-1]; - container = stack_pointer[-2]; - /* del container[sub] */ - int err = PyObject_DelItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - if (err) goto pop_2_error; - STACK_SHRINK(2); + TARGET(BUILD_STRING) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(BUILD_STRING); + 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]); + } + if (str == NULL) { stack_pointer += -oparg; goto error; } + stack_pointer[-oparg] = str; + stack_pointer += 1 - oparg; DISPATCH(); } - TARGET(CALL_INTRINSIC_1) { - PyObject *value; - PyObject *res; - value = stack_pointer[-1]; - assert(oparg <= MAX_INTRINSIC_1); - res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value); - Py_DECREF(value); - if (res == NULL) goto pop_1_error; - stack_pointer[-1] = res; + TARGET(BUILD_TUPLE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(BUILD_TUPLE); + PyObject **values; + PyObject *tup; + values = &stack_pointer[-oparg]; + tup = _PyTuple_FromArraySteal(values, oparg); + if (tup == NULL) { stack_pointer += -oparg; goto error; } + stack_pointer[-oparg] = tup; + stack_pointer += 1 - oparg; DISPATCH(); } - TARGET(CALL_INTRINSIC_2) { - PyObject *value1; - PyObject *value2; - PyObject *res; - value1 = stack_pointer[-1]; - value2 = stack_pointer[-2]; - assert(oparg <= MAX_INTRINSIC_2); - res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); - Py_DECREF(value2); - Py_DECREF(value1); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; - DISPATCH(); + TARGET(CACHE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CACHE); + TIER_ONE_ONLY + assert(0 && "Executing a cache."); + Py_UNREACHABLE(); } - TARGET(RAISE_VARARGS) { + TARGET(CALL) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL); + PREDICTED(CALL); + _Py_CODEUNIT *this_instr = next_instr - 4; PyObject **args; - args = stack_pointer - oparg; - PyObject *cause = NULL, *exc = NULL; - switch (oparg) { - case 2: - cause = args[1]; - /* fall through */ - case 1: - exc = args[0]; - /* fall through */ - case 0: - if (do_raise(tstate, exc, cause)) { - assert(oparg == 0); - monitor_reraise(tstate, frame, next_instr-1); - goto exception_unwind; + PyObject *self_or_null; + PyObject *callable; + PyObject *res; + // _SPECIALIZE_CALL + args = &stack_pointer[-oparg]; + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_Call(callable, next_instr, oparg + (self_or_null != NULL)); + DISPATCH_SAME_OPARG(); } - break; - default: - _PyErr_SetString(tstate, PyExc_SystemError, - "bad RAISE_VARARGS oparg"); - break; + STAT_INC(CALL, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ + } + // _CALL + { + // oparg counts all of the args, but *not* self: + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + else if (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; + } + // 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, total_args, NULL + ); + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + // 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(error); + } + frame->return_offset = (uint16_t)(next_instr - this_instr); + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + res = PyObject_Vectorcall( + callable, args, + total_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + NULL); + if (opcode == INSTRUMENTED_CALL) { + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : args[0]; + if (res == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, this_instr, callable, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, this_instr, callable, arg); + if (err < 0) { + Py_CLEAR(res); + } + } + } + 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_pointer += -2 - oparg; goto error; } } - if (true) { STACK_SHRINK(oparg); goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); + DISPATCH(); } - TARGET(INTERPRETER_EXIT) { - PyObject *retval; - retval = stack_pointer[-1]; - assert(frame == &entry_frame); - assert(_PyFrame_IsIncomplete(frame)); - /* Restore previous frame and return. */ - tstate->current_frame = frame->previous; - assert(!_PyErr_Occurred(tstate)); - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; - return retval; - } - - TARGET(RETURN_VALUE) { - PyObject *retval; - // _SAVE_CURRENT_IP - { - #if TIER_ONE - frame->prev_instr = next_instr - 1; - #endif - #if TIER_TWO - // Relies on a preceding _SET_IP - frame->prev_instr--; - #endif + TARGET(CALL_ALLOC_AND_ENTER_INIT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_ALLOC_AND_ENTER_INIT); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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 + * */ + _PyCallCache *cache = (_PyCallCache *)&this_instr[1]; + DEOPT_IF(null != NULL, CALL); + DEOPT_IF(!PyType_Check(callable), CALL); + PyTypeObject *tp = (PyTypeObject *)callable; + DEOPT_IF(tp->tp_version_tag != read_u32(cache->func_version), CALL); + 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); + STAT_INC(CALL, hit); + PyObject *self = _PyType_NewManagedObject(tp); + if (self == NULL) { + GOTO_ERROR(error); } - // _POP_FRAME - 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 + Py_DECREF(tp); + _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( + tstate, (PyCodeObject *)&_Py_InitCleanup, 1); + assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[0].op.code == EXIT_INIT_CHECK); + /* Push self onto stack of shim */ + Py_INCREF(self); + shim->localsplus[0] = self; + Py_INCREF(init); + _PyInterpreterFrame *init_frame = _PyFrame_PushUnchecked(tstate, init, oparg+1); + /* Copy self followed by args to __init__ frame */ + init_frame->localsplus[0] = self; + for (int i = 0; i < oparg; i++) { + init_frame->localsplus[i+1] = args[i]; } - DISPATCH(); - } - - TARGET(INSTRUMENTED_RETURN_VALUE) { - PyObject *retval; - retval = stack_pointer[-1]; - int err = _Py_call_instrumentation_arg( - tstate, PY_MONITORING_EVENT_PY_RETURN, - frame, next_instr-1, retval); - if (err) goto error; - STACK_SHRINK(1); - assert(EMPTY()); + frame->return_offset = (uint16_t)(next_instr - this_instr); + STACK_SHRINK(oparg+2); _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 = tstate->current_frame = dying->previous; - _PyEval_FrameClearAndPop(tstate, dying); - frame->prev_instr += frame->return_offset; - _PyFrame_StackPush(frame, retval); - goto resume_frame; + /* Link frames */ + init_frame->previous = shim; + shim->previous = 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, + * as it will be checked after start_frame */ + tstate->py_recursion_remaining--; + goto start_frame; } - TARGET(RETURN_CONST) { - PyObject *value; - PyObject *retval; - // LOAD_CONST + TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_BOUND_METHOD_EXACT_ARGS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject *null; + PyObject *callable; + PyObject *func; + PyObject *self; + PyObject *self_or_null; + PyObject **args; + _PyInterpreterFrame *new_frame; + /* Skip 1 cache entry */ + // _CHECK_PEP_523 { - value = GETITEM(FRAME_CO_CONSTS, oparg); - Py_INCREF(value); + 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(&this_instr[2].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]; + self_or_null = stack_pointer[-1 - 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 + // _SAVE_RETURN_OFFSET { #if TIER_ONE - frame->prev_instr = next_instr - 1; + frame->return_offset = (uint16_t)(next_instr - this_instr); #endif #if TIER_TWO - // Relies on a preceding _SET_IP - frame->prev_instr--; + frame->return_offset = oparg; #endif } - // _POP_FRAME - retval = value; + // _PUSH_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); + // Write it out explicitly because it's subtly different. + // Eventually this should be the only occurrence of this code. + assert(tstate->interp->eval_frame == NULL); + stack_pointer += -2 - oparg; + _PyFrame_SetStackPointer(frame, stack_pointer); + 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 + LOAD_IP(0); + #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { goto exit_unwind; } - #endif + #endif } + stack_pointer += (((0) ? 1 : 0)); DISPATCH(); } - TARGET(INSTRUMENTED_RETURN_CONST) { - PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg); - int err = _Py_call_instrumentation_arg( - tstate, PY_MONITORING_EVENT_PY_RETURN, - frame, next_instr-1, retval); - if (err) goto error; - 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 = 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; - PyObject *iter; - obj = stack_pointer[-1]; - unaryfunc getter = NULL; - PyTypeObject *type = Py_TYPE(obj); - - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } - - if (getter == NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an object with " - "__aiter__ method, got %.100s", - type->tp_name); - Py_DECREF(obj); - if (true) goto pop_1_error; + TARGET(CALL_BUILTIN_CLASS) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_BUILTIN_CLASS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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++; } - - iter = (*getter)(obj); - Py_DECREF(obj); - if (iter == NULL) goto pop_1_error; - - if (Py_TYPE(iter)->tp_as_async == NULL || - Py_TYPE(iter)->tp_as_async->am_anext == NULL) { - - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' received an object from __aiter__ " - "that does not implement __anext__: %.100s", - Py_TYPE(iter)->tp_name); - Py_DECREF(iter); - if (true) goto pop_1_error; + 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]); } - stack_pointer[-1] = iter; + Py_DECREF(tp); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(GET_ANEXT) { - PyObject *aiter; - PyObject *awaitable; - aiter = stack_pointer[-1]; - unaryfunc getter = NULL; - PyObject *next_iter = NULL; - PyTypeObject *type = Py_TYPE(aiter); - - if (PyAsyncGen_CheckExact(aiter)) { - awaitable = type->tp_as_async->am_anext(aiter); - if (awaitable == NULL) { - goto error; - } - } else { - if (type->tp_as_async != NULL){ - getter = type->tp_as_async->am_anext; - } - - if (getter != NULL) { - next_iter = (*getter)(aiter); - if (next_iter == NULL) { - goto error; - } - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an iterator with " - "__anext__ method, got %.100s", - type->tp_name); - goto error; - } - - awaitable = _PyCoro_GetAwaitableIter(next_iter); - if (awaitable == NULL) { - _PyErr_FormatFromCause( - PyExc_TypeError, - "'async for' received an invalid object " - "from __anext__: %.100s", - Py_TYPE(next_iter)->tp_name); - - Py_DECREF(next_iter); - goto error; - } else { - Py_DECREF(next_iter); - } + TARGET(CALL_BUILTIN_FAST) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_BUILTIN_FAST); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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 */ + 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, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + /* res = func(self, args, nargs) */ + res = ((_PyCFunctionFast)(void(*)(void))cfunc)( + PyCFunction_GET_SELF(callable), + args, + total_args); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); } - STACK_GROW(1); - stack_pointer[-1] = awaitable; + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + /* Not deopting because this doesn't mean our optimization was + wrong. `res` can be NULL for valid reasons. Eg. getattr(x, + 'invalid'). In those cases an exception is set, so we must + handle it. + */ + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(GET_AWAITABLE) { - PyObject *iterable; - PyObject *iter; - iterable = stack_pointer[-1]; - iter = _PyCoro_GetAwaitableIter(iterable); - - if (iter == NULL) { - _PyEval_FormatAwaitableError(tstate, Py_TYPE(iterable), oparg); + TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_BUILTIN_FAST_WITH_KEYWORDS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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 total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; } - - Py_DECREF(iterable); - - if (iter != NULL && PyCoro_CheckExact(iter)) { - PyObject *yf = _PyGen_yf((PyGenObject*)iter); - if (yf != NULL) { - /* `iter` is a coroutine object that is being - awaited, `yf` is a pointer to the current awaitable - being awaited on. */ - Py_DECREF(yf); - Py_CLEAR(iter); - _PyErr_SetString(tstate, PyExc_RuntimeError, - "coroutine is being awaited already"); - /* The code below jumps to `error` if `iter` is NULL. */ - } + 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]); } - - if (iter == NULL) goto pop_1_error; - stack_pointer[-1] = iter; + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(SEND) { - PREDICTED(SEND); - static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); - 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)) { - next_instr--; - _Py_Specialize_Send(receiver, next_instr); - DISPATCH_SAME_OPARG(); - } - STAT_INC(SEND, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - assert(frame != &entry_frame); - if ((tstate->interp->eval_frame == NULL) && - (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && - ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) - { - PyGenObject *gen = (PyGenObject *)receiver; - _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - 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)) { - retval = Py_TYPE(receiver)->tp_iternext(receiver); + TARGET(CALL_BUILTIN_O) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_BUILTIN_O); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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 */ + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; } - else { - retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); + DEOPT_IF(total_args != 1, CALL); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + GOTO_ERROR(error); } - if (retval == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) - ) { - monitor_raise(tstate, frame, next_instr-1); + PyObject *arg = args[0]; + res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(arg); + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_FUNCTION_EX) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CALL_FUNCTION_EX); + PREDICTED(CALL_FUNCTION_EX); + _Py_CODEUNIT *this_instr = next_instr - 1; + PyObject *kwargs = NULL; + PyObject *callargs; + PyObject *func; + PyObject *result; + if (oparg & 1) { kwargs = stack_pointer[-((oparg & 1))]; } + callargs = stack_pointer[-1 - ((oparg & 1))]; + func = stack_pointer[-3 - ((oparg & 1))]; + // 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)); + if (!PyTuple_CheckExact(callargs)) { + if (check_args_iterable(tstate, func, callargs) < 0) { + GOTO_ERROR(error); + } + PyObject *tuple = PySequence_Tuple(callargs); + if (tuple == NULL) { + GOTO_ERROR(error); } - if (_PyGen_FetchStopIterationValue(&retval) == 0) { - assert(retval != NULL); - JUMPBY(oparg); + Py_SETREF(callargs, tuple); + } + assert(PyTuple_CheckExact(callargs)); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func); + if (opcode == INSTRUMENTED_CALL_FUNCTION_EX && + !PyFunction_Check(func) && !PyMethod_Check(func) + ) { + PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ? + PyTuple_GET_ITEM(callargs, 0) : Py_None; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, this_instr, func, arg); + if (err) GOTO_ERROR(error); + result = PyObject_Call(func, callargs, kwargs); + if (result == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, this_instr, func, arg); } else { - goto error; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, this_instr, func, arg); + if (err < 0) { + Py_CLEAR(result); + } } } - Py_DECREF(v); - stack_pointer[-1] = retval; - next_instr += 1; + else { + if (Py_TYPE(func) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) { + assert(PyTuple_CheckExact(callargs)); + Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); + int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func)); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate, + (PyFunctionObject *)func, locals, + nargs, callargs, kwargs); + // Need to manually shrink the stack since we exit with DISPATCH_INLINED. + STACK_SHRINK(oparg + 3); + if (new_frame == NULL) { + GOTO_ERROR(error); + } + assert(next_instr - this_instr == 1); + frame->return_offset = 1; + DISPATCH_INLINED(new_frame); + } + result = PyObject_Call(func, callargs, kwargs); + } + Py_DECREF(func); + Py_DECREF(callargs); + Py_XDECREF(kwargs); + assert(PEEK(2 + (oparg & 1)) == NULL); + if (result == NULL) { stack_pointer += -3 - ((oparg & 1)); goto error; } + stack_pointer[-3 - ((oparg & 1))] = result; + stack_pointer += -2 - ((oparg & 1)); + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(SEND_GEN) { - 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(gen->gi_frame_state >= FRAME_EXECUTING, SEND); - STAT_INC(SEND, hit); - _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - 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(CALL_INTRINSIC_1) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CALL_INTRINSIC_1); + PyObject *value; + PyObject *res; + value = stack_pointer[-1]; + assert(oparg <= MAX_INTRINSIC_1); + res = _PyIntrinsics_UnaryFunctions[oparg].func(tstate, value); + Py_DECREF(value); + if (res == NULL) goto pop_1_error; + stack_pointer[-1] = res; + DISPATCH(); } - TARGET(INSTRUMENTED_YIELD_VALUE) { - 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); - gen->gi_frame_state = FRAME_SUSPENDED; - _PyFrame_SetStackPointer(frame, stack_pointer - 1); - int err = _Py_call_instrumentation_arg( - tstate, PY_MONITORING_EVENT_PY_YIELD, - frame, next_instr-1, retval); - if (err) goto error; - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *gen_frame = frame; - frame = tstate->current_frame = frame->previous; - gen_frame->previous = NULL; - _PyFrame_StackPush(frame, retval); - goto resume_frame; - } - - TARGET(YIELD_VALUE) { - 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. - assert(oparg >= 0); /* make the generator identify this as HAS_ARG */ - assert(frame != &entry_frame); - PyGenObject *gen = _PyFrame_GetGenerator(frame); - gen->gi_frame_state = FRAME_SUSPENDED; - _PyFrame_SetStackPointer(frame, stack_pointer - 1); - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - _Py_LeaveRecursiveCallPy(tstate); - _PyInterpreterFrame *gen_frame = frame; - frame = tstate->current_frame = frame->previous; - gen_frame->previous = NULL; - _PyFrame_StackPush(frame, retval); - goto resume_frame; + TARGET(CALL_INTRINSIC_2) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CALL_INTRINSIC_2); + PyObject *value1; + PyObject *value2; + PyObject *res; + value1 = stack_pointer[-1]; + value2 = stack_pointer[-2]; + assert(oparg <= MAX_INTRINSIC_2); + res = _PyIntrinsics_BinaryFunctions[oparg].func(tstate, value2, value1); + Py_DECREF(value2); + Py_DECREF(value1); + if (res == NULL) goto pop_2_error; + stack_pointer[-2] = res; + stack_pointer += -1; + DISPATCH(); } - TARGET(POP_EXCEPT) { - 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); + TARGET(CALL_ISINSTANCE) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_ISINSTANCE); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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]; + /* isinstance(o, o2) */ + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; + } + DEOPT_IF(total_args != 2, CALL); + PyInterpreterState *interp = tstate->interp; + DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + STAT_INC(CALL, hit); + PyObject *cls = args[1]; + PyObject *inst = args[0]; + int retval = PyObject_IsInstance(inst, cls); + if (retval < 0) { + GOTO_ERROR(error); + } + res = PyBool_FromLong(retval); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(inst); + Py_DECREF(cls); + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; DISPATCH(); } - TARGET(RERAISE) { - PyObject *exc; - PyObject **values; - exc = stack_pointer[-1]; - values = stack_pointer - 1 - oparg; - assert(oparg >= 0 && oparg <= 2); - if (oparg) { - PyObject *lasti = values[0]; - if (PyLong_Check(lasti)) { - frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); - assert(!_PyErr_Occurred(tstate)); + TARGET(CALL_KW) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CALL_KW); + PREDICTED(CALL_KW); + _Py_CODEUNIT *this_instr = next_instr - 1; + 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(error); + } + assert(next_instr - this_instr == 1); + frame->return_offset = 1; + 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, this_instr, callable, arg); } else { - assert(PyLong_Check(lasti)); - _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); - goto error; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, this_instr, callable, arg); + if (err < 0) { + Py_CLEAR(res); + } } } - 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; - PyObject *awaitable; - exc = stack_pointer[-1]; - awaitable = stack_pointer[-2]; - assert(exc && PyExceptionInstance_Check(exc)); - if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { - Py_DECREF(awaitable); - Py_DECREF(exc); - } - else { - Py_INCREF(exc); - _PyErr_SetRaisedException(tstate, exc); - monitor_reraise(tstate, frame, next_instr-1); - goto exception_unwind; + 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]); } - STACK_SHRINK(2); + if (res == NULL) { stack_pointer += -3 - oparg; goto error; } + stack_pointer[-3 - oparg] = res; + stack_pointer += -2 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(CLEANUP_THROW) { - 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)) { - value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); - Py_DECREF(sub_iter); - Py_DECREF(last_sent_val); - Py_DECREF(exc_value); - none = Py_None; + TARGET(CALL_LEN) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_LEN); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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 total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; } - else { - _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); - monitor_reraise(tstate, frame, next_instr-1); - goto exception_unwind; + DEOPT_IF(total_args != 1, CALL); + PyInterpreterState *interp = tstate->interp; + DEOPT_IF(callable != interp->callable_cache.len, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + Py_ssize_t len_i = PyObject_Length(arg); + if (len_i < 0) { + GOTO_ERROR(error); } - STACK_SHRINK(1); - stack_pointer[-2] = none; - stack_pointer[-1] = value; + res = PyLong_FromSsize_t(len_i); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(callable); + Py_DECREF(arg); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; DISPATCH(); } - TARGET(LOAD_ASSERTION_ERROR) { - PyObject *value; - value = Py_NewRef(PyExc_AssertionError); - STACK_GROW(1); - stack_pointer[-1] = value; + TARGET(CALL_LIST_APPEND) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_LIST_APPEND); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject **args; + PyObject *self; + PyObject *callable; + args = &stack_pointer[-oparg]; + self = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + assert(oparg == 1); + 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(callable); + STACK_SHRINK(3); + // Skip POP_TOP + assert(next_instr->op.code == POP_TOP); + SKIP_OVER(1); DISPATCH(); } - TARGET(LOAD_BUILD_CLASS) { - PyObject *bc; - if (PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc) < 0) goto error; - if (bc == NULL) { - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - if (true) goto error; + TARGET(CALL_METHOD_DESCRIPTOR_FAST) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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++; } - STACK_GROW(1); - stack_pointer[-1] = bc; - DISPATCH(); - } - - TARGET(STORE_NAME) { - PyObject *v; - v = stack_pointer[-1]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - PyObject *ns = LOCALS(); - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when storing %R", name); - Py_DECREF(v); - if (true) goto pop_1_error; + PyMethodDescrObject *method = (PyMethodDescrObject *)callable; + /* Builtin METH_FASTCALL methods, without keywords */ + 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, method->d_common.d_type), CALL); + STAT_INC(CALL, hit); + _PyCFunctionFast cfunc = + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + int nargs = total_args - 1; + res = cfunc(self, args + 1, nargs); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + /* Clear the stack of the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); } - if (PyDict_CheckExact(ns)) - err = PyDict_SetItem(ns, name, v); - else - err = PyObject_SetItem(ns, name, v); - Py_DECREF(v); - if (err) goto pop_1_error; - STACK_SHRINK(1); + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(DELETE_NAME) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - PyObject *ns = LOCALS(); - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when deleting %R", name); - goto error; + TARGET(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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++; } - err = PyObject_DelItem(ns, name); - // Can't use ERROR_IF here. - if (err != 0) { - _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); - goto error; + 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_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(UNPACK_SEQUENCE) { - PREDICTED(UNPACK_SEQUENCE); - static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); - PyObject *seq; - seq = stack_pointer[-1]; - #if ENABLE_SPECIALIZATION - _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_UnpackSequence(seq, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - STAT_INC(UNPACK_SEQUENCE, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - PyObject **top = stack_pointer + oparg - 1; - int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); - Py_DECREF(seq); - if (res == 0) goto pop_1_error; - STACK_SHRINK(1); - STACK_GROW(oparg); - next_instr += 1; - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { - 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); - STAT_INC(UNPACK_SEQUENCE, hit); - values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); - values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); - Py_DECREF(seq); - STACK_SHRINK(1); - STACK_GROW(oparg); - next_instr += 1; - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE_TUPLE) { - 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); - PyObject **items = _PyTuple_ITEMS(seq); - for (int i = oparg; --i >= 0; ) { - *values++ = Py_NewRef(items[i]); + TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_NOARGS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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]; + assert(oparg == 0 || oparg == 1); + int total_args = oparg; + if (self_or_null != NULL) { + args--; + total_args++; } - Py_DECREF(seq); - STACK_SHRINK(1); - STACK_GROW(oparg); - next_instr += 1; - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE_LIST) { - 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); - PyObject **items = _PyList_ITEMS(seq); - for (int i = oparg; --i >= 0; ) { - *values++ = Py_NewRef(items[i]); + DEOPT_IF(total_args != 1, CALL); + 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, method->d_common.d_type), CALL); + DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + GOTO_ERROR(error); } - Py_DECREF(seq); - STACK_SHRINK(1); - STACK_GROW(oparg); - next_instr += 1; - DISPATCH(); - } - - TARGET(UNPACK_EX) { - PyObject *seq; - seq = stack_pointer[-1]; - int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); - PyObject **top = stack_pointer + totalargs - 1; - 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)); + res = _PyCFunction_TrampolineCall(cfunc, self, NULL); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(STORE_ATTR) { - PREDICTED(STORE_ATTR); - static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); - 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)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - next_instr--; - _Py_Specialize_StoreAttr(owner, next_instr, name); - DISPATCH_SAME_OPARG(); - } - STAT_INC(STORE_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - int err = PyObject_SetAttr(owner, name, v); - Py_DECREF(v); - Py_DECREF(owner); - if (err) goto pop_2_error; - STACK_SHRINK(2); + TARGET(CALL_METHOD_DESCRIPTOR_O) { + frame->instr_ptr = next_instr; next_instr += 4; + INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_O); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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(total_args != 2, CALL); + 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, 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 + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + GOTO_ERROR(error); + } + res = _PyCFunction_TrampolineCall(cfunc, self, arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(arg); + Py_DECREF(callable); + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(DELETE_ATTR) { - PyObject *owner; - owner = stack_pointer[-1]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - int err = PyObject_DelAttr(owner, name); - Py_DECREF(owner); - if (err) goto pop_1_error; - STACK_SHRINK(1); - DISPATCH(); - } - - TARGET(STORE_GLOBAL) { - PyObject *v; - v = stack_pointer[-1]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - int err = PyDict_SetItem(GLOBALS(), name, v); - Py_DECREF(v); - if (err) goto pop_1_error; - STACK_SHRINK(1); - DISPATCH(); - } - - TARGET(DELETE_GLOBAL) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - int err; - err = PyDict_DelItem(GLOBALS(), name); - // Can't use ERROR_IF here. - if (err != 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; + TARGET(CALL_PY_EXACT_ARGS) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_PY_EXACT_ARGS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject *self_or_null; + PyObject *callable; + PyObject **args; + _PyInterpreterFrame *new_frame; + /* Skip 1 cache entry */ + // _CHECK_PEP_523 + { + DEOPT_IF(tstate->interp->eval_frame, CALL); } - DISPATCH(); - } - - TARGET(LOAD_LOCALS) { - PyObject *locals; - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found"); - if (true) goto error; + // _CHECK_FUNCTION_EXACT_ARGS + self_or_null = stack_pointer[-1 - oparg]; + callable = stack_pointer[-2 - oparg]; + { + uint32_t func_version = read_u32(&this_instr[2].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); } - Py_INCREF(locals); - STACK_GROW(1); - stack_pointer[-1] = locals; - DISPATCH(); - } - - 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; + // _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); } - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); + // _INIT_CALL_PY_EXACT_ARGS + args = &stack_pointer[-oparg]; + self_or_null = stack_pointer[-1 - oparg]; + { + int argcount = oparg; + if (self_or_null != NULL) { + args--; + argcount++; } - else if (_PyErr_Occurred(tstate)) { - goto error; + 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]; } - else { - if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { - goto error; - } - if (v == NULL) { - _PyEval_FormatExcCheckArg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; - } + } + // _SAVE_RETURN_OFFSET + { + #if TIER_ONE + frame->return_offset = (uint16_t)(next_instr - this_instr); + #endif + #if TIER_TWO + frame->return_offset = oparg; + #endif + } + // _PUSH_FRAME + { + // Write it out explicitly because it's subtly different. + // Eventually this should be the only occurrence of this code. + assert(tstate->interp->eval_frame == NULL); + stack_pointer += -2 - oparg; + _PyFrame_SetStackPointer(frame, stack_pointer); + new_frame->previous = frame; + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = new_frame; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(0); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; } + #endif } - Py_DECREF(mod_or_class_dict); - stack_pointer[-1] = v; + stack_pointer += (((0) ? 1 : 0)); DISPATCH(); } - 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; + TARGET(CALL_PY_WITH_DEFAULTS) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_PY_WITH_DEFAULTS); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + 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(&this_instr[2].cache); + DEOPT_IF(tstate->interp->eval_frame, CALL); + int argcount = oparg; + if (self_or_null != NULL) { + args--; + argcount++; } - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { - goto error; + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + 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); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; } - 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; - } - } + for (int i = argcount; i < code->co_argcount; i++) { + PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i - min_args); + new_frame->localsplus[i] = Py_NewRef(def); } - STACK_GROW(1); - stack_pointer[-1] = v; - DISPATCH(); + // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + frame->return_offset = (uint16_t)(next_instr - this_instr); + DISPATCH_INLINED(new_frame); } - TARGET(LOAD_GLOBAL) { - PREDICTED(LOAD_GLOBAL); - static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); + TARGET(CALL_STR_1) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(CALL_STR_1); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject **args; + PyObject *null; + PyObject *callable; PyObject *res; - PyObject *null = NULL; - #if ENABLE_SPECIALIZATION - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - next_instr--; - _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); - DISPATCH_SAME_OPARG(); - } - STAT_INC(LOAD_GLOBAL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - if (PyDict_CheckExact(GLOBALS()) - && PyDict_CheckExact(BUILTINS())) - { - 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 */ - _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - if (true) goto error; - } - Py_INCREF(res); - } - else { - /* Slow-path if globals or builtins is not a dict */ + 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); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + res = PyObject_Str(arg); + Py_DECREF(arg); + Py_DECREF(&PyUnicode_Type); // I.e., callable + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } - /* namespace 1: globals */ - if (PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0) goto error; - if (res == NULL) { - /* namespace 2: builtins */ - 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; - } - } - } - null = NULL; - STACK_GROW(1); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + TARGET(CALL_TUPLE_1) { + frame->instr_ptr = next_instr; next_instr += 4; + INSTRUCTION_STATS(CALL_TUPLE_1); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject **args; + PyObject *null; + PyObject *callable; + PyObject *res; + 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); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + res = PySequence_Tuple(arg); + Py_DECREF(arg); + Py_DECREF(&PyTuple_Type); // I.e., tuple + if (res == NULL) { stack_pointer += -2 - oparg; goto error; } + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; + CHECK_EVAL_BREAKER(); DISPATCH(); } - TARGET(LOAD_GLOBAL_MODULE) { - PyObject *res; - PyObject *null = NULL; - // _GUARD_GLOBALS_VERSION - { - uint16_t version = read_u16(&next_instr[1].cache); - PyDictObject *dict = (PyDictObject *)GLOBALS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); - assert(DK_IS_UNICODE(dict->ma_keys)); - } - // _LOAD_GLOBAL_MODULE - { - uint16_t index = read_u16(&next_instr[3].cache); - PyDictObject *dict = (PyDictObject *)GLOBALS(); - PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); - res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); - Py_INCREF(res); - STAT_INC(LOAD_GLOBAL, hit); - null = NULL; - } - STACK_GROW(1); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } + TARGET(CALL_TYPE_1) { + frame->instr_ptr = next_instr; next_instr += 4; + INSTRUCTION_STATS(CALL_TYPE_1); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject **args; + PyObject *null; + PyObject *callable; + PyObject *res; + 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]; + DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + STAT_INC(CALL, hit); + res = Py_NewRef(Py_TYPE(obj)); + Py_DECREF(obj); + Py_DECREF(&PyType_Type); // I.e., callable + stack_pointer[-2 - oparg] = res; + stack_pointer += -1 - oparg; DISPATCH(); } - TARGET(LOAD_GLOBAL_BUILTIN) { - PyObject *res; - PyObject *null = NULL; - // _GUARD_GLOBALS_VERSION - { - uint16_t version = read_u16(&next_instr[1].cache); - PyDictObject *dict = (PyDictObject *)GLOBALS(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - 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(); - DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); - assert(DK_IS_UNICODE(dict->ma_keys)); - } - // _LOAD_GLOBAL_BUILTINS - { - uint16_t index = read_u16(&next_instr[3].cache); - PyDictObject *bdict = (PyDictObject *)BUILTINS(); - PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); - res = entries[index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); - Py_INCREF(res); - STAT_INC(LOAD_GLOBAL, hit); - null = NULL; + TARGET(CHECK_EG_MATCH) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CHECK_EG_MATCH); + PyObject *match_type; + PyObject *exc_value; + PyObject *rest; + PyObject *match; + 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; } - STACK_GROW(1); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = res; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } - next_instr += 4; - DISPATCH(); - } - - TARGET(DELETE_FAST) { - PyObject *v = GETLOCAL(oparg); - if (v == NULL) goto unbound_local_error; - SETLOCAL(oparg, NULL); - DISPATCH(); - } - - TARGET(MAKE_CELL) { - // "initial" is probably NULL but not if it's an arg (or set - // via PyFrame_LocalsToFast() before MAKE_CELL has run). - PyObject *initial = GETLOCAL(oparg); - PyObject *cell = PyCell_New(initial); - if (cell == NULL) { - goto resume_with_error; + match = NULL; + rest = NULL; + 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; + assert((match == NULL) == (rest == NULL)); + if (match == NULL) goto pop_2_error; + if (!Py_IsNone(match)) { + PyErr_SetHandledException(match); } - SETLOCAL(oparg, cell); + stack_pointer[-2] = rest; + stack_pointer[-1] = match; DISPATCH(); } - TARGET(DELETE_DEREF) { - PyObject *cell = GETLOCAL(oparg); - PyObject *oldobj = PyCell_GET(cell); - // Can't use ERROR_IF here. - // Fortunately we don't need its superpower. - if (oldobj == NULL) { - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - goto error; + TARGET(CHECK_EXC_MATCH) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CHECK_EXC_MATCH); + PyObject *right; + PyObject *left; + PyObject *b; + right = stack_pointer[-1]; + left = stack_pointer[-2]; + assert(PyExceptionInstance_Check(left)); + if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { + Py_DECREF(right); + if (true) goto pop_1_error; } - PyCell_SET(cell, NULL); - Py_DECREF(oldobj); + int res = PyErr_GivenExceptionMatches(left, right); + Py_DECREF(right); + b = res ? Py_True : Py_False; + stack_pointer[-1] = b; DISPATCH(); } - TARGET(LOAD_FROM_DICT_OR_DEREF) { - PyObject *class_dict; + TARGET(CLEANUP_THROW) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CLEANUP_THROW); + PyObject *exc_value; + PyObject *last_sent_val; + PyObject *sub_iter; + PyObject *none; PyObject *value; - class_dict = stack_pointer[-1]; - PyObject *name; - assert(class_dict); - assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); - name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); - if (PyMapping_GetOptionalItem(class_dict, name, &value) < 0) { - Py_DECREF(class_dict); - goto error; + exc_value = stack_pointer[-1]; + last_sent_val = stack_pointer[-2]; + sub_iter = stack_pointer[-3]; + TIER_ONE_ONLY + assert(throwflag); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); + Py_DECREF(sub_iter); + Py_DECREF(last_sent_val); + Py_DECREF(exc_value); + none = Py_None; } - Py_DECREF(class_dict); - if (!value) { - PyObject *cell = GETLOCAL(oparg); - value = PyCell_GET(cell); - if (value == NULL) { - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - goto error; - } - Py_INCREF(value); + else { + _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); + monitor_reraise(tstate, frame, this_instr); + goto exception_unwind; } - stack_pointer[-1] = value; + stack_pointer[-3] = none; + stack_pointer[-2] = value; + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_DEREF) { - PyObject *value; - PyObject *cell = GETLOCAL(oparg); - value = PyCell_GET(cell); - if (value == NULL) { - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); - if (true) goto error; + TARGET(COMPARE_OP) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(COMPARE_OP); + PREDICTED(COMPARE_OP); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *right; + PyObject *left; + PyObject *res; + // _SPECIALIZE_COMPARE_OP + right = stack_pointer[-1]; + left = stack_pointer[-2]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_CompareOp(left, right, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(COMPARE_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - Py_INCREF(value); - STACK_GROW(1); - stack_pointer[-1] = value; + // _COMPARE_OP + { + assert((oparg >> 5) <= Py_GE); + res = PyObject_RichCompare(left, right, oparg >> 5); + Py_DECREF(left); + Py_DECREF(right); + if (res == NULL) goto pop_2_error; + if (oparg & 16) { + int res_bool = PyObject_IsTrue(res); + Py_DECREF(res); + if (res_bool < 0) goto pop_2_error; + res = res_bool ? Py_True : Py_False; + } + } + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(STORE_DEREF) { - PyObject *v; - v = stack_pointer[-1]; - PyObject *cell = GETLOCAL(oparg); - PyObject *oldobj = PyCell_GET(cell); - PyCell_SET(cell, v); - Py_XDECREF(oldobj); - STACK_SHRINK(1); + TARGET(COMPARE_OP_FLOAT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(COMPARE_OP_FLOAT); + static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); + 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); + double dleft = PyFloat_AS_DOUBLE(left); + double dright = PyFloat_AS_DOUBLE(right); + // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg + int sign_ish = COMPARISON_BIT(dleft, dright); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + res = (sign_ish & oparg) ? Py_True : Py_False; + // It's always a bool, so we don't care about oparg & 16. + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(COPY_FREE_VARS) { - /* Copy closure variables to free variables */ - PyCodeObject *co = _PyFrame_GetCode(frame); - assert(PyFunction_Check(frame->f_funcobj)); - PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; - assert(oparg == co->co_nfreevars); - int offset = co->co_nlocalsplus - oparg; - for (int i = 0; i < oparg; ++i) { - PyObject *o = PyTuple_GET_ITEM(closure, i); - frame->localsplus[offset + i] = Py_NewRef(o); - } + TARGET(COMPARE_OP_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(COMPARE_OP_INT); + static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); + 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); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 && + _PyLong_DigitCount((PyLongObject *)right) <= 1); + Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left); + Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right); + // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg + int sign_ish = COMPARISON_BIT(ileft, iright); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + res = (sign_ish & oparg) ? Py_True : Py_False; + // It's always a bool, so we don't care about oparg & 16. + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(BUILD_STRING) { - 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]); - } - if (str == NULL) { STACK_SHRINK(oparg); goto error; } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = str; + TARGET(COMPARE_OP_STR) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(COMPARE_OP_STR); + static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); + 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); + int eq = _PyUnicode_Equal(left, right); + assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + assert(eq == 0 || eq == 1); + assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); + assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); + res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; + // It's always a bool, so we don't care about oparg & 16. + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(BUILD_TUPLE) { - PyObject **values; - PyObject *tup; - values = stack_pointer - oparg; - tup = _PyTuple_FromArraySteal(values, oparg); - if (tup == NULL) { STACK_SHRINK(oparg); goto error; } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = tup; + TARGET(CONTAINS_OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CONTAINS_OP); + 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); + if (res < 0) goto pop_2_error; + b = (res ^ oparg) ? Py_True : Py_False; + stack_pointer[-2] = b; + stack_pointer += -1; DISPATCH(); } - TARGET(BUILD_LIST) { - PyObject **values; - PyObject *list; - values = stack_pointer - oparg; - list = _PyList_FromArraySteal(values, oparg); - if (list == NULL) { STACK_SHRINK(oparg); goto error; } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = list; + TARGET(CONVERT_VALUE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(CONVERT_VALUE); + 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]; + result = conv_fn(value); + Py_DECREF(value); + if (result == NULL) goto pop_1_error; + stack_pointer[-1] = result; DISPATCH(); } - TARGET(LIST_EXTEND) { - 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) && - (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) - { - _PyErr_Clear(tstate); - _PyErr_Format(tstate, PyExc_TypeError, - "Value after * must be an iterable, not %.200s", - Py_TYPE(iterable)->tp_name); - } - Py_DECREF(iterable); - if (true) goto pop_1_error; + TARGET(COPY) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(COPY); + PyObject *bottom; + PyObject *top; + bottom = stack_pointer[-1 - (oparg-1)]; + assert(oparg > 0); + top = Py_NewRef(bottom); + stack_pointer[0] = top; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(COPY_FREE_VARS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(COPY_FREE_VARS); + /* Copy closure variables to free variables */ + PyCodeObject *co = _PyFrame_GetCode(frame); + assert(PyFunction_Check(frame->f_funcobj)); + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + assert(oparg == co->co_nfreevars); + int offset = co->co_nlocalsplus - oparg; + for (int i = 0; i < oparg; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); } - assert(Py_IsNone(none_val)); - Py_DECREF(iterable); - STACK_SHRINK(1); DISPATCH(); } - TARGET(SET_UPDATE) { - 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; - STACK_SHRINK(1); + TARGET(DELETE_ATTR) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DELETE_ATTR); + PyObject *owner; + owner = stack_pointer[-1]; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + int err = PyObject_DelAttr(owner, name); + Py_DECREF(owner); + if (err) goto pop_1_error; + stack_pointer += -1; DISPATCH(); } - TARGET(BUILD_SET) { - PyObject **values; - PyObject *set; - values = stack_pointer - oparg; - set = PySet_New(NULL); - if (set == NULL) - goto error; - int err = 0; - for (int i = 0; i < oparg; i++) { - PyObject *item = values[i]; - if (err == 0) - err = PySet_Add(set, item); - Py_DECREF(item); - } - if (err != 0) { - Py_DECREF(set); - if (true) { STACK_SHRINK(oparg); goto error; } + TARGET(DELETE_DEREF) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DELETE_DEREF); + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + // Can't use ERROR_IF here. + // Fortunately we don't need its superpower. + if (oldobj == NULL) { + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + GOTO_ERROR(error); } - STACK_SHRINK(oparg); - STACK_GROW(1); - stack_pointer[-1] = set; + PyCell_SET(cell, NULL); + Py_DECREF(oldobj); DISPATCH(); } - TARGET(BUILD_MAP) { - PyObject **values; - PyObject *map; - values = stack_pointer - oparg*2; - map = _PyDict_FromItems( - values, 2, - values+1, 2, - oparg); - for (int _i = oparg*2; --_i >= 0;) { - Py_DECREF(values[_i]); - } - if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } - STACK_SHRINK(oparg*2); - STACK_GROW(1); - stack_pointer[-1] = map; + TARGET(DELETE_FAST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DELETE_FAST); + PyObject *v = GETLOCAL(oparg); + if (v == NULL) goto unbound_local_error; + SETLOCAL(oparg, NULL); DISPATCH(); } - TARGET(SETUP_ANNOTATIONS) { + TARGET(DELETE_GLOBAL) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DELETE_GLOBAL); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); int err; - PyObject *ann_dict; - if (LOCALS() == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when setting up annotations"); - if (true) goto error; - } - /* check if __annotations__ in locals()... */ - if (PyDict_CheckExact(LOCALS())) { - ann_dict = _PyDict_GetItemWithError(LOCALS(), - &_Py_ID(__annotations__)); - if (ann_dict == NULL) { - if (_PyErr_Occurred(tstate)) goto error; - /* ...if not, create a new one */ - ann_dict = PyDict_New(); - if (ann_dict == NULL) goto error; - err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - if (err) goto error; - } - } - else { - /* do the same if locals() is not a dict */ - if (PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict) < 0) goto error; - if (ann_dict == NULL) { - ann_dict = PyDict_New(); - if (ann_dict == NULL) goto error; - err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - if (err) goto error; - } - else { - Py_DECREF(ann_dict); + err = PyDict_DelItem(GLOBALS(), name); + // Can't use ERROR_IF here. + if (err != 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } + GOTO_ERROR(error); } DISPATCH(); } - TARGET(BUILD_CONST_KEY_MAP) { - 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, - "bad BUILD_CONST_KEY_MAP keys argument"); - goto error; // Pop the keys and values. + TARGET(DELETE_NAME) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DELETE_NAME); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); + GOTO_ERROR(error); } - map = _PyDict_FromItems( - &PyTuple_GET_ITEM(keys, 0), 1, - values, 1, oparg); - for (int _i = oparg; --_i >= 0;) { - Py_DECREF(values[_i]); + err = PyObject_DelItem(ns, name); + // Can't use ERROR_IF here. + if (err != 0) { + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); + GOTO_ERROR(error); } - Py_DECREF(keys); - if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } - STACK_SHRINK(oparg); - stack_pointer[-1] = map; DISPATCH(); } - TARGET(DICT_UPDATE) { + TARGET(DELETE_SUBSCR) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DELETE_SUBSCR); + PyObject *sub; + PyObject *container; + sub = stack_pointer[-1]; + container = stack_pointer[-2]; + /* del container[sub] */ + int err = PyObject_DelItem(container, sub); + Py_DECREF(container); + Py_DECREF(sub); + if (err) goto pop_2_error; + stack_pointer += -2; + DISPATCH(); + } + + TARGET(DICT_MERGE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DICT_MERGE); PyObject *update; PyObject *dict; + PyObject *callable; 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, - "'%.200s' object is not a mapping", - Py_TYPE(update)->tp_name); - } + callable = stack_pointer[-5 - (oparg - 1)]; + if (_PyDict_MergeEx(dict, update, 2) < 0) { + _PyEval_FormatKwargsError(tstate, callable, update); Py_DECREF(update); if (true) goto pop_1_error; } Py_DECREF(update); - STACK_SHRINK(1); + stack_pointer += -1; DISPATCH(); } - TARGET(DICT_MERGE) { + TARGET(DICT_UPDATE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(DICT_UPDATE); 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) { - _PyEval_FormatKwargsError(tstate, callable, update); + if (PyDict_Update(dict, update) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + Py_TYPE(update)->tp_name); + } Py_DECREF(update); if (true) goto pop_1_error; } Py_DECREF(update); - STACK_SHRINK(1); + stack_pointer += -1; DISPATCH(); } - TARGET(MAP_ADD) { + TARGET(END_ASYNC_FOR) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(END_ASYNC_FOR); + PyObject *exc; + PyObject *awaitable; + exc = stack_pointer[-1]; + awaitable = stack_pointer[-2]; + TIER_ONE_ONLY + assert(exc && PyExceptionInstance_Check(exc)); + if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { + Py_DECREF(awaitable); + Py_DECREF(exc); + } + else { + Py_INCREF(exc); + _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, this_instr); + goto exception_unwind; + } + stack_pointer += -2; + DISPATCH(); + } + + TARGET(END_FOR) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(END_FOR); PyObject *value; - PyObject *key; - PyObject *dict; + // _POP_TOP 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 - if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; - STACK_SHRINK(2); + { + Py_DECREF(value); + } + // _POP_TOP + value = stack_pointer[-2]; + { + Py_DECREF(value); + } + stack_pointer += -2; DISPATCH(); } - TARGET(INSTRUMENTED_LOAD_SUPER_ATTR) { - _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; - // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we - // don't want to specialize instrumented instructions - INCREMENT_ADAPTIVE_COUNTER(cache->counter); - GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); + TARGET(END_SEND) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(END_SEND); + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; + Py_DECREF(receiver); + stack_pointer[-2] = value; + stack_pointer += -1; + DISPATCH(); } - TARGET(LOAD_SUPER_ATTR) { - PREDICTED(LOAD_SUPER_ATTR); - static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size"); - 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 - _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method); - DISPATCH_SAME_OPARG(); - } - STAT_INC(LOAD_SUPER_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - - if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { - PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; - int err = _Py_call_instrumentation_2args( - tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr-1, global_super, arg); - if (err) goto pop_3_error; + TARGET(ENTER_EXECUTOR) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(ENTER_EXECUTOR); + TIER_ONE_ONLY + CHECK_EVAL_BREAKER(); + PyCodeObject *code = _PyFrame_GetCode(frame); + _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; + Py_INCREF(executor); + if (executor->execute == _PyUOpExecute) { + current_executor = (_PyUOpExecutorObject *)executor; + GOTO_TIER_TWO(); } - - // we make no attempt to optimize here; specializations should - // handle any case whose performance we care about - PyObject *stack[] = {class, self}; - PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); - if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { - PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; - if (super == NULL) { - _Py_call_instrumentation_exc2( - tstate, PY_MONITORING_EVENT_C_RAISE, - frame, next_instr-1, global_super, arg); - } - else { - int err = _Py_call_instrumentation_2args( - tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, global_super, arg); - if (err < 0) { - Py_CLEAR(super); - } - } + next_instr = executor->execute(executor, frame, stack_pointer); + frame = tstate->current_frame; + if (next_instr == NULL) { + goto resume_with_error; } - Py_DECREF(global_super); - Py_DECREF(class); - Py_DECREF(self); - if (super == NULL) goto pop_3_error; - attr = PyObject_GetAttr(super, name); - Py_DECREF(super); - if (attr == NULL) goto pop_3_error; - null = NULL; - STACK_SHRINK(2); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } - next_instr += 1; + stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } - TARGET(LOAD_SUPER_ATTR_ATTR) { - 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); - attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); - Py_DECREF(global_super); - Py_DECREF(class); - Py_DECREF(self); - if (attr == NULL) goto pop_3_error; - STACK_SHRINK(2); - stack_pointer[-1] = attr; + TARGET(EXIT_INIT_CHECK) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(EXIT_INIT_CHECK); + PyObject *should_be_none; + should_be_none = stack_pointer[-1]; + assert(STACK_LEVEL() == 2); + if (should_be_none != Py_None) { + PyErr_Format(PyExc_TypeError, + "__init__() should return None, not '%.200s'", + Py_TYPE(should_be_none)->tp_name); + GOTO_ERROR(error); + } + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_SUPER_ATTR_METHOD) { - 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); - STAT_INC(LOAD_SUPER_ATTR, hit); - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); - PyTypeObject *cls = (PyTypeObject *)class; - int method_found = 0; - attr = _PySuper_Lookup(cls, self, name, - Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); - Py_DECREF(global_super); - Py_DECREF(class); - if (attr == NULL) { - Py_DECREF(self); - if (true) goto pop_3_error; + TARGET(EXTENDED_ARG) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(EXTENDED_ARG); + TIER_ONE_ONLY + assert(oparg); + opcode = next_instr->op.code; + oparg = oparg << 8 | next_instr->op.arg; + PRE_DISPATCH_GOTO(); + DISPATCH_GOTO(); + } + + TARGET(FORMAT_SIMPLE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(FORMAT_SIMPLE); + 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)) { + res = PyObject_Format(value, NULL); + Py_DECREF(value); + if (res == NULL) goto pop_1_error; } - if (method_found) { - self_or_null = self; // transfer ownership - } else { - Py_DECREF(self); - self_or_null = NULL; + else { + res = value; } - STACK_SHRINK(1); - stack_pointer[-2] = attr; - stack_pointer[-1] = self_or_null; + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(FORMAT_WITH_SPEC) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(FORMAT_WITH_SPEC); + 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); + if (res == NULL) goto pop_2_error; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(LOAD_ATTR) { - PREDICTED(LOAD_ATTR); - static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); - 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)) { - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - next_instr--; - _Py_Specialize_LoadAttr(owner, next_instr, name); - DISPATCH_SAME_OPARG(); + TARGET(FOR_ITER) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(FOR_ITER); + PREDICTED(FOR_ITER); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *iter; + PyObject *next; + // _SPECIALIZE_FOR_ITER + iter = stack_pointer[-1]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_ForIter(iter, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(FOR_ITER, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - STAT_INC(LOAD_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); - if (oparg & 1) { - /* Designed to work in tandem with CALL, pushes two values. */ - 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(attr != NULL); // No errors on this branch - self_or_null = owner; // Transfer ownership + // _FOR_ITER + { + /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ + next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next == NULL) { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + GOTO_ERROR(error); + } + monitor_raise(tstate, frame, this_instr); + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(oparg + 1); + DISPATCH(); } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - CALL that it's not a method call. + // Common case: no jump, leave it to the code generator + } + stack_pointer[0] = next; + stack_pointer += 1; + DISPATCH(); + } - NULL | meth | arg1 | ... | argN - */ - Py_DECREF(owner); - if (attr == NULL) goto pop_1_error; - self_or_null = NULL; + TARGET(FOR_ITER_GEN) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(FOR_ITER_GEN); + static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); + 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; + _PyFrame_StackPush(gen_frame, Py_None); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + assert(next_instr - this_instr + oparg <= UINT16_MAX); + frame->return_offset = (uint16_t)(next_instr - this_instr + oparg); + DISPATCH_INLINED(gen_frame); + } + + TARGET(FOR_ITER_LIST) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(FOR_ITER_LIST); + static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); + PyObject *iter; + PyObject *next; + /* Skip 1 cache entry */ + // _ITER_CHECK_LIST + iter = stack_pointer[-1]; + { + DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); + } + // _ITER_JUMP_LIST + { + _PyListIterObject *it = (_PyListIterObject *)iter; + assert(Py_TYPE(iter) == &PyListIter_Type); + STAT_INC(FOR_ITER, hit); + PyListObject *seq = it->it_seq; + if (seq == NULL || it->it_index >= PyList_GET_SIZE(seq)) { + if (seq != NULL) { + it->it_seq = NULL; + Py_DECREF(seq); + } + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(oparg + 1); + DISPATCH(); } } - else { - /* Classic, pushes one value. */ - attr = PyObject_GetAttr(owner, name); - Py_DECREF(owner); - if (attr == NULL) goto pop_1_error; + // _ITER_NEXT_LIST + { + _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++)); } - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = self_or_null; } - next_instr += 9; + stack_pointer[0] = next; + stack_pointer += 1; DISPATCH(); } - TARGET(LOAD_ATTR_INSTANCE_VALUE) { - PyObject *owner; - PyObject *attr; - PyObject *null = NULL; - // _GUARD_TYPE_VERSION - owner = stack_pointer[-1]; + TARGET(FOR_ITER_RANGE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(FOR_ITER_RANGE); + static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); + PyObject *iter; + PyObject *next; + /* Skip 1 cache entry */ + // _ITER_CHECK_RANGE + iter = 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); + _PyRangeIterObject *r = (_PyRangeIterObject *)iter; + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); } - // _CHECK_MANAGED_OBJECT_HAS_VALUES + // _ITER_JUMP_RANGE { - 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) && - !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), - LOAD_ATTR); + _PyRangeIterObject *r = (_PyRangeIterObject *)iter; + assert(Py_TYPE(r) == &PyRangeIter_Type); + STAT_INC(FOR_ITER, hit); + if (r->len <= 0) { + STACK_SHRINK(1); + Py_DECREF(r); + // Jump over END_FOR instruction. + JUMPBY(oparg + 1); + DISPATCH(); + } } - // _LOAD_ATTR_INSTANCE_VALUE + // _ITER_NEXT_RANGE { - uint16_t index = read_u16(&next_instr[3].cache); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - attr = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(attr == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(attr); - null = NULL; - Py_DECREF(owner); + _PyRangeIterObject *r = (_PyRangeIterObject *)iter; + assert(Py_TYPE(r) == &PyRangeIter_Type); + assert(r->len > 0); + long value = r->start; + r->start = value + r->step; + r->len--; + next = PyLong_FromLong(value); + if (next == NULL) goto error; } - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } - next_instr += 9; + stack_pointer[0] = next; + stack_pointer += 1; DISPATCH(); } - TARGET(LOAD_ATTR_MODULE) { - PyObject *owner; - PyObject *attr; - PyObject *null = NULL; - owner = stack_pointer[-1]; - 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; - 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 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } - next_instr += 9; + TARGET(FOR_ITER_TUPLE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(FOR_ITER_TUPLE); + static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); + PyObject *iter; + PyObject *next; + /* Skip 1 cache entry */ + // _ITER_CHECK_TUPLE + iter = stack_pointer[-1]; + { + DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER); + } + // _ITER_JUMP_TUPLE + { + _PyTupleIterObject *it = (_PyTupleIterObject *)iter; + assert(Py_TYPE(iter) == &PyTupleIter_Type); + STAT_INC(FOR_ITER, hit); + PyTupleObject *seq = it->it_seq; + if (seq == NULL || it->it_index >= PyTuple_GET_SIZE(seq)) { + if (seq != NULL) { + it->it_seq = NULL; + Py_DECREF(seq); + } + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(oparg + 1); + DISPATCH(); + } + } + // _ITER_NEXT_TUPLE + { + _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++)); + } + stack_pointer[0] = next; + stack_pointer += 1; DISPATCH(); } - TARGET(LOAD_ATTR_WITH_HINT) { - PyObject *owner; - PyObject *attr; - PyObject *null = NULL; - owner = stack_pointer[-1]; - 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); - attr = ep->me_value; + TARGET(GET_AITER) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(GET_AITER); + PyObject *obj; + PyObject *iter; + obj = stack_pointer[-1]; + unaryfunc getter = NULL; + PyTypeObject *type = Py_TYPE(obj); + if (type->tp_as_async != NULL) { + getter = type->tp_as_async->am_aiter; } - else { - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - attr = ep->me_value; + if (getter == NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + Py_DECREF(obj); + if (true) goto pop_1_error; } - 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 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } - next_instr += 9; + iter = (*getter)(obj); + Py_DECREF(obj); + if (iter == NULL) goto pop_1_error; + if (Py_TYPE(iter)->tp_as_async == NULL || + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); + Py_DECREF(iter); + if (true) goto pop_1_error; + } + stack_pointer[-1] = iter; DISPATCH(); } - TARGET(LOAD_ATTR_SLOT) { - 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); + TARGET(GET_ANEXT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(GET_ANEXT); + PyObject *aiter; + PyObject *awaitable; + aiter = stack_pointer[-1]; + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyTypeObject *type = Py_TYPE(aiter); + if (PyAsyncGen_CheckExact(aiter)) { + awaitable = type->tp_as_async->am_anext(aiter); + if (awaitable == NULL) { + GOTO_ERROR(error); + } + } else { + if (type->tp_as_async != NULL){ + getter = type->tp_as_async->am_anext; + } + if (getter != NULL) { + next_iter = (*getter)(aiter); + if (next_iter == NULL) { + GOTO_ERROR(error); + } + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); + GOTO_ERROR(error); + } + awaitable = _PyCoro_GetAwaitableIter(next_iter); + if (awaitable == NULL) { + _PyErr_FormatFromCause( + PyExc_TypeError, + "'async for' received an invalid object " + "from __anext__: %.100s", + Py_TYPE(next_iter)->tp_name); + Py_DECREF(next_iter); + GOTO_ERROR(error); + } else { + Py_DECREF(next_iter); + } } - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1 - (oparg & 1 ? 1 : 0)] = attr; - if (oparg & 1) { stack_pointer[-(oparg & 1 ? 1 : 0)] = null; } - next_instr += 9; + stack_pointer[0] = awaitable; + stack_pointer += 1; DISPATCH(); } - TARGET(LOAD_ATTR_CLASS) { - PyObject *owner; - PyObject *attr; - PyObject *null = NULL; - owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - - DEOPT_IF(!PyType_Check(owner), LOAD_ATTR); - DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, - LOAD_ATTR); - assert(type_version != 0); - - STAT_INC(LOAD_ATTR, hit); - null = NULL; - attr = descr; - assert(attr != NULL); - Py_INCREF(attr); - 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; } - next_instr += 9; + TARGET(GET_AWAITABLE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(GET_AWAITABLE); + PyObject *iterable; + PyObject *iter; + iterable = stack_pointer[-1]; + iter = _PyCoro_GetAwaitableIter(iterable); + if (iter == NULL) { + _PyEval_FormatAwaitableError(tstate, Py_TYPE(iterable), oparg); + } + Py_DECREF(iterable); + if (iter != NULL && PyCoro_CheckExact(iter)) { + PyObject *yf = _PyGen_yf((PyGenObject*)iter); + if (yf != NULL) { + /* `iter` is a coroutine object that is being + awaited, `yf` is a pointer to the current awaitable + being awaited on. */ + Py_DECREF(yf); + Py_CLEAR(iter); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); + /* The code below jumps to `error` if `iter` is NULL. */ + } + } + if (iter == NULL) goto pop_1_error; + stack_pointer[-1] = iter; DISPATCH(); } - TARGET(LOAD_ATTR_PROPERTY) { - 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); - DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); - 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); - PyCodeObject *code = (PyCodeObject *)f->func_code; - assert(code->co_argcount == 1); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(fget); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); - // Manipulate stack directly because we exit with DISPATCH_INLINED(). - STACK_SHRINK(1); - new_frame->localsplus[0] = owner; - SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); + TARGET(GET_ITER) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(GET_ITER); + PyObject *iterable; + PyObject *iter; + iterable = stack_pointer[-1]; + /* before: [obj]; after [getiter(obj)] */ + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + if (iter == NULL) goto pop_1_error; + stack_pointer[-1] = iter; + DISPATCH(); } - TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { - 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); - 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); - PyCodeObject *code = (PyCodeObject *)f->func_code; - assert(code->co_argcount == 2); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - - PyObject *name = GETITEM(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(). - STACK_SHRINK(1); - new_frame->localsplus[0] = owner; - new_frame->localsplus[1] = Py_NewRef(name); - SKIP_OVER(INLINE_CACHE_ENTRIES_LOAD_ATTR); - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); + TARGET(GET_LEN) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(GET_LEN); + 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; + len_o = PyLong_FromSsize_t(len_i); + if (len_o == NULL) goto error; + stack_pointer[0] = len_o; + stack_pointer += 1; + DISPATCH(); } - TARGET(STORE_ATTR_INSTANCE_VALUE) { - PyObject *owner; - PyObject *value; - // _GUARD_TYPE_VERSION_STORE - 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); - } - // _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); + TARGET(GET_YIELD_FROM_ITER) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(GET_YIELD_FROM_ITER); + PyObject *iterable; + PyObject *iter; + iterable = stack_pointer[-1]; + /* before: [obj]; after [getiter(obj)] */ + if (PyCoro_CheckExact(iterable)) { + /* `iterable` is a coroutine */ + if (!(_PyFrame_GetCode(frame)->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { + /* and it is used in a 'yield from' expression of a + regular generator. */ + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); + GOTO_ERROR(error); } - Py_DECREF(owner); + iter = iterable; } - STACK_SHRINK(2); - next_instr += 4; - DISPATCH(); - } - - TARGET(STORE_ATTR_WITH_HINT) { - 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); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); - PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); - DEOPT_IF(dict == NULL, STORE_ATTR); - assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); - PyObject *old_value; - uint64_t new_version; - if (DK_IS_UNICODE(dict->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); - old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); - new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); - ep->me_value = value; + else if (PyGen_CheckExact(iterable)) { + iter = iterable; } else { - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); - old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); - new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); - ep->me_value = value; - } - Py_DECREF(old_value); - STAT_INC(STORE_ATTR, hit); - /* Ensure dict is GC tracked if it needs to be */ - if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { - _PyObject_GC_TRACK(dict); + /* `iterable` is not a generator. */ + iter = PyObject_GetIter(iterable); + if (iter == NULL) { + GOTO_ERROR(error); + } + Py_DECREF(iterable); } - /* PEP 509 */ - dict->ma_version_tag = new_version; - Py_DECREF(owner); - STACK_SHRINK(2); - next_instr += 4; + stack_pointer[-1] = iter; DISPATCH(); } - TARGET(STORE_ATTR_SLOT) { - PyObject *owner; - PyObject *value; - // _GUARD_TYPE_VERSION_STORE - 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; + TARGET(IMPORT_FROM) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(IMPORT_FROM); + PyObject *from; + PyObject *res; + from = stack_pointer[-1]; + TIER_ONE_ONLY + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + res = import_from(tstate, from, name); + if (res == NULL) goto error; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } - TARGET(COMPARE_OP) { - PREDICTED(COMPARE_OP); - static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); - PyObject *right; - PyObject *left; + TARGET(IMPORT_NAME) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(IMPORT_NAME); + PyObject *fromlist; + PyObject *level; 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)) { - next_instr--; - _Py_Specialize_CompareOp(left, right, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - STAT_INC(COMPARE_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - assert((oparg >> 5) <= Py_GE); - res = PyObject_RichCompare(left, right, oparg >> 5); - Py_DECREF(left); - Py_DECREF(right); + fromlist = stack_pointer[-1]; + level = stack_pointer[-2]; + TIER_ONE_ONLY + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + res = import_name(tstate, frame, name, fromlist, level); + Py_DECREF(level); + Py_DECREF(fromlist); if (res == NULL) goto pop_2_error; - if (oparg & 16) { - int res_bool = PyObject_IsTrue(res); - Py_DECREF(res); - if (res_bool < 0) goto pop_2_error; - res = res_bool ? Py_True : Py_False; - } - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 1; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } - TARGET(COMPARE_OP_FLOAT) { - 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); - double dleft = PyFloat_AS_DOUBLE(left); - double dright = PyFloat_AS_DOUBLE(right); - // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg - int sign_ish = COMPARISON_BIT(dleft, dright); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - res = (sign_ish & oparg) ? Py_True : Py_False; - // It's always a bool, so we don't care about oparg & 16. - STACK_SHRINK(1); - stack_pointer[-1] = res; + TARGET(INSTRUMENTED_CALL) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(INSTRUMENTED_CALL); + int is_meth = PEEK(oparg + 1) != NULL; + int total_args = oparg + is_meth; + PyObject *function = PEEK(oparg + 2); + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : PEEK(total_args); + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, this_instr, function, arg); + if (err) goto error; + INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + GO_TO_INSTRUCTION(CALL); + } + + TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { + frame->instr_ptr = next_instr; next_instr += 1; - DISPATCH(); + INSTRUCTION_STATS(INSTRUMENTED_CALL_FUNCTION_EX); + GO_TO_INSTRUCTION(CALL_FUNCTION_EX); } - TARGET(COMPARE_OP_INT) { - 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); - DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP); - STAT_INC(COMPARE_OP, hit); - assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 && - _PyLong_DigitCount((PyLongObject *)right) <= 1); - Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left); - Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right); - // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg - int sign_ish = COMPARISON_BIT(ileft, iright); - _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); - res = (sign_ish & oparg) ? Py_True : Py_False; - // It's always a bool, so we don't care about oparg & 16. - STACK_SHRINK(1); - stack_pointer[-1] = res; + TARGET(INSTRUMENTED_CALL_KW) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 1; - DISPATCH(); + INSTRUCTION_STATS(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, this_instr, function, arg); + if (err) goto error; + GO_TO_INSTRUCTION(CALL_KW); } - TARGET(COMPARE_OP_STR) { - 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); - int eq = _PyUnicode_Equal(left, right); - assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE); - _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - assert(eq == 0 || eq == 1); - assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); - assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); - res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; - // It's always a bool, so we don't care about oparg & 16. - STACK_SHRINK(1); - stack_pointer[-1] = res; + TARGET(INSTRUMENTED_END_FOR) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_END_FOR); + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; + TIER_ONE_ONLY + /* Need to create a fake StopIteration error here, + * to conform to PEP 380 */ + if (PyGen_Check(receiver)) { + PyErr_SetObject(PyExc_StopIteration, value); + if (monitor_stop_iteration(tstate, frame, this_instr)) { + GOTO_ERROR(error); + } + PyErr_SetRaisedException(NULL); + } + Py_DECREF(receiver); + Py_DECREF(value); + stack_pointer += -2; DISPATCH(); } - TARGET(IS_OP) { - 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); - b = res ? Py_True : Py_False; - STACK_SHRINK(1); - stack_pointer[-1] = b; - DISPATCH(); - } - - TARGET(CONTAINS_OP) { - 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); - if (res < 0) goto pop_2_error; - b = (res ^ oparg) ? Py_True : Py_False; - STACK_SHRINK(1); - stack_pointer[-1] = b; + TARGET(INSTRUMENTED_END_SEND) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_END_SEND); + PyObject *value; + PyObject *receiver; + value = stack_pointer[-1]; + receiver = stack_pointer[-2]; + TIER_ONE_ONLY + if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) { + PyErr_SetObject(PyExc_StopIteration, value); + if (monitor_stop_iteration(tstate, frame, this_instr)) { + GOTO_ERROR(error); + } + PyErr_SetRaisedException(NULL); + } + Py_DECREF(receiver); + stack_pointer[-2] = value; + stack_pointer += -1; DISPATCH(); } - TARGET(CHECK_EG_MATCH) { - PyObject *match_type; - PyObject *exc_value; - PyObject *rest; - PyObject *match; - 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; + TARGET(INSTRUMENTED_FOR_ITER) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_FOR_ITER); + _Py_CODEUNIT *target; + PyObject *iter = TOP(); + PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next != NULL) { + PUSH(next); + target = next_instr; } - - match = NULL; - rest = NULL; - 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; - - assert((match == NULL) == (rest == NULL)); - if (match == NULL) goto pop_2_error; - - if (!Py_IsNone(match)) { - PyErr_SetHandledException(match); + else { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + GOTO_ERROR(error); + } + monitor_raise(tstate, frame, this_instr); + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + STACK_SHRINK(1); + Py_DECREF(iter); + /* Skip END_FOR */ + target = next_instr + oparg + 1; } - stack_pointer[-2] = rest; - stack_pointer[-1] = match; + INSTRUMENTED_JUMP(this_instr, target, PY_MONITORING_EVENT_BRANCH); DISPATCH(); } - TARGET(CHECK_EXC_MATCH) { - PyObject *right; - PyObject *left; - PyObject *b; - right = stack_pointer[-1]; - left = stack_pointer[-2]; - assert(PyExceptionInstance_Check(left)); - if (_PyEval_CheckExceptTypeValid(tstate, right) < 0) { - Py_DECREF(right); - if (true) goto pop_1_error; + TARGET(INSTRUMENTED_INSTRUCTION) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_INSTRUCTION); + int next_opcode = _Py_call_instrumentation_instruction( + tstate, frame, this_instr); + if (next_opcode < 0) goto error; + next_instr = this_instr; + if (_PyOpcode_Caches[next_opcode]) { + INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); } - - int res = PyErr_GivenExceptionMatches(left, right); - Py_DECREF(right); - b = res ? Py_True : Py_False; - stack_pointer[-1] = b; - DISPATCH(); + assert(next_opcode > 0 && next_opcode < 256); + opcode = next_opcode; + DISPATCH_GOTO(); } - TARGET(IMPORT_NAME) { - 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); - Py_DECREF(fromlist); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); - stack_pointer[-1] = res; + TARGET(INSTRUMENTED_JUMP_BACKWARD) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_JUMP_BACKWARD); + CHECK_EVAL_BREAKER(); + INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP); DISPATCH(); } - TARGET(IMPORT_FROM) { - 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; - STACK_GROW(1); - stack_pointer[-1] = res; + TARGET(INSTRUMENTED_JUMP_FORWARD) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_JUMP_FORWARD); + INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP); DISPATCH(); } - TARGET(JUMP_FORWARD) { - JUMPBY(oparg); - DISPATCH(); + TARGET(INSTRUMENTED_LOAD_SUPER_ATTR) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_ATTR); + // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we + // don't want to specialize instrumented instructions + INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); } - TARGET(JUMP_BACKWARD) { - CHECK_EVAL_BREAKER(); - _Py_CODEUNIT *here = next_instr - 1; - assert(oparg <= INSTR_OFFSET()); - JUMPBY(1-oparg); + TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_FALSE); + PyObject *cond = POP(); + assert(PyBool_Check(cond)); + int flag = Py_IsFalse(cond); + int offset = flag * oparg; #if ENABLE_SPECIALIZATION - here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); - if (here[1].cache > tstate->interp->optimizer_backedge_threshold && - // Double-check that the opcode isn't instrumented or something: - here->op.code == JUMP_BACKWARD) - { - OBJECT_STAT_INC(optimization_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; - } - here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); - } - #endif /* ENABLE_SPECIALIZATION */ + this_instr[1].cache = (this_instr[1].cache << 1) | flag; + #endif + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); DISPATCH(); } - TARGET(ENTER_EXECUTOR) { - CHECK_EVAL_BREAKER(); - - PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = (_PyExecutorObject *)code->co_executors->executors[oparg&255]; - int original_oparg = executor->vm_data.oparg | (oparg & 0xfffff00); - JUMPBY(1-original_oparg); - frame->prev_instr = next_instr - 1; - Py_INCREF(executor); - frame = executor->execute(executor, frame, stack_pointer); - if (frame == NULL) { - frame = tstate->current_frame; - goto resume_with_error; + TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NONE); + PyObject *value = POP(); + int flag = Py_IsNone(value); + int offset; + if (flag) { + offset = oparg; } - goto resume_frame; + else { + Py_DECREF(value); + offset = 0; + } + #if ENABLE_SPECIALIZATION + this_instr[1].cache = (this_instr[1].cache << 1) | flag; + #endif + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + DISPATCH(); } - TARGET(POP_JUMP_IF_FALSE) { - PyObject *cond; - cond = stack_pointer[-1]; - assert(PyBool_Check(cond)); - int flag = Py_IsFalse(cond); + TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NOT_NONE); + PyObject *value = POP(); + int offset; + 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) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | !nflag; #endif - JUMPBY(oparg * flag); - STACK_SHRINK(1); - next_instr += 1; + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); DISPATCH(); } - TARGET(POP_JUMP_IF_TRUE) { - PyObject *cond; - cond = stack_pointer[-1]; + TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_TRUE); + PyObject *cond = POP(); assert(PyBool_Check(cond)); int flag = Py_IsTrue(cond); + int offset = flag * oparg; #if ENABLE_SPECIALIZATION - next_instr->cache = (next_instr->cache << 1) | flag; + this_instr[1].cache = (this_instr[1].cache << 1) | flag; #endif - JUMPBY(oparg * flag); - STACK_SHRINK(1); - next_instr += 1; + INSTRUMENTED_JUMP(this_instr, next_instr + offset, PY_MONITORING_EVENT_BRANCH); DISPATCH(); } - TARGET(POP_JUMP_IF_NONE) { - PyObject *value; - PyObject *b; - PyObject *cond; - // _IS_NONE - value = stack_pointer[-1]; - { - if (Py_IsNone(value)) { - b = Py_True; - } - else { - b = Py_False; - Py_DECREF(value); + TARGET(INSTRUMENTED_RESUME) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_RESUME); + 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(error); } + next_instr = this_instr; } - // POP_JUMP_IF_TRUE - cond = b; - { - assert(PyBool_Check(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 *value; - PyObject *b; - PyObject *cond; - // _IS_NONE - value = stack_pointer[-1]; - { - if (Py_IsNone(value)) { - b = Py_True; + else { + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { + CHECK_EVAL_BREAKER(); } - else { - b = Py_False; - Py_DECREF(value); + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = _Py_call_instrumentation( + tstate, oparg > 0, frame, this_instr); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (err) goto error; + if (frame->instr_ptr != this_instr) { + /* Instrumentation has jumped */ + next_instr = this_instr; + DISPATCH(); } } - // POP_JUMP_IF_FALSE - cond = b; - { - assert(PyBool_Check(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(JUMP_BACKWARD_NO_INTERRUPT) { - /* This bytecode is used in the `yield from` or `await` loop. - * If there is an interrupt, we want it handled in the innermost - * generator or coroutine, so we deliberately do not check it here. - * (see bpo-30039). - */ - JUMPBY(-oparg); - DISPATCH(); + TARGET(INSTRUMENTED_RETURN_CONST) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_RETURN_CONST); + PyObject *retval = GETITEM(FRAME_CO_CONSTS, oparg); + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_RETURN, + frame, this_instr, retval); + if (err) GOTO_ERROR(error); + 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 = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + _PyFrame_StackPush(frame, retval); + LOAD_IP(frame->return_offset); + goto resume_frame; } - TARGET(GET_LEN) { - 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; - len_o = PyLong_FromSsize_t(len_i); - if (len_o == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = len_o; - DISPATCH(); + TARGET(INSTRUMENTED_RETURN_VALUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_RETURN_VALUE); + PyObject *retval; + retval = stack_pointer[-1]; + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_RETURN, + frame, this_instr, retval); + if (err) GOTO_ERROR(error); + 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 = tstate->current_frame = dying->previous; + _PyEval_FrameClearAndPop(tstate, dying); + _PyFrame_StackPush(frame, retval); + LOAD_IP(frame->return_offset); + goto resume_frame; } - TARGET(MATCH_CLASS) { - 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 = _PyEval_MatchClass(tstate, subject, type, oparg, names); - Py_DECREF(subject); - Py_DECREF(type); - Py_DECREF(names); - if (attrs) { - assert(PyTuple_CheckExact(attrs)); // Success! - } - else { - if (_PyErr_Occurred(tstate)) goto pop_3_error; - attrs = Py_None; // Failure! - } - STACK_SHRINK(2); - stack_pointer[-1] = attrs; + TARGET(INSTRUMENTED_YIELD_VALUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INSTRUMENTED_YIELD_VALUE); + PyObject *retval; + retval = stack_pointer[-1]; + assert(frame != &entry_frame); + frame->instr_ptr = next_instr; + PyGenObject *gen = _PyFrame_GetGenerator(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + gen->gi_frame_state = FRAME_SUSPENDED + oparg; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_YIELD, + frame, this_instr, retval); + if (err) GOTO_ERROR(error); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + /* We don't know which of these is relevant here, so keep them equal */ + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + goto resume_frame; + } + + TARGET(INTERPRETER_EXIT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(INTERPRETER_EXIT); + PyObject *retval; + retval = stack_pointer[-1]; + assert(frame == &entry_frame); + assert(_PyFrame_IsIncomplete(frame)); + /* Restore previous frame and return. */ + tstate->current_frame = frame->previous; + assert(!_PyErr_Occurred(tstate)); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + return retval; + } + + TARGET(IS_OP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(IS_OP); + 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); + b = res ? Py_True : Py_False; + stack_pointer[-2] = b; + stack_pointer += -1; DISPATCH(); } - TARGET(MATCH_MAPPING) { - 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); - stack_pointer[-1] = res; + TARGET(JUMP_BACKWARD) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(JUMP_BACKWARD); + CHECK_EVAL_BREAKER(); + assert(oparg <= INSTR_OFFSET()); + JUMPBY(-oparg); + #if ENABLE_SPECIALIZATION + this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); + /* We are using unsigned values, but we really want signed values, so + * do the 2s complement comparison manually */ + uint16_t ucounter = this_instr[1].cache + (1 << 15); + uint16_t threshold = tstate->interp->optimizer_backedge_threshold + (1 << 15); + // Double-check that the opcode isn't instrumented or something: + if (ucounter > threshold && this_instr->op.code == JUMP_BACKWARD) { + OPT_STAT_INC(attempts); + int optimized = _PyOptimizer_BackEdge(frame, this_instr, next_instr, stack_pointer); + if (optimized < 0) goto error; + if (optimized) { + // Rewind and enter the executor: + assert(this_instr->op.code == ENTER_EXECUTOR); + next_instr = this_instr; + this_instr[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); + } + else { + int backoff = this_instr[1].cache & ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); + if (backoff < MINIMUM_TIER2_BACKOFF) { + backoff = MINIMUM_TIER2_BACKOFF; + } + else if (backoff < 15 - OPTIMIZER_BITS_IN_COUNTER) { + backoff++; + } + assert(backoff <= 15 - OPTIMIZER_BITS_IN_COUNTER); + this_instr[1].cache = ((1 << 16) - ((1 << OPTIMIZER_BITS_IN_COUNTER) << backoff)) | backoff; + } + } + #endif /* ENABLE_SPECIALIZATION */ DISPATCH(); } - TARGET(MATCH_SEQUENCE) { - 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); - stack_pointer[-1] = res; + TARGET(JUMP_BACKWARD_NO_INTERRUPT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(JUMP_BACKWARD_NO_INTERRUPT); + /* This bytecode is used in the `yield from` or `await` loop. + * If there is an interrupt, we want it handled in the innermost + * generator or coroutine, so we deliberately do not check it here. + * (see bpo-30039). + */ + JUMPBY(-oparg); DISPATCH(); } - TARGET(MATCH_KEYS) { - 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 = _PyEval_MatchKeys(tstate, subject, keys); - if (values_or_none == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = values_or_none; + TARGET(JUMP_FORWARD) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(JUMP_FORWARD); + JUMPBY(oparg); DISPATCH(); } - TARGET(GET_ITER) { - PyObject *iterable; - PyObject *iter; - iterable = stack_pointer[-1]; - /* before: [obj]; after [getiter(obj)] */ - iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - if (iter == NULL) goto pop_1_error; - stack_pointer[-1] = iter; + TARGET(LIST_APPEND) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LIST_APPEND); + 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_pointer += -1; DISPATCH(); } - TARGET(GET_YIELD_FROM_ITER) { + TARGET(LIST_EXTEND) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LIST_EXTEND); PyObject *iterable; - PyObject *iter; + PyObject *list; iterable = stack_pointer[-1]; - /* before: [obj]; after [getiter(obj)] */ - if (PyCoro_CheckExact(iterable)) { - /* `iterable` is a coroutine */ - if (!(_PyFrame_GetCode(frame)->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { - /* and it is used in a 'yield from' expression of a - regular generator. */ - _PyErr_SetString(tstate, PyExc_TypeError, - "cannot 'yield from' a coroutine object " - "in a non-coroutine generator"); - goto error; - } - iter = iterable; - } - else if (PyGen_CheckExact(iterable)) { - iter = iterable; - } - else { - /* `iterable` is not a generator. */ - iter = PyObject_GetIter(iterable); - if (iter == NULL) { - goto error; + list = stack_pointer[-2 - (oparg-1)]; + PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); + if (none_val == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) + { + _PyErr_Clear(tstate); + _PyErr_Format(tstate, PyExc_TypeError, + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); } Py_DECREF(iterable); + if (true) goto pop_1_error; } - stack_pointer[-1] = iter; + assert(Py_IsNone(none_val)); + Py_DECREF(iterable); + stack_pointer += -1; DISPATCH(); } - TARGET(FOR_ITER) { - PREDICTED(FOR_ITER); - static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); - PyObject *iter; - PyObject *next; - iter = stack_pointer[-1]; - #if ENABLE_SPECIALIZATION - _PyForIterCache *cache = (_PyForIterCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_ForIter(iter, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - STAT_INC(FOR_ITER, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ - next = (*Py_TYPE(iter)->tp_iternext)(iter); - if (next == NULL) { - if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; - } - monitor_raise(tstate, frame, next_instr-1); - _PyErr_Clear(tstate); - } - /* iterator ended normally */ - assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || - next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); - Py_DECREF(iter); - STACK_SHRINK(1); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); - /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(oparg + 1); - DISPATCH(); - } - // Common case: no jump, leave it to the code generator - STACK_GROW(1); - stack_pointer[-1] = next; + TARGET(LOAD_ASSERTION_ERROR) { + frame->instr_ptr = next_instr; next_instr += 1; + INSTRUCTION_STATS(LOAD_ASSERTION_ERROR); + PyObject *value; + value = Py_NewRef(PyExc_AssertionError); + stack_pointer[0] = value; + stack_pointer += 1; DISPATCH(); } - TARGET(INSTRUMENTED_FOR_ITER) { - _Py_CODEUNIT *here = next_instr-1; - _Py_CODEUNIT *target; - PyObject *iter = TOP(); - PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); - if (next != NULL) { - PUSH(next); - target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER; + TARGET(LOAD_ATTR) { + frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR); + PREDICTED(LOAD_ATTR); + _Py_CODEUNIT *this_instr = next_instr - 10; + PyObject *owner; + PyObject *attr; + PyObject *self_or_null = NULL; + // _SPECIALIZE_LOAD_ATTR + owner = stack_pointer[-1]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + next_instr = this_instr; + _Py_Specialize_LoadAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - else { - if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; + // _LOAD_ATTR + { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); + if (oparg & 1) { + /* Designed to work in tandem with CALL, pushes two values. */ + 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(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 + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + NULL | meth | arg1 | ... | argN + */ + Py_DECREF(owner); + if (attr == NULL) goto pop_1_error; + self_or_null = NULL; } - monitor_raise(tstate, frame, here); - _PyErr_Clear(tstate); } - /* iterator ended normally */ - assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || - next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); - STACK_SHRINK(1); - Py_DECREF(iter); - /* Skip END_FOR */ - target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; + else { + /* Classic, pushes one value. */ + attr = PyObject_GetAttr(owner, name); + Py_DECREF(owner); + if (attr == NULL) goto pop_1_error; + } } - INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = self_or_null; + stack_pointer += ((oparg & 1)); DISPATCH(); } - TARGET(FOR_ITER_LIST) { - PyObject *iter; - PyObject *next; - // _ITER_CHECK_LIST - iter = stack_pointer[-1]; - { - DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); - } - // _ITER_JUMP_LIST + TARGET(LOAD_ATTR_CLASS) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_CLASS); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _CHECK_ATTR_CLASS + owner = stack_pointer[-1]; { - _PyListIterObject *it = (_PyListIterObject *)iter; - assert(Py_TYPE(iter) == &PyListIter_Type); - STAT_INC(FOR_ITER, hit); - PyListObject *seq = it->it_seq; - if (seq == NULL || it->it_index >= PyList_GET_SIZE(seq)) { - if (seq != NULL) { - it->it_seq = NULL; - Py_DECREF(seq); - } - Py_DECREF(iter); - STACK_SHRINK(1); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); - /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(oparg + 1); - DISPATCH(); - } + uint32_t type_version = read_u32(&this_instr[2].cache); + DEOPT_IF(!PyType_Check(owner), LOAD_ATTR); + assert(type_version != 0); + DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, LOAD_ATTR); } - // _ITER_NEXT_LIST + /* Skip 2 cache entries */ + // _LOAD_ATTR_CLASS { - _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++)); + PyObject *descr = read_obj(&this_instr[6].cache); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + attr = Py_NewRef(descr); + null = NULL; + Py_DECREF(owner); } - STACK_GROW(1); - stack_pointer[-1] = next; - next_instr += 1; + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); DISPATCH(); } - TARGET(FOR_ITER_TUPLE) { - PyObject *iter; - PyObject *next; - // _ITER_CHECK_TUPLE - iter = stack_pointer[-1]; + TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + owner = stack_pointer[-1]; + uint32_t type_version = read_u32(&this_instr[2].cache); + uint32_t func_version = read_u32(&this_instr[4].cache); + PyObject *getattribute = read_obj(&this_instr[6].cache); + assert((oparg & 1) == 0); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + PyTypeObject *cls = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + PyObject *name = GETITEM(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(). + STACK_SHRINK(1); + new_frame->localsplus[0] = owner; + new_frame->localsplus[1] = Py_NewRef(name); + frame->return_offset = (uint16_t)(next_instr - this_instr); + DISPATCH_INLINED(new_frame); + } + + TARGET(LOAD_ATTR_INSTANCE_VALUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_INSTANCE_VALUE); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; { - DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER); + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); } - // _ITER_JUMP_TUPLE + // _CHECK_MANAGED_OBJECT_HAS_VALUES { - _PyTupleIterObject *it = (_PyTupleIterObject *)iter; - assert(Py_TYPE(iter) == &PyTupleIter_Type); - STAT_INC(FOR_ITER, hit); - PyTupleObject *seq = it->it_seq; - if (seq == NULL || it->it_index >= PyTuple_GET_SIZE(seq)) { - if (seq != NULL) { - it->it_seq = NULL; - Py_DECREF(seq); - } - Py_DECREF(iter); - STACK_SHRINK(1); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); - /* Jump forward oparg, then skip following END_FOR instruction */ - JUMPBY(oparg + 1); - DISPATCH(); - } + 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) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); } - // _ITER_NEXT_TUPLE + // _LOAD_ATTR_INSTANCE_VALUE { - _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++)); + uint16_t index = read_u16(&this_instr[4].cache); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + attr = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(attr == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(attr); + null = NULL; + Py_DECREF(owner); } - STACK_GROW(1); - stack_pointer[-1] = next; - next_instr += 1; + /* Skip 5 cache entries */ + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); DISPATCH(); } - TARGET(FOR_ITER_RANGE) { - PyObject *iter; - PyObject *next; - // _ITER_CHECK_RANGE - iter = stack_pointer[-1]; + TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_METHOD_LAZY_DICT); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + PyObject *attr; + PyObject *self = NULL; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; { - _PyRangeIterObject *r = (_PyRangeIterObject *)iter; - DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); } - // _ITER_JUMP_RANGE + // _CHECK_ATTR_METHOD_LAZY_DICT { - _PyRangeIterObject *r = (_PyRangeIterObject *)iter; - assert(Py_TYPE(r) == &PyRangeIter_Type); - STAT_INC(FOR_ITER, hit); - if (r->len <= 0) { - STACK_SHRINK(1); - Py_DECREF(r); - SKIP_OVER(INLINE_CACHE_ENTRIES_FOR_ITER); - // Jump over END_FOR instruction. - JUMPBY(oparg + 1); - DISPATCH(); - } - } - // _ITER_NEXT_RANGE + 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); + } + /* Skip 2 cache entries */ + // _LOAD_ATTR_METHOD_LAZY_DICT { - _PyRangeIterObject *r = (_PyRangeIterObject *)iter; - assert(Py_TYPE(r) == &PyRangeIter_Type); - assert(r->len > 0); - long value = r->start; - r->start = value + r->step; - r->len--; - next = PyLong_FromLong(value); - if (next == NULL) goto error; + PyObject *descr = read_obj(&this_instr[6].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] = next; - next_instr += 1; + stack_pointer[-1] = attr; + if (1) stack_pointer[0] = self; + stack_pointer += (((1) ? 1 : 0)); DISPATCH(); } - TARGET(FOR_ITER_GEN) { - 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; - _PyFrame_StackPush(gen_frame, Py_None); - 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_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; - PyObject *exit; - PyObject *res; - mgr = stack_pointer[-1]; - PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); - if (enter == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "asynchronous context manager protocol", - Py_TYPE(mgr)->tp_name); - } - goto error; - } - exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); - if (exit == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "asynchronous context manager protocol " - "(missed __aexit__ method)", - Py_TYPE(mgr)->tp_name); - } - Py_DECREF(enter); - goto error; + TARGET(LOAD_ATTR_METHOD_NO_DICT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_METHOD_NO_DICT); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + PyObject *attr; + PyObject *self = NULL; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); } - Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); - Py_DECREF(enter); - if (res == NULL) { - Py_DECREF(exit); - if (true) goto pop_1_error; + /* Skip 2 cache entries */ + // _LOAD_ATTR_METHOD_NO_DICT + { + PyObject *descr = read_obj(&this_instr[6].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[-2] = exit; - stack_pointer[-1] = res; - DISPATCH(); - } - - TARGET(BEFORE_WITH) { - 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__ - */ - PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); - if (enter == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "context manager protocol", - Py_TYPE(mgr)->tp_name); - } - goto error; - } - exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); - if (exit == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "context manager protocol " - "(missed __exit__ method)", - Py_TYPE(mgr)->tp_name); - } - Py_DECREF(enter); - goto error; - } - Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); - Py_DECREF(enter); - if (res == NULL) { - Py_DECREF(exit); - if (true) goto pop_1_error; - } - STACK_GROW(1); - stack_pointer[-2] = exit; - stack_pointer[-1] = res; - DISPATCH(); - } - - TARGET(WITH_EXCEPT_START) { - 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 - - lasti: THIRD = lasti of exception in exc_info() - - exit_func: FOURTH = the context.__exit__ bound method - We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). - Then we push the __exit__ return value. - */ - PyObject *exc, *tb; - - assert(val && PyExceptionInstance_Check(val)); - exc = PyExceptionInstance_Class(val); - tb = PyException_GetTraceback(val); - 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}; - res = PyObject_Vectorcall(exit_func, stack + 1, - 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); - if (res == NULL) goto error; - STACK_GROW(1); - stack_pointer[-1] = res; - DISPATCH(); - } - - TARGET(PUSH_EXC_INFO) { - 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; - } - else { - prev_exc = Py_None; - } - assert(PyExceptionInstance_Check(new_exc)); - exc_info->exc_value = Py_NewRef(new_exc); - STACK_GROW(1); - stack_pointer[-2] = prev_exc; - stack_pointer[-1] = new_exc; + stack_pointer[-1] = attr; + if (1) stack_pointer[0] = self; + stack_pointer += (((1) ? 1 : 0)); DISPATCH(); } TARGET(LOAD_ATTR_METHOD_WITH_VALUES) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_METHOD_WITH_VALUES); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; PyObject *attr; - PyObject *self; + PyObject *self = NULL; + /* Skip 1 cache entry */ // _GUARD_TYPE_VERSION owner = stack_pointer[-1]; { - uint32_t type_version = read_u32(&next_instr[1].cache); + uint32_t type_version = read_u32(&this_instr[2].cache); PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -3591,21 +3592,18 @@ { 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); + DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR); } // _GUARD_KEYS_VERSION { - uint32_t keys_version = read_u32(&next_instr[3].cache); + uint32_t keys_version = read_u32(&this_instr[4].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); + 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); + PyObject *descr = read_obj(&this_instr[6].cache); assert(oparg & 1); /* Cached method object */ STAT_INC(LOAD_ATTR, hit); @@ -3614,1497 +3612,2178 @@ assert(_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)); self = owner; } - STACK_GROW(1); - stack_pointer[-2] = attr; - stack_pointer[-1] = self; - next_instr += 9; + stack_pointer[-1] = attr; + if (1) stack_pointer[0] = self; + stack_pointer += (((1) ? 1 : 0)); DISPATCH(); } - TARGET(LOAD_ATTR_METHOD_NO_DICT) { + TARGET(LOAD_ATTR_MODULE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_MODULE); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; PyObject *attr; - PyObject *self; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _CHECK_ATTR_MODULE + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&this_instr[2].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(&this_instr[4].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); + } + /* Skip 5 cache entries */ + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); + DISPATCH(); + } + + TARGET(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_NONDESCRIPTOR_NO_DICT); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + PyObject *attr; + /* Skip 1 cache entry */ // _GUARD_TYPE_VERSION owner = stack_pointer[-1]; { - uint32_t type_version = read_u32(&next_instr[1].cache); + uint32_t type_version = read_u32(&this_instr[2].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 + /* Skip 2 cache entries */ + // _LOAD_ATTR_NONDESCRIPTOR_NO_DICT { - PyObject *descr = read_obj(&next_instr[5].cache); - assert(oparg & 1); + PyObject *descr = read_obj(&this_instr[6].cache); + assert((oparg & 1) == 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)); + Py_DECREF(owner); attr = Py_NewRef(descr); - self = owner; } - STACK_GROW(1); - stack_pointer[-2] = attr; - stack_pointer[-1] = self; - next_instr += 9; + stack_pointer[-1] = attr; + stack_pointer += (((0) ? 1 : 0)); DISPATCH(); } TARGET(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; PyObject *attr; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION owner = stack_pointer[-1]; - 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 *owner_cls = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && - !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), - LOAD_ATTR); - PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; - DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != - keys_version, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - Py_DECREF(owner); - attr = Py_NewRef(descr); + { + uint32_t type_version = read_u32(&this_instr[2].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(&this_instr[4].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(&this_instr[6].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; + stack_pointer += (((0) ? 1 : 0)); DISPATCH(); } - TARGET(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) { + TARGET(LOAD_ATTR_PROPERTY) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_PROPERTY); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; - PyObject *attr; owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); + uint32_t type_version = read_u32(&this_instr[2].cache); + uint32_t func_version = read_u32(&this_instr[4].cache); + PyObject *fget = read_obj(&this_instr[6].cache); assert((oparg & 1) == 0); - PyTypeObject *owner_cls = Py_TYPE(owner); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + PyTypeObject *cls = Py_TYPE(owner); assert(type_version != 0); - DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR); - assert(owner_cls->tp_dictoffset == 0); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 1); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - Py_DECREF(owner); - attr = Py_NewRef(descr); - stack_pointer[-1] = attr; - next_instr += 9; - DISPATCH(); + Py_INCREF(fget); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); + // Manipulate stack directly because we exit with DISPATCH_INLINED(). + STACK_SHRINK(1); + new_frame->localsplus[0] = owner; + frame->return_offset = (uint16_t)(next_instr - this_instr); + DISPATCH_INLINED(new_frame); } - TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { + TARGET(LOAD_ATTR_SLOT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_SLOT); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; PyObject *attr; - PyObject *self; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&next_instr[1].cache); - PyObject *descr = read_obj(&next_instr[5].cache); - assert(oparg & 1); - PyTypeObject *owner_cls = Py_TYPE(owner); - DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR); - Py_ssize_t dictoffset = owner_cls->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); - 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; - next_instr += 9; + { + uint32_t type_version = read_u32(&this_instr[2].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(&this_instr[4].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); + } + /* Skip 5 cache entries */ + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); DISPATCH(); } - TARGET(INSTRUMENTED_CALL) { - int is_meth = PEEK(oparg + 1) != NULL; - int total_args = oparg + is_meth; - PyObject *function = PEEK(oparg + 2); - PyObject *arg = total_args == 0 ? - &_PyInstrumentation_MISSING : PEEK(total_args); - int err = _Py_call_instrumentation_2args( - tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr-1, function, arg); - if (err) goto error; - _PyCallCache *cache = (_PyCallCache *)next_instr; - INCREMENT_ADAPTIVE_COUNTER(cache->counter); - GO_TO_INSTRUCTION(CALL); - } - - TARGET(CALL) { - PREDICTED(CALL); - static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); - 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]; - // oparg counts all of the args, but *not* self: - int total_args = oparg; - if (self_or_null != NULL) { - args--; - total_args++; + TARGET(LOAD_ATTR_WITH_HINT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 10; + INSTRUCTION_STATS(LOAD_ATTR_WITH_HINT); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner; + PyObject *attr; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); } - #if ENABLE_SPECIALIZATION - _PyCallCache *cache = (_PyCallCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { - next_instr--; - _Py_Specialize_Call(callable, next_instr, total_args); - DISPATCH_SAME_OPARG(); - } - STAT_INC(CALL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - 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; + // _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)); } - // 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) + // _LOAD_ATTR_WITH_HINT { - 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, total_args, NULL - ); - // Manipulate stack directly since we leave using DISPATCH_INLINED(). - STACK_SHRINK(oparg + 2); - // 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; - } - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); - } - /* Callable is not a normal Python function */ - res = PyObject_Vectorcall( - callable, args, - total_args | PY_VECTORCALL_ARGUMENTS_OFFSET, - NULL); - if (opcode == INSTRUMENTED_CALL) { - 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); + uint16_t hint = read_u16(&this_instr[4].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 { - int err = _Py_call_instrumentation_2args( - tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, callable, arg); - if (err < 0) { - Py_CLEAR(res); - } + 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); } - 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_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + /* Skip 5 cache entries */ + stack_pointer[-1] = attr; + if (oparg & 1) stack_pointer[0] = null; + stack_pointer += ((oparg & 1)); DISPATCH(); } - TARGET(CALL_BOUND_METHOD_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); + TARGET(LOAD_BUILD_CLASS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_BUILD_CLASS); + PyObject *bc; + if (PyMapping_GetOptionalItem(BUILTINS(), &_Py_ID(__build_class__), &bc) < 0) goto error; + if (bc == NULL) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + if (true) goto error; } - // _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); + stack_pointer[0] = bc; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_CONST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_CONST); + PyObject *value; + value = GETITEM(FRAME_CO_CONSTS, oparg); + Py_INCREF(value); + stack_pointer[0] = value; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_DEREF) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_DEREF); + PyObject *value; + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + if (true) goto error; } - // _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); + Py_INCREF(value); + stack_pointer[0] = value; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_FAST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FAST); + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + stack_pointer[0] = value; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_FAST_AND_CLEAR) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FAST_AND_CLEAR); + PyObject *value; + value = GETLOCAL(oparg); + // do not use SETLOCAL here, it decrefs the old value + GETLOCAL(oparg) = NULL; + stack_pointer[0] = value; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_FAST_CHECK) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FAST_CHECK); + PyObject *value; + value = GETLOCAL(oparg); + if (value == NULL) goto unbound_local_error; + Py_INCREF(value); + stack_pointer[0] = value; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_FAST_LOAD_FAST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FAST_LOAD_FAST); + PyObject *value1; + PyObject *value2; + uint32_t oparg1 = oparg >> 4; + uint32_t oparg2 = oparg & 15; + value1 = GETLOCAL(oparg1); + value2 = GETLOCAL(oparg2); + Py_INCREF(value1); + Py_INCREF(value2); + stack_pointer[0] = value1; + stack_pointer[1] = value2; + stack_pointer += 2; + DISPATCH(); + } + + TARGET(LOAD_FROM_DICT_OR_DEREF) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FROM_DICT_OR_DEREF); + PyObject *class_dict; + PyObject *value; + class_dict = stack_pointer[-1]; + PyObject *name; + assert(class_dict); + assert(oparg >= 0 && oparg < _PyFrame_GetCode(frame)->co_nlocalsplus); + name = PyTuple_GET_ITEM(_PyFrame_GetCode(frame)->co_localsplusnames, oparg); + if (PyMapping_GetOptionalItem(class_dict, name, &value) < 0) { + GOTO_ERROR(error); } - // _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); + if (!value) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + GOTO_ERROR(error); + } + Py_INCREF(value); } - // _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); + Py_DECREF(class_dict); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_FROM_DICT_OR_GLOBALS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(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(error); } - // _INIT_CALL_PY_EXACT_ARGS - args = stack_pointer - oparg; - { - int argcount = oparg; - if (self_or_null != NULL) { - args--; - argcount++; + if (v == NULL) { + if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) { + GOTO_ERROR(error); } - 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]; + if (v == NULL) { + if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { + GOTO_ERROR(error); + } + if (v == NULL) { + _PyEval_FormatExcCheckArg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + GOTO_ERROR(error); + } } } - // _SAVE_CURRENT_IP - next_instr += 3; + Py_DECREF(mod_or_class_dict); + stack_pointer[-1] = v; + DISPATCH(); + } + + TARGET(LOAD_GLOBAL) { + frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(LOAD_GLOBAL); + PREDICTED(LOAD_GLOBAL); + _Py_CODEUNIT *this_instr = next_instr - 5; + PyObject *res; + PyObject *null = NULL; + // _SPECIALIZE_LOAD_GLOBAL { - #if TIER_ONE - frame->prev_instr = next_instr - 1; - #endif - #if TIER_TWO - // Relies on a preceding _SET_IP - frame->prev_instr--; - #endif + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + next_instr = this_instr; + _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_GLOBAL, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - // _PUSH_FRAME - STACK_SHRINK(oparg); - STACK_SHRINK(2); + // _LOAD_GLOBAL { - // 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; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + if (PyDict_CheckExact(GLOBALS()) + && PyDict_CheckExact(BUILTINS())) + { + 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 */ + _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + if (true) goto error; + } + Py_INCREF(res); + } + else { + /* Slow-path if globals or builtins is not a dict */ + /* namespace 1: globals */ + if (PyMapping_GetOptionalItem(GLOBALS(), name, &res) < 0) goto error; + if (res == NULL) { + /* namespace 2: builtins */ + 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; + } + } } - #endif + null = NULL; } + stack_pointer[0] = res; + if (oparg & 1) stack_pointer[1] = null; + stack_pointer += 1 + ((oparg & 1)); DISPATCH(); } - TARGET(CALL_PY_EXACT_ARGS) { - PyObject *self_or_null; - PyObject *callable; - PyObject **args; - _PyInterpreterFrame *new_frame; - // _CHECK_PEP_523 - { - DEOPT_IF(tstate->interp->eval_frame, CALL); - } - // _CHECK_FUNCTION_EXACT_ARGS - self_or_null = stack_pointer[-1 - oparg]; - callable = stack_pointer[-2 - oparg]; + TARGET(LOAD_GLOBAL_BUILTIN) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(LOAD_GLOBAL_BUILTIN); + static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); + PyObject *res; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _GUARD_GLOBALS_VERSION { - 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); + uint16_t version = read_u16(&this_instr[2].cache); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); } - // _CHECK_STACK_SPACE + // _GUARD_BUILTINS_VERSION { - 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); + uint16_t version = read_u16(&this_instr[3].cache); + PyDictObject *dict = (PyDictObject *)BUILTINS(); + DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); } - // _INIT_CALL_PY_EXACT_ARGS - args = stack_pointer - oparg; + // _LOAD_GLOBAL_BUILTINS { - 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]; - } + uint16_t index = read_u16(&this_instr[4].cache); + PyDictObject *bdict = (PyDictObject *)BUILTINS(); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + res = entries[index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + Py_INCREF(res); + STAT_INC(LOAD_GLOBAL, hit); + null = NULL; } - // _SAVE_CURRENT_IP - next_instr += 3; + stack_pointer[0] = res; + if (oparg & 1) stack_pointer[1] = null; + stack_pointer += 1 + ((oparg & 1)); + DISPATCH(); + } + + TARGET(LOAD_GLOBAL_MODULE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(LOAD_GLOBAL_MODULE); + static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); + PyObject *res; + PyObject *null = NULL; + /* Skip 1 cache entry */ + // _GUARD_GLOBALS_VERSION { - #if TIER_ONE - frame->prev_instr = next_instr - 1; - #endif - #if TIER_TWO - // Relies on a preceding _SET_IP - frame->prev_instr--; - #endif + uint16_t version = read_u16(&this_instr[2].cache); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); } - // _PUSH_FRAME - STACK_SHRINK(oparg); - STACK_SHRINK(2); + /* Skip 1 cache entry */ + // _LOAD_GLOBAL_MODULE { - // 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 + uint16_t index = read_u16(&this_instr[4].cache); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + res = entries[index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + Py_INCREF(res); + STAT_INC(LOAD_GLOBAL, hit); + null = NULL; } + stack_pointer[0] = res; + if (oparg & 1) stack_pointer[1] = null; + stack_pointer += 1 + ((oparg & 1)); DISPATCH(); } - TARGET(CALL_PY_WITH_DEFAULTS) { - 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); - DEOPT_IF(tstate->interp->eval_frame, CALL); - int argcount = oparg; - if (self_or_null != NULL) { - args--; - argcount++; + TARGET(LOAD_LOCALS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_LOCALS); + PyObject *locals; + locals = LOCALS(); + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; } - DEOPT_IF(!PyFunction_Check(callable), CALL); - PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != func_version, CALL); - 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); - STAT_INC(CALL, hit); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); - for (int i = 0; i < argcount; i++) { - new_frame->localsplus[i] = args[i]; + Py_INCREF(locals); + stack_pointer[0] = locals; + stack_pointer += 1; + DISPATCH(); + } + + TARGET(LOAD_NAME) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(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; } - for (int i = argcount; i < code->co_argcount; i++) { - PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i - min_args); - new_frame->localsplus[i] = Py_NewRef(def); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + if (PyMapping_GetOptionalItem(mod_or_class_dict, name, &v) < 0) { + GOTO_ERROR(error); } - // Manipulate stack and cache 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); + if (v == NULL) { + if (PyDict_GetItemRef(GLOBALS(), name, &v) < 0) { + GOTO_ERROR(error); + } + if (v == NULL) { + if (PyMapping_GetOptionalItem(BUILTINS(), name, &v) < 0) { + GOTO_ERROR(error); + } + if (v == NULL) { + _PyEval_FormatExcCheckArg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + GOTO_ERROR(error); + } + } + } + stack_pointer[0] = v; + stack_pointer += 1; + DISPATCH(); } - TARGET(CALL_TYPE_1) { - PyObject **args; - PyObject *null; - PyObject *callable; - PyObject *res; - 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]; - DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); - STAT_INC(CALL, hit); - res = Py_NewRef(Py_TYPE(obj)); - Py_DECREF(obj); - Py_DECREF(&PyType_Type); // I.e., callable - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; + TARGET(LOAD_SUPER_ATTR) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(LOAD_SUPER_ATTR); + PREDICTED(LOAD_SUPER_ATTR); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *class; + PyObject *global_super; + PyObject *self; + PyObject *attr; + PyObject *null = NULL; + // _SPECIALIZE_LOAD_SUPER_ATTR + class = stack_pointer[-2]; + global_super = stack_pointer[-3]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + int load_method = oparg & 1; + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_SUPER_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ + } + // _LOAD_SUPER_ATTR + self = stack_pointer[-1]; + { + TIER_ONE_ONLY + if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { + PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, this_instr, global_super, arg); + if (err) goto pop_3_error; + } + // we make no attempt to optimize here; specializations should + // handle any case whose performance we care about + PyObject *stack[] = {class, self}; + PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); + if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { + PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; + if (super == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, this_instr, global_super, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, this_instr, global_super, arg); + if (err < 0) { + Py_CLEAR(super); + } + } + } + Py_DECREF(global_super); + Py_DECREF(class); + Py_DECREF(self); + if (super == NULL) goto pop_3_error; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + attr = PyObject_GetAttr(super, name); + Py_DECREF(super); + if (attr == NULL) goto pop_3_error; + null = NULL; + } + stack_pointer[-3] = attr; + if (oparg & 1) stack_pointer[-2] = null; + stack_pointer += -2 + ((oparg & 1)); DISPATCH(); } - TARGET(CALL_STR_1) { - PyObject **args; - PyObject *null; - PyObject *callable; - PyObject *res; - 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); - STAT_INC(CALL, hit); - PyObject *arg = args[0]; - res = PyObject_Str(arg); - Py_DECREF(arg); - Py_DECREF(&PyUnicode_Type); // I.e., callable - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + TARGET(LOAD_SUPER_ATTR_ATTR) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(LOAD_SUPER_ATTR_ATTR); + static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size"); + 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); + attr = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); + Py_DECREF(global_super); + Py_DECREF(class); + Py_DECREF(self); + if (attr == NULL) goto pop_3_error; + stack_pointer[-3] = attr; + stack_pointer += -2 + (((0) ? 1 : 0)); DISPATCH(); } - TARGET(CALL_TUPLE_1) { - PyObject **args; - PyObject *null; - PyObject *callable; - PyObject *res; - 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); - STAT_INC(CALL, hit); - PyObject *arg = args[0]; - res = PySequence_Tuple(arg); - Py_DECREF(arg); - Py_DECREF(&PyTuple_Type); // I.e., tuple - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + TARGET(LOAD_SUPER_ATTR_METHOD) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(LOAD_SUPER_ATTR_METHOD); + static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size"); + 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); + STAT_INC(LOAD_SUPER_ATTR, hit); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2); + PyTypeObject *cls = (PyTypeObject *)class; + int method_found = 0; + attr = _PySuper_Lookup(cls, self, name, + Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); + Py_DECREF(global_super); + Py_DECREF(class); + if (attr == NULL) { + Py_DECREF(self); + if (true) goto pop_3_error; + } + if (method_found) { + self_or_null = self; // transfer ownership + } else { + Py_DECREF(self); + self_or_null = NULL; + } + stack_pointer[-3] = attr; + stack_pointer[-2] = self_or_null; + stack_pointer += -1; DISPATCH(); } - 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 - * */ - _PyCallCache *cache = (_PyCallCache *)next_instr; - DEOPT_IF(null != NULL, CALL); - DEOPT_IF(!PyType_Check(callable), CALL); - PyTypeObject *tp = (PyTypeObject *)callable; - DEOPT_IF(tp->tp_version_tag != read_u32(cache->func_version), CALL); - 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); - STAT_INC(CALL, hit); - PyObject *self = _PyType_NewManagedObject(tp); - if (self == NULL) { - goto error; - } - Py_DECREF(tp); - _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( - tstate, (PyCodeObject *)&_Py_InitCleanup, 1, 0); - assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK); - /* Push self onto stack of shim */ - Py_INCREF(self); - shim->localsplus[0] = self; - Py_INCREF(init); - _PyInterpreterFrame *init_frame = _PyFrame_PushUnchecked(tstate, init, oparg+1); - /* Copy self followed by args to __init__ frame */ - init_frame->localsplus[0] = self; - for (int i = 0; i < oparg; i++) { - init_frame->localsplus[i+1] = args[i]; + TARGET(MAKE_CELL) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MAKE_CELL); + // "initial" is probably NULL but not if it's an arg (or set + // via PyFrame_LocalsToFast() before MAKE_CELL has run). + PyObject *initial = GETLOCAL(oparg); + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + GOTO_ERROR(error); } - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - frame->return_offset = 0; - STACK_SHRINK(oparg+2); - _PyFrame_SetStackPointer(frame, stack_pointer); - /* Link frames */ - init_frame->previous = shim; - shim->previous = 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, - * as it will be checked after start_frame */ - tstate->py_recursion_remaining--; - goto start_frame; + SETLOCAL(oparg, cell); + DISPATCH(); } - TARGET(EXIT_INIT_CHECK) { - PyObject *should_be_none; - should_be_none = stack_pointer[-1]; - assert(STACK_LEVEL() == 2); - if (should_be_none != Py_None) { - PyErr_Format(PyExc_TypeError, - "__init__() should return None, not '%.200s'", - Py_TYPE(should_be_none)->tp_name); - goto error; + TARGET(MAKE_FUNCTION) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MAKE_FUNCTION); + PyObject *codeobj; + PyObject *func; + codeobj = stack_pointer[-1]; + PyFunctionObject *func_obj = (PyFunctionObject *) + PyFunction_New(codeobj, GLOBALS()); + Py_DECREF(codeobj); + if (func_obj == NULL) { + GOTO_ERROR(error); } - STACK_SHRINK(1); + _PyFunction_SetVersion( + func_obj, ((PyCodeObject *)codeobj)->co_version); + func = (PyObject *)func_obj; + stack_pointer[-1] = func; DISPATCH(); } - TARGET(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; - next_instr += 3; - CHECK_EVAL_BREAKER(); + TARGET(MAP_ADD) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MAP_ADD); + 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 + if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; + stack_pointer += -2; DISPATCH(); } - 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 */ - int total_args = oparg; - if (self_or_null != NULL) { - args--; - total_args++; + TARGET(MATCH_CLASS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MATCH_CLASS); + 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 = _PyEval_MatchClass(tstate, subject, type, oparg, names); + Py_DECREF(subject); + Py_DECREF(type); + Py_DECREF(names); + if (attrs) { + assert(PyTuple_CheckExact(attrs)); // Success! } - DEOPT_IF(total_args != 1, CALL); - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); - STAT_INC(CALL, hit); - PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); - // This is slower but CPython promises to check all non-vectorcall - // function calls. - if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; + else { + if (_PyErr_Occurred(tstate)) goto pop_3_error; + // Error! + attrs = Py_None; // Failure! } - PyObject *arg = args[0]; - res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); - _Py_LeaveRecursiveCallTstate(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + stack_pointer[-3] = attrs; + stack_pointer += -2; + DISPATCH(); + } - Py_DECREF(arg); - Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + TARGET(MATCH_KEYS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MATCH_KEYS); + 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 = _PyEval_MatchKeys(tstate, subject, keys); + if (values_or_none == NULL) goto error; + stack_pointer[0] = values_or_none; + stack_pointer += 1; DISPATCH(); } - TARGET(CALL_BUILTIN_FAST) { - PyObject **args; - PyObject *self_or_null; - PyObject *callable; + TARGET(MATCH_MAPPING) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MATCH_MAPPING); + PyObject *subject; PyObject *res; - args = stack_pointer - oparg; - self_or_null = stack_pointer[-1 - oparg]; - callable = stack_pointer[-2 - oparg]; - /* Builtin METH_FASTCALL functions, without keywords */ - 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, CALL); - STAT_INC(CALL, hit); - PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); - /* res = func(self, args, nargs) */ - res = ((_PyCFunctionFast)(void(*)(void))cfunc)( - PyCFunction_GET_SELF(callable), - args, - total_args); - 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; } - /* Not deopting because this doesn't mean our optimization was - wrong. `res` can be NULL for valid reasons. Eg. getattr(x, - 'invalid'). In those cases an exception is set, so we must - handle it. - */ - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + subject = stack_pointer[-1]; + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + res = match ? Py_True : Py_False; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } - TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) { - PyObject **args; - PyObject *self_or_null; - PyObject *callable; + TARGET(MATCH_SEQUENCE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(MATCH_SEQUENCE); + PyObject *subject; 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 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)); + subject = stack_pointer[-1]; + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + res = match ? Py_True : Py_False; + stack_pointer[0] = res; + stack_pointer += 1; + DISPATCH(); + } - /* 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; - next_instr += 3; - CHECK_EVAL_BREAKER(); + TARGET(NOP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(NOP); DISPATCH(); } - TARGET(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 total_args = oparg; - if (self_or_null != NULL) { - args--; - total_args++; - } - DEOPT_IF(total_args != 1, CALL); - PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.len, CALL); - STAT_INC(CALL, hit); - PyObject *arg = args[0]; - Py_ssize_t len_i = PyObject_Length(arg); - if (len_i < 0) { - goto error; - } - res = PyLong_FromSsize_t(len_i); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + TARGET(POP_EXCEPT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(POP_EXCEPT); + PyObject *exc_value; + exc_value = stack_pointer[-1]; + _PyErr_StackItem *exc_info = tstate->exc_info; + Py_XSETREF(exc_info->exc_value, exc_value); + stack_pointer += -1; + DISPATCH(); + } - Py_DECREF(callable); - Py_DECREF(arg); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; + TARGET(POP_JUMP_IF_FALSE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(POP_JUMP_IF_FALSE); + PyObject *cond; + cond = stack_pointer[-1]; + assert(PyBool_Check(cond)); + int flag = Py_IsFalse(cond); + #if ENABLE_SPECIALIZATION + this_instr[1].cache = (this_instr[1].cache << 1) | flag; + #endif + JUMPBY(oparg * flag); + stack_pointer += -1; DISPATCH(); } - TARGET(CALL_ISINSTANCE) { - 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]; - /* isinstance(o, o2) */ - int total_args = oparg; - if (self_or_null != NULL) { - args--; - total_args++; + TARGET(POP_JUMP_IF_NONE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(POP_JUMP_IF_NONE); + PyObject *value; + PyObject *b; + PyObject *cond; + // _IS_NONE + value = stack_pointer[-1]; + { + if (Py_IsNone(value)) { + b = Py_True; + } + else { + b = Py_False; + Py_DECREF(value); + } } - DEOPT_IF(total_args != 2, CALL); - PyInterpreterState *interp = tstate->interp; - DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); - STAT_INC(CALL, hit); - PyObject *cls = args[1]; - PyObject *inst = args[0]; - int retval = PyObject_IsInstance(inst, cls); - if (retval < 0) { - goto error; + // _POP_JUMP_IF_TRUE + cond = b; + { + assert(PyBool_Check(cond)); + int flag = Py_IsTrue(cond); + #if ENABLE_SPECIALIZATION + this_instr[1].cache = (this_instr[1].cache << 1) | flag; + #endif + JUMPBY(oparg * flag); } - res = PyBool_FromLong(retval); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - Py_DECREF(inst); - Py_DECREF(cls); - Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; + stack_pointer += -1; DISPATCH(); } - 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); - 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 + TARGET(POP_JUMP_IF_NOT_NONE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(POP_JUMP_IF_NOT_NONE); + PyObject *value; + PyObject *b; + PyObject *cond; + // _IS_NONE + value = stack_pointer[-1]; + { + if (Py_IsNone(value)) { + b = Py_True; + } + else { + b = Py_False; + Py_DECREF(value); + } } - Py_DECREF(self); - Py_DECREF(callable); - STACK_SHRINK(3); - // CALL + POP_TOP - SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); - assert(next_instr[-1].op.code == POP_TOP); + // _POP_JUMP_IF_FALSE + cond = b; + { + assert(PyBool_Check(cond)); + int flag = Py_IsFalse(cond); + #if ENABLE_SPECIALIZATION + this_instr[1].cache = (this_instr[1].cache << 1) | flag; + #endif + JUMPBY(oparg * flag); + } + stack_pointer += -1; DISPATCH(); } - TARGET(CALL_METHOD_DESCRIPTOR_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]; - int total_args = oparg; - if (self_or_null != NULL) { - args--; - total_args++; - } - PyMethodDescrObject *method = (PyMethodDescrObject *)callable; - DEOPT_IF(total_args != 2, CALL); - 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, 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 - // function calls. - if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; - } - res = _PyCFunction_TrampolineCall(cfunc, self, arg); - _Py_LeaveRecursiveCallTstate(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(self); - Py_DECREF(arg); - Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + TARGET(POP_JUMP_IF_TRUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(POP_JUMP_IF_TRUE); + PyObject *cond; + cond = stack_pointer[-1]; + assert(PyBool_Check(cond)); + int flag = Py_IsTrue(cond); + #if ENABLE_SPECIALIZATION + this_instr[1].cache = (this_instr[1].cache << 1) | flag; + #endif + JUMPBY(oparg * flag); + stack_pointer += -1; DISPATCH(); } - TARGET(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)); + TARGET(POP_TOP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(POP_TOP); + PyObject *value; + value = stack_pointer[-1]; + Py_DECREF(value); + stack_pointer += -1; + DISPATCH(); + } - /* Free the arguments. */ - for (int i = 0; i < total_args; i++) { - Py_DECREF(args[i]); + TARGET(PUSH_EXC_INFO) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(PUSH_EXC_INFO); + 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; } - Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + else { + prev_exc = Py_None; + } + assert(PyExceptionInstance_Check(new_exc)); + exc_info->exc_value = Py_NewRef(new_exc); + stack_pointer[-1] = prev_exc; + stack_pointer[0] = new_exc; + stack_pointer += 1; DISPATCH(); } - TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) { - PyObject **args; - PyObject *self_or_null; - PyObject *callable; + TARGET(PUSH_NULL) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(PUSH_NULL); PyObject *res; - args = stack_pointer - oparg; - self_or_null = stack_pointer[-1 - oparg]; - callable = stack_pointer[-2 - oparg]; - assert(oparg == 0 || oparg == 1); - int total_args = oparg; - if (self_or_null != NULL) { - args--; - total_args++; - } - DEOPT_IF(total_args != 1, CALL); - 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, method->d_common.d_type), CALL); - DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); - STAT_INC(CALL, hit); - PyCFunction cfunc = meth->ml_meth; - // This is slower but CPython promises to check all non-vectorcall - // function calls. - if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; - } - res = _PyCFunction_TrampolineCall(cfunc, self, NULL); - _Py_LeaveRecursiveCallTstate(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(self); - Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); + res = NULL; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } - TARGET(CALL_METHOD_DESCRIPTOR_FAST) { + TARGET(RAISE_VARARGS) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RAISE_VARARGS); 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; - /* Builtin METH_FASTCALL methods, without keywords */ - 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, method->d_common.d_type), CALL); - STAT_INC(CALL, hit); - _PyCFunctionFast cfunc = - (_PyCFunctionFast)(void(*)(void))meth->ml_meth; - int nargs = total_args - 1; - res = cfunc(self, args + 1, nargs); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - /* Clear the stack of the arguments. */ - for (int i = 0; i < total_args; i++) { - Py_DECREF(args[i]); + args = &stack_pointer[-oparg]; + TIER_ONE_ONLY + PyObject *cause = NULL, *exc = NULL; + switch (oparg) { + case 2: + cause = args[1]; + /* fall through */ + case 1: + exc = args[0]; + /* fall through */ + case 0: + if (do_raise(tstate, exc, cause)) { + assert(oparg == 0); + monitor_reraise(tstate, frame, this_instr); + goto exception_unwind; + } + break; + default: + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); + break; + } + if (true) { stack_pointer += -oparg; goto error; } + } + + TARGET(RERAISE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RERAISE); + PyObject *exc; + PyObject **values; + exc = stack_pointer[-1]; + values = &stack_pointer[-1 - oparg]; + TIER_ONE_ONLY + assert(oparg >= 0 && oparg <= 2); + if (oparg) { + PyObject *lasti = values[0]; + if (PyLong_Check(lasti)) { + frame->instr_ptr = _PyCode_CODE(_PyFrame_GetCode(frame)) + PyLong_AsLong(lasti); + assert(!_PyErr_Occurred(tstate)); + } + else { + assert(PyLong_Check(lasti)); + _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); + GOTO_ERROR(error); + } + } + assert(exc && PyExceptionInstance_Check(exc)); + Py_INCREF(exc); + _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, this_instr); + goto exception_unwind; + } + + TARGET(RESERVED) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RESERVED); + TIER_ONE_ONLY + assert(0 && "Executing RESERVED instruction."); + Py_UNREACHABLE(); + } + + TARGET(RESUME) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RESUME); + PREDICTED(RESUME); + _Py_CODEUNIT *this_instr = next_instr - 1; + 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 = this_instr; + } + else { + if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { + CHECK_EVAL_BREAKER(); + } + this_instr->op.code = RESUME_CHECK; } - Py_DECREF(callable); - if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); - stack_pointer[-1] = res; - next_instr += 3; - CHECK_EVAL_BREAKER(); 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(RESUME_CHECK) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RESUME_CHECK); + static_assert(0 == 0, "incorrect cache size"); + #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(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++; + TARGET(RETURN_CONST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RETURN_CONST); + PyObject *value; + PyObject *retval; + // _LOAD_CONST + { + value = GETITEM(FRAME_CO_CONSTS, oparg); + Py_INCREF(value); } - 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; + // _POP_FRAME + retval = value; + { + #if TIER_ONE + assert(frame != &entry_frame); + #endif + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(EMPTY()); + _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); + _PyFrame_StackPush(frame, retval); + LOAD_SP(); + LOAD_IP(frame->return_offset); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } + #endif } - 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) + DISPATCH(); + } + + TARGET(RETURN_GENERATOR) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RETURN_GENERATOR); + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + if (gen == NULL) { + GOTO_ERROR(error); + } + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->instr_ptr = next_instr; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = tstate->current_frame = prev; + _PyFrame_StackPush(frame, (PyObject *)gen); + LOAD_IP(frame->return_offset); + goto resume_frame; + } + + TARGET(RETURN_VALUE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(RETURN_VALUE); + PyObject *retval; + retval = stack_pointer[-1]; + #if TIER_ONE + assert(frame != &entry_frame); + #endif + stack_pointer += -1; + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(EMPTY()); + _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); + _PyFrame_StackPush(frame, retval); + LOAD_SP(); + LOAD_IP(frame->return_offset); + #if LLTRACE && TIER_ONE + lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); + if (lltrace < 0) { + goto exit_unwind; + } + #endif + DISPATCH(); + } + + TARGET(SEND) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(SEND); + PREDICTED(SEND); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *receiver; + PyObject *v; + PyObject *retval; + // _SPECIALIZE_SEND + receiver = stack_pointer[-2]; { - 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; + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_Send(receiver, next_instr); + DISPATCH_SAME_OPARG(); } - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); + STAT_INC(SEND, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - /* 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); + // _SEND + v = stack_pointer[-1]; + { + assert(frame != &entry_frame); + if ((tstate->interp->eval_frame == NULL) && + (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && + ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) + { + PyGenObject *gen = (PyGenObject *)receiver; + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + 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; + assert(next_instr - this_instr + oparg <= UINT16_MAX); + frame->return_offset = (uint16_t)(next_instr - this_instr + oparg); + DISPATCH_INLINED(gen_frame); + } + if (Py_IsNone(v) && PyIter_Check(receiver)) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); } 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); + retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); + } + if (retval == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) + ) { + monitor_raise(tstate, frame, this_instr); + } + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + assert(retval != NULL); + JUMPBY(oparg); + } + else { + GOTO_ERROR(error); } } + Py_DECREF(v); + } + stack_pointer[-1] = retval; + DISPATCH(); + } + + TARGET(SEND_GEN) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(SEND_GEN); + static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); + 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(gen->gi_frame_state >= FRAME_EXECUTING, SEND); + STAT_INC(SEND, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + 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; + assert(next_instr - this_instr + oparg <= UINT16_MAX); + frame->return_offset = (uint16_t)(next_instr - this_instr + oparg); + DISPATCH_INLINED(gen_frame); + } + + TARGET(SETUP_ANNOTATIONS) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(SETUP_ANNOTATIONS); + int err; + PyObject *ann_dict; + if (LOCALS() == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); + if (true) goto error; + } + /* check if __annotations__ in locals()... */ + if (PyMapping_GetOptionalItem(LOCALS(), &_Py_ID(__annotations__), &ann_dict) < 0) goto error; + if (ann_dict == NULL) { + ann_dict = PyDict_New(); + if (ann_dict == NULL) goto error; + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + if (err) goto error; + } + else { + Py_DECREF(ann_dict); + } + DISPATCH(); + } + + TARGET(SET_ADD) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(SET_ADD); + 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; + stack_pointer += -1; + DISPATCH(); + } + + TARGET(SET_FUNCTION_ATTRIBUTE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(SET_FUNCTION_ATTRIBUTE); + PyObject *func; + PyObject *attr; + func = stack_pointer[-1]; + attr = stack_pointer[-2]; + assert(PyFunction_Check(func)); + PyFunctionObject *func_obj = (PyFunctionObject *)func; + switch(oparg) { + case MAKE_FUNCTION_CLOSURE: + assert(func_obj->func_closure == NULL); + func_obj->func_closure = attr; + break; + case MAKE_FUNCTION_ANNOTATIONS: + assert(func_obj->func_annotations == NULL); + func_obj->func_annotations = attr; + break; + case MAKE_FUNCTION_KWDEFAULTS: + assert(PyDict_CheckExact(attr)); + assert(func_obj->func_kwdefaults == NULL); + func_obj->func_kwdefaults = attr; + break; + case MAKE_FUNCTION_DEFAULTS: + assert(PyTuple_CheckExact(attr)); + assert(func_obj->func_defaults == NULL); + func_obj->func_defaults = attr; + break; + default: + Py_UNREACHABLE(); + } + stack_pointer[-2] = func; + stack_pointer += -1; + DISPATCH(); + } + + TARGET(SET_UPDATE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(SET_UPDATE); + 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; + stack_pointer += -1; + DISPATCH(); + } + + TARGET(STORE_ATTR) { + frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(STORE_ATTR); + PREDICTED(STORE_ATTR); + _Py_CODEUNIT *this_instr = next_instr - 5; + PyObject *owner; + PyObject *v; + // _SPECIALIZE_STORE_ATTR + owner = stack_pointer[-1]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + next_instr = this_instr; + _Py_Specialize_StoreAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ + } + // _STORE_ATTR + v = stack_pointer[-2]; + { + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + int err = PyObject_SetAttr(owner, name, v); + Py_DECREF(v); + Py_DECREF(owner); + if (err) goto pop_2_error; + } + stack_pointer += -2; + DISPATCH(); + } + + TARGET(STORE_ATTR_INSTANCE_VALUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(STORE_ATTR_INSTANCE_VALUE); + static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); + PyObject *owner; + PyObject *value; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + } + // _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(&this_instr[4].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); + } + stack_pointer += -2; + DISPATCH(); + } + + TARGET(STORE_ATTR_SLOT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(STORE_ATTR_SLOT); + static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); + PyObject *owner; + PyObject *value; + /* Skip 1 cache entry */ + // _GUARD_TYPE_VERSION + owner = stack_pointer[-1]; + { + uint32_t type_version = read_u32(&this_instr[2].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(&this_instr[4].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_pointer += -2; + DISPATCH(); + } + + TARGET(STORE_ATTR_WITH_HINT) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(STORE_ATTR_WITH_HINT); + static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); + PyObject *owner; + PyObject *value; + owner = stack_pointer[-1]; + value = stack_pointer[-2]; + uint32_t type_version = read_u32(&this_instr[2].cache); + uint16_t hint = read_u16(&this_instr[4].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); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, STORE_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); + PyObject *old_value; + uint64_t new_version; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(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); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + Py_DECREF(old_value); + STAT_INC(STORE_ATTR, hit); + /* Ensure dict is GC tracked if it needs to be */ + if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { + _PyObject_GC_TRACK(dict); + } + /* PEP 509 */ + dict->ma_version_tag = new_version; + Py_DECREF(owner); + stack_pointer += -2; + DISPATCH(); + } + + TARGET(STORE_DEREF) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_DEREF); + PyObject *v; + v = stack_pointer[-1]; + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + PyCell_SET(cell, v); + Py_XDECREF(oldobj); + stack_pointer += -1; + DISPATCH(); + } + + TARGET(STORE_FAST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_FAST); + PyObject *value; + value = stack_pointer[-1]; + SETLOCAL(oparg, value); + stack_pointer += -1; + DISPATCH(); + } + + TARGET(STORE_FAST_LOAD_FAST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_FAST_LOAD_FAST); + PyObject *value1; + PyObject *value2; + value1 = stack_pointer[-1]; + uint32_t oparg1 = oparg >> 4; + uint32_t oparg2 = oparg & 15; + SETLOCAL(oparg1, value1); + value2 = GETLOCAL(oparg2); + Py_INCREF(value2); + stack_pointer[-1] = value2; + DISPATCH(); + } + + TARGET(STORE_FAST_STORE_FAST) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_FAST_STORE_FAST); + 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); + SETLOCAL(oparg2, value2); + stack_pointer += -2; + DISPATCH(); + } + + TARGET(STORE_GLOBAL) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_GLOBAL); + PyObject *v; + v = stack_pointer[-1]; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + int err = PyDict_SetItem(GLOBALS(), name, v); + Py_DECREF(v); + if (err) goto pop_1_error; + stack_pointer += -1; + DISPATCH(); + } + + TARGET(STORE_NAME) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_NAME); + PyObject *v; + v = stack_pointer[-1]; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); + Py_DECREF(v); + if (true) goto pop_1_error; + } + if (PyDict_CheckExact(ns)) + err = PyDict_SetItem(ns, name, v); + else + err = PyObject_SetItem(ns, name, v); + Py_DECREF(v); + if (err) goto pop_1_error; + stack_pointer += -1; + DISPATCH(); + } + + TARGET(STORE_SLICE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(STORE_SLICE); + 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) { + err = 1; + } + else { + err = PyObject_SetItem(container, slice, v); + Py_DECREF(slice); + } + Py_DECREF(v); + Py_DECREF(container); + if (err) goto pop_4_error; + stack_pointer += -4; + DISPATCH(); + } + + TARGET(STORE_SUBSCR) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(STORE_SUBSCR); + PREDICTED(STORE_SUBSCR); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *sub; + PyObject *container; + PyObject *v; + // _SPECIALIZE_STORE_SUBSCR + sub = stack_pointer[-1]; + container = stack_pointer[-2]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_StoreSubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_SUBSCR, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - 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]); + // _STORE_SUBSCR + v = stack_pointer[-3]; + { + /* container[sub] = v */ + int err = PyObject_SetItem(container, sub, v); + Py_DECREF(v); + Py_DECREF(container); + Py_DECREF(sub); + if (err) goto pop_3_error; } - if (res == NULL) { STACK_SHRINK(oparg); goto pop_3_error; } - STACK_SHRINK(oparg); - STACK_SHRINK(2); - stack_pointer[-1] = res; - CHECK_EVAL_BREAKER(); + stack_pointer += -3; DISPATCH(); } - TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - GO_TO_INSTRUCTION(CALL_FUNCTION_EX); + TARGET(STORE_SUBSCR_DICT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(STORE_SUBSCR_DICT); + static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size"); + 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); + Py_DECREF(dict); + if (err) goto pop_3_error; + stack_pointer += -3; + DISPATCH(); } - TARGET(CALL_FUNCTION_EX) { - PREDICTED(CALL_FUNCTION_EX); - 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)); - if (!PyTuple_CheckExact(callargs)) { - if (check_args_iterable(tstate, func, callargs) < 0) { - goto error; - } - PyObject *tuple = PySequence_Tuple(callargs); - if (tuple == NULL) { - goto error; - } - Py_SETREF(callargs, tuple); - } - assert(PyTuple_CheckExact(callargs)); - EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func); - if (opcode == INSTRUMENTED_CALL_FUNCTION_EX && - !PyFunction_Check(func) && !PyMethod_Check(func) - ) { - PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ? - PyTuple_GET_ITEM(callargs, 0) : Py_None; - int err = _Py_call_instrumentation_2args( - tstate, PY_MONITORING_EVENT_CALL, - frame, next_instr-1, func, arg); - if (err) goto error; - result = PyObject_Call(func, callargs, kwargs); - if (result == NULL) { - _Py_call_instrumentation_exc2( - tstate, PY_MONITORING_EVENT_C_RAISE, - frame, next_instr-1, func, arg); - } - else { - int err = _Py_call_instrumentation_2args( - tstate, PY_MONITORING_EVENT_C_RETURN, - frame, next_instr-1, func, arg); - if (err < 0) { - Py_CLEAR(result); - } - } - } - else { - if (Py_TYPE(func) == &PyFunction_Type && - tstate->interp->eval_frame == NULL && - ((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) { - assert(PyTuple_CheckExact(callargs)); - Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); - int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags; - PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func)); - - _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate, - (PyFunctionObject *)func, locals, - nargs, callargs, kwargs); - // Need to manually shrink the stack since we exit with DISPATCH_INLINED. - STACK_SHRINK(oparg + 3); - if (new_frame == NULL) { - goto error; - } - frame->return_offset = 0; - DISPATCH_INLINED(new_frame); - } - result = PyObject_Call(func, callargs, kwargs); - } - Py_DECREF(func); - Py_DECREF(callargs); - Py_XDECREF(kwargs); - 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); - stack_pointer[-1] = result; - CHECK_EVAL_BREAKER(); + TARGET(STORE_SUBSCR_LIST_INT) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(STORE_SUBSCR_LIST_INT); + static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size"); + 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); + // Ensure nonnegative, zero-or-one-digit ints. + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), STORE_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + // Ensure index < len(list) + DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + PyObject *old_value = PyList_GET_ITEM(list, index); + PyList_SET_ITEM(list, index, value); + assert(old_value != NULL); + Py_DECREF(old_value); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + stack_pointer += -3; DISPATCH(); } - TARGET(MAKE_FUNCTION) { - PyObject *codeobj; - PyObject *func; - codeobj = stack_pointer[-1]; - - PyFunctionObject *func_obj = (PyFunctionObject *) - PyFunction_New(codeobj, GLOBALS()); + TARGET(SWAP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(SWAP); + 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; + DISPATCH(); + } - Py_DECREF(codeobj); - if (func_obj == NULL) { - goto error; + TARGET(TO_BOOL) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL); + PREDICTED(TO_BOOL); + _Py_CODEUNIT *this_instr = next_instr - 4; + PyObject *value; + PyObject *res; + // _SPECIALIZE_TO_BOOL + value = stack_pointer[-1]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_ToBool(value, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(TO_BOOL, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ } - - _PyFunction_SetVersion( - func_obj, ((PyCodeObject *)codeobj)->co_version); - func = (PyObject *)func_obj; - stack_pointer[-1] = func; + // _TO_BOOL + { + int err = PyObject_IsTrue(value); + Py_DECREF(value); + if (err < 0) goto pop_1_error; + res = err ? Py_True : Py_False; + } + stack_pointer[-1] = res; DISPATCH(); } - TARGET(SET_FUNCTION_ATTRIBUTE) { - PyObject *func; - PyObject *attr; - func = stack_pointer[-1]; - attr = stack_pointer[-2]; - assert(PyFunction_Check(func)); - PyFunctionObject *func_obj = (PyFunctionObject *)func; - switch(oparg) { - case MAKE_FUNCTION_CLOSURE: - assert(func_obj->func_closure == NULL); - func_obj->func_closure = attr; - break; - case MAKE_FUNCTION_ANNOTATIONS: - assert(func_obj->func_annotations == NULL); - func_obj->func_annotations = attr; - break; - case MAKE_FUNCTION_KWDEFAULTS: - assert(PyDict_CheckExact(attr)); - assert(func_obj->func_kwdefaults == NULL); - func_obj->func_kwdefaults = attr; - break; - case MAKE_FUNCTION_DEFAULTS: - assert(PyTuple_CheckExact(attr)); - assert(func_obj->func_defaults == NULL); - func_obj->func_defaults = attr; - break; - default: - Py_UNREACHABLE(); - } - STACK_SHRINK(1); - stack_pointer[-1] = func; + TARGET(TO_BOOL_ALWAYS_TRUE) { + _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL_ALWAYS_TRUE); + static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); + PyObject *value; + PyObject *res; + value = stack_pointer[-1]; + uint32_t version = read_u32(&this_instr[2].cache); + // This one is a bit weird, because we expect *some* failures: + assert(version); + DEOPT_IF(Py_TYPE(value)->tp_version_tag != version, TO_BOOL); + STAT_INC(TO_BOOL, hit); + Py_DECREF(value); + res = Py_True; + stack_pointer[-1] = res; DISPATCH(); } - TARGET(RETURN_GENERATOR) { - assert(PyFunction_Check(frame->f_funcobj)); - PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; - PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); - if (gen == NULL) { - goto error; - } - assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - _PyFrame_Copy(frame, gen_frame); - assert(frame->frame_obj == NULL); - gen->gi_frame_state = FRAME_CREATED; - gen_frame->owner = FRAME_OWNED_BY_GENERATOR; - _Py_LeaveRecursiveCallPy(tstate); - assert(frame != &entry_frame); - _PyInterpreterFrame *prev = frame->previous; - _PyThreadState_PopFrame(tstate, frame); - frame = tstate->current_frame = prev; - _PyFrame_StackPush(frame, (PyObject *)gen); - goto resume_frame; + TARGET(TO_BOOL_BOOL) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL_BOOL); + static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); + PyObject *value; + value = stack_pointer[-1]; + DEOPT_IF(!PyBool_Check(value), TO_BOOL); + STAT_INC(TO_BOOL, hit); + DISPATCH(); } - TARGET(BUILD_SLICE) { - 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); - Py_XDECREF(step); - if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - STACK_SHRINK(((oparg == 3) ? 1 : 0)); - STACK_SHRINK(1); - stack_pointer[-1] = slice; + TARGET(TO_BOOL_INT) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL_INT); + static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); + 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)) { + assert(_Py_IsImmortal(value)); + res = Py_False; + } + else { + Py_DECREF(value); + res = Py_True; + } + stack_pointer[-1] = res; DISPATCH(); } - TARGET(CONVERT_VALUE) { + TARGET(TO_BOOL_LIST) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL_LIST); + static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; - PyObject *result; + PyObject *res; value = stack_pointer[-1]; - convertion_func_ptr conv_fn; - assert(oparg >= FVC_STR && oparg <= FVC_ASCII); - conv_fn = CONVERSION_FUNCTIONS[oparg]; - result = conv_fn(value); + DEOPT_IF(!PyList_CheckExact(value), TO_BOOL); + STAT_INC(TO_BOOL, hit); + res = Py_SIZE(value) ? Py_True : Py_False; Py_DECREF(value); - if (result == NULL) goto pop_1_error; - stack_pointer[-1] = result; + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(TO_BOOL_NONE) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL_NONE); + static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); + 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); + res = Py_False; + stack_pointer[-1] = res; DISPATCH(); } - TARGET(FORMAT_SIMPLE) { + TARGET(TO_BOOL_STR) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(TO_BOOL_STR); + static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); 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)) { - res = PyObject_Format(value, NULL); - Py_DECREF(value); - if (res == NULL) goto pop_1_error; + DEOPT_IF(!PyUnicode_CheckExact(value), TO_BOOL); + STAT_INC(TO_BOOL, hit); + if (value == &_Py_STR(empty)) { + assert(_Py_IsImmortal(value)); + res = Py_False; } else { - res = value; + assert(Py_SIZE(value)); + Py_DECREF(value); + res = Py_True; } stack_pointer[-1] = res; DISPATCH(); } - TARGET(FORMAT_WITH_SPEC) { - PyObject *fmt_spec; + TARGET(UNARY_INVERT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(UNARY_INVERT); PyObject *value; PyObject *res; - fmt_spec = stack_pointer[-1]; - value = stack_pointer[-2]; - res = PyObject_Format(value, fmt_spec); + value = stack_pointer[-1]; + res = PyNumber_Invert(value); Py_DECREF(value); - Py_DECREF(fmt_spec); - if (res == NULL) goto pop_2_error; - STACK_SHRINK(1); + if (res == NULL) goto pop_1_error; stack_pointer[-1] = res; DISPATCH(); } - TARGET(COPY) { - PyObject *bottom; - PyObject *top; - bottom = stack_pointer[-1 - (oparg-1)]; - assert(oparg > 0); - top = Py_NewRef(bottom); - STACK_GROW(1); - stack_pointer[-1] = top; + TARGET(UNARY_NEGATIVE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(UNARY_NEGATIVE); + PyObject *value; + PyObject *res; + value = stack_pointer[-1]; + res = PyNumber_Negative(value); + Py_DECREF(value); + if (res == NULL) goto pop_1_error; + stack_pointer[-1] = res; DISPATCH(); } - TARGET(BINARY_OP) { - PREDICTED(BINARY_OP); - static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); - PyObject *rhs; - PyObject *lhs; + TARGET(UNARY_NOT) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(UNARY_NOT); + PyObject *value; 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)) { - next_instr--; - _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY); - DISPATCH_SAME_OPARG(); - } - STAT_INC(BINARY_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache->counter); - #endif /* ENABLE_SPECIALIZATION */ - 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; - STACK_SHRINK(1); + value = stack_pointer[-1]; + assert(PyBool_Check(value)); + res = Py_IsFalse(value) ? Py_True : Py_False; stack_pointer[-1] = res; - next_instr += 1; DISPATCH(); } - TARGET(SWAP) { - 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; + TARGET(UNPACK_EX) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(UNPACK_EX); + PyObject *seq; + seq = stack_pointer[-1]; + int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); + PyObject **top = stack_pointer + totalargs - 1; + int res = _PyEval_UnpackIterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); + Py_DECREF(seq); + if (res == 0) goto pop_1_error; + stack_pointer += (oparg >> 8) + (oparg & 0xFF); DISPATCH(); } - TARGET(INSTRUMENTED_INSTRUCTION) { - int next_opcode = _Py_call_instrumentation_instruction( - tstate, frame, next_instr-1); - if (next_opcode < 0) goto error; - next_instr--; - if (_PyOpcode_Caches[next_opcode]) { - _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1); - INCREMENT_ADAPTIVE_COUNTER(cache->counter); + TARGET(UNPACK_SEQUENCE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(UNPACK_SEQUENCE); + PREDICTED(UNPACK_SEQUENCE); + _Py_CODEUNIT *this_instr = next_instr - 2; + PyObject *seq; + // _SPECIALIZE_UNPACK_SEQUENCE + seq = stack_pointer[-1]; + { + uint16_t counter = read_u16(&this_instr[1].cache); + TIER_ONE_ONLY + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr = this_instr; + _Py_Specialize_UnpackSequence(seq, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(UNPACK_SEQUENCE, deferred); + DECREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); + #endif /* ENABLE_SPECIALIZATION */ + (void)seq; + (void)counter; } - assert(next_opcode > 0 && next_opcode < 256); - opcode = next_opcode; - DISPATCH_GOTO(); - } - - TARGET(INSTRUMENTED_JUMP_FORWARD) { - INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); + // _UNPACK_SEQUENCE + { + PyObject **top = stack_pointer + oparg - 1; + int res = _PyEval_UnpackIterable(tstate, seq, oparg, -1, top); + Py_DECREF(seq); + if (res == 0) goto pop_1_error; + } + stack_pointer += -1 + oparg; DISPATCH(); } - TARGET(INSTRUMENTED_JUMP_BACKWARD) { - CHECK_EVAL_BREAKER(); - INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); + TARGET(UNPACK_SEQUENCE_LIST) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(UNPACK_SEQUENCE_LIST); + static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); + 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); + PyObject **items = _PyList_ITEMS(seq); + for (int i = oparg; --i >= 0; ) { + *values++ = Py_NewRef(items[i]); + } + Py_DECREF(seq); + stack_pointer += -1 + oparg; DISPATCH(); } - TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - PyObject *cond = POP(); - assert(PyBool_Check(cond)); - _Py_CODEUNIT *here = next_instr - 1; - 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; + TARGET(UNPACK_SEQUENCE_TUPLE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(UNPACK_SEQUENCE_TUPLE); + static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); + 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); + PyObject **items = _PyTuple_ITEMS(seq); + for (int i = oparg; --i >= 0; ) { + *values++ = Py_NewRef(items[i]); + } + Py_DECREF(seq); + stack_pointer += -1 + oparg; DISPATCH(); } - TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - PyObject *cond = POP(); - assert(PyBool_Check(cond)); - _Py_CODEUNIT *here = next_instr - 1; - 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; + TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(UNPACK_SEQUENCE_TWO_TUPLE); + static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); + 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); + STAT_INC(UNPACK_SEQUENCE, hit); + values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); + values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); + Py_DECREF(seq); + stack_pointer += -1 + oparg; DISPATCH(); } - TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - PyObject *value = POP(); - _Py_CODEUNIT *here = next_instr - 1; - int flag = Py_IsNone(value); - int offset; - 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); + TARGET(WITH_EXCEPT_START) { + frame->instr_ptr = next_instr; next_instr += 1; - DISPATCH(); - } - - TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - PyObject *value = POP(); - _Py_CODEUNIT *here = next_instr-1; - int offset; - int nflag = Py_IsNone(value); - if (nflag) { - offset = 0; + INSTRUCTION_STATS(WITH_EXCEPT_START); + 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 + - lasti: THIRD = lasti of exception in exc_info() + - exit_func: FOURTH = the context.__exit__ bound method + We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). + Then we push the __exit__ return value. + */ + PyObject *exc, *tb; + assert(val && PyExceptionInstance_Check(val)); + exc = PyExceptionInstance_Class(val); + tb = PyException_GetTraceback(val); + if (tb == NULL) { + tb = Py_None; } else { - Py_DECREF(value); - offset = oparg; + Py_DECREF(tb); } - #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; + assert(PyLong_Check(lasti)); + (void)lasti; // Shut up compiler warning if asserts are off + PyObject *stack[4] = {NULL, exc, val, tb}; + res = PyObject_Vectorcall(exit_func, stack + 1, + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + if (res == NULL) goto error; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } - TARGET(EXTENDED_ARG) { - assert(oparg); - opcode = next_instr->op.code; - oparg = oparg << 8 | next_instr->op.arg; - PRE_DISPATCH_GOTO(); - DISPATCH_GOTO(); - } - - TARGET(CACHE) { - assert(0 && "Executing a cache."); - Py_UNREACHABLE(); - } - - TARGET(RESERVED) { - assert(0 && "Executing RESERVED instruction."); - Py_UNREACHABLE(); + TARGET(YIELD_VALUE) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(YIELD_VALUE); + 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. + assert(frame != &entry_frame); + frame->instr_ptr = next_instr; + PyGenObject *gen = _PyFrame_GetGenerator(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + gen->gi_frame_state = FRAME_SUSPENDED + oparg; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + /* We don't know which of these is relevant here, so keep them equal */ + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + goto resume_frame; } +#undef TIER_ONE diff --git a/Python/getargs.c b/Python/getargs.c index d590e2e153389e..0c4ce282f48764 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1,9 +1,11 @@ /* New getargs implementation */ +#define PY_CXX_CONST const #include "Python.h" #include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_dict.h" // _PyDict_HasOnlyStringKeys() +#include "pycore_modsupport.h" // export _PyArg_NoKeywords() #include "pycore_pylifecycle.h" // _PyArg_Fini #include "pycore_tuple.h" // _PyTuple_ITEMS() @@ -11,10 +13,10 @@ PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, - const char *, char **, ...); + const char *, const char * const *, ...); PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list); PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, - const char *, char **, va_list); + const char *, const char * const *, va_list); #define FLAG_COMPAT 1 @@ -46,14 +48,14 @@ static void seterror(Py_ssize_t, const char *, int *, const char *, const char * static const char *convertitem(PyObject *, const char **, va_list *, int, int *, char *, size_t, freelist_t *); static const char *converttuple(PyObject *, const char **, va_list *, int, - int *, char *, size_t, int, freelist_t *); + int *, char *, size_t, freelist_t *); static const char *convertsimple(PyObject *, const char **, va_list *, int, char *, size_t, freelist_t *); static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **); static int getbuffer(PyObject *, Py_buffer *, const char**); static int vgetargskeywords(PyObject *, PyObject *, - const char *, char **, va_list *, int); + const char *, const char * const *, va_list *, int); static int vgetargskeywordsfast(PyObject *, PyObject *, struct _PyArg_Parser *, va_list *, int); static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, @@ -453,7 +455,7 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, static const char * converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, - int *levels, char *msgbuf, size_t bufsize, int toplevel, + int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist) { int level = 0; @@ -476,14 +478,13 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } else if (c == ':' || c == ';' || c == '\0') break; - else if (level == 0 && Py_ISALPHA(c)) + else if (level == 0 && Py_ISALPHA(c) && c != 'e') n++; } if (!PySequence_Check(arg) || PyBytes_Check(arg)) { levels[0] = 0; PyOS_snprintf(msgbuf, bufsize, - toplevel ? "expected %d arguments, not %.50s" : "must be %d-item sequence, not %.50s", n, arg == Py_None ? "None" : Py_TYPE(arg)->tp_name); @@ -493,18 +494,9 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, len = PySequence_Size(arg); if (len != n) { levels[0] = 0; - if (toplevel) { - PyOS_snprintf(msgbuf, bufsize, - "expected %d argument%s, not %zd", - n, - n == 1 ? "" : "s", - len); - } - else { - PyOS_snprintf(msgbuf, bufsize, - "must be sequence of length %d, not %zd", - n, len); - } + PyOS_snprintf(msgbuf, bufsize, + "must be sequence of length %d, not %zd", + n, len); return msgbuf; } @@ -547,7 +539,7 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, if (*format == '(' /* ')' */) { format++; msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, - bufsize, 0, freelist); + bufsize, freelist); if (msg == NULL) format++; } @@ -1186,17 +1178,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, arg, msgbuf, bufsize); format++; - /* Caller is interested in Py_buffer, and the object - supports it directly. */ + /* Caller is interested in Py_buffer, and the object supports it + directly. The request implicitly asks for PyBUF_SIMPLE, so the + result is C-contiguous with format 'B'. */ if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) { PyErr_Clear(); return converterr("read-write bytes-like object", arg, msgbuf, bufsize); } - if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { - PyBuffer_Release((Py_buffer*)p); - return converterr("contiguous buffer", arg, msgbuf, bufsize); - } + assert(PyBuffer_IsContiguous((Py_buffer *)p, 'C')); if (addcleanup(p, freelist, cleanup_buffer)) { return converterr( "(cleanup problem)", @@ -1241,15 +1231,12 @@ convertbuffer(PyObject *arg, const void **p, const char **errmsg) static int getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) { + /* PyBUF_SIMPLE implies C-contiguous */ if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { *errmsg = "bytes-like object"; return -1; } - if (!PyBuffer_IsContiguous(view, 'C')) { - PyBuffer_Release(view); - *errmsg = "contiguous buffer"; - return -1; - } + assert(PyBuffer_IsContiguous(view, 'C')); return 0; } @@ -1261,7 +1248,7 @@ int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, - char **kwlist, ...) + const char * const *kwlist, ...) { int retval; va_list va; @@ -1285,7 +1272,7 @@ int _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, - char **kwlist, ...) + const char * const *kwlist, ...) { int retval; va_list va; @@ -1311,7 +1298,7 @@ int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, - char **kwlist, va_list va) + const char * const *kwlist, va_list va) { int retval; va_list lva; @@ -1336,7 +1323,7 @@ int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, - char **kwlist, va_list va) + const char * const *kwlist, va_list va) { int retval; va_list lva; @@ -1474,7 +1461,7 @@ PyArg_ValidateKeywordArguments(PyObject *kwargs) static int vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, - char **kwlist, va_list *p_va, int flags) + const char * const *kwlist, va_list *p_va, int flags) { char msgbuf[512]; int levels[32]; @@ -1729,7 +1716,7 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, return cleanreturn(0, &freelist); } for (i = pos; i < len; i++) { - if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) { + if (PyUnicode_EqualToUTF8(key, kwlist[i])) { match = 1; break; } @@ -1881,8 +1868,9 @@ new_kwtuple(const char * const *keywords, int total, int pos) } static int -_parser_init(struct _PyArg_Parser *parser) +_parser_init(void *arg) { + struct _PyArg_Parser *parser = (struct _PyArg_Parser *)arg; const char * const *keywords = parser->keywords; assert(keywords != NULL); assert(parser->pos == 0 && @@ -1893,7 +1881,7 @@ _parser_init(struct _PyArg_Parser *parser) int len, pos; if (scan_keywords(keywords, &len, &pos) < 0) { - return 0; + return -1; } const char *fname, *custommsg = NULL; @@ -1902,7 +1890,7 @@ _parser_init(struct _PyArg_Parser *parser) assert(parser->fname == NULL); if (parse_format(parser->format, len, pos, &fname, &custommsg, &min, &max) < 0) { - return 0; + return -1; } } else { @@ -1915,7 +1903,7 @@ _parser_init(struct _PyArg_Parser *parser) if (kwtuple == NULL) { kwtuple = new_kwtuple(keywords, len, pos); if (kwtuple == NULL) { - return 0; + return -1; } owned = 1; } @@ -1929,40 +1917,27 @@ _parser_init(struct _PyArg_Parser *parser) parser->min = min; parser->max = max; parser->kwtuple = kwtuple; - parser->initialized = owned ? 1 : -1; + parser->is_kwtuple_owned = owned; assert(parser->next == NULL); - parser->next = _PyRuntime.getargs.static_parsers; - _PyRuntime.getargs.static_parsers = parser; - return 1; + parser->next = _Py_atomic_load_ptr(&_PyRuntime.getargs.static_parsers); + do { + // compare-exchange updates parser->next on failure + } while (_Py_atomic_compare_exchange_ptr(&_PyRuntime.getargs.static_parsers, + &parser->next, parser)); + return 0; } static int parser_init(struct _PyArg_Parser *parser) { - // volatile as it can be modified by other threads - // and should not be optimized or reordered by compiler - if (*((volatile int *)&parser->initialized)) { - assert(parser->kwtuple != NULL); - return 1; - } - PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK); - // Check again if another thread initialized the parser - // while we were waiting for the lock. - if (*((volatile int *)&parser->initialized)) { - assert(parser->kwtuple != NULL); - PyThread_release_lock(_PyRuntime.getargs.mutex); - return 1; - } - int ret = _parser_init(parser); - PyThread_release_lock(_PyRuntime.getargs.mutex); - return ret; + return _PyOnceFlag_CallOnce(&parser->once, &_parser_init, parser); } static void parser_clear(struct _PyArg_Parser *parser) { - if (parser->initialized == 1) { + if (parser->is_kwtuple_owned) { Py_CLEAR(parser->kwtuple); } } @@ -2029,7 +2004,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, return 0; } - if (!parser_init(parser)) { + if (parser_init(parser) < 0) { return 0; } @@ -2262,7 +2237,7 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, args = buf; } - if (!parser_init(parser)) { + if (parser_init(parser) < 0) { return NULL; } @@ -2439,7 +2414,7 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, args = buf; } - if (!parser_init(parser)) { + if (parser_init(parser) < 0) { return NULL; } @@ -2522,7 +2497,7 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, * * Otherwise, we leave a place at `buf[vararg]` for vararg tuple * so the index is `i + 1`. */ - if (nargs < vararg) { + if (nargs < vararg && i != vararg) { buf[i] = current_arg; } else { diff --git a/Python/hashtable.c b/Python/hashtable.c index 8f5e8168ba1339..faf68fe4ff0bca 100644 --- a/Python/hashtable.c +++ b/Python/hashtable.c @@ -45,7 +45,7 @@ */ #include "Python.h" -#include "pycore_hashtable.h" +#include "pycore_hashtable.h" // export _Py_hashtable_new() #include "pycore_pyhash.h" // _Py_HashPointerRaw() #define HASHTABLE_MIN_SIZE 16 diff --git a/Python/import.c b/Python/import.c index 5636968ed9e63b..2dd95d8364a0be 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1,7 +1,6 @@ /* 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() @@ -17,7 +16,7 @@ #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 @@ -253,18 +252,21 @@ import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *n NOTE: because of this, initializing must be set *before* stuffing the new module in sys.modules. */ - spec = PyObject_GetAttr(mod, &_Py_ID(__spec__)); - int busy = _PyModuleSpec_IsInitializing(spec); - Py_XDECREF(spec); - if (busy) { - /* Wait until module is done importing. */ - PyObject *value = PyObject_CallMethodOneArg( - IMPORTLIB(interp), &_Py_ID(_lock_unlock_module), name); - if (value == NULL) { - return -1; - } - Py_DECREF(value); + int rc = PyObject_GetOptionalAttr(mod, &_Py_ID(__spec__), &spec); + if (rc > 0) { + rc = _PyModuleSpec_IsInitializing(spec); + Py_DECREF(spec); + } + if (rc <= 0) { + return rc; + } + /* Wait until module is done importing. */ + PyObject *value = PyObject_CallMethodOneArg( + IMPORTLIB(interp), &_Py_ID(_lock_unlock_module), name); + if (value == NULL) { + return -1; } + Py_DECREF(value); return 0; } @@ -396,8 +398,8 @@ remove_module(PyThreadState *tstate, PyObject *name) PyObject *modules = MODULES(tstate->interp); if (PyDict_CheckExact(modules)) { - PyObject *mod = _PyDict_Pop(modules, name, Py_None); - Py_XDECREF(mod); + // Error is reported to the caller + (void)PyDict_Pop(modules, name, NULL); } else if (PyMapping_DelItem(modules, name) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { @@ -416,11 +418,7 @@ remove_module(PyThreadState *tstate, PyObject *name) Py_ssize_t _PyImport_GetNextModuleIndex(void) { - PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK); - LAST_MODULE_INDEX++; - Py_ssize_t index = LAST_MODULE_INDEX; - PyThread_release_lock(EXTENSIONS.mutex); - return index; + return _Py_atomic_add_ssize(&LAST_MODULE_INDEX, 1) + 1; } static const char * @@ -585,7 +583,7 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp) if (PyList_SetSlice(MODULES_BY_INDEX(interp), 0, PyList_GET_SIZE(MODULES_BY_INDEX(interp)), NULL)) { - PyErr_WriteUnraisable(MODULES_BY_INDEX(interp)); + PyErr_FormatUnraisable("Exception ignored on clearing interpreters module list"); } } @@ -880,13 +878,13 @@ gets even messier. static inline void extensions_lock_acquire(void) { - PyThread_acquire_lock(_PyRuntime.imports.extensions.mutex, WAIT_LOCK); + PyMutex_Lock(&_PyRuntime.imports.extensions.mutex); } static inline void extensions_lock_release(void) { - PyThread_release_lock(_PyRuntime.imports.extensions.mutex); + PyMutex_Unlock(&_PyRuntime.imports.extensions.mutex); } /* Magic for extension modules (built-in as well as dynamically @@ -2373,11 +2371,11 @@ get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, if (nhooks < 0) return NULL; /* Shouldn't happen */ - importer = PyDict_GetItemWithError(path_importer_cache, p); - if (importer != NULL || _PyErr_Occurred(tstate)) { - return Py_XNewRef(importer); + if (PyDict_GetItemRef(path_importer_cache, p, &importer) != 0) { + // found or error + return importer; } - + // not found /* set path_importer_cache[p] to None to avoid recursion */ if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) return NULL; @@ -2566,7 +2564,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level { PyObject *abs_name; PyObject *package = NULL; - PyObject *spec; + PyObject *spec = NULL; Py_ssize_t last_dot; PyObject *base; int level_up; @@ -2579,20 +2577,18 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); goto error; } - package = PyDict_GetItemWithError(globals, &_Py_ID(__package__)); + if (PyDict_GetItemRef(globals, &_Py_ID(__package__), &package) < 0) { + goto error; + } if (package == Py_None) { + Py_DECREF(package); package = NULL; } - else if (package == NULL && _PyErr_Occurred(tstate)) { - goto error; - } - spec = PyDict_GetItemWithError(globals, &_Py_ID(__spec__)); - if (spec == NULL && _PyErr_Occurred(tstate)) { + if (PyDict_GetItemRef(globals, &_Py_ID(__spec__), &spec) < 0) { goto error; } if (package != NULL) { - Py_INCREF(package); if (!PyUnicode_Check(package)) { _PyErr_SetString(tstate, PyExc_TypeError, "package must be a string"); @@ -2636,16 +2632,15 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level goto error; } - package = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); + if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &package) < 0) { + goto error; + } if (package == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_KeyError, - "'__name__' not in globals"); - } + _PyErr_SetString(tstate, PyExc_KeyError, + "'__name__' not in globals"); goto error; } - Py_INCREF(package); if (!PyUnicode_Check(package)) { _PyErr_SetString(tstate, PyExc_TypeError, "__name__ must be a string"); @@ -2693,6 +2688,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level } } + Py_XDECREF(spec); base = PyUnicode_Substring(package, 0, last_dot); Py_DECREF(package); if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) { @@ -2709,6 +2705,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level "with no known parent package"); error: + Py_XDECREF(spec); Py_XDECREF(package); return NULL; } @@ -3157,13 +3154,13 @@ _PyImport_FiniCore(PyInterpreterState *interp) int verbose = _PyInterpreterState_GetConfig(interp)->verbose; if (_PySys_ClearAttrString(interp, "meta_path", verbose) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing sys.meta_path"); } // XXX Pull in most of finalize_modules() in pylifecycle.c. if (_PySys_ClearAttrString(interp, "modules", verbose) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing sys.modules"); } if (IMPORT_LOCK(interp) != NULL) { @@ -3243,10 +3240,10 @@ _PyImport_FiniExternal(PyInterpreterState *interp) // XXX Uninstall importlib metapath importers here? if (_PySys_ClearAttrString(interp, "path_importer_cache", verbose) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing sys.path_importer_cache"); } if (_PySys_ClearAttrString(interp, "path_hooks", verbose) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing sys.path_hooks"); } } 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 a0467f51d4834e..06e317907b8ec9 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -24,6 +24,109 @@ # 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 +#ifdef Py_DEBUG + SPEC(run_presite, WSTR_OPT), +#endif + {NULL, 0, 0}, +}; + +#undef SPEC + + /* --- Command line options --------------------------------------- */ /* Short usage message (with %s for argv0) */ @@ -130,13 +233,22 @@ 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\ \n\ -X pystats: Enable pystats collection at startup." #endif +#ifdef Py_DEBUG +"\n\ +\n\ +-X presite=package.module: import this module before site.py is run." +#endif ; /* Envvars that don't have equivalent command-line options are listed first */ @@ -168,14 +280,21 @@ 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" -"PYTHONNODEBUGRANGES: If this variable is set, it disables the inclusion of the \n" +"PYTHONNODEBUGRANGES: if this variable is set, it disables the inclusion of the \n" " tables mapping extra location information (end line, start column offset \n" " and end column offset) to every instruction in code objects. This is useful \n" " when smaller code objects and pyc files are desired as well as suppressing the \n" " extra visual location indicators when the interpreter displays tracebacks.\n" +"PYTHON_FROZEN_MODULES : if this variable is set, it determines whether or not \n" +" frozen modules should be used. The default is \"on\" (or \"off\" if you are \n" +" running a local build).\n" +"PYTHON_COLORS : If this variable is set to 1, the interpreter will" +" colorize various kinds of output. Setting it to 0 deactivates this behavior.\n" "These variables have equivalent command-line parameters (see --help for details):\n" "PYTHONDEBUG : enable parser debug mode (-d)\n" "PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n" @@ -191,6 +310,9 @@ static const char usage_envvars[] = #ifdef Py_STATS "PYTHONSTATS : turns on statistics gathering\n" #endif +#ifdef Py_DEBUG +"PYTHON_PRESITE=pkg.mod : import this module before site.py is run\n" +#endif ; #if defined(MS_WINDOWS) @@ -633,6 +755,8 @@ 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 @@ -672,6 +796,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); @@ -681,6 +806,9 @@ PyConfig_Clear(PyConfig *config) CLEAR(config->run_module); CLEAR(config->run_filename); CLEAR(config->check_hash_pycs_mode); +#ifdef Py_DEBUG + CLEAR(config->run_presite); +#endif _PyWideStringList_Clear(&config->orig_argv); #undef CLEAR @@ -732,6 +860,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; } @@ -869,103 +998,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); -#ifdef Py_STATS - COPY_ATTR(_pystats); -#endif - -#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(); } @@ -978,113 +1051,58 @@ _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); -#ifdef Py_STATS - SET_ITEM_INT(_pystats); -#endif + 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 } @@ -1263,131 +1281,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; } - 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); -#ifdef Py_STATS - GET_UINT(_pystats); -#endif -#undef CHECK_VALUE -#undef GET_UINT -#undef GET_INT -#undef GET_WSTR -#undef GET_WSTR_OPT + if (config->hash_seed > MAX_HASH_SEED) { + config_dict_invalid_value("hash_seed"); + return -1; + } return 0; } @@ -1678,6 +1646,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) { @@ -1818,6 +1825,36 @@ config_init_pycache_prefix(PyConfig *config) } +#ifdef Py_DEBUG +static PyStatus +config_init_run_presite(PyConfig *config) +{ + assert(config->run_presite == NULL); + + const wchar_t *xoption = config_get_xoption(config, L"presite"); + if (xoption) { + const wchar_t *sep = wcschr(xoption, L'='); + if (sep && wcslen(sep) > 1) { + config->run_presite = _PyMem_RawWcsdup(sep + 1); + if (config->run_presite == NULL) { + return _PyStatus_NO_MEMORY(); + } + } + else { + // PYTHON_PRESITE env var ignored + // if "-X presite=" option is used + config->run_presite = NULL; + } + return _PyStatus_OK(); + } + + return CONFIG_GET_ENV_DUP(config, &config->run_presite, + L"PYTHON_PRESITE", + "PYTHON_PRESITE"); +} +#endif + + static PyStatus config_read_complex_options(PyConfig *config) { @@ -1860,12 +1897,29 @@ 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)) { return status; } } + +#ifdef Py_DEBUG + if (config->run_presite == NULL) { + status = config_init_run_presite(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } +#endif + return _PyStatus_OK(); } @@ -2083,6 +2137,19 @@ config_init_import(PyConfig *config, int compute_path_config) return status; } + const char *env = config_get_env(config, "PYTHON_FROZEN_MODULES"); + if (env == NULL) { + } + else if (strcmp(env, "on") == 0) { + config->use_frozen_modules = 1; + } + else if (strcmp(env, "off") == 0) { + config->use_frozen_modules = 0; + } else { + return PyStatus_Error("bad value for PYTHON_FROZEN_MODULES " + "(expected \"on\" or \"off\")"); + } + /* -X frozen_modules=[on|off] */ const wchar_t *value = config_get_xoption_value(config, L"frozen_modules"); if (value == NULL) { @@ -3114,6 +3181,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 0b974f6133ce7d..35b0e7a8f35c56 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -4,6 +4,7 @@ #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" @@ -18,17 +19,9 @@ /* Uncomment this to dump debugging output when assertions fail */ // #define INSTRUMENT_DEBUG 1 -PyObject _PyInstrumentation_DISABLE = -{ - .ob_refcnt = _Py_IMMORTAL_REFCNT, - .ob_type = &PyBaseObject_Type -}; +PyObject _PyInstrumentation_DISABLE = _PyObject_HEAD_INIT(&PyBaseObject_Type); -PyObject _PyInstrumentation_MISSING = -{ - .ob_refcnt = _Py_IMMORTAL_REFCNT, - .ob_type = &PyBaseObject_Type -}; +PyObject _PyInstrumentation_MISSING = _PyObject_HEAD_INIT(&PyBaseObject_Type); static const int8_t EVENT_FOR_OPCODE[256] = { [RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN, @@ -895,10 +888,27 @@ 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 @@ -1055,7 +1065,7 @@ _Py_call_instrumentation_jump( { assert(event == PY_MONITORING_EVENT_JUMP || event == PY_MONITORING_EVENT_BRANCH); - assert(frame->prev_instr == instr); + assert(frame->instr_ptr == instr); PyCodeObject *code = _PyFrame_GetCode(frame); int to = (int)(target - _PyCode_CODE(code)); PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT)); @@ -1068,9 +1078,9 @@ _Py_call_instrumentation_jump( if (err) { return NULL; } - if (frame->prev_instr != instr) { + if (frame->instr_ptr != instr) { /* The callback has caused a jump (by setting the line number) */ - return frame->prev_instr; + return frame->instr_ptr; } return target; } @@ -1120,7 +1130,6 @@ _Py_Instrumentation_GetLine(PyCodeObject *code, int index) int _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev) { - 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)); @@ -1135,6 +1144,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, int8_t line_delta = line_data->line_delta; int line = compute_line(code, i, line_delta); assert(line >= 0); + assert(prev != NULL); int prev_index = (int)(prev - _PyCode_CODE(code)); int prev_line = _Py_Instrumentation_GetLine(code, prev_index); if (prev_line == line) { @@ -1556,7 +1566,7 @@ _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; @@ -1564,6 +1574,7 @@ _Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) if (code->co_executors != NULL) { _PyCode_Clear_Executors(code); } + _Py_Executors_InvalidateDependency(interp, code); int code_len = (int)Py_SIZE(code); /* code->_co_firsttraceable >= code_len indicates * that no instrumentation can be inserted. @@ -1594,7 +1605,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); @@ -1761,6 +1772,10 @@ 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) { @@ -1775,7 +1790,13 @@ _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); + _Py_Executors_InvalidateAll(interp); return instrument_all_executing_code_objects(interp); } @@ -1803,14 +1824,32 @@ _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEvent 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; } + _Py_Executors_InvalidateDependency(interp, code); if (_Py_Instrument(code, interp)) { return -1; } return 0; } +int +_PyMonitoring_GetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet *events) +{ + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (check_tool(interp, tool_id)) { + return -1; + } + if (code->_co_monitoring == NULL) { + *events = 0; + return 0; + } + _Py_LocalMonitors *local = &code->_co_monitoring->local_monitors; + *events = get_local_events(local, tool_id); + return 0; +} + /*[clinic input] module monitoring [clinic start generated code]*/ @@ -2086,8 +2125,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; } diff --git a/Python/intrinsics.c b/Python/intrinsics.c index bbd79ec473f470..d3146973b75178 100644 --- a/Python/intrinsics.c +++ b/Python/intrinsics.c @@ -5,6 +5,7 @@ #include "pycore_frame.h" #include "pycore_function.h" #include "pycore_global_objects.h" +#include "pycore_compile.h" // _PyCompile_GetUnaryIntrinsicName, etc #include "pycore_intrinsics.h" // INTRINSIC_PRINT #include "pycore_pyerrors.h" // _PyErr_SetString() #include "pycore_runtime.h" // _Py_ID() @@ -269,7 +270,7 @@ _PyIntrinsics_BinaryFunctions[] = { #undef INTRINSIC_FUNC_ENTRY PyObject* -PyUnstable_GetUnaryIntrinsicName(int index) +_PyCompile_GetUnaryIntrinsicName(int index) { if (index < 0 || index > MAX_INTRINSIC_1) { return NULL; @@ -278,7 +279,7 @@ PyUnstable_GetUnaryIntrinsicName(int index) } PyObject* -PyUnstable_GetBinaryIntrinsicName(int index) +_PyCompile_GetBinaryIntrinsicName(int index) { if (index < 0 || index > MAX_INTRINSIC_2) { return NULL; diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index 9258091afc7c49..ccbb3eb3f7c82a 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -46,7 +46,7 @@ call_profile_func(_PyLegacyEventHandler *self, PyObject *arg) } static PyObject * -sys_profile_func2( +sys_profile_start( _PyLegacyEventHandler *self, PyObject *const *args, size_t nargsf, PyObject *kwnames ) { @@ -56,7 +56,17 @@ sys_profile_func2( } static PyObject * -sys_profile_func3( +sys_profile_throw( + _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_return( _PyLegacyEventHandler *self, PyObject *const *args, size_t nargsf, PyObject *kwnames ) { @@ -72,7 +82,7 @@ sys_profile_unwind( ) { assert(kwnames == NULL); assert(PyVectorcall_NARGS(nargsf) == 3); - return call_profile_func(self, Py_None); + return call_profile_func(self, NULL); } static PyObject * @@ -107,6 +117,35 @@ sys_profile_call_or_return( Py_RETURN_NONE; } +int +_PyEval_SetOpcodeTrace( + PyFrameObject *frame, + bool enable +) { + assert(frame != NULL); + assert(PyCode_Check(frame->f_frame->f_executable)); + + PyCodeObject *code = (PyCodeObject *)frame->f_frame->f_executable; + _PyMonitoringEventSet events = 0; + + if (_PyMonitoring_GetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, &events) < 0) { + return -1; + } + + if (enable) { + if (events & (1 << PY_MONITORING_EVENT_INSTRUCTION)) { + return 0; + } + events |= (1 << PY_MONITORING_EVENT_INSTRUCTION); + } else { + if (!(events & (1 << PY_MONITORING_EVENT_INSTRUCTION))) { + return 0; + } + events &= (~(1 << PY_MONITORING_EVENT_INSTRUCTION)); + } + return _PyMonitoring_SetLocalEvents(code, PY_MONITORING_SYS_TRACE_ID, events); +} + static PyObject * call_trace_func(_PyLegacyEventHandler *self, PyObject *arg) { @@ -120,6 +159,12 @@ call_trace_func(_PyLegacyEventHandler *self, PyObject *arg) "Missing frame when calling trace function."); return NULL; } + if (frame->f_trace_opcodes) { + if (_PyEval_SetOpcodeTrace(frame, true) != 0) { + return NULL; + } + } + Py_INCREF(frame); int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, arg); Py_DECREF(frame); @@ -154,7 +199,7 @@ sys_trace_exception_func( } static PyObject * -sys_trace_func2( +sys_trace_start( _PyLegacyEventHandler *self, PyObject *const *args, size_t nargsf, PyObject *kwnames ) { @@ -164,7 +209,7 @@ sys_trace_func2( } static PyObject * -sys_trace_func3( +sys_trace_throw( _PyLegacyEventHandler *self, PyObject *const *args, size_t nargsf, PyObject *kwnames ) { @@ -173,6 +218,16 @@ sys_trace_func3( return call_trace_func(self, Py_None); } +static PyObject * +sys_trace_unwind( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_trace_func(self, NULL); +} + static PyObject * sys_trace_return( _PyLegacyEventHandler *self, PyObject *const *args, @@ -210,11 +265,14 @@ sys_trace_instruction_func( "Missing frame when calling trace function."); return NULL; } - if (!frame->f_trace_opcodes) { + PyThreadState *tstate = _PyThreadState_GET(); + if (!tstate->c_tracefunc || !frame->f_trace_opcodes) { + if (_PyEval_SetOpcodeTrace(frame, false) != 0) { + return NULL; + } Py_RETURN_NONE; } Py_INCREF(frame); - PyThreadState *tstate = _PyThreadState_GET(); int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, Py_None); frame->f_lineno = 0; Py_DECREF(frame); @@ -373,12 +431,17 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) if (!tstate->interp->sys_profile_initialized) { tstate->interp->sys_profile_initialized = true; if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, - (vectorcallfunc)sys_profile_func2, PyTrace_CALL, + (vectorcallfunc)sys_profile_start, PyTrace_CALL, 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_RETURN, + (vectorcallfunc)sys_profile_throw, PyTrace_CALL, + PY_MONITORING_EVENT_PY_THROW, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_return, PyTrace_RETURN, PY_MONITORING_EVENT_PY_RETURN, PY_MONITORING_EVENT_PY_YIELD)) { return -1; } @@ -417,7 +480,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); } @@ -441,12 +505,12 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) if (!tstate->interp->sys_trace_initialized) { tstate->interp->sys_trace_initialized = true; if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, - (vectorcallfunc)sys_trace_func2, PyTrace_CALL, + (vectorcallfunc)sys_trace_start, PyTrace_CALL, PY_MONITORING_EVENT_PY_START, PY_MONITORING_EVENT_PY_RESUME)) { return -1; } if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, - (vectorcallfunc)sys_trace_func3, PyTrace_CALL, + (vectorcallfunc)sys_trace_throw, PyTrace_CALL, PY_MONITORING_EVENT_PY_THROW, -1)) { return -1; } @@ -471,7 +535,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) return -1; } if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, - (vectorcallfunc)sys_trace_func3, PyTrace_RETURN, + (vectorcallfunc)sys_trace_unwind, PyTrace_RETURN, PY_MONITORING_EVENT_PY_UNWIND, -1)) { return -1; } @@ -505,9 +569,15 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) (1 << PY_MONITORING_EVENT_PY_UNWIND) | (1 << PY_MONITORING_EVENT_PY_THROW) | (1 << PY_MONITORING_EVENT_STOP_ITERATION) | (1 << PY_MONITORING_EVENT_EXCEPTION_HANDLED); - if (tstate->interp->f_opcode_trace_set) { - events |= (1 << PY_MONITORING_EVENT_INSTRUCTION); + + PyFrameObject* frame = PyEval_GetFrame(); + if (frame->f_trace_opcodes) { + int ret = _PyEval_SetOpcodeTrace(frame, true); + if (ret != 0) { + return ret; + } } } + return _PyMonitoring_SetEvents(PY_MONITORING_SYS_TRACE_ID, events); } diff --git a/Python/lock.c b/Python/lock.c index 3dad2aa93b5cc9..e9279f0b92a5e7 100644 --- a/Python/lock.c +++ b/Python/lock.c @@ -21,7 +21,7 @@ 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 +#if Py_GIL_DISABLED static const int MAX_SPIN_COUNT = 40; #else static const int MAX_SPIN_COUNT = 0; @@ -295,3 +295,61 @@ PyEvent_WaitTimed(PyEvent *evt, _PyTime_t timeout_ns) return _Py_atomic_load_uint8(&evt->v) == _Py_LOCKED; } } + +static int +unlock_once(_PyOnceFlag *o, int res) +{ + // On success (res=0), we set the state to _Py_ONCE_INITIALIZED. + // On failure (res=-1), we reset the state to _Py_UNLOCKED. + uint8_t new_value; + switch (res) { + case -1: new_value = _Py_UNLOCKED; break; + case 0: new_value = _Py_ONCE_INITIALIZED; break; + default: { + Py_FatalError("invalid result from _PyOnceFlag_CallOnce"); + Py_UNREACHABLE(); + break; + } + } + + uint8_t old_value = _Py_atomic_exchange_uint8(&o->v, new_value); + if ((old_value & _Py_HAS_PARKED) != 0) { + // wake up anyone waiting on the once flag + _PyParkingLot_UnparkAll(&o->v); + } + return res; +} + +int +_PyOnceFlag_CallOnceSlow(_PyOnceFlag *flag, _Py_once_fn_t *fn, void *arg) +{ + uint8_t v = _Py_atomic_load_uint8(&flag->v); + for (;;) { + if (v == _Py_UNLOCKED) { + if (!_Py_atomic_compare_exchange_uint8(&flag->v, &v, _Py_LOCKED)) { + continue; + } + int res = fn(arg); + return unlock_once(flag, res); + } + + if (v == _Py_ONCE_INITIALIZED) { + return 0; + } + + // The once flag is initializing (locked). + assert((v & _Py_LOCKED)); + if (!(v & _Py_HAS_PARKED)) { + // We are the first waiter. Set the _Py_HAS_PARKED flag. + uint8_t new_value = v | _Py_HAS_PARKED; + if (!_Py_atomic_compare_exchange_uint8(&flag->v, &v, new_value)) { + continue; + } + v = new_value; + } + + // Wait for initialization to finish. + _PyParkingLot_Park(&flag->v, &v, sizeof(v), -1, NULL, 1); + v = _Py_atomic_load_uint8(&flag->v); + } +} 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/optimizer.c b/Python/optimizer.c index fbdbf7291784c4..d44e733bc346fa 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -107,11 +107,12 @@ error_optimize( _PyExecutorObject **exec, int Py_UNUSED(stack_entries)) { + assert(0); PyErr_Format(PyExc_SystemError, "Should never call error_optimize"); return -1; } -static PyTypeObject DefaultOptimizer_Type = { +PyTypeObject _PyDefaultOptimizer_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "noop_optimizer", .tp_basicsize = sizeof(_PyOptimizerObject), @@ -120,10 +121,10 @@ static PyTypeObject DefaultOptimizer_Type = { }; _PyOptimizerObject _PyOptimizer_Default = { - PyObject_HEAD_INIT(&DefaultOptimizer_Type) + PyObject_HEAD_INIT(&_PyDefaultOptimizer_Type) .optimize = error_optimize, - .resume_threshold = UINT16_MAX, - .backedge_threshold = UINT16_MAX, + .resume_threshold = INT16_MAX, + .backedge_threshold = INT16_MAX, }; _PyOptimizerObject * @@ -166,6 +167,7 @@ _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNI } _PyOptimizerObject *opt = interp->optimizer; _PyExecutorObject *executor = NULL; + /* Start optimizing at the destination to guarantee forward progress */ int err = opt->optimize(opt, code, dest, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame))); if (err <= 0) { assert(executor == NULL); @@ -220,27 +222,39 @@ typedef struct { static void counter_dealloc(_PyCounterExecutorObject *self) { + _Py_ExecutorClear((_PyExecutorObject *)self); Py_DECREF(self->optimizer); PyObject_Free(self); } -static PyTypeObject CounterExecutor_Type = { +static PyObject * +is_valid(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(((_PyExecutorObject *)self)->vm_data.valid); +} + +static PyMethodDef executor_methods[] = { + { "is_valid", is_valid, METH_NOARGS, NULL }, + { NULL, NULL }, +}; + +PyTypeObject _PyCounterExecutor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "counting_executor", .tp_basicsize = sizeof(_PyCounterExecutorObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, .tp_dealloc = (destructor)counter_dealloc, + .tp_methods = executor_methods, }; -static _PyInterpreterFrame * +static _Py_CODEUNIT * counter_execute(_PyExecutorObject *self, _PyInterpreterFrame *frame, PyObject **stack_pointer) { ((_PyCounterExecutorObject *)self)->optimizer->count++; _PyFrame_SetStackPointer(frame, stack_pointer); - frame->prev_instr = ((_PyCounterExecutorObject *)self)->next_instr - 1; Py_DECREF(self); - return frame; + return ((_PyCounterExecutorObject *)self)->next_instr; } static int @@ -252,7 +266,7 @@ counter_optimize( int Py_UNUSED(curr_stackentries) ) { - _PyCounterExecutorObject *executor = (_PyCounterExecutorObject *)_PyObject_New(&CounterExecutor_Type); + _PyCounterExecutorObject *executor = (_PyCounterExecutorObject *)_PyObject_New(&_PyCounterExecutor_Type); if (executor == NULL) { return -1; } @@ -261,6 +275,9 @@ counter_optimize( executor->optimizer = (_PyCounterOptimizerObject *)self; executor->next_instr = instr; *exec_ptr = (_PyExecutorObject *)executor; + _PyBloomFilter empty; + _Py_BloomFilter_Init(&empty); + _Py_ExecutorInit((_PyExecutorObject *)executor, &empty); return 1; } @@ -270,30 +287,30 @@ counter_get_counter(PyObject *self, PyObject *args) return PyLong_FromLongLong(((_PyCounterOptimizerObject *)self)->count); } -static PyMethodDef counter_methods[] = { +static PyMethodDef counter_optimizer_methods[] = { { "get_count", counter_get_counter, METH_NOARGS, NULL }, { NULL, NULL }, }; -static PyTypeObject CounterOptimizer_Type = { +PyTypeObject _PyCounterOptimizer_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "Counter optimizer", .tp_basicsize = sizeof(_PyCounterOptimizerObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, - .tp_methods = counter_methods, + .tp_methods = counter_optimizer_methods, .tp_dealloc = (destructor)PyObject_Del, }; PyObject * PyUnstable_Optimizer_NewCounter(void) { - _PyCounterOptimizerObject *opt = (_PyCounterOptimizerObject *)_PyObject_New(&CounterOptimizer_Type); + _PyCounterOptimizerObject *opt = (_PyCounterOptimizerObject *)_PyObject_New(&_PyCounterOptimizer_Type); if (opt == NULL) { return NULL; } opt->base.optimize = counter_optimize; - opt->base.resume_threshold = UINT16_MAX; + opt->base.resume_threshold = INT16_MAX; opt->base.backedge_threshold = 0; opt->count = 0; return (PyObject *)opt; @@ -303,11 +320,13 @@ PyUnstable_Optimizer_NewCounter(void) static void uop_dealloc(_PyUOpExecutorObject *self) { + _Py_ExecutorClear((_PyExecutorObject *)self); PyObject_Free(self); } -static const char * -uop_name(int index) { +const char * +_PyUOpName(int index) +{ if (index <= MAX_REAL_OPCODE) { return _PyOpcode_OpName[index]; } @@ -328,7 +347,7 @@ uop_item(_PyUOpExecutorObject *self, Py_ssize_t index) PyErr_SetNone(PyExc_IndexError); return NULL; } - const char *name = uop_name(self->trace[index].opcode); + const char *name = _PyUOpName(self->trace[index].opcode); if (name == NULL) { name = ""; } @@ -356,7 +375,7 @@ PySequenceMethods uop_as_sequence = { .sq_item = (ssizeargfunc)uop_item, }; -static PyTypeObject UOpExecutor_Type = { +PyTypeObject _PyUOpExecutor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "uop_executor", .tp_basicsize = sizeof(_PyUOpExecutorObject) - sizeof(_PyUOpInstruction), @@ -364,59 +383,64 @@ static PyTypeObject UOpExecutor_Type = { .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, .tp_dealloc = (destructor)uop_dealloc, .tp_as_sequence = &uop_as_sequence, + .tp_methods = executor_methods, }; -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; -} +/* TO DO -- Generate these tables */ +static const uint16_t +_PyUOp_Replacements[OPCODE_METADATA_SIZE] = { + [_ITER_JUMP_RANGE] = _GUARD_NOT_EXHAUSTED_RANGE, + [_ITER_JUMP_LIST] = _GUARD_NOT_EXHAUSTED_LIST, + [_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE, + [_FOR_ITER] = _FOR_ITER_TIER_TWO, +}; + +static const uint16_t +BRANCH_TO_GUARD[4][2] = { + [POP_JUMP_IF_FALSE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_TRUE_POP, + [POP_JUMP_IF_FALSE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_FALSE_POP, + [POP_JUMP_IF_TRUE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_FALSE_POP, + [POP_JUMP_IF_TRUE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_TRUE_POP, + [POP_JUMP_IF_NONE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_NOT_NONE_POP, + [POP_JUMP_IF_NONE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_NONE_POP, + [POP_JUMP_IF_NOT_NONE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_NONE_POP, + [POP_JUMP_IF_NOT_NONE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_NOT_NONE_POP, +}; #define TRACE_STACK_SIZE 5 +#define CONFIDENCE_RANGE 1000 +#define CONFIDENCE_CUTOFF 333 + +/* Returns 1 on success, + * 0 if it failed to produce a worthwhile trace, + * and -1 on an error. + */ static int translate_bytecode_to_trace( PyCodeObject *code, _Py_CODEUNIT *instr, _PyUOpInstruction *trace, - int buffer_size) + int buffer_size, + _PyBloomFilter *dependencies) { PyCodeObject *initial_code = code; + _Py_BloomFilter_Add(dependencies, initial_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; + int confidence = CONFIDENCE_RANGE; // Adjusted by branch instructions #ifdef Py_DEBUG - char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG"); + char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); int lltrace = 0; - if (uop_debug != NULL && *uop_debug >= '0') { - lltrace = *uop_debug - '0'; // TODO: Parse an int and all that + if (python_lltrace != NULL && *python_lltrace >= '0') { + lltrace = *python_lltrace - '0'; // TODO: Parse an int and all that } #endif @@ -427,52 +451,41 @@ translate_bytecode_to_trace( #define DPRINTF(level, ...) #endif -#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND) \ + +#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \ DPRINTF(2, \ " ADD_TO_TRACE(%s, %d, %" PRIu64 ")\n", \ - uop_name(OPCODE), \ + _PyUOpName(OPCODE), \ (OPARG), \ (uint64_t)(OPERAND)); \ assert(trace_length < max_length); \ - assert(reserved > 0); \ - reserved--; \ trace[trace_length].opcode = (OPCODE); \ trace[trace_length].oparg = (OPARG); \ trace[trace_length].operand = (OPERAND); \ + trace[trace_length].target = (TARGET); \ trace_length++; #define INSTR_IP(INSTR, CODE) \ ((uint32_t)((INSTR) - ((_Py_CODEUNIT *)(CODE)->co_code_adaptive))) -#define ADD_TO_STUB(INDEX, OPCODE, OPARG, OPERAND) \ - DPRINTF(2, " ADD_TO_STUB(%d, %s, %d, %" PRIu64 ")\n", \ - (INDEX), \ - uop_name(OPCODE), \ - (OPARG), \ - (uint64_t)(OPERAND)); \ - assert(reserved > 0); \ - reserved--; \ - trace[(INDEX)].opcode = (OPCODE); \ - trace[(INDEX)].oparg = (OPARG); \ - trace[(INDEX)].operand = (OPERAND); - // Reserve space for n uops #define RESERVE_RAW(n, opname) \ 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 _SET_IP and _EXIT_TRACE -#define RESERVE(main, stub) RESERVE_RAW((main) + (stub) + 2, uop_name(opcode)) +// Reserve space for N uops, plus 3 for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE +#define RESERVE(needed) RESERVE_RAW((needed) + 3, _PyUOpName(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"); \ - ADD_TO_TRACE(_SET_IP, 0, 0); \ + OPT_STAT_INC(trace_stack_overflow); \ + ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); \ goto done; \ } \ trace_stack[trace_stack_depth].code = code; \ @@ -492,21 +505,27 @@ translate_bytecode_to_trace( PyUnicode_AsUTF8(code->co_filename), code->co_firstlineno, 2 * INSTR_IP(initial_instr, code)); - + uint32_t target = 0; top: // Jump here after _PUSH_FRAME or likely branches for (;;) { - RESERVE_RAW(2, "epilogue"); // Always need space for _SET_IP and _EXIT_TRACE - ADD_TO_TRACE(_SET_IP, INSTR_IP(instr, code), 0); + target = INSTR_IP(instr, code); + RESERVE_RAW(3, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE + ADD_TO_TRACE(_SET_IP, target, 0, target); + ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target); uint32_t opcode = instr->op.code; uint32_t oparg = instr->op.arg; uint32_t extras = 0; - while (opcode == EXTENDED_ARG) { + if (opcode == EXTENDED_ARG) { instr++; extras += 1; opcode = instr->op.code; oparg = (oparg << 8) | instr->op.arg; + if (opcode == EXTENDED_ARG) { + instr--; + goto done; + } } if (opcode == ENTER_EXECUTOR) { @@ -518,45 +537,34 @@ translate_bytecode_to_trace( } switch (opcode) { - case POP_JUMP_IF_NONE: - { - RESERVE(2, 2); - ADD_TO_TRACE(_IS_NONE, 0, 0); - opcode = POP_JUMP_IF_TRUE; - goto pop_jump_if_bool; - } - case POP_JUMP_IF_NOT_NONE: - { - RESERVE(2, 2); - ADD_TO_TRACE(_IS_NONE, 0, 0); - opcode = POP_JUMP_IF_FALSE; - goto pop_jump_if_bool; - } - case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: { -pop_jump_if_bool: - RESERVE(1, 2); - max_length -= 2; // Really the start of the stubs + RESERVE(1); 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; + int jump_likely = bitcount > 8; + if (jump_likely) { + confidence = confidence * bitcount / 16; + } + else { + confidence = confidence * (16 - bitcount) / 16; + } + if (confidence < CONFIDENCE_CUTOFF) { + DPRINTF(2, "Confidence too low (%d)\n", confidence); + OPT_STAT_INC(low_confidence); + goto done; + } + uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely]; _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, _SET_IP, INSTR_IP(stub_target, code), 0); - ADD_TO_STUB(max_length + 1, _EXIT_TRACE, 0, 0); + DPRINTF(2, "%s(%d): counter=%x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n", + _PyUOpName(opcode), oparg, + counter, bitcount, jump_likely, confidence, _PyUOpName(uopcode)); + ADD_TO_TRACE(uopcode, max_length, 0, target); if (jump_likely) { + _Py_CODEUNIT *target_instr = next_instr + oparg; 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; @@ -568,10 +576,11 @@ translate_bytecode_to_trace( case JUMP_BACKWARD: { if (instr + 2 - oparg == initial_instr && code == initial_code) { - RESERVE(1, 0); - ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0); + RESERVE(1); + ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0); } else { + OPT_STAT_INC(inner_loop); DPRINTF(2, "JUMP_BACKWARD not to top ends trace\n"); } goto done; @@ -579,70 +588,33 @@ translate_bytecode_to_trace( case JUMP_FORWARD: { - RESERVE(0, 0); + RESERVE(0); // This will emit two _SET_IP instructions; leave it to the optimizer instr += oparg; break; } - case FOR_ITER_LIST: - case FOR_ITER_TUPLE: - case FOR_ITER_RANGE: - { - RESERVE(4, 3); - int check_op, exhausted_op, next_op; - switch (opcode) { - case FOR_ITER_LIST: - check_op = _ITER_CHECK_LIST; - exhausted_op = _IS_ITER_EXHAUSTED_LIST; - next_op = _ITER_NEXT_LIST; - break; - case FOR_ITER_TUPLE: - check_op = _ITER_CHECK_TUPLE; - exhausted_op = _IS_ITER_EXHAUSTED_TUPLE; - next_op = _ITER_NEXT_TUPLE; - break; - case FOR_ITER_RANGE: - check_op = _ITER_CHECK_RANGE; - exhausted_op = _IS_ITER_EXHAUSTED_RANGE; - next_op = _ITER_NEXT_RANGE; - break; - default: - Py_UNREACHABLE(); - } - // Assume jump unlikely (can a for-loop exit be likely?) - _Py_CODEUNIT *target_instr = // +1 at the end skips over END_FOR - instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + oparg + 1; - max_length -= 3; // Really the start of the stubs - ADD_TO_TRACE(check_op, 0, 0); - ADD_TO_TRACE(exhausted_op, 0, 0); - ADD_TO_TRACE(_POP_JUMP_IF_TRUE, max_length, 0); - ADD_TO_TRACE(next_op, 0, 0); - - ADD_TO_STUB(max_length + 0, POP_TOP, 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; - } - default: { const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode]; if (expansion->nuops > 0) { // Reserve space for nuops (+ _SET_IP + _EXIT_TRACE) int nuops = expansion->nuops; - RESERVE(nuops, 0); + RESERVE(nuops); 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"); - goto done;} + 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; // Add one to account for the actual opcode/oparg pair: int offset = expansion->uops[i].offset + 1; @@ -657,6 +629,14 @@ translate_bytecode_to_trace( oparg += extras; } } + if (_PyUOp_Replacements[uop]) { + uop = _PyUOp_Replacements[uop]; + if (uop == _FOR_ITER_TIER_TWO) { + target += 1 + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; + assert(_PyCode_CODE(code)[target-1].op.code == END_FOR || + _PyCode_CODE(code)[target-1].op.code == INSTRUMENTED_END_FOR); + } + } break; case OPARG_CACHE_1: operand = read_u16(&instr[offset].cache); @@ -673,8 +653,9 @@ 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); + case OPARG_SAVE_RETURN_OFFSET: // op=_SAVE_RETURN_OFFSET; oparg=return_offset + oparg = offset; + assert(uop == _SAVE_RETURN_OFFSET); break; default: @@ -685,8 +666,8 @@ translate_bytecode_to_trace( expansion->uops[i].offset); Py_FatalError("garbled expansion"); } - ADD_TO_TRACE(expansion->uops[i].uop, oparg, operand); - if (expansion->uops[i].uop == _POP_FRAME) { + ADD_TO_TRACE(uop, oparg, operand, target); + if (uop == _POP_FRAME) { TRACE_STACK_POP(); DPRINTF(2, "Returning to %s (%s:%d) at byte offset %d\n", @@ -696,7 +677,7 @@ translate_bytecode_to_trace( 2 * INSTR_IP(instr, code)); goto top; } - if (expansion->uops[i].uop == _PUSH_FRAME) { + if (uop == _PUSH_FRAME) { assert(i + 1 == nuops); int func_version_offset = offsetof(_PyCallCache, func_version)/sizeof(_Py_CODEUNIT) @@ -713,7 +694,8 @@ translate_bytecode_to_trace( PyUnicode_AsUTF8(new_code->co_qualname), PyUnicode_AsUTF8(new_code->co_filename), new_code->co_firstlineno); - ADD_TO_TRACE(_SET_IP, 0, 0); + OPT_STAT_INC(recursive_call); + ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); goto done; } if (new_code->co_version != func_version) { @@ -721,12 +703,13 @@ translate_bytecode_to_trace( // 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); + ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); goto done; } // Increment IP to the return address instr += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + 1; TRACE_STACK_PUSH(); + _Py_BloomFilter_Add(dependencies, new_code); code = new_code; instr = _PyCode_CODE(code); DPRINTF(2, @@ -737,13 +720,14 @@ translate_bytecode_to_trace( 2 * INSTR_IP(instr, code)); goto top; } - ADD_TO_TRACE(_SET_IP, 0, 0); + ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); goto done; } } break; } - DPRINTF(2, "Unsupported opcode %s\n", uop_name(opcode)); + DPRINTF(2, "Unsupported opcode %s\n", _PyUOpName(opcode)); + OPT_UNSUPPORTED_OPCODE(opcode); goto done; // Break out of loop } // End default @@ -760,37 +744,20 @@ translate_bytecode_to_trace( } 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); + if (trace_length > 4) { + ADD_TO_TRACE(_EXIT_TRACE, 0, 0, target); DPRINTF(1, - "Created a trace for %s (%s:%d) at byte offset %d -- length %d+%d\n", + "Created a trace for %s (%s:%d) at byte offset %d -- length %d\n", PyUnicode_AsUTF8(code->co_qualname), PyUnicode_AsUTF8(code->co_filename), code->co_firstlineno, 2 * INSTR_IP(initial_instr, code), - 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; - } - } - return trace_length; + trace_length); + OPT_HIST(trace_length + buffer_size - max_length, trace_length_hist); + return 1; } 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), @@ -807,74 +774,99 @@ translate_bytecode_to_trace( #undef DPRINTF } +#define UNSET_BIT(array, bit) (array[(bit)>>5] &= ~(1<<((bit)&31))) +#define SET_BIT(array, bit) (array[(bit)>>5] |= (1<<((bit)&31))) +#define BIT_IS_SET(array, bit) (array[(bit)>>5] & (1<<((bit)&31))) + +/* Count the number of used uops, and mark them in the bit vector `used`. + * This can be done in a single pass using simple reachability analysis, + * as there are no backward jumps. + * NOPs are excluded from the count. +*/ 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; +compute_used(_PyUOpInstruction *buffer, uint32_t *used) +{ + int count = 0; + SET_BIT(used, 0); + for (int i = 0; i < _Py_UOP_MAX_TRACE_LENGTH; i++) { + if (!BIT_IS_SET(used, i)) { + continue; } - 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; + count++; + int opcode = buffer[i].opcode; + if (opcode == _JUMP_TO_TOP || opcode == _EXIT_TRACE) { + continue; } - else if (opcode == _JUMP_TO_TOP || opcode == _EXIT_TRACE) { - last_instr = pc + 1; - break; + /* All other micro-ops fall through, so i+1 is reachable */ + SET_BIT(used, i+1); + if (OPCODE_HAS_JUMP(opcode)) { + /* Mark target as reachable */ + SET_BIT(used, buffer[i].oparg); } - 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; - } + if (opcode == NOP) { + count--; + UNSET_BIT(used, i); } } - // 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++; + return count; +} + +/* Makes an executor from a buffer of uops. + * Account for the buffer having gaps and NOPs by computing a "used" + * bit vector and only copying the used uops. Here "used" means reachable + * and not a NOP. + */ +static _PyExecutorObject * +make_executor_from_uops(_PyUOpInstruction *buffer, _PyBloomFilter *dependencies) +{ + uint32_t used[(_Py_UOP_MAX_TRACE_LENGTH + 31)/32] = { 0 }; + int length = compute_used(buffer, used); + _PyUOpExecutorObject *executor = PyObject_NewVar(_PyUOpExecutorObject, &_PyUOpExecutor_Type, length); + if (executor == NULL) { + return NULL; + } + int dest = length - 1; + /* Scan backwards, so that we see the destinations of jumps before the jumps themselves. */ + for (int i = _Py_UOP_MAX_TRACE_LENGTH-1; i >= 0; i--) { + if (!BIT_IS_SET(used, i)) { + continue; } + executor->trace[dest] = buffer[i]; + int opcode = buffer[i].opcode; + if (opcode == _POP_JUMP_IF_FALSE || + opcode == _POP_JUMP_IF_TRUE) + { + /* The oparg of the target will already have been set to its new offset */ + int oparg = executor->trace[dest].oparg; + executor->trace[dest].oparg = buffer[oparg].oparg; + } + /* Set the oparg to be the destination offset, + * so that we can set the oparg of earlier jumps correctly. */ + buffer[i].oparg = dest; + dest--; } - // Stage 3: Move the stubs back. - if (dest < last_instr) { - int new_trace_length = move_stubs(trace, dest, last_instr, trace_length); + assert(dest == -1); + executor->base.execute = _PyUOpExecute; + _Py_ExecutorInit((_PyExecutorObject *)executor, dependencies); #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)); - } + char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); + int lltrace = 0; + if (python_lltrace != NULL && *python_lltrace >= '0') { + lltrace = *python_lltrace - '0'; // TODO: Parse an int and all that + } + if (lltrace >= 2) { + printf("Optimized executor (length %d):\n", length); + for (int i = 0; i < length; i++) { + printf("%4d %s(%d, %d, %" PRIu64 ")\n", + i, + _PyUOpName(executor->trace[i].opcode), + executor->trace[i].oparg, + executor->trace[i].target, + executor->trace[i].operand); } -#endif - trace_length = new_trace_length; } - return trace_length; +#endif + return (_PyExecutorObject *)executor; } static int @@ -885,34 +877,46 @@ uop_optimize( _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); - if (trace_length <= 0) { + _PyBloomFilter dependencies; + _Py_BloomFilter_Init(&dependencies); + _PyUOpInstruction buffer[_Py_UOP_MAX_TRACE_LENGTH]; + int err = translate_bytecode_to_trace(code, instr, buffer, _Py_UOP_MAX_TRACE_LENGTH, &dependencies); + if (err <= 0) { // Error or nothing translated - return trace_length; + return err; } - OBJECT_STAT_INC(optimization_traces_created); + 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); + if (uop_optimize == NULL || *uop_optimize > '0') { + err = _Py_uop_analyze_and_optimize(code, buffer, _Py_UOP_MAX_TRACE_LENGTH, curr_stackentries); + if (err < 0) { + return -1; + } } - trace_length = remove_unneeded_uops(trace, trace_length); - _PyUOpExecutorObject *executor = PyObject_NewVar(_PyUOpExecutorObject, &UOpExecutor_Type, trace_length); + _PyExecutorObject *executor = make_executor_from_uops(buffer, &dependencies); if (executor == NULL) { return -1; } - executor->base.execute = _PyUopExecute; - memcpy(executor->trace, trace, trace_length * sizeof(_PyUOpInstruction)); - *exec_ptr = (_PyExecutorObject *)executor; + OPT_HIST(Py_SIZE(executor), optimized_trace_length_hist); + *exec_ptr = executor; return 1; } +/* Dummy execute() function for UOp Executor. + * The actual implementation is inlined in ceval.c, + * in _PyEval_EvalFrameDefault(). */ +_Py_CODEUNIT * +_PyUOpExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer) +{ + Py_FatalError("Tier 2 is now inlined into Tier 1"); +} + static void uop_opt_dealloc(PyObject *self) { PyObject_Free(self); } -static PyTypeObject UOpOptimizer_Type = { +PyTypeObject _PyUOpOptimizer_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "uop_optimizer", .tp_basicsize = sizeof(_PyOptimizerObject), @@ -924,14 +928,217 @@ static PyTypeObject UOpOptimizer_Type = { PyObject * PyUnstable_Optimizer_NewUOpOptimizer(void) { - _PyOptimizerObject *opt = PyObject_New(_PyOptimizerObject, &UOpOptimizer_Type); + _PyOptimizerObject *opt = PyObject_New(_PyOptimizerObject, &_PyUOpOptimizer_Type); if (opt == NULL) { return NULL; } opt->optimize = uop_optimize; - opt->resume_threshold = UINT16_MAX; + opt->resume_threshold = INT16_MAX; // Need at least 3 iterations to settle specializations. // A few lower bits of the counter are reserved for other flags. opt->backedge_threshold = 16 << OPTIMIZER_BITS_IN_COUNTER; return (PyObject *)opt; } + + +/***************************************** + * Executor management + ****************************************/ + +/* We use a bloomfilter with k = 6, m = 256 + * The choice of k and the following constants + * could do with a more rigourous analysis, + * but here is a simple analysis: + * + * We want to keep the false positive rate low. + * For n = 5 (a trace depends on 5 objects), + * we expect 30 bits set, giving a false positive + * rate of (30/256)**6 == 2.5e-6 which is plenty + * good enough. + * + * However with n = 10 we expect 60 bits set (worst case), + * giving a false positive of (60/256)**6 == 0.0001 + * + * We choose k = 6, rather than a higher number as + * it means the false positive rate grows slower for high n. + * + * n = 5, k = 6 => fp = 2.6e-6 + * n = 5, k = 8 => fp = 3.5e-7 + * n = 10, k = 6 => fp = 1.6e-4 + * n = 10, k = 8 => fp = 0.9e-4 + * n = 15, k = 6 => fp = 0.18% + * n = 15, k = 8 => fp = 0.23% + * n = 20, k = 6 => fp = 1.1% + * n = 20, k = 8 => fp = 2.3% + * + * The above analysis assumes perfect hash functions, + * but those don't exist, so the real false positive + * rates may be worse. + */ + +#define K 6 + +#define SEED 20221211 + +/* TO DO -- Use more modern hash functions with better distribution of bits */ +static uint64_t +address_to_hash(void *ptr) { + assert(ptr != NULL); + uint64_t uhash = SEED; + uintptr_t addr = (uintptr_t)ptr; + for (int i = 0; i < SIZEOF_VOID_P; i++) { + uhash ^= addr & 255; + uhash *= (uint64_t)_PyHASH_MULTIPLIER; + addr >>= 8; + } + return uhash; +} + +void +_Py_BloomFilter_Init(_PyBloomFilter *bloom) +{ + for (int i = 0; i < BLOOM_FILTER_WORDS; i++) { + bloom->bits[i] = 0; + } +} + +/* We want K hash functions that each set 1 bit. + * A hash function that sets 1 bit in M bits can be trivially + * derived from a log2(M) bit hash function. + * So we extract 8 (log2(256)) bits at a time from + * the 64bit hash. */ +void +_Py_BloomFilter_Add(_PyBloomFilter *bloom, void *ptr) +{ + uint64_t hash = address_to_hash(ptr); + assert(K <= 8); + for (int i = 0; i < K; i++) { + uint8_t bits = hash & 255; + bloom->bits[bits >> 5] |= (1 << (bits&31)); + hash >>= 8; + } +} + +static bool +bloom_filter_may_contain(_PyBloomFilter *bloom, _PyBloomFilter *hashes) +{ + for (int i = 0; i < BLOOM_FILTER_WORDS; i++) { + if ((bloom->bits[i] & hashes->bits[i]) != hashes->bits[i]) { + return false; + } + } + return true; +} + +static void +link_executor(_PyExecutorObject *executor) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + _PyExecutorLinkListNode *links = &executor->vm_data.links; + _PyExecutorObject *head = interp->executor_list_head; + if (head == NULL) { + interp->executor_list_head = executor; + links->previous = NULL; + links->next = NULL; + } + else { + _PyExecutorObject *next = head->vm_data.links.next; + links->previous = head; + links->next = next; + if (next != NULL) { + next->vm_data.links.previous = executor; + } + head->vm_data.links.next = executor; + } + executor->vm_data.linked = true; + /* executor_list_head must be first in list */ + assert(interp->executor_list_head->vm_data.links.previous == NULL); +} + +static void +unlink_executor(_PyExecutorObject *executor) +{ + if (!executor->vm_data.linked) { + return; + } + _PyExecutorLinkListNode *links = &executor->vm_data.links; + _PyExecutorObject *next = links->next; + _PyExecutorObject *prev = links->previous; + if (next != NULL) { + next->vm_data.links.previous = prev; + } + if (prev != NULL) { + prev->vm_data.links.next = next; + } + else { + // prev == NULL implies that executor is the list head + PyInterpreterState *interp = PyInterpreterState_Get(); + assert(interp->executor_list_head == executor); + interp->executor_list_head = next; + } + executor->vm_data.linked = false; +} + +/* This must be called by optimizers before using the executor */ +void +_Py_ExecutorInit(_PyExecutorObject *executor, _PyBloomFilter *dependency_set) +{ + executor->vm_data.valid = true; + for (int i = 0; i < BLOOM_FILTER_WORDS; i++) { + executor->vm_data.bloom.bits[i] = dependency_set->bits[i]; + } + link_executor(executor); +} + +/* This must be called by executors during dealloc */ +void +_Py_ExecutorClear(_PyExecutorObject *executor) +{ + unlink_executor(executor); +} + +void +_Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj) +{ + assert(executor->vm_data.valid = true); + _Py_BloomFilter_Add(&executor->vm_data.bloom, obj); +} + +/* Invalidate all executors that depend on `obj` + * May cause other executors to be invalidated as well + */ +void +_Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj) +{ + _PyBloomFilter obj_filter; + _Py_BloomFilter_Init(&obj_filter); + _Py_BloomFilter_Add(&obj_filter, obj); + /* Walk the list of executors */ + /* TO DO -- Use a tree to avoid traversing as many objects */ + for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { + assert(exec->vm_data.valid); + _PyExecutorObject *next = exec->vm_data.links.next; + if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter)) { + exec->vm_data.valid = false; + unlink_executor(exec); + } + exec = next; + } +} + +/* Invalidate all executors */ +void +_Py_Executors_InvalidateAll(PyInterpreterState *interp) +{ + /* Walk the list of executors */ + for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { + assert(exec->vm_data.valid); + _PyExecutorObject *next = exec->vm_data.links.next; + exec->vm_data.links.next = NULL; + exec->vm_data.links.previous = NULL; + exec->vm_data.valid = false; + exec->vm_data.linked = false; + exec = next; + } + interp->executor_list_head = NULL; +} diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 2d177f14ff268b..8b471d70a10d7d 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -12,14 +12,53 @@ #include #include "pycore_optimizer.h" +static void +remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size) +{ + int last_set_ip = -1; + bool maybe_invalid = false; + for (int pc = 0; pc < buffer_size; pc++) { + int opcode = buffer[pc].opcode; + if (opcode == _SET_IP) { + buffer[pc].opcode = NOP; + last_set_ip = pc; + } + else if (opcode == _CHECK_VALIDITY) { + if (maybe_invalid) { + maybe_invalid = false; + } + else { + buffer[pc].opcode = NOP; + } + } + else if (opcode == _JUMP_TO_TOP || opcode == _EXIT_TRACE) { + break; + } + else { + if (OPCODE_HAS_ESCAPES(opcode)) { + maybe_invalid = true; + if (last_set_ip >= 0) { + buffer[last_set_ip].opcode = _SET_IP; + } + } + if (OPCODE_HAS_ERROR(opcode) || opcode == _PUSH_FRAME) { + if (last_set_ip >= 0) { + buffer[last_set_ip].opcode = _SET_IP; + } + } + } + } +} + int _Py_uop_analyze_and_optimize( PyCodeObject *co, - _PyUOpInstruction *trace, - int trace_len, + _PyUOpInstruction *buffer, + int buffer_size, int curr_stacklen ) { - return trace_len; + remove_unneeded_uops(buffer, buffer_size); + return 0; } diff --git a/Python/parking_lot.c b/Python/parking_lot.c index 664e622cc17474..d44c1b4b93b4d2 100644 --- a/Python/parking_lot.c +++ b/Python/parking_lot.c @@ -118,10 +118,19 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) if (timeout >= 0) { struct timespec ts; +#if defined(CLOCK_MONOTONIC) && defined(HAVE_SEM_CLOCKWAIT) + _PyTime_t deadline = _PyTime_Add(_PyTime_GetMonotonicClock(), timeout); + + _PyTime_AsTimespec_clamp(deadline, &ts); + + err = sem_clockwait(&sema->platform_sem, CLOCK_MONOTONIC, &ts); +#else _PyTime_t deadline = _PyTime_Add(_PyTime_GetSystemClock(), timeout); - _PyTime_AsTimespec(deadline, &ts); + + _PyTime_AsTimespec_clamp(deadline, &ts); err = sem_timedwait(&sema->platform_sem, &ts); +#endif } else { err = sem_wait(&sema->platform_sem); @@ -151,7 +160,7 @@ _PySemaphore_PlatformWait(_PySemaphore *sema, _PyTime_t timeout) struct timespec ts; _PyTime_t deadline = _PyTime_Add(_PyTime_GetSystemClock(), timeout); - _PyTime_AsTimespec(deadline, &ts); + _PyTime_AsTimespec_clamp(deadline, &ts); err = pthread_cond_timedwait(&sema->cond, &sema->mutex, &ts); } diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c index 209a23b6c1cbc7..540b650192ed34 100644 --- a/Python/perf_trampoline.c +++ b/Python/perf_trampoline.c @@ -133,7 +133,6 @@ any DWARF information available for them). #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 @@ -193,7 +192,7 @@ typedef struct trampoline_api_st trampoline_api_t; #define perf_code_arena _PyRuntime.ceval.perf.code_arena #define trampoline_api _PyRuntime.ceval.perf.trampoline_api #define perf_map_file _PyRuntime.ceval.perf.map_file - +#define persist_after_fork _PyRuntime.ceval.perf.persist_after_fork static void perf_map_write_entry(void *state, const void *code_addr, @@ -217,10 +216,24 @@ perf_map_write_entry(void *state, const void *code_addr, PyMem_RawFree(perf_map_entry); } +static void* +perf_map_init_state(void) +{ + PyUnstable_PerfMapState_Init(); + return NULL; +} + +static int +perf_map_free_state(void *state) +{ + PyUnstable_PerfMapState_Fini(); + return 0; +} + _PyPerf_Callbacks _Py_perfmap_callbacks = { - NULL, + &perf_map_init_state, &perf_map_write_entry, - NULL, + &perf_map_free_state, }; static int @@ -236,8 +249,7 @@ new_code_arena(void) 0); // offset (not used here) if (!memory) { PyErr_SetFromErrno(PyExc_OSError); - _PyErr_WriteUnraisableMsg( - "Failed to create new mmap for perf trampoline", NULL); + PyErr_FormatUnraisable("Failed to create new mmap for perf trampoline"); perf_status = PERF_STATUS_FAILED; return -1; } @@ -261,9 +273,8 @@ new_code_arena(void) if (res == -1) { PyErr_SetFromErrno(PyExc_OSError); munmap(memory, mem_size); - _PyErr_WriteUnraisableMsg( - "Failed to set mmap for perf trampoline to PROT_READ | PROT_EXEC", - NULL); + PyErr_FormatUnraisable("Failed to set mmap for perf trampoline to " + "PROT_READ | PROT_EXEC"); return -1; } @@ -277,8 +288,7 @@ new_code_arena(void) if (new_arena == NULL) { PyErr_NoMemory(); munmap(memory, mem_size); - _PyErr_WriteUnraisableMsg("Failed to allocate new code arena struct", - NULL); + PyErr_FormatUnraisable("Failed to allocate new code arena struct for perf trampoline"); return -1; } @@ -361,6 +371,26 @@ py_trampoline_evaluator(PyThreadState *ts, _PyInterpreterFrame *frame, } #endif // PY_HAVE_PERF_TRAMPOLINE +int PyUnstable_PerfTrampoline_CompileCode(PyCodeObject *co) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + py_trampoline f = NULL; + assert(extra_code_index != -1); + int ret = _PyCode_GetExtra((PyObject *)co, extra_code_index, (void **)&f); + if (ret != 0 || f == NULL) { + py_trampoline new_trampoline = compile_trampoline(); + if (new_trampoline == NULL) { + return 0; + } + trampoline_api.write_state(trampoline_api.state, new_trampoline, + perf_code_arena->code_size, co); + return _PyCode_SetExtra((PyObject *)co, extra_code_index, + (void *)new_trampoline); + } +#endif // PY_HAVE_PERF_TRAMPOLINE + return 0; +} + int _PyIsPerfTrampolineActive(void) { @@ -399,7 +429,6 @@ _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *callbacks) trampoline_api.write_state = callbacks->write_state; trampoline_api.free_state = callbacks->free_state; trampoline_api.state = NULL; - perf_status = PERF_STATUS_OK; #endif return 0; } @@ -418,6 +447,7 @@ _PyPerfTrampoline_Init(int activate) } if (!activate) { tstate->interp->eval_frame = NULL; + perf_status = PERF_STATUS_NO_INIT; } else { tstate->interp->eval_frame = py_trampoline_evaluator; @@ -428,6 +458,9 @@ _PyPerfTrampoline_Init(int activate) if (extra_code_index == -1) { return -1; } + if (trampoline_api.state == NULL && trampoline_api.init_state != NULL) { + trampoline_api.state = trampoline_api.init_state(); + } perf_status = PERF_STATUS_OK; } #endif @@ -438,12 +471,34 @@ int _PyPerfTrampoline_Fini(void) { #ifdef PY_HAVE_PERF_TRAMPOLINE + if (perf_status != PERF_STATUS_OK) { + return 0; + } PyThreadState *tstate = _PyThreadState_GET(); if (tstate->interp->eval_frame == py_trampoline_evaluator) { tstate->interp->eval_frame = NULL; } - free_code_arenas(); + if (perf_status == PERF_STATUS_OK) { + trampoline_api.free_state(trampoline_api.state); + } extra_code_index = -1; + perf_status = PERF_STATUS_NO_INIT; +#endif + return 0; +} + +void _PyPerfTrampoline_FreeArenas(void) { +#ifdef PY_HAVE_PERF_TRAMPOLINE + free_code_arenas(); +#endif + return; +} + +int +PyUnstable_PerfTrampoline_SetPersistAfterFork(int enable){ +#ifdef PY_HAVE_PERF_TRAMPOLINE + persist_after_fork = enable; + return persist_after_fork; #endif return 0; } @@ -452,12 +507,21 @@ PyStatus _PyPerfTrampoline_AfterFork_Child(void) { #ifdef PY_HAVE_PERF_TRAMPOLINE - // Restart trampoline in file in child. - int was_active = _PyIsPerfTrampolineActive(); - _PyPerfTrampoline_Fini(); - PyUnstable_PerfMapState_Fini(); - if (was_active) { - _PyPerfTrampoline_Init(1); + if (persist_after_fork) { + _PyPerfTrampoline_Fini(); + char filename[256]; + pid_t parent_pid = getppid(); + snprintf(filename, sizeof(filename), "/tmp/perf-%d.map", parent_pid); + if (PyUnstable_CopyPerfMapFile(filename) != 0) { + return PyStatus_Error("Failed to copy perf map file."); + } + } else { + // Restart trampoline in file in child. + int was_active = _PyIsPerfTrampolineActive(); + _PyPerfTrampoline_Fini(); + if (was_active) { + _PyPerfTrampoline_Init(1); + } } #endif return PyStatus_Ok(); diff --git a/Python/pyhash.c b/Python/pyhash.c index f9060b8003a0a7..141407c265677a 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -83,8 +83,6 @@ static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0}; */ -Py_hash_t _Py_HashPointer(const void *); - Py_hash_t _Py_HashDouble(PyObject *inst, double v) { @@ -132,23 +130,13 @@ _Py_HashDouble(PyObject *inst, double v) } Py_hash_t -_Py_HashPointerRaw(const void *p) -{ - size_t y = (size_t)p; - /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid - excessive hash collisions for dicts and sets */ - y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4)); - return (Py_hash_t)y; -} - -Py_hash_t -_Py_HashPointer(const void *p) +Py_HashPointer(const void *ptr) { - Py_hash_t x = _Py_HashPointerRaw(p); - if (x == -1) { - x = -2; + Py_hash_t hash = _Py_HashPointerRaw(ptr); + if (hash == -1) { + hash = -2; } - return x; + return hash; } Py_hash_t diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 23f66ec3601df6..0ec29846b0850b 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -37,6 +37,9 @@ #include // setlocale() #include // getenv() +#ifdef HAVE_UNISTD_H +# include // isatty() +#endif #if defined(__APPLE__) # include @@ -525,11 +528,6 @@ pycore_init_runtime(_PyRuntimeState *runtime, return status; } - status = _PyTime_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = _PyImport_Init(); if (_PyStatus_EXCEPTION(status)) { return status; @@ -578,44 +576,33 @@ init_interp_settings(PyInterpreterState *interp, interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS; } - /* We check "gil" in init_interp_create_gil(). */ + switch (config->gil) { + case PyInterpreterConfig_DEFAULT_GIL: break; + case PyInterpreterConfig_SHARED_GIL: break; + case PyInterpreterConfig_OWN_GIL: break; + default: + return _PyStatus_ERR("invalid interpreter config 'gil' value"); + } return _PyStatus_OK(); } -static PyStatus +static void init_interp_create_gil(PyThreadState *tstate, int gil) { - PyStatus status; - /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is only called here. */ // XXX This is broken with a per-interpreter GIL. _PyEval_FiniGIL(tstate->interp); /* Auto-thread-state API */ - status = _PyGILState_SetTstate(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + _PyGILState_SetTstate(tstate); - int own_gil; - switch (gil) { - case PyInterpreterConfig_DEFAULT_GIL: own_gil = 0; break; - case PyInterpreterConfig_SHARED_GIL: own_gil = 0; break; - case PyInterpreterConfig_OWN_GIL: own_gil = 1; break; - default: - return _PyStatus_ERR("invalid interpreter config 'gil' value"); - } + int own_gil = (gil == PyInterpreterConfig_OWN_GIL); /* Create the GIL and take it */ - status = _PyEval_InitGIL(tstate, own_gil); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - return _PyStatus_OK(); + _PyEval_InitGIL(tstate, own_gil); } @@ -652,18 +639,14 @@ 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)) { - return status; - } + init_interp_create_gil(tstate, config.gil); *tstate_p = tstate; return _PyStatus_OK(); @@ -736,6 +719,12 @@ pycore_init_types(PyInterpreterState *interp) if (_PyStatus_EXCEPTION(status)) { return status; } + + status = _PyXI_InitTypes(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); } @@ -822,6 +811,11 @@ pycore_interp_init(PyThreadState *tstate) return status; } + status = _PyDtoa_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + // The GC must be initialized before the first GC collection. status = _PyGC_Init(interp); if (_PyStatus_EXCEPTION(status)) { @@ -852,6 +846,11 @@ pycore_interp_init(PyThreadState *tstate) goto done; } + status = _PyXI_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + goto done; + } + const PyConfig *config = _PyInterpreterState_GetConfig(interp); status = _PyImport_InitCore(tstate, sysmod, config->_install_importlib); @@ -1074,6 +1073,38 @@ pyinit_main_reconfigure(PyThreadState *tstate) } +#ifdef Py_DEBUG +static void +run_presite(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + const PyConfig *config = _PyInterpreterState_GetConfig(interp); + + if (!config->run_presite) { + return; + } + + PyObject *presite_modname = PyUnicode_FromWideChar( + config->run_presite, + wcslen(config->run_presite) + ); + if (presite_modname == NULL) { + fprintf(stderr, "Could not convert pre-site module name to unicode\n"); + Py_DECREF(presite_modname); + } + else { + PyObject *presite = PyImport_Import(presite_modname); + if (presite == NULL) { + fprintf(stderr, "pre-site import failed:\n"); + _PyErr_Print(tstate); + } + Py_XDECREF(presite); + Py_DECREF(presite_modname); + } +} +#endif + + static PyStatus init_interp_main(PyThreadState *tstate) { @@ -1155,6 +1186,10 @@ init_interp_main(PyThreadState *tstate) return status; } +#ifdef Py_DEBUG + run_presite(tstate); +#endif + status = add_main_module(interp); if (_PyStatus_EXCEPTION(status)) { return status; @@ -1191,7 +1226,7 @@ init_interp_main(PyThreadState *tstate) // Turn on experimental tier 2 (uops-based) optimizer if (is_main_interp) { - char *envvar = Py_GETENV("PYTHONUOPS"); + char *envvar = Py_GETENV("PYTHON_UOPS"); int enabled = envvar != NULL && *envvar > '0'; if (_Py_get_xoption(&config->xoptions, L"uops") != NULL) { enabled = 1; @@ -1206,6 +1241,31 @@ init_interp_main(PyThreadState *tstate) } } + 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]"); + } + } + } + assert(!_PyErr_Occurred(tstate)); return _PyStatus_OK(); @@ -1350,13 +1410,13 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose) PySys_WriteStderr("# clear builtins._\n"); } if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on setting builtin variable _"); } const char * const *p; for (p = sys_deletes; *p != NULL; p++) { if (_PySys_ClearAttrString(interp, *p, verbose) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing sys.%s", *p); } } for (p = sys_files; *p != NULL; p+=2) { @@ -1367,13 +1427,13 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose) } PyObject *value; if (PyDict_GetItemStringRef(interp->sysdict, orig_name, &value) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on restoring sys.%s", name); } if (value == NULL) { value = Py_NewRef(Py_None); } if (PyDict_SetItemString(interp->sysdict, name, value) < 0) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on restoring sys.%s", name); } Py_DECREF(value); } @@ -1385,7 +1445,7 @@ finalize_remove_modules(PyObject *modules, int verbose) { PyObject *weaklist = PyList_New(0); if (weaklist == NULL) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on removing modules"); } #define STORE_MODULE_WEAKREF(name, mod) \ @@ -1394,13 +1454,13 @@ finalize_remove_modules(PyObject *modules, int verbose) if (wr) { \ PyObject *tup = PyTuple_Pack(2, name, wr); \ if (!tup || PyList_Append(weaklist, tup) < 0) { \ - PyErr_WriteUnraisable(NULL); \ + PyErr_FormatUnraisable("Exception ignored on removing modules"); \ } \ Py_XDECREF(tup); \ Py_DECREF(wr); \ } \ else { \ - PyErr_WriteUnraisable(NULL); \ + PyErr_FormatUnraisable("Exception ignored on removing modules"); \ } \ } @@ -1411,7 +1471,7 @@ finalize_remove_modules(PyObject *modules, int verbose) } \ STORE_MODULE_WEAKREF(name, mod); \ if (PyObject_SetItem(modules, name, Py_None) < 0) { \ - PyErr_WriteUnraisable(NULL); \ + PyErr_FormatUnraisable("Exception ignored on removing modules"); \ } \ } @@ -1425,14 +1485,14 @@ finalize_remove_modules(PyObject *modules, int verbose) else { PyObject *iterator = PyObject_GetIter(modules); if (iterator == NULL) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on removing modules"); } else { PyObject *key; while ((key = PyIter_Next(iterator))) { PyObject *value = PyObject_GetItem(modules, key); if (value == NULL) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on removing modules"); continue; } CLEAR_MODULE(key, value); @@ -1440,7 +1500,7 @@ finalize_remove_modules(PyObject *modules, int verbose) Py_DECREF(key); } if (PyErr_Occurred()) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on removing modules"); } Py_DECREF(iterator); } @@ -1460,7 +1520,7 @@ finalize_clear_modules_dict(PyObject *modules) } else { if (PyObject_CallMethodNoArgs(modules, &_Py_ID(clear)) == NULL) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on clearing sys.modules"); } } } @@ -1472,11 +1532,11 @@ finalize_restore_builtins(PyThreadState *tstate) PyInterpreterState *interp = tstate->interp; PyObject *dict = PyDict_Copy(interp->builtins); if (dict == NULL) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on restoring builtins"); } PyDict_Clear(interp->builtins); if (PyDict_Update(interp->builtins, interp->builtins_copy)) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on restoring builtins"); } Py_XDECREF(dict); } @@ -1638,7 +1698,7 @@ flush_std_files(void) if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { if (_PyFile_Flush(fout) < 0) { - PyErr_WriteUnraisable(fout); + PyErr_FormatUnraisable("Exception ignored on flushing sys.stdout"); status = -1; } } @@ -1673,6 +1733,7 @@ finalize_interp_types(PyInterpreterState *interp) { _PyUnicode_FiniTypes(interp); _PySys_FiniTypes(interp); + _PyXI_FiniTypes(interp); _PyExc_Fini(interp); _PyAsyncGen_Fini(interp); _PyContext_Fini(interp); @@ -1709,8 +1770,10 @@ finalize_interp_clear(PyThreadState *tstate) { int is_main_interp = _Py_IsMainInterpreter(tstate->interp); + _PyXI_Fini(tstate->interp); _PyExc_ClearExceptionGroupType(tstate->interp); _Py_clear_generic_types(tstate->interp); + _PyDtoa_Fini(tstate->interp); /* Clear interpreter state and all thread states */ _PyInterpreterState_Clear(tstate); @@ -1727,6 +1790,7 @@ finalize_interp_clear(PyThreadState *tstate) _PyArg_Fini(); _Py_ClearFileSystemEncoding(); _PyPerfTrampoline_Fini(); + _PyPerfTrampoline_FreeArenas(); } finalize_interp_types(tstate->interp); @@ -1784,7 +1848,6 @@ Py_FinalizeEx(void) */ _PyAtExit_Call(tstate->interp); - PyUnstable_PerfMapState_Fini(); /* Copy the core config, PyInterpreterState_Delete() free the core config memory */ @@ -2022,28 +2085,21 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) return _PyStatus_OK(); } - PyThreadState *tstate = _PyThreadState_New(interp); - if (tstate == NULL) { - PyInterpreterState_Delete(interp); - *tstate_p = NULL; - return _PyStatus_OK(); - } - _PyThreadState_Bind(tstate); - - // XXX For now we do this before the GIL is created. - PyThreadState *save_tstate = _PyThreadState_SwapNoGIL(tstate); - int has_gil = 0; + // XXX Might new_interpreter() have been called without the GIL held? + PyThreadState *save_tstate = _PyThreadState_GET(); + PyThreadState *tstate = NULL; /* From this point until the init_interp_create_gil() call, we must not do anything that requires that the GIL be held (or otherwise exist). That applies whether or not the new interpreter has its own GIL (e.g. the main interpreter). */ + if (save_tstate != NULL) { + _PyThreadState_Detach(save_tstate); + } /* Copy the current interpreter config into the new interpreter */ 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); src_config = _PyInterpreterState_GetConfig(save_tstate->interp); } else @@ -2065,11 +2121,14 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) goto error; } - status = init_interp_create_gil(tstate, config->gil); - if (_PyStatus_EXCEPTION(status)) { + tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_INTERP); + if (tstate == NULL) { + status = _PyStatus_NO_MEMORY(); goto error; } - has_gil = 1; + + _PyThreadState_Bind(tstate); + init_interp_create_gil(tstate, config->gil); /* No objects have been created yet. */ @@ -2088,17 +2147,14 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) error: *tstate_p = NULL; - - /* Oops, it didn't work. Undo it all. */ - PyErr_PrintEx(0); - if (has_gil) { - PyThreadState_Swap(save_tstate); + if (tstate != NULL) { + PyThreadState_Clear(tstate); + _PyThreadState_Detach(tstate); + PyThreadState_Delete(tstate); } - else { - _PyThreadState_SwapNoGIL(save_tstate); + if (save_tstate != NULL) { + _PyThreadState_Attach(save_tstate); } - PyThreadState_Clear(tstate); - PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); return status; @@ -2968,14 +3024,14 @@ wait_for_thread_shutdown(PyThreadState *tstate) PyObject *threading = PyImport_GetModule(&_Py_ID(threading)); if (threading == NULL) { if (_PyErr_Occurred(tstate)) { - PyErr_WriteUnraisable(NULL); + PyErr_FormatUnraisable("Exception ignored on threading shutdown"); } /* else: threading not imported */ return; } result = PyObject_CallMethodNoArgs(threading, &_Py_ID(_shutdown)); if (result == NULL) { - PyErr_WriteUnraisable(threading); + PyErr_FormatUnraisable("Exception ignored on threading shutdown"); } else { Py_DECREF(result); @@ -2986,13 +3042,13 @@ wait_for_thread_shutdown(PyThreadState *tstate) int Py_AtExit(void (*func)(void)) { struct _atexit_runtime_state *state = &_PyRuntime.atexit; - PyThread_acquire_lock(state->mutex, WAIT_LOCK); + PyMutex_Lock(&state->mutex); if (state->ncallbacks >= NEXITFUNCS) { - PyThread_release_lock(state->mutex); + PyMutex_Unlock(&state->mutex); return -1; } state->callbacks[state->ncallbacks++] = func; - PyThread_release_lock(state->mutex); + PyMutex_Unlock(&state->mutex); return 0; } @@ -3002,18 +3058,18 @@ call_ll_exitfuncs(_PyRuntimeState *runtime) atexit_callbackfunc exitfunc; struct _atexit_runtime_state *state = &runtime->atexit; - PyThread_acquire_lock(state->mutex, WAIT_LOCK); + PyMutex_Lock(&state->mutex); while (state->ncallbacks > 0) { /* pop last function from the list */ state->ncallbacks--; exitfunc = state->callbacks[state->ncallbacks]; state->callbacks[state->ncallbacks] = NULL; - PyThread_release_lock(state->mutex); + PyMutex_Unlock(&state->mutex); exitfunc(); - PyThread_acquire_lock(state->mutex, WAIT_LOCK); + PyMutex_Lock(&state->mutex); } - PyThread_release_lock(state->mutex); + PyMutex_Unlock(&state->mutex); fflush(stdout); fflush(stderr); diff --git a/Python/pystate.c b/Python/pystate.c index 01aa2552e56f0d..e18eb0186d0010 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_ceval.h" #include "pycore_code.h" // stats +#include "pycore_critical_section.h" // _PyCriticalSection_Resume() #include "pycore_dtoa.h" // _dtoa_state_INIT() #include "pycore_emscripten_trampoline.h" // _Py_EmscriptenTrampoline_Init() #include "pycore_frame.h" @@ -16,7 +17,6 @@ #include "pycore_pystate.h" #include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_sysmodule.h" // _PySys_Audit() -#include "pycore_weakref.h" // _PyWeakref_GET_REF() /* -------------------------------------------------------------------------- CAUTION @@ -263,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 @@ -379,50 +379,23 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime); _Py_COMP_DIAG_POP -#define NUMLOCKS 9 #define LOCKS_INIT(runtime) \ { \ &(runtime)->interpreters.mutex, \ - &(runtime)->xidregistry.mutex, \ - &(runtime)->getargs.mutex, \ - &(runtime)->unicode_state.ids.lock, \ + &(runtime)->xi.registry.mutex, \ + &(runtime)->unicode_state.ids.mutex, \ &(runtime)->imports.extensions.mutex, \ - &(runtime)->ceval.pending_mainthread.lock, \ + &(runtime)->ceval.pending_mainthread.mutex, \ &(runtime)->atexit.mutex, \ &(runtime)->audit_hooks.mutex, \ &(runtime)->allocators.mutex, \ } -static int -alloc_for_runtime(PyThread_type_lock locks[NUMLOCKS]) -{ - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - for (int i = 0; i < NUMLOCKS; i++) { - PyThread_type_lock lock = PyThread_allocate_lock(); - if (lock == NULL) { - for (int j = 0; j < i; j++) { - PyThread_free_lock(locks[j]); - locks[j] = NULL; - } - break; - } - locks[i] = lock; - } - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return 0; -} - static void init_runtime(_PyRuntimeState *runtime, void *open_code_hook, void *open_code_userdata, _Py_AuditHookEntry *audit_hook_head, - Py_ssize_t unicode_next_index, - PyThread_type_lock locks[NUMLOCKS]) + Py_ssize_t unicode_next_index) { assert(!runtime->preinitializing); assert(!runtime->preinitialized); @@ -436,12 +409,6 @@ init_runtime(_PyRuntimeState *runtime, PyPreConfig_InitPythonConfig(&runtime->preconfig); - PyThread_type_lock *lockptrs[NUMLOCKS] = LOCKS_INIT(runtime); - for (int i = 0; i < NUMLOCKS; i++) { - assert(locks[i] != NULL); - *lockptrs[i] = locks[i]; - } - // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); @@ -467,11 +434,6 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) // is called multiple times. Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index; - PyThread_type_lock locks[NUMLOCKS]; - if (alloc_for_runtime(locks) != 0) { - return _PyStatus_NO_MEMORY(); - } - if (runtime->_initialized) { // Py_Initialize() must be running again. // Reset to _PyRuntimeState_INIT. @@ -490,7 +452,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) } init_runtime(runtime, open_code_hook, open_code_userdata, audit_hook_head, - unicode_next_index, locks); + unicode_next_index); return _PyStatus_OK(); } @@ -510,23 +472,6 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) if (PyThread_tss_is_created(&runtime->trashTSSkey)) { PyThread_tss_delete(&runtime->trashTSSkey); } - - /* Force the allocator used by _PyRuntimeState_Init(). */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -#define FREE_LOCK(LOCK) \ - if (LOCK != NULL) { \ - PyThread_free_lock(LOCK); \ - LOCK = NULL; \ - } - - PyThread_type_lock *lockptrs[NUMLOCKS] = LOCKS_INIT(runtime); - for (int i = 0; i < NUMLOCKS; i++) { - FREE_LOCK(*lockptrs[i]); - } - -#undef FREE_LOCK - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } #ifdef HAVE_FORK @@ -538,28 +483,19 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) // This was initially set in _PyRuntimeState_Init(). runtime->main_thread = PyThread_get_thread_ident(); - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - PyThread_type_lock *lockptrs[NUMLOCKS] = LOCKS_INIT(runtime); - int reinit_err = 0; - for (int i = 0; i < NUMLOCKS; i++) { - reinit_err += _PyThread_at_fork_reinit(lockptrs[i]); - } - - 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(); + // Re-initialize global locks + PyMutex *locks[] = LOCKS_INIT(runtime); + for (size_t i = 0; i < Py_ARRAY_LENGTH(locks); i++) { + _PyMutex_at_fork_reinit(locks[i]); + } + /* 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); - - if (reinit_err < 0) { + if (_PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex) < 0) { return _PyStatus_ERR("Failed to reinitialize runtime locks"); } @@ -595,24 +531,6 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) { struct pyinterpreters *interpreters = &runtime->interpreters; interpreters->next_id = 0; - - /* Py_Finalize() calls _PyRuntimeState_Fini() which clears the mutex. - Create a new mutex if needed. */ - if (interpreters->mutex == NULL) { - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - interpreters->mutex = PyThread_allocate_lock(); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (interpreters->mutex == NULL) { - return _PyStatus_ERR("Can't initialize threads for interpreter"); - } - } - return _PyStatus_OK(); } @@ -655,8 +573,7 @@ free_interpreter(PyInterpreterState *interp) static PyStatus init_interpreter(PyInterpreterState *interp, _PyRuntimeState *runtime, int64_t id, - PyInterpreterState *next, - PyThread_type_lock pending_lock) + PyInterpreterState *next) { if (interp->_initialized) { return _PyStatus_ERR("interpreter already initialized"); @@ -685,7 +602,7 @@ init_interpreter(PyInterpreterState *interp, return status; } - _PyEval_InitState(interp, pending_lock); + _PyEval_InitState(interp); _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); _PyType_InitCache(interp); @@ -704,11 +621,12 @@ init_interpreter(PyInterpreterState *interp, interp->optimizer_backedge_threshold = _PyOptimizer_Default.backedge_threshold; interp->optimizer_resume_threshold = _PyOptimizer_Default.backedge_threshold; interp->next_func_version = 1; + interp->executor_list_head = NULL; 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; + interp->_initialized = 1; return _PyStatus_OK(); } @@ -730,11 +648,6 @@ _PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp) } } - PyThread_type_lock pending_lock = PyThread_allocate_lock(); - if (pending_lock == NULL) { - return _PyStatus_NO_MEMORY(); - } - /* 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 @@ -781,11 +694,10 @@ _PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp) interpreters->head = interp; status = init_interpreter(interp, runtime, - id, old_head, pending_lock); + id, old_head); if (_PyStatus_EXCEPTION(status)) { goto error; } - pending_lock = NULL; HEAD_UNLOCK(runtime); @@ -796,9 +708,6 @@ _PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp) error: HEAD_UNLOCK(runtime); - if (pending_lock != NULL) { - PyThread_free_lock(pending_lock); - } if (interp != NULL) { free_interpreter(interp); } @@ -877,6 +786,10 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->audit_hooks); + // 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; } @@ -953,7 +866,6 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) interp->code_watchers[i] = NULL; } interp->active_code_watchers = 0; - interp->f_opcode_trace_set = false; // XXX Once we have one allocator per interpreter (i.e. // per-interpreter GC) we must ensure that all of the interpreter's // objects have been cleaned up at the point. @@ -981,6 +893,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 @@ -994,15 +907,11 @@ 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); - _PyEval_FiniState(&interp->ceval); - // XXX These two calls should be done at the end of clear_interpreter(), // but currently some objects get decref'ed after that. #ifdef Py_REF_DEBUG @@ -1091,6 +1000,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 //---------- @@ -1150,8 +1114,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); @@ -1250,7 +1216,7 @@ _PyInterpreterState_LookUpID(int64_t requested_id) HEAD_UNLOCK(runtime); } if (interp == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_RuntimeError, + PyErr_Format(PyExc_InterpreterNotFoundError, "unrecognized interpreter ID %lld", requested_id); } return interp; @@ -1294,18 +1260,24 @@ allocate_chunk(int size_in_bytes, _PyStackChunk* previous) return res; } -static PyThreadState * +static _PyThreadStateImpl * alloc_threadstate(void) { - return PyMem_RawCalloc(1, sizeof(PyThreadState)); + return PyMem_RawCalloc(1, sizeof(_PyThreadStateImpl)); } static void -free_threadstate(PyThreadState *tstate) +free_threadstate(_PyThreadStateImpl *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->base.interp->_initial_thread) { + // Restore to _PyThreadState_INIT. + memcpy(tstate, + &initial._main_interpreter._initial_thread, + sizeof(*tstate)); + } + else { PyMem_RawFree(tstate); } } @@ -1319,9 +1291,10 @@ free_threadstate(PyThreadState *tstate) */ static void -init_threadstate(PyThreadState *tstate, - PyInterpreterState *interp, uint64_t id) +init_threadstate(_PyThreadStateImpl *_tstate, + PyInterpreterState *interp, uint64_t id, int whence) { + PyThreadState *tstate = (PyThreadState *)_tstate; if (tstate->_status.initialized) { Py_FatalError("thread state already initialized"); } @@ -1333,6 +1306,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; @@ -1362,8 +1339,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; @@ -1374,15 +1349,15 @@ add_threadstate(PyInterpreterState *interp, PyThreadState *tstate, } static PyThreadState * -new_threadstate(PyInterpreterState *interp) +new_threadstate(PyInterpreterState *interp, int whence) { - PyThreadState *tstate; + _PyThreadStateImpl *tstate; _PyRuntimeState *runtime = interp->runtime; // We don't need to allocate a thread state for the main interpreter // (the common case), but doing it later for the other case revealed a // reentrancy problem (deadlock). So for now we always allocate before // taking the interpreters lock. See GH-96071. - PyThreadState *new_tstate = alloc_threadstate(); + _PyThreadStateImpl *new_tstate = alloc_threadstate(); int used_newtstate; if (new_tstate == NULL) { return NULL; @@ -1397,10 +1372,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); @@ -1413,21 +1388,22 @@ new_threadstate(PyInterpreterState *interp) sizeof(*tstate)); } - init_threadstate(tstate, interp, id); - add_threadstate(interp, tstate, old_head); + init_threadstate(tstate, interp, id, whence); + add_threadstate(interp, (PyThreadState *)tstate, old_head); HEAD_UNLOCK(runtime); if (!used_newtstate) { // Must be called with lock unlocked to avoid re-entrancy deadlock. PyMem_RawFree(new_tstate); } - return tstate; + return (PyThreadState *)tstate; } 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 @@ -1441,16 +1417,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. @@ -1478,6 +1454,7 @@ void PyThreadState_Clear(PyThreadState *tstate) { assert(tstate->_status.initialized && !tstate->_status.cleared); + assert(current_fast_get(&_PyRuntime)->interp == tstate->interp); // XXX assert(!tstate->_status.bound || tstate->_status.unbound); tstate->_status.finalizing = 1; // just in case @@ -1547,6 +1524,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); } @@ -1561,6 +1544,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) { @@ -1602,7 +1586,7 @@ zapthreads(PyInterpreterState *interp) while ((tstate = interp->threads.head) != NULL) { tstate_verify_not_active(tstate); tstate_delete_common(tstate); - free_threadstate(tstate); + free_threadstate((_PyThreadStateImpl *)tstate); } } @@ -1613,7 +1597,7 @@ PyThreadState_Delete(PyThreadState *tstate) _Py_EnsureTstateNotNULL(tstate); tstate_verify_not_active(tstate); tstate_delete_common(tstate); - free_threadstate(tstate); + free_threadstate((_PyThreadStateImpl *)tstate); } @@ -1621,10 +1605,11 @@ 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); - free_threadstate(tstate); + free_threadstate((_PyThreadStateImpl *)tstate); } void @@ -1674,7 +1659,7 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) for (p = list; p; p = next) { next = p->next; PyThreadState_Clear(p); - free_threadstate(p); + free_threadstate((_PyThreadStateImpl *)p); } } @@ -1777,6 +1762,88 @@ tstate_deactivate(PyThreadState *tstate) // It will still be used in PyGILState_Ensure(). } +static int +tstate_try_attach(PyThreadState *tstate) +{ +#ifdef Py_GIL_DISABLED + 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_GIL_DISABLED + _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"); + } + + // Resume previous critical section. This acquires the lock(s) from the + // top-most critical section. + if (tstate->critical_section != 0) { + _PyCriticalSection_Resume(tstate); + } + +#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)); + if (tstate->critical_section != 0) { + _PyCriticalSection_SuspendAll(tstate); + } + tstate_set_detached(tstate); + tstate_deactivate(tstate); + current_fast_clear(&_PyRuntime); + _PyEval_ReleaseLock(tstate->interp, tstate); +} //---------- // other API @@ -1835,7 +1902,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) //--------------------------------- PyThreadState * -_PyThreadState_UncheckedGet(void) +PyThreadState_GetUnchecked(void) { return current_fast_get(&_PyRuntime); } @@ -1849,56 +1916,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; } @@ -2125,7 +2151,7 @@ _PyGILState_Fini(PyInterpreterState *interp) // XXX Drop this. -PyStatus +void _PyGILState_SetTstate(PyThreadState *tstate) { /* must init with valid states */ @@ -2135,7 +2161,7 @@ _PyGILState_SetTstate(PyThreadState *tstate) if (!_Py_IsMainInterpreter(tstate->interp)) { /* Currently, PyGILState is shared by all interpreters. The main * interpreter is responsible to initialize it. */ - return _PyStatus_OK(); + return; } #ifndef NDEBUG @@ -2145,8 +2171,6 @@ _PyGILState_SetTstate(PyThreadState *tstate) assert(gilstate_tss_get(runtime) == tstate); assert(tstate->gilstate_counter == 1); #endif - - return _PyStatus_OK(); } PyInterpreterState * @@ -2207,7 +2231,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"); } @@ -2285,521 +2311,9 @@ PyGILState_Release(PyGILState_STATE oldstate) } -/**************************/ -/* cross-interpreter data */ -/**************************/ - -/* cross-interpreter data */ - -static inline void -_xidata_init(_PyCrossInterpreterData *data) -{ - // If the value is being reused - // then _xidata_clear() should have been called already. - assert(data->data == NULL); - assert(data->obj == NULL); - *data = (_PyCrossInterpreterData){0}; - data->interp = -1; -} - -static inline void -_xidata_clear(_PyCrossInterpreterData *data) -{ - // _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; - } - Py_CLEAR(data->obj); -} - -void -_PyCrossInterpreterData_Init(_PyCrossInterpreterData *data, - PyInterpreterState *interp, - void *shared, PyObject *obj, - xid_newobjectfunc new_object) -{ - assert(data != NULL); - assert(new_object != NULL); - _xidata_init(data); - data->data = shared; - if (obj != NULL) { - assert(interp != NULL); - // released in _PyCrossInterpreterData_Clear() - data->obj = Py_NewRef(obj); - } - // Ideally every object would know its owning interpreter. - // Until then, we have to rely on the caller to identify it - // (but we don't need it in all cases). - data->interp = (interp != NULL) ? interp->id : -1; - data->new_object = new_object; -} - -int -_PyCrossInterpreterData_InitWithSize(_PyCrossInterpreterData *data, - PyInterpreterState *interp, - const size_t size, PyObject *obj, - xid_newobjectfunc new_object) -{ - assert(size > 0); - // For now we always free the shared data in the same interpreter - // where it was allocated, so the interpreter is required. - assert(interp != NULL); - _PyCrossInterpreterData_Init(data, interp, NULL, obj, new_object); - data->data = PyMem_RawMalloc(size); - if (data->data == NULL) { - return -1; - } - data->free = PyMem_RawFree; - return 0; -} - -void -_PyCrossInterpreterData_Clear(PyInterpreterState *interp, - _PyCrossInterpreterData *data) -{ - assert(data != NULL); - // This must be called in the owning interpreter. - assert(interp == NULL || data->interp == interp->id); - _xidata_clear(data); -} - -static int -_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) -{ - // data->data can be anything, including NULL, so we don't check it. - - // data->obj may be NULL, so we don't check it. - - if (data->interp < 0) { - _PyErr_SetString(tstate, PyExc_SystemError, "missing interp"); - return -1; - } - - if (data->new_object == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func"); - return -1; - } - - // data->free may be NULL, so we don't check it. - - return 0; -} - -crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); - -/* This is a separate func from _PyCrossInterpreterData_Lookup in order - to keep the registry code separate. */ -static crossinterpdatafunc -_lookup_getdata(PyObject *obj) -{ - crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); - if (getdata == NULL && PyErr_Occurred() == 0) - PyErr_Format(PyExc_ValueError, - "%S does not support cross-interpreter data", obj); - return getdata; -} - -int -_PyObject_CheckCrossInterpreterData(PyObject *obj) -{ - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { - return -1; - } - return 0; -} - -int -_PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = current_fast_get(runtime); -#ifdef Py_DEBUG - // The caller must hold the GIL - _Py_EnsureTstateNotNULL(tstate); -#endif - PyInterpreterState *interp = tstate->interp; - - // Reset data before re-populating. - *data = (_PyCrossInterpreterData){0}; - data->interp = -1; - - // Call the "getdata" func for the object. - Py_INCREF(obj); - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { - Py_DECREF(obj); - return -1; - } - int res = getdata(tstate, obj, data); - Py_DECREF(obj); - if (res != 0) { - return -1; - } - - // Fill in the blanks and validate the result. - data->interp = interp->id; - if (_check_xidata(tstate, data) != 0) { - (void)_PyCrossInterpreterData_Release(data); - return -1; - } - - return 0; -} - -PyObject * -_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) -{ - return data->new_object(data); -} - -static int -_release_xidata_pending(void *data) -{ - _xidata_clear((_PyCrossInterpreterData *)data); - return 0; -} - -static int -_xidata_release_and_rawfree_pending(void *data) -{ - _xidata_clear((_PyCrossInterpreterData *)data); - PyMem_RawFree(data); - return 0; -} - -static int -_xidata_release(_PyCrossInterpreterData *data, int rawfree) -{ - if ((data->data == NULL || data->free == NULL) && data->obj == NULL) { - // Nothing to release! - if (rawfree) { - PyMem_RawFree(data); - } - else { - data->data = NULL; - } - return 0; - } - - // Switch to the original interpreter. - PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); - if (interp == NULL) { - // The interpreter was already destroyed. - // 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. - if (interp == current_fast_get(interp->runtime)->interp) { - _xidata_clear(data); - if (rawfree) { - PyMem_RawFree(data); - } - } - else { - _Py_pending_call_func func = _release_xidata_pending; - if (rawfree) { - func = _xidata_release_and_rawfree_pending; - } - // XXX Emit a warning if this fails? - _PyEval_AddPendingCall(interp, func, data, 0); - } - return 0; -} - -int -_PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) -{ - return _xidata_release(data, 0); -} - -int -_PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *data) -{ - return _xidata_release(data, 1); -} - -/* registry of {type -> crossinterpdatafunc} */ - -/* 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. */ - -static int -_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->getdata = getdata; - newhead->prev = NULL; - newhead->next = xidregistry->head; - if (newhead->next != NULL) { - newhead->next->prev = newhead; - } - xidregistry->head = newhead; - return 0; -} - -static struct _xidregitem * -_xidregistry_remove_entry(struct _xidregistry *xidregistry, - struct _xidregitem *entry) -{ - struct _xidregitem *next = entry->next; - if (entry->prev != NULL) { - assert(entry->prev->next == entry); - entry->prev->next = next; - } - else { - assert(xidregistry->head == entry); - xidregistry->head = next; - } - if (next != NULL) { - next->prev = entry->prev; - } - Py_DECREF(entry->cls); - PyMem_RawFree(entry); - return next; -} - -static struct _xidregitem * -_xidregistry_find_type(struct _xidregistry *xidregistry, PyTypeObject *cls) -{ - struct _xidregitem *cur = xidregistry->head; - while (cur != NULL) { - PyObject *registered = _PyWeakref_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; - } - Py_DECREF(registered); - cur = cur->next; - } - } - return NULL; -} - -static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); - -int -_PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, - crossinterpdatafunc getdata) -{ - if (!PyType_Check(cls)) { - PyErr_Format(PyExc_ValueError, "only classes may be registered"); - return -1; - } - if (getdata == NULL) { - PyErr_Format(PyExc_ValueError, "missing 'getdata' func"); - return -1; - } - - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - if (xidregistry->head == NULL) { - _register_builtins_for_crossinterpreter_data(xidregistry); - } - int res = _xidregistry_add_type(xidregistry, cls, getdata); - PyThread_release_lock(xidregistry->mutex); - return res; -} - -int -_PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) -{ - int res = 0; - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); - if (matched != NULL) { - (void)_xidregistry_remove_entry(xidregistry, matched); - res = 1; - } - PyThread_release_lock(xidregistry->mutex); - return res; -} - - -/* Cross-interpreter objects are looked up by exact match on the class. - We can reassess this policy when we move from a global registry to a - tp_* slot. */ - -crossinterpdatafunc -_PyCrossInterpreterData_Lookup(PyObject *obj) -{ - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; - PyObject *cls = PyObject_Type(obj); - 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); - PyThread_release_lock(xidregistry->mutex); - return matched != NULL ? matched->getdata : NULL; -} - -/* cross-interpreter data for builtin types */ - -struct _shared_bytes_data { - char *bytes; - Py_ssize_t len; -}; - -static PyObject * -_new_bytes_object(_PyCrossInterpreterData *data) -{ - struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data); - return PyBytes_FromStringAndSize(shared->bytes, shared->len); -} - -static int -_bytes_shared(PyThreadState *tstate, PyObject *obj, - _PyCrossInterpreterData *data) -{ - if (_PyCrossInterpreterData_InitWithSize( - data, tstate->interp, sizeof(struct _shared_bytes_data), obj, - _new_bytes_object - ) < 0) - { - return -1; - } - struct _shared_bytes_data *shared = (struct _shared_bytes_data *)data->data; - if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { - _PyCrossInterpreterData_Clear(tstate->interp, data); - return -1; - } - return 0; -} - -struct _shared_str_data { - int kind; - const void *buffer; - Py_ssize_t len; -}; - -static PyObject * -_new_str_object(_PyCrossInterpreterData *data) -{ - struct _shared_str_data *shared = (struct _shared_str_data *)(data->data); - return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len); -} - -static int -_str_shared(PyThreadState *tstate, PyObject *obj, - _PyCrossInterpreterData *data) -{ - if (_PyCrossInterpreterData_InitWithSize( - data, tstate->interp, sizeof(struct _shared_str_data), obj, - _new_str_object - ) < 0) - { - return -1; - } - struct _shared_str_data *shared = (struct _shared_str_data *)data->data; - shared->kind = PyUnicode_KIND(obj); - shared->buffer = PyUnicode_DATA(obj); - shared->len = PyUnicode_GET_LENGTH(obj); - return 0; -} - -static PyObject * -_new_long_object(_PyCrossInterpreterData *data) -{ - return PyLong_FromSsize_t((Py_ssize_t)(data->data)); -} - -static int -_long_shared(PyThreadState *tstate, PyObject *obj, - _PyCrossInterpreterData *data) -{ - /* Note that this means the size of shareable ints is bounded by - * sys.maxsize. Hence on 32-bit architectures that is half the - * size of maximum shareable ints on 64-bit. - */ - Py_ssize_t value = PyLong_AsSsize_t(obj); - if (value == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - PyErr_SetString(PyExc_OverflowError, "try sending as bytes"); - } - return -1; - } - _PyCrossInterpreterData_Init(data, tstate->interp, (void *)value, NULL, - _new_long_object); - // data->obj and data->free remain NULL - return 0; -} - -static PyObject * -_new_none_object(_PyCrossInterpreterData *data) -{ - // XXX Singleton refcounts are problematic across interpreters... - return Py_NewRef(Py_None); -} - -static int -_none_shared(PyThreadState *tstate, PyObject *obj, - _PyCrossInterpreterData *data) -{ - _PyCrossInterpreterData_Init(data, tstate->interp, NULL, NULL, - _new_none_object); - // data->data, data->obj and data->free remain NULL - return 0; -} - -static void -_register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) -{ - // None - if (_xidregistry_add_type(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { - Py_FatalError("could not register None for cross-interpreter sharing"); - } - - // int - if (_xidregistry_add_type(xidregistry, &PyLong_Type, _long_shared) != 0) { - Py_FatalError("could not register int for cross-interpreter sharing"); - } - - // bytes - if (_xidregistry_add_type(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { - Py_FatalError("could not register bytes for cross-interpreter sharing"); - } - - // str - if (_xidregistry_add_type(xidregistry, &PyUnicode_Type, _str_shared) != 0) { - Py_FatalError("could not register str for cross-interpreter sharing"); - } -} - +/*************/ +/* Other API */ +/*************/ _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1b282aa870bfd2..5f305aa00e08b9 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -23,7 +23,7 @@ #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() @@ -40,14 +40,17 @@ /* Forward */ static void flush_io(void); static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, - PyCompilerFlags *, PyArena *); + PyCompilerFlags *, PyArena *, PyObject*, int); static PyObject *run_pyc_file(FILE *, PyObject *, PyObject *, PyCompilerFlags *); static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *); static PyObject* pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags); - +static PyObject * +_PyRun_StringFlagsWithName(const char *str, PyObject* name, int start, + PyObject *globals, PyObject *locals, PyCompilerFlags *flags, + int generate_new_source); int _PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit, @@ -178,7 +181,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(); @@ -236,9 +240,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); @@ -266,7 +270,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; @@ -279,7 +284,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, 1); _PyArena_Free(arena); Py_DECREF(main_module); if (res == NULL) { @@ -497,16 +502,25 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, int -PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) -{ +_PyRun_SimpleStringFlagsWithName(const char *command, const char* name, PyCompilerFlags *flags) { PyObject *main_module = PyImport_AddModuleRef("__main__"); if (main_module == NULL) { return -1; } PyObject *dict = PyModule_GetDict(main_module); // borrowed ref - PyObject *res = PyRun_StringFlags(command, Py_file_input, - dict, dict, flags); + PyObject *res = NULL; + if (name == NULL) { + res = PyRun_StringFlags(command, Py_file_input, dict, dict, flags); + } else { + PyObject* the_name = PyUnicode_FromString(name); + if (!the_name) { + PyErr_Print(); + return -1; + } + res = _PyRun_StringFlagsWithName(command, the_name, Py_file_input, dict, dict, flags, 0); + Py_DECREF(the_name); + } Py_DECREF(main_module); if (res == NULL) { PyErr_Print(); @@ -517,204 +531,12 @@ 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) +int +PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) { - 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; + return _PyRun_SimpleStringFlagsWithName(command, NULL, flags); } -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) { @@ -828,7 +650,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) PyErr_Clear(); goto done; } - _PyErr_WriteUnraisableMsg("in audit hook", NULL); + PyErr_FormatUnraisable("Exception ignored in audit hook"); } if (hook) { PyObject* args[3] = {typ, exc, tb}; @@ -883,29 +705,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) { @@ -929,15 +735,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; @@ -959,16 +757,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); @@ -976,40 +778,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; } @@ -1020,11 +798,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); @@ -1098,104 +879,9 @@ 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 *notes) -{ - PyObject *f = ctx->file; - - if (notes == NULL) { - return 0; - } - - if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) { - int res = 0; - if (write_indented_margin(ctx, f) < 0) { - res = -1; - } - PyObject *s = PyObject_Repr(notes); - if (s == NULL) { - PyErr_Clear(); - res = PyFile_WriteString("<__notes__ repr() failed>", f); - } - else { - res = PyFile_WriteObject(s, f, Py_PRINT_RAW); - Py_DECREF(s); - } - 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; - } - } - - return 0; -error: - Py_XDECREF(lines); - return -1; -} - static int print_exception(struct exception_print_context *ctx, PyObject *value) { - PyObject *notes = NULL; PyObject *f = ctx->file; if (!PyExceptionInstance_Check(value)) { @@ -1211,9 +897,6 @@ print_exception(struct exception_print_context *ctx, PyObject *value) /* grab the type and notes now because value can change below */ PyObject *type = (PyObject *) Py_TYPE(value); - if (PyObject_GetOptionalAttr(value, &_Py_ID(__notes__), ¬es) < 0) { - goto error; - } if (print_exception_file_and_line(ctx, &value) < 0) { goto error; @@ -1221,22 +904,13 @@ 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, notes) < 0) { - goto error; - } - - Py_XDECREF(notes); Py_DECREF(value); assert(!PyErr_Occurred()); return 0; error: - Py_XDECREF(notes); Py_DECREF(value); return -1; } @@ -1260,29 +934,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; } @@ -1359,133 +1022,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) { @@ -1498,12 +1034,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()); @@ -1515,12 +1046,10 @@ 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) { + assert(value != NULL); assert(file != NULL && file != Py_None); if (PyExceptionInstance_Check(value) && tb != NULL && PyTraceBack_Check(tb)) { @@ -1535,12 +1064,42 @@ _PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) } } + int unhandled_keyboard_interrupt = _PyRuntime.signals.unhandled_keyboard_interrupt; + + // 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_FormatUnraisable( + "Exception ignored in the internal traceback machinery"); + } +#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). @@ -1591,9 +1150,10 @@ void PyErr_DisplayException(PyObject *exc) PyErr_Display(NULL, exc, NULL); } -PyObject * -PyRun_StringFlags(const char *str, int start, PyObject *globals, - PyObject *locals, PyCompilerFlags *flags) +static PyObject * +_PyRun_StringFlagsWithName(const char *str, PyObject* name, int start, + PyObject *globals, PyObject *locals, PyCompilerFlags *flags, + int generate_new_source) { PyObject *ret = NULL; mod_ty mod; @@ -1603,17 +1163,36 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, if (arena == NULL) return NULL; + PyObject* source = NULL; _Py_DECLARE_STR(anon_string, ""); - mod = _PyParser_ASTFromString( - str, &_Py_STR(anon_string), start, flags, arena); - if (mod != NULL) - ret = run_mod(mod, &_Py_STR(anon_string), globals, locals, flags, arena); + if (name) { + source = PyUnicode_FromString(str); + if (!source) { + PyErr_Clear(); + } + } else { + name = &_Py_STR(anon_string); + } + + mod = _PyParser_ASTFromString(str, name, start, flags, arena); + + if (mod != NULL) { + ret = run_mod(mod, name, globals, locals, flags, arena, source, generate_new_source); + } + Py_XDECREF(source); _PyArena_Free(arena); return ret; } +PyObject * +PyRun_StringFlags(const char *str, int start, PyObject *globals, + PyObject *locals, PyCompilerFlags *flags) { + + return _PyRun_StringFlagsWithName(str, NULL, start, globals, locals, flags, 0); +} + static PyObject * pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags) @@ -1633,7 +1212,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, 0); } else { ret = NULL; @@ -1721,12 +1300,76 @@ 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, + int generate_new_source) { 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; + if (generate_new_source) { + interactive_filename = PyUnicode_FromFormat( + "%U-%d", filename, interp->_interactive_src_count++); + } else { + Py_INCREF(interactive_filename); + } + if (interactive_filename == NULL) { + return NULL; + } + } + + PyCodeObject *co = _PyAST_Compile(mod, interactive_filename, flags, -1, arena); + if (co == NULL) { + if (interactive_src) { + 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); diff --git a/Python/pytime.c b/Python/pytime.c index d1e29e57d362f6..77cb95f8feb179 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -55,6 +55,43 @@ #endif +static _PyTime_t +_PyTime_GCD(_PyTime_t x, _PyTime_t y) +{ + // Euclidean algorithm + assert(x >= 1); + assert(y >= 1); + while (y != 0) { + _PyTime_t tmp = y; + y = x % y; + x = tmp; + } + assert(x >= 1); + return x; +} + + +int +_PyTimeFraction_Set(_PyTimeFraction *frac, _PyTime_t numer, _PyTime_t denom) +{ + if (numer < 1 || denom < 1) { + return -1; + } + + _PyTime_t gcd = _PyTime_GCD(numer, denom); + frac->numer = numer / gcd; + frac->denom = denom / gcd; + return 0; +} + + +double +_PyTimeFraction_Resolution(const _PyTimeFraction *frac) +{ + return (double)frac->numer / (double)frac->denom / 1e9; +} + + static void pytime_time_t_overflow(void) { @@ -152,11 +189,17 @@ _PyTime_Mul(_PyTime_t t, _PyTime_t k) } - - _PyTime_t -_PyTime_MulDiv(_PyTime_t ticks, _PyTime_t mul, _PyTime_t div) +_PyTimeFraction_Mul(_PyTime_t ticks, const _PyTimeFraction *frac) { + const _PyTime_t mul = frac->numer; + const _PyTime_t div = frac->denom; + + if (div == 1) { + // Fast-path taken by mach_absolute_time() with 1/1 time base. + return _PyTime_Mul(ticks, mul); + } + /* Compute (ticks * mul / div) in two parts to reduce the risk of integer overflow: compute the integer part, and then the remaining part. @@ -470,7 +513,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; @@ -493,7 +536,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); } @@ -635,6 +678,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) @@ -1006,51 +1059,34 @@ _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) #ifdef __APPLE__ static int -py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) +py_mach_timebase_info(_PyTimeFraction *base, int raise) { - static mach_timebase_info_data_t timebase; - /* According to the Technical Q&A QA1398, mach_timebase_info() cannot - fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ + mach_timebase_info_data_t timebase; + // According to the Technical Q&A QA1398, mach_timebase_info() cannot + // fail: https://developer.apple.com/library/mac/#qa/qa1398/ (void)mach_timebase_info(&timebase); - /* Sanity check: should never occur in practice */ - if (timebase.numer < 1 || timebase.denom < 1) { + // Check that timebase.numer and timebase.denom can be casted to + // _PyTime_t. In practice, timebase uses uint32_t, so casting cannot + // overflow. At the end, only make sure that the type is uint32_t + // (_PyTime_t is 64-bit long). + Py_BUILD_ASSERT(sizeof(timebase.numer) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(timebase.denom) <= sizeof(_PyTime_t)); + _PyTime_t numer = (_PyTime_t)timebase.numer; + _PyTime_t denom = (_PyTime_t)timebase.denom; + + // Known time bases: + // + // * (1, 1) on Intel: 1 ns + // * (1000000000, 33333335) on PowerPC: ~30 ns + // * (1000000000, 25000000) on PowerPC: 40 ns + if (_PyTimeFraction_Set(base, numer, denom) < 0) { if (raise) { PyErr_SetString(PyExc_RuntimeError, "invalid mach_timebase_info"); } return -1; } - - /* Check that timebase.numer and timebase.denom can be casted to - _PyTime_t. In practice, timebase uses uint32_t, so casting cannot - overflow. At the end, only make sure that the type is uint32_t - (_PyTime_t is 64-bit long). */ - static_assert(sizeof(timebase.numer) <= sizeof(_PyTime_t), - "timebase.numer is larger than _PyTime_t"); - static_assert(sizeof(timebase.denom) <= sizeof(_PyTime_t), - "timebase.denom is larger than _PyTime_t"); - - /* Make sure that _PyTime_MulDiv(ticks, timebase_numer, timebase_denom) - cannot overflow. - - Known time bases: - - * (1, 1) on Intel - * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC - - None of these time bases can overflow with 64-bit _PyTime_t, but - check for overflow, just in case. */ - if ((_PyTime_t)timebase.numer > _PyTime_MAX / (_PyTime_t)timebase.denom) { - if (raise) { - PyErr_SetString(PyExc_OverflowError, - "mach_timebase_info is too large"); - } - return -1; - } - - *pnumer = (_PyTime_t)timebase.numer; - *pdenom = (_PyTime_t)timebase.denom; return 0; } #endif @@ -1099,17 +1135,16 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) } #elif defined(__APPLE__) - static _PyTime_t timebase_numer = 0; - static _PyTime_t timebase_denom = 0; - if (timebase_denom == 0) { - if (py_mach_timebase_info(&timebase_numer, &timebase_denom, raise_exc) < 0) { + static _PyTimeFraction base = {0, 0}; + if (base.denom == 0) { + if (py_mach_timebase_info(&base, raise_exc) < 0) { return -1; } } if (info) { info->implementation = "mach_absolute_time()"; - info->resolution = (double)timebase_numer / (double)timebase_denom * 1e-9; + info->resolution = _PyTimeFraction_Resolution(&base); info->monotonic = 1; info->adjustable = 0; } @@ -1119,7 +1154,7 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) assert(uticks <= (uint64_t)_PyTime_MAX); _PyTime_t ticks = (_PyTime_t)uticks; - _PyTime_t ns = _PyTime_MulDiv(ticks, timebase_numer, timebase_denom); + _PyTime_t ns = _PyTimeFraction_Mul(ticks, &base); *tp = pytime_from_nanoseconds(ns); #elif defined(__hpux) @@ -1203,7 +1238,7 @@ _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #ifdef MS_WINDOWS static int -py_win_perf_counter_frequency(LONGLONG *pfrequency, int raise) +py_win_perf_counter_frequency(_PyTimeFraction *base, int raise) { LONGLONG frequency; @@ -1215,25 +1250,20 @@ py_win_perf_counter_frequency(LONGLONG *pfrequency, int raise) // Since Windows XP, frequency cannot be zero. assert(frequency >= 1); - /* Make also sure that (ticks * SEC_TO_NS) cannot overflow in - _PyTime_MulDiv(), with ticks < frequency. - - Known QueryPerformanceFrequency() values: - - * 10,000,000 (10 MHz): 100 ns resolution - * 3,579,545 Hz (3.6 MHz): 279 ns resolution + Py_BUILD_ASSERT(sizeof(_PyTime_t) == sizeof(frequency)); + _PyTime_t denom = (_PyTime_t)frequency; - None of these frequencies can overflow with 64-bit _PyTime_t, but - check for integer overflow just in case. */ - if (frequency > _PyTime_MAX / SEC_TO_NS) { + // Known QueryPerformanceFrequency() values: + // + // * 10,000,000 (10 MHz): 100 ns resolution + // * 3,579,545 Hz (3.6 MHz): 279 ns resolution + if (_PyTimeFraction_Set(base, SEC_TO_NS, denom) < 0) { if (raise) { - PyErr_SetString(PyExc_OverflowError, - "QueryPerformanceFrequency is too large"); + PyErr_SetString(PyExc_RuntimeError, + "invalid QueryPerformanceFrequency"); } return -1; } - - *pfrequency = frequency; return 0; } @@ -1243,16 +1273,16 @@ py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) { assert(info == NULL || raise_exc); - static LONGLONG frequency = 0; - if (frequency == 0) { - if (py_win_perf_counter_frequency(&frequency, raise_exc) < 0) { + static _PyTimeFraction base = {0, 0}; + if (base.denom == 0) { + if (py_win_perf_counter_frequency(&base, raise_exc) < 0) { return -1; } } if (info) { info->implementation = "QueryPerformanceCounter()"; - info->resolution = 1.0 / (double)frequency; + info->resolution = _PyTimeFraction_Resolution(&base); info->monotonic = 1; info->adjustable = 0; } @@ -1268,7 +1298,7 @@ py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) "LONGLONG is larger than _PyTime_t"); ticks = (_PyTime_t)ticksll; - _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency); + _PyTime_t ns = _PyTimeFraction_Mul(ticks, &base); *tp = pytime_from_nanoseconds(ns); return 0; } diff --git a/Python/specialize.c b/Python/specialize.c index d9b748cad78f4f..7c2a4a42b1dcc3 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -10,6 +10,7 @@ #include "pycore_moduleobject.h" #include "pycore_object.h" #include "pycore_opcode_metadata.h" // _PyOpcode_Caches +#include "pycore_opcode_utils.h" // RESUME_AT_FUNC_START #include "pycore_pylifecycle.h" // _PyOS_URandomNonblock() #include "pycore_runtime.h" // _Py_ID() @@ -134,7 +135,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats) 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]) { + if (_PyOpcode_Caches[i] && i != JUMP_BACKWARD) { fprintf(out, "opcode[%s].specializable : 1\n", _PyOpcode_OpName[i]); } PRINT_STAT(i, specialization.success); @@ -199,10 +200,6 @@ print_object_stats(FILE *out, ObjectStats *stats) 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 @@ -215,6 +212,60 @@ print_gc_stats(FILE *out, GCStats *stats) } } +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); + fprintf(out, "Optimization low confidence: %" PRIu64 "\n", stats->low_confidence); + + 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); + } + if (stats->opcode[i].miss) { + fprintf(out, "uops[%s].specialization.miss : %" PRIu64 "\n", names[i], stats->opcode[i].miss); + } + } + + 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) { @@ -222,6 +273,7 @@ print_stats(FILE *out, PyStats *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 @@ -691,7 +743,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 == Py_T_OBJECT_EX) { + if (dmem->type == Py_T_OBJECT_EX || dmem->type == _Py_T_OBJECT) { return OBJECT_SLOT; } return OTHER_SLOT; @@ -891,7 +943,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 == Py_T_OBJECT_EX); + assert(dmem->type == Py_T_OBJECT_EX || dmem->type == _Py_T_OBJECT); assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); @@ -1031,7 +1083,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 == Py_T_OBJECT_EX); + assert(dmem->type == Py_T_OBJECT_EX || dmem->type == _Py_T_OBJECT); assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); @@ -2477,7 +2529,7 @@ static const PyBytesObject no_location = { }; const struct _PyCode_DEF(8) _Py_InitCleanup = { - _PyVarObject_HEAD_INIT(&PyCode_Type, 4) + _PyVarObject_HEAD_INIT(&PyCode_Type, 3), .co_consts = (PyObject *)&_Py_SINGLETON(tuple_empty), .co_names = (PyObject *)&_Py_SINGLETON(tuple_empty), .co_exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty), @@ -2492,9 +2544,8 @@ const struct _PyCode_DEF(8) _Py_InitCleanup = { .co_stacksize = 2, .co_framesize = 2 + FRAME_SPECIALS_SIZE, .co_code_adaptive = { - NOP, 0, EXIT_INIT_CHECK, 0, RETURN_VALUE, 0, - RESUME, 0, + RESUME, RESUME_AT_FUNC_START, } }; 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/symtable.c b/Python/symtable.c index 75ea9e902f4381..52d5932896b263 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -497,18 +497,14 @@ _PySymtable_Lookup(struct symtable *st, void *key) k = PyLong_FromVoidPtr(key); if (k == NULL) return NULL; - v = PyDict_GetItemWithError(st->st_blocks, k); - Py_DECREF(k); - - if (v) { - assert(PySTEntry_Check(v)); - } - else if (!PyErr_Occurred()) { + if (PyDict_GetItemRef(st->st_blocks, k, &v) == 0) { PyErr_SetString(PyExc_KeyError, "unknown symbol table entry"); } + Py_DECREF(k); - return (PySTEntryObject *)Py_XNewRef(v); + assert(v == NULL || PySTEntry_Check(v)); + return (PySTEntryObject *)v; } long @@ -1813,14 +1809,14 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case Try_kind: VISIT_SEQ(st, stmt, s->v.Try.body); - VISIT_SEQ(st, stmt, s->v.Try.orelse); VISIT_SEQ(st, excepthandler, s->v.Try.handlers); + VISIT_SEQ(st, stmt, s->v.Try.orelse); VISIT_SEQ(st, stmt, s->v.Try.finalbody); break; case TryStar_kind: VISIT_SEQ(st, stmt, s->v.TryStar.body); - VISIT_SEQ(st, stmt, s->v.TryStar.orelse); VISIT_SEQ(st, excepthandler, s->v.TryStar.handlers); + VISIT_SEQ(st, stmt, s->v.TryStar.orelse); VISIT_SEQ(st, stmt, s->v.TryStar.finalbody); break; case Assert_kind: diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 7ba7be10aacb92..57dc4a1226ce75 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -40,7 +40,9 @@ Data members: #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 @@ -108,6 +110,9 @@ PySys_GetObject(const char *name) PyObject *value = _PySys_GetObject(tstate->interp, name); /* XXX Suppress a new exception if it was raised and restore * the old one. */ + if (_PyErr_Occurred(tstate)) { + PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()"); + } _PyErr_SetRaisedException(tstate, exc); return value; } @@ -120,11 +125,9 @@ sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v) } PyObject *sd = interp->sysdict; if (v == NULL) { - v = _PyDict_Pop(sd, key, Py_None); - if (v == NULL) { + if (PyDict_Pop(sd, key, NULL) < 0) { return -1; } - Py_DECREF(v); return 0; } else { @@ -189,9 +192,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) { @@ -336,6 +337,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. @@ -435,15 +451,9 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) e->hookCFunction = (Py_AuditHookFunction)hook; e->userData = userData; - if (runtime->audit_hooks.mutex == NULL) { - /* The runtime must not be initialized yet. */ - add_audit_hook_entry_unlocked(runtime, e); - } - else { - PyThread_acquire_lock(runtime->audit_hooks.mutex, WAIT_LOCK); - add_audit_hook_entry_unlocked(runtime, e); - PyThread_release_lock(runtime->audit_hooks.mutex); - } + PyMutex_Lock(&runtime->audit_hooks.mutex); + add_audit_hook_entry_unlocked(runtime, e); + PyMutex_Unlock(&runtime->audit_hooks.mutex); return 0; } @@ -507,6 +517,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; } @@ -970,6 +983,23 @@ sys_intern_impl(PyObject *module, PyObject *s) } +/*[clinic input] +sys._is_interned -> bool + + string: unicode + / + +Return True if the given string is "interned". +[clinic start generated code]*/ + +static int +sys__is_interned_impl(PyObject *module, PyObject *string) +/*[clinic end generated code: output=c3678267b4e9d7ed input=039843e17883b606]*/ +{ + return PyUnicode_CHECK_INTERNED(string); +} + + /* * Cached interned string objects used for calling the profile and * trace functions. @@ -2288,6 +2318,20 @@ sys__getframemodulename_impl(PyObject *module, int depth) return Py_NewRef(r); } +/*[clinic input] +sys._get_cpu_count_config -> int + +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; PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) { @@ -2329,7 +2373,7 @@ PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry( #ifndef MS_WINDOWS if (perf_map_state.perf_map == NULL) { int ret = PyUnstable_PerfMapState_Init(); - if(ret != 0){ + if (ret != 0){ return ret; } } @@ -2356,6 +2400,45 @@ PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) { #endif } +PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename) { +#ifndef MS_WINDOWS + FILE* from = fopen(parent_filename, "r"); + if (!from) { + return -1; + } + if (perf_map_state.perf_map == NULL) { + int ret = PyUnstable_PerfMapState_Init(); + if (ret != 0) { + return ret; + } + } + char buf[4096]; + PyThread_acquire_lock(perf_map_state.map_lock, 1); + int fflush_result = 0, result = 0; + while (1) { + size_t bytes_read = fread(buf, 1, sizeof(buf), from); + size_t bytes_written = fwrite(buf, 1, bytes_read, perf_map_state.perf_map); + fflush_result = fflush(perf_map_state.perf_map); + if (fflush_result != 0 || bytes_read == 0 || bytes_written < bytes_read) { + result = -1; + goto close_and_release; + } + if (bytes_read < sizeof(buf) && feof(from)) { + goto close_and_release; + } + } +close_and_release: + fclose(from); + PyThread_release_lock(perf_map_state.map_lock); + return result; +#endif + return 0; +} + +#ifdef __cplusplus +} +#endif + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ @@ -2390,6 +2473,7 @@ static PyMethodDef sys_methods[] = { SYS_GETWINDOWSVERSION_METHODDEF SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF SYS_INTERN_METHODDEF + SYS__IS_INTERNED_METHODDEF SYS_IS_FINALIZING_METHODDEF SYS_MDEBUG_METHODDEF SYS_SETSWITCHINTERVAL_METHODDEF @@ -2422,6 +2506,7 @@ static PyMethodDef sys_methods[] = { SYS__STATS_CLEAR_METHODDEF SYS__STATS_DUMP_METHODDEF #endif + SYS__GET_CPU_COUNT_CONFIG_METHODDEF {NULL, NULL} // sentinel }; diff --git a/Python/thread.c b/Python/thread.c index 1ac2db2937e373..fefae8391617f7 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -6,9 +6,10 @@ Stuff shared by all thread_*.h files is collected here. */ #include "Python.h" +#include "pycore_ceval.h" // _PyEval_MakePendingCalls() #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 @@ -17,6 +18,26 @@ #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 @@ -72,6 +93,89 @@ PyThread_set_stacksize(size_t size) } +int +PyThread_ParseTimeoutArg(PyObject *arg, int blocking, PY_TIMEOUT_T *timeout_p) +{ + assert(_PyTime_FromSeconds(-1) == PyThread_UNSET_TIMEOUT); + if (arg == NULL || arg == Py_None) { + *timeout_p = blocking ? PyThread_UNSET_TIMEOUT : 0; + return 0; + } + if (!blocking) { + PyErr_SetString(PyExc_ValueError, + "can't specify a timeout for a non-blocking call"); + return -1; + } + + _PyTime_t timeout; + if (_PyTime_FromSecondsObject(&timeout, arg, _PyTime_ROUND_TIMEOUT) < 0) { + return -1; + } + if (timeout < 0) { + PyErr_SetString(PyExc_ValueError, + "timeout value must be a non-negative number"); + return -1; + } + + if (_PyTime_AsMicroseconds(timeout, + _PyTime_ROUND_TIMEOUT) > PY_TIMEOUT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "timeout value is too large"); + return -1; + } + *timeout_p = timeout; + return 0; +} + +PyLockStatus +PyThread_acquire_lock_timed_with_retries(PyThread_type_lock lock, + PY_TIMEOUT_T timeout) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyTime_t endtime = 0; + if (timeout > 0) { + endtime = _PyDeadline_Init(timeout); + } + + PyLockStatus r; + do { + _PyTime_t microseconds; + microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING); + + /* first a simple non-blocking try without releasing the GIL */ + r = PyThread_acquire_lock_timed(lock, 0, 0); + if (r == PY_LOCK_FAILURE && microseconds != 0) { + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock_timed(lock, microseconds, 1); + Py_END_ALLOW_THREADS + } + + if (r == PY_LOCK_INTR) { + /* Run signal handlers if we were interrupted. Propagate + * exceptions from signal handlers, such as KeyboardInterrupt, by + * passing up PY_LOCK_INTR. */ + if (_PyEval_MakePendingCalls(tstate) < 0) { + return PY_LOCK_INTR; + } + + /* If we're using a timeout, recompute the timeout after processing + * signals, since those can take time. */ + if (timeout > 0) { + timeout = _PyDeadline_Get(endtime); + + /* Check for negative values, since those mean block forever. + */ + if (timeout < 0) { + r = PY_LOCK_FAILURE; + } + } + } + } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */ + + return r; +} + + /* Thread Specific Storage (TSS) API Cross-platform components of TSS API implementation. diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 26f441bd6d3c56..14b9cddc24c0ec 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -182,9 +182,9 @@ bootstrap(void *call) return 0; } -unsigned long -PyThread_start_new_thread(void (*func)(void *), void *arg) -{ +int +PyThread_start_joinable_thread(void (*func)(void *), void *arg, + PyThread_ident_t* ident, PyThread_handle_t* handle) { HANDLE hThread; unsigned threadID; callobj *obj; @@ -194,7 +194,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); if (!obj) - return PYTHREAD_INVALID_THREAD_ID; + return -1; obj->func = func; obj->arg = arg; PyThreadState *tstate = _PyThreadState_GET(); @@ -207,22 +207,51 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) /* I've seen errno == EAGAIN here, which means "there are * too many threads". */ - int e = errno; - threadID = (unsigned)-1; HeapFree(GetProcessHeap(), 0, obj); + return -1; } - else { - CloseHandle(hThread); + *ident = threadID; + // The cast is safe since HANDLE is pointer-sized + *handle = (PyThread_handle_t) hThread; + return 0; +} + +unsigned long +PyThread_start_new_thread(void (*func)(void *), void *arg) { + PyThread_handle_t handle; + PyThread_ident_t ident; + if (PyThread_start_joinable_thread(func, arg, &ident, &handle)) { + return PYTHREAD_INVALID_THREAD_ID; } - return threadID; + CloseHandle((HANDLE) handle); + // The cast is safe since the ident is really an unsigned int + return (unsigned long) ident; +} + +int +PyThread_join_thread(PyThread_handle_t handle) { + HANDLE hThread = (HANDLE) handle; + int errored = (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0); + CloseHandle(hThread); + return errored; +} + +int +PyThread_detach_thread(PyThread_handle_t handle) { + HANDLE hThread = (HANDLE) handle; + return (CloseHandle(hThread) == 0); +} + +void +PyThread_update_thread_after_fork(PyThread_ident_t* ident, PyThread_handle_t* handle) { } /* * Return the thread Id instead of a handle. The Id is said to uniquely identify the * thread in the system */ -unsigned long -PyThread_get_thread_ident(void) +PyThread_ident_t +PyThread_get_thread_ident_ex(void) { if (!initialized) PyThread_init_thread(); @@ -230,6 +259,13 @@ PyThread_get_thread_ident(void) return GetCurrentThreadId(); } +unsigned long +PyThread_get_thread_ident(void) +{ + return (unsigned long) PyThread_get_thread_ident_ex(); +} + + #ifdef PY_HAVE_THREAD_NATIVE_ID /* * Return the native Thread ID (TID) of the calling thread. diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index f96c57da64636d..fb3b79fc160502 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 */ @@ -19,6 +20,8 @@ # include /* syscall(SYS_gettid) */ #elif defined(__FreeBSD__) # include /* pthread_getthreadid_np() */ +#elif defined(__FreeBSD_kernel__) +# include /* syscall(SYS_thr_self) */ #elif defined(__OpenBSD__) # include /* getthrid() */ #elif defined(_AIX) @@ -84,10 +87,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 @@ -234,8 +237,8 @@ pythread_wrapper(void *arg) return NULL; } -unsigned long -PyThread_start_new_thread(void (*func)(void *), void *arg) +static int +do_start_joinable_thread(void (*func)(void *), void *arg, pthread_t* out_id) { pthread_t th; int status; @@ -251,7 +254,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) if (pthread_attr_init(&attrs) != 0) - return PYTHREAD_INVALID_THREAD_ID; + return -1; #endif #if defined(THREAD_STACK_SIZE) PyThreadState *tstate = _PyThreadState_GET(); @@ -260,7 +263,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) if (tss != 0) { if (pthread_attr_setstacksize(&attrs, tss) != 0) { pthread_attr_destroy(&attrs); - return PYTHREAD_INVALID_THREAD_ID; + return -1; } } #endif @@ -271,7 +274,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback)); if (callback == NULL) { - return PYTHREAD_INVALID_THREAD_ID; + return -1; } callback->func = func; @@ -291,11 +294,34 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) if (status != 0) { PyMem_RawFree(callback); - return PYTHREAD_INVALID_THREAD_ID; + return -1; } + *out_id = th; + return 0; +} - pthread_detach(th); +int +PyThread_start_joinable_thread(void (*func)(void *), void *arg, + PyThread_ident_t* ident, PyThread_handle_t* handle) { + pthread_t th = (pthread_t) 0; + if (do_start_joinable_thread(func, arg, &th)) { + return -1; + } + *ident = (PyThread_ident_t) th; + *handle = (PyThread_handle_t) th; + assert(th == (pthread_t) *ident); + assert(th == (pthread_t) *handle); + return 0; +} +unsigned long +PyThread_start_new_thread(void (*func)(void *), void *arg) +{ + pthread_t th = (pthread_t) 0; + if (do_start_joinable_thread(func, arg, &th)) { + return PYTHREAD_INVALID_THREAD_ID; + } + pthread_detach(th); #if SIZEOF_PTHREAD_T <= SIZEOF_LONG return (unsigned long) th; #else @@ -303,20 +329,46 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) #endif } +int +PyThread_join_thread(PyThread_handle_t th) { + return pthread_join((pthread_t) th, NULL); +} + +int +PyThread_detach_thread(PyThread_handle_t th) { + return pthread_detach((pthread_t) th); +} + +void +PyThread_update_thread_after_fork(PyThread_ident_t* ident, PyThread_handle_t* handle) { + // The thread id might have been updated in the forked child + pthread_t th = pthread_self(); + *ident = (PyThread_ident_t) th; + *handle = (PyThread_handle_t) th; + assert(th == (pthread_t) *ident); + assert(th == (pthread_t) *handle); +} + /* XXX This implementation is considered (to quote Tim Peters) "inherently hosed" because: - It does not guarantee the promise that a non-zero integer is returned. - The cast to unsigned long is inherently unsafe. - It is not clear that the 'volatile' (for AIX?) are any longer necessary. */ -unsigned long -PyThread_get_thread_ident(void) -{ +PyThread_ident_t +PyThread_get_thread_ident_ex(void) { volatile pthread_t threadid; if (!initialized) PyThread_init_thread(); threadid = pthread_self(); - return (unsigned long) threadid; + assert(threadid == (pthread_t) (PyThread_ident_t) threadid); + return (PyThread_ident_t) threadid; +} + +unsigned long +PyThread_get_thread_ident(void) +{ + return (unsigned long) PyThread_get_thread_ident_ex(); } #ifdef PY_HAVE_THREAD_NATIVE_ID @@ -334,6 +386,9 @@ PyThread_get_thread_native_id(void) #elif defined(__FreeBSD__) int native_id; native_id = pthread_getthreadid_np(); +#elif defined(__FreeBSD_kernel__) + long native_id; + syscall(SYS_thr_self, &native_id); #elif defined(__OpenBSD__) pid_t native_id; native_id = getthrid(); diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h index 48bad36ec449ab..4741e594e52e65 100644 --- a/Python/thread_pthread_stubs.h +++ b/Python/thread_pthread_stubs.h @@ -94,6 +94,15 @@ pthread_detach(pthread_t thread) return 0; } +int +pthread_join(pthread_t thread, void** value_ptr) +{ + if (value_ptr) { + *value_ptr = NULL; + } + return 0; +} + PyAPI_FUNC(pthread_t) pthread_self(void) { return 0; diff --git a/Python/traceback.c b/Python/traceback.c index 7e791d0a59bd82..abd429ac6c1f71 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -16,22 +16,22 @@ #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 "osdefs.h" // SEP -#ifdef HAVE_FCNTL_H -# include +#ifdef HAVE_UNISTD_H +# include // lseek() #endif -#define OFF(x) offsetof(PyTracebackObject, x) +#define OFF(x) offsetof(PyTracebackObject, x) #define PUTS(fd, str) (void)_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] @@ -108,6 +108,26 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_)) return Py_NewRef(ret); } +static int +tb_get_lineno(PyTracebackObject* tb) { + _PyInterpreterFrame* frame = tb->tb_frame->f_frame; + assert(frame != NULL); + return PyCode_Addr2Line(_PyFrame_GetCode(frame), tb->tb_lasti); +} + +static PyObject * +tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_)) +{ + int lineno = self->tb_lineno; + if (lineno == -1) { + lineno = tb_get_lineno(self); + if (lineno < 0) { + Py_RETURN_NONE; + } + } + return PyLong_FromLong(lineno); +} + static int tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) { @@ -151,12 +171,12 @@ static PyMethodDef tb_methods[] = { static PyMemberDef tb_memberlist[] = { {"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 */ }; static PyGetSetDef tb_getsetters[] = { {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL}, + {"tb_lineno", (getter)tb_lineno_get, NULL, NULL, NULL}, {NULL} /* Sentinel */ }; @@ -235,8 +255,7 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) assert(tb_next == NULL || PyTraceBack_Check(tb_next)); assert(frame != NULL); int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT); - return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, - PyFrame_GetLineNumber(frame)); + return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, -1); } @@ -396,27 +415,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; @@ -544,10 +545,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; @@ -573,161 +570,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; - } - - // Keep going if the current char is not ')' - if (i+1 < right->col_offset && (segment_str[i] == ')')) { - continue; - } - - // 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; - Py_ssize_t str_len = strlen(segment_str); - - // Move right_anchor and left_anchor forward to the first non-whitespace character that is not ']' and '[' - while (*left_anchor < str_len && (IS_WHITESPACE(segment_str[*left_anchor]) || segment_str[*left_anchor] != '[')) { - ++*left_anchor; - } - while (*right_anchor < str_len && (IS_WHITESPACE(segment_str[*right_anchor]) || segment_str[*right_anchor] != ']')) { - ++*right_anchor; - } - if (*right_anchor < str_len){ - *right_anchor += 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 @@ -741,42 +588,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) { @@ -793,118 +612,13 @@ 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(); - goto done; - } - - int code_offset = tb->tb_lasti; - PyCodeObject* code = _PyFrame_GetCode(frame->f_frame); - const Py_ssize_t source_line_len = PyUnicode_GET_LENGTH(source_line); - - int start_line; - int end_line; - int start_col_byte_offset; - int end_col_byte_offset; - if (!PyCode_Addr2Location(code, code_offset, &start_line, &start_col_byte_offset, - &end_line, &end_col_byte_offset)) { - goto done; - } - - if (start_line < 0 || end_line < 0 - || start_col_byte_offset < 0 - || end_col_byte_offset < 0) - { - 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; - 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; - } - } - - 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: Py_XDECREF(source_line); return err; } @@ -929,8 +643,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; @@ -949,9 +662,13 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, } while (tb != NULL) { code = PyFrame_GetCode(tb->tb_frame); + int tb_lineno = tb->tb_lineno; + if (tb_lineno == -1) { + tb_lineno = tb_get_lineno(tb); + } if (last_file == NULL || code->co_filename != last_file || - last_line == -1 || tb->tb_lineno != last_line || + last_line == -1 || tb_lineno != last_line || last_name == NULL || code->co_name != last_name) { if (cnt > TB_RECURSIVE_CUTOFF) { if (tb_print_line_repeated(f, cnt) < 0) { @@ -959,14 +676,14 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, } } last_file = code->co_filename; - last_line = tb->tb_lineno; + last_line = tb_lineno; last_name = code->co_name; cnt = 0; } 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) { + if (tb_displayline(tb, f, code->co_filename, tb_lineno, + tb->tb_frame, code->co_name) < 0) { goto error; } @@ -991,8 +708,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; @@ -1015,15 +731,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; } @@ -1033,12 +746,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 diff --git a/Python/vm-state.md b/Python/vm-state.md new file mode 100644 index 00000000000000..4c68ba3b575cc8 --- /dev/null +++ b/Python/vm-state.md @@ -0,0 +1,90 @@ +# Python VM State + +## Definition of Tiers + +- **Tier 1** is the classic Python bytecode interpreter. + This includes the specializing adaptive interpreter described in [PEP 659](https://peps.python.org/pep-0659/) and introduced in Python 3.11. +- **Tier 2**, also known as the micro-instruction ("uop") interpreter, is a new interpreter with a different instruction format. + It will be introduced in Python 3.13, and also forms the basis for a JIT using copy-and-patch technology that is likely to be introduced at the same time (but, unlike the Tier 2 interpreter, hasn't landed in the main branch yet). + +# Frame state + +Almost all interpreter state is nominally stored in the frame structure. +A pointer to the current frame is held in `frame`. It contains: + +- **local variables** (a.k.a. "fast locals") +- **evaluation stack** (tacked onto the end of the locals) +- **stack top** (an integer giving the top of the evaluation stack) +- **instruction pointer** +- **code object**, which holds things like the array of instructions, lists of constants and names referenced by certain instructions, the exception handling table, and the table that translates instruction offsets to line numbers +- **return offset**, only relevant during calls, telling the interpreter where to return + +There are some other fields in the frame structure of less importance; notably frames are linked together in a singly-linked list via the `previous` pointer, pointing from callee to caller. +The frame also holds a pointer to the current function, globals, builtins, and the locals converted to dict (used to support the `locals()` built-in). + +## Fast locals and evaluation stack + +The frame contains a single array of object pointers, `localsplus`, which contains both the fast locals and the stack. +The top of the stack, including the locals, is indicated by `stacktop`. +For example, in a function with three locals, if the stack contains one value, `frame->stacktop == 4`. + +The interpreters share an implementation which uses the same memory but caches the depth (as a pointer) in a C local, `stack_pointer`. +We aren't sure yet exactly how the JIT will implement the stack; likely some of the values near the top of the stack will be held in registers. + +## Instruction pointer + +The canonical, in-memory, representation of the instruction pointer is `frame->instr_ptr`. +It always points to an instruction in the bytecode array of the frame's code object. +Dispatching on `frame->instr_ptr` would be very inefficient, so in Tier 1 we cache the upcoming value of `frame->instr_ptr` in the C local `next_instr`. + +## Tier 2 + +- `stack_pointer` is the same as in Tier 1 (but may be different in the JIT). +- At runtime we do not need a cache representation of `frame->instr_ptr`, as all stores to `frame->instr_ptr` are explicit. +- During optimization we track the value of `frame->instr_ptr`, emitting `_SET_IP` whenever `frame->instr_ptr` would have been updated. + +The Tier 2 instruction pointer is strictly internal to the Tier 2 interpreter, so isn't visible to any other part of the code. + +## Unwinding + +Unwinding uses exception tables to find the next point at which normal execution can occur, or fail if there are no exception handlers. +During unwinding both the stack and the instruction pointer should be in their canonical, in-memory representation. + +## Jumps in bytecode + +The implementation of jumps within a single Tier 2 superblock/trace is just that, an implementation. +The implementation in the JIT and in the Tier 2 interpreter will necessarily be different. +What is in common is that representation in the Tier 2 optimizer. + +We need the following types of jumps: + +- Conditional branches within the superblock. These must only go forwards and be within the superblock. +- Terminal exits. These go back to the Tier 1 interpreter and cannot be modified. +- Loop end jumps. These go backwards, must be within the superblock, cannot be modified, and can only go to the start of the superblock. +- Patchable exits. These initially exit to code that tracks whether the exit is hot (presumably with a counter) and can be patched. + +Currently, we don't have patchable exits. +Patching exits should be fairly straightforward in the interpreter. +It will be more complex in the JIT. + +(We might also consider deoptimizations as a separate jump type.) + +# Thread state and interpreter state + +Another important piece of VM state is the **thread state**, held in `tstate`. +The current frame pointer, `frame`, is always equal to `tstate->current_frame`. +The thread state also holds the exception state (`tstate->exc_info`) and the recursion counters (`tstate->c_recursion_remaining` and `tstate->py_recursion_remaining`). + +The thread state is also used to access the **interpreter state** (`tstate->interp`), which is important since the "eval breaker" flags are stored there (`tstate->interp->ceval.eval_breaker`, an "atomic" variable), as well as the "PEP 523 function" (`tstate->interp->eval_frame`). +The interpreter state also holds the optimizer state (`optimizer` and some counters). +Note that the eval breaker may be moved to the thread state soon as part of the multicore (PEP 703) work. + +# Tier 2 IR format + +The tier 2 IR (Internal Representation) format is also the basis for the Tier 2 interpreter (though the two formats may eventually differ). This format is also used as the input to the machine code generator (the JIT compiler). + +Tier 2 IR entries are all the same size; there is no equivalent to `EXTENDED_ARG` or trailing inline cache entries. Each instruction is a struct with the following fields (all integers of varying sizes): + +- **opcode**: Sometimes the same as a Tier 1 opcode, sometimes a separate micro opcode. Tier 2 opcodes are 9 bits (as opposed to Tier 1 opcodes, which fit in 8 bits). By convention, Tier 2 opcode names start with `_`. +- **oparg**: The argument. Usually the same as the Tier 1 oparg after expansion of `EXTENDED_ARG` prefixes. Up to 32 bits. +- **operand**: An aditional argument, Typically the value of *one* cache item from the Tier 1 inline cache, up to 64 bits. diff --git a/README.rst b/README.rst index 208bf8cec444a3..4c8602c97ac8ef 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 2 ===================================== .. 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:: diff --git a/Tools/build/deepfreeze.py b/Tools/build/deepfreeze.py index c3231a5a40c326..218c64e13374e6 100644 --- a/Tools/build/deepfreeze.py +++ b/Tools/build/deepfreeze.py @@ -115,6 +115,7 @@ def __init__(self, file: TextIO) -> None: self.inits: list[str] = [] self.identifiers, self.strings = self.get_identifiers_and_strings() self.write('#include "Python.h"') + self.write('#include "internal/pycore_object.h"') self.write('#include "internal/pycore_gc.h"') self.write('#include "internal/pycore_code.h"') self.write('#include "internal/pycore_frame.h"') @@ -154,14 +155,10 @@ def block(self, prefix: str, suffix: str = "") -> None: self.write("}" + suffix) def object_head(self, typename: str) -> None: - with self.block(".ob_base =", ","): - self.write(f".ob_refcnt = _Py_IMMORTAL_REFCNT,") - self.write(f".ob_type = &{typename},") + self.write(f".ob_base = _PyObject_HEAD_INIT(&{typename}),") def object_var_head(self, typename: str, size: int) -> None: - with self.block(".ob_base =", ","): - self.object_head(typename) - self.write(f".ob_size = {size},") + self.write(f".ob_base = _PyVarObject_HEAD_INIT(&{typename}, {size}),") def field(self, obj: object, name: str) -> None: self.write(f".{name} = {getattr(obj, name)},") @@ -491,7 +488,10 @@ def generate(args: list[str], output: TextIO) -> None: parser = argparse.ArgumentParser() parser.add_argument("-o", "--output", help="Defaults to deepfreeze.c", default="deepfreeze.c") parser.add_argument("-v", "--verbose", action="store_true", help="Print diagnostics") -parser.add_argument('args', nargs="+", help="Input file and module name (required) in file:modname format") +group = parser.add_mutually_exclusive_group(required=True) +group.add_argument("-f", "--file", help="read rule lines from a file") +group.add_argument('args', nargs="*", default=(), + help="Input file and module name (required) in file:modname format") @contextlib.contextmanager def report_time(label: str): @@ -509,9 +509,18 @@ def main() -> None: args = parser.parse_args() verbose = args.verbose output = args.output + + if args.file: + if verbose: + print(f"Reading targets from {args.file}") + with open(args.file, "rt", encoding="utf-8-sig") as fin: + rules = [x.strip() for x in fin] + else: + rules = args.args + with open(output, "w", encoding="utf-8") as file: with report_time("generate"): - generate(args.args, file) + generate(rules, file) if verbose: print(f"Wrote {os.path.getsize(output)} bytes to {output}") diff --git a/Tools/build/freeze_modules.py b/Tools/build/freeze_modules.py index a07f4d9786ea65..6a54f45bac3a86 100644 --- a/Tools/build/freeze_modules.py +++ b/Tools/build/freeze_modules.py @@ -21,6 +21,7 @@ # .gitattributes and .gitignore files needs to be updated. FROZEN_MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'frozen_modules') DEEPFROZEN_MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'deepfreeze') +DEEPFREEZE_MAPPING_FNAME = 'deepfreeze_mappings.txt' FROZEN_FILE = os.path.join(ROOT_DIR, 'Python', 'frozen.c') MAKEFILE = os.path.join(ROOT_DIR, 'Makefile.pre.in') @@ -467,6 +468,17 @@ def replace_block(lines, start_marker, end_marker, replacements, file): return lines[:start_pos + 1] + replacements + lines[end_pos:] +class UniqueList(list): + def __init__(self): + self._seen = set() + + def append(self, item): + if item in self._seen: + return + super().append(item) + self._seen.add(item) + + def regen_frozen(modules): headerlines = [] parentdir = os.path.dirname(FROZEN_FILE) @@ -476,7 +488,7 @@ def regen_frozen(modules): header = relpath_for_posix_display(src.frozenfile, parentdir) headerlines.append(f'#include "{header}"') - externlines = [] + externlines = UniqueList() bootstraplines = [] stdliblines = [] testlines = [] @@ -645,7 +657,9 @@ def regen_pcbuild(modules): projlines = [] filterlines = [] corelines = [] - deepfreezerules = ['\t'] + deepfreezemappings = [] for src in _iter_sources(modules): pyfile = relpath_for_windows_display(src.pyfile, ROOT_DIR) header = relpath_for_windows_display(src.frozenfile, ROOT_DIR) @@ -659,8 +673,7 @@ def regen_pcbuild(modules): filterlines.append(f' ') filterlines.append(' Python Files') filterlines.append(' ') - deepfreezerules.append(f'\t\t "$(PySourcePath){header}:{src.frozenid}" ^') - deepfreezerules.append('\t\t "-o" "$(PySourcePath)Python\\deepfreeze\\deepfreeze.c"\'/>' ) + deepfreezemappings.append(f' \n') corelines.append(f' ') @@ -675,6 +688,26 @@ def regen_pcbuild(modules): PCBUILD_PROJECT, ) outfile.writelines(lines) + with updating_file_with_tmpfile(PCBUILD_PROJECT) as (infile, outfile): + lines = infile.readlines() + lines = replace_block( + lines, + '', + '', + deepfreezemappings, + PCBUILD_PROJECT, + ) + outfile.writelines(lines) + with updating_file_with_tmpfile(PCBUILD_PROJECT) as (infile, outfile): + lines = infile.readlines() + lines = replace_block( + lines, + '', + '', + [deepfreezemappingsfile, ], + PCBUILD_PROJECT, + ) + outfile.writelines(lines) with updating_file_with_tmpfile(PCBUILD_PROJECT) as (infile, outfile): lines = infile.readlines() lines = replace_block( diff --git a/Tools/build/generate_sbom.py b/Tools/build/generate_sbom.py new file mode 100644 index 00000000000000..0089db81af9b9d --- /dev/null +++ b/Tools/build/generate_sbom.py @@ -0,0 +1,179 @@ +"""Tool for generating Software Bill of Materials (SBOM) for Python's dependencies""" + +import re +import hashlib +import json +import glob +import pathlib +import subprocess +import typing + +# Before adding a new entry to this list, double check that +# the license expression is a valid SPDX license expression: +# See: https://spdx.org/licenses +ALLOWED_LICENSE_EXPRESSIONS = { + "MIT", + "CC0-1.0", + "Apache-2.0", + "BSD-2-Clause", +} + +# Properties which are required for our purposes. +REQUIRED_PROPERTIES_PACKAGE = frozenset([ + "SPDXID", + "name", + "versionInfo", + "downloadLocation", + "checksums", + "licenseConcluded", + "externalRefs", + "originator", + "primaryPackagePurpose", +]) + + +class PackageFiles(typing.NamedTuple): + """Structure for describing the files of a package""" + include: list[str] + exclude: list[str] | None = None + + +# SBOMS don't have a method to specify the sources of files +# so we need to do that external to the SBOM itself. Add new +# values to 'exclude' if we create new files within tracked +# directories that aren't sourced from third-party packages. +PACKAGE_TO_FILES = { + "mpdecimal": PackageFiles( + include=["Modules/_decimal/libmpdec/**"] + ), + "expat": PackageFiles( + include=["Modules/expat/**"] + ), + "pip": PackageFiles( + include=["Lib/ensurepip/_bundled/pip-23.3.1-py3-none-any.whl"] + ), + "macholib": PackageFiles( + include=["Lib/ctypes/macholib/**"], + exclude=[ + "Lib/ctypes/macholib/README.ctypes", + "Lib/ctypes/macholib/fetch_macholib", + "Lib/ctypes/macholib/fetch_macholib.bat", + ], + ), + "libb2": PackageFiles( + include=["Modules/_blake2/impl/**"] + ), + "hacl-star": PackageFiles( + include=["Modules/_hacl/**"], + exclude=[ + "Modules/_hacl/refresh.sh", + "Modules/_hacl/README.md", + "Modules/_hacl/python_hacl_namespace.h", + ] + ), +} + + +def spdx_id(value: str) -> str: + """Encode a value into characters that are valid in an SPDX ID""" + return re.sub(r"[^a-zA-Z0-9.\-]+", "-", value) + + +def filter_gitignored_paths(paths: list[str]) -> list[str]: + """ + Filter out paths excluded by the gitignore file. + The output of 'git check-ignore --non-matching --verbose' looks + like this for non-matching (included) files: + + '::' + + And looks like this for matching (excluded) files: + + '.gitignore:9:*.a Tools/lib.a' + """ + # Filter out files in gitignore. + # Non-matching files show up as '::' + git_check_ignore_proc = subprocess.run( + ["git", "check-ignore", "--verbose", "--non-matching", *paths], + check=False, + stdout=subprocess.PIPE, + ) + # 1 means matches, 0 means no matches. + assert git_check_ignore_proc.returncode in (0, 1) + + # Return the list of paths sorted + git_check_ignore_lines = git_check_ignore_proc.stdout.decode().splitlines() + return sorted([line.split()[-1] for line in git_check_ignore_lines if line.startswith("::")]) + + +def main() -> None: + root_dir = pathlib.Path(__file__).parent.parent.parent + sbom_path = root_dir / "Misc/sbom.spdx.json" + sbom_data = json.loads(sbom_path.read_bytes()) + + # Make a bunch of assertions about the SBOM data to ensure it's consistent. + assert {package["name"] for package in sbom_data["packages"]} == set(PACKAGE_TO_FILES) + for package in sbom_data["packages"]: + + # Properties and ID must be properly formed. + assert set(package.keys()) == REQUIRED_PROPERTIES_PACKAGE + assert package["SPDXID"] == spdx_id(f"SPDXRef-PACKAGE-{package['name']}") + + # Version must be in the download and external references. + version = package["versionInfo"] + assert version in package["downloadLocation"] + assert all(version in ref["referenceLocator"] for ref in package["externalRefs"]) + + # License must be on the approved list for SPDX. + assert package["licenseConcluded"] in ALLOWED_LICENSE_EXPRESSIONS, package["licenseConcluded"] + + # Regenerate file information from current data. + sbom_files = [] + sbom_relationships = [] + + # We call 'sorted()' here a lot to avoid filesystem scan order issues. + for name, files in sorted(PACKAGE_TO_FILES.items()): + package_spdx_id = spdx_id(f"SPDXRef-PACKAGE-{name}") + exclude = files.exclude or () + for include in sorted(files.include): + + # Find all the paths and then filter them through .gitignore. + paths = glob.glob(include, root_dir=root_dir, recursive=True) + paths = filter_gitignored_paths(paths) + assert paths, include # Make sure that every value returns something! + + for path in paths: + # Skip directories and excluded files + if not (root_dir / path).is_file() or path in exclude: + continue + + # SPDX requires SHA1 to be used for files, but we provide SHA256 too. + data = (root_dir / path).read_bytes() + checksum_sha1 = hashlib.sha1(data).hexdigest() + checksum_sha256 = hashlib.sha256(data).hexdigest() + + file_spdx_id = spdx_id(f"SPDXRef-FILE-{path}") + sbom_files.append({ + "SPDXID": file_spdx_id, + "fileName": path, + "checksums": [ + {"algorithm": "SHA1", "checksumValue": checksum_sha1}, + {"algorithm": "SHA256", "checksumValue": checksum_sha256}, + ], + }) + + # Tie each file back to its respective package. + sbom_relationships.append({ + "spdxElementId": package_spdx_id, + "relatedSpdxElement": file_spdx_id, + "relationshipType": "CONTAINS", + }) + + # Update the SBOM on disk + sbom_data["files"] = sbom_files + sbom_data["relationships"] = sbom_relationships + sbom_path.write_text(json.dumps(sbom_data, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Tools/build/generate_stdlib_module_names.py b/Tools/build/generate_stdlib_module_names.py index 766a85d3d6f39e..5dce4e042d1eb4 100644 --- a/Tools/build/generate_stdlib_module_names.py +++ b/Tools/build/generate_stdlib_module_names.py @@ -36,6 +36,7 @@ '_testsinglephase', '_xxsubinterpreters', '_xxinterpchannels', + '_xxinterpqueues', '_xxtestfuzz', 'idlelib.idle_test', 'test', diff --git a/Tools/build/mypy.ini b/Tools/build/mypy.ini new file mode 100644 index 00000000000000..cf1dac7fde5ac5 --- /dev/null +++ b/Tools/build/mypy.ini @@ -0,0 +1,13 @@ +[mypy] +files = Tools/build/generate_sbom.py +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/build/regen-configure.sh b/Tools/build/regen-configure.sh new file mode 100755 index 00000000000000..e34a36c1a573e5 --- /dev/null +++ b/Tools/build/regen-configure.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -e -x + +# The check_generated_files job of .github/workflows/build.yml must kept in +# sync with this script. Use the same container image than the job so the job +# doesn't need to run autoreconf in a container. +IMAGE="ubuntu:22.04" +DEPENDENCIES="autotools-dev autoconf autoconf-archive pkg-config" +AUTORECONF="autoreconf -ivf -Werror" + +WORK_DIR="/src" +SHELL_CMD="apt-get update && apt-get -yq install $DEPENDENCIES && cd $WORK_DIR && $AUTORECONF" + +abs_srcdir=$(cd $(dirname $0)/../..; pwd) + +if podman --version &>/dev/null; then + RUNTIME="podman" +elif docker --version &>/dev/null; then + RUNTIME="docker" +else + echo "$@ needs either Podman or Docker container runtime." >&2 + exit 1 +fi + +PATH_OPT="" +if command -v selinuxenabled >/dev/null && selinuxenabled; then + PATH_OPT=":Z" +fi + +"$RUNTIME" run --rm -v "$abs_srcdir:$WORK_DIR$PATH_OPT" "$IMAGE" /usr/bin/bash -c "$SHELL_CMD" diff --git a/Tools/build/smelly.py b/Tools/build/smelly.py index 276a5ab2cc84c6..7c534269c57a09 100755 --- a/Tools/build/smelly.py +++ b/Tools/build/smelly.py @@ -11,6 +11,16 @@ if sys.platform == 'darwin': ALLOWED_PREFIXES += ('__Py',) +# mimalloc doesn't use static, but it's symbols are not exported +# from the shared library. They do show up in the static library +# before its linked into an executable. +ALLOWED_STATIC_PREFIXES = ('mi_', '_mi_') + +# "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'} @@ -54,7 +64,7 @@ def get_exported_symbols(library, dynamic=False): return stdout -def get_smelly_symbols(stdout): +def get_smelly_symbols(stdout, dynamic=False): smelly_symbols = [] python_symbols = [] local_symbols = [] @@ -72,7 +82,9 @@ 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 or + (not dynamic and symbol.startswith(ALLOWED_STATIC_PREFIXES))): python_symbols.append(result) continue @@ -90,7 +102,7 @@ def get_smelly_symbols(stdout): def check_library(library, dynamic=False): nm_output = get_exported_symbols(library, dynamic) - smelly_symbols, python_symbols = get_smelly_symbols(nm_output) + smelly_symbols, python_symbols = get_smelly_symbols(nm_output, dynamic) if not smelly_symbols: print(f"OK: no smelly symbol found ({len(python_symbols)} Python symbols)") diff --git a/Tools/build/stable_abi.py b/Tools/build/stable_abi.py index 7cba788ff33578..85c437d521a15a 100644 --- a/Tools/build/stable_abi.py +++ b/Tools/build/stable_abi.py @@ -521,7 +521,7 @@ def gcc_get_limited_api_macros(headers): api_hexversion = sys.version_info.major << 24 | sys.version_info.minor << 16 - preprocesor_output_with_macros = subprocess.check_output( + preprocessor_output_with_macros = subprocess.check_output( sysconfig.get_config_var("CC").split() + [ # Prevent the expansion of the exported macros so we can @@ -540,7 +540,7 @@ def gcc_get_limited_api_macros(headers): return { target for target in re.findall( - r"#define (\w+)", preprocesor_output_with_macros + r"#define (\w+)", preprocessor_output_with_macros ) } @@ -561,7 +561,7 @@ def gcc_get_limited_api_definitions(headers): Requires Python built with a GCC-compatible compiler. (clang might work) """ api_hexversion = sys.version_info.major << 24 | sys.version_info.minor << 16 - preprocesor_output = subprocess.check_output( + preprocessor_output = subprocess.check_output( sysconfig.get_config_var("CC").split() + [ # Prevent the expansion of the exported macros so we can capture @@ -581,13 +581,13 @@ def gcc_get_limited_api_definitions(headers): stderr=subprocess.DEVNULL, ) stable_functions = set( - re.findall(r"__PyAPI_FUNC\(.*?\)\s*(.*?)\s*\(", preprocesor_output) + re.findall(r"__PyAPI_FUNC\(.*?\)\s*(.*?)\s*\(", preprocessor_output) ) stable_exported_data = set( - re.findall(r"__EXPORT_DATA\((.*?)\)", preprocesor_output) + re.findall(r"__EXPORT_DATA\((.*?)\)", preprocessor_output) ) stable_data = set( - re.findall(r"__PyAPI_DATA\(.*?\)[\s\*\(]*([^);]*)\)?.*;", preprocesor_output) + re.findall(r"__PyAPI_DATA\(.*?\)[\s\*\(]*([^);]*)\)?.*;", preprocessor_output) ) return stable_data | stable_exported_data | stable_functions 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_analyzer/__init__.py b/Tools/c-analyzer/c_analyzer/__init__.py index 171fa25102bffc..b83ffc087a08d8 100644 --- a/Tools/c-analyzer/c_analyzer/__init__.py +++ b/Tools/c-analyzer/c_analyzer/__init__.py @@ -18,7 +18,7 @@ def analyze(filenmes, **kwargs): - results = iter_analyis_results(filenames, **kwargs) + results = iter_analysis_results(filenames, **kwargs) return Analysis.from_results(results) 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/cpython/_files.py b/Tools/c-analyzer/cpython/_files.py index ee9e46f7e5e95f..a9bf0a1961222a 100644 --- a/Tools/c-analyzer/cpython/_files.py +++ b/Tools/c-analyzer/cpython/_files.py @@ -9,6 +9,7 @@ # Technically, this is covered by "Include/*.h": #'Include/cpython/*.h', 'Include/internal/*.h', + 'Include/internal/mimalloc/**/*.h', 'Modules/**/*.h', 'Modules/**/*.c', 'Objects/**/*.h', diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index 4523b2ed5b9fdf..04388fb54caa6c 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -89,6 +89,11 @@ def clean_lines(text): # not actually source Python/bytecodes.c +# mimalloc +Objects/mimalloc/*.c +Include/internal/mimalloc/*.h +Include/internal/mimalloc/mimalloc/*.h + # @end=conf@ ''') @@ -109,6 +114,7 @@ def clean_lines(text): * . * ./Include * ./Include/internal +* ./Include/internal/mimalloc Modules/_decimal/**/*.c Modules/_decimal/libmpdec Modules/_elementtree.c Modules/expat diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index bb85fba895bc25..e3a1b5d532bda2 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -290,6 +290,10 @@ Objects/exceptions.c - PyExc_UnicodeWarning - Objects/exceptions.c - PyExc_BytesWarning - Objects/exceptions.c - PyExc_ResourceWarning - Objects/exceptions.c - PyExc_EncodingWarning - +Python/crossinterp.c - _PyExc_InterpreterError - +Python/crossinterp.c - _PyExc_InterpreterNotFoundError - +Python/crossinterp.c - PyExc_InterpreterError - +Python/crossinterp.c - PyExc_InterpreterNotFoundError - ##----------------------- ## singletons @@ -418,20 +422,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 - ## state 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 1f398701a7a5b5..2f9e80d6ab6737 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -88,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 @@ -161,6 +165,10 @@ Python/pylifecycle.c fatal_error reentrant - # explicitly protected, internal-only Modules/_xxinterpchannelsmodule.c - _globals - +Modules/_xxinterpqueuesmodule.c - _globals - + +# set once during module init +Modules/_decimal/_decimal.c - minalloc_is_set - ################################## @@ -328,7 +336,7 @@ 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 - _PyEval_BinaryOps - Python/ceval.c - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS - @@ -367,11 +375,11 @@ Python/sysmodule.c - perf_map_state - Python/sysmodule.c - _PySys_ImplCacheTag - Python/sysmodule.c - _PySys_ImplName - Python/sysmodule.c - whatstrings - -Python/optimizer.c - DefaultOptimizer_Type - -Python/optimizer.c - CounterExecutor_Type - -Python/optimizer.c - CounterOptimizer_Type - -Python/optimizer.c - UOpExecutor_Type - -Python/optimizer.c - UOpOptimizer_Type - +Python/optimizer.c - _PyDefaultOptimizer_Type - +Python/optimizer.c - _PyCounterExecutor_Type - +Python/optimizer.c - _PyCounterOptimizer_Type - +Python/optimizer.c - _PyUOpExecutor_Type - +Python/optimizer.c - _PyUOpOptimizer_Type - Python/optimizer.c - _PyOptimizer_Default - ##----------------------- @@ -523,7 +531,7 @@ Modules/_testcapimodule.c make_exception_with_doc kwlist - Modules/_testcapimodule.c raise_SIGINT_then_send_None PyId_send - Modules/_testcapimodule.c slot_tp_del PyId___tp_del__ - Modules/_testcapimodule.c test_capsule buffer - -Modules/_testcapimodule.c test_empty_argparse kwlist - +Modules/_testcapimodule.c getargs_empty kwlist - Modules/_testcapimodule.c test_structmembers_new keywords - Modules/_testcapimodule.c getargs_s_hash_int keywords - Modules/_testcapimodule.c - g_dict_watch_events - @@ -558,7 +566,6 @@ Modules/_testmultiphase.c - def_nonascii_latin - Modules/_testmultiphase.c - def_nonmodule - Modules/_testmultiphase.c - def_nonmodule_with_exec_slots - Modules/_testmultiphase.c - def_nonmodule_with_methods - -Modules/_testmultiphase.c - imp_dummy_def - Modules/_testmultiphase.c - main_def - Modules/_testmultiphase.c - main_slots - Modules/_testmultiphase.c - meth_state_access_slots - @@ -582,6 +589,7 @@ Modules/_xxtestfuzz/_xxtestfuzz.c - _fuzzmodule - Modules/_xxtestfuzz/_xxtestfuzz.c - module_methods - Modules/_xxtestfuzz/fuzzer.c - RE_FLAG_DEBUG - Modules/_xxtestfuzz/fuzzer.c - ast_literal_eval_method - +Modules/_xxtestfuzz/fuzzer.c - bytesio_type - Modules/_xxtestfuzz/fuzzer.c - compiled_patterns - Modules/_xxtestfuzz/fuzzer.c - csv_error - Modules/_xxtestfuzz/fuzzer.c - csv_module - @@ -591,18 +599,24 @@ 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 - xmlparser_type - +Modules/_xxtestfuzz/fuzzer.c - pycompile_scratch - +Modules/_xxtestfuzz/fuzzer.c - start_vals - +Modules/_xxtestfuzz/fuzzer.c - optimize_vals - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput CSV_READER_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput JSON_LOADS_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput SRE_COMPILE_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput SRE_MATCH_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput STRUCT_UNPACK_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput AST_LITERAL_EVAL_INITIALIZED - +Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput ELEMENTTREE_PARSEWHOLE_INITIALIZED - ##----------------------- ## the analyzer should have ignored these # 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 - @@ -664,7 +678,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 - @@ -722,3 +735,4 @@ 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 - +Modules/clinic/md5module.c.h _md5_md5 _keywords - diff --git a/Tools/cases_generator/analysis.py b/Tools/cases_generator/analysis.py index 91dcba8ceee13d..26d92c13cd82ab 100644 --- a/Tools/cases_generator/analysis.py +++ b/Tools/cases_generator/analysis.py @@ -12,7 +12,6 @@ InstructionOrCacheEffect, MacroInstruction, MacroParts, - OverriddenInstructionPlaceHolder, PseudoInstruction, ) import parsing @@ -26,7 +25,7 @@ "co_names": "Use FRAME_CO_NAMES.", } -RE_PREDICTED = r"^\s*(?:GO_TO_INSTRUCTION\(|DEOPT_IF\(.*?,\s*)(\w+)\);\s*(?://.*)?$" +RE_GO_TO_INSTR = r"^\s*GO_TO_INSTRUCTION\((\w+)\);\s*(?://.*)?$" class Analyzer: @@ -66,7 +65,6 @@ def note(self, msg: str, node: parsing.Node) -> None: parsing.InstDef | parsing.Macro | parsing.Pseudo - | OverriddenInstructionPlaceHolder ] instrs: dict[str, Instruction] # Includes ops macros: dict[str, parsing.Macro] @@ -141,22 +139,17 @@ def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None: match thing: case parsing.InstDef(name=name): macro: parsing.Macro | None = None - if thing.kind == "inst": + if thing.kind == "inst" and "override" not in thing.annotations: macro = parsing.Macro(name, [parsing.OpName(name)]) if name in self.instrs: - if not thing.override: + if "override" not in thing.annotations: raise psr.make_syntax_error( f"Duplicate definition of '{name}' @ {thing.context} " f"previous definition @ {self.instrs[name].inst.context}", thing_first_token, ) - placeholder = OverriddenInstructionPlaceHolder(name=name) - self.everything[instrs_idx[name]] = placeholder - if macro is not None: - self.warning( - f"Overriding desugared {macro.name} may not work", thing - ) - if name not in self.instrs and thing.override: + self.everything[instrs_idx[name]] = thing + if name not in self.instrs and "override" in thing.annotations: raise psr.make_syntax_error( f"Definition of '{name}' @ {thing.context} is supposed to be " "an override but no previous definition exists.", @@ -187,16 +180,23 @@ def analyze(self) -> None: Raises SystemExit if there is an error. """ self.analyze_macros_and_pseudos() - self.find_predictions() self.map_families() + self.mark_predictions() self.check_families() - def find_predictions(self) -> None: - """Find the instructions that need PREDICTED() labels.""" + 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_PREDICTED, line): + 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): @@ -225,11 +225,18 @@ def map_families(self) -> None: ) else: member_instr.family = family - elif not self.macro_instrs.get(member): + 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: @@ -365,8 +372,8 @@ def analyze_macro(self, macro: parsing.Macro) -> MacroInstruction: 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 + if instr.name != "_SAVE_RETURN_OFFSET": + # _SAVE_RETURN_OFFSET's oparg does not transfer flags.add(instr.instr_flags) case _: assert_never(component) @@ -376,14 +383,21 @@ def analyze_macro(self, macro: parsing.Macro) -> MacroInstruction: 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] + targets: list[Instruction | MacroInstruction] = [] + for target_name in pseudo.targets: + if target_name in self.instrs: + targets.append(self.instrs[target_name]) + else: + targets.append(self.macro_instrs[target_name]) 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"} + ignored_flags = {"HAS_EVAL_BREAK_FLAG", "HAS_DEOPT_FLAG", "HAS_ERROR_FLAG", + "HAS_ESCAPES_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) + + flags = InstructionFlags(**{f"{f}_FLAG" : True for f in pseudo.flags}) + for t in targets: + flags.add(t.instr_flags) + return PseudoInstruction(pseudo.name, targets, flags) def analyze_instruction( self, instr: Instruction, offset: int @@ -425,7 +439,6 @@ def report_non_viable_uops(self, jsonfile: str) -> None: "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", diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py new file mode 100644 index 00000000000000..bcc13538e51d9b --- /dev/null +++ b/Tools/cases_generator/analyzer.py @@ -0,0 +1,477 @@ +from dataclasses import dataclass +import lexer +import parser +from typing import Optional + + +@dataclass +class Properties: + escapes: bool + infallible: bool + deopts: bool + oparg: bool + jumps: bool + ends_with_eval_breaker: bool + needs_this: bool + always_exits: bool + stores_sp: bool + tier_one_only: bool + + def dump(self, indent: str) -> None: + print(indent, end="") + text = ", ".join([f"{key}: {value}" for (key, value) in self.__dict__.items()]) + print(indent, text, sep="") + + @staticmethod + def from_list(properties: list["Properties"]) -> "Properties": + return Properties( + escapes=any(p.escapes for p in properties), + infallible=all(p.infallible for p in properties), + deopts=any(p.deopts for p in properties), + oparg=any(p.oparg for p in properties), + jumps=any(p.jumps for p in properties), + ends_with_eval_breaker=any(p.ends_with_eval_breaker for p in properties), + needs_this=any(p.needs_this for p in properties), + always_exits=any(p.always_exits for p in properties), + stores_sp=any(p.stores_sp for p in properties), + tier_one_only=any(p.tier_one_only for p in properties), + ) + + +SKIP_PROPERTIES = Properties( + escapes=False, + infallible=True, + deopts=False, + oparg=False, + jumps=False, + ends_with_eval_breaker=False, + needs_this=False, + always_exits=False, + stores_sp=False, + tier_one_only=False, +) + + +@dataclass +class Skip: + "Unused cache entry" + size: int + + @property + def name(self) -> str: + return f"unused/{self.size}" + + @property + def properties(self) -> Properties: + return SKIP_PROPERTIES + + +@dataclass +class StackItem: + name: str + type: str | None + condition: str | None + size: str + peek: bool = False + + def __str__(self) -> str: + cond = f" if ({self.condition})" if self.condition else "" + size = f"[{self.size}]" if self.size != "1" else "" + type = "" if self.type is None else f"{self.type} " + return f"{type}{self.name}{size}{cond} {self.peek}" + + def is_array(self) -> bool: + return self.type == "PyObject **" + + +@dataclass +class StackEffect: + inputs: list[StackItem] + outputs: list[StackItem] + + def __str__(self) -> str: + return f"({', '.join([str(i) for i in self.inputs])} -- {', '.join([str(i) for i in self.outputs])})" + + +@dataclass +class CacheEntry: + name: str + size: int + + def __str__(self) -> str: + return f"{self.name}/{self.size}" + + +@dataclass +class Uop: + name: str + context: parser.Context | None + annotations: list[str] + stack: StackEffect + caches: list[CacheEntry] + body: list[lexer.Token] + properties: Properties + _size: int = -1 + implicitly_created: bool = False + + def dump(self, indent: str) -> None: + print( + indent, self.name, ", ".join(self.annotations) if self.annotations else "" + ) + print(indent, self.stack, ", ".join([str(c) for c in self.caches])) + self.properties.dump(" " + indent) + + @property + def size(self) -> int: + if self._size < 0: + self._size = sum(c.size for c in self.caches) + return self._size + + def is_viable(self) -> bool: + if self.name == "_SAVE_RETURN_OFFSET": + return True # Adjusts next_instr, but only in tier 1 code + if self.properties.needs_this: + return False + if "INSTRUMENTED" in self.name: + return False + if "replaced" in self.annotations: + return False + if self.name in ("INTERPRETER_EXIT", "JUMP_BACKWARD"): + return False + if len([c for c in self.caches if c.name != "unused"]) > 1: + return False + return True + + +Part = Uop | Skip + + +@dataclass +class Instruction: + name: str + parts: list[Part] + _properties: Properties | None + is_target: bool = False + family: Optional["Family"] = None + + @property + def properties(self) -> Properties: + if self._properties is None: + self._properties = self._compute_properties() + return self._properties + + def _compute_properties(self) -> Properties: + return Properties.from_list([part.properties for part in self.parts]) + + def dump(self, indent: str) -> None: + print(indent, self.name, "=", ", ".join([part.name for part in self.parts])) + self.properties.dump(" " + indent) + + @property + def size(self) -> int: + return 1 + sum(part.size for part in self.parts) + + +@dataclass +class PseudoInstruction: + name: str + targets: list[Instruction] + flags: list[str] + + def dump(self, indent: str) -> None: + print(indent, self.name, "->", " or ".join([t.name for t in self.targets])) + + +@dataclass +class Family: + name: str + size: str + members: list[Instruction] + + def dump(self, indent: str) -> None: + print(indent, self.name, "= ", ", ".join([m.name for m in self.members])) + + +@dataclass +class Analysis: + instructions: dict[str, Instruction] + uops: dict[str, Uop] + families: dict[str, Family] + pseudos: dict[str, PseudoInstruction] + + +def analysis_error(message: str, tkn: lexer.Token) -> SyntaxError: + # To do -- support file and line output + # Construct a SyntaxError instance from message and token + return lexer.make_syntax_error(message, "", tkn.line, tkn.column, "") + + +def override_error( + name: str, + context: parser.Context | None, + prev_context: parser.Context | None, + token: lexer.Token, +) -> SyntaxError: + return analysis_error( + f"Duplicate definition of '{name}' @ {context} " + f"previous definition @ {prev_context}", + token, + ) + + +def convert_stack_item(item: parser.StackEffect) -> StackItem: + return StackItem(item.name, item.type, item.cond, (item.size or "1")) + + +def analyze_stack(op: parser.InstDef) -> StackEffect: + inputs: list[StackItem] = [ + convert_stack_item(i) for i in op.inputs if isinstance(i, parser.StackEffect) + ] + outputs: list[StackItem] = [convert_stack_item(i) for i in op.outputs] + for input, output in zip(inputs, outputs): + if input.name == output.name: + input.peek = output.peek = True + return StackEffect(inputs, outputs) + + +def analyze_caches(op: parser.InstDef) -> list[CacheEntry]: + caches: list[parser.CacheEffect] = [ + i for i in op.inputs if isinstance(i, parser.CacheEffect) + ] + return [CacheEntry(i.name, int(i.size)) for i in caches] + + +def variable_used(node: parser.InstDef, 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 is_infallible(op: parser.InstDef) -> bool: + return not ( + variable_used(op, "ERROR_IF") + or variable_used(op, "error") + or variable_used(op, "pop_1_error") + or variable_used(op, "exception_unwind") + or variable_used(op, "resume_with_error") + ) + + +from flags import makes_escaping_api_call + +EXITS = { + "DISPATCH", + "GO_TO_INSTRUCTION", + "Py_UNREACHABLE", + "DISPATCH_INLINED", + "DISPATCH_GOTO", +} + + +def eval_breaker_at_end(op: parser.InstDef) -> bool: + return op.tokens[-5].text == "CHECK_EVAL_BREAKER" + + +def always_exits(op: parser.InstDef) -> bool: + depth = 0 + tkn_iter = iter(op.tokens) + for tkn in tkn_iter: + if tkn.kind == "LBRACE": + depth += 1 + elif tkn.kind == "RBRACE": + depth -= 1 + elif depth > 1: + continue + elif tkn.kind == "GOTO" or tkn.kind == "RETURN": + return True + elif tkn.kind == "KEYWORD": + if tkn.text in EXITS: + return True + elif tkn.kind == "IDENTIFIER": + if tkn.text in EXITS: + return True + if tkn.text == "DEOPT_IF" or tkn.text == "ERROR_IF": + next(tkn_iter) # '(' + t = next(tkn_iter) + if t.text == "true": + return True + return False + + +def compute_properties(op: parser.InstDef) -> Properties: + return Properties( + escapes=makes_escaping_api_call(op), + infallible=is_infallible(op), + deopts=variable_used(op, "DEOPT_IF"), + oparg=variable_used(op, "oparg"), + jumps=variable_used(op, "JUMPBY"), + ends_with_eval_breaker=eval_breaker_at_end(op), + needs_this=variable_used(op, "this_instr"), + always_exits=always_exits(op), + stores_sp=variable_used(op, "STORE_SP"), + tier_one_only=variable_used(op, "TIER_ONE_ONLY"), + ) + + +def make_uop(name: str, op: parser.InstDef) -> Uop: + return Uop( + name=name, + context=op.context, + annotations=op.annotations, + stack=analyze_stack(op), + caches=analyze_caches(op), + body=op.block.tokens, + properties=compute_properties(op), + ) + + +def add_op(op: parser.InstDef, uops: dict[str, Uop]) -> None: + assert op.kind == "op" + if op.name in uops: + if "override" not in op.annotations: + raise override_error( + op.name, op.context, uops[op.name].context, op.tokens[0] + ) + uops[op.name] = make_uop(op.name, op) + + +def add_instruction( + name: str, parts: list[Part], instructions: dict[str, Instruction] +) -> None: + instructions[name] = Instruction(name, parts, None) + + +def desugar_inst( + inst: parser.InstDef, instructions: dict[str, Instruction], uops: dict[str, Uop] +) -> None: + assert inst.kind == "inst" + name = inst.name + uop = make_uop("_" + inst.name, inst) + uop.implicitly_created = True + uops[inst.name] = uop + add_instruction(name, [uop], instructions) + + +def add_macro( + macro: parser.Macro, instructions: dict[str, Instruction], uops: dict[str, Uop] +) -> None: + parts: list[Uop | Skip] = [] + for part in macro.uops: + match part: + case parser.OpName(): + if part.name not in uops: + analysis_error(f"No Uop named {part.name}", macro.tokens[0]) + parts.append(uops[part.name]) + case parser.CacheEffect(): + parts.append(Skip(part.size)) + case _: + assert False + assert parts + add_instruction(macro.name, parts, instructions) + + +def add_family( + pfamily: parser.Family, + instructions: dict[str, Instruction], + families: dict[str, Family], +) -> None: + family = Family( + pfamily.name, + pfamily.size, + [instructions[member_name] for member_name in pfamily.members], + ) + for member in family.members: + member.family = family + # The head of the family is an implicit jump target for DEOPTs + instructions[family.name].is_target = True + families[family.name] = family + + +def add_pseudo( + pseudo: parser.Pseudo, + instructions: dict[str, Instruction], + pseudos: dict[str, PseudoInstruction], +) -> None: + pseudos[pseudo.name] = PseudoInstruction( + pseudo.name, + [instructions[target] for target in pseudo.targets], + pseudo.flags, + ) + + +def analyze_forest(forest: list[parser.AstNode]) -> Analysis: + instructions: dict[str, Instruction] = {} + uops: dict[str, Uop] = {} + families: dict[str, Family] = {} + pseudos: dict[str, PseudoInstruction] = {} + for node in forest: + match node: + case parser.InstDef(name): + if node.kind == "inst": + desugar_inst(node, instructions, uops) + else: + assert node.kind == "op" + add_op(node, uops) + case parser.Macro(): + pass + case parser.Family(): + pass + case parser.Pseudo(): + pass + case _: + assert False + for node in forest: + if isinstance(node, parser.Macro): + add_macro(node, instructions, uops) + for node in forest: + match node: + case parser.Family(): + add_family(node, instructions, families) + case parser.Pseudo(): + add_pseudo(node, instructions, pseudos) + case _: + pass + for uop in uops.values(): + tkn_iter = iter(uop.body) + for tkn in tkn_iter: + if tkn.kind == "IDENTIFIER" and tkn.text == "GO_TO_INSTRUCTION": + if next(tkn_iter).kind != "LPAREN": + continue + target = next(tkn_iter) + if target.kind != "IDENTIFIER": + continue + if target.text in instructions: + instructions[target.text].is_target = True + # Hack + instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"] + return Analysis(instructions, uops, families, pseudos) + + +def analyze_files(filenames: list[str]) -> Analysis: + return analyze_forest(parser.parse_files(filenames)) + + +def dump_analysis(analysis: Analysis) -> None: + print("Uops:") + for u in analysis.uops.values(): + u.dump(" ") + print("Instructions:") + for i in analysis.instructions.values(): + i.dump(" ") + print("Families:") + for f in analysis.families.values(): + f.dump(" ") + print("Pseudos:") + for p in analysis.pseudos.values(): + p.dump(" ") + + +if __name__ == "__main__": + import sys + + if len(sys.argv) < 2: + print("No input") + else: + filenames = sys.argv[1:] + dump_analysis(analyze_files(filenames)) diff --git a/Tools/cases_generator/cwriter.py b/Tools/cases_generator/cwriter.py new file mode 100644 index 00000000000000..34e39855a9b40a --- /dev/null +++ b/Tools/cases_generator/cwriter.py @@ -0,0 +1,116 @@ +from lexer import Token +from typing import TextIO + + +class CWriter: + "A writer that understands tokens and how to format C code" + + last_token: Token | None + + def __init__(self, out: TextIO, indent: int, line_directives: bool): + self.out = out + self.base_column = indent * 4 + self.indents = [i * 4 for i in range(indent + 1)] + self.line_directives = line_directives + self.last_token = None + self.newline = True + + def set_position(self, tkn: Token) -> None: + if self.last_token is not None: + if self.last_token.line < tkn.line: + self.out.write("\n") + if self.line_directives: + self.out.write(f'#line {tkn.line} "{tkn.filename}"\n') + self.out.write(" " * self.indents[-1]) + else: + gap = tkn.column - self.last_token.end_column + self.out.write(" " * gap) + elif self.newline: + self.out.write(" " * self.indents[-1]) + self.last_token = tkn + self.newline = False + + def emit_at(self, txt: str, where: Token) -> None: + self.set_position(where) + self.out.write(txt) + + def maybe_dedent(self, txt: str) -> None: + parens = txt.count("(") - txt.count(")") + if parens < 0: + self.indents.pop() + elif "}" in txt or is_label(txt): + self.indents.pop() + + def maybe_indent(self, txt: str) -> None: + parens = txt.count("(") - txt.count(")") + if parens > 0 and self.last_token: + offset = self.last_token.end_column - 1 + if offset <= self.indents[-1] or offset > 40: + offset = self.indents[-1] + 4 + self.indents.append(offset) + if is_label(txt): + self.indents.append(self.indents[-1] + 4) + elif "{" in txt: + if 'extern "C"' in txt: + self.indents.append(self.indents[-1]) + else: + self.indents.append(self.indents[-1] + 4) + + def emit_text(self, txt: str) -> None: + self.out.write(txt) + + def emit_multiline_comment(self, tkn: Token) -> None: + self.set_position(tkn) + lines = tkn.text.splitlines(True) + first = True + for line in lines: + text = line.lstrip() + if first: + spaces = 0 + else: + spaces = self.indents[-1] + if text.startswith("*"): + spaces += 1 + else: + spaces += 3 + first = False + self.out.write(" " * spaces) + self.out.write(text) + + def emit_token(self, tkn: Token) -> None: + if tkn.kind == "COMMENT" and "\n" in tkn.text: + return self.emit_multiline_comment(tkn) + self.maybe_dedent(tkn.text) + self.set_position(tkn) + self.emit_text(tkn.text) + self.maybe_indent(tkn.text) + + def emit_str(self, txt: str) -> None: + self.maybe_dedent(txt) + if self.newline and txt: + if txt[0] != "\n": + self.out.write(" " * self.indents[-1]) + self.newline = False + self.emit_text(txt) + if txt.endswith("\n"): + self.newline = True + self.maybe_indent(txt) + self.last_token = None + + def emit(self, txt: str | Token) -> None: + if isinstance(txt, Token): + self.emit_token(txt) + elif isinstance(txt, str): + self.emit_str(txt) + else: + assert False + + def start_line(self) -> None: + if not self.newline: + self.out.write("\n") + self.newline = True + self.last_token = None + + +def is_label(txt: str) -> bool: + return not txt.startswith("//") and txt.endswith(":") diff --git a/Tools/cases_generator/flags.py b/Tools/cases_generator/flags.py index 5241331bb97cdb..bf76112159e38e 100644 --- a/Tools/cases_generator/flags.py +++ b/Tools/cases_generator/flags.py @@ -5,6 +5,80 @@ import parsing from typing import AbstractSet +NON_ESCAPING_FUNCTIONS = ( + "Py_INCREF", + "_PyDictOrValues_IsValues", + "_PyObject_DictOrValuesPointer", + "_PyDictOrValues_GetValues", + "_PyObject_MakeInstanceAttributesFromDict", + "Py_DECREF", + "_Py_DECREF_SPECIALIZED", + "DECREF_INPUTS_AND_REUSE_FLOAT", + "PyUnicode_Append", + "_PyLong_IsZero", + "Py_SIZE", + "Py_TYPE", + "PyList_GET_ITEM", + "PyTuple_GET_ITEM", + "PyList_GET_SIZE", + "PyTuple_GET_SIZE", + "Py_ARRAY_LENGTH", + "Py_Unicode_GET_LENGTH", + "PyUnicode_READ_CHAR", + "_Py_SINGLETON", + "PyUnicode_GET_LENGTH", + "_PyLong_IsCompact", + "_PyLong_IsNonNegativeCompact", + "_PyLong_CompactValue", + "_Py_NewRef", + "_Py_IsImmortal", + "_Py_STR", + "_PyLong_Add", + "_PyLong_Multiply", + "_PyLong_Subtract", + "Py_NewRef", + "_PyList_ITEMS", + "_PyTuple_ITEMS", + "_PyList_AppendTakeRef", + "_Py_atomic_load_uintptr_relaxed", + "_PyFrame_GetCode", + "_PyThreadState_HasStackSpace", +) + +ESCAPING_FUNCTIONS = ( + "import_name", + "import_from", +) + + +def makes_escaping_api_call(instr: parsing.InstDef) -> bool: + if "CALL_INTRINSIC" in instr.name: + return True + tkns = iter(instr.tokens) + for tkn in tkns: + if tkn.kind != lx.IDENTIFIER: + continue + try: + next_tkn = next(tkns) + except StopIteration: + return False + if next_tkn.kind != lx.LPAREN: + continue + if tkn.text in ESCAPING_FUNCTIONS: + return True + if not tkn.text.startswith("Py") and not tkn.text.startswith("_Py"): + continue + if tkn.text.endswith("Check"): + continue + if tkn.text.startswith("Py_Is"): + continue + if tkn.text.endswith("CheckExact"): + continue + if tkn.text in NON_ESCAPING_FUNCTIONS: + continue + return True + return False + @dataclasses.dataclass class InstructionFlags: @@ -19,12 +93,13 @@ class InstructionFlags: HAS_EVAL_BREAK_FLAG: bool = False HAS_DEOPT_FLAG: bool = False HAS_ERROR_FLAG: bool = False + HAS_ESCAPES_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": + def fromInstruction(instr: parsing.InstDef) -> "InstructionFlags": has_free = ( variable_used(instr, "PyCell_New") or variable_used(instr, "PyCell_GET") @@ -50,6 +125,7 @@ def fromInstruction(instr: parsing.Node) -> "InstructionFlags": or variable_used(instr, "exception_unwind") or variable_used(instr, "resume_with_error") ), + HAS_ESCAPES_FLAG=makes_escaping_api_call(instr), ) @staticmethod @@ -99,7 +175,7 @@ def variable_used_unspecialized(node: parsing.Node, name: str) -> bool: tokens: list[lx.Token] = [] skipping = False for i, token in enumerate(node.tokens): - if token.kind == "MACRO": + if token.kind == "CMACRO": text = "".join(token.text.split()) # TODO: Handle nested #if if text == "#if": diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index 9192d1038ab7d6..c6ed5911b846bf 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -26,7 +26,6 @@ MacroInstruction, MacroParts, PseudoInstruction, - OverriddenInstructionPlaceHolder, TIER_ONE, TIER_TWO, ) @@ -68,7 +67,7 @@ "OPARG_CACHE_4": 4, "OPARG_TOP": 5, "OPARG_BOTTOM": 6, - "OPARG_SET_IP": 7, + "OPARG_SAVE_RETURN_OFFSET": 7, } INSTR_FMT_PREFIX = "INSTR_FMT_" @@ -95,20 +94,13 @@ arg_parser.add_argument( "-v", - "--verbose", + "--viable", 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( - "-n", - "--opcode_ids_h", - type=str, - help="Header file with opcode number definitions", - default=DEFAULT_OPCODE_IDS_H_OUTPUT, -) arg_parser.add_argument( "-t", "--opcode_targets_h", @@ -136,13 +128,6 @@ arg_parser.add_argument( "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" ) -arg_parser.add_argument( - "-e", - "--executor-cases", - type=str, - help="Write executor cases to this file", - default=DEFAULT_EXECUTOR_OUTPUT, -) arg_parser.add_argument( "-a", "--abstract-interpreter-cases", @@ -179,17 +164,17 @@ def effect_str(effects: list[StackEffect]) -> str: # for all targets. for target in self.pseudos[thing.name].targets: target_instr = self.instrs.get(target) - # Currently target is always an instr. This could change - # in the future, e.g., if we have a pseudo targetting a - # macro instruction. - assert target_instr - target_popped = effect_str(target_instr.input_effects) - target_pushed = effect_str(target_instr.output_effects) - if popped is None: - popped, pushed = target_popped, target_pushed + if target_instr is None: + macro_instr = self.macro_instrs[target] + popped, pushed = stacking.get_stack_effect_info_for_macro(macro_instr) else: - assert popped == target_popped - assert pushed == target_pushed + target_popped = effect_str(target_instr.input_effects) + target_pushed = effect_str(target_instr.output_effects) + if popped is None: + popped, pushed = target_popped, target_pushed + else: + assert popped == target_popped + assert pushed == target_pushed case _: assert_never(thing) assert popped is not None and pushed is not None @@ -208,8 +193,6 @@ 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): - continue if isinstance(thing, parsing.Macro) and thing.name in self.instrs: continue instr, popped, pushed = self.get_stack_effect_info(thing) @@ -337,42 +320,8 @@ def map_op(op: int, name: str) -> None: 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 */") + def write_opcode_targets(self, opcode_targets_filename: str) -> None: + """Write header file that defines the jump target table""" with open(opcode_targets_filename, "w") as f: # Create formatter @@ -393,20 +342,14 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No for thing in self.everything: format: str | None = None match thing: - case OverriddenInstructionPlaceHolder(): - continue case parsing.InstDef(): format = self.instrs[thing.name].instr_fmt case parsing.Macro(): format = self.macro_instrs[thing.name].instr_fmt case parsing.Pseudo(): - for target in self.pseudos[thing.name].targets: - target_instr = self.instrs.get(target) - assert target_instr - if format is None: - format = target_instr.instr_fmt - else: - assert format == target_instr.instr_fmt + # Pseudo instructions exist only in the compiler, + # so do not have a format + continue case _: assert_never(thing) assert format is not None @@ -431,7 +374,7 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No self.write_pseudo_instrs() self.out.emit("") - self.write_uop_items(lambda name, counter: f"#define {name} {counter}") + self.out.emit('#include "pycore_uop_ids.h"') self.write_stack_effect_functions() @@ -469,12 +412,12 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No self.out.emit("") self.out.emit( - "#define OPCODE_METADATA_FMT(OP) " - "(_PyOpcode_opcode_metadata[(OP)].instr_format)" + "#define OPCODE_METADATA_FLAGS(OP) " + "(_PyOpcode_opcode_metadata[(OP)].flags & (HAS_ARG_FLAG | HAS_JUMP_FLAG))" ) self.out.emit("#define SAME_OPCODE_METADATA(OP1, OP2) \\") self.out.emit( - " (OPCODE_METADATA_FMT(OP1) == OPCODE_METADATA_FMT(OP2))" + " (OPCODE_METADATA_FLAGS(OP1) == OPCODE_METADATA_FLAGS(OP2))" ) self.out.emit("") @@ -492,8 +435,6 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No # Write metadata for each instruction for thing in self.everything: match thing: - case OverriddenInstructionPlaceHolder(): - continue case parsing.InstDef(): self.write_metadata_for_inst(self.instrs[thing.name]) case parsing.Macro(): @@ -552,8 +493,6 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No 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(): @@ -664,11 +603,14 @@ def write_macro_expansions( expansions: list[tuple[str, int, int]] = [] # [(name, size, offset), ...] for part in parts: if isinstance(part, Component): - # All component instructions must be viable uops - if not part.instr.is_viable_uop(): + # Skip specializations + if "specializing" in part.instr.annotations: + continue + # All other component instructions must be viable uops + if not part.instr.is_viable_uop() and "replaced" not in part.instr.annotations: # 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 + # Suppress it using 'replaced op(...)' for macros having # manual translation in translate_bytecode_to_trace() # in Python/optimizer.c. if len(parts) > 1 or part.instr.name != name: @@ -678,8 +620,8 @@ def write_macro_expansions( ) return if not part.active_caches: - if part.instr.name == "_SET_IP": - size, offset = OPARG_SIZES["OPARG_SET_IP"], cache_offset + if part.instr.name == "_SAVE_RETURN_OFFSET": + size, offset = OPARG_SIZES["OPARG_SAVE_RETURN_OFFSET"], cache_offset else: size, offset = OPARG_SIZES["OPARG_FULL"], 0 else: @@ -739,12 +681,13 @@ def write_expansions( 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 | None, flags: InstructionFlags) -> None: flag_names = flags.names(value=True) if not flag_names: flag_names.append("0") + fmt_macro = "0" if fmt is None else INSTR_FMT_PREFIX + fmt self.out.emit( - f"[{name}] = {{ true, {INSTR_FMT_PREFIX}{fmt}," + f"[{name}] = {{ true, {fmt_macro}," f" {' | '.join(flag_names)} }}," ) @@ -758,7 +701,7 @@ def write_metadata_for_macro(self, mac: MacroInstruction) -> None: 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) + self.emit_metadata_entry(ps.name, None, ps.instr_flags) def write_instructions( self, output_filename: str, emit_line_directives: bool @@ -770,24 +713,33 @@ def write_instructions( self.write_provenance_header() + self.out.write_raw("\n") + self.out.write_raw("#ifdef TIER_TWO\n") + self.out.write_raw(" #error \"This file is for Tier 1 only\"\n") + self.out.write_raw("#endif\n") + self.out.write_raw("#define TIER_ONE 1\n") + # Write and count instructions of all kinds n_macros = 0 + cases = [] for thing in self.everything: match thing: - case OverriddenInstructionPlaceHolder(): - self.write_overridden_instr_place_holder(thing) case parsing.InstDef(): pass case parsing.Macro(): n_macros += 1 mac = self.macro_instrs[thing.name] - stacking.write_macro_instr( - mac, self.out, self.families.get(mac.name) - ) + cases.append((mac.name, mac)) case parsing.Pseudo(): pass case _: assert_never(thing) + cases.sort() + for _, mac in cases: + stacking.write_macro_instr(mac, self.out) + + self.out.write_raw("\n") + self.out.write_raw("#undef TIER_ONE\n") print( f"Wrote {n_macros} cases to {output_filename}", @@ -802,15 +754,28 @@ def write_executor_instructions( with open(executor_filename, "w") as f: self.out = Formatter(f, 8, emit_line_directives) self.write_provenance_header() + + self.out.write_raw("\n") + self.out.write_raw("#ifdef TIER_ONE\n") + self.out.write_raw(" #error \"This file is for Tier 2 only\"\n") + self.out.write_raw("#endif\n") + self.out.write_raw("#define TIER_TWO 2\n") + 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}:"): + if instr.instr_flags.HAS_ARG_FLAG: + self.out.emit("oparg = CURRENT_OPARG();") 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;") + + self.out.write_raw("\n") + self.out.write_raw("#undef TIER_TWO\n") + print( f"Wrote {n_uops} cases to {executor_filename}", file=sys.stderr, @@ -838,14 +803,6 @@ def write_abstract_interpreter_instructions( 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 is_super_instruction(mac: MacroInstruction) -> bool: if ( @@ -872,18 +829,16 @@ def main() -> None: a.analyze() # Prints messages and sets a.errors on failure if a.errors: sys.exit(f"Found {a.errors} errors") - if args.verbose: + if args.viable: # 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_opcode_targets(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 ) diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py new file mode 100644 index 00000000000000..e0674a7343498d --- /dev/null +++ b/Tools/cases_generator/generators_common.py @@ -0,0 +1,186 @@ +from pathlib import Path +from typing import TextIO + +from analyzer import ( + Analysis, + Instruction, + Uop, + Part, + analyze_files, + Skip, + StackItem, + analysis_error, +) +from cwriter import CWriter +from typing import Callable, Mapping, TextIO, Iterator +from lexer import Token +from stack import StackOffset, Stack + + +ROOT = Path(__file__).parent.parent.parent +DEFAULT_INPUT = (ROOT / "Python/bytecodes.c").absolute().as_posix() + + +def root_relative_path(filename: str) -> str: + return Path(filename).absolute().relative_to(ROOT).as_posix() + + +def write_header(generator: str, sources: list[str], outfile: TextIO) -> None: + outfile.write( + f"""// This file is generated by {root_relative_path(generator)} +// from: +// {", ".join(root_relative_path(src) for src in sources)} +// Do not edit! +""" + ) + + +def emit_to(out: CWriter, tkn_iter: Iterator[Token], end: str) -> None: + parens = 0 + for tkn in tkn_iter: + if tkn.kind == end and parens == 0: + return + if tkn.kind == "LPAREN": + parens += 1 + if tkn.kind == "RPAREN": + parens -= 1 + out.emit(tkn) + + +def replace_deopt( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + unused: Stack, + inst: Instruction | None, +) -> None: + out.emit_at("DEOPT_IF", tkn) + out.emit(next(tkn_iter)) + emit_to(out, tkn_iter, "RPAREN") + next(tkn_iter) # Semi colon + out.emit(", ") + assert inst is not None + assert inst.family is not None + out.emit(inst.family.name) + out.emit(");\n") + + +def replace_error( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + stack: Stack, + inst: Instruction | None, +) -> None: + out.emit_at("if ", tkn) + out.emit(next(tkn_iter)) + emit_to(out, tkn_iter, "COMMA") + label = next(tkn_iter).text + next(tkn_iter) # RPAREN + next(tkn_iter) # Semi colon + out.emit(") ") + c_offset = stack.peek_offset.to_c() + try: + offset = -int(c_offset) + close = ";\n" + except ValueError: + offset = None + out.emit(f"{{ stack_pointer += {c_offset}; ") + close = "; }\n" + out.emit("goto ") + if offset: + out.emit(f"pop_{offset}_") + out.emit(label) + out.emit(close) + + +def replace_decrefs( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + stack: Stack, + inst: Instruction | None, +) -> None: + next(tkn_iter) + next(tkn_iter) + next(tkn_iter) + out.emit_at("", tkn) + for var in uop.stack.inputs: + if var.name == "unused" or var.name == "null" or var.peek: + continue + if var.size != "1": + out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") + out.emit(f"Py_DECREF({var.name}[_i]);\n") + out.emit("}\n") + elif var.condition: + out.emit(f"Py_XDECREF({var.name});\n") + else: + out.emit(f"Py_DECREF({var.name});\n") + + +def replace_store_sp( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + stack: Stack, + inst: Instruction | None, +) -> None: + next(tkn_iter) + next(tkn_iter) + next(tkn_iter) + out.emit_at("", tkn) + stack.flush(out) + out.emit("_PyFrame_SetStackPointer(frame, stack_pointer);\n") + + +def replace_check_eval_breaker( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + stack: Stack, + inst: Instruction | None, +) -> None: + next(tkn_iter) + next(tkn_iter) + next(tkn_iter) + if not uop.properties.ends_with_eval_breaker: + out.emit_at("CHECK_EVAL_BREAKER();", tkn) + + +REPLACEMENT_FUNCTIONS = { + "DEOPT_IF": replace_deopt, + "ERROR_IF": replace_error, + "DECREF_INPUTS": replace_decrefs, + "CHECK_EVAL_BREAKER": replace_check_eval_breaker, + "STORE_SP": replace_store_sp, +} + +ReplacementFunctionType = Callable[ + [CWriter, Token, Iterator[Token], Uop, Stack, Instruction | None], None +] + + +def emit_tokens( + out: CWriter, + uop: Uop, + stack: Stack, + inst: Instruction | None, + replacement_functions: Mapping[ + str, ReplacementFunctionType + ] = REPLACEMENT_FUNCTIONS, +) -> None: + tkns = uop.body[1:-1] + if not tkns: + return + tkn_iter = iter(tkns) + out.start_line() + for tkn in tkn_iter: + if tkn.kind == "IDENTIFIER" and tkn.text in replacement_functions: + replacement_functions[tkn.text](out, tkn, tkn_iter, uop, stack, inst) + else: + out.emit(tkn) diff --git a/Tools/cases_generator/instructions.py b/Tools/cases_generator/instructions.py index 6fbf7d93f42fde..149a08810e4ae5 100644 --- a/Tools/cases_generator/instructions.py +++ b/Tools/cases_generator/instructions.py @@ -25,18 +25,10 @@ class ActiveCacheEffect: 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", ) @@ -54,6 +46,7 @@ class Instruction: # Parts of the underlying instruction definition inst: parsing.InstDef name: str + annotations: list[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 @@ -61,6 +54,7 @@ class Instruction: # Computed by constructor always_exits: str # If the block always exits, its last line; else "" has_deopt: bool + needs_this_instr: bool cache_offset: int cache_effects: list[parsing.CacheEffect] input_effects: list[StackEffect] @@ -77,6 +71,7 @@ class Instruction: def __init__(self, inst: parsing.InstDef): self.inst = inst self.name = inst.name + self.annotations = inst.annotations self.block = inst.block self.block_text, self.check_eval_breaker, self.block_line = extract_block_text( self.block @@ -87,6 +82,7 @@ def __init__(self, inst: parsing.InstDef): effect for effect in inst.inputs if isinstance(effect, parsing.CacheEffect) ] self.cache_offset = sum(c.size for c in self.cache_effects) + self.needs_this_instr = variable_used(self.inst, "this_instr") or any(c.name != UNUSED for c in self.cache_effects) self.input_effects = [ effect for effect in inst.inputs if isinstance(effect, StackEffect) ] @@ -124,6 +120,8 @@ def is_viable_uop(self) -> bool: if self.name == "_EXIT_TRACE": return True # This has 'return frame' but it's okay + if self.name == "_SAVE_RETURN_OFFSET": + return True # Adjusts next_instr, but only in tier 1 code if self.always_exits: dprint(f"Skipping {self.name} because it always exits: {self.always_exits}") return False @@ -144,7 +142,8 @@ def write_body( out: Formatter, dedent: int, active_caches: list[ActiveCacheEffect], - tier: Tiers = TIER_ONE, + tier: Tiers, + family: parsing.Family | None, ) -> None: """Write the instruction body.""" # Write cache effect variable declarations and initializations @@ -163,10 +162,11 @@ def write_body( func = f"read_u{bits}" if tier == TIER_ONE: out.emit( - f"{typ}{ceffect.name} = {func}(&next_instr[{active.offset}].cache);" + f"{typ}{ceffect.name} = " + f"{func}(&this_instr[{active.offset + 1}].cache);" ) else: - out.emit(f"{typ}{ceffect.name} = ({typ.strip()})operand;") + out.emit(f"{typ}{ceffect.name} = ({typ.strip()})CURRENT_OPERAND();") # Write the body, substituting a goto for ERROR_IF() and other stuff assert dedent <= 0 @@ -201,12 +201,24 @@ def write_body( ninputs, symbolic = list_effect_size(ieffs) if ninputs: label = f"pop_{ninputs}_{label}" + if tier == TIER_TWO: + label = label + "_tier_two" 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) @@ -244,7 +256,8 @@ def write_body( out: Formatter, dedent: int, active_caches: list[ActiveCacheEffect], - tier: Tiers = TIER_ONE, + tier: Tiers, + family: parsing.Family | None, ) -> None: pass @@ -268,7 +281,9 @@ class MacroInstruction: macro: parsing.Macro parts: MacroParts cache_offset: int + # Set later predicted: bool = False + family: parsing.Family | None = None @dataclasses.dataclass @@ -276,16 +291,10 @@ class PseudoInstruction: """A pseudo instruction.""" name: str - targets: list[Instruction] - instr_fmt: str + targets: list[Instruction | MacroInstruction] instr_flags: InstructionFlags -@dataclasses.dataclass -class OverriddenInstructionPlaceHolder: - name: str - - AnyInstruction = Instruction | MacroInstruction | PseudoInstruction diff --git a/Tools/cases_generator/lexer.py b/Tools/cases_generator/lexer.py index a60f6c11a4c460..c3c2954a42083f 100644 --- a/Tools/cases_generator/lexer.py +++ b/Tools/cases_generator/lexer.py @@ -80,11 +80,12 @@ def choice(*opts: str) -> str: # Macros macro = r"# *(ifdef|ifndef|undef|define|error|endif|if|else|include|#)" -MACRO = "MACRO" +CMACRO = "CMACRO" 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]+" @@ -111,7 +112,7 @@ def choice(*opts: str) -> str: char = r"\'.\'" # TODO: escape sequence CHARACTER = "CHARACTER" -comment_re = r"//.*|/\*([^*]|\*[^/])*\*/" +comment_re = r"(//.*)|/\*([^*]|\*[^/])*\*/" COMMENT = "COMMENT" newline = r"\n" @@ -173,10 +174,6 @@ def choice(*opts: str) -> str: 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" @@ -207,8 +204,20 @@ def choice(*opts: str) -> str: kwds.append(VOLATILE) WHILE = "WHILE" kwds.append(WHILE) +# An instruction in the DSL +INST = "INST" +kwds.append(INST) +# A micro-op in the DSL +OP = "OP" +kwds.append(OP) +# A macro in the DSL +MACRO = "MACRO" +kwds.append(MACRO) keywords = {name.lower(): name for name in kwds} +ANNOTATION = "ANNOTATION" +annotations = {"specializing", "guard", "override", "register", "replaced"} + __all__ = [] __all__.extend(kwds) @@ -225,6 +234,7 @@ def make_syntax_error( @dataclass(slots=True) class Token: + filename: str kind: str text: str begin: tuple[int, int] @@ -252,7 +262,7 @@ def width(self) -> int: def replaceText(self, txt: str) -> "Token": assert isinstance(txt, str) - return Token(self.kind, txt, self.begin, self.end) + return Token(self.filename, self.kind, txt, self.begin, self.end) def __repr__(self) -> str: b0, b1 = self.begin @@ -263,13 +273,15 @@ def __repr__(self) -> str: return f"{self.kind}({self.text!r}, {b0}:{b1}, {e0}:{e1})" -def tokenize(src: str, line: int = 1, filename: str | None = None) -> Iterator[Token]: +def tokenize(src: str, line: int = 1, filename: str = "") -> Iterator[Token]: linestart = -1 for m in matcher.finditer(src): start, end = m.span() text = m.group(0) if text in keywords: kind = keywords[text] + elif text in annotations: + kind = ANNOTATION elif letter.match(text): kind = IDENTIFIER elif text == "...": @@ -289,7 +301,7 @@ def tokenize(src: str, line: int = 1, filename: str | None = None) -> Iterator[T elif text[0] == "'": kind = CHARACTER elif text[0] == "#": - kind = MACRO + kind = CMACRO elif text[0] == "/" and text[1] in "/*": kind = COMMENT else: @@ -312,7 +324,7 @@ def tokenize(src: str, line: int = 1, filename: str | None = None) -> Iterator[T else: begin = line, start - linestart if kind != "\n": - yield Token(kind, text, begin, (line, start - linestart + len(text))) + yield Token(filename, kind, text, begin, (line, start - linestart + len(text))) def to_text(tkns: list[Token], dedent: int = 0) -> str: diff --git a/Tools/cases_generator/mypy.ini b/Tools/cases_generator/mypy.ini index e7175e263350b2..8e5a31851c596e 100644 --- a/Tools/cases_generator/mypy.ini +++ b/Tools/cases_generator/mypy.ini @@ -11,3 +11,5 @@ strict = True strict_concatenate = True enable_error_code = ignore-without-code,redundant-expr,truthy-bool,possibly-undefined warn_unreachable = True +allow_redefinition = True +implicit_reexport = True diff --git a/Tools/cases_generator/opcode_id_generator.py b/Tools/cases_generator/opcode_id_generator.py new file mode 100644 index 00000000000000..ddbb409bbced39 --- /dev/null +++ b/Tools/cases_generator/opcode_id_generator.py @@ -0,0 +1,153 @@ +"""Generate the list of opcode IDs. +Reads the instruction definitions from bytecodes.c. +Writes the IDs to opcode._ids.h by default. +""" + +import argparse +import os.path +import sys + +from analyzer import ( + Analysis, + Instruction, + analyze_files, +) +from generators_common import ( + DEFAULT_INPUT, + ROOT, + write_header, +) +from cwriter import CWriter +from typing import TextIO + + +DEFAULT_OUTPUT = ROOT / "Include/opcode_ids.h" + + +def generate_opcode_header(filenames: list[str], analysis: Analysis, outfile: TextIO) -> None: + write_header(__file__, filenames, outfile) + out = CWriter(outfile, 0, False) + out.emit("\n") + instmap: dict[str, int] = {} + + # 0 is reserved for cache entries. This helps debugging. + instmap["CACHE"] = 0 + + # 17 is reserved as it is the initial value for the specializing counter. + # This helps catch cases where we attempt to execute a cache. + instmap["RESERVED"] = 17 + + # 149 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py + instmap["RESUME"] = 149 + instmap["INSTRUMENTED_LINE"] = 254 + + instrumented = [ + name for name in analysis.instructions if name.startswith("INSTRUMENTED") + ] + + # 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.append("INSTRUMENTED_LINE") + + specialized: set[str] = set() + no_arg: list[str] = [] + has_arg: list[str] = [] + + for family in analysis.families.values(): + specialized.update(inst.name for inst in family.members) + + for inst in analysis.instructions.values(): + name = inst.name + if name in specialized: + continue + if name in instrumented: + continue + if inst.properties.oparg: + has_arg.append(name) + else: + no_arg.append(name) + + # 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) - 1) + assert min_internal + len(specialized) < min_instrumented + + next_opcode = 1 + + def add_instruction(name: str) -> None: + nonlocal next_opcode + if name in instmap: + return # Pre-defined name + while next_opcode in instmap.values(): + next_opcode += 1 + instmap[name] = next_opcode + next_opcode += 1 + + for name in sorted(no_arg): + add_instruction(name) + for name in sorted(has_arg): + add_instruction(name) + # For compatibility + next_opcode = min_internal + for name in sorted(specialized): + add_instruction(name) + next_opcode = min_instrumented + for name in instrumented: + add_instruction(name) + + for op, name in enumerate(sorted(analysis.pseudos), 256): + instmap[name] = op + + assert 255 not in instmap.values() + + out.emit( + """#ifndef Py_OPCODE_IDS_H +#define Py_OPCODE_IDS_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Instruction opcodes for compiled code */ +""" + ) + + def write_define(name: str, op: int) -> None: + out.emit(f"#define {name:<38} {op:>3}\n") + + for op, name in sorted([(op, name) for (name, op) in instmap.items()]): + write_define(name, op) + + out.emit("\n") + write_define("HAVE_ARGUMENT", len(no_arg)) + write_define("MIN_INSTRUMENTED_OPCODE", min_instrumented) + + out.emit("\n") + out.emit("#ifdef __cplusplus\n") + out.emit("}\n") + out.emit("#endif\n") + out.emit("#endif /* !Py_OPCODE_IDS_H */\n") + + +arg_parser = argparse.ArgumentParser( + description="Generate the header file with all opcode IDs.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) + +arg_parser.add_argument( + "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT +) + +arg_parser.add_argument( + "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" +) + +if __name__ == "__main__": + args = arg_parser.parse_args() + if len(args.input) == 0: + args.input.append(DEFAULT_INPUT) + data = analyze_files(args.input) + with open(args.output, "w") as outfile: + generate_opcode_header(args.input, data, outfile) diff --git a/Tools/cases_generator/parser.py b/Tools/cases_generator/parser.py new file mode 100644 index 00000000000000..12173a61199700 --- /dev/null +++ b/Tools/cases_generator/parser.py @@ -0,0 +1,55 @@ +from parsing import ( + InstDef, + Macro, + Pseudo, + Family, + Parser, + Context, + CacheEffect, + StackEffect, + OpName, + AstNode, +) +from formatting import prettify_filename + + +BEGIN_MARKER = "// BEGIN BYTECODES //" +END_MARKER = "// END BYTECODES //" + + +def parse_files(filenames: list[str]) -> list[AstNode]: + result: list[AstNode] = [] + for filename in filenames: + with open(filename) as file: + src = file.read() + + psr = 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_first_token = psr.peek() + while node := psr.definition(): + assert node is not None + result.append(node) # type: ignore[arg-type] + if not psr.eof(): + psr.backup() + raise psr.make_syntax_error( + f"Extra stuff at the end of {filename}", psr.next(True) + ) + return result diff --git a/Tools/cases_generator/parsing.py b/Tools/cases_generator/parsing.py index 25be5ca3e0da5d..60c185dcef58e9 100644 --- a/Tools/cases_generator/parsing.py +++ b/Tools/cases_generator/parsing.py @@ -105,8 +105,7 @@ class OpName(Node): @dataclass class InstHeader(Node): - override: bool - register: bool + annotations: list[str] kind: Literal["inst", "op"] name: str inputs: list[InputEffect] @@ -115,8 +114,7 @@ class InstHeader(Node): @dataclass class InstDef(Node): - override: bool - register: bool + annotations: list[str] kind: Literal["inst", "op"] name: str inputs: list[InputEffect] @@ -140,20 +138,22 @@ class Family(Node): @dataclass class Pseudo(Node): name: str - targets: list[str] # opcodes this can be replaced by + flags: list[str] # instr flags to set on the pseudo instruction + targets: list[str] # opcodes this can be replaced by +AstNode = InstDef | Macro | Pseudo | Family class Parser(PLexer): @contextual - def definition(self) -> InstDef | Macro | Pseudo | Family | None: - if inst := self.inst_def(): - return inst + def definition(self) -> AstNode | None: if macro := self.macro_def(): return macro if family := self.family_def(): return family if pseudo := self.pseudo_def(): return pseudo + if inst := self.inst_def(): + return inst return None @contextual @@ -161,8 +161,7 @@ def inst_def(self) -> InstDef | None: if hdr := self.inst_header(): if block := self.block(): return InstDef( - hdr.override, - hdr.register, + hdr.annotations, hdr.kind, hdr.name, hdr.inputs, @@ -174,13 +173,15 @@ def inst_def(self) -> InstDef | None: @contextual def inst_header(self) -> InstHeader | None: - # [override] inst(NAME) - # | [override] [register] inst(NAME, (inputs -- outputs)) - # | [override] [register] op(NAME, (inputs -- outputs)) - # 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 tkn.text in ("inst", "op"): + # annotation* inst(NAME, (inputs -- outputs)) + # | annotation* op(NAME, (inputs -- outputs)) + annotations = [] + while anno := self.expect(lx.ANNOTATION): + annotations.append(anno.text) + tkn = self.expect(lx.INST) + if not tkn: + tkn = self.expect(lx.OP) + if tkn: kind = cast(Literal["inst", "op"], tkn.text) if self.expect(lx.LPAREN) and (tkn := self.expect(lx.IDENTIFIER)): name = tkn.text @@ -188,7 +189,7 @@ def inst_header(self) -> InstHeader | None: inp, outp = self.io_effect() if self.expect(lx.RPAREN): if (tkn := self.peek()) and tkn.kind == lx.LBRACE: - return InstHeader(override, register, kind, name, inp, outp) + return InstHeader(annotations, kind, name, inp, outp) return None def io_effect(self) -> tuple[list[InputEffect], list[OutputEffect]]: @@ -312,7 +313,7 @@ def op(self) -> OpName | None: @contextual def macro_def(self) -> Macro | None: - if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "macro": + if tkn := self.expect(lx.MACRO): if self.expect(lx.LPAREN): if tkn := self.expect(lx.IDENTIFIER): if self.expect(lx.RPAREN): @@ -375,19 +376,39 @@ def family_def(self) -> Family | None: ) return None + def flags(self) -> list[str]: + here = self.getpos() + if self.expect(lx.LPAREN): + if tkn := self.expect(lx.IDENTIFIER): + flags = [tkn.text] + while self.expect(lx.COMMA): + if tkn := self.expect(lx.IDENTIFIER): + flags.append(tkn.text) + else: + break + if not self.expect(lx.RPAREN): + raise self.make_syntax_error("Expected comma or right paren") + return flags + self.setpos(here) + return [] + @contextual def pseudo_def(self) -> Pseudo | None: if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "pseudo": size = None if self.expect(lx.LPAREN): if tkn := self.expect(lx.IDENTIFIER): + if self.expect(lx.COMMA): + flags = self.flags() + else: + flags = [] if self.expect(lx.RPAREN): if self.expect(lx.EQUALS): if not self.expect(lx.LBRACE): 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, flags, members) return None def members(self) -> list[str] | None: diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py new file mode 100644 index 00000000000000..c36a56ebf2d381 --- /dev/null +++ b/Tools/cases_generator/stack.py @@ -0,0 +1,168 @@ +import sys +from analyzer import StackItem +from dataclasses import dataclass +from formatting import maybe_parenthesize +from cwriter import CWriter + + +def var_size(var: StackItem) -> str: + if var.condition: + # Special case simplification + if var.condition == "oparg & 1" and var.size == "1": + return f"({var.condition})" + else: + return f"(({var.condition}) ? {var.size} : 0)" + else: + return var.size + + +class StackOffset: + "The stack offset of the virtual base of the stack from the physical stack pointer" + + def __init__(self) -> None: + self.popped: list[str] = [] + self.pushed: list[str] = [] + + def pop(self, item: StackItem) -> None: + self.popped.append(var_size(item)) + + def push(self, item: StackItem) -> None: + self.pushed.append(var_size(item)) + + def simplify(self) -> None: + "Remove matching values from both the popped and pushed list" + if not self.popped or not self.pushed: + return + # Sort the list so the lexically largest element is last. + popped = sorted(self.popped) + pushed = sorted(self.pushed) + self.popped = [] + self.pushed = [] + while popped and pushed: + pop = popped.pop() + push = pushed.pop() + if pop == push: + pass + elif pop > push: + # if pop > push, there can be no element in pushed matching pop. + self.popped.append(pop) + pushed.append(push) + else: + self.pushed.append(push) + popped.append(pop) + self.popped.extend(popped) + self.pushed.extend(pushed) + + def to_c(self) -> str: + self.simplify() + int_offset = 0 + symbol_offset = "" + for item in self.popped: + try: + int_offset -= int(item) + except ValueError: + symbol_offset += f" - {maybe_parenthesize(item)}" + for item in self.pushed: + try: + int_offset += int(item) + except ValueError: + symbol_offset += f" + {maybe_parenthesize(item)}" + if symbol_offset and not int_offset: + res = symbol_offset + else: + res = f"{int_offset}{symbol_offset}" + if res.startswith(" + "): + res = res[3:] + if res.startswith(" - "): + res = "-" + res[3:] + return res + + def clear(self) -> None: + self.popped = [] + self.pushed = [] + + +class SizeMismatch(Exception): + pass + + +class Stack: + def __init__(self) -> None: + self.top_offset = StackOffset() + self.base_offset = StackOffset() + self.peek_offset = StackOffset() + self.variables: list[StackItem] = [] + self.defined: set[str] = set() + + def pop(self, var: StackItem) -> str: + self.top_offset.pop(var) + if not var.peek: + self.peek_offset.pop(var) + indirect = "&" if var.is_array() else "" + if self.variables: + popped = self.variables.pop() + if popped.size != var.size: + raise SizeMismatch( + f"Size mismatch when popping '{popped.name}' from stack to assign to {var.name}. " + f"Expected {var.size} got {popped.size}" + ) + if popped.name == var.name: + return "" + elif popped.name == "unused": + self.defined.add(var.name) + return ( + f"{var.name} = {indirect}stack_pointer[{self.top_offset.to_c()}];\n" + ) + elif var.name == "unused": + return "" + else: + self.defined.add(var.name) + return f"{var.name} = {popped.name};\n" + self.base_offset.pop(var) + if var.name == "unused": + return "" + else: + self.defined.add(var.name) + cast = f"({var.type})" if (not indirect and var.type) else "" + assign = ( + f"{var.name} = {cast}{indirect}stack_pointer[{self.base_offset.to_c()}];" + ) + if var.condition: + return f"if ({var.condition}) {{ {assign} }}\n" + return f"{assign}\n" + + def push(self, var: StackItem) -> str: + self.variables.append(var) + if var.is_array() and var.name not in self.defined and var.name != "unused": + c_offset = self.top_offset.to_c() + self.top_offset.push(var) + self.defined.add(var.name) + return f"{var.name} = &stack_pointer[{c_offset}];\n" + else: + self.top_offset.push(var) + return "" + + def flush(self, out: CWriter) -> None: + for var in self.variables: + if not var.peek: + cast = "(PyObject *)" if var.type else "" + if var.name != "unused" and not var.is_array(): + if var.condition: + out.emit(f" if ({var.condition}) ") + out.emit( + f"stack_pointer[{self.base_offset.to_c()}] = {cast}{var.name};\n" + ) + self.base_offset.push(var) + if self.base_offset.to_c() != self.top_offset.to_c(): + print("base", self.base_offset.to_c(), "top", self.top_offset.to_c()) + assert False + number = self.base_offset.to_c() + if number != "0": + out.emit(f"stack_pointer += {number};\n") + self.variables = [] + self.base_offset.clear() + self.top_offset.clear() + self.peek_offset.clear() + + def as_comment(self) -> str: + return f"/* Variables: {[v.name for v in self.variables]}. Base offset: {self.base_offset.to_c()}. Top offset: {self.top_offset.to_c()} */" diff --git a/Tools/cases_generator/stacking.py b/Tools/cases_generator/stacking.py index 1f9fda66a5f034..123e38c524f49d 100644 --- a/Tools/cases_generator/stacking.py +++ b/Tools/cases_generator/stacking.py @@ -351,14 +351,13 @@ def write_single_instr( 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, family: Family | None -) -> None: +def write_macro_instr(mac: MacroInstruction, out: Formatter) -> None: parts = [ part for part in mac.parts @@ -366,16 +365,25 @@ def write_macro_instr( ] out.emit("") with out.block(f"TARGET({mac.name})"): + needs_this = any(part.instr.needs_this_instr for part in parts) + if needs_this and not mac.predicted: + out.emit(f"_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;") + else: + out.emit(f"frame->instr_ptr = next_instr;") + out.emit(f"next_instr += {mac.cache_offset+1};") + out.emit(f"INSTRUCTION_STATS({mac.name});") if mac.predicted: out.emit(f"PREDICTED({mac.name});") - out.static_assert_family_size(mac.name, family, mac.cache_offset) + if needs_this: + out.emit(f"_Py_CODEUNIT *this_instr = next_instr - {mac.cache_offset+1};") + 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) + 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();") @@ -386,6 +394,7 @@ def write_components( out: Formatter, tier: Tiers, cache_offset: int, + family: Family | None, ) -> bool: managers = get_managers(parts) @@ -446,18 +455,16 @@ def write_components( ), f"Expected {mgr.instr.name!r} to be the last uop" assert_no_pokes(managers) - if mgr.instr.name == "_SAVE_CURRENT_IP": + if mgr.instr.name == "_SAVE_RETURN_OFFSET": 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) + 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) + 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 diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py new file mode 100644 index 00000000000000..11885dca6fe1a2 --- /dev/null +++ b/Tools/cases_generator/tier1_generator.py @@ -0,0 +1,190 @@ +"""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 os.path +import sys + +from analyzer import ( + Analysis, + Instruction, + Uop, + Part, + analyze_files, + Skip, + StackItem, + analysis_error, +) +from generators_common import ( + DEFAULT_INPUT, + ROOT, + write_header, + emit_tokens, +) +from cwriter import CWriter +from typing import TextIO, Iterator +from lexer import Token +from stack import StackOffset, Stack, SizeMismatch + + +DEFAULT_OUTPUT = ROOT / "Python/generated_cases.c.h" + + +FOOTER = "#undef TIER_ONE\n" + + +def declare_variables(inst: Instruction, out: CWriter) -> None: + variables = {"unused"} + for uop in inst.parts: + if isinstance(uop, Uop): + for var in reversed(uop.stack.inputs): + if var.name not in variables: + type = var.type if var.type else "PyObject *" + variables.add(var.name) + if var.condition: + out.emit(f"{type}{var.name} = NULL;\n") + else: + out.emit(f"{type}{var.name};\n") + for var in uop.stack.outputs: + if var.name not in variables: + variables.add(var.name) + type = var.type if var.type else "PyObject *" + if var.condition: + out.emit(f"{type}{var.name} = NULL;\n") + else: + out.emit(f"{type}{var.name};\n") + + +def write_uop( + uop: Part, out: CWriter, offset: int, stack: Stack, inst: Instruction, braces: bool +) -> int: + # out.emit(stack.as_comment() + "\n") + if isinstance(uop, Skip): + entries = "entries" if uop.size > 1 else "entry" + out.emit(f"/* Skip {uop.size} cache {entries} */\n") + return offset + uop.size + try: + out.start_line() + if braces: + out.emit(f"// {uop.name}\n") + for var in reversed(uop.stack.inputs): + out.emit(stack.pop(var)) + if braces: + out.emit("{\n") + if not uop.properties.stores_sp: + for i, var in enumerate(uop.stack.outputs): + out.emit(stack.push(var)) + for cache in uop.caches: + if cache.name != "unused": + if cache.size == 4: + type = "PyObject *" + reader = "read_obj" + else: + type = f"uint{cache.size*16}_t " + reader = f"read_u{cache.size*16}" + out.emit( + f"{type}{cache.name} = {reader}(&this_instr[{offset}].cache);\n" + ) + offset += cache.size + emit_tokens(out, uop, stack, inst) + if uop.properties.stores_sp: + for i, var in enumerate(uop.stack.outputs): + out.emit(stack.push(var)) + if braces: + out.start_line() + out.emit("}\n") + # out.emit(stack.as_comment() + "\n") + return offset + except SizeMismatch as ex: + raise analysis_error(ex.args[0], uop.body[0]) + + +def uses_this(inst: Instruction) -> bool: + if inst.properties.needs_this: + return True + for uop in inst.parts: + if isinstance(uop, Skip): + continue + for cache in uop.caches: + if cache.name != "unused": + return True + return False + + +def generate_tier1( + filenames: list[str], analysis: Analysis, outfile: TextIO, lines: bool +) -> None: + write_header(__file__, filenames, outfile) + outfile.write( + """ +#ifdef TIER_TWO + #error "This file is for Tier 1 only" +#endif +#define TIER_ONE 1 +""" + ) + out = CWriter(outfile, 2, lines) + out.emit("\n") + for name, inst in sorted(analysis.instructions.items()): + needs_this = uses_this(inst) + out.emit("\n") + out.emit(f"TARGET({name}) {{\n") + if needs_this and not inst.is_target: + out.emit(f"_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;\n") + else: + out.emit(f"frame->instr_ptr = next_instr;\n") + out.emit(f"next_instr += {inst.size};\n") + out.emit(f"INSTRUCTION_STATS({name});\n") + if inst.is_target: + out.emit(f"PREDICTED({name});\n") + if needs_this: + out.emit(f"_Py_CODEUNIT *this_instr = next_instr - {inst.size};\n") + if inst.family is not None: + out.emit( + f"static_assert({inst.family.size} == {inst.size-1}" + ', "incorrect cache size");\n' + ) + declare_variables(inst, out) + offset = 1 # The instruction itself + stack = Stack() + for part in inst.parts: + # Only emit braces if more than one uop + offset = write_uop(part, out, offset, stack, inst, len(inst.parts) > 1) + out.start_line() + if not inst.parts[-1].properties.always_exits: + stack.flush(out) + if inst.parts[-1].properties.ends_with_eval_breaker: + out.emit("CHECK_EVAL_BREAKER();\n") + out.emit("DISPATCH();\n") + out.start_line() + out.emit("}") + out.emit("\n") + outfile.write(FOOTER) + + +arg_parser = argparse.ArgumentParser( + description="Generate the code for the interpreter switch.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) + +arg_parser.add_argument( + "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT +) + +arg_parser.add_argument( + "-l", "--emit-line-directives", help="Emit #line directives", action="store_true" +) + +arg_parser.add_argument( + "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" +) + +if __name__ == "__main__": + args = arg_parser.parse_args() + if len(args.input) == 0: + args.input.append(DEFAULT_INPUT) + data = analyze_files(args.input) + with open(args.output, "w") as outfile: + generate_tier1(args.input, data, outfile, args.emit_line_directives) diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py new file mode 100644 index 00000000000000..a22fb6dd932503 --- /dev/null +++ b/Tools/cases_generator/tier2_generator.py @@ -0,0 +1,203 @@ +"""Generate the cases for the tier 2 interpreter. +Reads the instruction definitions from bytecodes.c. +Writes the cases to executor_cases.c.h, which is #included in ceval.c. +""" + +import argparse +import os.path +import sys + +from analyzer import ( + Analysis, + Instruction, + Uop, + Part, + analyze_files, + Skip, + StackItem, + analysis_error, +) +from generators_common import ( + DEFAULT_INPUT, + ROOT, + write_header, + emit_tokens, + emit_to, + REPLACEMENT_FUNCTIONS, +) +from cwriter import CWriter +from typing import TextIO, Iterator +from lexer import Token +from stack import StackOffset, Stack, SizeMismatch + +DEFAULT_OUTPUT = ROOT / "Python/executor_cases.c.h" + + +def declare_variables(uop: Uop, out: CWriter) -> None: + variables = {"unused"} + for var in reversed(uop.stack.inputs): + if var.name not in variables: + type = var.type if var.type else "PyObject *" + variables.add(var.name) + if var.condition: + out.emit(f"{type}{var.name} = NULL;\n") + else: + out.emit(f"{type}{var.name};\n") + for var in uop.stack.outputs: + if var.name not in variables: + variables.add(var.name) + type = var.type if var.type else "PyObject *" + if var.condition: + out.emit(f"{type}{var.name} = NULL;\n") + else: + out.emit(f"{type}{var.name};\n") + + +def tier2_replace_error( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + stack: Stack, + inst: Instruction | None, +) -> None: + out.emit_at("if ", tkn) + out.emit(next(tkn_iter)) + emit_to(out, tkn_iter, "COMMA") + label = next(tkn_iter).text + next(tkn_iter) # RPAREN + next(tkn_iter) # Semi colon + out.emit(") ") + c_offset = stack.peek_offset.to_c() + try: + offset = -int(c_offset) + close = ";\n" + except ValueError: + offset = None + out.emit(f"{{ stack_pointer += {c_offset}; ") + close = "; }\n" + out.emit("goto ") + if offset: + out.emit(f"pop_{offset}_") + out.emit(label + "_tier_two") + out.emit(close) + + +def tier2_replace_deopt( + out: CWriter, + tkn: Token, + tkn_iter: Iterator[Token], + uop: Uop, + unused: Stack, + inst: Instruction | None, +) -> None: + out.emit_at("if ", tkn) + out.emit(next(tkn_iter)) + emit_to(out, tkn_iter, "RPAREN") + next(tkn_iter) # Semi colon + out.emit(") goto deoptimize;\n") + + +TIER2_REPLACEMENT_FUNCTIONS = REPLACEMENT_FUNCTIONS.copy() +TIER2_REPLACEMENT_FUNCTIONS["ERROR_IF"] = tier2_replace_error +TIER2_REPLACEMENT_FUNCTIONS["DEOPT_IF"] = tier2_replace_deopt + + +def is_super(uop: Uop) -> bool: + for tkn in uop.body: + if tkn.kind == "IDENTIFIER" and tkn.text == "oparg1": + return True + return False + + +def write_uop(uop: Uop, out: CWriter, stack: Stack) -> None: + try: + out.start_line() + if uop.properties.oparg: + out.emit("oparg = CURRENT_OPARG();\n") + for var in reversed(uop.stack.inputs): + out.emit(stack.pop(var)) + if not uop.properties.stores_sp: + for i, var in enumerate(uop.stack.outputs): + out.emit(stack.push(var)) + for cache in uop.caches: + if cache.name != "unused": + if cache.size == 4: + type = cast ="PyObject *" + else: + type = f"uint{cache.size*16}_t " + cast = f"uint{cache.size*16}_t" + out.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n") + emit_tokens(out, uop, stack, None, TIER2_REPLACEMENT_FUNCTIONS) + if uop.properties.stores_sp: + for i, var in enumerate(uop.stack.outputs): + out.emit(stack.push(var)) + except SizeMismatch as ex: + raise analysis_error(ex.args[0], uop.body[0]) + + +SKIPS = ("_EXTENDED_ARG",) + + +def generate_tier2( + filenames: list[str], analysis: Analysis, outfile: TextIO, lines: bool +) -> None: + write_header(__file__, filenames, outfile) + outfile.write( + """ +#ifdef TIER_ONE + #error "This file is for Tier 2 only" +#endif +#define TIER_TWO 2 +""" + ) + out = CWriter(outfile, 2, lines) + out.emit("\n") + for name, uop in analysis.uops.items(): + if uop.properties.tier_one_only: + continue + if is_super(uop): + continue + if not uop.is_viable(): + out.emit(f"/* {uop.name} is not a viable micro-op for tier 2 */\n\n") + continue + out.emit(f"case {uop.name}: {{\n") + declare_variables(uop, out) + stack = Stack() + write_uop(uop, out, stack) + out.start_line() + if not uop.properties.always_exits: + stack.flush(out) + if uop.properties.ends_with_eval_breaker: + out.emit("CHECK_EVAL_BREAKER();\n") + out.emit("break;\n") + out.start_line() + out.emit("}") + out.emit("\n\n") + outfile.write("#undef TIER_TWO\n") + + +arg_parser = argparse.ArgumentParser( + description="Generate the code for the tier 2 interpreter.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) + +arg_parser.add_argument( + "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT +) + +arg_parser.add_argument( + "-l", "--emit-line-directives", help="Emit #line directives", action="store_true" +) + +arg_parser.add_argument( + "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" +) + +if __name__ == "__main__": + args = arg_parser.parse_args() + if len(args.input) == 0: + args.input.append(DEFAULT_INPUT) + data = analyze_files(args.input) + with open(args.output, "w") as outfile: + generate_tier2(args.input, data, outfile, args.emit_line_directives) diff --git a/Tools/cases_generator/uop_id_generator.py b/Tools/cases_generator/uop_id_generator.py new file mode 100644 index 00000000000000..277da25835f6fb --- /dev/null +++ b/Tools/cases_generator/uop_id_generator.py @@ -0,0 +1,98 @@ +"""Generate the list of uop IDs. +Reads the instruction definitions from bytecodes.c. +Writes the IDs to pycore_uop_ids.h by default. +""" + +import argparse +import os.path +import sys + +from analyzer import ( + Analysis, + Instruction, + analyze_files, +) +from generators_common import ( + DEFAULT_INPUT, + ROOT, + write_header, +) +from cwriter import CWriter +from typing import TextIO + + +DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_ids.h" + + +OMIT = {"_CACHE", "_RESERVED", "_EXTENDED_ARG"} + + +def generate_uop_ids( + filenames: list[str], analysis: Analysis, outfile: TextIO, distinct_namespace: bool +) -> None: + write_header(__file__, filenames, outfile) + out = CWriter(outfile, 0, False) + out.emit( + """#ifndef Py_CORE_UOP_IDS_H +#define Py_CORE_UOP_IDS_H +#ifdef __cplusplus +extern "C" { +#endif + +""" + ) + + next_id = 1 if distinct_namespace else 300 + # These two are first by convention + out.emit(f"#define _EXIT_TRACE {next_id}\n") + next_id += 1 + out.emit(f"#define _SET_IP {next_id}\n") + next_id += 1 + PRE_DEFINED = {"_EXIT_TRACE", "_SET_IP"} + + for uop in analysis.uops.values(): + if uop.name in PRE_DEFINED: + continue + # TODO: We should omit all tier-1 only uops, but + # generate_cases.py still generates code for those. + if uop.name in OMIT: + continue + if uop.implicitly_created and not distinct_namespace: + out.emit(f"#define {uop.name} {uop.name[1:]}\n") + else: + out.emit(f"#define {uop.name} {next_id}\n") + next_id += 1 + + out.emit("\n") + out.emit("#ifdef __cplusplus\n") + out.emit("}\n") + out.emit("#endif\n") + out.emit("#endif /* !Py_OPCODE_IDS_H */\n") + + +arg_parser = argparse.ArgumentParser( + description="Generate the header file with all uop IDs.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) + +arg_parser.add_argument( + "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT +) +arg_parser.add_argument( + "-n", + "--namespace", + help="Give uops a distinct namespace", + action="store_true", +) + +arg_parser.add_argument( + "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" +) + +if __name__ == "__main__": + args = arg_parser.parse_args() + if len(args.input) == 0: + args.input.append(DEFAULT_INPUT) + data = analyze_files(args.input) + with open(args.output, "w") as outfile: + generate_uop_ids(args.input, data, outfile, args.namespace) 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 eca4747a3e4d57..5ec088765f3e01 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -406,7 +406,7 @@ def flush() -> None: flush() return tuple(version) -def version_comparitor(version1: str, version2: str) -> Literal[-1, 0, 1]: +def version_comparator(version1: str, version2: str) -> Literal[-1, 0, 1]: iterator = itertools.zip_longest( version_splitter(version1), version_splitter(version2), fillvalue=0 ) @@ -470,6 +470,10 @@ def __init__(self) -> None: # The C statements required to clean up after the impl call. self.cleanup: list[str] = [] + # The C statements to generate critical sections (per-object locking). + self.lock: list[str] = [] + self.unlock: list[str] = [] + class FormatCounterFormatter(string.Formatter): """ @@ -842,6 +846,14 @@ class CLanguage(Language): static PyObject * {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) """) + PARSER_PROTOTYPE_GETTER: Final[str] = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, void *Py_UNUSED(context)) + """) + PARSER_PROTOTYPE_SETTER: Final[str] = normalize_snippet(""" + static int + {c_basename}({self_type}{self_name}, PyObject *value, void *Py_UNUSED(context)) + """) METH_O_PROTOTYPE: Final[str] = normalize_snippet(""" static PyObject * {c_basename}({impl_parameters}) @@ -861,6 +873,22 @@ class CLanguage(Language): #define {methoddef_name} \ {{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}}, """) + GETTERDEF_PROTOTYPE_DEFINE: Final[str] = normalize_snippet(r""" + #if defined({getset_name}_GETSETDEF) + # undef {getset_name}_GETSETDEF + # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_basename}_get, (setter){getset_basename}_set, NULL}}, + #else + # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_basename}_get, NULL, NULL}}, + #endif + """) + SETTERDEF_PROTOTYPE_DEFINE: Final[str] = normalize_snippet(r""" + #if defined({getset_name}_GETSETDEF) + # undef {getset_name}_GETSETDEF + # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_basename}_get, (setter){getset_basename}_set, NULL}}, + #else + # define {getset_name}_GETSETDEF {{"{name}", NULL, (setter){getset_basename}_set, NULL}}, + #endif + """) METHODDEF_PROTOTYPE_IFNDEF: Final[str] = normalize_snippet(""" #ifndef {methoddef_name} #define {methoddef_name} @@ -924,7 +952,6 @@ def compiler_deprecated_warning( # Format the preprocessor warning and error messages. assert isinstance(self.cpp.filename, str) - source = os.path.basename(self.cpp.filename) message = f"Update the clinic input of {func.full_name!r}." code = self.COMPILER_DEPRECATION_WARNING_PROTOTYPE.format( major=minversion[0], @@ -1108,9 +1135,11 @@ def output_templates( if include: clinic.add_include(include.filename, include.reason, condition=include.condition) - + if f.critical_section: + clinic.add_include('pycore_critical_section.h', 'Py_BEGIN_CRITICAL_SECTION()') has_option_groups = parameters and (parameters[0].group or parameters[-1].group) - default_return_converter = f.return_converter.type == 'PyObject *' + simple_return = (f.return_converter.type == 'PyObject *' + and not f.critical_section) new_or_init = f.kind.new_or_init vararg: int | str = NO_VARARG @@ -1156,6 +1185,13 @@ def output_templates( methoddef_define = self.METHODDEF_PROTOTYPE_DEFINE if new_or_init and not f.docstring: docstring_prototype = docstring_definition = '' + elif f.kind is GETTER: + methoddef_define = self.GETTERDEF_PROTOTYPE_DEFINE + docstring_prototype = docstring_definition = '' + elif f.kind is SETTER: + return_value_declaration = "int {return_value};" + methoddef_define = self.SETTERDEF_PROTOTYPE_DEFINE + docstring_prototype = docstring_prototype = docstring_definition = '' else: docstring_prototype = self.DOCSTRING_PROTOTYPE_VAR docstring_definition = self.DOCSTRING_PROTOTYPE_STRVAR @@ -1184,7 +1220,9 @@ def parser_body( """) + "\n" finale = normalize_snippet(""" {modifications} + {lock} {return_value} = {c_basename}_impl({impl_arguments}); + {unlock} {return_conversion} {post_parsing} @@ -1200,7 +1238,7 @@ def parser_body( fastcall = not new_or_init limited_capi = clinic.limited_capi - if limited_capi and (requires_defining_class or pseudo_args or + if limited_capi and (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)): @@ -1208,9 +1246,20 @@ def parser_body( limited_capi = False parsearg: str | None + if f.kind in {GETTER, SETTER} and parameters: + fail(f"@{f.kind.name.lower()} method cannot define parameters") + if not parameters: parser_code: list[str] | None - if not requires_defining_class: + if f.kind is GETTER: + flags = "" # This should end up unused + parser_prototype = self.PARSER_PROTOTYPE_GETTER + parser_code = [] + elif f.kind is SETTER: + flags = "" + parser_prototype = self.PARSER_PROTOTYPE_SETTER + parser_code = [] + elif not requires_defining_class: # no parameters, METH_NOARGS flags = "METH_NOARGS" parser_prototype = self.PARSER_PROTOTYPE_NOARGS @@ -1220,7 +1269,7 @@ def parser_body( flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS" parser_prototype = self.PARSER_PROTOTYPE_DEF_CLASS - return_error = ('return NULL;' if default_return_converter + return_error = ('return NULL;' if simple_return else 'goto exit;') parser_code = [normalize_snippet(""" if (nargs) {{ @@ -1229,7 +1278,7 @@ def parser_body( }} """ % return_error, indent=4)] - if default_return_converter: + if simple_return: parser_definition = '\n'.join([ parser_prototype, '{{', @@ -1246,7 +1295,7 @@ def parser_body( converters[0].format_unit == 'O'): meth_o_prototype = self.METH_O_PROTOTYPE - if default_return_converter: + if simple_return: # maps perfectly to METH_O, doesn't need a return converter. # so we skip making a parse function # and call directly into the impl function. @@ -1345,6 +1394,8 @@ def parser_body( """, indent=4)) else: + clinic.add_include('pycore_modsupport.h', + '_PyArg_CheckPositional()') parser_code = [normalize_snippet(f""" if (!_PyArg_CheckPositional("{{name}}", {nargs}, {min_pos}, {max_args})) {{{{ goto exit; @@ -1402,6 +1453,8 @@ def parser_body( if limited_capi: fastcall = False if fastcall: + clinic.add_include('pycore_modsupport.h', + '_PyArg_ParseStack()') parser_code = [normalize_snippet(""" if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}", {parse_arguments})) {{ @@ -1429,59 +1482,64 @@ def parser_body( 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" % ( - min_pos, - max_pos, - min_kw_only - ) - nargs = "nargs" - else: - args_declaration = "_PyArg_UnpackKeywordsWithVararg", "%s, %s, %s, %s" % ( - min_pos, - max_pos, - min_kw_only, - vararg - ) - nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" if limited_capi: parser_code = None fastcall = False - - elif fastcall: - flags = "METH_FASTCALL|METH_KEYWORDS" - parser_prototype = self.PARSER_PROTOTYPE_FASTCALL_KEYWORDS - argname_fmt = 'args[%d]' - 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) - parser_code = [normalize_snippet(""" - args = %s(args, nargs, NULL, kwnames, &_parser, %s, argsbuf); - if (!args) {{ - goto exit; - }} - """ % args_declaration, indent=4)] else: - # positional-or-keyword arguments - flags = "METH_VARARGS|METH_KEYWORDS" - parser_prototype = self.PARSER_PROTOTYPE_KEYWORD - argname_fmt = 'fastargs[%d]' - 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);" - if has_optional_kw: - declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (nargs, min_pos + min_kw_only) - parser_code = [normalize_snippet(""" - fastargs = %s(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, %s, argsbuf); - if (!fastargs) {{ - goto exit; - }} - """ % args_declaration, indent=4)] + if vararg == NO_VARARG: + clinic.add_include('pycore_modsupport.h', + '_PyArg_UnpackKeywords()') + args_declaration = "_PyArg_UnpackKeywords", "%s, %s, %s" % ( + min_pos, + max_pos, + min_kw_only + ) + nargs = "nargs" + else: + clinic.add_include('pycore_modsupport.h', + '_PyArg_UnpackKeywordsWithVararg()') + args_declaration = "_PyArg_UnpackKeywordsWithVararg", "%s, %s, %s, %s" % ( + min_pos, + max_pos, + min_kw_only, + vararg + ) + nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0" + + if fastcall: + flags = "METH_FASTCALL|METH_KEYWORDS" + parser_prototype = self.PARSER_PROTOTYPE_FASTCALL_KEYWORDS + argname_fmt = 'args[%d]' + 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) + parser_code = [normalize_snippet(""" + args = %s(args, nargs, NULL, kwnames, &_parser, %s, argsbuf); + if (!args) {{ + goto exit; + }} + """ % args_declaration, indent=4)] + else: + # positional-or-keyword arguments + flags = "METH_VARARGS|METH_KEYWORDS" + parser_prototype = self.PARSER_PROTOTYPE_KEYWORD + argname_fmt = 'fastargs[%d]' + 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);" + if has_optional_kw: + declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (nargs, min_pos + min_kw_only) + parser_code = [normalize_snippet(""" + fastargs = %s(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, %s, argsbuf); + if (!fastargs) {{ + goto exit; + }} + """ % args_declaration, indent=4)] if requires_defining_class: flags = 'METH_METHOD|' + flags @@ -1575,6 +1633,8 @@ def parser_body( declarations += "\nPy_ssize_t nargs = PyTuple_Size(args);" elif fastcall: + clinic.add_include('pycore_modsupport.h', + '_PyArg_ParseStackAndKeywords()') parser_code = [normalize_snippet(""" if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma} {parse_arguments})) {{ @@ -1582,6 +1642,8 @@ def parser_body( }} """, indent=4)] else: + clinic.add_include('pycore_modsupport.h', + '_PyArg_ParseTupleAndKeywordsFast()') parser_code = [normalize_snippet(""" if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, {parse_arguments})) {{ @@ -1627,12 +1689,16 @@ def parser_body( if not parses_keywords: declarations = '{base_type_ptr}' + clinic.add_include('pycore_modsupport.h', + '_PyArg_NoKeywords()') fields.insert(0, normalize_snippet(""" if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs)) {{ goto exit; }} """, indent=4)) if not parses_positional: + clinic.add_include('pycore_modsupport.h', + '_PyArg_NoPositional()') fields.insert(0, normalize_snippet(""" if ({self_type_check}!_PyArg_NoPositional("{name}", args)) {{ goto exit; @@ -1643,12 +1709,13 @@ def parser_body( declarations=declarations) + methoddef_cast_end = "" if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'): methoddef_cast = "(PyCFunction)" - methoddef_cast_end = "" + elif f.kind is GETTER: + methoddef_cast = "" # This should end up unused elif limited_capi: methoddef_cast = "(PyCFunction)(void(*)(void))" - methoddef_cast_end = "" else: methoddef_cast = "_PyCFunction_CAST(" methoddef_cast_end = ")" @@ -1843,10 +1910,23 @@ def render_function( selfless = parameters[1:] assert isinstance(f_self.converter, self_converter), "No self parameter in " + repr(f.full_name) + "!" + if f.critical_section: + match len(f.target_critical_section): + case 0: + lock = 'Py_BEGIN_CRITICAL_SECTION({self_name});' + unlock = 'Py_END_CRITICAL_SECTION();' + case 1: + lock = 'Py_BEGIN_CRITICAL_SECTION({target_critical_section});' + unlock = 'Py_END_CRITICAL_SECTION();' + case _: + lock = 'Py_BEGIN_CRITICAL_SECTION2({target_critical_section});' + unlock = 'Py_END_CRITICAL_SECTION2();' + data.lock.append(lock) + data.unlock.append(unlock) + 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 @@ -1891,17 +1971,33 @@ def render_function( full_name = f.full_name 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" + if f.kind in {GETTER, SETTER}: + template_dict['getset_name'] = f.c_basename.upper() + template_dict['getset_basename'] = f.c_basename + if f.kind is GETTER: + template_dict['c_basename'] = f.c_basename + "_get" + elif f.kind is SETTER: + template_dict['c_basename'] = f.c_basename + "_set" + # Implicitly add the setter value parameter. + data.impl_parameters.append("PyObject *value") + data.impl_arguments.append("value") + else: + template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF" + template_dict['c_basename'] = f.c_basename template_dict['docstring'] = self.docstring_for_c_string(f) template_dict['self_name'] = template_dict['self_type'] = template_dict['self_type_check'] = '' + template_dict['target_critical_section'] = ', '.join(f.target_critical_section) for converter in converters: converter.set_template_dict(template_dict) f.return_converter.render(f, data) - template_dict['impl_return_type'] = f.return_converter.type + if f.kind is SETTER: + # All setters return an int. + template_dict['impl_return_type'] = 'int' + else: + template_dict['impl_return_type'] = f.return_converter.type template_dict['declarations'] = format_escape("\n".join(data.declarations)) template_dict['initializers'] = "\n\n".join(data.initializers) @@ -1923,6 +2019,8 @@ def render_function( template_dict['post_parsing'] = format_escape("".join(data.post_parsing).rstrip()) template_dict['cleanup'] = format_escape("".join(data.cleanup)) template_dict['return_value'] = data.return_value + template_dict['lock'] = "\n".join(data.lock) + template_dict['unlock'] = "\n".join(data.unlock) # used by unpack tuple code generator unpack_min = first_optional @@ -1947,6 +2045,8 @@ def render_function( modifications=template_dict['modifications'], post_parsing=template_dict['post_parsing'], cleanup=template_dict['cleanup'], + lock=template_dict['lock'], + unlock=template_dict['unlock'], ) # Only generate the "exit:" label @@ -2425,7 +2525,7 @@ def dump(self) -> str: 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: @@ -2891,6 +2991,8 @@ class FunctionKind(enum.Enum): CLASS_METHOD = enum.auto() METHOD_INIT = enum.auto() METHOD_NEW = enum.auto() + GETTER = enum.auto() + SETTER = enum.auto() @functools.cached_property def new_or_init(self) -> bool: @@ -2906,6 +3008,8 @@ def __repr__(self) -> str: CLASS_METHOD: Final = FunctionKind.CLASS_METHOD METHOD_INIT: Final = FunctionKind.METHOD_INIT METHOD_NEW: Final = FunctionKind.METHOD_NEW +GETTER: Final = FunctionKind.GETTER +SETTER: Final = FunctionKind.SETTER ParamDict = dict[str, "Parameter"] ReturnConverterType = Callable[..., "CReturnConverter"] @@ -2940,6 +3044,8 @@ class Function: # functions with optional groups because we can't represent # those accurately with inspect.Signature in 3.4. docstring_only: bool = False + critical_section: bool = False + target_critical_section: list[str] = dc.field(default_factory=list) def __post_init__(self) -> None: self.parent = self.cls or self.module @@ -2990,7 +3096,8 @@ def methoddef_flags(self) -> str | None: case FunctionKind.STATIC_METHOD: flags.append('METH_STATIC') case _ as kind: - assert kind is FunctionKind.CALLABLE, f"unknown kind: {kind!r}" + acceptable_kinds = {FunctionKind.CALLABLE, FunctionKind.GETTER, FunctionKind.SETTER} + assert kind in acceptable_kinds, f"unknown kind: {kind!r}" if self.coexist: flags.append('METH_COEXIST') return '|'.join(flags) @@ -3109,9 +3216,7 @@ def closure(f: CConverterClassT) -> CConverterClassT: if not kwargs: added_f = f else: - # 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] + added_f = functools.partial(f, **kwargs) if format_unit: legacy_converters[format_unit] = added_f return f @@ -3119,7 +3224,7 @@ def closure(f: CConverterClassT) -> CConverterClassT: class CConverterAutoRegister(type): def __init__( - cls, name: str, bases: tuple[type, ...], classdict: dict[str, Any] + cls, name: str, bases: tuple[type[object], ...], classdict: dict[str, Any] ) -> None: converter_cls = cast(type["CConverter"], cls) add_c_converter(converter_cls) @@ -3152,7 +3257,7 @@ class CConverter(metaclass=CConverterAutoRegister): # If not None, default must be isinstance() of this type. # (You can also specify a tuple of types.) - default_type: bltns.type[Any] | tuple[bltns.type[Any], ...] | None = None + default_type: bltns.type[object] | tuple[bltns.type[object], ...] | None = None # "default" converted into a C value, as a string. # Or None if there is no default. @@ -3503,6 +3608,8 @@ def bad_argument(self, displayname: str, expected: str, *, limited_capi: bool, e else: if expected_literal: expected = f'"{expected}"' + if clinic is not None: + clinic.add_include('pycore_modsupport.h', '_PyArg_BadArgument()') return f'_PyArg_BadArgument("{{{{name}}}}", "{displayname}", {expected}, {{argname}});' def format_code(self, fmt: str, *, @@ -3616,7 +3723,7 @@ def add_include(self, name: str, reason: str, ReturnConverterDict = dict[str, ReturnConverterType] return_converters: ReturnConverterDict = {} -TypeSet = set[bltns.type[Any]] +TypeSet = set[bltns.type[object]] class bool_converter(CConverter): @@ -4280,7 +4387,7 @@ class buffer: pass class rwbuffer: pass class robuffer: pass -StrConverterKeyType = tuple[frozenset[type], bool, bool] +StrConverterKeyType = tuple[frozenset[type[object]], bool, bool] def str_converter_key( types: TypeSet, encoding: bool | str | None, zeroes: bool @@ -4589,15 +4696,12 @@ def cleanup(self) -> str: return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"]) def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None: + # PyBUF_SIMPLE guarantees that the format units of the buffers are C-contiguous. if self.format_unit == 'y*': return self.format_code(""" if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ goto exit; }}}} - if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - {bad_argument} - goto exit; - }}}} """, argname=argname, bad_argument=self.bad_argument(displayname, 'contiguous buffer', limited_capi=limited_capi), @@ -4616,10 +4720,6 @@ def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> st if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ goto exit; }}}} - if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - {bad_argument} - goto exit; - }}}} }}}} """, argname=argname, @@ -4631,10 +4731,6 @@ def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> st {bad_argument} goto exit; }}}} - if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{ - {bad_argument2} - goto exit; - }}}} """, argname=argname, bad_argument=self.bad_argument(displayname, 'read-write bytes-like object', limited_capi=limited_capi), @@ -4646,7 +4742,7 @@ def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> st def correct_name_for_self( f: Function ) -> tuple[str, str]: - if f.kind in (CALLABLE, METHOD_INIT): + if f.kind in {CALLABLE, METHOD_INIT, GETTER, SETTER}: if f.cls: return "PyObject *", "self" return "PyObject *", "module" @@ -4790,7 +4886,7 @@ class CReturnConverterAutoRegister(type): def __init__( cls: ReturnConverterType, name: str, - bases: tuple[type, ...], + bases: tuple[type[object], ...], classdict: dict[str, Any] ) -> None: add_c_return_converter(cls) @@ -5103,8 +5199,11 @@ class DSLParser: indent: IndentStack kind: FunctionKind coexist: bool + forced_text_signature: str | None parameter_continuation: str preserve_output: bool + critical_section: bool + target_critical_section: list[str] from_version_re = re.compile(r'([*/]) +\[from +(.+)\]') def __init__(self, clinic: Clinic) -> None: @@ -5136,13 +5235,15 @@ def reset(self) -> None: self.indent = IndentStack() self.kind = CALLABLE self.coexist = False - self.forced_text_signature: str | None = None + self.forced_text_signature = None self.parameter_continuation = '' self.preserve_output = False + self.critical_section = False + self.target_critical_section = [] def directive_version(self, required: str) -> None: global version - if version_comparitor(version, required) < 0: + if version_comparator(version, required) < 0: fail("Insufficient Clinic version!\n" f" Version: {version}\n" f" Required: {required}") @@ -5267,6 +5368,30 @@ def at_classmethod(self) -> None: fail("Can't set @classmethod, function is not a normal callable") self.kind = CLASS_METHOD + def at_critical_section(self, *args: str) -> None: + if len(args) > 2: + fail("Up to 2 critical section variables are supported") + self.target_critical_section.extend(args) + self.critical_section = True + + def at_getter(self) -> None: + match self.kind: + case FunctionKind.GETTER: + fail("Cannot apply @getter twice to the same function!") + case FunctionKind.SETTER: + fail("Cannot apply both @getter and @setter to the same function!") + case _: + self.kind = FunctionKind.GETTER + + def at_setter(self) -> None: + match self.kind: + case FunctionKind.SETTER: + fail("Cannot apply @setter twice to the same function!") + case FunctionKind.GETTER: + fail("Cannot apply both @getter and @setter to the same function!") + case _: + self.kind = FunctionKind.SETTER + def at_staticmethod(self) -> None: if self.kind is not CALLABLE: fail("Can't set @staticmethod, function is not a normal callable") @@ -5376,14 +5501,20 @@ def update_function_kind(self, fullname: str) -> None: _, 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): + if (self.kind is CLASS_METHOD) and cls: + self.kind = METHOD_NEW + else: 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 + if (self.kind is CALLABLE) and cls: + self.kind = METHOD_INIT + else: + fail( + "'__init__' must be a normal method; " + f"got '{self.kind}'!" + ) def state_modulename_name(self, line: str) -> None: # looking for declaration, which establishes the leftmost column @@ -5460,6 +5591,8 @@ def state_modulename_name(self, line: str) -> None: return_converter = None if returns: + if self.kind in {GETTER, SETTER}: + fail(f"@{self.kind.name.lower()} method cannot define a return type") ast_input = f"def x() -> {returns}: pass" try: module_node = ast.parse(ast_input) @@ -5489,7 +5622,9 @@ def state_modulename_name(self, line: str) -> None: return_converter = CReturnConverter() 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) + return_converter=return_converter, kind=self.kind, coexist=self.coexist, + critical_section=self.critical_section, + target_critical_section=self.target_critical_section) self.block.signatures.append(self.function) # insert a self converter automatically @@ -5946,6 +6081,7 @@ def parse_star(self, function: Function, version: VersionTuple | None) -> None: if version is None: if self.keyword_only: fail(f"Function {function.name!r} uses '*' more than once.") + self.check_previous_star() self.check_remaining_star() self.keyword_only = True else: @@ -6343,7 +6479,6 @@ def check_remaining_star(self, lineno: int | None = None) -> None: else: return - no_param_after_symbol = True for p in reversed(self.function.parameters.values()): if self.keyword_only: if p.kind == inspect.Parameter.KEYWORD_ONLY: @@ -6356,6 +6491,14 @@ def check_remaining_star(self, lineno: int | None = None) -> None: fail(f"Function {self.function.name!r} specifies {symbol!r} " f"without following parameters.", line_number=lineno) + def check_previous_star(self, lineno: int | None = None) -> None: + assert isinstance(self.function, Function) + + for p in self.function.parameters.values(): + if p.kind == inspect.Parameter.VAR_POSITIONAL: + fail(f"Function {self.function.name!r} uses '*' more than once.") + + def do_post_block_processing_cleanup(self, lineno: int) -> None: """ Called when processing the block is done. diff --git a/Tools/freeze/test/freeze.py b/Tools/freeze/test/freeze.py index cdf77c57bbb6ae..1e3687dbb807a6 100644 --- a/Tools/freeze/test/freeze.py +++ b/Tools/freeze/test/freeze.py @@ -27,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, @@ -48,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() @@ -91,13 +93,18 @@ def copy_source_tree(newroot, oldroot): shutil.copytree(oldroot, newroot, ignore=support.copy_python_src_ignore) if os.path.exists(os.path.join(newroot, 'Makefile')): - _run_quiet([MAKE, 'clean'], newroot) + # 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) @@ -125,30 +132,28 @@ def prepare(script=None, outdir=None): 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 @@ -161,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/gdb/libpython.py b/Tools/gdb/libpython.py index 78b0c08d25ab01..5ef55524c11be2 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1065,9 +1065,9 @@ def _f_nlocalsplus(self): def _f_lasti(self): codeunit_p = gdb.lookup_type("_Py_CODEUNIT").pointer() - prev_instr = self._gdbval["prev_instr"] + instr_ptr = self._gdbval["instr_ptr"] first_instr = self._f_code().field("co_code_adaptive").cast(codeunit_p) - return int(prev_instr - first_instr) + return int(instr_ptr - first_instr) def is_shim(self): return self._f_special("owner", int) == FRAME_OWNED_BY_CSTACK 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/dev/dev_files.wxs b/Tools/msi/dev/dev_files.wxs index 21f9c848cc6be5..4357dc86d9d356 100644 --- a/Tools/msi/dev/dev_files.wxs +++ b/Tools/msi/dev/dev_files.wxs @@ -3,7 +3,7 @@ - + diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs index 87e164cb6759f6..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 e3959ce428c7c5..af1f0584bb5403 100755 --- a/Tools/patchcheck/patchcheck.py +++ b/Tools/patchcheck/patchcheck.py @@ -30,7 +30,8 @@ def 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): @@ -84,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: @@ -171,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) @@ -212,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.""" @@ -251,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.""" @@ -259,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.""" @@ -267,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') @@ -275,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) @@ -300,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/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/build.py b/Tools/peg_generator/pegen/build.py index 6b04ae9ec7025c..7df39a3b0ae48e 100644 --- a/Tools/peg_generator/pegen/build.py +++ b/Tools/peg_generator/pegen/build.py @@ -123,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"), @@ -133,7 +140,13 @@ 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"), ] + if sys.platform == "win32": + # HACK: The location of pyconfig.h has moved within our build, and + # setuptools hasn't updated for it yet. So add the path manually for now + include_dirs.append(pathlib.Path(sysconfig.get_config_h_filename()).parent) extension = Extension( extension_name, sources=[generated_source_path], diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index 301949bdae96fe..7cdd5debe9a225 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -38,7 +38,11 @@ #endif #ifdef __wasi__ -# define MAXSTACK 4000 +# ifdef Py_DEBUG +# define MAXSTACK 1000 +# else +# define MAXSTACK 4000 +# endif #else # define MAXSTACK 6000 #endif diff --git a/Tools/requirements-dev.txt b/Tools/requirements-dev.txt index 35bceb205e8a9b..3a2e62f70bbb60 100644 --- a/Tools/requirements-dev.txt +++ b/Tools/requirements-dev.txt @@ -1,7 +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 +mypy==1.7.1 # needed for peg_generator: -types-psutil==5.9.5.16 -types-setuptools==68.1.0.1 +types-psutil==5.9.5.17 +types-setuptools==69.0.0.0 diff --git a/Tools/requirements-hypothesis.txt b/Tools/requirements-hypothesis.txt index 9db2b74c87cfb0..1bca5d2367f4b2 100644 --- a/Tools/requirements-hypothesis.txt +++ b/Tools/requirements-hypothesis.txt @@ -1,4 +1,4 @@ # Requirements file for hypothesis that # we use to run our property-based tests in CI. -hypothesis==6.84.0 +hypothesis==6.91.0 diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py deleted file mode 100644 index 3e3d15d3b0da5c..00000000000000 --- a/Tools/scripts/run_tests.py +++ /dev/null @@ -1,78 +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_python_flag(arg): - return arg.startswith('-p') or arg.startswith('--python') - - -def main(regrtest_args): - args = [sys.executable] - - 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() - - # 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 - '--fast-ci', # Fast Continuous Integration mode - ]) - 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']) - - 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), flush=True) - - 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 3b2bdd8015be4a..80a1280c025aca 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -2,668 +2,1177 @@ default stats folders. """ +from __future__ import annotations + # NOTE: Bytecode introspection modules (opcode, dis, etc.) should only -# happen when loading a single dataset. When comparing datasets, it +# be imported 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 +from collections.abc import KeysView from datetime import date +import enum +import functools import itertools +import json +from operator import itemgetter +import os +from pathlib import Path +import re import sys +from typing import Any, Callable, TextIO, TypeAlias + + +RawData: TypeAlias = dict[str, Any] +Rows: TypeAlias = list[tuple] +Columns: TypeAlias = tuple[str, ...] +RowCalculator: TypeAlias = Callable[["Stats"], Rows] + + +# TODO: Check for parity + if os.name == "nt": DEFAULT_DIR = "c:\\temp\\py_stats\\" else: DEFAULT_DIR = "/tmp/py_stats/" -TOTAL = "specialization.hit", "specialization.miss", "execution_count" -def format_ratio(num, den): - """ - Format a ratio as a percentage. When the denominator is 0, returns the empty - string. - """ - if den == 0: - return "" - else: - return f"{num/den:.01%}" +SOURCE_DIR = Path(__file__).parents[2] -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 - common key. - """ - if len(a_rows) == 0 and len(b_rows) == 0: - return [] +TOTAL = "specialization.hit", "specialization.miss", "execution_count" - if len(a_rows): - a_ncols = list(set(len(x) for x in a_rows)) - if len(a_ncols) != 1: - raise ValueError("Table a is ragged") - if len(b_rows): - b_ncols = list(set(len(x) for x in b_rows)) - if len(b_ncols) != 1: - raise ValueError("Table b is ragged") +def pretty(name: str) -> str: + return name.replace("_", " ").lower() - if len(a_rows) and len(b_rows) and a_ncols[0] != b_ncols[0]: - raise ValueError("Tables have different widths") - if len(a_rows): - ncols = a_ncols[0] - else: - ncols = b_ncols[0] - - default = [""] * (ncols - 1) - a_data = {x[0]: x[1:] for x in a_rows} - b_data = {x[0]: x[1:] for x in b_rows} - - if len(a_data) != len(a_rows) or len(b_data) != len(b_rows): - raise ValueError("Duplicate keys") - - # To preserve ordering, use A's keys as is and then add any in B that aren't - # in A - keys = list(a_data.keys()) + [k for k in b_data.keys() if k not in a_data] - return [(k, *a_data.get(k, default), *b_data.get(k, default)) for k in keys] - -def calculate_specialization_stats(family_stats, total): - rows = [] - for key in sorted(family_stats): - if key.startswith("specialization.failure_kinds"): - continue - if key in ("specialization.hit", "specialization.miss"): - label = key[len("specialization."):] - elif key == "execution_count": - continue - elif key in ("specialization.success", "specialization.failure", "specializable"): - continue - elif key.startswith("pair"): - continue - else: - label = key - rows.append((f"{label:>12}", f"{family_stats[key]:>12}", format_ratio(family_stats[key], total))) - return rows - -def calculate_specialization_success_failure(family_stats): - total_attempts = 0 - for key in ("specialization.success", "specialization.failure"): - total_attempts += family_stats.get(key, 0) - rows = [] - if total_attempts: - for key in ("specialization.success", "specialization.failure"): - label = key[len("specialization."):] - label = label[0].upper() + label[1:] - val = family_stats.get(key, 0) - rows.append((label, val, format_ratio(val, total_attempts))) - return rows - -def calculate_specialization_failure_kinds(name, family_stats, defines): - total_failures = family_stats.get("specialization.failure", 0) - failure_kinds = [ 0 ] * 40 - for key in family_stats: - if not key.startswith("specialization.failure_kind"): - continue - _, index = key[:-1].split("[") - index = int(index) - failure_kinds[index] = family_stats[key] - failures = [(value, index) for (index, value) in enumerate(failure_kinds)] - failures.sort(reverse=True) - rows = [] - for value, index in failures: - if not value: - continue - rows.append((kind_to_text(index, defines, name), value, format_ratio(value, total_failures))) - return rows - -def print_specialization_stats(name, family_stats, defines): - if "specializable" not in family_stats: - return - total = sum(family_stats.get(kind, 0) for kind in TOTAL) - if total == 0: - return - with Section(name, 3, f"specialization stats for {name} family"): - rows = calculate_specialization_stats(family_stats, total) - emit_table(("Kind", "Count", "Ratio"), rows) - rows = calculate_specialization_success_failure(family_stats) - if rows: - print_title("Specialization attempts", 4) - emit_table(("", "Count:", "Ratio:"), rows) - rows = calculate_specialization_failure_kinds(name, family_stats, defines) - emit_table(("Failure kind", "Count:", "Ratio:"), rows) - -def print_comparative_specialization_stats(name, base_family_stats, head_family_stats, defines): - if "specializable" not in base_family_stats: - return - - base_total = sum(base_family_stats.get(kind, 0) for kind in TOTAL) - head_total = sum(head_family_stats.get(kind, 0) for kind in TOTAL) - if base_total + head_total == 0: - return - with Section(name, 3, f"specialization stats for {name} family"): - base_rows = calculate_specialization_stats(base_family_stats, base_total) - head_rows = calculate_specialization_stats(head_family_stats, head_total) - emit_table( - ("Kind", "Base Count", "Base Ratio", "Head Count", "Head Ratio"), - join_rows(base_rows, head_rows) - ) - base_rows = calculate_specialization_success_failure(base_family_stats) - head_rows = calculate_specialization_success_failure(head_family_stats) - rows = join_rows(base_rows, head_rows) - if rows: - print_title("Specialization attempts", 4) - emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows) - base_rows = calculate_specialization_failure_kinds(name, base_family_stats, defines) - head_rows = calculate_specialization_failure_kinds(name, head_family_stats, defines) - emit_table( - ("Failure kind", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), - join_rows(base_rows, head_rows) - ) +def _load_metadata_from_source(): + def get_defines(filepath: Path, prefix: str = "SPEC_FAIL"): + with open(SOURCE_DIR / filepath) as spec_src: + defines = collections.defaultdict(list) + start = "#define " + prefix + "_" + for line in spec_src: + line = line.strip() + if not line.startswith(start): + continue + line = line[len(start) :] + name, val = line.split() + defines[int(val.strip())].append(name.strip()) + return defines + + import opcode + + return { + "_specialized_instructions": [ + op for op in opcode._specialized_opmap.keys() if "__" not in op # type: ignore + ], + "_stats_defines": get_defines( + Path("Include") / "cpython" / "pystats.h", "EVAL_CALL" + ), + "_defines": get_defines(Path("Python") / "specialize.c"), + } + + +def load_raw_data(input: Path) -> RawData: + if input.is_file(): + with open(input, "r") as fd: + data = json.load(fd) -def gather_stats(input): - # Note the output of this function must be JSON-serializable + data["_stats_defines"] = {int(k): v for k, v in data["_stats_defines"].items()} + data["_defines"] = {int(k): v for k, v in data["_defines"].items()} - if os.path.isfile(input): - with open(input, "r") as fd: - stats = json.load(fd) + return data - 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 input.is_dir(): + stats = collections.Counter[str]() - elif os.path.isdir(input): - stats = collections.Counter() - for filename in os.listdir(input): - with open(os.path.join(input, filename)) as fd: + for filename in input.iterdir(): + with open(filename) as fd: for line in fd: try: key, value = line.split(":") except ValueError: - print(f"Unparsable line: '{line.strip()}' in {filename}", file=sys.stderr) + print( + f"Unparsable line: '{line.strip()}' in {filename}", + file=sys.stderr, + ) continue - key = key.strip() - value = int(value) - stats[key] += value - stats['__nfiles__'] += 1 - - import opcode + stats[key.strip()] += int(value) + stats["__nfiles__"] += 1 - 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() + data = dict(stats) + data.update(_load_metadata_from_source()) + return data - return stats else: raise ValueError(f"{input:r} is not a file or directory path") -def extract_opcode_stats(stats): - opcode_stats = collections.defaultdict(dict) - for key, value in stats.items(): - if not key.startswith("opcode"): - continue - name, _, rest = key[7:].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 + "_" - for line in spec_src: - line = line.strip() - if not line.startswith(start): - continue - line = line[len(start):] - name, val = line.split() - defines[int(val.strip())].append(name.strip()) - return defines - -def pretty(defname): - return defname.replace("_", " ").lower() - -def kind_to_text(kind, defines, opname): - if kind <= 8: - return pretty(defines[kind][0]) - if opname == "LOAD_SUPER_ATTR": - opname = "SUPER" - elif opname.endswith("ATTR"): - opname = "ATTR" - elif opname in ("FOR_ITER", "SEND"): - opname = "ITER" - elif opname.endswith("SUBSCR"): - opname = "SUBSCR" - for name in defines[kind]: - if name.startswith(opname): - return pretty(name[len(opname)+1:]) - return "kind " + str(kind) - -def categorized_counts(opcode_stats, specialized_instructions): - basic = 0 - specialized = 0 - not_specialized = 0 - for name, opcode_stat in opcode_stats.items(): - if "execution_count" not in opcode_stat: - continue - count = opcode_stat['execution_count'] - if "specializable" in opcode_stat: - not_specialized += count - elif name in specialized_instructions: - miss = opcode_stat.get("specialization.miss", 0) - not_specialized += miss - specialized += count - miss + +def save_raw_data(data: RawData, json_output: TextIO): + json.dump(data, json_output) + + +class OpcodeStats: + """ + Manages the data related to specific set of opcodes, e.g. tier1 (with prefix + "opcode") or tier2 (with prefix "uops"). + """ + + def __init__(self, data: dict[str, Any], defines, specialized_instructions): + self._data = data + self._defines = defines + self._specialized_instructions = specialized_instructions + + def get_opcode_names(self) -> KeysView[str]: + return self._data.keys() + + def get_pair_counts(self) -> dict[tuple[str, str], int]: + pair_counts = {} + for name_i, opcode_stat in self._data.items(): + for key, value in opcode_stat.items(): + if value and key.startswith("pair_count"): + name_j, _, _ = key[len("pair_count") + 1 :].partition("]") + pair_counts[(name_i, name_j)] = value + return pair_counts + + def get_total_execution_count(self) -> int: + return sum(x.get("execution_count", 0) for x in self._data.values()) + + def get_execution_counts(self) -> dict[str, tuple[int, int]]: + counts = {} + for name, opcode_stat in self._data.items(): + if "execution_count" in opcode_stat: + count = opcode_stat["execution_count"] + miss = 0 + if "specializable" not in opcode_stat: + miss = opcode_stat.get("specialization.miss", 0) + counts[name] = (count, miss) + return counts + + @functools.cache + def _get_pred_succ( + self, + ) -> tuple[dict[str, collections.Counter], dict[str, collections.Counter]]: + pair_counts = self.get_pair_counts() + + predecessors: dict[str, collections.Counter] = collections.defaultdict( + collections.Counter + ) + successors: dict[str, collections.Counter] = collections.defaultdict( + collections.Counter + ) + for (first, second), count in pair_counts.items(): + if count: + predecessors[second][first] = count + successors[first][second] = count + + return predecessors, successors + + def get_predecessors(self, opcode: str) -> collections.Counter[str]: + return self._get_pred_succ()[0][opcode] + + def get_successors(self, opcode: str) -> collections.Counter[str]: + return self._get_pred_succ()[1][opcode] + + def _get_stats_for_opcode(self, opcode: str) -> dict[str, int]: + return self._data[opcode] + + def get_specialization_total(self, opcode: str) -> int: + family_stats = self._get_stats_for_opcode(opcode) + return sum(family_stats.get(kind, 0) for kind in TOTAL) + + def get_specialization_counts(self, opcode: str) -> dict[str, int]: + family_stats = self._get_stats_for_opcode(opcode) + + result = {} + for key, value in sorted(family_stats.items()): + if key.startswith("specialization."): + label = key[len("specialization.") :] + if label in ("success", "failure") or label.startswith("failure_kinds"): + continue + elif key in ( + "execution_count", + "specializable", + ) or key.startswith("pair"): + continue + else: + label = key + result[label] = value + + return result + + def get_specialization_success_failure(self, opcode: str) -> dict[str, int]: + family_stats = self._get_stats_for_opcode(opcode) + result = {} + for key in ("specialization.success", "specialization.failure"): + label = key[len("specialization.") :] + val = family_stats.get(key, 0) + result[label] = val + return result + + def get_specialization_failure_total(self, opcode: str) -> int: + return self._get_stats_for_opcode(opcode).get("specialization.failure", 0) + + def get_specialization_failure_kinds(self, opcode: str) -> dict[str, int]: + def kind_to_text(kind: int, opcode: str): + if kind <= 8: + return pretty(self._defines[kind][0]) + if opcode == "LOAD_SUPER_ATTR": + opcode = "SUPER" + elif opcode.endswith("ATTR"): + opcode = "ATTR" + elif opcode in ("FOR_ITER", "SEND"): + opcode = "ITER" + elif opcode.endswith("SUBSCR"): + opcode = "SUBSCR" + for name in self._defines[kind]: + if name.startswith(opcode): + return pretty(name[len(opcode) + 1 :]) + return "kind " + str(kind) + + family_stats = self._get_stats_for_opcode(opcode) + failure_kinds = [0] * 40 + for key in family_stats: + if not key.startswith("specialization.failure_kind"): + continue + index = int(key[:-1].split("[")[1]) + failure_kinds[index] = family_stats[key] + return { + kind_to_text(index, opcode): value + for (index, value) in enumerate(failure_kinds) + if value + } + + def is_specializable(self, opcode: str) -> bool: + return "specializable" in self._get_stats_for_opcode(opcode) + + def get_specialized_total_counts(self) -> tuple[int, int, int]: + basic = 0 + specialized_hits = 0 + specialized_misses = 0 + not_specialized = 0 + for opcode, opcode_stat in self._data.items(): + if "execution_count" not in opcode_stat: + continue + count = opcode_stat["execution_count"] + if "specializable" in opcode_stat: + not_specialized += count + elif opcode in self._specialized_instructions: + miss = opcode_stat.get("specialization.miss", 0) + specialized_hits += count - miss + specialized_misses += miss + else: + basic += count + return basic, specialized_hits, specialized_misses, not_specialized + + def get_deferred_counts(self) -> dict[str, int]: + return { + opcode: opcode_stat.get("specialization.deferred", 0) + for opcode, opcode_stat in self._data.items() + if opcode != "RESUME" + } + + def get_misses_counts(self) -> dict[str, int]: + return { + opcode: opcode_stat.get("specialization.miss", 0) + for opcode, opcode_stat in self._data.items() + if not self.is_specializable(opcode) + } + + def get_opcode_counts(self) -> dict[str, int]: + counts = {} + for opcode, entry in self._data.items(): + count = entry.get("count", 0) + if count: + counts[opcode] = count + return counts + + +class Stats: + def __init__(self, data: RawData): + self._data = data + + def get(self, key: str) -> int: + return self._data.get(key, 0) + + @functools.cache + def get_opcode_stats(self, prefix: str) -> OpcodeStats: + opcode_stats = collections.defaultdict[str, dict](dict) + for key, value in self._data.items(): + if not key.startswith(prefix): + continue + name, _, rest = key[len(prefix) + 1 :].partition("]") + opcode_stats[name][rest.strip(".")] = value + return OpcodeStats( + opcode_stats, + self._data["_defines"], + self._data["_specialized_instructions"], + ) + + def get_call_stats(self) -> dict[str, int]: + defines = self._data["_stats_defines"] + result = {} + for key, value in sorted(self._data.items()): + if "Calls to" in key: + result[key] = value + elif key.startswith("Calls "): + name, index = key[:-1].split("[") + label = f"{name} ({pretty(defines[int(index)][0])})" + result[label] = value + + for key, value in sorted(self._data.items()): + if key.startswith("Frame"): + result[key] = value + + return result + + def get_object_stats(self) -> dict[str, tuple[int, int]]: + total_materializations = self._data.get("Object new values", 0) + total_allocations = self._data.get("Object allocations", 0) + self._data.get( + "Object allocations from freelist", 0 + ) + total_increfs = self._data.get( + "Object interpreter increfs", 0 + ) + self._data.get("Object increfs", 0) + total_decrefs = self._data.get( + "Object interpreter decrefs", 0 + ) + self._data.get("Object decrefs", 0) + + result = {} + for key, value in self._data.items(): + if key.startswith("Object"): + if "materialize" in key: + den = total_materializations + elif "allocations" in key: + den = total_allocations + elif "increfs" in key: + den = total_increfs + elif "decrefs" in key: + den = total_decrefs + else: + den = None + label = key[6:].strip() + label = label[0].upper() + label[1:] + result[label] = (value, den) + return result + + def get_gc_stats(self) -> list[dict[str, int]]: + gc_stats: list[dict[str, int]] = [] + for key, value in self._data.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 gc_stats + + def get_optimization_stats(self) -> dict[str, tuple[int, int | None]]: + if "Optimization attempts" not in self._data: + return {} + + attempts = self._data["Optimization attempts"] + created = self._data["Optimization traces created"] + executed = self._data["Optimization traces executed"] + uops = self._data["Optimization uops executed"] + trace_stack_overflow = self._data["Optimization trace stack overflow"] + trace_stack_underflow = self._data["Optimization trace stack underflow"] + trace_too_long = self._data["Optimization trace too long"] + trace_too_short = self._data["Optimization trace too short"] + inner_loop = self._data["Optimization inner loop"] + recursive_call = self._data["Optimization recursive call"] + low_confidence = self._data["Optimization low confidence"] + + return { + "Optimization attempts": (attempts, None), + "Traces created": (created, attempts), + "Trace stack overflow": (trace_stack_overflow, attempts), + "Trace stack underflow": (trace_stack_underflow, attempts), + "Trace too long": (trace_too_long, attempts), + "Trace too short": (trace_too_short, attempts), + "Inner loop found": (inner_loop, attempts), + "Recursive call": (recursive_call, attempts), + "Low confidence": (low_confidence, attempts), + "Traces executed": (executed, None), + "Uops executed": (uops, executed), + } + + def get_histogram(self, prefix: str) -> list[tuple[int, int]]: + rows = [] + for k, v in self._data.items(): + match = re.match(f"{prefix}\\[([0-9]+)\\]", k) + if match is not None: + entry = int(match.groups()[0]) + rows.append((entry, v)) + rows.sort() + return rows + + +class Count(int): + def markdown(self) -> str: + return format(self, ",d") + + +class Ratio: + def __init__(self, num: int, den: int | None, percentage: bool = True): + self.num = num + self.den = den + self.percentage = percentage + + def __float__(self): + if self.den == 0: + return 0.0 + elif self.den is None: + return self.num else: - basic += count - return basic, not_specialized, specialized + return self.num / self.den + + def markdown(self) -> str: + if self.den is None: + return "" + elif self.den == 0: + if self.num != 0: + return f"{self.num:,} / 0 !!" + return "" + elif self.percentage: + return f"{self.num / self.den:,.01%}" + else: + return f"{self.num / self.den:,.02f}" + + +class DiffRatio(Ratio): + def __init__(self, base: int | str, head: int | str): + if isinstance(base, str) or isinstance(head, str): + super().__init__(0, 0) + else: + super().__init__(head - base, base) + + +class JoinMode(enum.Enum): + # Join using the first column as a key + SIMPLE = 0 + # Join using the first column as a key, and indicate the change in the + # second column of each input table as a new column + CHANGE = 1 + # Join using the first column as a key, indicating the change in the second + # column of each input table as a ne column, and omit all other columns + CHANGE_ONE_COLUMN = 2 + + +class Table: + """ + A Table defines how to convert a set of Stats into a specific set of rows + displaying some aspect of the data. + """ + + def __init__( + self, + column_names: Columns, + calc_rows: RowCalculator, + join_mode: JoinMode = JoinMode.SIMPLE, + ): + self.columns = column_names + self.calc_rows = calc_rows + self.join_mode = join_mode + + def join_row(self, key: str, row_a: tuple, row_b: tuple) -> tuple: + match self.join_mode: + case JoinMode.SIMPLE: + return (key, *row_a, *row_b) + case JoinMode.CHANGE: + return (key, *row_a, *row_b, DiffRatio(row_a[0], row_b[0])) + case JoinMode.CHANGE_ONE_COLUMN: + return (key, row_a[0], row_b[0], DiffRatio(row_a[0], row_b[0])) + + def join_columns(self, columns: Columns) -> Columns: + match self.join_mode: + case JoinMode.SIMPLE: + return ( + columns[0], + *("Base " + x for x in columns[1:]), + *("Head " + x for x in columns[1:]), + ) + case JoinMode.CHANGE: + return ( + columns[0], + *("Base " + x for x in columns[1:]), + *("Head " + x for x in columns[1:]), + ) + ("Change:",) + case JoinMode.CHANGE_ONE_COLUMN: + return ( + columns[0], + "Base " + columns[1], + "Head " + columns[1], + "Change:", + ) + + def join_tables(self, rows_a: Rows, rows_b: Rows) -> tuple[Columns, Rows]: + ncols = len(self.columns) + + default = ("",) * (ncols - 1) + data_a = {x[0]: x[1:] for x in rows_a} + data_b = {x[0]: x[1:] for x in rows_b} + + if len(data_a) != len(rows_a) or len(data_b) != len(rows_b): + raise ValueError("Duplicate keys") + + # To preserve ordering, use A's keys as is and then add any in B that + # aren't in A + keys = list(data_a.keys()) + [k for k in data_b.keys() if k not in data_a] + rows = [ + self.join_row(k, data_a.get(k, default), data_b.get(k, default)) + for k in keys + ] + if self.join_mode in (JoinMode.CHANGE, JoinMode.CHANGE_ONE_COLUMN): + rows.sort(key=lambda row: abs(float(row[-1])), reverse=True) + + columns = self.join_columns(self.columns) + return columns, rows + + def get_table( + self, base_stats: Stats, head_stats: Stats | None = None + ) -> tuple[Columns, Rows]: + if head_stats is None: + rows = self.calc_rows(base_stats) + return self.columns, rows + else: + rows_a = self.calc_rows(base_stats) + rows_b = self.calc_rows(head_stats) + cols, rows = self.join_tables(rows_a, rows_b) + return cols, rows -def print_title(name, level=2): - print("#"*level, name) - print() class Section: + """ + A Section defines a section of the output document. + """ - def __init__(self, title, level=2, summary=None): + def __init__( + self, + title: str = "", + summary: str = "", + part_iter=None, + comparative: bool = True, + ): self.title = title - self.level = level - if summary is None: + if not summary: self.summary = title.lower() else: self.summary = summary + if part_iter is None: + part_iter = [] + if isinstance(part_iter, list): - def __enter__(self): - print_title(self.title, self.level) - print("
") - print("", self.summary, "") - print() - return self - - def __exit__(*args): - print() - print("
") - print() - -def to_str(x): - if isinstance(x, int): - return format(x, ",d") - else: - return str(x) - -def emit_table(header, rows): - width = len(header) - header_line = "|" - under_line = "|" - for item in header: - under = "---" - if item.endswith(":"): - item = item[:-1] - under += ":" - header_line += item + " | " - under_line += under + "|" - print(header_line) - print(under_line) - for row in rows: - if width is not None and len(row) != width: - raise ValueError("Wrong number of elements in row '" + str(row) + "'") - print("|", " | ".join(to_str(i) for i in row), "|") - print() - -def calculate_execution_counts(opcode_stats, total): - counts = [] - for name, opcode_stat in opcode_stats.items(): - if "execution_count" in opcode_stat: - count = opcode_stat['execution_count'] - miss = 0 - if "specializable" not in opcode_stat: - miss = opcode_stat.get("specialization.miss") - counts.append((count, name, miss)) - counts.sort(reverse=True) - cumulative = 0 - rows = [] - for (count, name, miss) in counts: - cumulative += count - if miss: - miss = format_ratio(miss, count) + def iter_parts(base_stats: Stats, head_stats: Stats | None): + yield from part_iter + + self.part_iter = iter_parts else: - miss = "" - rows.append((name, count, format_ratio(count, total), - format_ratio(cumulative, total), miss)) - return rows - -def emit_execution_counts(opcode_stats, total): - with Section("Execution counts", summary="execution counts for all instructions"): - rows = calculate_execution_counts(opcode_stats, total) - emit_table( - ("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), - rows - ) + self.part_iter = part_iter + self.comparative = comparative -def emit_comparative_execution_counts( - base_opcode_stats, base_total, head_opcode_stats, head_total -): - with Section("Execution counts", summary="execution counts for all instructions"): - base_rows = calculate_execution_counts(base_opcode_stats, base_total) - head_rows = calculate_execution_counts(head_opcode_stats, head_total) - base_data = dict((x[0], x[1:]) for x in base_rows) - head_data = dict((x[0], x[1:]) for x in head_rows) - opcodes = set(base_data.keys()) | set(head_data.keys()) - rows = [] - default = [0, "0.0%", "0.0%", 0] - for opcode in opcodes: - base_entry = base_data.get(opcode, default) - head_entry = head_data.get(opcode, default) - if base_entry[0] == 0: - change = 1 +def calc_execution_count_table(prefix: str) -> RowCalculator: + def calc(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats(prefix) + counts = opcode_stats.get_execution_counts() + total = opcode_stats.get_total_execution_count() + cumulative = 0 + rows: Rows = [] + for opcode, (count, miss) in sorted( + counts.items(), key=itemgetter(1), reverse=True + ): + cumulative += count + if miss: + miss_val = Ratio(miss, count) else: - change = (head_entry[0] - base_entry[0]) / base_entry[0] + miss_val = None rows.append( - (opcode, base_entry[0], head_entry[0], - f"{100*change:0.1f}%")) + ( + opcode, + Count(count), + Ratio(count, total), + Ratio(cumulative, total), + miss_val, + ) + ) + return rows - rows.sort(key=lambda x: -abs(percentage_to_float(x[-1]))) + return calc - emit_table( - ("Name", "Base Count:", "Head Count:", "Change:"), - rows - ) -def get_defines(): - spec_path = os.path.join(os.path.dirname(__file__), "../../Python/specialize.c") - with open(spec_path) as spec_src: - defines = parse_kinds(spec_src) - return defines - -def emit_specialization_stats(opcode_stats, defines): - with Section("Specialization stats", summary="specialization stats by family"): - 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): - with Section("Specialization stats", summary="specialization stats by family"): - 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 execution_count_section() -> Section: + return Section( + "Execution counts", + "execution counts for all instructions", + [ + Table( + ("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), + calc_execution_count_table("opcode"), + join_mode=JoinMode.CHANGE_ONE_COLUMN, ) - -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, specialized_instructions): - with Section("Specialization effectiveness"): - 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")): - total = 0 - counts = [] - 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, 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] ] - emit_table(("Name", "Count:", "Ratio:"), rows) - -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, 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) - ) -def get_stats_defines(): - 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): - total = 0 - for key, value in stats.items(): - if "Calls to" in key: - total += value - rows = [] - for key, value in stats.items(): - if "Calls to" in key: - rows.append((key, value, format_ratio(value, total))) - elif key.startswith("Calls "): - name, index = key[:-1].split("[") - index = int(index) - label = name + " (" + pretty(defines[index][0]) + ")" - rows.append((label, value, format_ratio(value, total))) - for key, value in stats.items(): - if key.startswith("Frame"): - rows.append((key, value, format_ratio(value, total))) - return rows - -def emit_call_stats(stats, defines): - with Section("Call stats", summary="Inlined calls and frame stats"): - rows = calculate_call_stats(stats, defines) - emit_table(("", "Count:", "Ratio:"), rows) - -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, defines) - head_rows = calculate_call_stats(head_stats, defines) - rows = join_rows(base_rows, head_rows) - rows.sort(key=lambda x: -percentage_to_float(x[-1])) - emit_table( - ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), - rows - ) -def calculate_object_stats(stats): - total_materializations = stats.get("Object new values") - total_allocations = stats.get("Object allocations") + stats.get("Object allocations from freelist") - total_increfs = stats.get("Object interpreter increfs") + stats.get("Object increfs") - total_decrefs = stats.get("Object interpreter decrefs") + stats.get("Object decrefs") - rows = [] - for key, value in stats.items(): - if key.startswith("Object"): - if "materialize" in key: - ratio = format_ratio(value, total_materializations) - elif "allocations" in key: - ratio = format_ratio(value, total_allocations) - elif "increfs" in key: - ratio = format_ratio(value, total_increfs) - elif "decrefs" in key: - ratio = format_ratio(value, total_decrefs) - else: - ratio = "" - label = key[6:].strip() - label = label[0].upper() + label[1:] - rows.append((label, value, ratio)) - return rows - -def 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) - -def emit_comparative_object_stats(base_stats, head_stats): - with Section("Object stats", summary="allocations, frees and dict materializatons"): - base_rows = calculate_object_stats(base_stats) - head_rows = calculate_object_stats(head_stats) - emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), join_rows(base_rows, head_rows)) - -def 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.values(): - if "execution_count" in opcode_stat: - total += opcode_stat['execution_count'] - return total - -def emit_pair_counts(opcode_stats, total): - pair_counts = [] - for name_i, opcode_stat in opcode_stats.items(): - for key, value in opcode_stat.items(): - if key.startswith("pair_count"): - name_j, _, _ = key[11:].partition("]") - if value: - pair_counts.append((value, (name_i, name_j))) - with Section("Pair counts", summary="Pair counts for top 100 pairs"): - pair_counts.sort(reverse=True) +def pair_count_section() -> Section: + def calc_pair_count_table(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats("opcode") + pair_counts = opcode_stats.get_pair_counts() + total = opcode_stats.get_total_execution_count() + cumulative = 0 - rows = [] - for (count, pair) in itertools.islice(pair_counts, 100): - name_i, name_j = pair + rows: Rows = [] + for (opcode_i, opcode_j), count in itertools.islice( + sorted(pair_counts.items(), key=itemgetter(1), reverse=True), 100 + ): cumulative += count - 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() - total_successors = collections.Counter() - for count, (first, second) in pair_counts: - if count: - predecessors[second][first] = count - successors[first][second] = count - total_predecessors[second] += count - total_successors[first] += count - for name 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 = [(pred, count, f"{count/total1:.1%}") - for (pred, count) in predecessors[name].most_common(5)] - if total2: - 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 + rows.append( + ( + f"{opcode_i} {opcode_j}", + Count(count), + Ratio(count, total), + Ratio(cumulative, total), ) - emit_table(("Successors", "Count:", "Percentage:"), - succ_rows + ) + return rows + + return Section( + "Pair counts", + "Pair counts for top 100 pairs", + [ + Table( + ("Pair", "Count:", "Self:", "Cumulative:"), + calc_pair_count_table, + ) + ], + comparative=False, + ) + + +def pre_succ_pairs_section() -> Section: + def iter_pre_succ_pairs_tables(base_stats: Stats, head_stats: Stats | None = None): + assert head_stats is None + + opcode_stats = base_stats.get_opcode_stats("opcode") + + for opcode in opcode_stats.get_opcode_names(): + predecessors = opcode_stats.get_predecessors(opcode) + successors = opcode_stats.get_successors(opcode) + predecessors_total = predecessors.total() + successors_total = successors.total() + if predecessors_total == 0 and successors_total == 0: + continue + pred_rows = [ + (pred, Count(count), Ratio(count, predecessors_total)) + for (pred, count) in predecessors.most_common(5) + ] + succ_rows = [ + (succ, Count(count), Ratio(count, successors_total)) + for (succ, count) in successors.most_common(5) + ] + + yield Section( + opcode, + f"Successors and predecessors for {opcode}", + [ + Table( + ("Predecessors", "Count:", "Percentage:"), + lambda *_: pred_rows, # type: ignore + ), + Table( + ("Successors", "Count:", "Percentage:"), + lambda *_: succ_rows, # type: ignore + ), + ], + ) + + return Section( + "Predecessor/Successor Pairs", + "Top 5 predecessors and successors of each opcode", + iter_pre_succ_pairs_tables, + comparative=False, + ) + + +def specialization_section() -> Section: + def calc_specialization_table(opcode: str) -> RowCalculator: + def calc(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats("opcode") + total = opcode_stats.get_specialization_total(opcode) + specialization_counts = opcode_stats.get_specialization_counts(opcode) + + return [ + ( + f"{label:>12}", + Count(count), + Ratio(count, total), ) + for label, count in specialization_counts.items() + ] + + return calc + + def calc_specialization_success_failure_table(name: str) -> RowCalculator: + def calc(stats: Stats) -> Rows: + values = stats.get_opcode_stats( + "opcode" + ).get_specialization_success_failure(name) + total = sum(values.values()) + if total: + return [ + (label.capitalize(), Count(val), Ratio(val, total)) + for label, val in values.items() + ] + else: + return [] + + return calc + + def calc_specialization_failure_kind_table(name: str) -> RowCalculator: + def calc(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats("opcode") + failures = opcode_stats.get_specialization_failure_kinds(name) + total = opcode_stats.get_specialization_failure_total(name) + + return sorted( + [ + (label, Count(value), Ratio(value, total)) + for label, value in failures.items() + if value + ], + key=itemgetter(1), + reverse=True, + ) + + return calc + + def iter_specialization_tables(base_stats: Stats, head_stats: Stats | None = None): + opcode_base_stats = base_stats.get_opcode_stats("opcode") + names = opcode_base_stats.get_opcode_names() + if head_stats is not None: + opcode_head_stats = head_stats.get_opcode_stats("opcode") + names &= opcode_head_stats.get_opcode_names() # type: ignore + else: + opcode_head_stats = None + + for opcode in sorted(names): + if not opcode_base_stats.is_specializable(opcode): + continue + if opcode_base_stats.get_specialization_total(opcode) == 0 and ( + opcode_head_stats is None + or opcode_head_stats.get_specialization_total(opcode) == 0 + ): + continue + yield Section( + opcode, + f"specialization stats for {opcode} family", + [ + Table( + ("Kind", "Count:", "Ratio:"), + calc_specialization_table(opcode), + JoinMode.CHANGE, + ), + Table( + ("", "Count:", "Ratio:"), + calc_specialization_success_failure_table(opcode), + JoinMode.CHANGE, + ), + Table( + ("Failure kind", "Count:", "Ratio:"), + calc_specialization_failure_kind_table(opcode), + JoinMode.CHANGE, + ), + ], + ) + + return Section( + "Specialization stats", + "specialization stats by family", + iter_specialization_tables, + ) + + +def specialization_effectiveness_section() -> Section: + def calc_specialization_effectiveness_table(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats("opcode") + total = opcode_stats.get_total_execution_count() + + ( + basic, + specialized_hits, + specialized_misses, + not_specialized, + ) = opcode_stats.get_specialized_total_counts() + + return [ + ("Basic", Count(basic), Ratio(basic, total)), + ( + "Not specialized", + Count(not_specialized), + Ratio(not_specialized, total), + ), + ( + "Specialized hits", + Count(specialized_hits), + Ratio(specialized_hits, total), + ), + ( + "Specialized misses", + Count(specialized_misses), + Ratio(specialized_misses, total), + ), + ] + + def calc_deferred_by_table(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats("opcode") + deferred_counts = opcode_stats.get_deferred_counts() + total = sum(deferred_counts.values()) + if total == 0: + return [] + + return [ + (name, Count(value), Ratio(value, total)) + for name, value in sorted( + deferred_counts.items(), key=itemgetter(1), reverse=True + )[:10] + ] -def output_single_stats(stats): - opcode_stats = extract_opcode_stats(stats) - total = get_total(opcode_stats) - emit_execution_counts(opcode_stats, total) - emit_pair_counts(opcode_stats, total) - emit_specialization_stats(opcode_stats, 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) - with Section("Meta stats", summary="Meta statistics"): - emit_table(("", "Count:"), [('Number of data files', stats['__nfiles__'])]) - - -def output_comparative_stats(base_stats, head_stats): - base_opcode_stats = extract_opcode_stats(base_stats) - base_total = get_total(base_opcode_stats) - - head_opcode_stats = extract_opcode_stats(head_stats) - head_total = get_total(head_opcode_stats) - - emit_comparative_execution_counts( - base_opcode_stats, base_total, head_opcode_stats, head_total + def calc_misses_by_table(stats: Stats) -> Rows: + opcode_stats = stats.get_opcode_stats("opcode") + misses_counts = opcode_stats.get_misses_counts() + total = sum(misses_counts.values()) + if total == 0: + return [] + + return [ + (name, Count(value), Ratio(value, total)) + for name, value in sorted( + misses_counts.items(), key=itemgetter(1), reverse=True + )[:10] + ] + + return Section( + "Specialization effectiveness", + "", + [ + Table( + ("Instructions", "Count:", "Ratio:"), + calc_specialization_effectiveness_table, + JoinMode.CHANGE, + ), + Section( + "Deferred by instruction", + "", + [ + Table( + ("Name", "Count:", "Ratio:"), + calc_deferred_by_table, + JoinMode.CHANGE, + ) + ], + ), + Section( + "Misses by instruction", + "", + [ + Table( + ("Name", "Count:", "Ratio:"), + calc_misses_by_table, + JoinMode.CHANGE, + ) + ], + ), + ], ) - emit_comparative_specialization_stats( - base_opcode_stats, head_opcode_stats, head_stats["_defines"] + + +def call_stats_section() -> Section: + def calc_call_stats_table(stats: Stats) -> Rows: + call_stats = stats.get_call_stats() + total = sum(v for k, v in call_stats.items() if "Calls to" in k) + return [ + (key, Count(value), Ratio(value, total)) + for key, value in call_stats.items() + ] + + return Section( + "Call stats", + "Inlined calls and frame stats", + [ + Table( + ("", "Count:", "Ratio:"), + calc_call_stats_table, + JoinMode.CHANGE, + ) + ], ) - emit_comparative_specialization_overview( - base_opcode_stats, base_total, head_opcode_stats, head_total, - head_stats["_specialized_instructions"] + + +def object_stats_section() -> Section: + def calc_object_stats_table(stats: Stats) -> Rows: + object_stats = stats.get_object_stats() + return [ + (label, Count(value), Ratio(value, den)) + for label, (value, den) in object_stats.items() + ] + + return Section( + "Object stats", + "allocations, frees and dict materializatons", + [ + Table( + ("", "Count:", "Ratio:"), + calc_object_stats_table, + JoinMode.CHANGE, + ) + ], ) - 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) - -def output_stats(inputs, json_output=None): - if len(inputs) == 1: - stats = gather_stats(inputs[0]) - if json_output is not None: - json.dump(stats, json_output) - output_single_stats(stats) - elif len(inputs) == 2: - if json_output is not None: - raise ValueError( - "Can not output to JSON when there are multiple inputs" + + +def gc_stats_section() -> Section: + def calc_gc_stats(stats: Stats) -> Rows: + gc_stats = stats.get_gc_stats() + + return [ + ( + Count(i), + Count(gen["collections"]), + Count(gen["objects collected"]), + Count(gen["object visits"]), ) + for (i, gen) in enumerate(gc_stats) + ] + + return Section( + "GC stats", + "GC collections and effectiveness", + [ + Table( + ("Generation:", "Collections:", "Objects collected:", "Object visits:"), + calc_gc_stats, + ) + ], + ) - base_stats = gather_stats(inputs[0]) - head_stats = gather_stats(inputs[1]) - output_comparative_stats(base_stats, head_stats) - print("---") - print("Stats gathered on:", date.today()) +def optimization_section() -> Section: + def calc_optimization_table(stats: Stats) -> Rows: + optimization_stats = stats.get_optimization_stats() + + return [ + ( + label, + Count(value), + Ratio(value, den, percentage=label != "Uops executed"), + ) + for label, (value, den) in optimization_stats.items() + ] + + def calc_histogram_table(key: str, den: str) -> RowCalculator: + def calc(stats: Stats) -> Rows: + histogram = stats.get_histogram(key) + denominator = stats.get(den) + + rows: Rows = [] + last_non_zero = 0 + for k, v in histogram: + if v != 0: + last_non_zero = len(rows) + rows.append( + ( + f"<= {k:,d}", + Count(v), + Ratio(v, denominator), + ) + ) + # Don't include any zero entries at the end + rows = rows[: last_non_zero + 1] + return rows + + return calc + + def calc_unsupported_opcodes_table(stats: Stats) -> Rows: + unsupported_opcodes = stats.get_opcode_stats("unsupported_opcode") + return sorted( + [ + (opcode, Count(count)) + for opcode, count in unsupported_opcodes.get_opcode_counts().items() + ], + key=itemgetter(1), + reverse=True, + ) + + def iter_optimization_tables(base_stats: Stats, head_stats: Stats | None = None): + if not base_stats.get_optimization_stats() or ( + head_stats is not None and not head_stats.get_optimization_stats() + ): + return + + yield Table(("", "Count:", "Ratio:"), calc_optimization_table, JoinMode.CHANGE) + for name, den in [ + ("Trace length", "Optimization traces created"), + ("Optimized trace length", "Optimization traces created"), + ("Trace run length", "Optimization traces executed"), + ]: + yield Section( + f"{name} histogram", + "", + [ + Table( + ("Range", "Count:", "Ratio:"), + calc_histogram_table(name, den), + JoinMode.CHANGE, + ) + ], + ) + yield Section( + "Uop execution stats", + "", + [ + Table( + ("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), + calc_execution_count_table("uops"), + JoinMode.CHANGE_ONE_COLUMN, + ) + ], + ) + yield Section( + "Unsupported opcodes", + "", + [ + Table( + ("Opcode", "Count:"), + calc_unsupported_opcodes_table, + JoinMode.CHANGE, + ) + ], + ) + + return Section( + "Optimization (Tier 2) stats", + "statistics about the Tier 2 optimizer", + iter_optimization_tables, + ) + + +def meta_stats_section() -> Section: + def calc_rows(stats: Stats) -> Rows: + return [("Number of data files", Count(stats.get("__nfiles__")))] + + return Section( + "Meta stats", + "Meta statistics", + [Table(("", "Count:"), calc_rows, JoinMode.CHANGE)], + ) + + +LAYOUT = [ + execution_count_section(), + pair_count_section(), + pre_succ_pairs_section(), + specialization_section(), + specialization_effectiveness_section(), + call_stats_section(), + object_stats_section(), + gc_stats_section(), + optimization_section(), + meta_stats_section(), +] + + +def output_markdown( + out: TextIO, + obj: Section | Table | list, + base_stats: Stats, + head_stats: Stats | None = None, + level: int = 2, +) -> None: + def to_markdown(x): + if hasattr(x, "markdown"): + return x.markdown() + elif isinstance(x, str): + return x + elif x is None: + return "" + else: + raise TypeError(f"Can't convert {x} to markdown") + + match obj: + case Section(): + if obj.title: + print("#" * level, obj.title, file=out) + print(file=out) + print("
", file=out) + print("", obj.summary, "", file=out) + print(file=out) + if head_stats is not None and obj.comparative is False: + print("Not included in comparative output.\n") + else: + for part in obj.part_iter(base_stats, head_stats): + output_markdown(out, part, base_stats, head_stats, level=level + 1) + print(file=out) + if obj.title: + print("
", file=out) + print(file=out) + + case Table(): + header, rows = obj.get_table(base_stats, head_stats) + if len(rows) == 0: + return + + width = len(header) + header_line = "|" + under_line = "|" + for item in header: + under = "---" + if item.endswith(":"): + item = item[:-1] + under += ":" + header_line += item + " | " + under_line += under + "|" + print(header_line, file=out) + print(under_line, file=out) + for row in rows: + if len(row) != width: + raise ValueError( + "Wrong number of elements in row '" + str(row) + "'" + ) + print("|", " | ".join(to_markdown(i) for i in row), "|", file=out) + print(file=out) + + case list(): + for part in obj: + output_markdown(out, part, base_stats, head_stats, level=level) + + print("---", file=out) + print("Stats gathered on:", date.today(), file=out) + + +def output_stats(inputs: list[Path], json_output=TextIO | None): + match len(inputs): + case 1: + data = load_raw_data(Path(inputs[0])) + if json_output is not None: + save_raw_data(data, json_output) # type: ignore + stats = Stats(data) + output_markdown(sys.stdout, LAYOUT, stats) + case 2: + if json_output is not None: + raise ValueError( + "Can not output to JSON when there are multiple inputs" + ) + base_data = load_raw_data(Path(inputs[0])) + head_data = load_raw_data(Path(inputs[1])) + base_stats = Stats(base_data) + head_stats = Stats(head_data) + output_markdown(sys.stdout, LAYOUT, base_stats, head_stats) + def main(): parser = argparse.ArgumentParser(description="Summarize pystats results") @@ -680,14 +1189,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() @@ -697,5 +1206,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 f066fb52cfd496..120e3883adc795 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -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/dawg.py b/Tools/unicode/dawg.py new file mode 100644 index 00000000000000..b74d602f6e1d79 --- /dev/null +++ b/Tools/unicode/dawg.py @@ -0,0 +1,533 @@ +# Original Algorithm: +# By Steve Hanov, 2011. Released to the public domain. +# Please see http://stevehanov.ca/blog/index.php?id=115 for the accompanying article. +# +# Adapted for PyPy/CPython by Carl Friedrich Bolz-Tereick +# +# Based on Daciuk, Jan, et al. "Incremental construction of minimal acyclic finite-state automata." +# Computational linguistics 26.1 (2000): 3-16. +# +# Updated 2014 to use DAWG as a mapping; see +# Kowaltowski, T.; CL. Lucchesi (1993), "Applications of finite automata representing large vocabularies", +# Software-Practice and Experience 1993 + +from collections import defaultdict +from functools import cached_property + + +# This class represents a node in the directed acyclic word graph (DAWG). It +# has a list of edges to other nodes. It has functions for testing whether it +# is equivalent to another node. Nodes are equivalent if they have identical +# edges, and each identical edge leads to identical states. The __hash__ and +# __eq__ functions allow it to be used as a key in a python dictionary. + + +class DawgNode: + + def __init__(self, dawg): + self.id = dawg.next_id + dawg.next_id += 1 + self.final = False + self.edges = {} + + self.linear_edges = None # later: list of (string, next_state) + + def __str__(self): + if self.final: + arr = ["1"] + else: + arr = ["0"] + + for (label, node) in sorted(self.edges.items()): + arr.append(label) + arr.append(str(node.id)) + + return "_".join(arr) + __repr__ = __str__ + + def _as_tuple(self): + edges = sorted(self.edges.items()) + edge_tuple = tuple((label, node.id) for label, node in edges) + return (self.final, edge_tuple) + + def __hash__(self): + return hash(self._as_tuple()) + + def __eq__(self, other): + return self._as_tuple() == other._as_tuple() + + @cached_property + def num_reachable_linear(self): + # returns the number of different paths to final nodes reachable from + # this one + + count = 0 + # staying at self counts as a path if self is final + if self.final: + count += 1 + for label, node in self.linear_edges: + count += node.num_reachable_linear + + return count + + +class Dawg: + def __init__(self): + self.previous_word = "" + self.next_id = 0 + self.root = DawgNode(self) + + # Here is a list of nodes that have not been checked for duplication. + self.unchecked_nodes = [] + + # To deduplicate, maintain a dictionary with + # minimized_nodes[canonical_node] is canonical_node. + # Based on __hash__ and __eq__, minimized_nodes[n] is the + # canonical node equal to n. + # In other words, self.minimized_nodes[x] == x for all nodes found in + # the dict. + self.minimized_nodes = {} + + # word: value mapping + self.data = {} + # value: word mapping + self.inverse = {} + + def insert(self, word, value): + if not all(0 <= ord(c) < 128 for c in word): + raise ValueError("Use 7-bit ASCII characters only") + if word <= self.previous_word: + raise ValueError("Error: Words must be inserted in alphabetical order.") + if value in self.inverse: + raise ValueError(f"value {value} is duplicate, got it for word {self.inverse[value]} and now {word}") + + # find common prefix between word and previous word + common_prefix = 0 + for i in range(min(len(word), len(self.previous_word))): + if word[i] != self.previous_word[i]: + break + common_prefix += 1 + + # Check the unchecked_nodes for redundant nodes, proceeding from last + # one down to the common prefix size. Then truncate the list at that + # point. + self._minimize(common_prefix) + + self.data[word] = value + self.inverse[value] = word + + # add the suffix, starting from the correct node mid-way through the + # graph + if len(self.unchecked_nodes) == 0: + node = self.root + else: + node = self.unchecked_nodes[-1][2] + + for letter in word[common_prefix:]: + next_node = DawgNode(self) + node.edges[letter] = next_node + self.unchecked_nodes.append((node, letter, next_node)) + node = next_node + + node.final = True + self.previous_word = word + + def finish(self): + if not self.data: + raise ValueError("need at least one word in the dawg") + # minimize all unchecked_nodes + self._minimize(0) + + self._linearize_edges() + + topoorder, linear_data, inverse = self._topological_order() + return self.compute_packed(topoorder), linear_data, inverse + + def _minimize(self, down_to): + # proceed from the leaf up to a certain point + for i in range(len(self.unchecked_nodes) - 1, down_to - 1, -1): + (parent, letter, child) = self.unchecked_nodes[i] + if child in self.minimized_nodes: + # replace the child with the previously encountered one + parent.edges[letter] = self.minimized_nodes[child] + else: + # add the state to the minimized nodes. + self.minimized_nodes[child] = child + self.unchecked_nodes.pop() + + def _lookup(self, word): + """ Return an integer 0 <= k < number of strings in dawg + where word is the kth successful traversal of the dawg. """ + node = self.root + skipped = 0 # keep track of number of final nodes that we skipped + index = 0 + while index < len(word): + for label, child in node.linear_edges: + if word[index] == label[0]: + if word[index:index + len(label)] == label: + if node.final: + skipped += 1 + index += len(label) + node = child + break + else: + return None + skipped += child.num_reachable_linear + else: + return None + return skipped + + def enum_all_nodes(self): + stack = [self.root] + done = set() + while stack: + node = stack.pop() + if node.id in done: + continue + yield node + done.add(node.id) + for label, child in sorted(node.edges.items()): + stack.append(child) + + def prettyprint(self): + for node in sorted(self.enum_all_nodes(), key=lambda e: e.id): + s_final = " final" if node.final else "" + print(f"{node.id}: ({node}) {s_final}") + for label, child in sorted(node.edges.items()): + print(f" {label} goto {child.id}") + + def _inverse_lookup(self, number): + assert 0, "not working in the current form, but keep it as the pure python version of compact lookup" + result = [] + node = self.root + while 1: + if node.final: + if pos == 0: + return "".join(result) + pos -= 1 + for label, child in sorted(node.edges.items()): + nextpos = pos - child.num_reachable_linear + if nextpos < 0: + result.append(label) + node = child + break + else: + pos = nextpos + else: + assert 0 + + def _linearize_edges(self): + # compute "linear" edges. the idea is that long chains of edges without + # any of the intermediate states being final or any extra incoming or + # outgoing edges can be represented by having removing them, and + # instead using longer strings as edge labels (instead of single + # characters) + incoming = defaultdict(list) + nodes = sorted(self.enum_all_nodes(), key=lambda e: e.id) + for node in nodes: + for label, child in sorted(node.edges.items()): + incoming[child].append(node) + for node in nodes: + node.linear_edges = [] + for label, child in sorted(node.edges.items()): + s = [label] + while len(child.edges) == 1 and len(incoming[child]) == 1 and not child.final: + (c, child), = child.edges.items() + s.append(c) + node.linear_edges.append((''.join(s), child)) + + def _topological_order(self): + # compute reachable linear nodes, and the set of incoming edges for each node + order = [] + stack = [self.root] + seen = set() + while stack: + # depth first traversal + node = stack.pop() + if node.id in seen: + continue + seen.add(node.id) + order.append(node) + for label, child in node.linear_edges: + stack.append(child) + + # do a (slightly bad) topological sort + incoming = defaultdict(set) + for node in order: + for label, child in node.linear_edges: + incoming[child].add((label, node)) + no_incoming = [order[0]] + topoorder = [] + positions = {} + while no_incoming: + node = no_incoming.pop() + topoorder.append(node) + positions[node] = len(topoorder) + # use "reversed" to make sure that the linear_edges get reorderd + # from their alphabetical order as little as necessary (no_incoming + # is LIFO) + for label, child in reversed(node.linear_edges): + incoming[child].discard((label, node)) + if not incoming[child]: + no_incoming.append(child) + del incoming[child] + # check result + assert set(topoorder) == set(order) + assert len(set(topoorder)) == len(topoorder) + + for node in order: + node.linear_edges.sort(key=lambda element: positions[element[1]]) + + for node in order: + for label, child in node.linear_edges: + assert positions[child] > positions[node] + # number the nodes. afterwards every input string in the set has a + # unique number in the 0 <= number < len(data). We then put the data in + # self.data into a linear list using these numbers as indexes. + topoorder[0].num_reachable_linear + linear_data = [None] * len(self.data) + inverse = {} # maps value back to index + for word, value in self.data.items(): + index = self._lookup(word) + linear_data[index] = value + inverse[value] = index + + return topoorder, linear_data, inverse + + def compute_packed(self, order): + def compute_chunk(node, offsets): + """ compute the packed node/edge data for a node. result is a + list of bytes as long as order. the jump distance calculations use + the offsets dictionary to know where in the final big output + bytestring the individual nodes will end up. """ + result = bytearray() + offset = offsets[node] + encode_varint_unsigned(number_add_bits(node.num_reachable_linear, node.final), result) + if len(node.linear_edges) == 0: + assert node.final + encode_varint_unsigned(0, result) # add a 0 saying "done" + prev_child_offset = offset + len(result) + for edgeindex, (label, targetnode) in enumerate(node.linear_edges): + label = label.encode('ascii') + child_offset = offsets[targetnode] + child_offset_difference = child_offset - prev_child_offset + + info = number_add_bits(child_offset_difference, len(label) == 1, edgeindex == len(node.linear_edges) - 1) + if edgeindex == 0: + assert info != 0 + encode_varint_unsigned(info, result) + prev_child_offset = child_offset + if len(label) > 1: + encode_varint_unsigned(len(label), result) + result.extend(label) + return result + + def compute_new_offsets(chunks, offsets): + """ Given a list of chunks, compute the new offsets (by adding the + chunk lengths together). Also check if we cannot shrink the output + further because none of the node offsets are smaller now. if that's + the case return None. """ + new_offsets = {} + curr_offset = 0 + should_continue = False + for node, result in zip(order, chunks): + if curr_offset < offsets[node]: + # the new offset is below the current assumption, this + # means we can shrink the output more + should_continue = True + new_offsets[node] = curr_offset + curr_offset += len(result) + if not should_continue: + return None + return new_offsets + + # assign initial offsets to every node + offsets = {} + for i, node in enumerate(order): + # we don't know position of the edge yet, just use something big as + # the starting position. we'll have to do further iterations anyway, + # but the size is at least a lower limit then + offsets[node] = i * 2 ** 30 + + + # due to the variable integer width encoding of edge targets we need to + # run this to fixpoint. in the process we shrink the output more and + # more until we can't any more. at any point we can stop and use the + # output, but we might need padding zero bytes when joining the chunks + # to have the correct jump distances + last_offsets = None + while 1: + chunks = [compute_chunk(node, offsets) for node in order] + last_offsets = offsets + offsets = compute_new_offsets(chunks, offsets) + if offsets is None: # couldn't shrink + break + + # build the final packed string + total_result = bytearray() + for node, result in zip(order, chunks): + node_offset = last_offsets[node] + if node_offset > len(total_result): + # need to pad to get the offsets correct + padding = b"\x00" * (node_offset - len(total_result)) + total_result.extend(padding) + assert node_offset == len(total_result) + total_result.extend(result) + return bytes(total_result) + + +# ______________________________________________________________________ +# the following functions operate on the packed representation + +def number_add_bits(x, *bits): + for bit in bits: + assert bit == 0 or bit == 1 + x = (x << 1) | bit + return x + +def encode_varint_unsigned(i, res): + # https://en.wikipedia.org/wiki/LEB128 unsigned variant + more = True + startlen = len(res) + if i < 0: + raise ValueError("only positive numbers supported", i) + while more: + lowest7bits = i & 0b1111111 + i >>= 7 + if i == 0: + more = False + else: + lowest7bits |= 0b10000000 + res.append(lowest7bits) + return len(res) - startlen + +def number_split_bits(x, n, acc=()): + if n == 1: + return x >> 1, x & 1 + if n == 2: + return x >> 2, (x >> 1) & 1, x & 1 + assert 0, "implement me!" + +def decode_varint_unsigned(b, index=0): + res = 0 + shift = 0 + while True: + byte = b[index] + res = res | ((byte & 0b1111111) << shift) + index += 1 + shift += 7 + if not (byte & 0b10000000): + return res, index + +def decode_node(packed, node): + x, node = decode_varint_unsigned(packed, node) + node_count, final = number_split_bits(x, 1) + return node_count, final, node + +def decode_edge(packed, edgeindex, prev_child_offset, offset): + x, offset = decode_varint_unsigned(packed, offset) + if x == 0 and edgeindex == 0: + raise KeyError # trying to decode past a final node + child_offset_difference, len1, last_edge = number_split_bits(x, 2) + child_offset = prev_child_offset + child_offset_difference + if len1: + size = 1 + else: + size, offset = decode_varint_unsigned(packed, offset) + return child_offset, last_edge, size, offset + +def _match_edge(packed, s, size, node_offset, stringpos): + if size > 1 and stringpos + size > len(s): + # past the end of the string, can't match + return False + for i in range(size): + if packed[node_offset + i] != s[stringpos + i]: + # if a subsequent char of an edge doesn't match, the word isn't in + # the dawg + if i > 0: + raise KeyError + return False + return True + +def lookup(packed, data, s): + return data[_lookup(packed, s)] + +def _lookup(packed, s): + stringpos = 0 + node_offset = 0 + skipped = 0 # keep track of number of final nodes that we skipped + false = False + while stringpos < len(s): + #print(f"{node_offset=} {stringpos=}") + _, final, edge_offset = decode_node(packed, node_offset) + prev_child_offset = edge_offset + edgeindex = 0 + while 1: + child_offset, last_edge, size, edgelabel_chars_offset = decode_edge(packed, edgeindex, prev_child_offset, edge_offset) + #print(f" {edge_offset=} {child_offset=} {last_edge=} {size=} {edgelabel_chars_offset=}") + edgeindex += 1 + prev_child_offset = child_offset + if _match_edge(packed, s, size, edgelabel_chars_offset, stringpos): + # match + if final: + skipped += 1 + stringpos += size + node_offset = child_offset + break + if last_edge: + raise KeyError + descendant_count, _, _ = decode_node(packed, child_offset) + skipped += descendant_count + edge_offset = edgelabel_chars_offset + size + _, final, _ = decode_node(packed, node_offset) + if final: + return skipped + raise KeyError + +def inverse_lookup(packed, inverse, x): + pos = inverse[x] + return _inverse_lookup(packed, pos) + +def _inverse_lookup(packed, pos): + result = bytearray() + node_offset = 0 + while 1: + node_count, final, edge_offset = decode_node(packed, node_offset) + if final: + if pos == 0: + return bytes(result) + pos -= 1 + prev_child_offset = edge_offset + edgeindex = 0 + while 1: + child_offset, last_edge, size, edgelabel_chars_offset = decode_edge(packed, edgeindex, prev_child_offset, edge_offset) + edgeindex += 1 + prev_child_offset = child_offset + descendant_count, _, _ = decode_node(packed, child_offset) + nextpos = pos - descendant_count + if nextpos < 0: + assert edgelabel_chars_offset >= 0 + result.extend(packed[edgelabel_chars_offset: edgelabel_chars_offset + size]) + node_offset = child_offset + break + elif not last_edge: + pos = nextpos + edge_offset = edgelabel_chars_offset + size + else: + raise KeyError + else: + raise KeyError + + +def build_compression_dawg(ucdata): + d = Dawg() + ucdata.sort() + for name, value in ucdata: + d.insert(name, value) + packed, pos_to_code, reversedict = d.finish() + print("size of dawg [KiB]", round(len(packed) / 1024, 2)) + # check that lookup and inverse_lookup work correctly on the input data + for name, value in ucdata: + assert lookup(packed, pos_to_code, name.encode('ascii')) == value + assert inverse_lookup(packed, reversedict, value) == name.encode('ascii') + return packed, pos_to_code diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 6bf5274551c00a..a5ac09eb96f19a 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -623,120 +623,12 @@ def makeunicodetype(unicode, trace): # unicode name database def makeunicodename(unicode, trace): + from dawg import build_compression_dawg FILE = "Modules/unicodename_db.h" print("--- Preparing", FILE, "...") - # collect names - names = [None] * len(unicode.chars) - - for char in unicode.chars: - record = unicode.table[char] - if record: - name = record.name.strip() - if name and name[0] != "<": - names[char] = name + chr(0) - - print(len([n for n in names if n is not None]), "distinct names") - - # collect unique words from names (note that we differ between - # words inside a sentence, and words ending a sentence. the - # latter includes the trailing null byte. - - words = {} - n = b = 0 - for char in unicode.chars: - name = names[char] - if name: - w = name.split() - b = b + len(name) - n = n + len(w) - for w in w: - l = words.get(w) - if l: - l.append(None) - else: - words[w] = [len(words)] - - print(n, "words in text;", b, "bytes") - - wordlist = list(words.items()) - - # sort on falling frequency, then by name - def word_key(a): - aword, alist = a - return -len(alist), aword - wordlist.sort(key=word_key) - - # figure out how many phrasebook escapes we need - escapes = 0 - while escapes * 256 < len(wordlist): - escapes = escapes + 1 - print(escapes, "escapes") - - short = 256 - escapes - - assert short > 0 - - print(short, "short indexes in lexicon") - - # statistics - n = 0 - for i in range(short): - n = n + len(wordlist[i][1]) - print(n, "short indexes in phrasebook") - - # pick the most commonly used words, and sort the rest on falling - # length (to maximize overlap) - - wordlist, wordtail = wordlist[:short], wordlist[short:] - wordtail.sort(key=lambda a: a[0], reverse=True) - wordlist.extend(wordtail) - - # generate lexicon from words - - lexicon_offset = [0] - lexicon = "" - words = {} - - # build a lexicon string - offset = 0 - for w, x in wordlist: - # encoding: bit 7 indicates last character in word (chr(128) - # indicates the last character in an entire string) - ww = w[:-1] + chr(ord(w[-1])+128) - # reuse string tails, when possible - o = lexicon.find(ww) - if o < 0: - o = offset - lexicon = lexicon + ww - offset = offset + len(w) - words[w] = len(lexicon_offset) - lexicon_offset.append(o) - - lexicon = list(map(ord, lexicon)) - - # generate phrasebook from names and lexicon - phrasebook = [0] - phrasebook_offset = [0] * len(unicode.chars) - for char in unicode.chars: - name = names[char] - if name: - w = name.split() - phrasebook_offset[char] = len(phrasebook) - for w in w: - i = words[w] - if i < short: - phrasebook.append(i) - else: - # store as two bytes - phrasebook.append((i>>8) + short) - phrasebook.append(i&255) - - assert getsize(phrasebook) == 1 - - # # unicode name hash table # extract names @@ -748,12 +640,6 @@ def word_key(a): if name and name[0] != "<": data.append((name, char)) - # the magic number 47 was chosen to minimize the number of - # collisions on the current data set. if you like, change it - # and see what happens... - - codehash = Hash("code", data, 47) - print("--- Writing", FILE, "...") with open(FILE, "w") as fp: @@ -762,24 +648,22 @@ def word_key(a): fprint("/* this file was generated by %s %s */" % (SCRIPT, VERSION)) fprint() fprint("#define NAME_MAXLEN", 256) + assert max(len(x) for x in data) < 256 fprint() - fprint("/* lexicon */") - Array("lexicon", lexicon).dump(fp, trace) - Array("lexicon_offset", lexicon_offset).dump(fp, trace) - - # split decomposition index table - offset1, offset2, shift = splitbins(phrasebook_offset, trace) - - fprint("/* code->name phrasebook */") - fprint("#define phrasebook_shift", shift) - fprint("#define phrasebook_short", short) - - Array("phrasebook", phrasebook).dump(fp, trace) - Array("phrasebook_offset1", offset1).dump(fp, trace) - Array("phrasebook_offset2", offset2).dump(fp, trace) fprint("/* name->code dictionary */") - codehash.dump(fp, trace) + packed_dawg, pos_to_codepoint = build_compression_dawg(data) + notfound = len(pos_to_codepoint) + inverse_list = [notfound] * len(unicode.chars) + for pos, codepoint in enumerate(pos_to_codepoint): + inverse_list[codepoint] = pos + Array("packed_name_dawg", list(packed_dawg)).dump(fp, trace) + Array("dawg_pos_to_codepoint", pos_to_codepoint).dump(fp, trace) + index1, index2, shift = splitbins(inverse_list, trace) + fprint("#define DAWG_CODEPOINT_TO_POS_SHIFT", shift) + fprint("#define DAWG_CODEPOINT_TO_POS_NOTFOUND", notfound) + Array("dawg_codepoint_to_pos_index1", index1).dump(fp, trace) + Array("dawg_codepoint_to_pos_index2", index2).dump(fp, trace) fprint() fprint('static const unsigned int aliases_start = %#x;' % @@ -1188,94 +1072,6 @@ def uselatin1(self): self.chars = list(range(256)) -# hash table tools - -# this is a straight-forward reimplementation of Python's built-in -# dictionary type, using a static data structure, and a custom string -# hash algorithm. - -def myhash(s, magic): - h = 0 - for c in map(ord, s.upper()): - h = (h * magic) + c - ix = h & 0xff000000 - if ix: - h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff - return h - - -SIZES = [ - (4,3), (8,3), (16,3), (32,5), (64,3), (128,3), (256,29), (512,17), - (1024,9), (2048,5), (4096,83), (8192,27), (16384,43), (32768,3), - (65536,45), (131072,9), (262144,39), (524288,39), (1048576,9), - (2097152,5), (4194304,3), (8388608,33), (16777216,27) -] - - -class Hash: - def __init__(self, name, data, magic): - # turn a (key, value) list into a static hash table structure - - # determine table size - for size, poly in SIZES: - if size > len(data): - poly = size + poly - break - else: - raise AssertionError("ran out of polynomials") - - print(size, "slots in hash table") - - table = [None] * size - - mask = size-1 - - n = 0 - - hash = myhash - - # initialize hash table - for key, value in data: - h = hash(key, magic) - i = (~h) & mask - v = table[i] - if v is None: - table[i] = value - continue - incr = (h ^ (h >> 3)) & mask - if not incr: - incr = mask - while 1: - n = n + 1 - i = (i + incr) & mask - v = table[i] - if v is None: - table[i] = value - break - incr = incr << 1 - if incr > mask: - incr = incr ^ poly - - print(n, "collisions") - self.collisions = n - - for i in range(len(table)): - if table[i] is None: - table[i] = 0 - - self.data = Array(name + "_hash", table) - self.magic = magic - self.name = name - self.size = size - self.poly = poly - - def dump(self, file, trace): - # write data to file, as a C array - self.data.dump(file, trace) - file.write("#define %s_magic %d\n" % (self.name, self.magic)) - file.write("#define %s_size %d\n" % (self.name, self.size)) - file.write("#define %s_poly %d\n" % (self.name, self.poly)) - # stuff to deal with arrays of unsigned integers diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index 8ef63c6dcd9ddc..beb857f69e40da 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -298,102 +298,68 @@ AddType application/wasm wasm ## WASI (wasm32-wasi) -WASI builds require the [WASI SDK](/~https://github.com/WebAssembly/wasi-sdk) 16.0+. -See `.devcontainer/Dockerfile` for an example of how to download and -install the WASI SDK. +**NOTE**: The instructions below assume a Unix-based OS due to cross-compilation for CPython being set up for `./configure`. -### Build +### Prerequisites + +Developing for WASI requires two additional tools to be installed beyond the typical tools required to build CPython: + +1. The [WASI SDK](/~https://github.com/WebAssembly/wasi-sdk) 16.0+ +2. A WASI host/runtime ([wasmtime](https://wasmtime.dev) 14+ is recommended and what the instructions below assume) -The script ``wasi-env`` sets necessary compiler and linker flags as well as -``pkg-config`` overrides. The script assumes that WASI-SDK is installed in -``/opt/wasi-sdk`` or ``$WASI_SDK_PATH``. +All of this is provided in the [devcontainer](https://devguide.python.org/getting-started/setup-building/#contribute-using-github-codespaces) if you don't want to install these tools locally. -There are two scripts you can use to do a WASI build from a source checkout. You can either use: +### Building +Building for WASI requires doing a cross-build where you have a "build" Python to help produce a WASI build of CPython (technically it's a "host x host" cross-build because the build Python is also the target Python while the host build is the WASI build; yes, it's confusing terminology). In the end you should have a build Python in `cross-build/build` and a WASI build in `cross-build/wasm32-wasi`. + +The easiest way to do a build is to use the `wasi.py` script. You can either have it perform the entire build process from start to finish in one step, or you can do it in discrete steps that mirror running `configure` and `make` for each of the two builds of Python you end up producing (which are beneficial when you only need to do a specific step after getting a complete build, e.g. editing some code and you just need to run `make` for the WASI build). The script is designed to self-document what actions it is performing on your behalf, both as a way to check its work but also for educaitonal purposes. + +The discrete steps for building via `wasi.py` are: ```shell -./Tools/wasm/wasm_build.py wasi build +python Tools/wasm/wasi.py configure-build-python +python Tools/wasm/wasi.py make-build-python +python Tools/wasm/wasi.py configure-host +python Tools/wasm/wasi.py make-host ``` -or: +To do it all in a single command, run: ```shell -./Tools/wasm/build_wasi.sh +python Tools/wasm/wasi.py build ``` -The commands are equivalent to the following steps: - -- Make sure `Modules/Setup.local` exists -- Make sure the necessary build tools are installed: - - [WASI SDK](/~https://github.com/WebAssembly/wasi-sdk) (which ships with `clang`) - - `make` - - `pkg-config` (on Linux) -- Create the build Python - - `mkdir -p builddir/build` - - `pushd builddir/build` - - Get the build platform - - Python: `sysconfig.get_config_var("BUILD_GNU_TYPE")` - - Shell: `../../config.guess` - - `../../configure -C` - - `make all` - - ```PYTHON_VERSION=`./python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")'` ``` - - `popd` -- Create the host/WASI Python - - `mkdir builddir/wasi` - - `pushd builddir/wasi` - - `../../Tools/wasm/wasi-env ../../configure -C --host=wasm32-unknown-wasi --build=$(../../config.guess) --with-build-python=../build/python` - - `CONFIG_SITE=../../Tools/wasm/config.site-wasm32-wasi` - - `HOSTRUNNER="wasmtime run --mapdir /::$(dirname $(dirname $(pwd))) --env PYTHONPATH=/builddir/wasi/build/lib.wasi-wasm32-$PYTHON_VERSION $(pwd)/python.wasm --"` - - Maps the source checkout to `/` in the WASI runtime - - Stdlib gets loaded from `/Lib` - - Gets `_sysconfigdata__wasi_wasm32-wasi.py` on to `sys.path` via `PYTHONPATH` - - Set by `wasi-env` - - `WASI_SDK_PATH` - - `WASI_SYSROOT` - - `CC` - - `CPP` - - `CXX` - - `LDSHARED` - - `AR` - - `RANLIB` - - `CFLAGS` - - `LDFLAGS` - - `PKG_CONFIG_PATH` - - `PKG_CONFIG_LIBDIR` - - `PKG_CONFIG_SYSROOT_DIR` - - `PATH` - - `make all` - +That will: -### Running - -If you followed the instructions above, you can run the interpreter via e.g., `wasmtime` from within the `Tools/wasi` directory (make sure to set/change `$PYTHON_VERSION` and do note the paths are relative to running in`builddir/wasi` for simplicity only): +1. Run `configure` for the build Python (same as `wasi.py configure-build-python`) +2. Run `make` for the build Python (`wasi.py make-build-python`) +3. Run `configure` for the WASI build (`wasi.py configure-host`) +4. Run `make` for the WASI build (`wasi.py make-host`) +See the `--help` for the various options available for each of the subcommands which controls things like the location of the WASI SDK, the command to use with the WASI host/runtime, etc. Also note that you can use `--` as a separator for any of the `configure`-related commands -- including `build` itself -- to pass arguments to the underlying `configure` call. For example, if you want a pydebug build that also caches the results from `configure`, you can do: ```shell -wasmtime run --mapdir /::../.. --env PYTHONPATH=/builddir/wasi/build/lib.wasi-wasm32-$PYTHON_VERSION python.wasm -- +python Tools/wasm/wasi.py build -- -C --with-pydebug ``` -There are also helpers provided by `Tools/wasm/wasm_build.py` as listed below. Also, if you used `Tools/wasm/build_wasi.sh`, a `run_wasi.sh` file will be created in `builddir/wasi` which will run the above command for you (it also uses absolute paths, so it can be executed from anywhere). - -#### REPL - +The `wasi.py` script is able to infer details from the build Python, and so you only technically need to specify `--with-pydebug` once via `configure-build-python` as this will lead to `configure-host` detecting its use if you use the discrete steps: ```shell -./Tools/wasm/wasm_build.py wasi repl +python Tools/wasm/wasi.py configure-build-python -- -C --with-pydebug +python Tools/wasm/wasi.py make-build-python +python Tools/wasm/wasi.py configure-host -- -C +python Tools/wasm/wasi.py make-host ``` -#### Tests +### Running + +If you used `wasi.py` to do your build then there will be a `cross-build/wasm32-wasi/python.sh` file which you can use to run the `python.wasm` file (see the output from the `configure-host` subcommand): ```shell -./Tools/wasm/wasm_build.py wasi test +cross-build/wasm32-wasi/python.sh --version ``` -### Debugging +While you _can_ run `python.wasm` directly, Python will fail to start up without certain things being set (e.g. `PYTHONPATH` for `sysconfig` data). As such, the `python.sh` file records these details for you. -* ``wasmtime run -g`` generates debugging symbols for gdb and lldb. The - feature is currently broken, see - /~https://github.com/bytecodealliance/wasmtime/issues/4669 . -* The environment variable ``RUST_LOG=wasi_common`` enables debug and - trace logging. -## Detect WebAssembly builds +## Detecting WebAssembly builds ### Python code @@ -402,15 +368,17 @@ import os, sys if sys.platform == "emscripten": # Python on Emscripten + ... if sys.platform == "wasi": # Python on WASI + ... if os.name == "posix": # WASM platforms identify as POSIX-like. # Windows does not provide os.uname(). machine = os.uname().machine if machine.startswith("wasm"): - # WebAssembly (wasm32, wasm64 in the future) + # WebAssembly (wasm32, wasm64 potentially in the future) ``` ```python diff --git a/Tools/wasm/mypy.ini b/Tools/wasm/mypy.ini index c62598f89eba69..4de0a30c260f5f 100644 --- a/Tools/wasm/mypy.ini +++ b/Tools/wasm/mypy.ini @@ -1,5 +1,5 @@ [mypy] -files = Tools/wasm +files = Tools/wasm/wasm_*.py pretty = True show_traceback = True @@ -9,6 +9,3 @@ 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/wasi.py b/Tools/wasm/wasi.py new file mode 100644 index 00000000000000..34c0e9375e24c8 --- /dev/null +++ b/Tools/wasm/wasi.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python3 + +import argparse +import contextlib +import functools +import os +try: + from os import process_cpu_count as cpu_count +except ImportError: + from os import cpu_count +import pathlib +import shutil +import subprocess +import sys +import sysconfig +import tempfile + + +CHECKOUT = pathlib.Path(__file__).parent.parent.parent +CROSS_BUILD_DIR = CHECKOUT / "cross-build" +BUILD_DIR = CROSS_BUILD_DIR / "build" +HOST_TRIPLE = "wasm32-wasi" +HOST_DIR = CROSS_BUILD_DIR / HOST_TRIPLE + + +def updated_env(updates={}): + """Create a new dict representing the environment to use. + + The changes made to the execution environment are printed out. + """ + env_defaults = {} + # https://reproducible-builds.org/docs/source-date-epoch/ + git_epoch_cmd = ["git", "log", "-1", "--pretty=%ct"] + try: + epoch = subprocess.check_output(git_epoch_cmd, encoding="utf-8").strip() + env_defaults["SOURCE_DATE_EPOCH"] = epoch + except subprocess.CalledProcessError: + pass # Might be building from a tarball. + # This layering lets SOURCE_DATE_EPOCH from os.environ takes precedence. + environment = env_defaults | os.environ | updates + + env_diff = {} + for key, value in environment.items(): + if os.environ.get(key) != value: + env_diff[key] = value + + print("🌎 Environment changes:") + for key in sorted(env_diff.keys()): + print(f" {key}={env_diff[key]}") + + return environment + + +def subdir(working_dir, *, clean_ok=False): + """Decorator to change to a working directory.""" + def decorator(func): + @functools.wraps(func) + def wrapper(context): + try: + tput_output = subprocess.check_output(["tput", "cols"], + encoding="utf-8") + terminal_width = int(tput_output.strip()) + except subprocess.CalledProcessError: + terminal_width = 80 + print("⎯" * terminal_width) + print("📁", working_dir) + if clean_ok and context.clean and working_dir.exists(): + print(f"🚮 Deleting directory (--clean)...") + shutil.rmtree(working_dir) + + working_dir.mkdir(parents=True, exist_ok=True) + + with contextlib.chdir(working_dir): + return func(context, working_dir) + + return wrapper + + return decorator + + +def call(command, *, quiet, **kwargs): + """Execute a command. + + If 'quiet' is true, then redirect stdout and stderr to a temporary file. + """ + print("❯", " ".join(map(str, command))) + if not quiet: + stdout = None + stderr = None + else: + stdout = tempfile.NamedTemporaryFile("w", encoding="utf-8", + delete=False, + prefix="cpython-wasi-", + suffix=".log") + stderr = subprocess.STDOUT + print(f"📝 Logging output to {stdout.name} (--quiet)...") + + subprocess.check_call(command, **kwargs, stdout=stdout, stderr=stderr) + + +def build_platform(): + """The name of the build/host platform.""" + # Can also be found via `config.guess`.` + return sysconfig.get_config_var("BUILD_GNU_TYPE") + + +def build_python_path(): + """The path to the build Python binary.""" + binary = BUILD_DIR / "python" + if not binary.is_file(): + binary = binary.with_suffix(".exe") + if not binary.is_file(): + raise FileNotFoundError("Unable to find `python(.exe)` in " + f"{BUILD_DIR}") + + return binary + + +@subdir(BUILD_DIR, clean_ok=True) +def configure_build_python(context, working_dir): + """Configure the build/host Python.""" + local_setup = CHECKOUT / "Modules" / "Setup.local" + if local_setup.exists(): + print(f"👍 {local_setup} exists ...") + else: + print(f"📝 Touching {local_setup} ...") + local_setup.touch() + + configure = [os.path.relpath(CHECKOUT / 'configure', working_dir)] + if context.args: + configure.extend(context.args) + + call(configure, quiet=context.quiet) + + +@subdir(BUILD_DIR) +def make_build_python(context, working_dir): + """Make/build the build Python.""" + call(["make", "--jobs", str(cpu_count()), "all"], + quiet=context.quiet) + + binary = build_python_path() + cmd = [binary, "-c", + "import sys; " + "print(f'{sys.version_info.major}.{sys.version_info.minor}')"] + version = subprocess.check_output(cmd, encoding="utf-8").strip() + + print(f"🎉 {binary} {version}") + + +def find_wasi_sdk(): + """Find the path to wasi-sdk.""" + if wasi_sdk_path := os.environ.get("WASI_SDK_PATH"): + return pathlib.Path(wasi_sdk_path) + elif (default_path := pathlib.Path("/opt/wasi-sdk")).exists(): + return default_path + + +def wasi_sdk_env(context): + """Calculate environment variables for building with wasi-sdk.""" + wasi_sdk_path = context.wasi_sdk_path + sysroot = wasi_sdk_path / "share" / "wasi-sysroot" + env = {"CC": "clang", "CPP": "clang-cpp", "CXX": "clang++", + "LDSHARED": "wasm-ld", "AR": "llvm-ar", "RANLIB": "ranlib"} + + for env_var, binary_name in list(env.items()): + env[env_var] = os.fsdecode(wasi_sdk_path / "bin" / binary_name) + + if wasi_sdk_path != pathlib.Path("/opt/wasi-sdk"): + for compiler in ["CC", "CPP", "CXX"]: + env[compiler] += f" --sysroot={sysroot}" + + env["PKG_CONFIG_PATH"] = "" + env["PKG_CONFIG_LIBDIR"] = os.pathsep.join( + map(os.fsdecode, + [sysroot / "lib" / "pkgconfig", + sysroot / "share" / "pkgconfig"])) + env["PKG_CONFIG_SYSROOT_DIR"] = os.fsdecode(sysroot) + + env["WASI_SDK_PATH"] = os.fsdecode(wasi_sdk_path) + env["WASI_SYSROOT"] = os.fsdecode(sysroot) + + env["PATH"] = os.pathsep.join([os.fsdecode(wasi_sdk_path / "bin"), + os.environ["PATH"]]) + + return env + + +@subdir(HOST_DIR, clean_ok=True) +def configure_wasi_python(context, working_dir): + """Configure the WASI/host build.""" + if not context.wasi_sdk_path or not context.wasi_sdk_path.exists(): + raise ValueError("WASI-SDK not found; " + "download from " + "/~https://github.com/WebAssembly/wasi-sdk and/or " + "specify via $WASI_SDK_PATH or --wasi-sdk") + + config_site = os.fsdecode(CHECKOUT / "Tools" / "wasm" / "config.site-wasm32-wasi") + + wasi_build_dir = working_dir.relative_to(CHECKOUT) + + python_build_dir = BUILD_DIR / "build" + lib_dirs = list(python_build_dir.glob("lib.*")) + assert len(lib_dirs) == 1, f"Expected a single lib.* directory in {python_build_dir}" + lib_dir = os.fsdecode(lib_dirs[0]) + pydebug = lib_dir.endswith("-pydebug") + python_version = lib_dir.removesuffix("-pydebug").rpartition("-")[-1] + sysconfig_data = f"{wasi_build_dir}/build/lib.wasi-wasm32-{python_version}" + if pydebug: + sysconfig_data += "-pydebug" + + # Use PYTHONPATH to include sysconfig data which must be anchored to the + # WASI guest's `/` directory. + host_runner = context.host_runner.format(GUEST_DIR="/", + HOST_DIR=CHECKOUT, + ENV_VAR_NAME="PYTHONPATH", + ENV_VAR_VALUE=f"/{sysconfig_data}", + PYTHON_WASM=working_dir / "python.wasm") + env_additions = {"CONFIG_SITE": config_site, "HOSTRUNNER": host_runner} + build_python = os.fsdecode(build_python_path()) + # The path to `configure` MUST be relative, else `python.wasm` is unable + # to find the stdlib due to Python not recognizing that it's being + # executed from within a checkout. + configure = [os.path.relpath(CHECKOUT / 'configure', working_dir), + f"--host={HOST_TRIPLE}", + f"--build={build_platform()}", + f"--with-build-python={build_python}"] + if pydebug: + configure.append("--with-pydebug") + if context.args: + configure.extend(context.args) + call(configure, + env=updated_env(env_additions | wasi_sdk_env(context)), + quiet=context.quiet) + + exec_script = working_dir / "python.sh" + with exec_script.open("w", encoding="utf-8") as file: + file.write(f'#!/bin/sh\nexec {host_runner} "$@"\n') + exec_script.chmod(0o755) + print(f"🏃‍♀️ Created {exec_script} ... ") + sys.stdout.flush() + + +@subdir(HOST_DIR) +def make_wasi_python(context, working_dir): + """Run `make` for the WASI/host build.""" + call(["make", "--jobs", str(cpu_count()), "all"], + env=updated_env(), + quiet=context.quiet) + + exec_script = working_dir / "python.sh" + subprocess.check_call([exec_script, "--version"]) + + +def build_all(context): + """Build everything.""" + steps = [configure_build_python, make_build_python, configure_wasi_python, + make_wasi_python] + for step in steps: + step(context) + + +def main(): + default_host_runner = (f"{shutil.which('wasmtime')} run " + # Make sure the stack size will work for a pydebug + # build. + # The 8388608 value comes from `ulimit -s` under Linux + # which equates to 8291 KiB. + "--wasm max-wasm-stack=8388608 " + # Enable thread support. + "--wasm threads=y --wasi threads=y " + # Map the checkout to / to load the stdlib from /Lib. + "--dir {HOST_DIR}::{GUEST_DIR} " + # Set PYTHONPATH to the sysconfig data. + "--env {ENV_VAR_NAME}={ENV_VAR_VALUE} " + # Path to the WASM binary. + "{PYTHON_WASM}") + + parser = argparse.ArgumentParser() + subcommands = parser.add_subparsers(dest="subcommand") + build = subcommands.add_parser("build", help="Build everything") + configure_build = subcommands.add_parser("configure-build-python", + help="Run `configure` for the " + "build Python") + make_build = subcommands.add_parser("make-build-python", + help="Run `make` for the build Python") + configure_host = subcommands.add_parser("configure-host", + help="Run `configure` for the " + "host/WASI (pydebug builds " + "are inferred from the build " + "Python)") + make_host = subcommands.add_parser("make-host", + help="Run `make` for the host/WASI") + for subcommand in build, configure_build, make_build, configure_host, make_host: + subcommand.add_argument("--quiet", action="store_true", default=False, + dest="quiet", + help="Redirect output from subprocesses to a log file") + for subcommand in build, configure_build, configure_host: + subcommand.add_argument("--clean", action="store_true", default=False, + dest="clean", + help="Delete any relevant directories before building") + for subcommand in build, configure_build, configure_host: + subcommand.add_argument("args", nargs="*", + help="Extra arguments to pass to `configure`") + for subcommand in build, configure_host: + subcommand.add_argument("--wasi-sdk", type=pathlib.Path, + dest="wasi_sdk_path", + default=find_wasi_sdk(), + help="Path to wasi-sdk; defaults to " + "$WASI_SDK_PATH or /opt/wasi-sdk") + subcommand.add_argument("--host-runner", action="store", + default=default_host_runner, dest="host_runner", + help="Command template for running the WebAssembly " + "code (default meant for wasmtime 14 or newer: " + f"`{default_host_runner}`)") + + context = parser.parse_args() + + dispatch = {"configure-build-python": configure_build_python, + "make-build-python": make_build_python, + "configure-host": configure_wasi_python, + "make-host": make_wasi_python, + "build": build_all} + dispatch[context.subcommand](context) + + +if __name__ == "__main__": + main() diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py index 3558ecd869dfc5..c0b9999a5dad03 100755 --- a/Tools/wasm/wasm_build.py +++ b/Tools/wasm/wasm_build.py @@ -516,7 +516,11 @@ def make_cmd(self) -> List[str]: 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: diff --git a/aclocal.m4 b/aclocal.m4 index da8ee95b9c7f6b..09ae5d1aa8a608 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.16.4 -*- Autoconf -*- +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. @@ -276,7 +276,7 @@ AC_DEFUN([AX_CHECK_OPENSSL], [ ]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 11 (pkg-config-0.29.1) +# serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -318,7 +318,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) +[m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -419,7 +419,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -429,11 +429,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -450,7 +450,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -551,74 +551,6 @@ AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR -dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, -dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], -dnl [DESCRIPTION], [DEFAULT]) -dnl ------------------------------------------ -dnl -dnl Prepare a "--with-" configure option using the lowercase -dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and -dnl PKG_CHECK_MODULES in a single macro. -AC_DEFUN([PKG_WITH_MODULES], -[ -m4_pushdef([with_arg], m4_tolower([$1])) - -m4_pushdef([description], - [m4_default([$5], [build with ]with_arg[ support])]) - -m4_pushdef([def_arg], [m4_default([$6], [auto])]) -m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) -m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) - -m4_case(def_arg, - [yes],[m4_pushdef([with_without], [--without-]with_arg)], - [m4_pushdef([with_without],[--with-]with_arg)]) - -AC_ARG_WITH(with_arg, - AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, - [AS_TR_SH([with_]with_arg)=def_arg]) - -AS_CASE([$AS_TR_SH([with_]with_arg)], - [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], - [auto],[PKG_CHECK_MODULES([$1],[$2], - [m4_n([def_action_if_found]) $3], - [m4_n([def_action_if_not_found]) $4])]) - -m4_popdef([with_arg]) -m4_popdef([description]) -m4_popdef([def_arg]) - -])dnl PKG_WITH_MODULES - -dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, -dnl [DESCRIPTION], [DEFAULT]) -dnl ----------------------------------------------- -dnl -dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES -dnl check._[VARIABLE-PREFIX] is exported as make variable. -AC_DEFUN([PKG_HAVE_WITH_MODULES], -[ -PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) - -AM_CONDITIONAL([HAVE_][$1], - [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) -])dnl PKG_HAVE_WITH_MODULES - -dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, -dnl [DESCRIPTION], [DEFAULT]) -dnl ------------------------------------------------------ -dnl -dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after -dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make -dnl and preprocessor variable. -AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], -[ -PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) - -AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], - [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) -])dnl PKG_HAVE_DEFINE_WITH_MODULES - # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. diff --git a/configure b/configure index 0e5f3f64c680b2..668a0efd77db0e 100755 --- a/configure +++ b/configure @@ -769,6 +769,8 @@ MODULE__MULTIPROCESSING_FALSE MODULE__MULTIPROCESSING_TRUE MODULE__ZONEINFO_FALSE MODULE__ZONEINFO_TRUE +MODULE__XXINTERPQUEUES_FALSE +MODULE__XXINTERPQUEUES_TRUE MODULE__XXINTERPCHANNELS_FALSE MODULE__XXINTERPCHANNELS_TRUE MODULE__XXSUBINTERPRETERS_FALSE @@ -860,6 +862,8 @@ DTRACE_OBJS DTRACE_HEADERS DFLAGS DTRACE +WITH_MIMALLOC +MIMALLOC_HEADERS GDBM_LIBS GDBM_CFLAGS X11_LIBS @@ -1088,6 +1092,7 @@ enable_loadable_sqlite_extensions with_dbmliborder enable_ipv6 with_doc_strings +with_mimalloc with_pymalloc with_freelists with_c_locale_coercion @@ -1874,6 +1879,8 @@ Optional Packages: value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'. --with-doc-strings enable documentation strings (default is yes) + --with-mimalloc build with mimalloc memory allocator (default is yes + if C11 stdatomic.h is available.) --with-pymalloc enable specialized mallocs (default is yes) --with-freelists enable object freelists (default is yes) --with-c-locale-coercion @@ -4284,6 +4291,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; } @@ -7869,7 +7885,7 @@ printf "%s\n" "$disable_gil" >&6; } if test "$disable_gil" = "yes" then -printf "%s\n" "#define Py_NOGIL 1" >>confdefs.h +printf "%s\n" "#define Py_GIL_DISABLED 1" >>confdefs.h # Add "t" for "threaded" ABIFLAGS="${ABIFLAGS}t" @@ -9259,10 +9275,15 @@ then : # without this, configure fails to find pthread_create, sem_init, # etc because they are only available in the sysroot for # wasm32-wasi-threads. + # Note: wasi-threads requires --import-memory. + # Note: wasi requires --export-memory. + # Note: --export-memory is implicit unless --import-memory is given + # Note: this requires LLVM >= 16. as_fn_append CFLAGS " -target wasm32-wasi-threads -pthread" as_fn_append CFLAGS_NODIST " -target wasm32-wasi-threads -pthread" as_fn_append LDFLAGS_NODIST " -target wasm32-wasi-threads -pthread" as_fn_append LDFLAGS_NODIST " -Wl,--import-memory" + as_fn_append LDFLAGS_NODIST " -Wl,--export-memory" as_fn_append LDFLAGS_NODIST " -Wl,--max-memory=10485760" fi @@ -10709,6 +10730,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 @@ -13015,8 +13042,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBUUID" >&5 -printf %s "checking for LIBUUID... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid >= 2.20" >&5 +printf %s "checking for uuid >= 2.20... " >&6; } if test -n "$LIBUUID_CFLAGS"; then pkg_cv_LIBUUID_CFLAGS="$LIBUUID_CFLAGS" @@ -13056,7 +13083,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -13196,7 +13223,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -13904,8 +13931,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBFFI" >&5 -printf %s "checking for LIBFFI... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libffi" >&5 +printf %s "checking for libffi... " >&6; } if test -n "$LIBFFI_CFLAGS"; then pkg_cv_LIBFFI_CFLAGS="$LIBFFI_CFLAGS" @@ -13945,7 +13972,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -14032,7 +14059,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -14436,8 +14463,8 @@ fi pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBSQLITE3" >&5 -printf %s "checking for LIBSQLITE3... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3 >= 3.15.2" >&5 +printf %s "checking for sqlite3 >= 3.15.2... " >&6; } if test -n "$LIBSQLITE3_CFLAGS"; then pkg_cv_LIBSQLITE3_CFLAGS="$LIBSQLITE3_CFLAGS" @@ -14477,7 +14504,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -14499,7 +14526,7 @@ fi elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} @@ -15200,8 +15227,8 @@ for _QUERY in \ pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for TCLTK" >&5 -printf %s "checking for TCLTK... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $_QUERY" >&5 +printf %s "checking for $_QUERY... " >&6; } if test -n "$TCLTK_CFLAGS"; then pkg_cv_TCLTK_CFLAGS="$TCLTK_CFLAGS" @@ -15241,7 +15268,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -15259,7 +15286,7 @@ fi found_tcltk=no elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } found_tcltk=no else @@ -15297,8 +15324,8 @@ case $ac_sys_system in #( pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 -printf %s "checking for X11... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x11" >&5 +printf %s "checking for x11... " >&6; } if test -n "$X11_CFLAGS"; then pkg_cv_X11_CFLAGS="$X11_CFLAGS" @@ -15338,7 +15365,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -15365,7 +15392,7 @@ Alternatively, you may set the environment variables X11_CFLAGS and X11_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} @@ -16752,6 +16779,129 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_doc_strings" >&5 printf "%s\n" "$with_doc_strings" >&6; } +# Check for stdatomic.h, required for mimalloc. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5 +printf %s "checking for stdatomic.h... " >&6; } +if test ${ac_cv_header_stdatomic_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + atomic_int int_var; + atomic_uintptr_t uintptr_var; + int main() { + atomic_store_explicit(&int_var, 5, memory_order_relaxed); + atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); + int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_header_stdatomic_h=yes +else $as_nop + ac_cv_header_stdatomic_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdatomic_h" >&5 +printf "%s\n" "$ac_cv_header_stdatomic_h" >&6; } + +if test "x$ac_cv_header_stdatomic_h" = xyes +then : + + +printf "%s\n" "#define HAVE_STD_ATOMIC 1" >>confdefs.h + + +fi + +# Check for GCC >= 4.7 and clang __atomic builtin functions +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for builtin __atomic_load_n and __atomic_store_n functions" >&5 +printf %s "checking for builtin __atomic_load_n and __atomic_store_n functions... " >&6; } +if test ${ac_cv_builtin_atomic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + int val; + int main() { + __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); + (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); + return 0; + } + + +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_builtin_atomic=yes +else $as_nop + ac_cv_builtin_atomic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_builtin_atomic" >&5 +printf "%s\n" "$ac_cv_builtin_atomic" >&6; } + +if test "x$ac_cv_builtin_atomic" = xyes +then : + + +printf "%s\n" "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h + + +fi + +# --with-mimalloc +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-mimalloc" >&5 +printf %s "checking for --with-mimalloc... " >&6; } + +# Check whether --with-mimalloc was given. +if test ${with_mimalloc+y} +then : + withval=$with_mimalloc; +else $as_nop + with_mimalloc="$ac_cv_header_stdatomic_h" + +fi + + +if test "$with_mimalloc" != no; then + if test "$ac_cv_header_stdatomic_h" != yes; then + # mimalloc-atomic.h wants C11 stdatomic.h on POSIX + as_fn_error $? "mimalloc requires stdatomic.h, use --without-mimalloc to disable mimalloc." "$LINENO" 5 + fi + with_mimalloc=yes + +printf "%s\n" "#define WITH_MIMALLOC 1" >>confdefs.h + + MIMALLOC_HEADERS='$(MIMALLOC_HEADERS)' + +elif test "$disable_gil" = "yes"; then + as_fn_error $? "--disable-gil requires mimalloc memory allocator (--with-mimalloc)." "$LINENO" 5 +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_mimalloc" >&5 +printf "%s\n" "$with_mimalloc" >&6; } + + + # Check for Python-specific malloc support { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc" >&5 printf %s "checking for --with-pymalloc... " >&6; } @@ -17077,6 +17227,12 @@ if test "x$ac_cv_func_clock" = xyes then : printf "%s\n" "#define HAVE_CLOCK 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "closefrom" "ac_cv_func_closefrom" +if test "x$ac_cv_func_closefrom" = xyes +then : + printf "%s\n" "#define HAVE_CLOSEFROM 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "close_range" "ac_cv_func_close_range" if test "x$ac_cv_func_close_range" = xyes @@ -18781,6 +18937,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 @@ -19252,8 +19452,8 @@ fi pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 -printf %s "checking for ZLIB... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib >= 1.2.0" >&5 +printf %s "checking for zlib >= 1.2.0... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" @@ -19293,7 +19493,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19436,7 +19636,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -19600,8 +19800,8 @@ fi pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZIP2" >&5 -printf %s "checking for BZIP2... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bzip2" >&5 +printf %s "checking for bzip2... " >&6; } if test -n "$BZIP2_CFLAGS"; then pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" @@ -19641,7 +19841,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19737,7 +19937,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -19828,8 +20028,8 @@ fi pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5 -printf %s "checking for LIBLZMA... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for liblzma" >&5 +printf %s "checking for liblzma... " >&6; } if test -n "$LIBLZMA_CFLAGS"; then pkg_cv_LIBLZMA_CFLAGS="$LIBLZMA_CFLAGS" @@ -19869,7 +20069,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19965,7 +20165,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -23781,7 +23981,6 @@ fi - # Check whether --with-readline was given. if test ${with_readline+y} then : @@ -23804,29 +24003,13 @@ 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 : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBREADLINE" >&5 -printf %s "checking for LIBREADLINE... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline" >&5 +printf %s "checking for readline... " >&6; } if test -n "$LIBREADLINE_CFLAGS"; then pkg_cv_LIBREADLINE_CFLAGS="$LIBREADLINE_CFLAGS" @@ -23866,7 +24049,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -23959,7 +24142,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -24056,8 +24239,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBEDIT" >&5 -printf %s "checking for LIBEDIT... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libedit" >&5 +printf %s "checking for libedit... " >&6; } if test -n "$LIBEDIT_CFLAGS"; then pkg_cv_LIBEDIT_CFLAGS="$LIBEDIT_CFLAGS" @@ -24097,7 +24280,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -24192,7 +24375,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -24618,6 +24801,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 @@ -24925,8 +25127,8 @@ then : if test "$ac_sys_system" != "Darwin"; then pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CURSES" >&5 -printf %s "checking for CURSES... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncursesw" >&5 +printf %s "checking for ncursesw... " >&6; } if test -n "$CURSES_CFLAGS"; then pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" @@ -24966,7 +25168,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -25044,7 +25246,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -25125,8 +25327,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CURSES" >&5 -printf %s "checking for CURSES... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5 +printf %s "checking for ncurses... " >&6; } if test -n "$CURSES_CFLAGS"; then pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" @@ -25166,7 +25368,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -25242,7 +25444,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -25319,7 +25521,7 @@ fi fi CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') -if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then +if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1" printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h @@ -25360,8 +25562,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PANEL" >&5 -printf %s "checking for PANEL... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panelw" >&5 +printf %s "checking for panelw... " >&6; } if test -n "$PANEL_CFLAGS"; then pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" @@ -25401,7 +25603,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -25477,7 +25679,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -25556,8 +25758,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PANEL" >&5 -printf %s "checking for PANEL... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panel" >&5 +printf %s "checking for panel... " >&6; } if test -n "$PANEL_CFLAGS"; then pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" @@ -25597,7 +25799,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -25673,7 +25875,7 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS @@ -26600,7 +26802,11 @@ SRCDIRS="\ Modules/cjkcodecs \ Modules/expat \ Objects \ + Objects/mimalloc \ + Objects/mimalloc/prim \ Parser \ + Parser/tokenizer \ + Parser/lexer \ Programs \ Python \ Python/frozen_modules \ @@ -26756,95 +26962,6 @@ printf "%s\n" "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h esac fi -# Check for stdatomic.h -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5 -printf %s "checking for stdatomic.h... " >&6; } -if test ${ac_cv_header_stdatomic_h+y} -then : - printf %s "(cached) " >&6 -else $as_nop - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - atomic_int int_var; - atomic_uintptr_t uintptr_var; - int main(void) { - atomic_store_explicit(&int_var, 5, memory_order_relaxed); - atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); - int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); - return 0; - } - - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_header_stdatomic_h=yes -else $as_nop - ac_cv_header_stdatomic_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdatomic_h" >&5 -printf "%s\n" "$ac_cv_header_stdatomic_h" >&6; } - -if test "x$ac_cv_header_stdatomic_h" = xyes -then : - - -printf "%s\n" "#define HAVE_STD_ATOMIC 1" >>confdefs.h - - -fi - -# Check for GCC >= 4.7 and clang __atomic builtin functions -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for builtin __atomic_load_n and __atomic_store_n functions" >&5 -printf %s "checking for builtin __atomic_load_n and __atomic_store_n functions... " >&6; } -if test ${ac_cv_builtin_atomic+y} -then : - printf %s "(cached) " >&6 -else $as_nop - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - int val; - int main(void) { - __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); - (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); - return 0; - } - - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_builtin_atomic=yes -else $as_nop - ac_cv_builtin_atomic=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_builtin_atomic" >&5 -printf "%s\n" "$ac_cv_builtin_atomic" >&6; } - -if test "x$ac_cv_builtin_atomic" = xyes -then : - - -printf "%s\n" "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h - - -fi - # ensurepip option { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ensurepip" >&5 printf %s "checking for ensurepip... " >&6; } @@ -27664,8 +27781,8 @@ then : pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBB2" >&5 -printf %s "checking for LIBB2... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libb2" >&5 +printf %s "checking for libb2... " >&6; } if test -n "$LIBB2_CFLAGS"; then pkg_cv_LIBB2_CFLAGS="$LIBB2_CFLAGS" @@ -27705,7 +27822,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -27723,7 +27840,7 @@ fi have_libb2=no elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } have_libb2=no else @@ -27778,6 +27895,9 @@ printf "%s\n" "$TEST_MODULES" >&6; } # libatomic __atomic_fetch_or_8(), or not, depending on the C compiler and the # compiler flags. # +# gh-112779: On RISC-V, GCC 12 and earlier require libatomic support for 1-byte +# and 2-byte operations, but not for 8-byte operations. +# # 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 @@ -27817,12 +27937,19 @@ typedef intptr_t Py_ssize_t; int main() { - uint64_t byte; - _Py_atomic_store_uint64(&byte, 2); - if (_Py_atomic_or_uint64(&byte, 8) != 2) { + uint64_t value; + _Py_atomic_store_uint64(&value, 2); + if (_Py_atomic_or_uint64(&value, 8) != 2) { return 1; // error } - if (_Py_atomic_load_uint64(&byte) != 10) { + if (_Py_atomic_load_uint64(&value) != 10) { + return 1; // error + } + uint8_t byte = 0xb8; + if (_Py_atomic_or_uint8(&byte, 0x2d) != 0xb8) { + return 1; // error + } + if (_Py_atomic_load_uint8(&byte) != 0xbd) { return 1; // error } return 0; // all good @@ -27846,6 +27973,7 @@ printf "%s\n" "$ac_cv_libatomic_needed" >&6; } if test "x$ac_cv_libatomic_needed" = xyes then : LIBS="${LIBS} -latomic" + LIBATOMIC=${LIBATOMIC-"-latomic"} fi CPPFLAGS=$save_CPPFLAGS @@ -27899,6 +28027,7 @@ case $ac_sys_system in #( py_cv_module__tkinter=n/a py_cv_module__xxsubinterpreters=n/a py_cv_module__xxinterpchannels=n/a + py_cv_module__xxinterpqueues=n/a py_cv_module_grp=n/a py_cv_module_pwd=n/a py_cv_module_resource=n/a @@ -28398,6 +28527,28 @@ then : +fi + + + if test "$py_cv_module__xxinterpqueues" != "n/a" +then : + py_cv_module__xxinterpqueues=yes +fi + if test "$py_cv_module__xxinterpqueues" = yes; then + MODULE__XXINTERPQUEUES_TRUE= + MODULE__XXINTERPQUEUES_FALSE='#' +else + MODULE__XXINTERPQUEUES_TRUE='#' + MODULE__XXINTERPQUEUES_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__XXINTERPQUEUES_STATE=$py_cv_module__xxinterpqueues$as_nl" + if test "x$py_cv_module__xxinterpqueues" = xyes +then : + + + + fi @@ -29999,7 +30150,7 @@ fi then : - + as_fn_append MODULE_BLOCK "MODULE__TESTCAPI_LDFLAGS=$LIBATOMIC$as_nl" fi if test "$py_cv_module__testcapi" = yes; then @@ -30634,6 +30785,10 @@ if test -z "${MODULE__XXINTERPCHANNELS_TRUE}" && test -z "${MODULE__XXINTERPCHAN as_fn_error $? "conditional \"MODULE__XXINTERPCHANNELS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__XXINTERPQUEUES_TRUE}" && test -z "${MODULE__XXINTERPQUEUES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__XXINTERPQUEUES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__ZONEINFO_TRUE}" && test -z "${MODULE__ZONEINFO_FALSE}"; then as_fn_error $? "conditional \"MODULE__ZONEINFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -32107,3 +32262,8 @@ CPython core team, see https://peps.python.org/pep-0011/ for more information. " >&2;} fi +if test "$ac_cv_header_stdatomic_h" != "yes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Your compiler or platform does have a working C11 stdatomic.h. A future version of Python may require stdatomic.h." >&5 +printf "%s\n" "$as_me: Your compiler or platform does have a working C11 stdatomic.h. A future version of Python may require stdatomic.h." >&6;} +fi + diff --git a/configure.ac b/configure.ac index 493868130414ee..020553abd71b4f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,15 +1,12 @@ -dnl *************************************************** -dnl * Please run autoreconf -if to test your changes! * -dnl *************************************************** +dnl ************************************************************ +dnl * Please run autoreconf -ivf -Werror to test your changes! * +dnl ************************************************************ dnl dnl Python's configure script requires autoconf 2.71, autoconf-archive, -dnl pkgconf's m4 macros. +dnl aclocal 1.16, and pkg-config. dnl -dnl It is recommended to use a cpython_autoconf container to regenerate the -dnl configure script: -dnl -dnl podman run --rm --pull=always -v $(pwd):/src:Z quay.io/tiran/cpython_autoconf:271 -dnl docker run --rm --pull=always -v $(pwd):/src quay.io/tiran/cpython_autoconf:271 +dnl It is recommended to use the Tools/build/regen-configure.sh shell script +dnl to regenerate the configure script. dnl # Set VERSION so we only need to edit in one place (i.e., here) @@ -590,6 +587,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"]) @@ -1500,7 +1505,7 @@ AC_MSG_RESULT([$disable_gil]) if test "$disable_gil" = "yes" then - AC_DEFINE([Py_NOGIL], [1], + AC_DEFINE([Py_GIL_DISABLED], [1], [Define if you want to disable the GIL]) # Add "t" for "threaded" ABIFLAGS="${ABIFLAGS}t" @@ -2154,10 +2159,15 @@ AS_CASE([$ac_sys_system], # without this, configure fails to find pthread_create, sem_init, # etc because they are only available in the sysroot for # wasm32-wasi-threads. + # Note: wasi-threads requires --import-memory. + # Note: wasi requires --export-memory. + # Note: --export-memory is implicit unless --import-memory is given + # Note: this requires LLVM >= 16. AS_VAR_APPEND([CFLAGS], [" -target wasm32-wasi-threads -pthread"]) AS_VAR_APPEND([CFLAGS_NODIST], [" -target wasm32-wasi-threads -pthread"]) AS_VAR_APPEND([LDFLAGS_NODIST], [" -target wasm32-wasi-threads -pthread"]) AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--import-memory"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--export-memory"]) AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--max-memory=10485760"]) ]) @@ -2691,7 +2701,7 @@ AC_CHECK_HEADERS([ \ 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 \ ]) @@ -4489,6 +4499,73 @@ then fi AC_MSG_RESULT([$with_doc_strings]) +# Check for stdatomic.h, required for mimalloc. +AC_CACHE_CHECK([for stdatomic.h], [ac_cv_header_stdatomic_h], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + #include + atomic_int int_var; + atomic_uintptr_t uintptr_var; + int main() { + atomic_store_explicit(&int_var, 5, memory_order_relaxed); + atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); + int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); + return 0; + } + ]]) +],[ac_cv_header_stdatomic_h=yes],[ac_cv_header_stdatomic_h=no]) +]) + +AS_VAR_IF([ac_cv_header_stdatomic_h], [yes], [ + AC_DEFINE(HAVE_STD_ATOMIC, 1, + [Has stdatomic.h with atomic_int and atomic_uintptr_t]) +]) + +# Check for GCC >= 4.7 and clang __atomic builtin functions +AC_CACHE_CHECK([for builtin __atomic_load_n and __atomic_store_n functions], [ac_cv_builtin_atomic], [ +AC_LINK_IFELSE( +[ + AC_LANG_SOURCE([[ + int val; + int main() { + __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); + (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); + return 0; + } + ]]) +],[ac_cv_builtin_atomic=yes],[ac_cv_builtin_atomic=no]) +]) + +AS_VAR_IF([ac_cv_builtin_atomic], [yes], [ + AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Has builtin __atomic_load_n() and __atomic_store_n() functions]) +]) + +# --with-mimalloc +AC_MSG_CHECKING([for --with-mimalloc]) +AC_ARG_WITH([mimalloc], + [AS_HELP_STRING([--with-mimalloc], + [build with mimalloc memory allocator (default is yes if C11 stdatomic.h is available.)])], + [], + [with_mimalloc="$ac_cv_header_stdatomic_h"] +) + +if test "$with_mimalloc" != no; then + if test "$ac_cv_header_stdatomic_h" != yes; then + # mimalloc-atomic.h wants C11 stdatomic.h on POSIX + AC_MSG_ERROR([mimalloc requires stdatomic.h, use --without-mimalloc to disable mimalloc.]) + fi + with_mimalloc=yes + AC_DEFINE([WITH_MIMALLOC], [1], [Define if you want to compile in mimalloc memory allocator.]) + AC_SUBST([MIMALLOC_HEADERS], ['$(MIMALLOC_HEADERS)']) +elif test "$disable_gil" = "yes"; then + AC_MSG_ERROR([--disable-gil requires mimalloc memory allocator (--with-mimalloc).]) +fi + +AC_MSG_RESULT([$with_mimalloc]) +AC_SUBST([WITH_MIMALLOC]) +AC_SUBST([MIMALLOC_HEADERS]) + # Check for Python-specific malloc support AC_MSG_CHECKING([for --with-pymalloc]) AC_ARG_WITH( @@ -4668,7 +4745,7 @@ fi # checks for library functions AC_CHECK_FUNCS([ \ - accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \ + accept4 alarm bind_textdomain_codeset chmod chown clock closefrom close_range confstr \ copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ @@ -4744,6 +4821,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 @@ -5832,7 +5916,6 @@ 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], @@ -5849,15 +5932,6 @@ 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 @@ -5992,6 +6066,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() ]) @@ -6198,9 +6279,11 @@ dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets dnl the macro to 700. CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') -if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then +if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. - dnl If we are here, we found a locally-supplied version of libncursesw. + dnl System-supplied ncurses combines libncurses/libpanel and supports wide + dnl characters, so we can use it like ncursesw. + dnl If a locally-supplied version of libncursesw is found, we will use that. dnl There should also be a libpanelw. dnl _XOPEN_SOURCE defines are usually excluded for macOS, but we need dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support. @@ -6503,7 +6586,11 @@ SRCDIRS="\ Modules/cjkcodecs \ Modules/expat \ Objects \ + Objects/mimalloc \ + Objects/mimalloc/prim \ Parser \ + Parser/tokenizer \ + Parser/lexer \ Programs \ Python \ Python/frozen_modules \ @@ -6598,49 +6685,6 @@ if test "$ac_cv_gcc_asm_for_x87" = yes; then esac fi -# Check for stdatomic.h -AC_CACHE_CHECK([for stdatomic.h], [ac_cv_header_stdatomic_h], [ -AC_LINK_IFELSE( -[ - AC_LANG_SOURCE([[ - #include - atomic_int int_var; - atomic_uintptr_t uintptr_var; - int main(void) { - atomic_store_explicit(&int_var, 5, memory_order_relaxed); - atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); - int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); - return 0; - } - ]]) -],[ac_cv_header_stdatomic_h=yes],[ac_cv_header_stdatomic_h=no]) -]) - -AS_VAR_IF([ac_cv_header_stdatomic_h], [yes], [ - AC_DEFINE([HAVE_STD_ATOMIC], [1], - [Has stdatomic.h with atomic_int and atomic_uintptr_t]) -]) - -# Check for GCC >= 4.7 and clang __atomic builtin functions -AC_CACHE_CHECK([for builtin __atomic_load_n and __atomic_store_n functions], [ac_cv_builtin_atomic], [ -AC_LINK_IFELSE( -[ - AC_LANG_SOURCE([[ - int val; - int main(void) { - __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); - (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); - return 0; - } - ]]) -],[ac_cv_builtin_atomic=yes],[ac_cv_builtin_atomic=no]) -]) - -AS_VAR_IF([ac_cv_builtin_atomic], [yes], [ - AC_DEFINE([HAVE_BUILTIN_ATOMIC], [1], - [Has builtin __atomic_load_n() and __atomic_store_n() functions]) -]) - # ensurepip option AC_MSG_CHECKING([for ensurepip]) AC_ARG_WITH([ensurepip], @@ -6981,6 +7025,9 @@ AC_SUBST([TEST_MODULES]) # libatomic __atomic_fetch_or_8(), or not, depending on the C compiler and the # compiler flags. # +# gh-112779: On RISC-V, GCC 12 and earlier require libatomic support for 1-byte +# and 2-byte operations, but not for 8-byte operations. +# # 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 @@ -7010,12 +7057,19 @@ typedef intptr_t Py_ssize_t; int main() { - uint64_t byte; - _Py_atomic_store_uint64(&byte, 2); - if (_Py_atomic_or_uint64(&byte, 8) != 2) { + uint64_t value; + _Py_atomic_store_uint64(&value, 2); + if (_Py_atomic_or_uint64(&value, 8) != 2) { return 1; // error } - if (_Py_atomic_load_uint64(&byte) != 10) { + if (_Py_atomic_load_uint64(&value) != 10) { + return 1; // error + } + uint8_t byte = 0xb8; + if (_Py_atomic_or_uint8(&byte, 0x2d) != 0xb8) { + return 1; // error + } + if (_Py_atomic_load_uint8(&byte) != 0xbd) { return 1; // error } return 0; // all good @@ -7027,7 +7081,8 @@ int main() ]) AS_VAR_IF([ac_cv_libatomic_needed], [yes], - [LIBS="${LIBS} -latomic"]) + [LIBS="${LIBS} -latomic" + LIBATOMIC=${LIBATOMIC-"-latomic"}]) _RESTORE_VAR([CPPFLAGS]) @@ -7065,6 +7120,7 @@ AS_CASE([$ac_sys_system], [_tkinter], [_xxsubinterpreters], [_xxinterpchannels], + [_xxinterpqueues], [grp], [pwd], [resource], @@ -7181,6 +7237,7 @@ PY_STDLIB_MOD_SIMPLE([_struct]) PY_STDLIB_MOD_SIMPLE([_typing]) PY_STDLIB_MOD_SIMPLE([_xxsubinterpreters]) PY_STDLIB_MOD_SIMPLE([_xxinterpchannels]) +PY_STDLIB_MOD_SIMPLE([_xxinterpqueues]) PY_STDLIB_MOD_SIMPLE([_zoneinfo]) dnl multiprocessing modules @@ -7299,7 +7356,10 @@ PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) dnl test modules -PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testcapi], + [test "$TEST_MODULES" = yes], + dnl Modules/_testcapi needs -latomic for 32bit AIX build + [], [], [$LIBATOMIC]) 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]) @@ -7368,3 +7428,10 @@ AS_VAR_IF([PY_SUPPORT_TIER], [0], [AC_MSG_WARN([ Platform "$host" with compiler "$ac_cv_cc_name" is not supported by the CPython core team, see https://peps.python.org/pep-0011/ for more information. ])]) + +if test "$ac_cv_header_stdatomic_h" != "yes"; then + AC_MSG_NOTICE(m4_normalize([ + Your compiler or platform does have a working C11 stdatomic.h. A future + version of Python may require stdatomic.h. + ])) +fi diff --git a/pyconfig.h.in b/pyconfig.h.in index c2c75c96dcaad1..9c429c03722383 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -157,6 +157,9 @@ /* Define to 1 if you have the `clock_settime' function. */ #undef HAVE_CLOCK_SETTIME +/* Define to 1 if you have the `closefrom' function. */ +#undef HAVE_CLOSEFROM + /* Define to 1 if you have the `close_range' function. */ #undef HAVE_CLOSE_RANGE @@ -983,6 +986,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 @@ -1363,6 +1369,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 @@ -1405,6 +1414,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 @@ -1602,16 +1614,19 @@ /* Defined if Python is built as a shared library. */ #undef Py_ENABLE_SHARED +/* Define if you want to disable the GIL */ +#undef Py_GIL_DISABLED + /* Define hash algorithm for str, bytes and memoryview. SipHash24: 1, FNV: 2, 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 @@ -1788,9 +1803,6 @@ /* 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 @@ -1815,6 +1827,9 @@ /* Define to 1 if libintl is needed for locale functions. */ #undef WITH_LIBINTL +/* Define if you want to compile in mimalloc memory allocator. */ +#undef WITH_MIMALLOC + /* Define if you want to produce an OpenStep/Rhapsody framework (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK